]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/sh/sh.md
rtl.h (MEM_READONLY_P): Replace RTX_UNCHANGING_P.
[thirdparty/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 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, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, 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
147 ;; These are used with unspec_volatile.
148 (UNSPECV_BLOCKAGE 0)
149 (UNSPECV_ALIGN 1)
150 (UNSPECV_CONST2 2)
151 (UNSPECV_CONST4 4)
152 (UNSPECV_CONST8 6)
153 (UNSPECV_WINDOW_END 10)
154 (UNSPECV_CONST_END 11)
155 ])
156
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
160
161 ;; Target CPU.
162
163 (define_attr "cpu"
164 "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
165 (const (symbol_ref "sh_cpu_attr")))
166
167 (define_attr "endian" "big,little"
168 (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169 (const_string "little") (const_string "big"))))
170
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173 (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174 (const_string "yes") (const_string "no"))))
175
176 (define_attr "fmovd" "yes,no"
177 (const (if_then_else (symbol_ref "TARGET_FMOVD")
178 (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181 (const
182 (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183 (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184 (const_string "sh1"))))
185
186 ;; cbranch conditional branch instructions
187 ;; jump unconditional jumps
188 ;; arith ordinary arithmetic
189 ;; arith3 a compound insn that behaves similarly to a sequence of
190 ;; three insns of type arith
191 ;; arith3b like above, but might end with a redirected branch
192 ;; load from memory
193 ;; load_si Likewise, SImode variant for general register.
194 ;; fload Likewise, but load to fp register.
195 ;; store to memory
196 ;; move general purpose register to register
197 ;; mt_group other sh4 mt instructions
198 ;; fmove register to register, floating point
199 ;; smpy word precision integer multiply
200 ;; dmpy longword or doublelongword precision integer multiply
201 ;; return rts
202 ;; pload load of pr reg, which can't be put into delay slot of rts
203 ;; prset copy register to pr reg, ditto
204 ;; pstore store of pr reg, which can't be put into delay slot of jsr
205 ;; prget copy pr to register, ditto
206 ;; pcload pc relative load of constant value
207 ;; pcfload Likewise, but load to fp register.
208 ;; pcload_si Likewise, SImode variant for general register.
209 ;; rte return from exception
210 ;; sfunc special function call with known used registers
211 ;; call function call
212 ;; fp floating point
213 ;; fdiv floating point divide (or square root)
214 ;; gp_fpul move from general purpose register to fpul
215 ;; fpul_gp move from fpul to general purpose register
216 ;; mac_gp move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s fix_truncsfsi2_i4
219 ;; dfdiv double precision floating point divide (or square root)
220 ;; cwb ic_invalidate_line_i
221 ;; movua SH4a unaligned load
222 ;; fsrra square root reciprocal approximate
223 ;; fsca sine and cosine approximate
224 ;; tls_load load TLS related address
225 ;; arith_media SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media SHmedia compare instructions
228 ;; dfdiv_media SHmedia double precision divide and square root
229 ;; dfmul_media SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media SHmedia longword multiply
233 ;; fcmp_media SHmedia floating point compare instructions
234 ;; fdiv_media SHmedia single precision divide and square root
235 ;; fload_media SHmedia floating point register load instructions
236 ;; fmove_media SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media SHmedia unconditional branch instructions
243 ;; load_media SHmedia general register load instructions
244 ;; pt_media SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media SHmedia ptabs instruction
246 ;; store_media SHmedia general register store instructions
247 ;; mcmp_media SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media SHmedia mac-style fixed point operations
249 ;; d2mpy_media SHmedia: two 32 bit integer multiplies
250 ;; atrans SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil no-op move, will be deleted.
253
254 (define_attr "type"
255 "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"
256 (const_string "other"))
257
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
260 ;;
261 ;; mt_group SH4 "mt" group instructions.
262 ;;
263 ;; ex_group SH4 "ex" group instructions.
264 ;;
265 ;; ls_group SH4 "ls" group instructions.
266 ;;
267
268 (define_attr "insn_class"
269 "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270 (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271 (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272 (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273 (eq_attr "type" "cbranch,jump") (const_string "br_group")
274 (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275 (const_string "fe_group")
276 (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")]
277 (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
281
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
283
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
285
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
289 ;; state.
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
293
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long. Something in the
296 ; range -4090..4100 bytes can be 6 bytes long. All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
299 ; 2 bytes.
300
301 ;; The maximum range used for SImode constant pool entries is 1018. A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool. Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table. That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code. For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
313 ;;
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
316
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
318 ;; inside an le.
319 (define_attr "short_cbranch_p" "no,yes"
320 (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
321 (const_string "no")
322 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
323 (const_string "yes")
324 (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
325 (const_string "no")
326 (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
327 (const_string "yes")
328 ] (const_string "no")))
329
330 (define_attr "med_branch_p" "no,yes"
331 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
332 (const_int 1988))
333 (const_string "yes")
334 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335 (const_string "no")
336 (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
337 (const_int 8186))
338 (const_string "yes")
339 ] (const_string "no")))
340
341 (define_attr "med_cbranch_p" "no,yes"
342 (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
343 (const_int 1986))
344 (const_string "yes")
345 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
346 (const_string "no")
347 (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
348 (const_int 8184))
349 (const_string "yes")
350 ] (const_string "no")))
351
352 (define_attr "braf_branch_p" "no,yes"
353 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
354 (const_string "no")
355 (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
356 (const_int 20660))
357 (const_string "yes")
358 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
359 (const_string "no")
360 (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
361 (const_int 65530))
362 (const_string "yes")
363 ] (const_string "no")))
364
365 (define_attr "braf_cbranch_p" "no,yes"
366 (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
367 (const_string "no")
368 (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
369 (const_int 20658))
370 (const_string "yes")
371 (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
372 (const_string "no")
373 (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
374 (const_int 65528))
375 (const_string "yes")
376 ] (const_string "no")))
377
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
384
385 ; All other instructions are two bytes long by default.
386
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390 (cond [(eq_attr "type" "cbranch")
391 (cond [(eq_attr "short_cbranch_p" "yes")
392 (const_int 2)
393 (eq_attr "med_cbranch_p" "yes")
394 (const_int 6)
395 (eq_attr "braf_cbranch_p" "yes")
396 (const_int 12)
397 ;; ??? using pc is not computed transitively.
398 (ne (match_dup 0) (match_dup 0))
399 (const_int 14)
400 (ne (symbol_ref ("flag_pic")) (const_int 0))
401 (const_int 24)
402 ] (const_int 16))
403 (eq_attr "type" "jump")
404 (cond [(eq_attr "med_branch_p" "yes")
405 (const_int 2)
406 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
407 (symbol_ref "INSN"))
408 (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409 (symbol_ref "code_for_indirect_jump_scratch")))
410 (if_then_else (eq_attr "braf_branch_p" "yes")
411 (const_int 6)
412 (const_int 10))
413 (eq_attr "braf_branch_p" "yes")
414 (const_int 10)
415 ;; ??? using pc is not computed transitively.
416 (ne (match_dup 0) (match_dup 0))
417 (const_int 12)
418 (ne (symbol_ref ("flag_pic")) (const_int 0))
419 (const_int 22)
420 ] (const_int 14))
421 (eq_attr "type" "pt_media")
422 (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
423 (const_int 20) (const_int 12))
424 ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
425 (const_int 4)
426 (const_int 2))))
427
428 ;; DFA descriptions for the pipelines
429
430 (include "sh1.md")
431 (include "shmedia.md")
432 (include "sh4.md")
433
434 ;; Definitions for filling delay slots
435
436 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
437
438 ;; ??? This should be (nil) instead of (const_int 0)
439 (define_attr "hit_stack" "yes,no"
440 (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
441 (const_int 0))
442 (const_string "no")]
443 (const_string "yes")))
444
445 (define_attr "interrupt_function" "no,yes"
446 (const (symbol_ref "current_function_interrupt")))
447
448 (define_attr "in_delay_slot" "yes,no"
449 (cond [(eq_attr "type" "cbranch") (const_string "no")
450 (eq_attr "type" "pcload,pcload_si") (const_string "no")
451 (eq_attr "needs_delay_slot" "yes") (const_string "no")
452 (eq_attr "length" "2") (const_string "yes")
453 ] (const_string "no")))
454
455 (define_attr "cond_delay_slot" "yes,no"
456 (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
457 ] (const_string "no")))
458
459 (define_attr "is_sfunc" ""
460 (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
461
462 (define_attr "is_mac_media" ""
463 (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
464
465 (define_attr "branch_zero" "yes,no"
466 (cond [(eq_attr "type" "!cbranch") (const_string "no")
467 (ne (symbol_ref "(next_active_insn (insn)\
468 == (prev_active_insn\
469 (XEXP (SET_SRC (PATTERN (insn)), 1))))\
470 && get_attr_length (next_active_insn (insn)) == 2")
471 (const_int 0))
472 (const_string "yes")]
473 (const_string "no")))
474
475 ;; SH4 Double-precision computation with double-precision result -
476 ;; the two halves are ready at different times.
477 (define_attr "dfp_comp" "yes,no"
478 (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
479 (const_string "no")))
480
481 ;; Insns for which the latency of a preceding fp insn is decreased by one.
482 (define_attr "late_fp_use" "yes,no" (const_string "no"))
483 ;; And feeding insns for which this relevant.
484 (define_attr "any_fp_comp" "yes,no"
485 (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
486 (const_string "yes")]
487 (const_string "no")))
488
489 (define_attr "any_int_load" "yes,no"
490 (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
491 (const_string "yes")]
492 (const_string "no")))
493
494 (define_delay
495 (eq_attr "needs_delay_slot" "yes")
496 [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
497
498 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
499 ;; and thus we can't put a pop instruction in its delay slot.
500 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
501 ;; instruction can go in the delay slot.
502
503 ;; Since a normal return (rts) implicitly uses the PR register,
504 ;; we can't allow PR register loads in an rts delay slot.
505
506 (define_delay
507 (eq_attr "type" "return")
508 [(and (eq_attr "in_delay_slot" "yes")
509 (ior (and (eq_attr "interrupt_function" "no")
510 (eq_attr "type" "!pload,prset"))
511 (and (eq_attr "interrupt_function" "yes")
512 (ior
513 (ne (symbol_ref "TARGET_SH3") (const_int 0))
514 (eq_attr "hit_stack" "no"))))) (nil) (nil)])
515
516 ;; Since a call implicitly uses the PR register, we can't allow
517 ;; a PR register store in a jsr delay slot.
518
519 (define_delay
520 (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
521 [(and (eq_attr "in_delay_slot" "yes")
522 (eq_attr "type" "!pstore,prget")) (nil) (nil)])
523
524 ;; Say that we have annulled true branches, since this gives smaller and
525 ;; faster code when branches are predicted as not taken.
526
527 ;; ??? The non-annulled condition should really be "in_delay_slot",
528 ;; but insns that can be filled in non-annulled get priority over insns
529 ;; that can only be filled in anulled.
530
531 (define_delay
532 (and (eq_attr "type" "cbranch")
533 (ne (symbol_ref "TARGET_SH2") (const_int 0)))
534 ;; SH2e has a hardware bug that pretty much prohibits the use of
535 ;; annuled delay slots.
536 [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
537 (not (eq_attr "cpu" "sh2e"))) (nil)])
538 \f
539 ;; -------------------------------------------------------------------------
540 ;; SImode signed integer comparisons
541 ;; -------------------------------------------------------------------------
542
543 (define_insn ""
544 [(set (reg:SI T_REG)
545 (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
546 (match_operand:SI 1 "arith_operand" "K08,r"))
547 (const_int 0)))]
548 "TARGET_SH1"
549 "tst %1,%0"
550 [(set_attr "type" "mt_group")])
551
552 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
553 ;; That would still allow reload to create cmpi instructions, but would
554 ;; perhaps allow forcing the constant into a register when that is better.
555 ;; Probably should use r0 for mem/imm compares, but force constant into a
556 ;; register for pseudo/imm compares.
557
558 (define_insn "cmpeqsi_t"
559 [(set (reg:SI T_REG)
560 (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
561 (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
562 "TARGET_SH1"
563 "@
564 tst %0,%0
565 cmp/eq %1,%0
566 cmp/eq %1,%0"
567 [(set_attr "type" "mt_group")])
568
569 (define_insn "cmpgtsi_t"
570 [(set (reg:SI T_REG)
571 (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
572 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
573 "TARGET_SH1"
574 "@
575 cmp/gt %1,%0
576 cmp/pl %0"
577 [(set_attr "type" "mt_group")])
578
579 (define_insn "cmpgesi_t"
580 [(set (reg:SI T_REG)
581 (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
582 (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
583 "TARGET_SH1"
584 "@
585 cmp/ge %1,%0
586 cmp/pz %0"
587 [(set_attr "type" "mt_group")])
588
589 ;; -------------------------------------------------------------------------
590 ;; SImode unsigned integer comparisons
591 ;; -------------------------------------------------------------------------
592
593 (define_insn "cmpgeusi_t"
594 [(set (reg:SI T_REG)
595 (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
596 (match_operand:SI 1 "arith_reg_operand" "r")))]
597 "TARGET_SH1"
598 "cmp/hs %1,%0"
599 [(set_attr "type" "mt_group")])
600
601 (define_insn "cmpgtusi_t"
602 [(set (reg:SI T_REG)
603 (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
604 (match_operand:SI 1 "arith_reg_operand" "r")))]
605 "TARGET_SH1"
606 "cmp/hi %1,%0"
607 [(set_attr "type" "mt_group")])
608
609 ;; We save the compare operands in the cmpxx patterns and use them when
610 ;; we generate the branch.
611
612 (define_expand "cmpsi"
613 [(set (reg:SI T_REG)
614 (compare (match_operand:SI 0 "cmpsi_operand" "")
615 (match_operand:SI 1 "arith_operand" "")))]
616 "TARGET_SH1"
617 "
618 {
619 if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
620 && GET_CODE (operands[1]) != CONST_INT)
621 operands[0] = copy_to_mode_reg (SImode, operands[0]);
622 sh_compare_op0 = operands[0];
623 sh_compare_op1 = operands[1];
624 DONE;
625 }")
626 \f
627 ;; -------------------------------------------------------------------------
628 ;; DImode signed integer comparisons
629 ;; -------------------------------------------------------------------------
630
631 ;; ??? Could get better scheduling by splitting the initial test from the
632 ;; rest of the insn after reload. However, the gain would hardly justify
633 ;; the sh.md size increase necessary to do that.
634
635 (define_insn ""
636 [(set (reg:SI T_REG)
637 (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
638 (match_operand:DI 1 "arith_operand" "r"))
639 (const_int 0)))]
640 "TARGET_SH1"
641 "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
642 insn, operands);"
643 [(set_attr "length" "6")
644 (set_attr "type" "arith3b")])
645
646 (define_insn "cmpeqdi_t"
647 [(set (reg:SI T_REG)
648 (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
649 (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
650 "TARGET_SH1"
651 "@
652 tst %S0,%S0\;bf %,Ldi%=\;tst %R0,%R0\\n%,Ldi%=:
653 cmp/eq %S1,%S0\;bf %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
654 [(set_attr "length" "6")
655 (set_attr "type" "arith3b")])
656
657 (define_split
658 [(set (reg:SI T_REG)
659 (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
660 (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
661 ;; If we applied this split when not optimizing, it would only be
662 ;; applied during the machine-dependent reorg, when no new basic blocks
663 ;; may be created.
664 "TARGET_SH1 && reload_completed && optimize"
665 [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
666 (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
667 (label_ref (match_dup 6))
668 (pc)))
669 (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
670 (match_dup 6)]
671 "
672 {
673 operands[2]
674 = gen_rtx_REG (SImode,
675 true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
676 operands[3]
677 = (operands[1] == const0_rtx
678 ? const0_rtx
679 : gen_rtx_REG (SImode,
680 true_regnum (operands[1])
681 + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
682 operands[4] = gen_lowpart (SImode, operands[0]);
683 operands[5] = gen_lowpart (SImode, operands[1]);
684 operands[6] = gen_label_rtx ();
685 }")
686
687 (define_insn "cmpgtdi_t"
688 [(set (reg:SI T_REG)
689 (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
690 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
691 "TARGET_SH2"
692 "@
693 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
694 tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
695 [(set_attr "length" "8")
696 (set_attr "type" "arith3")])
697
698 (define_insn "cmpgedi_t"
699 [(set (reg:SI T_REG)
700 (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
701 (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
702 "TARGET_SH2"
703 "@
704 cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
705 cmp/pz\\t%S0"
706 [(set_attr "length" "8,2")
707 (set_attr "type" "arith3,mt_group")])
708 \f
709 ;; -------------------------------------------------------------------------
710 ;; DImode unsigned integer comparisons
711 ;; -------------------------------------------------------------------------
712
713 (define_insn "cmpgeudi_t"
714 [(set (reg:SI T_REG)
715 (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
716 (match_operand:DI 1 "arith_reg_operand" "r")))]
717 "TARGET_SH2"
718 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
719 [(set_attr "length" "8")
720 (set_attr "type" "arith3")])
721
722 (define_insn "cmpgtudi_t"
723 [(set (reg:SI T_REG)
724 (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
725 (match_operand:DI 1 "arith_reg_operand" "r")))]
726 "TARGET_SH2"
727 "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
728 [(set_attr "length" "8")
729 (set_attr "type" "arith3")])
730
731 (define_insn "cmpeqdi_media"
732 [(set (match_operand:DI 0 "register_operand" "=r")
733 (eq:DI (match_operand:DI 1 "register_operand" "%r")
734 (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
735 "TARGET_SHMEDIA"
736 "cmpeq %1, %N2, %0"
737 [(set_attr "type" "cmp_media")])
738
739 (define_insn "cmpgtdi_media"
740 [(set (match_operand:DI 0 "register_operand" "=r")
741 (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
742 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
743 "TARGET_SHMEDIA"
744 "cmpgt %N1, %N2, %0"
745 [(set_attr "type" "cmp_media")])
746
747 (define_insn "cmpgtudi_media"
748 [(set (match_operand:DI 0 "register_operand" "=r")
749 (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
750 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
751 "TARGET_SHMEDIA"
752 "cmpgtu %N1, %N2, %0"
753 [(set_attr "type" "cmp_media")])
754
755 ;; We save the compare operands in the cmpxx patterns and use them when
756 ;; we generate the branch.
757
758 (define_expand "cmpdi"
759 [(set (reg:SI T_REG)
760 (compare (match_operand:DI 0 "arith_operand" "")
761 (match_operand:DI 1 "arith_operand" "")))]
762 "TARGET_SH2 || TARGET_SHMEDIA"
763 "
764 {
765 sh_compare_op0 = operands[0];
766 sh_compare_op1 = operands[1];
767 DONE;
768 }")
769 ;; -------------------------------------------------------------------------
770 ;; Conditional move instructions
771 ;; -------------------------------------------------------------------------
772
773 ;; The insn names may seem reversed, but note that cmveq performs the move
774 ;; if op1 == 0, and cmvne does it if op1 != 0.
775
776 (define_insn "movdicc_false"
777 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
778 (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
779 (const_int 0))
780 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
781 (match_operand:DI 3 "arith_reg_operand" "0")))]
782 "TARGET_SHMEDIA"
783 "cmveq %1, %N2, %0"
784 [(set_attr "type" "arith_media")])
785
786 (define_insn "movdicc_true"
787 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
788 (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
789 (const_int 0))
790 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
791 (match_operand:DI 3 "arith_reg_operand" "0")))]
792 "TARGET_SHMEDIA"
793 "cmvne %1, %N2, %0"
794 [(set_attr "type" "arith_media")])
795
796 (define_expand "movdicc"
797 [(set (match_operand:DI 0 "register_operand" "")
798 (if_then_else:DI (match_operand 1 "comparison_operator" "")
799 (match_operand:DI 2 "register_operand" "")
800 (match_operand:DI 3 "register_operand" "")))]
801 "TARGET_SHMEDIA"
802 "
803 {
804 if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
805 && GET_MODE (sh_compare_op0) == DImode
806 && sh_compare_op1 == const0_rtx)
807 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
808 sh_compare_op0, sh_compare_op1);
809 else
810 {
811 rtx tmp;
812
813 if (no_new_pseudos)
814 FAIL;
815
816 tmp = gen_reg_rtx (DImode);
817
818 switch (GET_CODE (operands[1]))
819 {
820 case EQ:
821 emit_insn (gen_seq (tmp));
822 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
823 break;
824
825 case NE:
826 emit_insn (gen_seq (tmp));
827 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
828 break;
829
830 case GT:
831 emit_insn (gen_sgt (tmp));
832 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
833 break;
834
835 case LT:
836 emit_insn (gen_slt (tmp));
837 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
838 break;
839
840 case GE:
841 emit_insn (gen_slt (tmp));
842 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
843 break;
844
845 case LE:
846 emit_insn (gen_sgt (tmp));
847 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
848 break;
849
850 case GTU:
851 emit_insn (gen_sgtu (tmp));
852 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
853 break;
854
855 case LTU:
856 emit_insn (gen_sltu (tmp));
857 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
858 break;
859
860 case GEU:
861 emit_insn (gen_sltu (tmp));
862 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
863 break;
864
865 case LEU:
866 emit_insn (gen_sgtu (tmp));
867 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
868 break;
869
870 case UNORDERED:
871 emit_insn (gen_sunordered (tmp));
872 operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
873 break;
874
875 case ORDERED:
876 emit_insn (gen_sunordered (tmp));
877 operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
878 break;
879
880 case UNEQ:
881 case UNGE:
882 case UNGT:
883 case UNLE:
884 case UNLT:
885 case LTGT:
886 FAIL;
887
888 default:
889 abort ();
890 }
891 }
892 }")
893 \f
894 ;; -------------------------------------------------------------------------
895 ;; Addition instructions
896 ;; -------------------------------------------------------------------------
897
898 (define_expand "adddi3"
899 [(set (match_operand:DI 0 "arith_reg_operand" "")
900 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
901 (match_operand:DI 2 "arith_operand" "")))]
902 ""
903 "
904 {
905 if (TARGET_SH1)
906 {
907 if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
908 FAIL;
909 operands[2] = force_reg (DImode, operands[2]);
910 emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
911 DONE;
912 }
913 }")
914
915 (define_insn "*adddi3_media"
916 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
917 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
918 (match_operand:DI 2 "arith_operand" "r,I10")))]
919 "TARGET_SHMEDIA"
920 "@
921 add %1, %2, %0
922 addi %1, %2, %0"
923 [(set_attr "type" "arith_media")])
924
925 (define_insn "adddi3z_media"
926 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
927 (zero_extend:DI
928 (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
929 (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
930 "TARGET_SHMEDIA"
931 "addz.l %1, %N2, %0"
932 [(set_attr "type" "arith_media")])
933
934 (define_insn "adddi3_compact"
935 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
936 (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
937 (match_operand:DI 2 "arith_reg_operand" "r")))
938 (clobber (reg:SI T_REG))]
939 "TARGET_SH1"
940 "#"
941 [(set_attr "length" "6")])
942
943 (define_split
944 [(set (match_operand:DI 0 "arith_reg_operand" "")
945 (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
946 (match_operand:DI 2 "arith_reg_operand" "")))
947 (clobber (reg:SI T_REG))]
948 "TARGET_SH1 && reload_completed"
949 [(const_int 0)]
950 "
951 {
952 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
953 high0 = gen_rtx_REG (SImode,
954 true_regnum (operands[0])
955 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
956 high2 = gen_rtx_REG (SImode,
957 true_regnum (operands[2])
958 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
959 emit_insn (gen_clrt ());
960 emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
961 emit_insn (gen_addc1 (high0, high0, high2));
962 DONE;
963 }")
964
965 (define_insn "addc"
966 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
967 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
968 (match_operand:SI 2 "arith_reg_operand" "r"))
969 (reg:SI T_REG)))
970 (set (reg:SI T_REG)
971 (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
972 "TARGET_SH1"
973 "addc %2,%0"
974 [(set_attr "type" "arith")])
975
976 (define_insn "addc1"
977 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
978 (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
979 (match_operand:SI 2 "arith_reg_operand" "r"))
980 (reg:SI T_REG)))
981 (clobber (reg:SI T_REG))]
982 "TARGET_SH1"
983 "addc %2,%0"
984 [(set_attr "type" "arith")])
985
986 (define_expand "addsi3"
987 [(set (match_operand:SI 0 "arith_reg_operand" "")
988 (plus:SI (match_operand:SI 1 "arith_operand" "")
989 (match_operand:SI 2 "arith_operand" "")))]
990 ""
991 "
992 {
993 if (TARGET_SHMEDIA)
994 operands[1] = force_reg (SImode, operands[1]);
995 }")
996
997 (define_insn "addsi3_media"
998 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
999 (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1000 (match_operand:SI 2 "arith_operand" "r,I10")))]
1001 "TARGET_SHMEDIA"
1002 "@
1003 add.l %1, %2, %0
1004 addi.l %1, %2, %0"
1005 [(set_attr "type" "arith_media")])
1006
1007 (define_insn "*addsi3_compact"
1008 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1009 (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1010 (match_operand:SI 2 "arith_operand" "rI08")))]
1011 "TARGET_SH1"
1012 "add %2,%0"
1013 [(set_attr "type" "arith")])
1014
1015 ;; -------------------------------------------------------------------------
1016 ;; Subtraction instructions
1017 ;; -------------------------------------------------------------------------
1018
1019 (define_expand "subdi3"
1020 [(set (match_operand:DI 0 "arith_reg_operand" "")
1021 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1022 (match_operand:DI 2 "arith_reg_operand" "")))]
1023 ""
1024 "
1025 {
1026 if (TARGET_SH1)
1027 {
1028 operands[1] = force_reg (DImode, operands[1]);
1029 emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1030 DONE;
1031 }
1032 }")
1033
1034 (define_insn "*subdi3_media"
1035 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1036 (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1037 (match_operand:DI 2 "arith_reg_operand" "r")))]
1038 "TARGET_SHMEDIA"
1039 "sub %N1, %2, %0"
1040 [(set_attr "type" "arith_media")])
1041
1042 (define_insn "subdi3_compact"
1043 [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1044 (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1045 (match_operand:DI 2 "arith_reg_operand" "r")))
1046 (clobber (reg:SI T_REG))]
1047 "TARGET_SH1"
1048 "#"
1049 [(set_attr "length" "6")])
1050
1051 (define_split
1052 [(set (match_operand:DI 0 "arith_reg_operand" "")
1053 (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1054 (match_operand:DI 2 "arith_reg_operand" "")))
1055 (clobber (reg:SI T_REG))]
1056 "TARGET_SH1 && reload_completed"
1057 [(const_int 0)]
1058 "
1059 {
1060 rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1061 high0 = gen_rtx_REG (SImode,
1062 true_regnum (operands[0])
1063 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1064 high2 = gen_rtx_REG (SImode,
1065 true_regnum (operands[2])
1066 + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1067 emit_insn (gen_clrt ());
1068 emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1069 emit_insn (gen_subc1 (high0, high0, high2));
1070 DONE;
1071 }")
1072
1073 (define_insn "subc"
1074 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1075 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1076 (match_operand:SI 2 "arith_reg_operand" "r"))
1077 (reg:SI T_REG)))
1078 (set (reg:SI T_REG)
1079 (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1080 (reg:SI T_REG))
1081 (match_dup 1)))]
1082 "TARGET_SH1"
1083 "subc %2,%0"
1084 [(set_attr "type" "arith")])
1085
1086 (define_insn "subc1"
1087 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1088 (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1089 (match_operand:SI 2 "arith_reg_operand" "r"))
1090 (reg:SI T_REG)))
1091 (clobber (reg:SI T_REG))]
1092 "TARGET_SH1"
1093 "subc %2,%0"
1094 [(set_attr "type" "arith")])
1095
1096 (define_insn "*subsi3_internal"
1097 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1098 (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1099 (match_operand:SI 2 "arith_reg_operand" "r")))]
1100 "TARGET_SH1"
1101 "sub %2,%0"
1102 [(set_attr "type" "arith")])
1103
1104 (define_insn "*subsi3_media"
1105 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1106 (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1107 (match_operand:SI 2 "extend_reg_operand" "r")))]
1108 "TARGET_SHMEDIA"
1109 "sub.l %N1, %2, %0"
1110 [(set_attr "type" "arith_media")])
1111
1112 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1113 ;; will sometimes save one instruction. Otherwise we might get
1114 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1115 ;; are the same.
1116
1117 (define_expand "subsi3"
1118 [(set (match_operand:SI 0 "arith_reg_operand" "")
1119 (minus:SI (match_operand:SI 1 "arith_operand" "")
1120 (match_operand:SI 2 "arith_reg_operand" "")))]
1121 ""
1122 "
1123 {
1124 if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1125 {
1126 emit_insn (gen_negsi2 (operands[0], operands[2]));
1127 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1128 DONE;
1129 }
1130 if (TARGET_SHMEDIA)
1131 {
1132 if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1133 FAIL;
1134 if (operands[1] != const0_rtx)
1135 operands[1] = force_reg (SImode, operands[1]);
1136 }
1137 }")
1138 \f
1139 ;; -------------------------------------------------------------------------
1140 ;; Division instructions
1141 ;; -------------------------------------------------------------------------
1142
1143 ;; We take advantage of the library routines which don't clobber as many
1144 ;; registers as a normal function call would.
1145
1146 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1147 ;; also has an effect on the register that holds the address of the sfunc.
1148 ;; To make this work, we have an extra dummy insn that shows the use
1149 ;; of this register for reorg.
1150
1151 (define_insn "use_sfunc_addr"
1152 [(set (reg:SI PR_REG)
1153 (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1154 "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1155 ""
1156 [(set_attr "length" "0")])
1157
1158 (define_insn "udivsi3_sh2a"
1159 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1160 (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1161 (match_operand:SI 2 "arith_reg_operand" "z")))]
1162 "TARGET_SH2A"
1163 "divu %2,%1"
1164 [(set_attr "type" "arith")])
1165
1166 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1167 ;; hard register 0. If we used hard register 0, then the next instruction
1168 ;; would be a move from hard register 0 to a pseudo-reg. If the pseudo-reg
1169 ;; gets allocated to a stack slot that needs its address reloaded, then
1170 ;; there is nothing to prevent reload from using r0 to reload the address.
1171 ;; This reload would clobber the value in r0 we are trying to store.
1172 ;; If we let reload allocate r0, then this problem can never happen.
1173
1174 (define_insn "udivsi3_i1"
1175 [(set (match_operand:SI 0 "register_operand" "=z")
1176 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1177 (clobber (reg:SI T_REG))
1178 (clobber (reg:SI PR_REG))
1179 (clobber (reg:SI R4_REG))
1180 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1181 "TARGET_SH1 && ! TARGET_SH4"
1182 "jsr @%1%#"
1183 [(set_attr "type" "sfunc")
1184 (set_attr "needs_delay_slot" "yes")])
1185
1186 ; Since shmedia-nofpu code could be linked against shcompact code, and
1187 ; the udivsi3 libcall has the same name, we must consider all registers
1188 ; clobbered that are in the union of the registers clobbered by the
1189 ; shmedia and the shcompact implementation. Note, if the shcompact
1190 ; implementation actually used shcompact code, we'd need to clobber
1191 ; also r23 and fr23.
1192 (define_insn "udivsi3_i1_media"
1193 [(set (match_operand:SI 0 "register_operand" "=z")
1194 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1195 (clobber (reg:SI T_MEDIA_REG))
1196 (clobber (reg:SI PR_MEDIA_REG))
1197 (clobber (reg:SI R20_REG))
1198 (clobber (reg:SI R21_REG))
1199 (clobber (reg:SI R22_REG))
1200 (clobber (reg:DI TR0_REG))
1201 (clobber (reg:DI TR1_REG))
1202 (clobber (reg:DI TR2_REG))
1203 (use (match_operand:DI 1 "target_operand" "b"))]
1204 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1205 "blink %1, r18"
1206 [(set_attr "type" "sfunc")
1207 (set_attr "needs_delay_slot" "yes")])
1208
1209 (define_expand "udivsi3_i4_media"
1210 [(set (match_dup 3)
1211 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1212 (set (match_dup 4)
1213 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1214 (set (match_dup 5) (float:DF (match_dup 3)))
1215 (set (match_dup 6) (float:DF (match_dup 4)))
1216 (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1217 (set (match_dup 8) (fix:DI (match_dup 7)))
1218 (set (match_operand:SI 0 "register_operand" "")
1219 (truncate:SI (match_dup 8)))]
1220 "TARGET_SHMEDIA_FPU"
1221 "
1222 {
1223 operands[3] = gen_reg_rtx (DImode);
1224 operands[4] = gen_reg_rtx (DImode);
1225 operands[5] = gen_reg_rtx (DFmode);
1226 operands[6] = gen_reg_rtx (DFmode);
1227 operands[7] = gen_reg_rtx (DFmode);
1228 operands[8] = gen_reg_rtx (DImode);
1229 }")
1230
1231 (define_insn "udivsi3_i4"
1232 [(set (match_operand:SI 0 "register_operand" "=y")
1233 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1234 (clobber (reg:SI T_REG))
1235 (clobber (reg:SI PR_REG))
1236 (clobber (reg:DF DR0_REG))
1237 (clobber (reg:DF DR2_REG))
1238 (clobber (reg:DF DR4_REG))
1239 (clobber (reg:SI R0_REG))
1240 (clobber (reg:SI R1_REG))
1241 (clobber (reg:SI R4_REG))
1242 (clobber (reg:SI R5_REG))
1243 (use (reg:PSI FPSCR_REG))
1244 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1245 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1246 "jsr @%1%#"
1247 [(set_attr "type" "sfunc")
1248 (set_attr "fp_mode" "double")
1249 (set_attr "needs_delay_slot" "yes")])
1250
1251 (define_insn "udivsi3_i4_single"
1252 [(set (match_operand:SI 0 "register_operand" "=y")
1253 (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1254 (clobber (reg:SI T_REG))
1255 (clobber (reg:SI PR_REG))
1256 (clobber (reg:DF DR0_REG))
1257 (clobber (reg:DF DR2_REG))
1258 (clobber (reg:DF DR4_REG))
1259 (clobber (reg:SI R0_REG))
1260 (clobber (reg:SI R1_REG))
1261 (clobber (reg:SI R4_REG))
1262 (clobber (reg:SI R5_REG))
1263 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1264 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1265 "jsr @%1%#"
1266 [(set_attr "type" "sfunc")
1267 (set_attr "needs_delay_slot" "yes")])
1268
1269 (define_expand "udivsi3"
1270 [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1271 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1272 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1273 (parallel [(set (match_operand:SI 0 "register_operand" "")
1274 (udiv:SI (reg:SI R4_REG)
1275 (reg:SI R5_REG)))
1276 (clobber (reg:SI T_REG))
1277 (clobber (reg:SI PR_REG))
1278 (clobber (reg:SI R4_REG))
1279 (use (match_dup 3))])]
1280 ""
1281 "
1282 {
1283 rtx first, last;
1284
1285 operands[3] = gen_reg_rtx (Pmode);
1286 /* Emit the move of the address to a pseudo outside of the libcall. */
1287 if (TARGET_HARD_SH4 && TARGET_SH2E)
1288 {
1289 emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1290 if (TARGET_FPU_SINGLE)
1291 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1292 else
1293 last = gen_udivsi3_i4 (operands[0], operands[3]);
1294 }
1295 else if (TARGET_SHMEDIA_FPU)
1296 {
1297 operands[1] = force_reg (SImode, operands[1]);
1298 operands[2] = force_reg (SImode, operands[2]);
1299 emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1300 DONE;
1301 }
1302 else if (TARGET_SH2A)
1303 {
1304 operands[1] = force_reg (SImode, operands[1]);
1305 operands[2] = force_reg (SImode, operands[2]);
1306 emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1307 DONE;
1308 }
1309 else if (TARGET_SH5)
1310 {
1311 emit_move_insn (operands[3],
1312 function_symbol (TARGET_FPU_ANY
1313 ? \"__udivsi3_i4\"
1314 : \"__udivsi3\"));
1315
1316 if (TARGET_SHMEDIA)
1317 last = gen_udivsi3_i1_media (operands[0],
1318 Pmode == DImode
1319 ? operands[3]
1320 : gen_rtx_SUBREG (DImode, operands[3],
1321 0));
1322 else if (TARGET_FPU_ANY)
1323 last = gen_udivsi3_i4_single (operands[0], operands[3]);
1324 else
1325 last = gen_udivsi3_i1 (operands[0], operands[3]);
1326 }
1327 else
1328 {
1329 emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1330 last = gen_udivsi3_i1 (operands[0], operands[3]);
1331 }
1332 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1333 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1334 last = emit_insn (last);
1335 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1336 invariant code motion can move it. */
1337 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1338 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1339 DONE;
1340 }")
1341
1342 (define_insn "divsi3_sh2a"
1343 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1344 (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1345 (match_operand:SI 2 "arith_reg_operand" "z")))]
1346 "TARGET_SH2A"
1347 "divs %2,%1"
1348 [(set_attr "type" "arith")])
1349
1350 (define_insn "divsi3_i1"
1351 [(set (match_operand:SI 0 "register_operand" "=z")
1352 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1353 (clobber (reg:SI T_REG))
1354 (clobber (reg:SI PR_REG))
1355 (clobber (reg:SI R1_REG))
1356 (clobber (reg:SI R2_REG))
1357 (clobber (reg:SI R3_REG))
1358 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1359 "TARGET_SH1 && ! TARGET_SH4"
1360 "jsr @%1%#"
1361 [(set_attr "type" "sfunc")
1362 (set_attr "needs_delay_slot" "yes")])
1363
1364 ; Since shmedia-nofpu code could be linked against shcompact code, and
1365 ; the sdivsi3 libcall has the same name, we must consider all registers
1366 ; clobbered that are in the union of the registers clobbered by the
1367 ; shmedia and the shcompact implementation. Note, if the shcompact
1368 ; implementation actually used shcompact code, we'd need to clobber
1369 ; also r22, r23 and fr23.
1370 (define_insn "divsi3_i1_media"
1371 [(set (match_operand:SI 0 "register_operand" "=z")
1372 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1373 (clobber (reg:SI T_MEDIA_REG))
1374 (clobber (reg:SI PR_MEDIA_REG))
1375 (clobber (reg:SI R1_REG))
1376 (clobber (reg:SI R2_REG))
1377 (clobber (reg:SI R3_REG))
1378 (clobber (reg:SI R20_REG))
1379 (clobber (reg:SI R21_REG))
1380 (clobber (reg:DI TR0_REG))
1381 (clobber (reg:DI TR1_REG))
1382 (clobber (reg:DI TR2_REG))
1383 (use (match_operand:DI 1 "target_operand" "b"))]
1384 "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1385 "blink %1, r18"
1386 [(set_attr "type" "sfunc")])
1387
1388 (define_expand "divsi3_i4_media"
1389 [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1390 (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1391 (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1392 (set (match_operand:SI 0 "register_operand" "=r")
1393 (fix:SI (match_dup 5)))]
1394 "TARGET_SHMEDIA_FPU"
1395 "
1396 {
1397 operands[3] = gen_reg_rtx (DFmode);
1398 operands[4] = gen_reg_rtx (DFmode);
1399 operands[5] = gen_reg_rtx (DFmode);
1400 }")
1401
1402 (define_insn "divsi3_i4"
1403 [(set (match_operand:SI 0 "register_operand" "=y")
1404 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1405 (clobber (reg:SI PR_REG))
1406 (clobber (reg:DF DR0_REG))
1407 (clobber (reg:DF DR2_REG))
1408 (use (reg:PSI FPSCR_REG))
1409 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1410 "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1411 "jsr @%1%#"
1412 [(set_attr "type" "sfunc")
1413 (set_attr "fp_mode" "double")
1414 (set_attr "needs_delay_slot" "yes")])
1415
1416 (define_insn "divsi3_i4_single"
1417 [(set (match_operand:SI 0 "register_operand" "=y")
1418 (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1419 (clobber (reg:SI PR_REG))
1420 (clobber (reg:DF DR0_REG))
1421 (clobber (reg:DF DR2_REG))
1422 (clobber (reg:SI R2_REG))
1423 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1424 "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1425 "jsr @%1%#"
1426 [(set_attr "type" "sfunc")
1427 (set_attr "needs_delay_slot" "yes")])
1428
1429 (define_expand "divsi3"
1430 [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1431 (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1432 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1433 (parallel [(set (match_operand:SI 0 "register_operand" "")
1434 (div:SI (reg:SI R4_REG)
1435 (reg:SI R5_REG)))
1436 (clobber (reg:SI T_REG))
1437 (clobber (reg:SI PR_REG))
1438 (clobber (reg:SI R1_REG))
1439 (clobber (reg:SI R2_REG))
1440 (clobber (reg:SI R3_REG))
1441 (use (match_dup 3))])]
1442 ""
1443 "
1444 {
1445 rtx first, last;
1446
1447 operands[3] = gen_reg_rtx (Pmode);
1448 /* Emit the move of the address to a pseudo outside of the libcall. */
1449 if (TARGET_HARD_SH4 && TARGET_SH2E)
1450 {
1451 emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1452 if (TARGET_FPU_SINGLE)
1453 last = gen_divsi3_i4_single (operands[0], operands[3]);
1454 else
1455 last = gen_divsi3_i4 (operands[0], operands[3]);
1456 }
1457 else if (TARGET_SH2A)
1458 {
1459 operands[1] = force_reg (SImode, operands[1]);
1460 operands[2] = force_reg (SImode, operands[2]);
1461 emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1462 DONE;
1463 }
1464 else if (TARGET_SHMEDIA_FPU)
1465 {
1466 operands[1] = force_reg (SImode, operands[1]);
1467 operands[2] = force_reg (SImode, operands[2]);
1468 emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1469 DONE;
1470 }
1471 else if (TARGET_SH5)
1472 {
1473 emit_move_insn (operands[3],
1474 function_symbol (TARGET_FPU_ANY
1475 ? \"__sdivsi3_i4\"
1476 : \"__sdivsi3\"));
1477
1478 if (TARGET_SHMEDIA)
1479 last = gen_divsi3_i1_media (operands[0],
1480 Pmode == DImode
1481 ? operands[3]
1482 : gen_rtx_SUBREG (DImode, operands[3],
1483 0));
1484 else if (TARGET_FPU_ANY)
1485 last = gen_divsi3_i4_single (operands[0], operands[3]);
1486 else
1487 last = gen_divsi3_i1 (operands[0], operands[3]);
1488 }
1489 else
1490 {
1491 emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1492 last = gen_divsi3_i1 (operands[0], operands[3]);
1493 }
1494 first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1495 emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1496 last = emit_insn (last);
1497 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1498 invariant code motion can move it. */
1499 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1500 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1501 DONE;
1502 }")
1503 \f
1504 ;; -------------------------------------------------------------------------
1505 ;; Multiplication instructions
1506 ;; -------------------------------------------------------------------------
1507
1508 (define_insn "umulhisi3_i"
1509 [(set (reg:SI MACL_REG)
1510 (mult:SI (zero_extend:SI
1511 (match_operand:HI 0 "arith_reg_operand" "r"))
1512 (zero_extend:SI
1513 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1514 "TARGET_SH1"
1515 "mulu.w %1,%0"
1516 [(set_attr "type" "smpy")])
1517
1518 (define_insn "mulhisi3_i"
1519 [(set (reg:SI MACL_REG)
1520 (mult:SI (sign_extend:SI
1521 (match_operand:HI 0 "arith_reg_operand" "r"))
1522 (sign_extend:SI
1523 (match_operand:HI 1 "arith_reg_operand" "r"))))]
1524 "TARGET_SH1"
1525 "muls.w %1,%0"
1526 [(set_attr "type" "smpy")])
1527
1528 (define_expand "mulhisi3"
1529 [(set (reg:SI MACL_REG)
1530 (mult:SI (sign_extend:SI
1531 (match_operand:HI 1 "arith_reg_operand" ""))
1532 (sign_extend:SI
1533 (match_operand:HI 2 "arith_reg_operand" ""))))
1534 (set (match_operand:SI 0 "arith_reg_operand" "")
1535 (reg:SI MACL_REG))]
1536 "TARGET_SH1"
1537 "
1538 {
1539 rtx first, last;
1540
1541 first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1542 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1543 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1544 invariant code motion can move it. */
1545 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1546 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1547 /* expand_binop can't find a suitable code in umul_widen_optab to
1548 make a REG_EQUAL note from, so make one here.
1549 See also smulsi3_highpart.
1550 ??? Alternatively, we could put this at the calling site of expand_binop,
1551 i.e. expand_expr. */
1552 REG_NOTES (last)
1553 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1554 REG_NOTES (last));
1555 DONE;
1556 }")
1557
1558 (define_expand "umulhisi3"
1559 [(set (reg:SI MACL_REG)
1560 (mult:SI (zero_extend:SI
1561 (match_operand:HI 1 "arith_reg_operand" ""))
1562 (zero_extend:SI
1563 (match_operand:HI 2 "arith_reg_operand" ""))))
1564 (set (match_operand:SI 0 "arith_reg_operand" "")
1565 (reg:SI MACL_REG))]
1566 "TARGET_SH1"
1567 "
1568 {
1569 rtx first, last;
1570
1571 first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1572 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1573 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1574 invariant code motion can move it. */
1575 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1576 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1577 /* expand_binop can't find a suitable code in umul_widen_optab to
1578 make a REG_EQUAL note from, so make one here.
1579 See also smulsi3_highpart.
1580 ??? Alternatively, we could put this at the calling site of expand_binop,
1581 i.e. expand_expr. */
1582 REG_NOTES (last)
1583 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1584 REG_NOTES (last));
1585 DONE;
1586 }")
1587
1588 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1589 ;; a call to a routine which clobbers known registers.
1590
1591 (define_insn ""
1592 [(set (match_operand:SI 1 "register_operand" "=z")
1593 (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1594 (clobber (reg:SI MACL_REG))
1595 (clobber (reg:SI T_REG))
1596 (clobber (reg:SI PR_REG))
1597 (clobber (reg:SI R3_REG))
1598 (clobber (reg:SI R2_REG))
1599 (clobber (reg:SI R1_REG))
1600 (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1601 "TARGET_SH1"
1602 "jsr @%0%#"
1603 [(set_attr "type" "sfunc")
1604 (set_attr "needs_delay_slot" "yes")])
1605
1606 (define_expand "mulsi3_call"
1607 [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1608 (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1609 (parallel[(set (match_operand:SI 0 "register_operand" "")
1610 (mult:SI (reg:SI R4_REG)
1611 (reg:SI R5_REG)))
1612 (clobber (reg:SI MACL_REG))
1613 (clobber (reg:SI T_REG))
1614 (clobber (reg:SI PR_REG))
1615 (clobber (reg:SI R3_REG))
1616 (clobber (reg:SI R2_REG))
1617 (clobber (reg:SI R1_REG))
1618 (use (match_operand:SI 3 "register_operand" ""))])]
1619 "TARGET_SH1"
1620 "")
1621
1622 (define_insn "mul_r"
1623 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1624 (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1625 (match_operand:SI 2 "arith_reg_operand" "z")))]
1626 "TARGET_SH2A"
1627 "mulr %2,%0"
1628 [(set_attr "type" "dmpy")])
1629
1630 (define_insn "mul_l"
1631 [(set (reg:SI MACL_REG)
1632 (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1633 (match_operand:SI 1 "arith_reg_operand" "r")))]
1634 "TARGET_SH2"
1635 "mul.l %1,%0"
1636 [(set_attr "type" "dmpy")])
1637
1638 (define_expand "mulsi3"
1639 [(set (reg:SI MACL_REG)
1640 (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
1641 (match_operand:SI 2 "arith_reg_operand" "")))
1642 (set (match_operand:SI 0 "arith_reg_operand" "")
1643 (reg:SI MACL_REG))]
1644 "TARGET_SH1"
1645 "
1646 {
1647 rtx first, last;
1648
1649 if (!TARGET_SH2)
1650 {
1651 /* The address must be set outside the libcall,
1652 since it goes into a pseudo. */
1653 rtx sym = function_symbol (\"__mulsi3\");
1654 rtx addr = force_reg (SImode, sym);
1655 rtx insns = gen_mulsi3_call (operands[0], operands[1],
1656 operands[2], addr);
1657 first = insns;
1658 last = emit_insn (insns);
1659 }
1660 else
1661 {
1662 rtx macl = gen_rtx_REG (SImode, MACL_REG);
1663
1664 first = emit_insn (gen_mul_l (operands[1], operands[2]));
1665 /* consec_sets_giv can only recognize the first insn that sets a
1666 giv as the giv insn. So we must tag this also with a REG_EQUAL
1667 note. */
1668 last = emit_insn (gen_movsi_i ((operands[0]), macl));
1669 }
1670 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1671 invariant code motion can move it. */
1672 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1673 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1674 DONE;
1675 }")
1676
1677 (define_insn "mulsidi3_i"
1678 [(set (reg:SI MACH_REG)
1679 (truncate:SI
1680 (lshiftrt:DI
1681 (mult:DI
1682 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1683 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1684 (const_int 32))))
1685 (set (reg:SI MACL_REG)
1686 (mult:SI (match_dup 0)
1687 (match_dup 1)))]
1688 "TARGET_SH2"
1689 "dmuls.l %1,%0"
1690 [(set_attr "type" "dmpy")])
1691
1692 (define_expand "mulsidi3"
1693 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1694 (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1695 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1696 "TARGET_SH2 || TARGET_SHMEDIA"
1697 "
1698 {
1699 if (TARGET_SH2)
1700 {
1701 emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1702 operands[2]));
1703 DONE;
1704 }
1705 }")
1706
1707 (define_insn "mulsidi3_media"
1708 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1709 (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1710 (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1711 "TARGET_SHMEDIA"
1712 "muls.l %1, %2, %0"
1713 [(set_attr "type" "dmpy_media")])
1714
1715 (define_insn "mulsidi3_compact"
1716 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1717 (mult:DI
1718 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1719 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1720 (clobber (reg:SI MACH_REG))
1721 (clobber (reg:SI MACL_REG))]
1722 "TARGET_SH2"
1723 "#")
1724
1725 (define_split
1726 [(set (match_operand:DI 0 "arith_reg_operand" "")
1727 (mult:DI
1728 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1729 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1730 (clobber (reg:SI MACH_REG))
1731 (clobber (reg:SI MACL_REG))]
1732 "TARGET_SH2"
1733 [(const_int 0)]
1734 "
1735 {
1736 rtx low_dst = gen_lowpart (SImode, operands[0]);
1737 rtx high_dst = gen_highpart (SImode, operands[0]);
1738
1739 emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1740
1741 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1742 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1743 /* We need something to tag the possible REG_EQUAL notes on to. */
1744 emit_move_insn (operands[0], operands[0]);
1745 DONE;
1746 }")
1747
1748 (define_insn "umulsidi3_i"
1749 [(set (reg:SI MACH_REG)
1750 (truncate:SI
1751 (lshiftrt:DI
1752 (mult:DI
1753 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1754 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1755 (const_int 32))))
1756 (set (reg:SI MACL_REG)
1757 (mult:SI (match_dup 0)
1758 (match_dup 1)))]
1759 "TARGET_SH2"
1760 "dmulu.l %1,%0"
1761 [(set_attr "type" "dmpy")])
1762
1763 (define_expand "umulsidi3"
1764 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1765 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1766 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1767 "TARGET_SH2 || TARGET_SHMEDIA"
1768 "
1769 {
1770 if (TARGET_SH2)
1771 {
1772 emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1773 operands[2]));
1774 DONE;
1775 }
1776 }")
1777
1778 (define_insn "umulsidi3_media"
1779 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1780 (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1781 (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1782 "TARGET_SHMEDIA"
1783 "mulu.l %1, %2, %0"
1784 [(set_attr "type" "dmpy_media")])
1785
1786 (define_insn "umulsidi3_compact"
1787 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1788 (mult:DI
1789 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1790 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1791 (clobber (reg:SI MACH_REG))
1792 (clobber (reg:SI MACL_REG))]
1793 "TARGET_SH2"
1794 "#")
1795
1796 (define_split
1797 [(set (match_operand:DI 0 "arith_reg_operand" "")
1798 (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1799 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1800 (clobber (reg:SI MACH_REG))
1801 (clobber (reg:SI MACL_REG))]
1802 "TARGET_SH2"
1803 [(const_int 0)]
1804 "
1805 {
1806 rtx low_dst = gen_lowpart (SImode, operands[0]);
1807 rtx high_dst = gen_highpart (SImode, operands[0]);
1808
1809 emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1810
1811 emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1812 emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1813 /* We need something to tag the possible REG_EQUAL notes on to. */
1814 emit_move_insn (operands[0], operands[0]);
1815 DONE;
1816 }")
1817
1818 (define_insn "smulsi3_highpart_i"
1819 [(set (reg:SI MACH_REG)
1820 (truncate:SI
1821 (lshiftrt:DI
1822 (mult:DI
1823 (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1824 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1825 (const_int 32))))
1826 (clobber (reg:SI MACL_REG))]
1827 "TARGET_SH2"
1828 "dmuls.l %1,%0"
1829 [(set_attr "type" "dmpy")])
1830
1831 (define_expand "smulsi3_highpart"
1832 [(parallel
1833 [(set (reg:SI MACH_REG)
1834 (truncate:SI
1835 (lshiftrt:DI
1836 (mult:DI
1837 (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1838 (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1839 (const_int 32))))
1840 (clobber (reg:SI MACL_REG))])
1841 (set (match_operand:SI 0 "arith_reg_operand" "")
1842 (reg:SI MACH_REG))]
1843 "TARGET_SH2"
1844 "
1845 {
1846 rtx first, last;
1847
1848 first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1849 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1850 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1851 invariant code motion can move it. */
1852 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1853 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1854 /* expand_binop can't find a suitable code in mul_highpart_optab to
1855 make a REG_EQUAL note from, so make one here.
1856 See also {,u}mulhisi.
1857 ??? Alternatively, we could put this at the calling site of expand_binop,
1858 i.e. expand_mult_highpart. */
1859 REG_NOTES (last)
1860 = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1861 REG_NOTES (last));
1862 DONE;
1863 }")
1864
1865 (define_insn "umulsi3_highpart_i"
1866 [(set (reg:SI MACH_REG)
1867 (truncate:SI
1868 (lshiftrt:DI
1869 (mult:DI
1870 (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1871 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1872 (const_int 32))))
1873 (clobber (reg:SI MACL_REG))]
1874 "TARGET_SH2"
1875 "dmulu.l %1,%0"
1876 [(set_attr "type" "dmpy")])
1877
1878 (define_expand "umulsi3_highpart"
1879 [(parallel
1880 [(set (reg:SI MACH_REG)
1881 (truncate:SI
1882 (lshiftrt:DI
1883 (mult:DI
1884 (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1885 (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1886 (const_int 32))))
1887 (clobber (reg:SI MACL_REG))])
1888 (set (match_operand:SI 0 "arith_reg_operand" "")
1889 (reg:SI MACH_REG))]
1890 "TARGET_SH2"
1891 "
1892 {
1893 rtx first, last;
1894
1895 first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1896 last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1897 /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1898 invariant code motion can move it. */
1899 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1900 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1901 DONE;
1902 }")
1903 \f
1904 ;; -------------------------------------------------------------------------
1905 ;; Logical operations
1906 ;; -------------------------------------------------------------------------
1907
1908 (define_insn "*andsi3_compact"
1909 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1910 (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1911 (match_operand:SI 2 "logical_operand" "r,K08")))]
1912 "TARGET_SH1"
1913 "and %2,%0"
1914 [(set_attr "type" "arith")])
1915
1916 ;; If the constant is 255, then emit an extu.b instruction instead of an
1917 ;; and, since that will give better code.
1918
1919 (define_expand "andsi3"
1920 [(set (match_operand:SI 0 "arith_reg_operand" "")
1921 (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1922 (match_operand:SI 2 "logical_operand" "")))]
1923 "TARGET_SH1"
1924 "
1925 {
1926 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1927 {
1928 emit_insn (gen_zero_extendqisi2 (operands[0],
1929 gen_lowpart (QImode, operands[1])));
1930 DONE;
1931 }
1932 }")
1933
1934 (define_insn_and_split "anddi3"
1935 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1936 (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1937 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1938 "TARGET_SHMEDIA"
1939 "@
1940 and %1, %2, %0
1941 andi %1, %2, %0
1942 #"
1943 "reload_completed
1944 && ! logical_operand (operands[2], DImode)"
1945 [(const_int 0)]
1946 "
1947 {
1948 if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1949 emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1950 else
1951 emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1952 DONE;
1953 }"
1954 [(set_attr "type" "arith_media")])
1955
1956 (define_insn "andcdi3"
1957 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1958 (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1959 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1960 "TARGET_SHMEDIA"
1961 "andc %1,%2,%0"
1962 [(set_attr "type" "arith_media")])
1963
1964 (define_insn "iorsi3"
1965 [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1966 (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1967 (match_operand:SI 2 "logical_operand" "r,K08")))]
1968 "TARGET_SH1"
1969 "or %2,%0"
1970 [(set_attr "type" "arith")])
1971
1972 (define_insn "iordi3"
1973 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1974 (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1975 (match_operand:DI 2 "logical_operand" "r,I10")))]
1976 "TARGET_SHMEDIA"
1977 "@
1978 or %1, %2, %0
1979 ori %1, %2, %0"
1980 [(set_attr "type" "arith_media")])
1981
1982 (define_insn "xorsi3"
1983 [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1984 (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1985 (match_operand:SI 2 "logical_operand" "K08,r")))]
1986 "TARGET_SH1"
1987 "xor %2,%0"
1988 [(set_attr "type" "arith")])
1989
1990 (define_insn "xordi3"
1991 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1992 (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1993 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1994 "TARGET_SHMEDIA"
1995 "@
1996 xor %1, %2, %0
1997 xori %1, %2, %0"
1998 [(set_attr "type" "arith_media")])
1999
2000 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2001 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2002 (define_split
2003 [(set (match_operand:DI 0 "arith_reg_operand" "")
2004 (sign_extend:DI (match_operator 4 "binary_logical_operator"
2005 [(match_operand 1 "any_register_operand" "")
2006 (match_operand 2 "any_register_operand" "")])))]
2007 "TARGET_SHMEDIA"
2008 [(set (match_dup 5) (match_dup 4))
2009 (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2010 "
2011 {
2012 enum machine_mode inmode = GET_MODE (operands[1]);
2013 int offset = 0;
2014
2015 if (GET_CODE (operands[0]) == SUBREG)
2016 {
2017 offset = SUBREG_BYTE (operands[0]);
2018 operands[0] = SUBREG_REG (operands[0]);
2019 }
2020 if (GET_CODE (operands[0]) != REG)
2021 abort ();
2022 if (! TARGET_LITTLE_ENDIAN)
2023 offset += 8 - GET_MODE_SIZE (inmode);
2024 operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2025 }")
2026 \f
2027 ;; -------------------------------------------------------------------------
2028 ;; Shifts and rotates
2029 ;; -------------------------------------------------------------------------
2030
2031 (define_expand "rotldi3"
2032 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2033 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2034 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2035 "TARGET_SHMEDIA"
2036 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2037
2038 (define_insn "rotldi3_mextr"
2039 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2040 (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2041 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2042 "TARGET_SHMEDIA"
2043 "*
2044 {
2045 static char templ[16];
2046
2047 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2048 8 - (int) (INTVAL (operands[2]) >> 3));
2049 return templ;
2050 }"
2051 [(set_attr "type" "arith_media")])
2052
2053 (define_expand "rotrdi3"
2054 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2055 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2056 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2057 "TARGET_SHMEDIA"
2058 "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2059
2060 (define_insn "rotrdi3_mextr"
2061 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2062 (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2063 (match_operand:HI 2 "mextr_bit_offset" "i")))]
2064 "TARGET_SHMEDIA"
2065 "*
2066 {
2067 static char templ[16];
2068
2069 sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2070 return templ;
2071 }"
2072 [(set_attr "type" "arith_media")])
2073
2074 (define_insn "rotlsi3_1"
2075 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2076 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2077 (const_int 1)))
2078 (set (reg:SI T_REG)
2079 (lshiftrt:SI (match_dup 1) (const_int 31)))]
2080 "TARGET_SH1"
2081 "rotl %0"
2082 [(set_attr "type" "arith")])
2083
2084 (define_insn "rotlsi3_31"
2085 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2086 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2087 (const_int 31)))
2088 (clobber (reg:SI T_REG))]
2089 "TARGET_SH1"
2090 "rotr %0"
2091 [(set_attr "type" "arith")])
2092
2093 (define_insn "rotlsi3_16"
2094 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2095 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2096 (const_int 16)))]
2097 "TARGET_SH1"
2098 "swap.w %1,%0"
2099 [(set_attr "type" "arith")])
2100
2101 (define_expand "rotlsi3"
2102 [(set (match_operand:SI 0 "arith_reg_operand" "")
2103 (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2104 (match_operand:SI 2 "immediate_operand" "")))]
2105 "TARGET_SH1"
2106 "
2107 {
2108 static const char rot_tab[] = {
2109 000, 000, 000, 000, 000, 000, 010, 001,
2110 001, 001, 011, 013, 003, 003, 003, 003,
2111 003, 003, 003, 003, 003, 013, 012, 002,
2112 002, 002, 010, 000, 000, 000, 000, 000,
2113 };
2114
2115 int count, choice;
2116
2117 if (GET_CODE (operands[2]) != CONST_INT)
2118 FAIL;
2119 count = INTVAL (operands[2]);
2120 choice = rot_tab[count];
2121 if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2122 FAIL;
2123 choice &= 7;
2124 switch (choice)
2125 {
2126 case 0:
2127 emit_move_insn (operands[0], operands[1]);
2128 count -= (count & 16) * 2;
2129 break;
2130 case 3:
2131 emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2132 count -= 16;
2133 break;
2134 case 1:
2135 case 2:
2136 {
2137 rtx parts[2];
2138 parts[0] = gen_reg_rtx (SImode);
2139 parts[1] = gen_reg_rtx (SImode);
2140 emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2141 emit_move_insn (parts[choice-1], operands[1]);
2142 emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2143 emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2144 emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2145 count = (count & ~16) - 8;
2146 }
2147 }
2148
2149 for (; count > 0; count--)
2150 emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2151 for (; count < 0; count++)
2152 emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2153
2154 DONE;
2155 }")
2156
2157 (define_insn "*rotlhi3_8"
2158 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2159 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2160 (const_int 8)))]
2161 "TARGET_SH1"
2162 "swap.b %1,%0"
2163 [(set_attr "type" "arith")])
2164
2165 (define_expand "rotlhi3"
2166 [(set (match_operand:HI 0 "arith_reg_operand" "")
2167 (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2168 (match_operand:HI 2 "immediate_operand" "")))]
2169 "TARGET_SH1"
2170 "
2171 {
2172 if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2173 FAIL;
2174 }")
2175
2176 ;;
2177 ;; shift left
2178
2179 (define_insn "ashlsi3_sh2a"
2180 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2181 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2182 (match_operand:SI 2 "arith_reg_operand" "r")))]
2183 "TARGET_SH2A"
2184 "shad %2,%0"
2185 [(set_attr "type" "arith")
2186 (set_attr "length" "4")])
2187
2188 ;; This pattern is used by init_expmed for computing the costs of shift
2189 ;; insns.
2190
2191 (define_insn_and_split "ashlsi3_std"
2192 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2193 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2194 (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2195 (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2196 "TARGET_SH3
2197 || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2198 && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2199 "@
2200 shld %2,%0
2201 add %0,%0
2202 shll%O2 %0
2203 #"
2204 "TARGET_SH3
2205 && reload_completed
2206 && GET_CODE (operands[2]) == CONST_INT
2207 && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2208 [(set (match_dup 3) (match_dup 2))
2209 (parallel
2210 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2211 (clobber (match_dup 4))])]
2212 "operands[4] = gen_rtx_SCRATCH (SImode);"
2213 [(set_attr "length" "*,*,*,4")
2214 (set_attr "type" "dyn_shift,arith,arith,arith")])
2215
2216 (define_insn "ashlhi3_k"
2217 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2218 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2219 (match_operand:HI 2 "const_int_operand" "M,P27")))]
2220 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2221 "@
2222 add %0,%0
2223 shll%O2 %0"
2224 [(set_attr "type" "arith")])
2225
2226 (define_insn "ashlsi3_n"
2227 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2228 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2229 (match_operand:SI 2 "const_int_operand" "n")))
2230 (clobber (reg:SI T_REG))]
2231 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2232 "#"
2233 [(set (attr "length")
2234 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2235 (const_string "2")
2236 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2237 (const_string "4")
2238 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2239 (const_string "6")]
2240 (const_string "8")))
2241 (set_attr "type" "arith")])
2242
2243 (define_split
2244 [(set (match_operand:SI 0 "arith_reg_operand" "")
2245 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2246 (match_operand:SI 2 "const_int_operand" "")))
2247 (clobber (reg:SI T_REG))]
2248 "TARGET_SH1 && reload_completed"
2249 [(use (reg:SI R0_REG))]
2250 "
2251 {
2252 gen_shifty_op (ASHIFT, operands);
2253 DONE;
2254 }")
2255
2256 (define_insn "ashlsi3_media"
2257 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2258 (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2259 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2260 "TARGET_SHMEDIA"
2261 "@
2262 shlld.l %1, %2, %0
2263 shlli.l %1, %2, %0"
2264 [(set_attr "type" "arith_media")])
2265
2266 (define_expand "ashlsi3"
2267 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2268 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2269 (match_operand:SI 2 "nonmemory_operand" "")))
2270 (clobber (reg:SI T_REG))])]
2271 ""
2272 "
2273 {
2274 if (TARGET_SHMEDIA)
2275 {
2276 emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2277 DONE;
2278 }
2279 if (GET_CODE (operands[2]) == CONST_INT
2280 && sh_dynamicalize_shift_p (operands[2]))
2281 operands[2] = force_reg (SImode, operands[2]);
2282 if (TARGET_SH3)
2283 {
2284 emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2285 DONE;
2286 }
2287 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2288 FAIL;
2289 }")
2290
2291 (define_insn "ashlhi3"
2292 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2293 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2294 (match_operand:HI 2 "const_int_operand" "n")))
2295 (clobber (reg:SI T_REG))]
2296 "TARGET_SH1"
2297 "#"
2298 [(set (attr "length")
2299 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2300 (const_string "2")
2301 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2302 (const_string "4")]
2303 (const_string "6")))
2304 (set_attr "type" "arith")])
2305
2306 (define_split
2307 [(set (match_operand:HI 0 "arith_reg_operand" "")
2308 (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2309 (match_operand:HI 2 "const_int_operand" "")))
2310 (clobber (reg:SI T_REG))]
2311 "TARGET_SH1 && reload_completed"
2312 [(use (reg:SI R0_REG))]
2313 "
2314 {
2315 gen_shifty_hi_op (ASHIFT, operands);
2316 DONE;
2317 }")
2318
2319 ;
2320 ; arithmetic shift right
2321 ;
2322
2323 (define_insn "ashrsi3_sh2a"
2324 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2325 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2326 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2327 "TARGET_SH2A"
2328 "shad %2,%0"
2329 [(set_attr "type" "dyn_shift")
2330 (set_attr "length" "4")])
2331
2332 (define_insn "ashrsi3_k"
2333 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2334 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2335 (match_operand:SI 2 "const_int_operand" "M")))
2336 (clobber (reg:SI T_REG))]
2337 "TARGET_SH1 && INTVAL (operands[2]) == 1"
2338 "shar %0"
2339 [(set_attr "type" "arith")])
2340
2341 ;; We can't do HImode right shifts correctly unless we start out with an
2342 ;; explicit zero / sign extension; doing that would result in worse overall
2343 ;; code, so just let the machine independent code widen the mode.
2344 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2345
2346
2347 ;; ??? This should be a define expand.
2348
2349 (define_insn "ashrsi2_16"
2350 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2351 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2352 (const_int 16)))]
2353 "TARGET_SH1"
2354 "#"
2355 [(set_attr "length" "4")])
2356
2357 (define_split
2358 [(set (match_operand:SI 0 "arith_reg_operand" "")
2359 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2360 (const_int 16)))]
2361 "TARGET_SH1"
2362 [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2363 (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2364 "operands[2] = gen_lowpart (HImode, operands[0]);")
2365
2366 ;; ??? This should be a define expand.
2367
2368 (define_insn "ashrsi2_31"
2369 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2370 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2371 (const_int 31)))
2372 (clobber (reg:SI T_REG))]
2373 "TARGET_SH1"
2374 "#"
2375 [(set_attr "length" "4")])
2376
2377 (define_split
2378 [(set (match_operand:SI 0 "arith_reg_operand" "")
2379 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2380 (const_int 31)))
2381 (clobber (reg:SI T_REG))]
2382 "TARGET_SH1"
2383 [(const_int 0)]
2384 "
2385 {
2386 emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2387 emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2388 DONE;
2389 }")
2390
2391 (define_insn "ashlsi_c"
2392 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2393 (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2394 (set (reg:SI T_REG)
2395 (lt:SI (match_dup 1) (const_int 0)))]
2396 "TARGET_SH1"
2397 "shll %0"
2398 [(set_attr "type" "arith")])
2399
2400 (define_insn "ashrsi3_d"
2401 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2402 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2403 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2404 "TARGET_SH3"
2405 "shad %2,%0"
2406 [(set_attr "type" "dyn_shift")])
2407
2408 (define_insn "ashrsi3_n"
2409 [(set (reg:SI R4_REG)
2410 (ashiftrt:SI (reg:SI R4_REG)
2411 (match_operand:SI 0 "const_int_operand" "i")))
2412 (clobber (reg:SI T_REG))
2413 (clobber (reg:SI PR_REG))
2414 (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2415 "TARGET_SH1"
2416 "jsr @%1%#"
2417 [(set_attr "type" "sfunc")
2418 (set_attr "needs_delay_slot" "yes")])
2419
2420 (define_insn "ashrsi3_media"
2421 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2422 (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2423 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2424 "TARGET_SHMEDIA"
2425 "@
2426 shard.l %1, %2, %0
2427 shari.l %1, %2, %0"
2428 [(set_attr "type" "arith_media")])
2429
2430 (define_expand "ashrsi3"
2431 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2432 (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2433 (match_operand:SI 2 "nonmemory_operand" "")))
2434 (clobber (reg:SI T_REG))])]
2435 ""
2436 "
2437 {
2438 if (TARGET_SHMEDIA)
2439 {
2440 emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2441 DONE;
2442 }
2443 if (expand_ashiftrt (operands))
2444 DONE;
2445 else
2446 FAIL;
2447 }")
2448
2449 ;; logical shift right
2450
2451 (define_insn "lshrsi3_sh2a"
2452 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2453 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2454 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2455 "TARGET_SH2A"
2456 "shld %2,%0"
2457 [(set_attr "type" "dyn_shift")
2458 (set_attr "length" "4")])
2459
2460 (define_insn "lshrsi3_d"
2461 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2462 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2463 (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2464 "TARGET_SH3"
2465 "shld %2,%0"
2466 [(set_attr "type" "dyn_shift")])
2467
2468 ;; Only the single bit shift clobbers the T bit.
2469
2470 (define_insn "lshrsi3_m"
2471 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2472 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2473 (match_operand:SI 2 "const_int_operand" "M")))
2474 (clobber (reg:SI T_REG))]
2475 "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2476 "shlr %0"
2477 [(set_attr "type" "arith")])
2478
2479 (define_insn "lshrsi3_k"
2480 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2481 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2482 (match_operand:SI 2 "const_int_operand" "P27")))]
2483 "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2484 && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2485 "shlr%O2 %0"
2486 [(set_attr "type" "arith")])
2487
2488 (define_insn "lshrsi3_n"
2489 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2490 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2491 (match_operand:SI 2 "const_int_operand" "n")))
2492 (clobber (reg:SI T_REG))]
2493 "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2494 "#"
2495 [(set (attr "length")
2496 (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2497 (const_string "2")
2498 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2499 (const_string "4")
2500 (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2501 (const_string "6")]
2502 (const_string "8")))
2503 (set_attr "type" "arith")])
2504
2505 (define_split
2506 [(set (match_operand:SI 0 "arith_reg_operand" "")
2507 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2508 (match_operand:SI 2 "const_int_operand" "")))
2509 (clobber (reg:SI T_REG))]
2510 "TARGET_SH1 && reload_completed"
2511 [(use (reg:SI R0_REG))]
2512 "
2513 {
2514 gen_shifty_op (LSHIFTRT, operands);
2515 DONE;
2516 }")
2517
2518 (define_insn "lshrsi3_media"
2519 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2520 (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2521 (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2522 "TARGET_SHMEDIA"
2523 "@
2524 shlrd.l %1, %2, %0
2525 shlri.l %1, %2, %0"
2526 [(set_attr "type" "arith_media")])
2527
2528 (define_expand "lshrsi3"
2529 [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2530 (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2531 (match_operand:SI 2 "nonmemory_operand" "")))
2532 (clobber (reg:SI T_REG))])]
2533 ""
2534 "
2535 {
2536 if (TARGET_SHMEDIA)
2537 {
2538 emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2539 DONE;
2540 }
2541 if (GET_CODE (operands[2]) == CONST_INT
2542 && sh_dynamicalize_shift_p (operands[2]))
2543 operands[2] = force_reg (SImode, operands[2]);
2544 if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2545 {
2546 rtx count = copy_to_mode_reg (SImode, operands[2]);
2547 emit_insn (gen_negsi2 (count, count));
2548 emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2549 DONE;
2550 }
2551 if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2552 FAIL;
2553 }")
2554
2555 ;; ??? This should be a define expand.
2556
2557 (define_insn "ashldi3_k"
2558 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2559 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2560 (const_int 1)))
2561 (clobber (reg:SI T_REG))]
2562 "TARGET_SH1"
2563 "shll %R0\;rotcl %S0"
2564 [(set_attr "length" "4")
2565 (set_attr "type" "arith")])
2566
2567 (define_insn "ashldi3_media"
2568 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2569 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2570 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2571 "TARGET_SHMEDIA"
2572 "@
2573 shlld %1, %2, %0
2574 shlli %1, %2, %0"
2575 [(set_attr "type" "arith_media")])
2576
2577 (define_expand "ashldi3"
2578 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2579 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2580 (match_operand:DI 2 "immediate_operand" "")))
2581 (clobber (reg:SI T_REG))])]
2582 ""
2583 "
2584 {
2585 if (TARGET_SHMEDIA)
2586 {
2587 emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2588 DONE;
2589 }
2590 if (GET_CODE (operands[2]) != CONST_INT
2591 || INTVAL (operands[2]) != 1)
2592 FAIL;
2593 }")
2594
2595 ;; ??? This should be a define expand.
2596
2597 (define_insn "lshrdi3_k"
2598 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2599 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2600 (const_int 1)))
2601 (clobber (reg:SI T_REG))]
2602 "TARGET_SH1"
2603 "shlr %S0\;rotcr %R0"
2604 [(set_attr "length" "4")
2605 (set_attr "type" "arith")])
2606
2607 (define_insn "lshrdi3_media"
2608 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2609 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2610 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2611 "TARGET_SHMEDIA"
2612 "@
2613 shlrd %1, %2, %0
2614 shlri %1, %2, %0"
2615 [(set_attr "type" "arith_media")])
2616
2617 (define_expand "lshrdi3"
2618 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2619 (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2620 (match_operand:DI 2 "immediate_operand" "")))
2621 (clobber (reg:SI T_REG))])]
2622 ""
2623 "
2624 {
2625 if (TARGET_SHMEDIA)
2626 {
2627 emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2628 DONE;
2629 }
2630 if (GET_CODE (operands[2]) != CONST_INT
2631 || INTVAL (operands[2]) != 1)
2632 FAIL;
2633 }")
2634
2635 ;; ??? This should be a define expand.
2636
2637 (define_insn "ashrdi3_k"
2638 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2639 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2640 (const_int 1)))
2641 (clobber (reg:SI T_REG))]
2642 "TARGET_SH1"
2643 "shar %S0\;rotcr %R0"
2644 [(set_attr "length" "4")
2645 (set_attr "type" "arith")])
2646
2647 (define_insn "ashrdi3_media"
2648 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2649 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2650 (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2651 "TARGET_SHMEDIA"
2652 "@
2653 shard %1, %2, %0
2654 shari %1, %2, %0"
2655 [(set_attr "type" "arith_media")])
2656
2657 (define_expand "ashrdi3"
2658 [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2659 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2660 (match_operand:DI 2 "immediate_operand" "")))
2661 (clobber (reg:SI T_REG))])]
2662 ""
2663 "
2664 {
2665 if (TARGET_SHMEDIA)
2666 {
2667 emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2668 DONE;
2669 }
2670 if (GET_CODE (operands[2]) != CONST_INT
2671 || INTVAL (operands[2]) != 1)
2672 FAIL;
2673 }")
2674
2675 ;; combined left/right shift
2676
2677 (define_split
2678 [(set (match_operand:SI 0 "register_operand" "")
2679 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2680 (match_operand:SI 2 "const_int_operand" ""))
2681 (match_operand:SI 3 "const_int_operand" "")))]
2682 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2683 [(use (reg:SI R0_REG))]
2684 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2685 DONE;")
2686
2687 (define_split
2688 [(set (match_operand:SI 0 "register_operand" "")
2689 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2690 (match_operand:SI 2 "const_int_operand" ""))
2691 (match_operand:SI 3 "const_int_operand" "")))
2692 (clobber (reg:SI T_REG))]
2693 "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2694 [(use (reg:SI R0_REG))]
2695 "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2696 DONE;")
2697
2698 (define_insn ""
2699 [(set (match_operand:SI 0 "register_operand" "=r")
2700 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2701 (match_operand:SI 2 "const_int_operand" "n"))
2702 (match_operand:SI 3 "const_int_operand" "n")))
2703 (clobber (reg:SI T_REG))]
2704 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2705 "#"
2706 [(set (attr "length")
2707 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2708 (const_string "4")
2709 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2710 (const_string "6")
2711 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2712 (const_string "8")
2713 (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2714 (const_string "10")
2715 (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2716 (const_string "12")
2717 (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2718 (const_string "14")
2719 (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2720 (const_string "16")]
2721 (const_string "18")))
2722 (set_attr "type" "arith")])
2723
2724 (define_insn ""
2725 [(set (match_operand:SI 0 "register_operand" "=z")
2726 (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2727 (match_operand:SI 2 "const_int_operand" "n"))
2728 (match_operand:SI 3 "const_int_operand" "n")))
2729 (clobber (reg:SI T_REG))]
2730 "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2731 "#"
2732 [(set (attr "length")
2733 (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2734 (const_string "4")
2735 (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2736 (const_string "6")
2737 (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2738 (const_string "8")]
2739 (const_string "10")))
2740 (set_attr "type" "arith")])
2741
2742 ;; shift left / and combination with a scratch register: The combine pass
2743 ;; does not accept the individual instructions, even though they are
2744 ;; cheap. But it needs a precise description so that it is usable after
2745 ;; reload.
2746 (define_insn "and_shl_scratch"
2747 [(set (match_operand:SI 0 "register_operand" "=r,&r")
2748 (lshiftrt:SI
2749 (ashift:SI
2750 (and:SI
2751 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2752 (match_operand:SI 2 "const_int_operand" "N,n"))
2753 (match_operand:SI 3 "" "0,r"))
2754 (match_operand:SI 4 "const_int_operand" "n,n"))
2755 (match_operand:SI 5 "const_int_operand" "n,n")))
2756 (clobber (reg:SI T_REG))]
2757 "TARGET_SH1"
2758 "#"
2759 [(set (attr "length")
2760 (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2761 (const_string "4")
2762 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2763 (const_string "6")
2764 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2765 (const_string "8")
2766 (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2767 (const_string "10")]
2768 (const_string "12")))
2769 (set_attr "type" "arith")])
2770
2771 (define_split
2772 [(set (match_operand:SI 0 "register_operand" "")
2773 (lshiftrt:SI
2774 (ashift:SI
2775 (and:SI
2776 (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2777 (match_operand:SI 2 "const_int_operand" ""))
2778 (match_operand:SI 3 "register_operand" ""))
2779 (match_operand:SI 4 "const_int_operand" ""))
2780 (match_operand:SI 5 "const_int_operand" "")))
2781 (clobber (reg:SI T_REG))]
2782 "TARGET_SH1"
2783 [(use (reg:SI R0_REG))]
2784 "
2785 {
2786 rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2787
2788 if (INTVAL (operands[2]))
2789 {
2790 gen_shifty_op (LSHIFTRT, operands);
2791 }
2792 emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2793 operands[2] = operands[4];
2794 gen_shifty_op (ASHIFT, operands);
2795 if (INTVAL (operands[5]))
2796 {
2797 operands[2] = operands[5];
2798 gen_shifty_op (LSHIFTRT, operands);
2799 }
2800 DONE;
2801 }")
2802
2803 ;; signed left/right shift combination.
2804 (define_split
2805 [(set (match_operand:SI 0 "register_operand" "")
2806 (sign_extract:SI
2807 (ashift:SI (match_operand:SI 1 "register_operand" "")
2808 (match_operand:SI 2 "const_int_operand" ""))
2809 (match_operand:SI 3 "const_int_operand" "")
2810 (const_int 0)))
2811 (clobber (reg:SI T_REG))]
2812 "TARGET_SH1"
2813 [(use (reg:SI R0_REG))]
2814 "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2815 DONE;")
2816
2817 (define_insn "shl_sext_ext"
2818 [(set (match_operand:SI 0 "register_operand" "=r")
2819 (sign_extract:SI
2820 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2821 (match_operand:SI 2 "const_int_operand" "n"))
2822 (match_operand:SI 3 "const_int_operand" "n")
2823 (const_int 0)))
2824 (clobber (reg:SI T_REG))]
2825 "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2826 "#"
2827 [(set (attr "length")
2828 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2829 (const_string "2")
2830 (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2831 (const_string "4")
2832 (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2833 (const_string "6")
2834 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2835 (const_string "8")
2836 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2837 (const_string "10")
2838 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2839 (const_string "12")
2840 (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2841 (const_string "14")
2842 (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2843 (const_string "16")]
2844 (const_string "18")))
2845 (set_attr "type" "arith")])
2846
2847 (define_insn "shl_sext_sub"
2848 [(set (match_operand:SI 0 "register_operand" "=z")
2849 (sign_extract:SI
2850 (ashift:SI (match_operand:SI 1 "register_operand" "0")
2851 (match_operand:SI 2 "const_int_operand" "n"))
2852 (match_operand:SI 3 "const_int_operand" "n")
2853 (const_int 0)))
2854 (clobber (reg:SI T_REG))]
2855 "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2856 "#"
2857 [(set (attr "length")
2858 (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2859 (const_string "6")
2860 (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2861 (const_string "8")
2862 (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2863 (const_string "10")
2864 (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2865 (const_string "12")]
2866 (const_string "14")))
2867 (set_attr "type" "arith")])
2868
2869 ;; These patterns are found in expansions of DImode shifts by 16, and
2870 ;; allow the xtrct instruction to be generated from C source.
2871
2872 (define_insn "xtrct_left"
2873 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2874 (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2875 (const_int 16))
2876 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2877 (const_int 16))))]
2878 "TARGET_SH1"
2879 "xtrct %1,%0"
2880 [(set_attr "type" "arith")])
2881
2882 (define_insn "xtrct_right"
2883 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2884 (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2885 (const_int 16))
2886 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2887 (const_int 16))))]
2888 "TARGET_SH1"
2889 "xtrct %2,%0"
2890 [(set_attr "type" "arith")])
2891
2892 ;; -------------------------------------------------------------------------
2893 ;; Unary arithmetic
2894 ;; -------------------------------------------------------------------------
2895
2896 (define_insn "negc"
2897 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2898 (neg:SI (plus:SI (reg:SI T_REG)
2899 (match_operand:SI 1 "arith_reg_operand" "r"))))
2900 (set (reg:SI T_REG)
2901 (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2902 (const_int 0)))]
2903 "TARGET_SH1"
2904 "negc %1,%0"
2905 [(set_attr "type" "arith")])
2906
2907 (define_insn "*negdi_media"
2908 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2909 (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2910 "TARGET_SHMEDIA"
2911 "sub r63, %1, %0"
2912 [(set_attr "type" "arith_media")])
2913
2914 (define_expand "negdi2"
2915 [(set (match_operand:DI 0 "arith_reg_operand" "")
2916 (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2917 ""
2918 "
2919 {
2920 if (TARGET_SH1)
2921 {
2922 int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2923 int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2924
2925 rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2926 rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2927
2928 rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2929 rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2930
2931 emit_insn (gen_clrt ());
2932 emit_insn (gen_negc (low_dst, low_src));
2933 emit_insn (gen_negc (high_dst, high_src));
2934 DONE;
2935 }
2936 }")
2937
2938 (define_insn "negsi2"
2939 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2940 (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2941 "TARGET_SH1"
2942 "neg %1,%0"
2943 [(set_attr "type" "arith")])
2944
2945 (define_insn "one_cmplsi2"
2946 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2947 (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2948 "TARGET_SH1"
2949 "not %1,%0"
2950 [(set_attr "type" "arith")])
2951
2952 (define_expand "one_cmpldi2"
2953 [(set (match_operand:DI 0 "arith_reg_operand" "")
2954 (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2955 (const_int -1)))]
2956 "TARGET_SHMEDIA" "")
2957 \f
2958 ;; -------------------------------------------------------------------------
2959 ;; Zero extension instructions
2960 ;; -------------------------------------------------------------------------
2961
2962 (define_insn "zero_extendsidi2"
2963 [(set (match_operand:DI 0 "register_operand" "=r")
2964 (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2965 "TARGET_SHMEDIA"
2966 "addz.l %1, r63, %0"
2967 [(set_attr "type" "arith_media")])
2968
2969 (define_insn "zero_extendhidi2"
2970 [(set (match_operand:DI 0 "register_operand" "=r,r")
2971 (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2972 "TARGET_SHMEDIA"
2973 "@
2974 #
2975 ld%M1.uw %m1, %0"
2976 [(set_attr "type" "*,load_media")])
2977
2978 (define_split
2979 [(set (match_operand:DI 0 "register_operand" "")
2980 (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2981 "TARGET_SHMEDIA && reload_completed"
2982 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2983 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2984 "
2985 {
2986 if (GET_CODE (operands[1]) == TRUNCATE)
2987 operands[1] = XEXP (operands[1], 0);
2988 }")
2989
2990 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2991 ;; reload the entire truncate expression.
2992 (define_insn_and_split "*loaddi_trunc"
2993 [(set (match_operand 0 "int_gpr_dest" "=r")
2994 (truncate (match_operand:DI 1 "memory_operand" "m")))]
2995 "TARGET_SHMEDIA && reload_completed"
2996 "#"
2997 "TARGET_SHMEDIA && reload_completed"
2998 [(set (match_dup 0) (match_dup 1))]
2999 "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3000
3001 (define_insn "zero_extendqidi2"
3002 [(set (match_operand:DI 0 "register_operand" "=r,r")
3003 (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3004 "TARGET_SHMEDIA"
3005 "@
3006 andi %1, 255, %0
3007 ld%M1.ub %m1, %0"
3008 [(set_attr "type" "arith_media,load_media")])
3009
3010 (define_expand "zero_extendhisi2"
3011 [(set (match_operand:SI 0 "arith_reg_operand" "")
3012 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3013 ""
3014 "
3015 {
3016 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3017 operands[1] = copy_to_mode_reg (HImode, operands[1]);
3018 }")
3019
3020 (define_insn "*zero_extendhisi2_compact"
3021 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3022 (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3023 "TARGET_SH1"
3024 "extu.w %1,%0"
3025 [(set_attr "type" "arith")])
3026
3027 (define_insn "*zero_extendhisi2_media"
3028 [(set (match_operand:SI 0 "register_operand" "=r,r")
3029 (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3030 "TARGET_SHMEDIA"
3031 "@
3032 #
3033 ld%M1.uw %m1, %0"
3034 [(set_attr "type" "arith_media,load_media")])
3035
3036 (define_split
3037 [(set (match_operand:SI 0 "register_operand" "")
3038 (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3039 "TARGET_SHMEDIA && reload_completed"
3040 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3041 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3042 "
3043 {
3044 if (GET_CODE (operands[1]) == TRUNCATE)
3045 operands[1] = XEXP (operands[1], 0);
3046 }")
3047
3048 (define_expand "zero_extendqisi2"
3049 [(set (match_operand:SI 0 "arith_reg_operand" "")
3050 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3051 ""
3052 "
3053 {
3054 if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3055 operands[1] = copy_to_mode_reg (QImode, operands[1]);
3056 }")
3057
3058 (define_insn "*zero_extendqisi2_compact"
3059 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3060 (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3061 "TARGET_SH1"
3062 "extu.b %1,%0"
3063 [(set_attr "type" "arith")])
3064
3065 (define_insn "*zero_extendqisi2_media"
3066 [(set (match_operand:SI 0 "register_operand" "=r,r")
3067 (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3068 "TARGET_SHMEDIA"
3069 "@
3070 andi %1, 255, %0
3071 ld%M1.ub %m1, %0"
3072 [(set_attr "type" "arith_media,load_media")])
3073
3074 (define_insn "zero_extendqihi2"
3075 [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3076 (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3077 "TARGET_SH1"
3078 "extu.b %1,%0"
3079 [(set_attr "type" "arith")])
3080
3081 ;; -------------------------------------------------------------------------
3082 ;; Sign extension instructions
3083 ;; -------------------------------------------------------------------------
3084
3085 ;; ??? This should be a define expand.
3086 ;; ??? Or perhaps it should be dropped?
3087
3088 ;; convert_move generates good code for SH[1-4].
3089 (define_insn "extendsidi2"
3090 [(set (match_operand:DI 0 "register_operand" "=r,r")
3091 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3092 "TARGET_SHMEDIA"
3093 "@
3094 add.l %1, r63, %0
3095 ld%M1.l %m1, %0"
3096 [(set_attr "type" "arith_media,load_media")])
3097
3098 (define_insn "extendhidi2"
3099 [(set (match_operand:DI 0 "register_operand" "=r,r")
3100 (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3101 "TARGET_SHMEDIA"
3102 "@
3103 #
3104 ld%M1.w %m1, %0"
3105 [(set_attr "type" "*,load_media")])
3106
3107 (define_split
3108 [(set (match_operand:DI 0 "register_operand" "")
3109 (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3110 "TARGET_SHMEDIA && reload_completed"
3111 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3112 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3113 "
3114 {
3115 if (GET_CODE (operands[1]) == TRUNCATE)
3116 operands[1] = XEXP (operands[1], 0);
3117 }")
3118
3119 (define_insn "extendqidi2"
3120 [(set (match_operand:DI 0 "register_operand" "=r,r")
3121 (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3122 "TARGET_SHMEDIA"
3123 "@
3124 #
3125 ld%M1.b %m1, %0"
3126 [(set_attr "type" "*,load_media")])
3127
3128 (define_split
3129 [(set (match_operand:DI 0 "register_operand" "")
3130 (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3131 "TARGET_SHMEDIA && reload_completed"
3132 [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3133 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3134 "
3135 {
3136 if (GET_CODE (operands[1]) == TRUNCATE)
3137 operands[1] = XEXP (operands[1], 0);
3138 }")
3139
3140 (define_expand "extendhisi2"
3141 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3142 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3143 ""
3144 "")
3145
3146 (define_insn "*extendhisi2_compact"
3147 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3148 (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3149 "TARGET_SH1"
3150 "@
3151 exts.w %1,%0
3152 mov.w %1,%0"
3153 [(set_attr "type" "arith,load")])
3154
3155 (define_insn "*extendhisi2_media"
3156 [(set (match_operand:SI 0 "register_operand" "=r,r")
3157 (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3158 "TARGET_SHMEDIA"
3159 "@
3160 #
3161 ld%M1.w %m1, %0"
3162 [(set_attr "type" "arith_media,load_media")])
3163
3164 (define_split
3165 [(set (match_operand:SI 0 "register_operand" "")
3166 (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3167 "TARGET_SHMEDIA && reload_completed"
3168 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3169 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3170 "
3171 {
3172 if (GET_CODE (operands[1]) == TRUNCATE)
3173 operands[1] = XEXP (operands[1], 0);
3174 }")
3175
3176 (define_expand "extendqisi2"
3177 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3178 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3179 ""
3180 "")
3181
3182 (define_insn "*extendqisi2_compact"
3183 [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3184 (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3185 "TARGET_SH1"
3186 "@
3187 exts.b %1,%0
3188 mov.b %1,%0"
3189 [(set_attr "type" "arith,load")])
3190
3191 (define_insn "*extendqisi2_media"
3192 [(set (match_operand:SI 0 "register_operand" "=r,r")
3193 (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3194 "TARGET_SHMEDIA"
3195 "@
3196 #
3197 ld%M1.b %m1, %0"
3198 [(set_attr "type" "arith_media,load_media")])
3199
3200 (define_split
3201 [(set (match_operand:SI 0 "register_operand" "")
3202 (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3203 "TARGET_SHMEDIA && reload_completed"
3204 [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3205 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3206 "
3207 {
3208 if (GET_CODE (operands[1]) == TRUNCATE)
3209 operands[1] = XEXP (operands[1], 0);
3210 }")
3211
3212 (define_insn "extendqihi2"
3213 [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3214 (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3215 "TARGET_SH1"
3216 "@
3217 exts.b %1,%0
3218 mov.b %1,%0"
3219 [(set_attr "type" "arith,load")])
3220
3221 /* It would seem useful to combine the truncXi patterns into the movXi
3222 patterns, but unary operators are ignored when matching constraints,
3223 so we need separate patterns. */
3224 (define_insn "truncdisi2"
3225 [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3226 (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3227 "TARGET_SHMEDIA"
3228 "@
3229 add.l %1, r63, %0
3230 st%M0.l %m0, %1
3231 fst%M0.s %m0, %T1
3232 fmov.ls %1, %0
3233 fmov.sl %T1, %0
3234 fmov.s %T1, %0"
3235 [(set_attr "type" "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3236
3237
3238 (define_insn "truncdihi2"
3239 [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3240 (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3241 "TARGET_SHMEDIA"
3242 "@
3243 shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3244 st%M0.w %m0, %1"
3245 [(set_attr "type" "arith_media,store_media")
3246 (set_attr "length" "8,4")])
3247
3248 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3249 ; Because we use zero extension, we can't provide signed QImode compares
3250 ; using a simple compare or conditional banch insn.
3251 (define_insn "truncdiqi2"
3252 [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3253 (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3254 "TARGET_SHMEDIA"
3255 "@
3256 andi %1, 255, %0
3257 st%M0.b %m0, %1"
3258 [(set_attr "type" "arith_media,store")])
3259
3260 ;; -------------------------------------------------------------------------
3261 ;; Move instructions
3262 ;; -------------------------------------------------------------------------
3263
3264 ;; define push and pop so it is easy for sh.c
3265 ;; We can't use push and pop on SHcompact because the stack must always
3266 ;; be 8-byte aligned.
3267
3268 (define_expand "push"
3269 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3270 (match_operand:SI 0 "register_operand" "r,l,x"))]
3271 "TARGET_SH1 && ! TARGET_SH5"
3272 "")
3273
3274 (define_expand "pop"
3275 [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3276 (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3277 "TARGET_SH1 && ! TARGET_SH5"
3278 "")
3279
3280 (define_expand "push_e"
3281 [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3282 (match_operand:SF 0 "" ""))
3283 (use (reg:PSI FPSCR_REG))
3284 (clobber (scratch:SI))])]
3285 "TARGET_SH1 && ! TARGET_SH5"
3286 "")
3287
3288 (define_insn "push_fpul"
3289 [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3290 "TARGET_SH2E && ! TARGET_SH5"
3291 "sts.l fpul,@-r15"
3292 [(set_attr "type" "store")
3293 (set_attr "late_fp_use" "yes")
3294 (set_attr "hit_stack" "yes")])
3295
3296 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3297 ;; so use that.
3298 (define_expand "push_4"
3299 [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3300 (match_operand:DF 0 "" ""))
3301 (use (reg:PSI FPSCR_REG))
3302 (clobber (scratch:SI))])]
3303 "TARGET_SH1 && ! TARGET_SH5"
3304 "")
3305
3306 (define_expand "pop_e"
3307 [(parallel [(set (match_operand:SF 0 "" "")
3308 (mem:SF (post_inc:SI (reg:SI SP_REG))))
3309 (use (reg:PSI FPSCR_REG))
3310 (clobber (scratch:SI))])]
3311 "TARGET_SH1 && ! TARGET_SH5"
3312 "")
3313
3314 (define_insn "pop_fpul"
3315 [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3316 "TARGET_SH2E && ! TARGET_SH5"
3317 "lds.l @r15+,fpul"
3318 [(set_attr "type" "load")
3319 (set_attr "hit_stack" "yes")])
3320
3321 (define_expand "pop_4"
3322 [(parallel [(set (match_operand:DF 0 "" "")
3323 (mem:DF (post_inc:SI (reg:SI SP_REG))))
3324 (use (reg:PSI FPSCR_REG))
3325 (clobber (scratch:SI))])]
3326 "TARGET_SH1 && ! TARGET_SH5"
3327 "")
3328
3329 (define_expand "push_fpscr"
3330 [(const_int 0)]
3331 "TARGET_SH2E"
3332 "
3333 {
3334 rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3335 gen_rtx_PRE_DEC (Pmode,
3336 stack_pointer_rtx)),
3337 get_fpscr_rtx ()));
3338 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3339 DONE;
3340 }")
3341
3342 (define_expand "pop_fpscr"
3343 [(const_int 0)]
3344 "TARGET_SH2E"
3345 "
3346 {
3347 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3348 gen_rtx_MEM (PSImode,
3349 gen_rtx_POST_INC (Pmode,
3350 stack_pointer_rtx))));
3351 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3352 DONE;
3353 }")
3354
3355 ;; These two patterns can happen as the result of optimization, when
3356 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3357 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3358
3359 (define_insn "clrt"
3360 [(set (reg:SI T_REG) (const_int 0))]
3361 "TARGET_SH1"
3362 "clrt")
3363
3364 (define_insn "sett"
3365 [(set (reg:SI T_REG) (const_int 1))]
3366 "TARGET_SH1"
3367 "sett")
3368
3369 ;; t/r must come after r/r, lest reload will try to reload stuff like
3370 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3371 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3372 (define_insn "movsi_i"
3373 [(set (match_operand:SI 0 "general_movdst_operand"
3374 "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3375 (match_operand:SI 1 "general_movsrc_operand"
3376 "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3377 "TARGET_SH1
3378 && ! TARGET_SH2E
3379 && ! TARGET_SH2A
3380 && (register_operand (operands[0], SImode)
3381 || register_operand (operands[1], SImode))"
3382 "@
3383 mov.l %1,%0
3384 mov %1,%0
3385 cmp/pl %1
3386 mov.l %1,%0
3387 sts %1,%0
3388 sts %1,%0
3389 movt %0
3390 mov.l %1,%0
3391 sts.l %1,%0
3392 sts.l %1,%0
3393 lds %1,%0
3394 lds %1,%0
3395 lds.l %1,%0
3396 lds.l %1,%0
3397 fake %1,%0"
3398 [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3399 (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3400
3401 ;; t/r must come after r/r, lest reload will try to reload stuff like
3402 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3403 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3404 ;; will require a reload.
3405 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3406 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3407 (define_insn "movsi_ie"
3408 [(set (match_operand:SI 0 "general_movdst_operand"
3409 "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3410 (match_operand:SI 1 "general_movsrc_operand"
3411 "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3412 "(TARGET_SH2E || TARGET_SH2A)
3413 && (register_operand (operands[0], SImode)
3414 || register_operand (operands[1], SImode))"
3415 "@
3416 mov.l %1,%0
3417 mov %1,%0
3418 movi20 %1,%0
3419 cmp/pl %1
3420 mov.l %1,%0
3421 sts %1,%0
3422 sts %1,%0
3423 movt %0
3424 mov.l %1,%0
3425 sts.l %1,%0
3426 sts.l %1,%0
3427 lds %1,%0
3428 lds %1,%0
3429 lds.l %1,%0
3430 lds.l %1,%0
3431 lds.l %1,%0
3432 sts.l %1,%0
3433 fake %1,%0
3434 lds %1,%0
3435 sts %1,%0
3436 fsts fpul,%0
3437 flds %1,fpul
3438 fmov %1,%0
3439 ! move optimized away"
3440 [(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")
3441 (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3442 (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3443
3444 (define_insn "movsi_i_lowpart"
3445 [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3446 (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3447 "TARGET_SH1
3448 && (register_operand (operands[0], SImode)
3449 || register_operand (operands[1], SImode))"
3450 "@
3451 mov.l %1,%0
3452 mov %1,%0
3453 mov.l %1,%0
3454 sts %1,%0
3455 sts %1,%0
3456 movt %0
3457 mov.l %1,%0
3458 fake %1,%0"
3459 [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3460
3461 (define_insn_and_split "load_ra"
3462 [(set (match_operand:SI 0 "general_movdst_operand" "")
3463 (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3464 "TARGET_SH1"
3465 "#"
3466 "&& ! currently_expanding_to_rtl"
3467 [(set (match_dup 0) (match_dup 1))]
3468 "
3469 {
3470 if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3471 operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3472 }")
3473
3474 (define_insn "*movsi_media"
3475 [(set (match_operand:SI 0 "general_movdst_operand"
3476 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3477 (match_operand:SI 1 "general_movsrc_operand"
3478 "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3479 "TARGET_SHMEDIA_FPU
3480 && (register_operand (operands[0], SImode)
3481 || sh_register_operand (operands[1], SImode))"
3482 "@
3483 add.l %1, r63, %0
3484 movi %1, %0
3485 #
3486 ld%M1.l %m1, %0
3487 st%M0.l %m0, %N1
3488 fld%M1.s %m1, %0
3489 fst%M0.s %m0, %1
3490 fmov.ls %N1, %0
3491 fmov.sl %1, %0
3492 fmov.s %1, %0
3493 ptabs %1, %0
3494 gettr %1, %0
3495 pt %1, %0"
3496 [(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")
3497 (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3498
3499 (define_insn "*movsi_media_nofpu"
3500 [(set (match_operand:SI 0 "general_movdst_operand"
3501 "=r,r,r,r,m,*b,r,b")
3502 (match_operand:SI 1 "general_movsrc_operand"
3503 "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3504 "TARGET_SHMEDIA
3505 && (register_operand (operands[0], SImode)
3506 || sh_register_operand (operands[1], SImode))"
3507 "@
3508 add.l %1, r63, %0
3509 movi %1, %0
3510 #
3511 ld%M1.l %m1, %0
3512 st%M0.l %m0, %N1
3513 ptabs %1, %0
3514 gettr %1, %0
3515 pt %1, %0"
3516 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3517 (set_attr "length" "4,4,8,4,4,4,4,12")])
3518
3519 (define_split
3520 [(set (match_operand:SI 0 "arith_reg_operand" "")
3521 (match_operand:SI 1 "immediate_operand" ""))]
3522 "TARGET_SHMEDIA && reload_completed
3523 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3524 [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3525 "
3526 {
3527 operands[2] = shallow_copy_rtx (operands[1]);
3528 PUT_MODE (operands[2], DImode);
3529 }")
3530
3531 (define_split
3532 [(set (match_operand:SI 0 "register_operand" "")
3533 (match_operand:SI 1 "immediate_operand" ""))]
3534 "TARGET_SHMEDIA && reload_completed
3535 && ((GET_CODE (operands[1]) == CONST_INT
3536 && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3537 || GET_CODE (operands[1]) == CONST_DOUBLE)"
3538 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3539
3540 (define_expand "movsi"
3541 [(set (match_operand:SI 0 "general_movdst_operand" "")
3542 (match_operand:SI 1 "general_movsrc_operand" ""))]
3543 ""
3544 "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3545
3546 (define_expand "ic_invalidate_line"
3547 [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3548 (match_dup 1)] UNSPEC_ICACHE)
3549 (clobber (scratch:SI))])]
3550 "TARGET_HARD_SH4 || TARGET_SH5"
3551 "
3552 {
3553 if (TARGET_SHMEDIA)
3554 {
3555 emit_insn (gen_ic_invalidate_line_media (operands[0]));
3556 DONE;
3557 }
3558 else if (TARGET_SHCOMPACT)
3559 {
3560 operands[1] = function_symbol (\"__ic_invalidate\");
3561 operands[1] = force_reg (Pmode, operands[1]);
3562 emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3563 DONE;
3564 }
3565 else if (TARGET_SH4A_ARCH)
3566 {
3567 emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3568 DONE;
3569 }
3570 operands[0] = force_reg (Pmode, operands[0]);
3571 operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3572 Pmode)));
3573 }")
3574
3575 ;; The address %0 is assumed to be 4-aligned at least. Thus, by ORing
3576 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3577 ;; the requirement *1*00 for associative address writes. The alignment of
3578 ;; %0 implies that its least significant bit is cleared,
3579 ;; thus we clear the V bit of a matching entry if there is one.
3580 (define_insn "ic_invalidate_line_i"
3581 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3582 (match_operand:SI 1 "register_operand" "r")]
3583 UNSPEC_ICACHE)
3584 (clobber (match_scratch:SI 2 "=&r"))]
3585 "TARGET_HARD_SH4"
3586 "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3587 [(set_attr "length" "8")
3588 (set_attr "type" "cwb")])
3589
3590 (define_insn "ic_invalidate_line_sh4a"
3591 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3592 UNSPEC_ICACHE)]
3593 "TARGET_SH4A_ARCH"
3594 "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3595 [(set_attr "length" "16")
3596 (set_attr "type" "cwb")])
3597
3598 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3599 ;; an add in the code that calculates the address.
3600 (define_insn "ic_invalidate_line_media"
3601 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3602 UNSPEC_ICACHE)]
3603 "TARGET_SHMEDIA"
3604 "ocbwb %0,0\;synco\;icbi %0, 0\;synci"
3605 [(set_attr "length" "16")
3606 (set_attr "type" "invalidate_line_media")])
3607
3608 (define_insn "ic_invalidate_line_compact"
3609 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3610 (match_operand:SI 1 "register_operand" "r")]
3611 UNSPEC_ICACHE)
3612 (clobber (reg:SI PR_REG))]
3613 "TARGET_SHCOMPACT"
3614 "jsr @%1%#"
3615 [(set_attr "type" "sfunc")
3616 (set_attr "needs_delay_slot" "yes")])
3617
3618 (define_expand "initialize_trampoline"
3619 [(match_operand:SI 0 "" "")
3620 (match_operand:SI 1 "" "")
3621 (match_operand:SI 2 "" "")]
3622 "TARGET_SHCOMPACT"
3623 "
3624 {
3625 rtx sfun, tramp;
3626
3627 tramp = force_reg (Pmode, operands[0]);
3628 sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3629 emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3630 emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3631
3632 emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3633 DONE;
3634 }")
3635
3636 (define_insn "initialize_trampoline_compact"
3637 [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3638 (match_operand:SI 1 "register_operand" "r")
3639 (reg:SI R2_REG) (reg:SI R3_REG)]
3640 UNSPEC_INIT_TRAMP)
3641
3642 (clobber (reg:SI PR_REG))]
3643 "TARGET_SHCOMPACT"
3644 "jsr @%1%#"
3645 [(set_attr "type" "sfunc")
3646 (set_attr "needs_delay_slot" "yes")])
3647
3648 (define_insn "movqi_i"
3649 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3650 (match_operand:QI 1 "general_movsrc_operand" "ri,m,r,t,l,r"))]
3651 "TARGET_SH1
3652 && (arith_reg_operand (operands[0], QImode)
3653 || arith_reg_operand (operands[1], QImode))"
3654 "@
3655 mov %1,%0
3656 mov.b %1,%0
3657 mov.b %1,%0
3658 movt %0
3659 sts %1,%0
3660 lds %1,%0"
3661 [(set_attr "type" "move,load,store,move,move,move")])
3662
3663 (define_insn "*movqi_media"
3664 [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3665 (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3666 "TARGET_SHMEDIA
3667 && (arith_reg_operand (operands[0], QImode)
3668 || arith_reg_or_0_operand (operands[1], QImode))"
3669 "@
3670 add.l %1, r63, %0
3671 movi %1, %0
3672 ld%M1.ub %m1, %0
3673 st%M0.b %m0, %N1"
3674 [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3675
3676 (define_expand "movqi"
3677 [(set (match_operand:QI 0 "general_operand" "")
3678 (match_operand:QI 1 "general_operand" ""))]
3679 ""
3680 "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3681
3682 (define_expand "reload_inqi"
3683 [(set (match_operand:SI 2 "" "=&r")
3684 (match_operand:QI 1 "inqhi_operand" ""))
3685 (set (match_operand:QI 0 "arith_reg_operand" "=r")
3686 (truncate:QI (match_dup 3)))]
3687 "TARGET_SHMEDIA"
3688 "
3689 {
3690 rtx inner = XEXP (operands[1], 0);
3691 int regno = REGNO (inner);
3692
3693 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3694 operands[1] = gen_rtx_REG (SImode, regno);
3695 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3696 }")
3697
3698 /* When storing r0, we have to avoid reg+reg addressing. */
3699 (define_insn "movhi_i"
3700 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3701 (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3702 "TARGET_SH1
3703 && (arith_reg_operand (operands[0], HImode)
3704 || arith_reg_operand (operands[1], HImode))
3705 && (GET_CODE (operands[0]) != MEM
3706 || GET_CODE (XEXP (operands[0], 0)) != PLUS
3707 || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3708 || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3709 "@
3710 mov.w %1,%0
3711 mov %1,%0
3712 mov.w %1,%0
3713 movt %0
3714 mov.w %1,%0
3715 sts %1,%0
3716 lds %1,%0
3717 fake %1,%0"
3718 [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3719
3720 (define_insn "*movhi_media"
3721 [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3722 (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3723 "TARGET_SHMEDIA
3724 && (arith_reg_operand (operands[0], HImode)
3725 || arith_reg_or_0_operand (operands[1], HImode))"
3726 "@
3727 add.l %1, r63, %0
3728 movi %1, %0
3729 #
3730 ld%M1.w %m1, %0
3731 st%M0.w %m0, %N1"
3732 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3733
3734 (define_split
3735 [(set (match_operand:HI 0 "register_operand" "")
3736 (match_operand:HI 1 "immediate_operand" ""))]
3737 "TARGET_SHMEDIA && reload_completed
3738 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3739 [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3740
3741 (define_expand "movhi"
3742 [(set (match_operand:HI 0 "general_movdst_operand" "")
3743 (match_operand:HI 1 "general_movsrc_operand" ""))]
3744 ""
3745 "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3746
3747 (define_expand "reload_inhi"
3748 [(set (match_operand:SI 2 "" "=&r")
3749 (match_operand:HI 1 "inqhi_operand" ""))
3750 (set (match_operand:HI 0 "arith_reg_operand" "=r")
3751 (truncate:HI (match_dup 3)))]
3752 "TARGET_SHMEDIA"
3753 "
3754 {
3755 rtx inner = XEXP (operands[1], 0);
3756 int regno = REGNO (inner);
3757
3758 regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3759 operands[1] = gen_rtx_REG (SImode, regno);
3760 operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3761 }")
3762
3763 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3764 ;; compiled with -m2 -ml -O3 -funroll-loops
3765 (define_insn "*movdi_i"
3766 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3767 (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3768 "TARGET_SH1
3769 && (arith_reg_operand (operands[0], DImode)
3770 || arith_reg_operand (operands[1], DImode))"
3771 "* return output_movedouble (insn, operands, DImode);"
3772 [(set_attr "length" "4")
3773 (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3774
3775 ;; If the output is a register and the input is memory or a register, we have
3776 ;; to be careful and see which word needs to be loaded first.
3777
3778 (define_split
3779 [(set (match_operand:DI 0 "general_movdst_operand" "")
3780 (match_operand:DI 1 "general_movsrc_operand" ""))]
3781 "TARGET_SH1 && reload_completed"
3782 [(set (match_dup 2) (match_dup 3))
3783 (set (match_dup 4) (match_dup 5))]
3784 "
3785 {
3786 int regno;
3787
3788 if ((GET_CODE (operands[0]) == MEM
3789 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3790 || (GET_CODE (operands[1]) == MEM
3791 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3792 FAIL;
3793
3794 if (GET_CODE (operands[0]) == REG)
3795 regno = REGNO (operands[0]);
3796 else if (GET_CODE (operands[0]) == SUBREG)
3797 regno = subreg_regno (operands[0]);
3798 else if (GET_CODE (operands[0]) == MEM)
3799 regno = -1;
3800 else
3801 abort ();
3802
3803 if (regno == -1
3804 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3805 {
3806 operands[2] = operand_subword (operands[0], 0, 0, DImode);
3807 operands[3] = operand_subword (operands[1], 0, 0, DImode);
3808 operands[4] = operand_subword (operands[0], 1, 0, DImode);
3809 operands[5] = operand_subword (operands[1], 1, 0, DImode);
3810 }
3811 else
3812 {
3813 operands[2] = operand_subword (operands[0], 1, 0, DImode);
3814 operands[3] = operand_subword (operands[1], 1, 0, DImode);
3815 operands[4] = operand_subword (operands[0], 0, 0, DImode);
3816 operands[5] = operand_subword (operands[1], 0, 0, DImode);
3817 }
3818
3819 if (operands[2] == 0 || operands[3] == 0
3820 || operands[4] == 0 || operands[5] == 0)
3821 FAIL;
3822 }")
3823
3824 (define_insn "*movdi_media"
3825 [(set (match_operand:DI 0 "general_movdst_operand"
3826 "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3827 (match_operand:DI 1 "general_movsrc_operand"
3828 "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3829 "TARGET_SHMEDIA_FPU
3830 && (register_operand (operands[0], DImode)
3831 || sh_register_operand (operands[1], DImode))"
3832 "@
3833 add %1, r63, %0
3834 movi %1, %0
3835 #
3836 ld%M1.q %m1, %0
3837 st%M0.q %m0, %N1
3838 fld%M1.d %m1, %0
3839 fst%M0.d %m0, %1
3840 fmov.qd %N1, %0
3841 fmov.dq %1, %0
3842 fmov.d %1, %0
3843 ptabs %1, %0
3844 gettr %1, %0
3845 pt %1, %0"
3846 [(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")
3847 (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3848
3849 (define_insn "*movdi_media_nofpu"
3850 [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3851 (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3852 "TARGET_SHMEDIA
3853 && (register_operand (operands[0], DImode)
3854 || sh_register_operand (operands[1], DImode))"
3855 "@
3856 add %1, r63, %0
3857 movi %1, %0
3858 #
3859 ld%M1.q %m1, %0
3860 st%M0.q %m0, %N1
3861 ptabs %1, %0
3862 gettr %1, %0
3863 pt %1, %0"
3864 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3865 (set_attr "length" "4,4,16,4,4,4,4,*")])
3866
3867 (define_split
3868 [(set (match_operand:DI 0 "arith_reg_operand" "")
3869 (match_operand:DI 1 "immediate_operand" ""))]
3870 "TARGET_SHMEDIA && reload_completed
3871 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3872 [(set (match_dup 0) (match_dup 1))]
3873 "
3874 {
3875 rtx insn;
3876
3877 if (TARGET_SHMEDIA64)
3878 insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3879 else
3880 insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3881
3882 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3883 REG_NOTES (insn));
3884
3885 DONE;
3886 }")
3887
3888 (define_expand "movdi_const"
3889 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3890 (const:DI (sign_extend:DI
3891 (truncate:HI
3892 (ashiftrt:DI
3893 (match_operand:DI 1 "immediate_operand" "s")
3894 (const_int 48))))))
3895 (set (match_dup 0)
3896 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3897 (zero_extend:DI
3898 (truncate:HI
3899 (const:DI
3900 (sign_extend:DI
3901 (truncate:HI
3902 (ashiftrt:SI
3903 (match_dup 1)
3904 (const_int 32)))))))))
3905 (set (match_dup 0)
3906 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3907 (zero_extend:DI
3908 (truncate:HI
3909 (const:DI
3910 (sign_extend:DI
3911 (truncate:HI
3912 (ashiftrt:SI
3913 (match_dup 1)
3914 (const_int 16)))))))))
3915 (set (match_dup 0)
3916 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3917 (zero_extend:DI
3918 (truncate:HI
3919 (const:DI
3920 (sign_extend:DI
3921 (truncate:HI
3922 (match_dup 1))))))))]
3923 "TARGET_SHMEDIA64 && reload_completed
3924 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3925 "
3926 {
3927 sh_mark_label (operands[1], 4);
3928 }")
3929
3930 (define_expand "movdi_const_32bit"
3931 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3932 (const:DI (sign_extend:DI
3933 (truncate:HI
3934 (ashiftrt:DI
3935 (match_operand:DI 1 "immediate_operand" "s")
3936 (const_int 16))))))
3937 (set (match_dup 0)
3938 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3939 (zero_extend:DI
3940 (truncate:HI
3941 (const:DI
3942 (sign_extend:DI
3943 (truncate:HI
3944 (match_dup 1))))))))]
3945 "TARGET_SHMEDIA32 && reload_completed
3946 && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3947 "
3948 {
3949 sh_mark_label (operands[1], 2);
3950 }")
3951
3952 (define_expand "movdi_const_16bit"
3953 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3954 (const:DI (sign_extend:DI
3955 (truncate:HI
3956 (match_operand:DI 1 "immediate_operand" "s")))))]
3957 "TARGET_SHMEDIA && flag_pic && reload_completed
3958 && GET_CODE (operands[1]) == SYMBOL_REF"
3959 "")
3960
3961 (define_split
3962 [(set (match_operand:DI 0 "arith_reg_operand" "")
3963 (match_operand:DI 1 "immediate_operand" ""))]
3964 "TARGET_SHMEDIA && reload_completed
3965 && GET_CODE (operands[1]) == CONST_INT
3966 && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3967 [(set (match_dup 0) (match_dup 2))
3968 (match_dup 1)]
3969 "
3970 {
3971 unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3972 unsigned HOST_WIDE_INT low = val;
3973 unsigned HOST_WIDE_INT high = val;
3974 unsigned HOST_WIDE_INT sign;
3975 unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3976
3977 /* Sign-extend the 16 least-significant bits. */
3978 low &= 0xffff;
3979 low ^= 0x8000;
3980 low -= 0x8000;
3981
3982 /* Arithmetic shift right the word by 16 bits. */
3983 high >>= 16;
3984 sign = 1;
3985 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3986 high ^= sign;
3987 high -= sign;
3988 do
3989 {
3990 /* If we can't generate the constant with a two-insn movi / shori
3991 sequence, try some other strategies. */
3992 if (! CONST_OK_FOR_I16 (high))
3993 {
3994 /* Try constant load / left shift. We know VAL != 0. */
3995 val2 = val ^ (val-1);
3996 if (val2 > 0x1ffff)
3997 {
3998 int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3999
4000 if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4001 || (! CONST_OK_FOR_I16 (high >> 16)
4002 && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4003 {
4004 val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4005 operands[1] = gen_ashldi3_media (operands[0], operands[0],
4006 GEN_INT (trailing_zeroes));
4007 break;
4008 }
4009 }
4010 /* Try constant load / right shift. */
4011 val2 = (val >> 15) + 1;
4012 if (val2 == (val2 & -val2))
4013 {
4014 int shift = 49 - exact_log2 (val2);
4015
4016 val2 = trunc_int_for_mode (val << shift, DImode);
4017 if (CONST_OK_FOR_I16 (val2))
4018 {
4019 operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4020 GEN_INT (shift));
4021 break;
4022 }
4023 }
4024 /* Try mperm.w . */
4025 val2 = val & 0xffff;
4026 if ((val >> 16 & 0xffff) == val2
4027 && (val >> 32 & 0xffff) == val2
4028 && (val >> 48 & 0xffff) == val2)
4029 {
4030 val2 = (HOST_WIDE_INT) val >> 48;
4031 operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4032 operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4033 break;
4034 }
4035 /* Try movi / mshflo.l */
4036 val2 = (HOST_WIDE_INT) val >> 32;
4037 if (val2 == ((unsigned HOST_WIDE_INT)
4038 trunc_int_for_mode (val, SImode)))
4039 {
4040 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4041 operands[0]);
4042 break;
4043 }
4044 /* Try movi / mshflo.l w/ r63. */
4045 val2 = val + ((HOST_WIDE_INT) -1 << 32);
4046 if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4047 {
4048 operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4049 const0_rtx);
4050 break;
4051 }
4052 }
4053 val2 = high;
4054 operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4055 }
4056 while (0);
4057 operands[2] = GEN_INT (val2);
4058 }")
4059
4060 (define_split
4061 [(set (match_operand:DI 0 "arith_reg_operand" "")
4062 (match_operand:DI 1 "immediate_operand" ""))]
4063 "TARGET_SHMEDIA && reload_completed
4064 && GET_CODE (operands[1]) == CONST_DOUBLE"
4065 [(set (match_dup 0) (match_dup 2))
4066 (set (match_dup 0)
4067 (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4068 (zero_extend:DI (truncate:HI (match_dup 1)))))]
4069 "
4070 {
4071 unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4072 unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4073 unsigned HOST_WIDE_INT val = low;
4074 unsigned HOST_WIDE_INT sign;
4075
4076 /* Sign-extend the 16 least-significant bits. */
4077 val &= 0xffff;
4078 val ^= 0x8000;
4079 val -= 0x8000;
4080 operands[1] = GEN_INT (val);
4081
4082 /* Arithmetic shift right the double-word by 16 bits. */
4083 low >>= 16;
4084 low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4085 high >>= 16;
4086 sign = 1;
4087 sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4088 high ^= sign;
4089 high -= sign;
4090
4091 /* This will only be true if high is a sign-extension of low, i.e.,
4092 it must be either 0 or (unsigned)-1, and be zero iff the
4093 most-significant bit of low is set. */
4094 if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4095 operands[2] = GEN_INT (low);
4096 else
4097 operands[2] = immed_double_const (low, high, DImode);
4098 }")
4099
4100 (define_insn "shori_media"
4101 [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4102 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4103 (const_int 16))
4104 (zero_extend:DI
4105 (truncate:HI
4106 (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4107 "TARGET_SHMEDIA"
4108 "@
4109 shori %u2, %0
4110 #"
4111 [(set_attr "type" "arith_media,*")])
4112
4113 (define_expand "movdi"
4114 [(set (match_operand:DI 0 "general_movdst_operand" "")
4115 (match_operand:DI 1 "general_movsrc_operand" ""))]
4116 ""
4117 "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4118
4119 (define_insn "movdf_media"
4120 [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4121 (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4122 "TARGET_SHMEDIA_FPU
4123 && (register_operand (operands[0], DFmode)
4124 || sh_register_operand (operands[1], DFmode))"
4125 "@
4126 fmov.d %1, %0
4127 fmov.qd %N1, %0
4128 fmov.dq %1, %0
4129 add %1, r63, %0
4130 #
4131 fld%M1.d %m1, %0
4132 fst%M0.d %m0, %1
4133 ld%M1.q %m1, %0
4134 st%M0.q %m0, %N1"
4135 [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4136
4137 (define_insn "movdf_media_nofpu"
4138 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4139 (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4140 "TARGET_SHMEDIA
4141 && (register_operand (operands[0], DFmode)
4142 || sh_register_operand (operands[1], DFmode))"
4143 "@
4144 add %1, r63, %0
4145 #
4146 ld%M1.q %m1, %0
4147 st%M0.q %m0, %N1"
4148 [(set_attr "type" "arith_media,*,load_media,store_media")])
4149
4150 (define_split
4151 [(set (match_operand:DF 0 "arith_reg_operand" "")
4152 (match_operand:DF 1 "immediate_operand" ""))]
4153 "TARGET_SHMEDIA && reload_completed"
4154 [(set (match_dup 3) (match_dup 2))]
4155 "
4156 {
4157 int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4158 long values[2];
4159 REAL_VALUE_TYPE value;
4160
4161 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4162 REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4163
4164 if (HOST_BITS_PER_WIDE_INT >= 64)
4165 operands[2] = immed_double_const ((unsigned long) values[endian]
4166 | ((HOST_WIDE_INT) values[1 - endian]
4167 << 32), 0, DImode);
4168 else if (HOST_BITS_PER_WIDE_INT == 32)
4169 operands[2] = immed_double_const (values[endian], values[1 - endian],
4170 DImode);
4171 else
4172 abort ();
4173
4174 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4175 }")
4176
4177 ;; ??? This should be a define expand.
4178
4179 (define_insn "movdf_k"
4180 [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4181 (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4182 "TARGET_SH1
4183 && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
4184 /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4185 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4186 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4187 && (arith_reg_operand (operands[0], DFmode)
4188 || arith_reg_operand (operands[1], DFmode))"
4189 "* return output_movedouble (insn, operands, DFmode);"
4190 [(set_attr "length" "4")
4191 (set_attr "type" "move,pcload,load,store")])
4192
4193 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4194 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4195 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4196 ;; the d/m/c/X alternative, which is split later into single-precision
4197 ;; instructions. And when not optimizing, no splits are done before fixing
4198 ;; up pcloads, so we need usable length information for that.
4199 (define_insn "movdf_i4"
4200 [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4201 (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4202 (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4203 (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4204 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4205 && (arith_reg_operand (operands[0], DFmode)
4206 || arith_reg_operand (operands[1], DFmode))"
4207 "@
4208 fmov %1,%0
4209 #
4210 #
4211 fmov.d %1,%0
4212 fmov.d %1,%0
4213 #
4214 #
4215 #
4216 #
4217 #"
4218 [(set_attr_alternative "length"
4219 [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4220 (const_int 4)
4221 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4222 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4223 (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4224 (const_int 4)
4225 (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4226 ;; We can't use 4-byte push/pop on SHcompact, so we have to
4227 ;; increment or decrement r15 explicitly.
4228 (if_then_else
4229 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4230 (const_int 10) (const_int 8))
4231 (if_then_else
4232 (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4233 (const_int 10) (const_int 8))])
4234 (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4235 (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4236 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4237 (const_string "double")
4238 (const_string "none")))])
4239
4240 ;; Moving DFmode between fp/general registers through memory
4241 ;; (the top of the stack) is faster than moving through fpul even for
4242 ;; little endian. Because the type of an instruction is important for its
4243 ;; scheduling, it is beneficial to split these operations, rather than
4244 ;; emitting them in one single chunk, even if this will expose a stack
4245 ;; use that will prevent scheduling of other stack accesses beyond this
4246 ;; instruction.
4247 (define_split
4248 [(set (match_operand:DF 0 "register_operand" "")
4249 (match_operand:DF 1 "register_operand" ""))
4250 (use (match_operand:PSI 2 "fpscr_operand" ""))
4251 (clobber (match_scratch:SI 3 "=X"))]
4252 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
4253 && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4254 [(const_int 0)]
4255 "
4256 {
4257 rtx insn, tos;
4258
4259 if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4260 {
4261 emit_move_insn (stack_pointer_rtx,
4262 plus_constant (stack_pointer_rtx, -8));
4263 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4264 }
4265 else
4266 tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4267 insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4268 if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4269 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4270 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4271 tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4272 else
4273 tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4274 insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4275 if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4276 emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4277 else
4278 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4279 DONE;
4280 }")
4281
4282 ;; local-alloc sometimes allocates scratch registers even when not required,
4283 ;; so we must be prepared to handle these.
4284
4285 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4286 (define_split
4287 [(set (match_operand:DF 0 "general_movdst_operand" "")
4288 (match_operand:DF 1 "general_movsrc_operand" ""))
4289 (use (match_operand:PSI 2 "fpscr_operand" ""))
4290 (clobber (match_scratch:SI 3 ""))]
4291 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4292 && reload_completed
4293 && true_regnum (operands[0]) < 16
4294 && true_regnum (operands[1]) < 16"
4295 [(set (match_dup 0) (match_dup 1))]
4296 "
4297 {
4298 /* If this was a reg <-> mem operation with base + index reg addressing,
4299 we have to handle this in a special way. */
4300 rtx mem = operands[0];
4301 int store_p = 1;
4302 if (! memory_operand (mem, DFmode))
4303 {
4304 mem = operands[1];
4305 store_p = 0;
4306 }
4307 if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4308 mem = SUBREG_REG (mem);
4309 if (GET_CODE (mem) == MEM)
4310 {
4311 rtx addr = XEXP (mem, 0);
4312 if (GET_CODE (addr) == PLUS
4313 && GET_CODE (XEXP (addr, 0)) == REG
4314 && GET_CODE (XEXP (addr, 1)) == REG)
4315 {
4316 int offset;
4317 rtx reg0 = gen_rtx_REG (Pmode, 0);
4318 rtx regop = operands[store_p], word0 ,word1;
4319
4320 if (GET_CODE (regop) == SUBREG)
4321 alter_subreg (&regop);
4322 if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4323 offset = 2;
4324 else
4325 offset = 4;
4326 mem = copy_rtx (mem);
4327 PUT_MODE (mem, SImode);
4328 word0 = gen_rtx_SUBREG (SImode, regop, 0);
4329 alter_subreg (&word0);
4330 word1 = gen_rtx_SUBREG (SImode, regop, 4);
4331 alter_subreg (&word1);
4332 if (store_p || ! refers_to_regno_p (REGNO (word0),
4333 REGNO (word0) + 1, addr, 0))
4334 {
4335 emit_insn (store_p
4336 ? gen_movsi_ie (mem, word0)
4337 : gen_movsi_ie (word0, mem));
4338 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4339 mem = copy_rtx (mem);
4340 emit_insn (store_p
4341 ? gen_movsi_ie (mem, word1)
4342 : gen_movsi_ie (word1, mem));
4343 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4344 }
4345 else
4346 {
4347 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4348 emit_insn (gen_movsi_ie (word1, mem));
4349 emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4350 mem = copy_rtx (mem);
4351 emit_insn (gen_movsi_ie (word0, mem));
4352 }
4353 DONE;
4354 }
4355 }
4356 }")
4357
4358 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4359 (define_split
4360 [(set (match_operand:DF 0 "register_operand" "")
4361 (match_operand:DF 1 "memory_operand" ""))
4362 (use (match_operand:PSI 2 "fpscr_operand" ""))
4363 (clobber (reg:SI R0_REG))]
4364 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
4365 [(parallel [(set (match_dup 0) (match_dup 1))
4366 (use (match_dup 2))
4367 (clobber (scratch:SI))])]
4368 "")
4369
4370 (define_expand "reload_indf"
4371 [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4372 (match_operand:DF 1 "immediate_operand" "FQ"))
4373 (use (reg:PSI FPSCR_REG))
4374 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4375 "TARGET_SH1"
4376 "")
4377
4378 (define_expand "reload_outdf"
4379 [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4380 (match_operand:DF 1 "register_operand" "af,r"))
4381 (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4382 "TARGET_SH1"
4383 "")
4384
4385 ;; Simplify no-op moves.
4386 (define_split
4387 [(set (match_operand:SF 0 "register_operand" "")
4388 (match_operand:SF 1 "register_operand" ""))
4389 (use (match_operand:PSI 2 "fpscr_operand" ""))
4390 (clobber (match_scratch:SI 3 ""))]
4391 "TARGET_SH2E && reload_completed
4392 && true_regnum (operands[0]) == true_regnum (operands[1])"
4393 [(set (match_dup 0) (match_dup 0))]
4394 "")
4395
4396 ;; fmovd substitute post-reload splits
4397 (define_split
4398 [(set (match_operand:DF 0 "register_operand" "")
4399 (match_operand:DF 1 "register_operand" ""))
4400 (use (match_operand:PSI 2 "fpscr_operand" ""))
4401 (clobber (match_scratch:SI 3 ""))]
4402 "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4403 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4404 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4405 [(const_int 0)]
4406 "
4407 {
4408 int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4409 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4410 gen_rtx_REG (SFmode, src), operands[2]));
4411 emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4412 gen_rtx_REG (SFmode, src + 1), operands[2]));
4413 DONE;
4414 }")
4415
4416 (define_split
4417 [(set (match_operand:DF 0 "register_operand" "")
4418 (mem:DF (match_operand:SI 1 "register_operand" "")))
4419 (use (match_operand:PSI 2 "fpscr_operand" ""))
4420 (clobber (match_scratch:SI 3 ""))]
4421 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4422 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4423 && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4424 [(const_int 0)]
4425 "
4426 {
4427 int regno = true_regnum (operands[0]);
4428 rtx insn;
4429 rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4430
4431 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4432 regno + !! TARGET_LITTLE_ENDIAN),
4433 mem2, operands[2]));
4434 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4435 insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4436 regno + ! TARGET_LITTLE_ENDIAN),
4437 gen_rtx_MEM (SFmode, operands[1]),
4438 operands[2]));
4439 DONE;
4440 }")
4441
4442 (define_split
4443 [(set (match_operand:DF 0 "register_operand" "")
4444 (match_operand:DF 1 "memory_operand" ""))
4445 (use (match_operand:PSI 2 "fpscr_operand" ""))
4446 (clobber (match_scratch:SI 3 ""))]
4447 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4448 && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4449 [(const_int 0)]
4450 "
4451 {
4452 int regno = true_regnum (operands[0]);
4453 rtx addr, insn, adjust = NULL_RTX;
4454 rtx mem2 = copy_rtx (operands[1]);
4455 rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4456 rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4457
4458 PUT_MODE (mem2, SFmode);
4459 operands[1] = copy_rtx (mem2);
4460 addr = XEXP (mem2, 0);
4461 if (GET_CODE (addr) != POST_INC)
4462 {
4463 /* If we have to modify the stack pointer, the value that we have
4464 read with post-increment might be modified by an interrupt,
4465 so write it back. */
4466 if (REGNO (addr) == STACK_POINTER_REGNUM)
4467 adjust = gen_push_e (reg0);
4468 else
4469 adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4470 XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4471 }
4472 addr = XEXP (addr, 0);
4473 insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4474 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4475 insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4476 if (adjust)
4477 emit_insn (adjust);
4478 else
4479 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4480 DONE;
4481 }")
4482
4483 (define_split
4484 [(set (match_operand:DF 0 "memory_operand" "")
4485 (match_operand:DF 1 "register_operand" ""))
4486 (use (match_operand:PSI 2 "fpscr_operand" ""))
4487 (clobber (match_scratch:SI 3 ""))]
4488 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4489 && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4490 [(const_int 0)]
4491 "
4492 {
4493 int regno = true_regnum (operands[1]);
4494 rtx insn, addr, adjust = NULL_RTX;
4495
4496 operands[0] = copy_rtx (operands[0]);
4497 PUT_MODE (operands[0], SFmode);
4498 insn = emit_insn (gen_movsf_ie (operands[0],
4499 gen_rtx_REG (SFmode,
4500 regno + ! TARGET_LITTLE_ENDIAN),
4501 operands[2]));
4502 operands[0] = copy_rtx (operands[0]);
4503 addr = XEXP (operands[0], 0);
4504 if (GET_CODE (addr) != PRE_DEC)
4505 {
4506 adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4507 emit_insn_before (adjust, insn);
4508 XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4509 }
4510 addr = XEXP (addr, 0);
4511 if (! adjust)
4512 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4513 insn = emit_insn (gen_movsf_ie (operands[0],
4514 gen_rtx_REG (SFmode,
4515 regno + !! TARGET_LITTLE_ENDIAN),
4516 operands[2]));
4517 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4518 DONE;
4519 }")
4520
4521 ;; If the output is a register and the input is memory or a register, we have
4522 ;; to be careful and see which word needs to be loaded first.
4523
4524 (define_split
4525 [(set (match_operand:DF 0 "general_movdst_operand" "")
4526 (match_operand:DF 1 "general_movsrc_operand" ""))]
4527 "TARGET_SH1 && reload_completed"
4528 [(set (match_dup 2) (match_dup 3))
4529 (set (match_dup 4) (match_dup 5))]
4530 "
4531 {
4532 int regno;
4533
4534 if ((GET_CODE (operands[0]) == MEM
4535 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4536 || (GET_CODE (operands[1]) == MEM
4537 && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4538 FAIL;
4539
4540 if (GET_CODE (operands[0]) == REG)
4541 regno = REGNO (operands[0]);
4542 else if (GET_CODE (operands[0]) == SUBREG)
4543 regno = subreg_regno (operands[0]);
4544 else if (GET_CODE (operands[0]) == MEM)
4545 regno = -1;
4546 else
4547 abort ();
4548
4549 if (regno == -1
4550 || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4551 {
4552 operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4553 operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4554 operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4555 operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4556 }
4557 else
4558 {
4559 operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4560 operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4561 operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4562 operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4563 }
4564
4565 if (operands[2] == 0 || operands[3] == 0
4566 || operands[4] == 0 || operands[5] == 0)
4567 FAIL;
4568 }")
4569
4570 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4571 ;; used only once, let combine add in the index again.
4572
4573 (define_split
4574 [(set (match_operand:SI 0 "register_operand" "")
4575 (match_operand:SI 1 "" ""))
4576 (clobber (match_operand 2 "register_operand" ""))]
4577 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4578 [(use (reg:SI R0_REG))]
4579 "
4580 {
4581 rtx addr, reg, const_int;
4582
4583 if (GET_CODE (operands[1]) != MEM)
4584 FAIL;
4585 addr = XEXP (operands[1], 0);
4586 if (GET_CODE (addr) != PLUS)
4587 FAIL;
4588 reg = XEXP (addr, 0);
4589 const_int = XEXP (addr, 1);
4590 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4591 && GET_CODE (const_int) == CONST_INT))
4592 FAIL;
4593 emit_move_insn (operands[2], const_int);
4594 emit_move_insn (operands[0],
4595 change_address (operands[1], VOIDmode,
4596 gen_rtx_PLUS (SImode, reg, operands[2])));
4597 DONE;
4598 }")
4599
4600 (define_split
4601 [(set (match_operand:SI 1 "" "")
4602 (match_operand:SI 0 "register_operand" ""))
4603 (clobber (match_operand 2 "register_operand" ""))]
4604 "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4605 [(use (reg:SI R0_REG))]
4606 "
4607 {
4608 rtx addr, reg, const_int;
4609
4610 if (GET_CODE (operands[1]) != MEM)
4611 FAIL;
4612 addr = XEXP (operands[1], 0);
4613 if (GET_CODE (addr) != PLUS)
4614 FAIL;
4615 reg = XEXP (addr, 0);
4616 const_int = XEXP (addr, 1);
4617 if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4618 && GET_CODE (const_int) == CONST_INT))
4619 FAIL;
4620 emit_move_insn (operands[2], const_int);
4621 emit_move_insn (change_address (operands[1], VOIDmode,
4622 gen_rtx_PLUS (SImode, reg, operands[2])),
4623 operands[0]);
4624 DONE;
4625 }")
4626
4627 (define_expand "movdf"
4628 [(set (match_operand:DF 0 "general_movdst_operand" "")
4629 (match_operand:DF 1 "general_movsrc_operand" ""))]
4630 ""
4631 "
4632 {
4633 if (prepare_move_operands (operands, DFmode)) DONE;
4634 if (TARGET_SHMEDIA)
4635 {
4636 if (TARGET_SHMEDIA_FPU)
4637 emit_insn (gen_movdf_media (operands[0], operands[1]));
4638 else
4639 emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4640 DONE;
4641 }
4642 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
4643 {
4644 emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4645 DONE;
4646 }
4647 }")
4648
4649 ;;This is incompatible with the way gcc uses subregs.
4650 ;;(define_insn "movv2sf_i"
4651 ;; [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4652 ;; (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4653 ;; "TARGET_SHMEDIA_FPU
4654 ;; && (fp_arith_reg_operand (operands[0], V2SFmode)
4655 ;; || fp_arith_reg_operand (operands[1], V2SFmode))"
4656 ;; "@
4657 ;; #
4658 ;; fld%M1.p %m1, %0
4659 ;; fst%M0.p %m0, %1"
4660 ;; [(set_attr "type" "*,fload_media,fstore_media")])
4661
4662 (define_insn_and_split "movv2sf_i"
4663 [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4664 (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4665 "TARGET_SHMEDIA_FPU"
4666 "#"
4667 "TARGET_SHMEDIA_FPU && reload_completed"
4668 [(set (match_dup 0) (match_dup 1))]
4669 "
4670 {
4671 operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4672 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4673 }")
4674
4675 (define_expand "movv2sf"
4676 [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4677 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4678 "TARGET_SHMEDIA_FPU"
4679 "
4680 {
4681 if (prepare_move_operands (operands, V2SFmode))
4682 DONE;
4683 }")
4684
4685 (define_expand "addv2sf3"
4686 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4687 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4688 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4689 "TARGET_SHMEDIA_FPU"
4690 "
4691 {
4692 sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4693 DONE;
4694 }")
4695
4696 (define_expand "subv2sf3"
4697 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4698 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4699 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4700 "TARGET_SHMEDIA_FPU"
4701 "
4702 {
4703 sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4704 DONE;
4705 }")
4706
4707 (define_expand "mulv2sf3"
4708 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4709 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4710 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4711 "TARGET_SHMEDIA_FPU"
4712 "
4713 {
4714 sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4715 DONE;
4716 }")
4717
4718 (define_expand "divv2sf3"
4719 [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4720 (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4721 (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4722 "TARGET_SHMEDIA_FPU"
4723 "
4724 {
4725 sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4726 DONE;
4727 }")
4728
4729 (define_insn_and_split "*movv4sf_i"
4730 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4731 (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4732 "TARGET_SHMEDIA_FPU"
4733 "#"
4734 "&& reload_completed"
4735 [(const_int 0)]
4736 "
4737 {
4738 int i;
4739
4740 for (i = 0; i < 4/2; i++)
4741 {
4742 rtx x, y;
4743
4744 if (GET_CODE (operands[0]) == MEM)
4745 x = gen_rtx_MEM (V2SFmode,
4746 plus_constant (XEXP (operands[0], 0),
4747 i * GET_MODE_SIZE (V2SFmode)));
4748 else
4749 x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4750
4751 if (GET_CODE (operands[1]) == MEM)
4752 y = gen_rtx_MEM (V2SFmode,
4753 plus_constant (XEXP (operands[1], 0),
4754 i * GET_MODE_SIZE (V2SFmode)));
4755 else
4756 y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4757
4758 emit_insn (gen_movv2sf_i (x, y));
4759 }
4760
4761 DONE;
4762 }"
4763 [(set_attr "length" "8")])
4764
4765 (define_expand "movv4sf"
4766 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4767 (match_operand:V4SF 1 "general_operand" ""))]
4768 "TARGET_SHMEDIA_FPU"
4769 "
4770 {
4771 if (prepare_move_operands (operands, V4SFmode))
4772 DONE;
4773 }")
4774
4775 (define_insn_and_split "*movv16sf_i"
4776 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4777 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4778 "TARGET_SHMEDIA_FPU"
4779 "#"
4780 "&& reload_completed"
4781 [(const_int 0)]
4782 "
4783 {
4784 int i;
4785
4786 for (i = 0; i < 16/2; i++)
4787 {
4788 rtx x,y;
4789
4790 if (GET_CODE (operands[0]) == MEM)
4791 x = gen_rtx_MEM (V2SFmode,
4792 plus_constant (XEXP (operands[0], 0),
4793 i * GET_MODE_SIZE (V2SFmode)));
4794 else
4795 {
4796 x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4797 alter_subreg (&x);
4798 }
4799
4800 if (GET_CODE (operands[1]) == MEM)
4801 y = gen_rtx_MEM (V2SFmode,
4802 plus_constant (XEXP (operands[1], 0),
4803 i * GET_MODE_SIZE (V2SFmode)));
4804 else
4805 {
4806 y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4807 alter_subreg (&y);
4808 }
4809
4810 emit_insn (gen_movv2sf_i (x, y));
4811 }
4812
4813 DONE;
4814 }"
4815 [(set_attr "length" "32")])
4816
4817 (define_expand "movv16sf"
4818 [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4819 (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4820 "TARGET_SHMEDIA_FPU"
4821 "
4822 {
4823 if (prepare_move_operands (operands, V16SFmode))
4824 DONE;
4825 }")
4826
4827 (define_insn "movsf_media"
4828 [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4829 (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4830 "TARGET_SHMEDIA_FPU
4831 && (register_operand (operands[0], SFmode)
4832 || sh_register_operand (operands[1], SFmode))"
4833 "@
4834 fmov.s %1, %0
4835 fmov.ls %N1, %0
4836 fmov.sl %1, %0
4837 add.l %1, r63, %0
4838 #
4839 fld%M1.s %m1, %0
4840 fst%M0.s %m0, %1
4841 ld%M1.l %m1, %0
4842 st%M0.l %m0, %N1"
4843 [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4844
4845 (define_insn "movsf_media_nofpu"
4846 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4847 (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4848 "TARGET_SHMEDIA
4849 && (register_operand (operands[0], SFmode)
4850 || sh_register_operand (operands[1], SFmode))"
4851 "@
4852 add.l %1, r63, %0
4853 #
4854 ld%M1.l %m1, %0
4855 st%M0.l %m0, %N1"
4856 [(set_attr "type" "arith_media,*,load_media,store_media")])
4857
4858 (define_split
4859 [(set (match_operand:SF 0 "arith_reg_operand" "")
4860 (match_operand:SF 1 "immediate_operand" ""))]
4861 "TARGET_SHMEDIA && reload_completed
4862 && ! FP_REGISTER_P (true_regnum (operands[0]))"
4863 [(set (match_dup 3) (match_dup 2))]
4864 "
4865 {
4866 long values;
4867 REAL_VALUE_TYPE value;
4868
4869 REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4870 REAL_VALUE_TO_TARGET_SINGLE (value, values);
4871 operands[2] = GEN_INT (values);
4872
4873 operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4874 }")
4875
4876 (define_insn "movsf_i"
4877 [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4878 (match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
4879 "TARGET_SH1
4880 && (! TARGET_SH2E
4881 /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4882 || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4883 || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4884 && (arith_reg_operand (operands[0], SFmode)
4885 || arith_reg_operand (operands[1], SFmode))"
4886 "@
4887 mov %1,%0
4888 mov #0,%0
4889 mov.l %1,%0
4890 mov.l %1,%0
4891 mov.l %1,%0
4892 lds %1,%0
4893 sts %1,%0"
4894 [(set_attr "type" "move,move,pcload,load,store,move,move")])
4895
4896 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4897 ;; update_flow_info would not know where to put REG_EQUAL notes
4898 ;; when the destination changes mode.
4899 (define_insn "movsf_ie"
4900 [(set (match_operand:SF 0 "general_movdst_operand"
4901 "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4902 (match_operand:SF 1 "general_movsrc_operand"
4903 "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4904 (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"))
4905 (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4906
4907 "TARGET_SH2E
4908 && (arith_reg_operand (operands[0], SFmode)
4909 || arith_reg_operand (operands[1], SFmode)
4910 || arith_reg_operand (operands[3], SImode)
4911 || (fpul_operand (operands[0], SFmode)
4912 && memory_operand (operands[1], SFmode)
4913 && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4914 || (fpul_operand (operands[1], SFmode)
4915 && memory_operand (operands[0], SFmode)
4916 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4917 "@
4918 fmov %1,%0
4919 mov %1,%0
4920 fldi0 %0
4921 fldi1 %0
4922 #
4923 fmov.s %1,%0
4924 fmov.s %1,%0
4925 mov.l %1,%0
4926 mov.l %1,%0
4927 mov.l %1,%0
4928 fsts fpul,%0
4929 flds %1,fpul
4930 lds.l %1,%0
4931 #
4932 sts %1,%0
4933 lds %1,%0
4934 sts.l %1,%0
4935 lds.l %1,%0
4936 ! move optimized away"
4937 [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4938 (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4939 (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
4940 (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4941 (const_string "single")
4942 (const_string "none")))])
4943
4944 (define_split
4945 [(set (match_operand:SF 0 "register_operand" "")
4946 (match_operand:SF 1 "register_operand" ""))
4947 (use (match_operand:PSI 2 "fpscr_operand" ""))
4948 (clobber (reg:SI FPUL_REG))]
4949 "TARGET_SH1"
4950 [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4951 (use (match_dup 2))
4952 (clobber (scratch:SI))])
4953 (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4954 (use (match_dup 2))
4955 (clobber (scratch:SI))])]
4956 "")
4957
4958 (define_expand "movsf"
4959 [(set (match_operand:SF 0 "general_movdst_operand" "")
4960 (match_operand:SF 1 "general_movsrc_operand" ""))]
4961 ""
4962 "
4963 {
4964 if (prepare_move_operands (operands, SFmode))
4965 DONE;
4966 if (TARGET_SHMEDIA)
4967 {
4968 if (TARGET_SHMEDIA_FPU)
4969 emit_insn (gen_movsf_media (operands[0], operands[1]));
4970 else
4971 emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4972 DONE;
4973 }
4974 if (TARGET_SH2E)
4975 {
4976 emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4977 DONE;
4978 }
4979 }")
4980
4981 (define_insn "mov_nop"
4982 [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4983 "TARGET_SH2E"
4984 ""
4985 [(set_attr "length" "0")
4986 (set_attr "type" "nil")])
4987
4988 (define_expand "reload_insf"
4989 [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4990 (match_operand:SF 1 "immediate_operand" "FQ"))
4991 (use (reg:PSI FPSCR_REG))
4992 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4993 "TARGET_SH1"
4994 "")
4995
4996 (define_expand "reload_insi"
4997 [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4998 (match_operand:SF 1 "immediate_operand" "FQ"))
4999 (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5000 "TARGET_SH1"
5001 "")
5002
5003 (define_insn "*movsi_y"
5004 [(set (match_operand:SI 0 "register_operand" "=y,y")
5005 (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5006 (clobber (match_scratch:SI 2 "=&z,r"))]
5007 "TARGET_SH2E
5008 && (reload_in_progress || reload_completed)"
5009 "#"
5010 [(set_attr "length" "4")
5011 (set_attr "type" "pcload,move")])
5012
5013 (define_split
5014 [(set (match_operand:SI 0 "register_operand" "")
5015 (match_operand:SI 1 "immediate_operand" ""))
5016 (clobber (match_operand:SI 2 "register_operand" ""))]
5017 "TARGET_SH1"
5018 [(set (match_dup 2) (match_dup 1))
5019 (set (match_dup 0) (match_dup 2))]
5020 "")
5021
5022 (define_split
5023 [(set (match_operand:SI 0 "register_operand" "")
5024 (match_operand:SI 1 "memory_operand" ""))
5025 (clobber (reg:SI R0_REG))]
5026 "TARGET_SH1"
5027 [(set (match_dup 0) (match_dup 1))]
5028 "")
5029 \f
5030 ;; ------------------------------------------------------------------------
5031 ;; Define the real conditional branch instructions.
5032 ;; ------------------------------------------------------------------------
5033
5034 (define_insn "branch_true"
5035 [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5036 (label_ref (match_operand 0 "" ""))
5037 (pc)))]
5038 "TARGET_SH1"
5039 "* return output_branch (1, insn, operands);"
5040 [(set_attr "type" "cbranch")])
5041
5042 (define_insn "branch_false"
5043 [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5044 (label_ref (match_operand 0 "" ""))
5045 (pc)))]
5046 "TARGET_SH1"
5047 "* return output_branch (0, insn, operands);"
5048 [(set_attr "type" "cbranch")])
5049
5050 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5051 ;; which destination is too far away.
5052 ;; The const_int_operand is distinct for each branch target; it avoids
5053 ;; unwanted matches with redundant_insn.
5054 (define_insn "block_branch_redirect"
5055 [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5056 "TARGET_SH1"
5057 ""
5058 [(set_attr "length" "0")])
5059
5060 ;; This one has the additional purpose to record a possible scratch register
5061 ;; for the following branch.
5062 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5063 ;; because the insn then might be deemed dead and deleted. And we can't
5064 ;; make the use in the jump insn explicit because that would disable
5065 ;; delay slot scheduling from the target.
5066 (define_insn "indirect_jump_scratch"
5067 [(set (match_operand:SI 0 "register_operand" "=r")
5068 (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5069 (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5070 "TARGET_SH1"
5071 ""
5072 [(set_attr "length" "0")])
5073
5074 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5075 ;; being pulled into the delay slot of a condbranch that has been made to
5076 ;; jump around the unconditional jump because it was out of range.
5077 (define_insn "stuff_delay_slot"
5078 [(set (pc)
5079 (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5080 (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5081 "TARGET_SH1"
5082 ""
5083 [(set_attr "length" "0")
5084 (set_attr "cond_delay_slot" "yes")])
5085 \f
5086 ;; Conditional branch insns
5087
5088 (define_expand "beq_media"
5089 [(set (pc)
5090 (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5091 (match_operand:DI 2 "arith_operand" "r,I06"))
5092 (label_ref:DI (match_operand 0 "" ""))
5093 (pc)))]
5094 "TARGET_SHMEDIA"
5095 "")
5096
5097 (define_insn "*beq_media_i"
5098 [(set (pc)
5099 (if_then_else (match_operator 3 "equality_comparison_operator"
5100 [(match_operand:DI 1 "arith_reg_operand" "r,r")
5101 (match_operand:DI 2 "arith_operand" "r,I06")])
5102 (match_operand:DI 0 "target_operand" "b,b")
5103 (pc)))]
5104 "TARGET_SHMEDIA"
5105 "@
5106 b%o3%' %1, %2, %0
5107 b%o3i%' %1, %2, %0"
5108 [(set_attr "type" "cbranch_media")])
5109
5110 (define_expand "bne_media"
5111 [(set (pc)
5112 (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5113 (match_operand:DI 2 "arith_operand" "r,I06"))
5114 (label_ref:DI (match_operand 0 "" ""))
5115 (pc)))]
5116 "TARGET_SHMEDIA"
5117 "")
5118
5119 (define_expand "bgt_media"
5120 [(set (pc)
5121 (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5122 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5123 (label_ref:DI (match_operand 0 "" ""))
5124 (pc)))]
5125 "TARGET_SHMEDIA"
5126 "")
5127
5128 (define_expand "bge_media"
5129 [(set (pc)
5130 (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5131 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5132 (label_ref:DI (match_operand 0 "" ""))
5133 (pc)))]
5134 "TARGET_SHMEDIA"
5135 "")
5136
5137 (define_expand "bgtu_media"
5138 [(set (pc)
5139 (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5140 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5141 (label_ref:DI (match_operand 0 "" ""))
5142 (pc)))]
5143 "TARGET_SHMEDIA"
5144 "")
5145
5146 (define_expand "bgeu_media"
5147 [(set (pc)
5148 (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5149 (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5150 (label_ref:DI (match_operand 0 "" ""))
5151 (pc)))]
5152 "TARGET_SHMEDIA"
5153 "")
5154
5155 (define_insn "*bgt_media_i"
5156 [(set (pc)
5157 (if_then_else (match_operator 3 "greater_comparison_operator"
5158 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5159 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5160 (match_operand:DI 0 "target_operand" "b")
5161 (pc)))]
5162 "TARGET_SHMEDIA"
5163 "b%o3%' %N1, %N2, %0"
5164 [(set_attr "type" "cbranch_media")])
5165
5166 ;; These are only needed to make invert_jump() happy.
5167 (define_insn "*blt_media_i"
5168 [(set (pc)
5169 (if_then_else (match_operator 3 "less_comparison_operator"
5170 [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5171 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5172 (match_operand:DI 0 "target_operand" "b")
5173 (pc)))]
5174 "TARGET_SHMEDIA"
5175 "b%o3%' %N2, %N1, %0"
5176 [(set_attr "type" "cbranch_media")])
5177
5178 (define_expand "beq"
5179 [(set (pc)
5180 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5181 (label_ref (match_operand 0 "" ""))
5182 (pc)))]
5183 ""
5184 "
5185 {
5186 if (TARGET_SHMEDIA)
5187 {
5188 if (GET_MODE (sh_compare_op0) != DImode)
5189 {
5190 rtx tmp = gen_reg_rtx (DImode);
5191
5192 emit_insn (gen_seq (tmp));
5193 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5194 DONE;
5195 }
5196
5197 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5198 emit_jump_insn (gen_beq_media (operands[0],
5199 sh_compare_op0, sh_compare_op1));
5200 DONE;
5201 }
5202
5203 from_compare (operands, EQ);
5204 }")
5205
5206 (define_expand "bne"
5207 [(set (pc)
5208 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5209 (label_ref (match_operand 0 "" ""))
5210 (pc)))]
5211 ""
5212 "
5213 {
5214 if (TARGET_SHMEDIA)
5215 {
5216 if (GET_MODE (sh_compare_op0) != DImode)
5217 {
5218 rtx tmp = gen_reg_rtx (DImode);
5219
5220 emit_insn (gen_seq (tmp));
5221 emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5222 DONE;
5223 }
5224
5225 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5226 emit_jump_insn (gen_bne_media (operands[0],
5227 sh_compare_op0, sh_compare_op1));
5228 DONE;
5229 }
5230
5231 from_compare (operands, EQ);
5232 }")
5233
5234 (define_expand "bgt"
5235 [(set (pc)
5236 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5237 (label_ref (match_operand 0 "" ""))
5238 (pc)))]
5239 ""
5240 "
5241 {
5242 if (TARGET_SHMEDIA)
5243 {
5244 if (GET_MODE (sh_compare_op0) != DImode)
5245 {
5246 rtx tmp = gen_reg_rtx (DImode);
5247
5248 emit_insn (gen_sgt (tmp));
5249 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5250 DONE;
5251 }
5252
5253 if (sh_compare_op0 != const0_rtx)
5254 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5255 if (sh_compare_op1 != const0_rtx)
5256 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5257 emit_jump_insn (gen_bgt_media (operands[0],
5258 sh_compare_op0, sh_compare_op1));
5259 DONE;
5260 }
5261
5262 from_compare (operands, GT);
5263 }")
5264
5265 (define_expand "blt"
5266 [(set (pc)
5267 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268 (label_ref (match_operand 0 "" ""))
5269 (pc)))]
5270 ""
5271 "
5272 {
5273 if (TARGET_SHMEDIA)
5274 {
5275 if (GET_MODE (sh_compare_op0) != DImode)
5276 {
5277 rtx tmp = gen_reg_rtx (DImode);
5278
5279 emit_insn (gen_slt (tmp));
5280 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5281 DONE;
5282 }
5283
5284 if (sh_compare_op0 != const0_rtx)
5285 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5286 if (sh_compare_op1 != const0_rtx)
5287 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5288 emit_jump_insn (gen_bgt_media (operands[0],
5289 sh_compare_op1, sh_compare_op0));
5290 DONE;
5291 }
5292
5293 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5294 {
5295 rtx tmp = sh_compare_op0;
5296 sh_compare_op0 = sh_compare_op1;
5297 sh_compare_op1 = tmp;
5298 emit_insn (gen_bgt (operands[0]));
5299 DONE;
5300 }
5301 from_compare (operands, GE);
5302 }")
5303
5304 (define_expand "ble"
5305 [(set (pc)
5306 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5307 (label_ref (match_operand 0 "" ""))
5308 (pc)))]
5309 ""
5310 "
5311 {
5312 if (TARGET_SHMEDIA)
5313 {
5314 if (GET_MODE (sh_compare_op0) != DImode)
5315 {
5316 rtx tmp = gen_reg_rtx (DImode);
5317
5318 emit_insn (gen_sle (tmp));
5319 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5320 DONE;
5321 }
5322
5323 if (sh_compare_op0 != const0_rtx)
5324 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5325 if (sh_compare_op1 != const0_rtx)
5326 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5327 emit_jump_insn (gen_bge_media (operands[0],
5328 sh_compare_op1, sh_compare_op0));
5329 DONE;
5330 }
5331
5332 if (TARGET_SH2E
5333 && TARGET_IEEE
5334 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5335 {
5336 rtx tmp = sh_compare_op0;
5337 sh_compare_op0 = sh_compare_op1;
5338 sh_compare_op1 = tmp;
5339 emit_insn (gen_bge (operands[0]));
5340 DONE;
5341 }
5342 from_compare (operands, GT);
5343 }")
5344
5345 (define_expand "bge"
5346 [(set (pc)
5347 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5348 (label_ref (match_operand 0 "" ""))
5349 (pc)))]
5350 ""
5351 "
5352 {
5353 if (TARGET_SHMEDIA)
5354 {
5355 if (GET_MODE (sh_compare_op0) != DImode)
5356 {
5357 rtx tmp = gen_reg_rtx (DImode);
5358
5359 emit_insn (gen_sge (tmp));
5360 emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5361 DONE;
5362 }
5363
5364 if (sh_compare_op0 != const0_rtx)
5365 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5366 if (sh_compare_op1 != const0_rtx)
5367 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5368 emit_jump_insn (gen_bge_media (operands[0],
5369 sh_compare_op0, sh_compare_op1));
5370 DONE;
5371 }
5372
5373 if (TARGET_SH2E
5374 && ! TARGET_IEEE
5375 && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5376 {
5377 rtx tmp = sh_compare_op0;
5378 sh_compare_op0 = sh_compare_op1;
5379 sh_compare_op1 = tmp;
5380 emit_insn (gen_ble (operands[0]));
5381 DONE;
5382 }
5383 from_compare (operands, GE);
5384 }")
5385
5386 (define_expand "bgtu"
5387 [(set (pc)
5388 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5389 (label_ref (match_operand 0 "" ""))
5390 (pc)))]
5391 ""
5392 "
5393 {
5394 if (TARGET_SHMEDIA)
5395 {
5396 if (sh_compare_op0 != const0_rtx)
5397 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5398 if (sh_compare_op1 != const0_rtx)
5399 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5400 emit_jump_insn (gen_bgtu_media (operands[0],
5401 sh_compare_op0, sh_compare_op1));
5402 DONE;
5403 }
5404
5405 from_compare (operands, GTU);
5406 }")
5407
5408 (define_expand "bltu"
5409 [(set (pc)
5410 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5411 (label_ref (match_operand 0 "" ""))
5412 (pc)))]
5413 ""
5414 "
5415 {
5416 if (TARGET_SHMEDIA)
5417 {
5418 if (sh_compare_op0 != const0_rtx)
5419 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5420 if (sh_compare_op1 != const0_rtx)
5421 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5422 emit_jump_insn (gen_bgtu_media (operands[0],
5423 sh_compare_op1, sh_compare_op0));
5424 DONE;
5425 }
5426
5427 from_compare (operands, GEU);
5428 }")
5429
5430 (define_expand "bgeu"
5431 [(set (pc)
5432 (if_then_else (ne (reg:SI T_REG) (const_int 0))
5433 (label_ref (match_operand 0 "" ""))
5434 (pc)))]
5435 ""
5436 "
5437 {
5438 if (TARGET_SHMEDIA)
5439 {
5440 if (sh_compare_op0 != const0_rtx)
5441 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5442 if (sh_compare_op1 != const0_rtx)
5443 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5444 emit_jump_insn (gen_bgeu_media (operands[0],
5445 sh_compare_op0, sh_compare_op1));
5446 DONE;
5447 }
5448
5449 from_compare (operands, GEU);
5450 }")
5451
5452 (define_expand "bleu"
5453 [(set (pc)
5454 (if_then_else (eq (reg:SI T_REG) (const_int 0))
5455 (label_ref (match_operand 0 "" ""))
5456 (pc)))]
5457 ""
5458 "
5459 {
5460 if (TARGET_SHMEDIA)
5461 {
5462 if (sh_compare_op0 != const0_rtx)
5463 sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5464 if (sh_compare_op1 != const0_rtx)
5465 sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5466 emit_jump_insn (gen_bgeu_media (operands[0],
5467 sh_compare_op1, sh_compare_op0));
5468 DONE;
5469 }
5470
5471 from_compare (operands, GTU);
5472 }")
5473
5474 (define_expand "bunordered"
5475 [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5476 (set (pc)
5477 (if_then_else (ne (match_dup 1) (const_int 0))
5478 (label_ref:DI (match_operand 0 "" ""))
5479 (pc)))]
5480 "TARGET_SHMEDIA"
5481 "
5482 {
5483 operands[1] = gen_reg_rtx (DImode);
5484 operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5485 operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5486 }")
5487 \f
5488 ;; ------------------------------------------------------------------------
5489 ;; Jump and linkage insns
5490 ;; ------------------------------------------------------------------------
5491
5492 (define_insn "jump_compact"
5493 [(set (pc)
5494 (label_ref (match_operand 0 "" "")))]
5495 "TARGET_SH1"
5496 "*
5497 {
5498 /* The length is 16 if the delay slot is unfilled. */
5499 if (get_attr_length(insn) > 4)
5500 return output_far_jump(insn, operands[0]);
5501 else
5502 return \"bra %l0%#\";
5503 }"
5504 [(set_attr "type" "jump")
5505 (set_attr "needs_delay_slot" "yes")])
5506
5507 ;; ??? It would be much saner to explicitly use the scratch register
5508 ;; in the jump insn, and have indirect_jump_scratch only set it,
5509 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5510 ;; from the target then, as it uses simplejump_p.
5511 ;;(define_insn "jump_compact_far"
5512 ;; [(set (pc)
5513 ;; (label_ref (match_operand 0 "" "")))
5514 ;; (use (match_operand 1 "register_operand" "r")]
5515 ;; "TARGET_SH1"
5516 ;; "* return output_far_jump(insn, operands[0], operands[1]);"
5517 ;; [(set_attr "type" "jump")
5518 ;; (set_attr "needs_delay_slot" "yes")])
5519
5520 (define_insn "jump_media"
5521 [(set (pc)
5522 (match_operand:DI 0 "target_operand" "b"))]
5523 "TARGET_SHMEDIA"
5524 "blink %0, r63"
5525 [(set_attr "type" "jump_media")])
5526
5527 (define_expand "jump"
5528 [(set (pc)
5529 (label_ref (match_operand 0 "" "")))]
5530 ""
5531 "
5532 {
5533 if (TARGET_SH1)
5534 emit_jump_insn (gen_jump_compact (operands[0]));
5535 else if (TARGET_SHMEDIA)
5536 {
5537 if (reload_in_progress || reload_completed)
5538 FAIL;
5539 emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5540 operands[0])));
5541 }
5542 DONE;
5543 }")
5544
5545 (define_insn "force_mode_for_call"
5546 [(use (reg:PSI FPSCR_REG))]
5547 "TARGET_SHCOMPACT"
5548 ""
5549 [(set_attr "length" "0")
5550 (set (attr "fp_mode")
5551 (if_then_else (eq_attr "fpu_single" "yes")
5552 (const_string "single") (const_string "double")))])
5553
5554 (define_insn "calli"
5555 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5556 (match_operand 1 "" ""))
5557 (use (reg:PSI FPSCR_REG))
5558 (clobber (reg:SI PR_REG))]
5559 "TARGET_SH1"
5560 "jsr @%0%#"
5561 [(set_attr "type" "call")
5562 (set (attr "fp_mode")
5563 (if_then_else (eq_attr "fpu_single" "yes")
5564 (const_string "single") (const_string "double")))
5565 (set_attr "needs_delay_slot" "yes")
5566 (set_attr "fp_set" "unknown")])
5567
5568 ;; This is a pc-rel call, using bsrf, for use with PIC.
5569
5570 (define_insn "calli_pcrel"
5571 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5572 (match_operand 1 "" ""))
5573 (use (reg:PSI FPSCR_REG))
5574 (use (reg:SI PIC_REG))
5575 (use (match_operand 2 "" ""))
5576 (clobber (reg:SI PR_REG))]
5577 "TARGET_SH2"
5578 "bsrf %0\\n%O2:%#"
5579 [(set_attr "type" "call")
5580 (set (attr "fp_mode")
5581 (if_then_else (eq_attr "fpu_single" "yes")
5582 (const_string "single") (const_string "double")))
5583 (set_attr "needs_delay_slot" "yes")
5584 (set_attr "fp_set" "unknown")])
5585
5586 (define_insn_and_split "call_pcrel"
5587 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5588 (match_operand 1 "" ""))
5589 (use (reg:PSI FPSCR_REG))
5590 (use (reg:SI PIC_REG))
5591 (clobber (reg:SI PR_REG))
5592 (clobber (match_scratch:SI 2 "=r"))]
5593 "TARGET_SH2"
5594 "#"
5595 "reload_completed"
5596 [(const_int 0)]
5597 "
5598 {
5599 rtx lab = PATTERN (gen_call_site ());
5600
5601 if (SYMBOL_REF_LOCAL_P (operands[0]))
5602 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5603 else
5604 emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5605 emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5606 DONE;
5607 }"
5608 [(set_attr "type" "call")
5609 (set (attr "fp_mode")
5610 (if_then_else (eq_attr "fpu_single" "yes")
5611 (const_string "single") (const_string "double")))
5612 (set_attr "needs_delay_slot" "yes")
5613 (set_attr "fp_set" "unknown")])
5614
5615 (define_insn "call_compact"
5616 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5617 (match_operand 1 "" ""))
5618 (match_operand 2 "immediate_operand" "n")
5619 (use (reg:SI R0_REG))
5620 (use (reg:SI R1_REG))
5621 (use (reg:PSI FPSCR_REG))
5622 (clobber (reg:SI PR_REG))]
5623 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5624 "jsr @%0%#"
5625 [(set_attr "type" "call")
5626 (set (attr "fp_mode")
5627 (if_then_else (eq_attr "fpu_single" "yes")
5628 (const_string "single") (const_string "double")))
5629 (set_attr "needs_delay_slot" "yes")])
5630
5631 (define_insn "call_compact_rettramp"
5632 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5633 (match_operand 1 "" ""))
5634 (match_operand 2 "immediate_operand" "n")
5635 (use (reg:SI R0_REG))
5636 (use (reg:SI R1_REG))
5637 (use (reg:PSI FPSCR_REG))
5638 (clobber (reg:SI R10_REG))
5639 (clobber (reg:SI PR_REG))]
5640 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5641 "jsr @%0%#"
5642 [(set_attr "type" "call")
5643 (set (attr "fp_mode")
5644 (if_then_else (eq_attr "fpu_single" "yes")
5645 (const_string "single") (const_string "double")))
5646 (set_attr "needs_delay_slot" "yes")])
5647
5648 (define_insn "call_media"
5649 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5650 (match_operand 1 "" ""))
5651 (clobber (reg:DI PR_MEDIA_REG))]
5652 "TARGET_SHMEDIA"
5653 "blink %0, r18"
5654 [(set_attr "type" "jump_media")])
5655
5656 (define_insn "call_valuei"
5657 [(set (match_operand 0 "" "=rf")
5658 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5659 (match_operand 2 "" "")))
5660 (use (reg:PSI FPSCR_REG))
5661 (clobber (reg:SI PR_REG))]
5662 "TARGET_SH1"
5663 "jsr @%1%#"
5664 [(set_attr "type" "call")
5665 (set (attr "fp_mode")
5666 (if_then_else (eq_attr "fpu_single" "yes")
5667 (const_string "single") (const_string "double")))
5668 (set_attr "needs_delay_slot" "yes")
5669 (set_attr "fp_set" "unknown")])
5670
5671 (define_insn "call_valuei_pcrel"
5672 [(set (match_operand 0 "" "=rf")
5673 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5674 (match_operand 2 "" "")))
5675 (use (reg:PSI FPSCR_REG))
5676 (use (reg:SI PIC_REG))
5677 (use (match_operand 3 "" ""))
5678 (clobber (reg:SI PR_REG))]
5679 "TARGET_SH2"
5680 "bsrf %1\\n%O3:%#"
5681 [(set_attr "type" "call")
5682 (set (attr "fp_mode")
5683 (if_then_else (eq_attr "fpu_single" "yes")
5684 (const_string "single") (const_string "double")))
5685 (set_attr "needs_delay_slot" "yes")
5686 (set_attr "fp_set" "unknown")])
5687
5688 (define_insn_and_split "call_value_pcrel"
5689 [(set (match_operand 0 "" "=rf")
5690 (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5691 (match_operand 2 "" "")))
5692 (use (reg:PSI FPSCR_REG))
5693 (use (reg:SI PIC_REG))
5694 (clobber (reg:SI PR_REG))
5695 (clobber (match_scratch:SI 3 "=r"))]
5696 "TARGET_SH2"
5697 "#"
5698 "reload_completed"
5699 [(const_int 0)]
5700 "
5701 {
5702 rtx lab = PATTERN (gen_call_site ());
5703
5704 if (SYMBOL_REF_LOCAL_P (operands[1]))
5705 emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5706 else
5707 emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5708 emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5709 operands[2], lab));
5710 DONE;
5711 }"
5712 [(set_attr "type" "call")
5713 (set (attr "fp_mode")
5714 (if_then_else (eq_attr "fpu_single" "yes")
5715 (const_string "single") (const_string "double")))
5716 (set_attr "needs_delay_slot" "yes")
5717 (set_attr "fp_set" "unknown")])
5718
5719 (define_insn "call_value_compact"
5720 [(set (match_operand 0 "" "=rf")
5721 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5722 (match_operand 2 "" "")))
5723 (match_operand 3 "immediate_operand" "n")
5724 (use (reg:SI R0_REG))
5725 (use (reg:SI R1_REG))
5726 (use (reg:PSI FPSCR_REG))
5727 (clobber (reg:SI PR_REG))]
5728 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5729 "jsr @%1%#"
5730 [(set_attr "type" "call")
5731 (set (attr "fp_mode")
5732 (if_then_else (eq_attr "fpu_single" "yes")
5733 (const_string "single") (const_string "double")))
5734 (set_attr "needs_delay_slot" "yes")])
5735
5736 (define_insn "call_value_compact_rettramp"
5737 [(set (match_operand 0 "" "=rf")
5738 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5739 (match_operand 2 "" "")))
5740 (match_operand 3 "immediate_operand" "n")
5741 (use (reg:SI R0_REG))
5742 (use (reg:SI R1_REG))
5743 (use (reg:PSI FPSCR_REG))
5744 (clobber (reg:SI R10_REG))
5745 (clobber (reg:SI PR_REG))]
5746 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5747 "jsr @%1%#"
5748 [(set_attr "type" "call")
5749 (set (attr "fp_mode")
5750 (if_then_else (eq_attr "fpu_single" "yes")
5751 (const_string "single") (const_string "double")))
5752 (set_attr "needs_delay_slot" "yes")])
5753
5754 (define_insn "call_value_media"
5755 [(set (match_operand 0 "" "=rf")
5756 (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5757 (match_operand 2 "" "")))
5758 (clobber (reg:DI PR_MEDIA_REG))]
5759 "TARGET_SHMEDIA"
5760 "blink %1, r18"
5761 [(set_attr "type" "jump_media")])
5762
5763 (define_expand "call"
5764 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5765 (match_operand 1 "" ""))
5766 (match_operand 2 "" "")
5767 (use (reg:PSI FPSCR_REG))
5768 (clobber (reg:SI PR_REG))])]
5769 ""
5770 "
5771 {
5772 if (TARGET_SHMEDIA)
5773 {
5774 operands[0] = XEXP (operands[0], 0);
5775 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5776 {
5777 if (! SYMBOL_REF_LOCAL_P (operands[0]))
5778 {
5779 rtx reg = gen_reg_rtx (Pmode);
5780
5781 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5782 operands[0] = reg;
5783 }
5784 else
5785 {
5786 operands[0] = gen_sym2PIC (operands[0]);
5787 PUT_MODE (operands[0], Pmode);
5788 }
5789 }
5790 if (GET_MODE (operands[0]) == SImode)
5791 {
5792 if (GET_CODE (operands[0]) == REG)
5793 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5794 else if (GET_CODE (operands[0]) == SUBREG)
5795 {
5796 operands[0] = SUBREG_REG (operands[0]);
5797 if (GET_MODE (operands[0]) != DImode)
5798 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5799 }
5800 else
5801 {
5802 operands[0] = shallow_copy_rtx (operands[0]);
5803 PUT_MODE (operands[0], DImode);
5804 }
5805 }
5806 if (! target_reg_operand (operands[0], DImode))
5807 operands[0] = copy_to_mode_reg (DImode, operands[0]);
5808 emit_call_insn (gen_call_media (operands[0], operands[1]));
5809 DONE;
5810 }
5811 else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5812 {
5813 rtx cookie_rtx = operands[2];
5814 long cookie = INTVAL (cookie_rtx);
5815 rtx func = XEXP (operands[0], 0);
5816 rtx r0, r1;
5817
5818 if (flag_pic)
5819 {
5820 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5821 {
5822 rtx reg = gen_reg_rtx (Pmode);
5823
5824 emit_insn (gen_symGOTPLT2reg (reg, func));
5825 func = reg;
5826 }
5827 else
5828 func = legitimize_pic_address (func, Pmode, 0);
5829 }
5830
5831 r0 = gen_rtx_REG (SImode, R0_REG);
5832 r1 = gen_rtx_REG (SImode, R1_REG);
5833
5834 /* Since such a call function may use all call-clobbered
5835 registers, we force a mode switch earlier, so that we don't
5836 run out of registers when adjusting fpscr for the call. */
5837 emit_insn (gen_force_mode_for_call ());
5838
5839 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5840 if (flag_pic)
5841 {
5842 rtx reg = gen_reg_rtx (Pmode);
5843
5844 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5845 operands[0] = reg;
5846 }
5847 operands[0] = force_reg (SImode, operands[0]);
5848
5849 emit_move_insn (r0, func);
5850 emit_move_insn (r1, cookie_rtx);
5851
5852 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5853 emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5854 operands[2]));
5855 else
5856 emit_call_insn (gen_call_compact (operands[0], operands[1],
5857 operands[2]));
5858
5859 DONE;
5860 }
5861 else if (TARGET_SHCOMPACT && flag_pic
5862 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5863 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5864 {
5865 rtx reg = gen_reg_rtx (Pmode);
5866
5867 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5868 XEXP (operands[0], 0) = reg;
5869 }
5870 if (flag_pic && TARGET_SH2
5871 && GET_CODE (operands[0]) == MEM
5872 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5873 {
5874 emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5875 DONE;
5876 }
5877 else
5878 {
5879 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5880 operands[1] = operands[2];
5881 }
5882
5883 emit_call_insn (gen_calli (operands[0], operands[1]));
5884 DONE;
5885 }")
5886
5887 (define_insn "call_pop_compact"
5888 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5889 (match_operand 1 "" ""))
5890 (match_operand 2 "immediate_operand" "n")
5891 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5892 (match_operand 3 "immediate_operand" "n")))
5893 (use (reg:SI R0_REG))
5894 (use (reg:SI R1_REG))
5895 (use (reg:PSI FPSCR_REG))
5896 (clobber (reg:SI PR_REG))]
5897 "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5898 "jsr @%0%#"
5899 [(set_attr "type" "call")
5900 (set (attr "fp_mode")
5901 (if_then_else (eq_attr "fpu_single" "yes")
5902 (const_string "single") (const_string "double")))
5903 (set_attr "needs_delay_slot" "yes")])
5904
5905 (define_insn "call_pop_compact_rettramp"
5906 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5907 (match_operand 1 "" ""))
5908 (match_operand 2 "immediate_operand" "n")
5909 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5910 (match_operand 3 "immediate_operand" "n")))
5911 (use (reg:SI R0_REG))
5912 (use (reg:SI R1_REG))
5913 (use (reg:PSI FPSCR_REG))
5914 (clobber (reg:SI R10_REG))
5915 (clobber (reg:SI PR_REG))]
5916 "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5917 "jsr @%0%#"
5918 [(set_attr "type" "call")
5919 (set (attr "fp_mode")
5920 (if_then_else (eq_attr "fpu_single" "yes")
5921 (const_string "single") (const_string "double")))
5922 (set_attr "needs_delay_slot" "yes")])
5923
5924 (define_expand "call_pop"
5925 [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5926 (match_operand 1 "" ""))
5927 (match_operand 2 "" "")
5928 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5929 (match_operand 3 "" "")))])]
5930 "TARGET_SHCOMPACT"
5931 "
5932 {
5933 if (operands[2] && INTVAL (operands[2]))
5934 {
5935 rtx cookie_rtx = operands[2];
5936 long cookie = INTVAL (cookie_rtx);
5937 rtx func = XEXP (operands[0], 0);
5938 rtx r0, r1;
5939
5940 if (flag_pic)
5941 {
5942 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5943 {
5944 rtx reg = gen_reg_rtx (Pmode);
5945
5946 emit_insn (gen_symGOTPLT2reg (reg, func));
5947 func = reg;
5948 }
5949 else
5950 func = legitimize_pic_address (func, Pmode, 0);
5951 }
5952
5953 r0 = gen_rtx_REG (SImode, R0_REG);
5954 r1 = gen_rtx_REG (SImode, R1_REG);
5955
5956 /* Since such a call function may use all call-clobbered
5957 registers, we force a mode switch earlier, so that we don't
5958 run out of registers when adjusting fpscr for the call. */
5959 emit_insn (gen_force_mode_for_call ());
5960
5961 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5962 if (flag_pic)
5963 {
5964 rtx reg = gen_reg_rtx (Pmode);
5965
5966 emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5967 operands[0] = reg;
5968 }
5969 operands[0] = force_reg (SImode, operands[0]);
5970
5971 emit_move_insn (r0, func);
5972 emit_move_insn (r1, cookie_rtx);
5973
5974 if (cookie & CALL_COOKIE_RET_TRAMP (1))
5975 emit_call_insn (gen_call_pop_compact_rettramp
5976 (operands[0], operands[1], operands[2], operands[3]));
5977 else
5978 emit_call_insn (gen_call_pop_compact
5979 (operands[0], operands[1], operands[2], operands[3]));
5980
5981 DONE;
5982 }
5983
5984 abort ();
5985 }")
5986
5987 (define_expand "call_value"
5988 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5989 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5990 (match_operand 2 "" "")))
5991 (match_operand 3 "" "")
5992 (use (reg:PSI FPSCR_REG))
5993 (clobber (reg:SI PR_REG))])]
5994 ""
5995 "
5996 {
5997 if (TARGET_SHMEDIA)
5998 {
5999 operands[1] = XEXP (operands[1], 0);
6000 if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6001 {
6002 if (! SYMBOL_REF_LOCAL_P (operands[1]))
6003 {
6004 rtx reg = gen_reg_rtx (Pmode);
6005
6006 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6007 operands[1] = reg;
6008 }
6009 else
6010 {
6011 operands[1] = gen_sym2PIC (operands[1]);
6012 PUT_MODE (operands[1], Pmode);
6013 }
6014 }
6015 if (GET_MODE (operands[1]) == SImode)
6016 {
6017 if (GET_CODE (operands[1]) == REG)
6018 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6019 else if (GET_CODE (operands[1]) == SUBREG)
6020 {
6021 operands[1] = SUBREG_REG (operands[1]);
6022 if (GET_MODE (operands[1]) != DImode)
6023 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6024 }
6025 else
6026 {
6027 operands[1] = shallow_copy_rtx (operands[1]);
6028 PUT_MODE (operands[1], DImode);
6029 }
6030 }
6031 if (! target_reg_operand (operands[1], DImode))
6032 operands[1] = copy_to_mode_reg (DImode, operands[1]);
6033 emit_call_insn (gen_call_value_media (operands[0], operands[1],
6034 operands[2]));
6035 DONE;
6036 }
6037 else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6038 {
6039 rtx cookie_rtx = operands[3];
6040 long cookie = INTVAL (cookie_rtx);
6041 rtx func = XEXP (operands[1], 0);
6042 rtx r0, r1;
6043
6044 if (flag_pic)
6045 {
6046 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6047 {
6048 rtx reg = gen_reg_rtx (Pmode);
6049
6050 emit_insn (gen_symGOTPLT2reg (reg, func));
6051 func = reg;
6052 }
6053 else
6054 func = legitimize_pic_address (func, Pmode, 0);
6055 }
6056
6057 r0 = gen_rtx_REG (SImode, R0_REG);
6058 r1 = gen_rtx_REG (SImode, R1_REG);
6059
6060 /* Since such a call function may use all call-clobbered
6061 registers, we force a mode switch earlier, so that we don't
6062 run out of registers when adjusting fpscr for the call. */
6063 emit_insn (gen_force_mode_for_call ());
6064
6065 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6066 if (flag_pic)
6067 {
6068 rtx reg = gen_reg_rtx (Pmode);
6069
6070 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6071 operands[1] = reg;
6072 }
6073 operands[1] = force_reg (SImode, operands[1]);
6074
6075 emit_move_insn (r0, func);
6076 emit_move_insn (r1, cookie_rtx);
6077
6078 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6079 emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6080 operands[1],
6081 operands[2],
6082 operands[3]));
6083 else
6084 emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6085 operands[2], operands[3]));
6086
6087 DONE;
6088 }
6089 else if (TARGET_SHCOMPACT && flag_pic
6090 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6091 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6092 {
6093 rtx reg = gen_reg_rtx (Pmode);
6094
6095 emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6096 XEXP (operands[1], 0) = reg;
6097 }
6098 if (flag_pic && TARGET_SH2
6099 && GET_CODE (operands[1]) == MEM
6100 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6101 {
6102 emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6103 operands[2]));
6104 DONE;
6105 }
6106 else
6107 operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6108
6109 emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6110 DONE;
6111 }")
6112
6113 (define_insn "sibcalli"
6114 [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6115 (match_operand 1 "" ""))
6116 (use (reg:PSI FPSCR_REG))
6117 (return)]
6118 "TARGET_SH1"
6119 "jmp @%0%#"
6120 [(set_attr "needs_delay_slot" "yes")
6121 (set (attr "fp_mode")
6122 (if_then_else (eq_attr "fpu_single" "yes")
6123 (const_string "single") (const_string "double")))
6124 (set_attr "type" "jump_ind")])
6125
6126 (define_insn "sibcalli_pcrel"
6127 [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6128 (match_operand 1 "" ""))
6129 (use (match_operand 2 "" ""))
6130 (use (reg:PSI FPSCR_REG))
6131 (return)]
6132 "TARGET_SH2"
6133 "braf %0\\n%O2:%#"
6134 [(set_attr "needs_delay_slot" "yes")
6135 (set (attr "fp_mode")
6136 (if_then_else (eq_attr "fpu_single" "yes")
6137 (const_string "single") (const_string "double")))
6138 (set_attr "type" "jump_ind")])
6139
6140 (define_insn_and_split "sibcall_pcrel"
6141 [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6142 (match_operand 1 "" ""))
6143 (use (reg:PSI FPSCR_REG))
6144 (clobber (match_scratch:SI 2 "=k"))
6145 (return)]
6146 "TARGET_SH2"
6147 "#"
6148 "reload_completed"
6149 [(const_int 0)]
6150 "
6151 {
6152 rtx lab = PATTERN (gen_call_site ());
6153 rtx call_insn;
6154
6155 emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6156 call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6157 lab));
6158 SIBLING_CALL_P (call_insn) = 1;
6159 DONE;
6160 }"
6161 [(set_attr "needs_delay_slot" "yes")
6162 (set (attr "fp_mode")
6163 (if_then_else (eq_attr "fpu_single" "yes")
6164 (const_string "single") (const_string "double")))
6165 (set_attr "type" "jump_ind")])
6166
6167 (define_insn "sibcall_compact"
6168 [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6169 (match_operand 1 "" ""))
6170 (return)
6171 (use (match_operand:SI 2 "register_operand" "z,x"))
6172 (use (reg:SI R1_REG))
6173 (use (reg:PSI FPSCR_REG))
6174 ;; We want to make sure the `x' above will only match MACH_REG
6175 ;; because sibcall_epilogue may clobber MACL_REG.
6176 (clobber (reg:SI MACL_REG))]
6177 "TARGET_SHCOMPACT"
6178 "@
6179 jmp @%0%#
6180 jmp @%0\\n sts %2, r0"
6181 [(set_attr "needs_delay_slot" "yes,no")
6182 (set_attr "length" "2,4")
6183 (set (attr "fp_mode") (const_string "single"))
6184 (set_attr "type" "jump_ind")])
6185
6186 (define_insn "sibcall_media"
6187 [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6188 (match_operand 1 "" ""))
6189 (use (reg:SI PR_MEDIA_REG))
6190 (return)]
6191 "TARGET_SHMEDIA"
6192 "blink %0, r63"
6193 [(set_attr "type" "jump_media")])
6194
6195 (define_expand "sibcall"
6196 [(parallel
6197 [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6198 (match_operand 1 "" ""))
6199 (match_operand 2 "" "")
6200 (use (reg:PSI FPSCR_REG))
6201 (return)])]
6202 ""
6203 "
6204 {
6205 if (TARGET_SHMEDIA)
6206 {
6207 operands[0] = XEXP (operands[0], 0);
6208 if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6209 {
6210 if (! SYMBOL_REF_LOCAL_P (operands[0]))
6211 {
6212 rtx reg = gen_reg_rtx (Pmode);
6213
6214 /* We must not use GOTPLT for sibcalls, because PIC_REG
6215 must be restored before the PLT code gets to run. */
6216 emit_insn (gen_symGOT2reg (reg, operands[0]));
6217 operands[0] = reg;
6218 }
6219 else
6220 {
6221 operands[0] = gen_sym2PIC (operands[0]);
6222 PUT_MODE (operands[0], Pmode);
6223 }
6224 }
6225 if (GET_MODE (operands[0]) == SImode)
6226 {
6227 if (GET_CODE (operands[0]) == REG)
6228 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6229 else if (GET_CODE (operands[0]) == SUBREG)
6230 {
6231 operands[0] = SUBREG_REG (operands[0]);
6232 if (GET_MODE (operands[0]) != DImode)
6233 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6234 }
6235 else
6236 {
6237 operands[0] = shallow_copy_rtx (operands[0]);
6238 PUT_MODE (operands[0], DImode);
6239 }
6240 }
6241 if (! target_reg_operand (operands[0], DImode))
6242 operands[0] = copy_to_mode_reg (DImode, operands[0]);
6243 emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6244 DONE;
6245 }
6246 else if (TARGET_SHCOMPACT && operands[2]
6247 && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6248 {
6249 rtx cookie_rtx = operands[2];
6250 long cookie = INTVAL (cookie_rtx);
6251 rtx func = XEXP (operands[0], 0);
6252 rtx mach, r1;
6253
6254 if (flag_pic)
6255 {
6256 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6257 {
6258 rtx reg = gen_reg_rtx (Pmode);
6259
6260 emit_insn (gen_symGOT2reg (reg, func));
6261 func = reg;
6262 }
6263 else
6264 func = legitimize_pic_address (func, Pmode, 0);
6265 }
6266
6267 /* FIXME: if we could tell whether all argument registers are
6268 already taken, we could decide whether to force the use of
6269 MACH_REG or to stick to R0_REG. Unfortunately, there's no
6270 simple way to tell. We could use the CALL_COOKIE, but we
6271 can't currently tell a register used for regular argument
6272 passing from one that is unused. If we leave it up to reload
6273 to decide which register to use, it seems to always choose
6274 R0_REG, which leaves no available registers in SIBCALL_REGS
6275 to hold the address of the trampoline. */
6276 mach = gen_rtx_REG (SImode, MACH_REG);
6277 r1 = gen_rtx_REG (SImode, R1_REG);
6278
6279 /* Since such a call function may use all call-clobbered
6280 registers, we force a mode switch earlier, so that we don't
6281 run out of registers when adjusting fpscr for the call. */
6282 emit_insn (gen_force_mode_for_call ());
6283
6284 operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6285 if (flag_pic)
6286 {
6287 rtx reg = gen_reg_rtx (Pmode);
6288
6289 emit_insn (gen_symGOT2reg (reg, operands[0]));
6290 operands[0] = reg;
6291 }
6292 operands[0] = force_reg (SImode, operands[0]);
6293
6294 /* We don't need a return trampoline, since the callee will
6295 return directly to the upper caller. */
6296 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6297 {
6298 cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6299 cookie_rtx = GEN_INT (cookie);
6300 }
6301
6302 emit_move_insn (mach, func);
6303 emit_move_insn (r1, cookie_rtx);
6304
6305 emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6306 DONE;
6307 }
6308 else if (TARGET_SHCOMPACT && flag_pic
6309 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6310 && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6311 {
6312 rtx reg = gen_reg_rtx (Pmode);
6313
6314 emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6315 XEXP (operands[0], 0) = reg;
6316 }
6317 if (flag_pic && TARGET_SH2
6318 && GET_CODE (operands[0]) == MEM
6319 && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6320 /* The PLT needs the PIC register, but the epilogue would have
6321 to restore it, so we can only use PC-relative PIC calls for
6322 static functions. */
6323 && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6324 {
6325 emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6326 DONE;
6327 }
6328 else
6329 operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6330
6331 emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6332 DONE;
6333 }")
6334
6335 (define_expand "sibcall_value"
6336 [(set (match_operand 0 "" "")
6337 (call (match_operand 1 "" "")
6338 (match_operand 2 "" "")))
6339 (match_operand 3 "" "")]
6340 ""
6341 "
6342 {
6343 emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6344 DONE;
6345 }")
6346
6347 (define_insn "call_value_pop_compact"
6348 [(set (match_operand 0 "" "=rf")
6349 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6350 (match_operand 2 "" "")))
6351 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6352 (match_operand 4 "immediate_operand" "n")))
6353 (match_operand 3 "immediate_operand" "n")
6354 (use (reg:SI R0_REG))
6355 (use (reg:SI R1_REG))
6356 (use (reg:PSI FPSCR_REG))
6357 (clobber (reg:SI PR_REG))]
6358 "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6359 "jsr @%1%#"
6360 [(set_attr "type" "call")
6361 (set (attr "fp_mode")
6362 (if_then_else (eq_attr "fpu_single" "yes")
6363 (const_string "single") (const_string "double")))
6364 (set_attr "needs_delay_slot" "yes")])
6365
6366 (define_insn "call_value_pop_compact_rettramp"
6367 [(set (match_operand 0 "" "=rf")
6368 (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6369 (match_operand 2 "" "")))
6370 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6371 (match_operand 4 "immediate_operand" "n")))
6372 (match_operand 3 "immediate_operand" "n")
6373 (use (reg:SI R0_REG))
6374 (use (reg:SI R1_REG))
6375 (use (reg:PSI FPSCR_REG))
6376 (clobber (reg:SI R10_REG))
6377 (clobber (reg:SI PR_REG))]
6378 "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6379 "jsr @%1%#"
6380 [(set_attr "type" "call")
6381 (set (attr "fp_mode")
6382 (if_then_else (eq_attr "fpu_single" "yes")
6383 (const_string "single") (const_string "double")))
6384 (set_attr "needs_delay_slot" "yes")])
6385
6386 (define_expand "call_value_pop"
6387 [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6388 (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6389 (match_operand 2 "" "")))
6390 (match_operand 3 "" "")
6391 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6392 (match_operand 4 "" "")))])]
6393 "TARGET_SHCOMPACT"
6394 "
6395 {
6396 if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6397 {
6398 rtx cookie_rtx = operands[3];
6399 long cookie = INTVAL (cookie_rtx);
6400 rtx func = XEXP (operands[1], 0);
6401 rtx r0, r1;
6402
6403 if (flag_pic)
6404 {
6405 if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6406 {
6407 rtx reg = gen_reg_rtx (Pmode);
6408
6409 emit_insn (gen_symGOTPLT2reg (reg, func));
6410 func = reg;
6411 }
6412 else
6413 func = legitimize_pic_address (func, Pmode, 0);
6414 }
6415
6416 r0 = gen_rtx_REG (SImode, R0_REG);
6417 r1 = gen_rtx_REG (SImode, R1_REG);
6418
6419 /* Since such a call function may use all call-clobbered
6420 registers, we force a mode switch earlier, so that we don't
6421 run out of registers when adjusting fpscr for the call. */
6422 emit_insn (gen_force_mode_for_call ());
6423
6424 operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6425 if (flag_pic)
6426 {
6427 rtx reg = gen_reg_rtx (Pmode);
6428
6429 emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6430 operands[1] = reg;
6431 }
6432 operands[1] = force_reg (SImode, operands[1]);
6433
6434 emit_move_insn (r0, func);
6435 emit_move_insn (r1, cookie_rtx);
6436
6437 if (cookie & CALL_COOKIE_RET_TRAMP (1))
6438 emit_call_insn (gen_call_value_pop_compact_rettramp
6439 (operands[0], operands[1], operands[2],
6440 operands[3], operands[4]));
6441 else
6442 emit_call_insn (gen_call_value_pop_compact
6443 (operands[0], operands[1], operands[2],
6444 operands[3], operands[4]));
6445
6446 DONE;
6447 }
6448
6449 abort ();
6450 }")
6451
6452 (define_expand "sibcall_epilogue"
6453 [(return)]
6454 ""
6455 "
6456 {
6457 sh_expand_epilogue (1);
6458 if (TARGET_SHCOMPACT)
6459 {
6460 rtx insn, set;
6461
6462 /* If epilogue clobbers r0, preserve it in macl. */
6463 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6464 if ((set = single_set (insn))
6465 && GET_CODE (SET_DEST (set)) == REG
6466 && REGNO (SET_DEST (set)) == R0_REG)
6467 {
6468 rtx r0 = gen_rtx_REG (SImode, R0_REG);
6469 rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6470 rtx i;
6471
6472 /* We can't tell at this point whether the sibcall is a
6473 sibcall_compact and, if it is, whether it uses r0 or
6474 mach as operand 2, so let the instructions that
6475 preserve r0 be optimized away if r0 turns out to be
6476 dead. */
6477 i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6478 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6479 REG_NOTES (i));
6480 i = emit_move_insn (r0, tmp);
6481 REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6482 REG_NOTES (i));
6483 break;
6484 }
6485 }
6486 DONE;
6487 }")
6488
6489 (define_insn "indirect_jump_compact"
6490 [(set (pc)
6491 (match_operand:SI 0 "arith_reg_operand" "r"))]
6492 "TARGET_SH1"
6493 "jmp @%0%#"
6494 [(set_attr "needs_delay_slot" "yes")
6495 (set_attr "type" "jump_ind")])
6496
6497 (define_expand "indirect_jump"
6498 [(set (pc)
6499 (match_operand 0 "register_operand" ""))]
6500 ""
6501 "
6502 {
6503 if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6504 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6505 }")
6506
6507 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6508 ;; which can be present in structured code from indirect jumps which can not
6509 ;; be present in structured code. This allows -fprofile-arcs to work.
6510
6511 ;; For SH1 processors.
6512 (define_insn "casesi_jump_1"
6513 [(set (pc)
6514 (match_operand:SI 0 "register_operand" "r"))
6515 (use (label_ref (match_operand 1 "" "")))]
6516 "TARGET_SH1"
6517 "jmp @%0%#"
6518 [(set_attr "needs_delay_slot" "yes")
6519 (set_attr "type" "jump_ind")])
6520
6521 ;; For all later processors.
6522 (define_insn "casesi_jump_2"
6523 [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6524 (label_ref (match_operand 1 "" ""))))
6525 (use (label_ref (match_operand 2 "" "")))]
6526 "TARGET_SH2
6527 && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6528 "braf %0%#"
6529 [(set_attr "needs_delay_slot" "yes")
6530 (set_attr "type" "jump_ind")])
6531
6532 (define_insn "casesi_jump_media"
6533 [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6534 (use (label_ref (match_operand 1 "" "")))]
6535 "TARGET_SHMEDIA"
6536 "blink %0, r63"
6537 [(set_attr "type" "jump_media")])
6538
6539 ;; Call subroutine returning any type.
6540 ;; ??? This probably doesn't work.
6541
6542 (define_expand "untyped_call"
6543 [(parallel [(call (match_operand 0 "" "")
6544 (const_int 0))
6545 (match_operand 1 "" "")
6546 (match_operand 2 "" "")])]
6547 "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
6548 "
6549 {
6550 int i;
6551
6552 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6553
6554 for (i = 0; i < XVECLEN (operands[2], 0); i++)
6555 {
6556 rtx set = XVECEXP (operands[2], 0, i);
6557 emit_move_insn (SET_DEST (set), SET_SRC (set));
6558 }
6559
6560 /* The optimizer does not know that the call sets the function value
6561 registers we stored in the result block. We avoid problems by
6562 claiming that all hard registers are used and clobbered at this
6563 point. */
6564 emit_insn (gen_blockage ());
6565
6566 DONE;
6567 }")
6568 \f
6569 ;; ------------------------------------------------------------------------
6570 ;; Misc insns
6571 ;; ------------------------------------------------------------------------
6572
6573 (define_insn "dect"
6574 [(set (reg:SI T_REG)
6575 (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6576 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6577 "TARGET_SH2"
6578 "dt %0"
6579 [(set_attr "type" "arith")])
6580
6581 (define_insn "nop"
6582 [(const_int 0)]
6583 ""
6584 "nop")
6585
6586 ;; Load address of a label. This is only generated by the casesi expand,
6587 ;; and by machine_dependent_reorg (fixing up fp moves).
6588 ;; This must use unspec, because this only works for labels that are
6589 ;; within range,
6590
6591 (define_insn "mova"
6592 [(set (reg:SI R0_REG)
6593 (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6594 "TARGET_SH1"
6595 "mova %O0,r0"
6596 [(set_attr "in_delay_slot" "no")
6597 (set_attr "type" "arith")])
6598
6599 ;; machine_dependent_reorg will make this a `mova'.
6600 (define_insn "mova_const"
6601 [(set (reg:SI R0_REG)
6602 (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6603 "TARGET_SH1"
6604 "#"
6605 [(set_attr "in_delay_slot" "no")
6606 (set_attr "type" "arith")])
6607
6608 (define_expand "GOTaddr2picreg"
6609 [(set (reg:SI R0_REG)
6610 (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6611 UNSPEC_MOVA))
6612 (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6613 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6614 "" "
6615 {
6616 operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6617 operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6618
6619 if (TARGET_SH5)
6620 operands[1] = gen_datalabel_ref (operands[1]);
6621
6622 if (TARGET_SHMEDIA)
6623 {
6624 rtx tr = gen_rtx_REG (DImode, TR0_REG);
6625 rtx dipic = operands[0];
6626 rtx lab = PATTERN (gen_call_site ());
6627 rtx insn, equiv;
6628
6629 equiv = operands[1];
6630 operands[1] = gen_rtx_MINUS (DImode,
6631 operands[1],
6632 gen_rtx_CONST
6633 (DImode,
6634 gen_rtx_MINUS (DImode,
6635 gen_rtx_CONST (DImode,
6636 lab),
6637 pc_rtx)));
6638 operands[1] = gen_sym2PIC (operands[1]);
6639 PUT_MODE (operands[1], DImode);
6640
6641 if (GET_MODE (dipic) != DImode)
6642 dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6643
6644 if (TARGET_SHMEDIA64)
6645 emit_insn (gen_movdi_const (dipic, operands[1]));
6646 else
6647 emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6648
6649 emit_insn (gen_ptrel (tr, dipic, lab));
6650
6651 if (GET_MODE (operands[0]) != GET_MODE (tr))
6652 tr = gen_lowpart (GET_MODE (operands[0]), tr);
6653
6654 insn = emit_move_insn (operands[0], tr);
6655
6656 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6657 REG_NOTES (insn));
6658
6659 DONE;
6660 }
6661 }
6662 ")
6663
6664 (define_insn "*ptb"
6665 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6666 (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6667 UNSPEC_DATALABEL)))]
6668 "TARGET_SHMEDIA && flag_pic
6669 && EXTRA_CONSTRAINT_Csy (operands[1])"
6670 "ptb/u datalabel %1, %0"
6671 [(set_attr "type" "pt_media")
6672 (set_attr "length" "*")])
6673
6674 (define_insn "ptrel"
6675 [(set (match_operand:DI 0 "target_reg_operand" "=b")
6676 (plus:DI (match_operand:DI 1 "register_operand" "r")
6677 (pc)))
6678 (match_operand:DI 2 "" "")]
6679 "TARGET_SHMEDIA"
6680 "%O2: ptrel/u %1, %0"
6681 [(set_attr "type" "ptabs_media")])
6682
6683 (define_expand "builtin_setjmp_receiver"
6684 [(match_operand 0 "" "")]
6685 "flag_pic"
6686 "
6687 {
6688 emit_insn (gen_GOTaddr2picreg ());
6689 DONE;
6690 }")
6691
6692 (define_expand "call_site"
6693 [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6694 "TARGET_SH1"
6695 "
6696 {
6697 static HOST_WIDE_INT i = 0;
6698 operands[0] = GEN_INT (i);
6699 i++;
6700 }")
6701
6702 (define_expand "sym_label2reg"
6703 [(set (match_operand:SI 0 "" "")
6704 (const:SI (minus:SI
6705 (const:SI
6706 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6707 (const:SI
6708 (plus:SI
6709 (match_operand:SI 2 "" "")
6710 (const_int 2))))))]
6711 "TARGET_SH1" "")
6712
6713 (define_expand "symGOT_load"
6714 [(set (match_dup 2) (match_operand 1 "" ""))
6715 (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6716 (set (match_operand 0 "" "") (mem (match_dup 3)))]
6717 ""
6718 "
6719 {
6720 rtx insn;
6721
6722 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6723 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6724
6725 if (TARGET_SHMEDIA)
6726 {
6727 rtx reg = operands[2];
6728
6729 if (GET_MODE (reg) != DImode)
6730 reg = gen_rtx_SUBREG (DImode, reg, 0);
6731
6732 if (flag_pic > 1)
6733 emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6734 else
6735 emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6736 }
6737 else
6738 emit_move_insn (operands[2], operands[1]);
6739
6740 emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6741 operands[2],
6742 gen_rtx_REG (Pmode, PIC_REG)));
6743
6744 insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6745
6746 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6747 0), 0, 0),
6748 REG_NOTES (insn));
6749
6750 DONE;
6751 }")
6752
6753 (define_expand "sym2GOT"
6754 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6755 ""
6756 "")
6757
6758 (define_expand "symGOT2reg"
6759 [(match_operand 0 "" "") (match_operand 1 "" "")]
6760 ""
6761 "
6762 {
6763 rtx gotsym, insn;
6764
6765 gotsym = gen_sym2GOT (operands[1]);
6766 PUT_MODE (gotsym, Pmode);
6767 insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6768
6769 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
6770
6771 DONE;
6772 }")
6773
6774 (define_expand "sym2GOTPLT"
6775 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6776 ""
6777 "")
6778
6779 (define_expand "symGOTPLT2reg"
6780 [(match_operand 0 "" "") (match_operand 1 "" "")]
6781 ""
6782 "
6783 {
6784 emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6785 DONE;
6786 }")
6787
6788 (define_expand "sym2GOTOFF"
6789 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6790 ""
6791 "")
6792
6793 (define_expand "symGOTOFF2reg"
6794 [(match_operand 0 "" "") (match_operand 1 "" "")]
6795 ""
6796 "
6797 {
6798 rtx gotoffsym, insn;
6799 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6800
6801 gotoffsym = gen_sym2GOTOFF (operands[1]);
6802 PUT_MODE (gotoffsym, Pmode);
6803 emit_move_insn (t, gotoffsym);
6804 insn = emit_move_insn (operands[0],
6805 gen_rtx_PLUS (Pmode, t,
6806 gen_rtx_REG (Pmode, PIC_REG)));
6807
6808 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6809 REG_NOTES (insn));
6810
6811 DONE;
6812 }")
6813
6814 (define_expand "symPLT_label2reg"
6815 [(set (match_operand:SI 0 "" "")
6816 (const:SI (minus:SI
6817 (const:SI
6818 (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6819 (const:SI
6820 (minus:SI
6821 (const:SI (plus:SI
6822 (match_operand:SI 2 "" "")
6823 (const_int 2)))
6824 (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6825 ;; Even though the PIC register is not really used by the call
6826 ;; sequence in which this is expanded, the PLT code assumes the PIC
6827 ;; register is set, so we must not skip its initialization. Since
6828 ;; we only use this expand as part of calling sequences, and never
6829 ;; to take the address of a function, this is the best point to
6830 ;; insert the (use). Using the PLT to take the address of a
6831 ;; function would be wrong, not only because the PLT entry could
6832 ;; then be called from a function that doesn't initialize the PIC
6833 ;; register to the proper GOT, but also because pointers to the
6834 ;; same function might not compare equal, should they be set by
6835 ;; different shared libraries.
6836 (use (reg:SI PIC_REG))]
6837 "TARGET_SH1"
6838 "")
6839
6840 (define_expand "sym2PIC"
6841 [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6842 ""
6843 "")
6844
6845 ;; TLS code generation.
6846 ;; ??? this should be a define_insn_and_split
6847 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6848 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6849 ;; for details.
6850
6851 (define_insn "tls_global_dynamic"
6852 [(set (match_operand:SI 0 "register_operand" "=&z")
6853 (call (unspec:SI [(match_operand:SI 1 "" "")]
6854 UNSPEC_TLSGD)
6855 (const_int 0)))
6856 (use (reg:PSI FPSCR_REG))
6857 (use (reg:SI PIC_REG))
6858 (clobber (reg:SI PR_REG))
6859 (clobber (scratch:SI))]
6860 "TARGET_SH1"
6861 "*
6862 {
6863 return \"\\
6864 mov.l\\t1f,r4\\n\\
6865 \\tmova\\t2f,r0\\n\\
6866 \\tmov.l\\t2f,r1\\n\\
6867 \\tadd\\tr0,r1\\n\\
6868 \\tjsr\\t@r1\\n\\
6869 \\tadd\\tr12,r4\\n\\
6870 \\tbra\\t3f\\n\\
6871 \\tnop\\n\\
6872 \\t.align\\t2\\n\\
6873 1:\\t.long\\t%a1@TLSGD\\n\\
6874 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6875 3:\";
6876 }"
6877 [(set_attr "type" "tls_load")
6878 (set_attr "length" "26")])
6879
6880 (define_insn "tls_local_dynamic"
6881 [(set (match_operand:SI 0 "register_operand" "=&z")
6882 (call (unspec:SI [(match_operand:SI 1 "" "")]
6883 UNSPEC_TLSLDM)
6884 (const_int 0)))
6885 (use (reg:PSI FPSCR_REG))
6886 (use (reg:SI PIC_REG))
6887 (clobber (reg:SI PR_REG))
6888 (clobber (scratch:SI))]
6889 "TARGET_SH1"
6890 "*
6891 {
6892 return \"\\
6893 mov.l\\t1f,r4\\n\\
6894 \\tmova\\t2f,r0\\n\\
6895 \\tmov.l\\t2f,r1\\n\\
6896 \\tadd\\tr0,r1\\n\\
6897 \\tjsr\\t@r1\\n\\
6898 \\tadd\\tr12,r4\\n\\
6899 \\tbra\\t3f\\n\\
6900 \\tnop\\n\\
6901 \\t.align\\t2\\n\\
6902 1:\\t.long\\t%a1@TLSLDM\\n\\
6903 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6904 3:\";
6905 }"
6906 [(set_attr "type" "tls_load")
6907 (set_attr "length" "26")])
6908
6909 (define_expand "sym2DTPOFF"
6910 [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6911 ""
6912 "")
6913
6914 (define_expand "symDTPOFF2reg"
6915 [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6916 ""
6917 "
6918 {
6919 rtx dtpoffsym, insn;
6920 rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6921
6922 dtpoffsym = gen_sym2DTPOFF (operands[1]);
6923 PUT_MODE (dtpoffsym, Pmode);
6924 emit_move_insn (t, dtpoffsym);
6925 insn = emit_move_insn (operands[0],
6926 gen_rtx_PLUS (Pmode, t, operands[2]));
6927 DONE;
6928 }")
6929
6930 (define_expand "sym2GOTTPOFF"
6931 [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6932 ""
6933 "")
6934
6935 (define_insn "tls_initial_exec"
6936 [(set (match_operand:SI 0 "register_operand" "=&r")
6937 (unspec:SI [(match_operand:SI 1 "" "")]
6938 UNSPEC_TLSIE))
6939 (use (reg:SI GBR_REG))
6940 (use (reg:SI PIC_REG))
6941 (clobber (reg:SI R0_REG))]
6942 ""
6943 "*
6944 {
6945 return \"\\
6946 mov.l\\t1f,r0\\n\\
6947 \\tstc\\tgbr,%0\\n\\
6948 \\tmov.l\\t@(r0,r12),r0\\n\\
6949 \\tbra\\t2f\\n\\
6950 \\tadd\\tr0,%0\\n\\
6951 \\t.align\\t2\\n\\
6952 1:\\t.long\\t%a1\\n\\
6953 2:\";
6954 }"
6955 [(set_attr "type" "tls_load")
6956 (set_attr "length" "16")])
6957
6958 (define_expand "sym2TPOFF"
6959 [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6960 ""
6961 "")
6962
6963 (define_expand "symTPOFF2reg"
6964 [(match_operand 0 "" "") (match_operand 1 "" "")]
6965 ""
6966 "
6967 {
6968 rtx tpoffsym, insn;
6969
6970 tpoffsym = gen_sym2TPOFF (operands[1]);
6971 PUT_MODE (tpoffsym, Pmode);
6972 insn = emit_move_insn (operands[0], tpoffsym);
6973 DONE;
6974 }")
6975
6976 (define_insn "load_gbr"
6977 [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6978 (use (reg:SI GBR_REG))]
6979 ""
6980 "stc gbr,%0"
6981 [(set_attr "type" "tls_load")])
6982
6983 ;; case instruction for switch statements.
6984
6985 ;; Operand 0 is index
6986 ;; operand 1 is the minimum bound
6987 ;; operand 2 is the maximum bound - minimum bound + 1
6988 ;; operand 3 is CODE_LABEL for the table;
6989 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6990
6991 (define_expand "casesi"
6992 [(match_operand:SI 0 "arith_reg_operand" "")
6993 (match_operand:SI 1 "arith_reg_operand" "")
6994 (match_operand:SI 2 "arith_reg_operand" "")
6995 (match_operand 3 "" "") (match_operand 4 "" "")]
6996 ""
6997 "
6998 {
6999 rtx reg = gen_reg_rtx (SImode);
7000 rtx reg2 = gen_reg_rtx (SImode);
7001 if (TARGET_SHMEDIA)
7002 {
7003 rtx reg = gen_reg_rtx (DImode);
7004 rtx reg2 = gen_reg_rtx (DImode);
7005 rtx reg3 = gen_reg_rtx (DImode);
7006 rtx reg4 = gen_reg_rtx (DImode);
7007 rtx reg5 = gen_reg_rtx (DImode);
7008
7009 operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7010 operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7011 operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7012
7013 emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7014 emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7015 emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7016 emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7017 emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7018 (DImode, operands[3])));
7019 emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7020 emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7021 emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7022 emit_barrier ();
7023 DONE;
7024 }
7025 operands[1] = copy_to_mode_reg (SImode, operands[1]);
7026 operands[2] = copy_to_mode_reg (SImode, operands[2]);
7027 /* If optimizing, casesi_worker depends on the mode of the instruction
7028 before label it 'uses' - operands[3]. */
7029 emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7030 reg));
7031 emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7032 if (TARGET_SH2)
7033 emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7034 else
7035 emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7036 /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7037 operands[3], but to lab. We will fix this up in
7038 machine_dependent_reorg. */
7039 emit_barrier ();
7040 DONE;
7041 }")
7042
7043 (define_expand "casesi_0"
7044 [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7045 (set (match_dup 4) (minus:SI (match_dup 4)
7046 (match_operand:SI 1 "arith_operand" "")))
7047 (set (reg:SI T_REG)
7048 (gtu:SI (match_dup 4)
7049 (match_operand:SI 2 "arith_reg_operand" "")))
7050 (set (pc)
7051 (if_then_else (ne (reg:SI T_REG)
7052 (const_int 0))
7053 (label_ref (match_operand 3 "" ""))
7054 (pc)))]
7055 "TARGET_SH1"
7056 "")
7057
7058 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7059 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7060 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7061
7062 (define_insn "casesi_worker_0"
7063 [(set (match_operand:SI 0 "register_operand" "=r,r")
7064 (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7065 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7066 (clobber (match_scratch:SI 3 "=X,1"))
7067 (clobber (match_scratch:SI 4 "=&z,z"))]
7068 "TARGET_SH1"
7069 "#")
7070
7071 (define_split
7072 [(set (match_operand:SI 0 "register_operand" "")
7073 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7074 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7075 (clobber (match_scratch:SI 3 ""))
7076 (clobber (match_scratch:SI 4 ""))]
7077 "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7078 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7079 (parallel [(set (match_dup 0)
7080 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7081 (label_ref (match_dup 2))] UNSPEC_CASESI))
7082 (clobber (match_dup 3))])
7083 (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7084 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7085
7086 (define_split
7087 [(set (match_operand:SI 0 "register_operand" "")
7088 (unspec:SI [(match_operand:SI 1 "register_operand" "")
7089 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7090 (clobber (match_scratch:SI 3 ""))
7091 (clobber (match_scratch:SI 4 ""))]
7092 "TARGET_SH2 && reload_completed"
7093 [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7094 (parallel [(set (match_dup 0)
7095 (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7096 (label_ref (match_dup 2))] UNSPEC_CASESI))
7097 (clobber (match_dup 3))])]
7098 "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7099
7100 (define_insn "casesi_worker_1"
7101 [(set (match_operand:SI 0 "register_operand" "=r,r")
7102 (unspec:SI [(reg:SI R0_REG)
7103 (match_operand:SI 1 "register_operand" "0,r")
7104 (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7105 (clobber (match_scratch:SI 3 "=X,1"))]
7106 "TARGET_SH1"
7107 "*
7108 {
7109 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7110
7111 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7112 abort ();
7113
7114 switch (GET_MODE (diff_vec))
7115 {
7116 case SImode:
7117 return \"shll2 %1\;mov.l @(r0,%1),%0\";
7118 case HImode:
7119 return \"add %1,%1\;mov.w @(r0,%1),%0\";
7120 case QImode:
7121 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7122 return \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7123 return \"mov.b @(r0,%1),%0\";
7124 default:
7125 abort ();
7126 }
7127 }"
7128 [(set_attr "length" "4")])
7129
7130 (define_insn "casesi_worker_2"
7131 [(set (match_operand:SI 0 "register_operand" "=r,r")
7132 (unspec:SI [(reg:SI R0_REG)
7133 (match_operand:SI 1 "register_operand" "0,r")
7134 (label_ref (match_operand 2 "" ""))
7135 (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7136 (clobber (match_operand:SI 4 "" "=X,1"))]
7137 "TARGET_SH2 && reload_completed && flag_pic"
7138 "*
7139 {
7140 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7141 const char *load;
7142
7143 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7144 abort ();
7145
7146 switch (GET_MODE (diff_vec))
7147 {
7148 case SImode:
7149 output_asm_insn (\"shll2 %1\", operands);
7150 load = \"mov.l @(r0,%1),%0\"; break;
7151 case HImode:
7152 output_asm_insn (\"add %1,%1\", operands);
7153 load = \"mov.w @(r0,%1),%0\"; break;
7154 case QImode:
7155 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7156 load = \"mov.b @(r0,%1),%0\;extu.b %0,%0\";
7157 else
7158 load = \"mov.b @(r0,%1),%0\";
7159 break;
7160 default:
7161 abort ();
7162 }
7163 output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7164 return load;
7165 }"
7166 [(set_attr "length" "8")])
7167
7168 (define_insn "casesi_shift_media"
7169 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7170 (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7171 (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7172 UNSPEC_CASESI)))]
7173 "TARGET_SHMEDIA"
7174 "*
7175 {
7176 rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7177
7178 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7179 abort ();
7180
7181 switch (GET_MODE (diff_vec))
7182 {
7183 case SImode:
7184 return \"shlli %1, 2, %0\";
7185 case HImode:
7186 return \"shlli %1, 1, %0\";
7187 case QImode:
7188 if (rtx_equal_p (operands[0], operands[1]))
7189 return \"\";
7190 return \"add %1, r63, %0\";
7191 default:
7192 abort ();
7193 }
7194 }"
7195 [(set_attr "type" "arith_media")])
7196
7197 (define_insn "casesi_load_media"
7198 [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7199 (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7200 (match_operand 2 "arith_reg_operand" "r")
7201 (label_ref:DI (match_operand 3 "" ""))] 2)))]
7202 "TARGET_SHMEDIA"
7203 "*
7204 {
7205 rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7206
7207 if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7208 abort ();
7209
7210 switch (GET_MODE (diff_vec))
7211 {
7212 case SImode:
7213 return \"ldx.l %1, %2, %0\";
7214 case HImode:
7215 #if 0
7216 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7217 return \"ldx.uw %1, %2, %0\";
7218 #endif
7219 return \"ldx.w %1, %2, %0\";
7220 case QImode:
7221 if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7222 return \"ldx.ub %1, %2, %0\";
7223 return \"ldx.b %1, %2, %0\";
7224 default:
7225 abort ();
7226 }
7227 }"
7228 [(set_attr "type" "load_media")])
7229
7230 (define_expand "return"
7231 [(return)]
7232 "reload_completed && ! sh_need_epilogue ()"
7233 "
7234 {
7235 if (TARGET_SHMEDIA)
7236 {
7237 emit_jump_insn (gen_return_media ());
7238 DONE;
7239 }
7240
7241 if (TARGET_SHCOMPACT
7242 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7243 {
7244 emit_jump_insn (gen_shcompact_return_tramp ());
7245 DONE;
7246 }
7247 }")
7248
7249 (define_insn "*return_i"
7250 [(return)]
7251 "TARGET_SH1 && ! (TARGET_SHCOMPACT
7252 && (current_function_args_info.call_cookie
7253 & CALL_COOKIE_RET_TRAMP (1)))
7254 && reload_completed"
7255 "%@ %#"
7256 [(set_attr "type" "return")
7257 (set_attr "needs_delay_slot" "yes")])
7258
7259 (define_expand "shcompact_return_tramp"
7260 [(return)]
7261 "TARGET_SHCOMPACT
7262 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7263 "
7264 {
7265 rtx reg = gen_rtx_REG (Pmode, R0_REG);
7266 rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7267
7268 if (flag_pic)
7269 emit_insn (gen_symGOTPLT2reg (reg, sym));
7270 else
7271 emit_move_insn (reg, sym);
7272
7273 emit_jump_insn (gen_shcompact_return_tramp_i ());
7274 DONE;
7275 }")
7276
7277 (define_insn "shcompact_return_tramp_i"
7278 [(parallel [(return) (use (reg:SI R0_REG))])]
7279 "TARGET_SHCOMPACT
7280 && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7281 "jmp @r0%#"
7282 [(set_attr "type" "jump_ind")
7283 (set_attr "needs_delay_slot" "yes")])
7284
7285 (define_insn "return_media_i"
7286 [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7287 "TARGET_SHMEDIA && reload_completed"
7288 "blink %0, r63"
7289 [(set_attr "type" "jump_media")])
7290
7291 (define_insn "return_media_rte"
7292 [(return)]
7293 "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7294 "rte"
7295 [(set_attr "type" "jump_media")])
7296
7297 (define_expand "return_media"
7298 [(return)]
7299 "TARGET_SHMEDIA && reload_completed"
7300 "
7301 {
7302 int tr_regno = sh_media_register_for_return ();
7303 rtx tr;
7304
7305 if (current_function_interrupt)
7306 {
7307 emit_jump_insn (gen_return_media_rte ());
7308 DONE;
7309 }
7310 if (tr_regno < 0)
7311 {
7312 rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7313
7314 if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7315 abort ();
7316 tr_regno = TR0_REG;
7317 tr = gen_rtx_REG (DImode, tr_regno);
7318 emit_move_insn (tr, r18);
7319 }
7320 else
7321 tr = gen_rtx_REG (DImode, tr_regno);
7322
7323 emit_jump_insn (gen_return_media_i (tr));
7324 DONE;
7325 }")
7326
7327 (define_insn "shcompact_preserve_incoming_args"
7328 [(set (match_operand:SI 0 "register_operand" "+r")
7329 (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7330 "TARGET_SHCOMPACT"
7331 ""
7332 [(set_attr "length" "0")])
7333
7334 (define_insn "shcompact_incoming_args"
7335 [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7336 (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7337 (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7338 (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7339 (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7340 (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7341 (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7342 (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7343 (set (mem:BLK (reg:SI MACL_REG))
7344 (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7345 (use (reg:SI R0_REG))
7346 (clobber (reg:SI R0_REG))
7347 (clobber (reg:SI MACL_REG))
7348 (clobber (reg:SI MACH_REG))
7349 (clobber (reg:SI PR_REG))]
7350 "TARGET_SHCOMPACT"
7351 "jsr @r0%#"
7352 [(set_attr "needs_delay_slot" "yes")])
7353
7354 (define_insn "shmedia_save_restore_regs_compact"
7355 [(set (reg:SI SP_REG)
7356 (plus:SI (reg:SI SP_REG)
7357 (match_operand:SI 0 "immediate_operand" "i")))
7358 (use (reg:SI R0_REG))
7359 (clobber (reg:SI PR_REG))]
7360 "TARGET_SHCOMPACT
7361 && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7362 || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7363 "jsr @r0%#"
7364 [(set_attr "needs_delay_slot" "yes")])
7365
7366 (define_expand "prologue"
7367 [(const_int 0)]
7368 ""
7369 "sh_expand_prologue (); DONE;")
7370
7371 (define_expand "epilogue"
7372 [(return)]
7373 ""
7374 "
7375 {
7376 sh_expand_epilogue (0);
7377 emit_jump_insn (gen_return ());
7378 DONE;
7379 }")
7380
7381 (define_expand "eh_return"
7382 [(use (match_operand 0 "register_operand" ""))]
7383 ""
7384 {
7385 rtx ra = operands[0];
7386
7387 if (TARGET_SHMEDIA64)
7388 emit_insn (gen_eh_set_ra_di (ra));
7389 else
7390 emit_insn (gen_eh_set_ra_si (ra));
7391
7392 DONE;
7393 })
7394
7395 ;; Clobber the return address on the stack. We can't expand this
7396 ;; until we know where it will be put in the stack frame.
7397
7398 (define_insn "eh_set_ra_si"
7399 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7400 (clobber (match_scratch:SI 1 "=&r"))]
7401 "! TARGET_SHMEDIA64"
7402 "#")
7403
7404 (define_insn "eh_set_ra_di"
7405 [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7406 (clobber (match_scratch:DI 1 "=&r"))]
7407 "TARGET_SHMEDIA64"
7408 "#")
7409
7410 (define_split
7411 [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7412 (clobber (match_scratch 1 ""))]
7413 "reload_completed"
7414 [(const_int 0)]
7415 "
7416 {
7417 sh_set_return_address (operands[0], operands[1]);
7418 DONE;
7419 }")
7420
7421 (define_insn "blockage"
7422 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7423 ""
7424 ""
7425 [(set_attr "length" "0")])
7426 \f
7427 ;; ------------------------------------------------------------------------
7428 ;; Scc instructions
7429 ;; ------------------------------------------------------------------------
7430
7431 (define_insn "movt"
7432 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7433 (eq:SI (reg:SI T_REG) (const_int 1)))]
7434 "TARGET_SH1"
7435 "movt %0"
7436 [(set_attr "type" "arith")])
7437
7438 (define_expand "seq"
7439 [(set (match_operand:SI 0 "arith_reg_operand" "")
7440 (match_dup 1))]
7441 ""
7442 "
7443 {
7444 if (TARGET_SHMEDIA)
7445 {
7446 if (GET_MODE (operands[0]) != DImode)
7447 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7448 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7449 if (sh_compare_op1 != const0_rtx)
7450 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7451 ? GET_MODE (sh_compare_op0)
7452 : GET_MODE (sh_compare_op1),
7453 sh_compare_op1);
7454
7455 switch (GET_MODE (sh_compare_op0))
7456 {
7457 case DImode:
7458 emit_insn (gen_cmpeqdi_media (operands[0],
7459 sh_compare_op0, sh_compare_op1));
7460 break;
7461
7462 case SFmode:
7463 if (! TARGET_SHMEDIA_FPU)
7464 FAIL;
7465 emit_insn (gen_cmpeqsf_media (operands[0],
7466 sh_compare_op0, sh_compare_op1));
7467 break;
7468
7469 case DFmode:
7470 if (! TARGET_SHMEDIA_FPU)
7471 FAIL;
7472 emit_insn (gen_cmpeqdf_media (operands[0],
7473 sh_compare_op0, sh_compare_op1));
7474 break;
7475
7476 default:
7477 FAIL;
7478 }
7479 DONE;
7480 }
7481 if (sh_expand_t_scc (EQ, operands[0]))
7482 DONE;
7483 if (! currently_expanding_to_rtl)
7484 FAIL;
7485 operands[1] = prepare_scc_operands (EQ);
7486 }")
7487
7488 (define_expand "slt"
7489 [(set (match_operand:SI 0 "arith_reg_operand" "")
7490 (match_dup 1))]
7491 ""
7492 "
7493 {
7494 if (TARGET_SHMEDIA)
7495 {
7496 if (GET_MODE (operands[0]) != DImode)
7497 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7498 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7499 if (sh_compare_op1 != const0_rtx)
7500 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7501 ? GET_MODE (sh_compare_op0)
7502 : GET_MODE (sh_compare_op1),
7503 sh_compare_op1);
7504
7505 switch (GET_MODE (sh_compare_op0))
7506 {
7507 case DImode:
7508 emit_insn (gen_cmpgtdi_media (operands[0],
7509 sh_compare_op1, sh_compare_op0));
7510 break;
7511
7512 case SFmode:
7513 if (! TARGET_SHMEDIA_FPU)
7514 FAIL;
7515 emit_insn (gen_cmpgtsf_media (operands[0],
7516 sh_compare_op1, sh_compare_op0));
7517 break;
7518
7519 case DFmode:
7520 if (! TARGET_SHMEDIA_FPU)
7521 FAIL;
7522 emit_insn (gen_cmpgtdf_media (operands[0],
7523 sh_compare_op1, sh_compare_op0));
7524 break;
7525
7526 default:
7527 FAIL;
7528 }
7529 DONE;
7530 }
7531 if (! currently_expanding_to_rtl)
7532 FAIL;
7533 operands[1] = prepare_scc_operands (LT);
7534 }")
7535
7536 (define_expand "sle"
7537 [(match_operand:SI 0 "arith_reg_operand" "")]
7538 ""
7539 "
7540 {
7541 rtx tmp = sh_compare_op0;
7542
7543 if (TARGET_SHMEDIA)
7544 {
7545 if (GET_MODE (operands[0]) != DImode)
7546 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7547 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7548 if (sh_compare_op1 != const0_rtx)
7549 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7550 ? GET_MODE (sh_compare_op0)
7551 : GET_MODE (sh_compare_op1),
7552 sh_compare_op1);
7553
7554 switch (GET_MODE (sh_compare_op0))
7555 {
7556 case DImode:
7557 {
7558 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7559
7560 emit_insn (gen_cmpgtdi_media (tmp,
7561 sh_compare_op0, sh_compare_op1));
7562 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7563 break;
7564 }
7565
7566 case SFmode:
7567 if (! TARGET_SHMEDIA_FPU)
7568 FAIL;
7569 emit_insn (gen_cmpgesf_media (operands[0],
7570 sh_compare_op1, sh_compare_op0));
7571 break;
7572
7573 case DFmode:
7574 if (! TARGET_SHMEDIA_FPU)
7575 FAIL;
7576 emit_insn (gen_cmpgedf_media (operands[0],
7577 sh_compare_op1, sh_compare_op0));
7578 break;
7579
7580 default:
7581 FAIL;
7582 }
7583 DONE;
7584 }
7585
7586 sh_compare_op0 = sh_compare_op1;
7587 sh_compare_op1 = tmp;
7588 emit_insn (gen_sge (operands[0]));
7589 DONE;
7590 }")
7591
7592 (define_expand "sgt"
7593 [(set (match_operand:SI 0 "arith_reg_operand" "")
7594 (match_dup 1))]
7595 ""
7596 "
7597 {
7598 if (TARGET_SHMEDIA)
7599 {
7600 if (GET_MODE (operands[0]) != DImode)
7601 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7602 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7603 if (sh_compare_op1 != const0_rtx)
7604 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7605 ? GET_MODE (sh_compare_op0)
7606 : GET_MODE (sh_compare_op1),
7607 sh_compare_op1);
7608
7609 switch (GET_MODE (sh_compare_op0))
7610 {
7611 case DImode:
7612 emit_insn (gen_cmpgtdi_media (operands[0],
7613 sh_compare_op0, sh_compare_op1));
7614 break;
7615
7616 case SFmode:
7617 if (! TARGET_SHMEDIA_FPU)
7618 FAIL;
7619 emit_insn (gen_cmpgtsf_media (operands[0],
7620 sh_compare_op0, sh_compare_op1));
7621 break;
7622
7623 case DFmode:
7624 if (! TARGET_SHMEDIA_FPU)
7625 FAIL;
7626 emit_insn (gen_cmpgtdf_media (operands[0],
7627 sh_compare_op0, sh_compare_op1));
7628 break;
7629
7630 default:
7631 FAIL;
7632 }
7633 DONE;
7634 }
7635 if (! currently_expanding_to_rtl)
7636 FAIL;
7637 operands[1] = prepare_scc_operands (GT);
7638 }")
7639
7640 (define_expand "sge"
7641 [(set (match_operand:SI 0 "arith_reg_operand" "")
7642 (match_dup 1))]
7643 ""
7644 "
7645 {
7646 if (TARGET_SHMEDIA)
7647 {
7648 if (GET_MODE (operands[0]) != DImode)
7649 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7650 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7651 if (sh_compare_op1 != const0_rtx)
7652 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7653 ? GET_MODE (sh_compare_op0)
7654 : GET_MODE (sh_compare_op1),
7655 sh_compare_op1);
7656
7657 switch (GET_MODE (sh_compare_op0))
7658 {
7659 case DImode:
7660 {
7661 rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7662
7663 emit_insn (gen_cmpgtdi_media (tmp,
7664 sh_compare_op1, sh_compare_op0));
7665 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7666 break;
7667 }
7668
7669 case SFmode:
7670 if (! TARGET_SHMEDIA_FPU)
7671 FAIL;
7672 emit_insn (gen_cmpgesf_media (operands[0],
7673 sh_compare_op0, sh_compare_op1));
7674 break;
7675
7676 case DFmode:
7677 if (! TARGET_SHMEDIA_FPU)
7678 FAIL;
7679 emit_insn (gen_cmpgedf_media (operands[0],
7680 sh_compare_op0, sh_compare_op1));
7681 break;
7682
7683 default:
7684 FAIL;
7685 }
7686 DONE;
7687 }
7688
7689 if (! currently_expanding_to_rtl)
7690 FAIL;
7691 if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7692 {
7693 if (TARGET_IEEE)
7694 {
7695 rtx lab = gen_label_rtx ();
7696 prepare_scc_operands (EQ);
7697 emit_jump_insn (gen_branch_true (lab));
7698 prepare_scc_operands (GT);
7699 emit_label (lab);
7700 emit_insn (gen_movt (operands[0]));
7701 }
7702 else
7703 emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7704 DONE;
7705 }
7706 operands[1] = prepare_scc_operands (GE);
7707 }")
7708
7709 (define_expand "sgtu"
7710 [(set (match_operand:SI 0 "arith_reg_operand" "")
7711 (match_dup 1))]
7712 ""
7713 "
7714 {
7715 if (TARGET_SHMEDIA)
7716 {
7717 if (GET_MODE (operands[0]) != DImode)
7718 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7719 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7720 if (sh_compare_op1 != const0_rtx)
7721 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7722 ? GET_MODE (sh_compare_op0)
7723 : GET_MODE (sh_compare_op1),
7724 sh_compare_op1);
7725
7726 emit_insn (gen_cmpgtudi_media (operands[0],
7727 sh_compare_op0, sh_compare_op1));
7728 DONE;
7729 }
7730 if (! currently_expanding_to_rtl)
7731 FAIL;
7732 operands[1] = prepare_scc_operands (GTU);
7733 }")
7734
7735 (define_expand "sltu"
7736 [(set (match_operand:SI 0 "arith_reg_operand" "")
7737 (match_dup 1))]
7738 ""
7739 "
7740 {
7741 if (TARGET_SHMEDIA)
7742 {
7743 if (GET_MODE (operands[0]) != DImode)
7744 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7745 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7746 if (sh_compare_op1 != const0_rtx)
7747 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7748 ? GET_MODE (sh_compare_op0)
7749 : GET_MODE (sh_compare_op1),
7750 sh_compare_op1);
7751
7752 emit_insn (gen_cmpgtudi_media (operands[0],
7753 sh_compare_op1, sh_compare_op0));
7754 DONE;
7755 }
7756 if (! currently_expanding_to_rtl)
7757 FAIL;
7758 operands[1] = prepare_scc_operands (LTU);
7759 }")
7760
7761 (define_expand "sleu"
7762 [(set (match_operand:SI 0 "arith_reg_operand" "")
7763 (match_dup 1))]
7764 ""
7765 "
7766 {
7767 if (TARGET_SHMEDIA)
7768 {
7769 rtx tmp;
7770
7771 if (GET_MODE (operands[0]) != DImode)
7772 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7773 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7774 if (sh_compare_op1 != const0_rtx)
7775 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7776 ? GET_MODE (sh_compare_op0)
7777 : GET_MODE (sh_compare_op1),
7778 sh_compare_op1);
7779
7780 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7781
7782 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7783 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7784
7785 DONE;
7786 }
7787 if (! currently_expanding_to_rtl)
7788 FAIL;
7789 operands[1] = prepare_scc_operands (LEU);
7790 }")
7791
7792 (define_expand "sgeu"
7793 [(set (match_operand:SI 0 "arith_reg_operand" "")
7794 (match_dup 1))]
7795 ""
7796 "
7797 {
7798 if (TARGET_SHMEDIA)
7799 {
7800 rtx tmp;
7801
7802 if (GET_MODE (operands[0]) != DImode)
7803 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7804 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7805 if (sh_compare_op1 != const0_rtx)
7806 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7807 ? GET_MODE (sh_compare_op0)
7808 : GET_MODE (sh_compare_op1),
7809 sh_compare_op1);
7810
7811 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7812
7813 emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7814 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7815
7816 DONE;
7817 }
7818
7819 if (! currently_expanding_to_rtl)
7820 FAIL;
7821 operands[1] = prepare_scc_operands (GEU);
7822 }")
7823
7824 ;; sne moves the complement of the T reg to DEST like this:
7825 ;; cmp/eq ...
7826 ;; mov #-1,temp
7827 ;; negc temp,dest
7828 ;; This is better than xoring compare result with 1 because it does
7829 ;; not require r0 and further, the -1 may be CSE-ed or lifted out of a
7830 ;; loop.
7831
7832 (define_expand "sne"
7833 [(set (match_dup 2) (const_int -1))
7834 (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7835 (neg:SI (plus:SI (match_dup 1)
7836 (match_dup 2))))
7837 (set (reg:SI T_REG)
7838 (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7839 (const_int 0)))])]
7840 ""
7841 "
7842 {
7843 if (TARGET_SHMEDIA)
7844 {
7845 rtx tmp;
7846
7847 if (GET_MODE (operands[0]) != DImode)
7848 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7849
7850 if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7851 FAIL;
7852
7853 sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7854 if (sh_compare_op1 != const0_rtx)
7855 sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7856 ? GET_MODE (sh_compare_op0)
7857 : GET_MODE (sh_compare_op1),
7858 sh_compare_op1);
7859
7860 tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7861
7862 emit_insn (gen_seq (tmp));
7863 emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7864
7865 DONE;
7866 }
7867
7868 if (sh_expand_t_scc (NE, operands[0]))
7869 DONE;
7870 if (! currently_expanding_to_rtl)
7871 FAIL;
7872 operands[1] = prepare_scc_operands (EQ);
7873 operands[2] = gen_reg_rtx (SImode);
7874 }")
7875
7876 (define_expand "sunordered"
7877 [(set (match_operand:DI 0 "arith_reg_operand" "")
7878 (unordered:DI (match_dup 1) (match_dup 2)))]
7879 "TARGET_SHMEDIA_FPU"
7880 "
7881 {
7882 operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7883 operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7884 }")
7885
7886 ;; Use the same trick for FP sle / sge
7887 (define_expand "movnegt"
7888 [(set (match_dup 2) (const_int -1))
7889 (parallel [(set (match_operand 0 "" "")
7890 (neg:SI (plus:SI (match_dup 1)
7891 (match_dup 2))))
7892 (set (reg:SI T_REG)
7893 (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7894 (const_int 0)))])]
7895 "TARGET_SH1"
7896 "operands[2] = gen_reg_rtx (SImode);")
7897
7898 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7899 ;; This prevents a regression that occurred when we switched from xor to
7900 ;; mov/neg for sne.
7901
7902 (define_split
7903 [(set (match_operand:SI 0 "arith_reg_operand" "")
7904 (plus:SI (reg:SI T_REG)
7905 (const_int -1)))]
7906 "TARGET_SH1"
7907 [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7908 (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7909 "")
7910
7911 ;; -------------------------------------------------------------------------
7912 ;; Instructions to cope with inline literal tables
7913 ;; -------------------------------------------------------------------------
7914
7915 ; 2 byte integer in line
7916
7917 (define_insn "consttable_2"
7918 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7919 (match_operand 1 "" "")]
7920 UNSPECV_CONST2)]
7921 ""
7922 "*
7923 {
7924 if (operands[1] != const0_rtx)
7925 assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7926 return \"\";
7927 }"
7928 [(set_attr "length" "2")
7929 (set_attr "in_delay_slot" "no")])
7930
7931 ; 4 byte integer in line
7932
7933 (define_insn "consttable_4"
7934 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7935 (match_operand 1 "" "")]
7936 UNSPECV_CONST4)]
7937 ""
7938 "*
7939 {
7940 if (operands[1] != const0_rtx)
7941 assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7942 return \"\";
7943 }"
7944 [(set_attr "length" "4")
7945 (set_attr "in_delay_slot" "no")])
7946
7947 ; 8 byte integer in line
7948
7949 (define_insn "consttable_8"
7950 [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7951 (match_operand 1 "" "")]
7952 UNSPECV_CONST8)]
7953 ""
7954 "*
7955 {
7956 if (operands[1] != const0_rtx)
7957 assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7958 return \"\";
7959 }"
7960 [(set_attr "length" "8")
7961 (set_attr "in_delay_slot" "no")])
7962
7963 ; 4 byte floating point
7964
7965 (define_insn "consttable_sf"
7966 [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7967 (match_operand 1 "" "")]
7968 UNSPECV_CONST4)]
7969 ""
7970 "*
7971 {
7972 if (operands[1] != const0_rtx)
7973 {
7974 REAL_VALUE_TYPE d;
7975 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7976 assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7977 }
7978 return \"\";
7979 }"
7980 [(set_attr "length" "4")
7981 (set_attr "in_delay_slot" "no")])
7982
7983 ; 8 byte floating point
7984
7985 (define_insn "consttable_df"
7986 [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7987 (match_operand 1 "" "")]
7988 UNSPECV_CONST8)]
7989 ""
7990 "*
7991 {
7992 if (operands[1] != const0_rtx)
7993 {
7994 REAL_VALUE_TYPE d;
7995 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7996 assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7997 }
7998 return \"\";
7999 }"
8000 [(set_attr "length" "8")
8001 (set_attr "in_delay_slot" "no")])
8002
8003 ;; Alignment is needed for some constant tables; it may also be added for
8004 ;; Instructions at the start of loops, or after unconditional branches.
8005 ;; ??? We would get more accurate lengths if we did instruction
8006 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8007 ;; here is too conservative.
8008
8009 ; align to a two byte boundary
8010
8011 (define_expand "align_2"
8012 [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8013 ""
8014 "")
8015
8016 ; align to a four byte boundary
8017 ;; align_4 and align_log are instructions for the starts of loops, or
8018 ;; after unconditional branches, which may take up extra room.
8019
8020 (define_expand "align_4"
8021 [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8022 ""
8023 "")
8024
8025 ; align to a cache line boundary
8026
8027 (define_insn "align_log"
8028 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8029 ""
8030 ""
8031 [(set_attr "length" "0")
8032 (set_attr "in_delay_slot" "no")])
8033
8034 ; emitted at the end of the literal table, used to emit the
8035 ; 32bit branch labels if needed.
8036
8037 (define_insn "consttable_end"
8038 [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8039 ""
8040 "* return output_jump_label_table ();"
8041 [(set_attr "in_delay_slot" "no")])
8042
8043 ; emitted at the end of the window in the literal table.
8044
8045 (define_insn "consttable_window_end"
8046 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8047 ""
8048 ""
8049 [(set_attr "length" "0")
8050 (set_attr "in_delay_slot" "no")])
8051
8052 ;; -------------------------------------------------------------------------
8053 ;; Misc
8054 ;; -------------------------------------------------------------------------
8055
8056 ;; String/block move insn.
8057
8058 (define_expand "movmemsi"
8059 [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8060 (mem:BLK (match_operand:BLK 1 "" "")))
8061 (use (match_operand:SI 2 "nonmemory_operand" ""))
8062 (use (match_operand:SI 3 "immediate_operand" ""))
8063 (clobber (reg:SI PR_REG))
8064 (clobber (reg:SI R4_REG))
8065 (clobber (reg:SI R5_REG))
8066 (clobber (reg:SI R0_REG))])]
8067 "TARGET_SH1 && ! TARGET_SH5"
8068 "
8069 {
8070 if(expand_block_move (operands))
8071 DONE;
8072 else FAIL;
8073 }")
8074
8075 (define_insn "block_move_real"
8076 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8077 (mem:BLK (reg:SI R5_REG)))
8078 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8079 (clobber (reg:SI PR_REG))
8080 (clobber (reg:SI R0_REG))])]
8081 "TARGET_SH1 && ! TARGET_HARD_SH4"
8082 "jsr @%0%#"
8083 [(set_attr "type" "sfunc")
8084 (set_attr "needs_delay_slot" "yes")])
8085
8086 (define_insn "block_lump_real"
8087 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8088 (mem:BLK (reg:SI R5_REG)))
8089 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8090 (use (reg:SI R6_REG))
8091 (clobber (reg:SI PR_REG))
8092 (clobber (reg:SI T_REG))
8093 (clobber (reg:SI R4_REG))
8094 (clobber (reg:SI R5_REG))
8095 (clobber (reg:SI R6_REG))
8096 (clobber (reg:SI R0_REG))])]
8097 "TARGET_SH1 && ! TARGET_HARD_SH4"
8098 "jsr @%0%#"
8099 [(set_attr "type" "sfunc")
8100 (set_attr "needs_delay_slot" "yes")])
8101
8102 (define_insn "block_move_real_i4"
8103 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8104 (mem:BLK (reg:SI R5_REG)))
8105 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8106 (clobber (reg:SI PR_REG))
8107 (clobber (reg:SI R0_REG))
8108 (clobber (reg:SI R1_REG))
8109 (clobber (reg:SI R2_REG))])]
8110 "TARGET_HARD_SH4"
8111 "jsr @%0%#"
8112 [(set_attr "type" "sfunc")
8113 (set_attr "needs_delay_slot" "yes")])
8114
8115 (define_insn "block_lump_real_i4"
8116 [(parallel [(set (mem:BLK (reg:SI R4_REG))
8117 (mem:BLK (reg:SI R5_REG)))
8118 (use (match_operand:SI 0 "arith_reg_operand" "r"))
8119 (use (reg:SI R6_REG))
8120 (clobber (reg:SI PR_REG))
8121 (clobber (reg:SI T_REG))
8122 (clobber (reg:SI R4_REG))
8123 (clobber (reg:SI R5_REG))
8124 (clobber (reg:SI R6_REG))
8125 (clobber (reg:SI R0_REG))
8126 (clobber (reg:SI R1_REG))
8127 (clobber (reg:SI R2_REG))
8128 (clobber (reg:SI R3_REG))])]
8129 "TARGET_HARD_SH4"
8130 "jsr @%0%#"
8131 [(set_attr "type" "sfunc")
8132 (set_attr "needs_delay_slot" "yes")])
8133 \f
8134 ;; -------------------------------------------------------------------------
8135 ;; Floating point instructions.
8136 ;; -------------------------------------------------------------------------
8137
8138 ;; ??? All patterns should have a type attribute.
8139
8140 (define_expand "fpu_switch0"
8141 [(set (match_operand:SI 0 "" "") (match_dup 2))
8142 (set (match_dup 1) (mem:PSI (match_dup 0)))]
8143 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8144 "
8145 {
8146 operands[1] = get_fpscr_rtx ();
8147 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8148 if (flag_pic)
8149 operands[2] = legitimize_pic_address (operands[2], SImode,
8150 no_new_pseudos ? operands[0] : 0);
8151 }")
8152
8153 (define_expand "fpu_switch1"
8154 [(set (match_operand:SI 0 "" "") (match_dup 2))
8155 (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8156 (set (match_dup 1) (mem:PSI (match_dup 3)))]
8157 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8158 "
8159 {
8160 operands[1] = get_fpscr_rtx ();
8161 operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8162 if (flag_pic)
8163 operands[2] = legitimize_pic_address (operands[2], SImode,
8164 no_new_pseudos ? operands[0] : 0);
8165 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8166 }")
8167
8168 (define_expand "movpsi"
8169 [(set (match_operand:PSI 0 "register_operand" "")
8170 (match_operand:PSI 1 "general_movsrc_operand" ""))]
8171 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8172 "")
8173
8174 ;; The c / m alternative is a fake to guide reload to load directly into
8175 ;; fpscr, since reload doesn't know how to use post-increment.
8176 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8177 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8178 ;; predicate after reload.
8179 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8180 ;; like a mac -> gpr move.
8181 (define_insn "fpu_switch"
8182 [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8183 (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8184 "TARGET_SH2E
8185 && (! reload_completed
8186 || true_regnum (operands[0]) != FPSCR_REG
8187 || GET_CODE (operands[1]) != MEM
8188 || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8189 "@
8190 ! precision stays the same
8191 lds.l %1,fpscr
8192 mov.l %1,%0
8193 #
8194 lds %1,fpscr
8195 mov %1,%0
8196 mov.l %1,%0
8197 sts fpscr,%0
8198 sts.l fpscr,%0"
8199 [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8200 (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8201
8202 (define_split
8203 [(set (reg:PSI FPSCR_REG)
8204 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8205 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8206 [(set (match_dup 0) (match_dup 0))]
8207 "
8208 {
8209 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8210 gen_rtx_MEM (PSImode,
8211 gen_rtx_POST_INC (Pmode,
8212 operands[0]))));
8213 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8214 }")
8215
8216 (define_split
8217 [(set (reg:PSI FPSCR_REG)
8218 (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8219 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8220 [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8221 "
8222 {
8223 rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8224 gen_rtx_MEM (PSImode,
8225 gen_rtx_POST_INC (Pmode,
8226 operands[0]))));
8227 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8228 }")
8229
8230 ;; ??? This uses the fp unit, but has no type indicating that.
8231 ;; If we did that, this would either give a bogus latency or introduce
8232 ;; a bogus FIFO constraint.
8233 ;; Since this insn is currently only used for prologues/epilogues,
8234 ;; it is probably best to claim no function unit, which matches the
8235 ;; current setting.
8236 (define_insn "toggle_sz"
8237 [(set (reg:PSI FPSCR_REG)
8238 (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8239 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8240 "fschg"
8241 [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8242
8243 ;; There's no way we can use it today, since optimize mode switching
8244 ;; doesn't enable us to know from which mode we're switching to the
8245 ;; mode it requests, to tell whether we can use a relative mode switch
8246 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8247 ;; memory).
8248 (define_insn "toggle_pr"
8249 [(set (reg:PSI FPSCR_REG)
8250 (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8251 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8252 "fpchg"
8253 [(set_attr "type" "fp")])
8254
8255 (define_expand "addsf3"
8256 [(set (match_operand:SF 0 "arith_reg_operand" "")
8257 (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8258 (match_operand:SF 2 "arith_reg_operand" "")))]
8259 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8260 "
8261 {
8262 if (TARGET_SH2E)
8263 {
8264 expand_sf_binop (&gen_addsf3_i, operands);
8265 DONE;
8266 }
8267 }")
8268
8269 (define_insn "*addsf3_media"
8270 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8271 (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8272 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8273 "TARGET_SHMEDIA_FPU"
8274 "fadd.s %1, %2, %0"
8275 [(set_attr "type" "fparith_media")])
8276
8277 (define_insn_and_split "unary_sf_op"
8278 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8279 (vec_select:V2SF
8280 (vec_concat:V2SF
8281 (vec_select:SF
8282 (match_dup 0)
8283 (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8284 (match_operator:SF 2 "unary_float_operator"
8285 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8286 (parallel [(match_operand 4
8287 "const_int_operand" "n")]))]))
8288 (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8289 "TARGET_SHMEDIA_FPU"
8290 "#"
8291 "TARGET_SHMEDIA_FPU && reload_completed"
8292 [(set (match_dup 5) (match_dup 6))]
8293 "
8294 {
8295 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8296 rtx op1 = gen_rtx_REG (SFmode,
8297 (true_regnum (operands[1])
8298 + (INTVAL (operands[4]) ^ endian)));
8299
8300 operands[7] = gen_rtx_REG (SFmode,
8301 (true_regnum (operands[0])
8302 + (INTVAL (operands[3]) ^ endian)));
8303 operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8304 }"
8305 [(set_attr "type" "fparith_media")])
8306
8307 (define_insn_and_split "binary_sf_op"
8308 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8309 (vec_select:V2SF
8310 (vec_concat:V2SF
8311 (vec_select:SF
8312 (match_dup 0)
8313 (parallel [(match_operand 7 "const_int_operand" "n")]))
8314 (match_operator:SF 3 "binary_float_operator"
8315 [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8316 (parallel [(match_operand 5
8317 "const_int_operand" "n")]))
8318 (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8319 (parallel [(match_operand 6
8320 "const_int_operand" "n")]))]))
8321 (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8322 "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8323 "#"
8324 "&& reload_completed"
8325 [(set (match_dup 8) (match_dup 9))]
8326 "
8327 {
8328 int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8329 rtx op1 = gen_rtx_REG (SFmode,
8330 (true_regnum (operands[1])
8331 + (INTVAL (operands[5]) ^ endian)));
8332 rtx op2 = gen_rtx_REG (SFmode,
8333 (true_regnum (operands[2])
8334 + (INTVAL (operands[6]) ^ endian)));
8335
8336 operands[8] = gen_rtx_REG (SFmode,
8337 (true_regnum (operands[0])
8338 + (INTVAL (operands[4]) ^ endian)));
8339 operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8340 }"
8341 [(set_attr "type" "fparith_media")])
8342
8343 (define_insn "addsf3_i"
8344 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8345 (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8346 (match_operand:SF 2 "arith_reg_operand" "f")))
8347 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8348 "TARGET_SH2E"
8349 "fadd %2,%0"
8350 [(set_attr "type" "fp")
8351 (set_attr "fp_mode" "single")])
8352
8353 (define_expand "subsf3"
8354 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8355 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8356 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8357 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8358 "
8359 {
8360 if (TARGET_SH2E)
8361 {
8362 expand_sf_binop (&gen_subsf3_i, operands);
8363 DONE;
8364 }
8365 }")
8366
8367 (define_insn "*subsf3_media"
8368 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8369 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8370 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8371 "TARGET_SHMEDIA_FPU"
8372 "fsub.s %1, %2, %0"
8373 [(set_attr "type" "fparith_media")])
8374
8375 (define_insn "subsf3_i"
8376 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8377 (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8378 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8379 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8380 "TARGET_SH2E"
8381 "fsub %2,%0"
8382 [(set_attr "type" "fp")
8383 (set_attr "fp_mode" "single")])
8384
8385 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8386 ;; register in feeding fp instructions. Thus, we cannot generate fmac for
8387 ;; mixed-precision SH4 targets. To allow it to be still generated for the
8388 ;; SH3E, we use a separate insn for SH3E mulsf3.
8389
8390 (define_expand "mulsf3"
8391 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8392 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8393 (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8394 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8395 "
8396 {
8397 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8398 expand_sf_binop (&gen_mulsf3_i4, operands);
8399 else if (TARGET_SH2E)
8400 emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8401 if (! TARGET_SHMEDIA)
8402 DONE;
8403 }")
8404
8405 (define_insn "*mulsf3_media"
8406 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8407 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8408 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8409 "TARGET_SHMEDIA_FPU"
8410 "fmul.s %1, %2, %0"
8411 [(set_attr "type" "fparith_media")])
8412
8413 (define_insn "mulsf3_i4"
8414 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8415 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8416 (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8417 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8418 "TARGET_SH2E"
8419 "fmul %2,%0"
8420 [(set_attr "type" "fp")
8421 (set_attr "fp_mode" "single")])
8422
8423 (define_insn "mulsf3_ie"
8424 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8425 (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8426 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8427 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8428 "fmul %2,%0"
8429 [(set_attr "type" "fp")])
8430
8431 (define_insn "*mac_media"
8432 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8433 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8434 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8435 (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8436 "TARGET_SHMEDIA_FPU"
8437 "fmac.s %1, %2, %0"
8438 [(set_attr "type" "fparith_media")])
8439
8440 (define_insn "*macsf3"
8441 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8442 (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8443 (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8444 (match_operand:SF 3 "arith_reg_operand" "0")))
8445 (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8446 "TARGET_SH2E && ! TARGET_SH4"
8447 "fmac fr0,%2,%0"
8448 [(set_attr "type" "fp")
8449 (set_attr "fp_mode" "single")])
8450
8451 (define_expand "divsf3"
8452 [(set (match_operand:SF 0 "arith_reg_operand" "")
8453 (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8454 (match_operand:SF 2 "arith_reg_operand" "")))]
8455 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8456 "
8457 {
8458 if (TARGET_SH2E)
8459 {
8460 expand_sf_binop (&gen_divsf3_i, operands);
8461 DONE;
8462 }
8463 }")
8464
8465 (define_insn "*divsf3_media"
8466 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8467 (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8468 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8469 "TARGET_SHMEDIA_FPU"
8470 "fdiv.s %1, %2, %0"
8471 [(set_attr "type" "fdiv_media")])
8472
8473 (define_insn "divsf3_i"
8474 [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8475 (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8476 (match_operand:SF 2 "arith_reg_operand" "f")))
8477 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8478 "TARGET_SH2E"
8479 "fdiv %2,%0"
8480 [(set_attr "type" "fdiv")
8481 (set_attr "fp_mode" "single")])
8482
8483 (define_insn "floatdisf2"
8484 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8485 (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8486 "TARGET_SHMEDIA_FPU"
8487 "float.qs %1, %0"
8488 [(set_attr "type" "fpconv_media")])
8489
8490 (define_expand "floatsisf2"
8491 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8492 (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8493 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8494 "
8495 {
8496 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8497 {
8498 emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8499 DONE;
8500 }
8501 }")
8502
8503 (define_insn "*floatsisf2_media"
8504 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8505 (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8506 "TARGET_SHMEDIA_FPU"
8507 "float.ls %1, %0"
8508 [(set_attr "type" "fpconv_media")])
8509
8510 (define_insn "floatsisf2_i4"
8511 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8512 (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8513 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8514 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8515 "float %1,%0"
8516 [(set_attr "type" "fp")
8517 (set_attr "fp_mode" "single")])
8518
8519 (define_insn "*floatsisf2_ie"
8520 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8521 (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8522 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8523 "float %1,%0"
8524 [(set_attr "type" "fp")])
8525
8526 (define_insn "fix_truncsfdi2"
8527 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8528 (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8529 "TARGET_SHMEDIA_FPU"
8530 "ftrc.sq %1, %0"
8531 [(set_attr "type" "fpconv_media")])
8532
8533 (define_expand "fix_truncsfsi2"
8534 [(set (match_operand:SI 0 "fpul_operand" "=y")
8535 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8536 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8537 "
8538 {
8539 if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8540 {
8541 emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8542 DONE;
8543 }
8544 }")
8545
8546 (define_insn "*fix_truncsfsi2_media"
8547 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8548 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8549 "TARGET_SHMEDIA_FPU"
8550 "ftrc.sl %1, %0"
8551 [(set_attr "type" "fpconv_media")])
8552
8553 (define_insn "fix_truncsfsi2_i4"
8554 [(set (match_operand:SI 0 "fpul_operand" "=y")
8555 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8556 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8557 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8558 "ftrc %1,%0"
8559 [(set_attr "type" "ftrc_s")
8560 (set_attr "fp_mode" "single")])
8561
8562 ;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to
8563 ;; fix_truncsfsi2_i4.
8564 ;; (define_insn "fix_truncsfsi2_i4_2"
8565 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8566 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8567 ;; (use (reg:PSI FPSCR_REG))
8568 ;; (clobber (reg:SI FPUL_REG))]
8569 ;; "TARGET_SH4"
8570 ;; "#"
8571 ;; [(set_attr "length" "4")
8572 ;; (set_attr "fp_mode" "single")])
8573
8574 ;;(define_split
8575 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8576 ;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8577 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
8578 ;; (clobber (reg:SI FPUL_REG))]
8579 ;; "TARGET_SH4"
8580 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8581 ;; (use (match_dup 2))])
8582 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
8583
8584 (define_insn "*fixsfsi"
8585 [(set (match_operand:SI 0 "fpul_operand" "=y")
8586 (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8587 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8588 "ftrc %1,%0"
8589 [(set_attr "type" "fp")])
8590
8591 (define_insn "cmpgtsf_t"
8592 [(set (reg:SI T_REG)
8593 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8594 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8595 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8596 "fcmp/gt %1,%0"
8597 [(set_attr "type" "fp")
8598 (set_attr "fp_mode" "single")])
8599
8600 (define_insn "cmpeqsf_t"
8601 [(set (reg:SI T_REG)
8602 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8603 (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8604 "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8605 "fcmp/eq %1,%0"
8606 [(set_attr "type" "fp")
8607 (set_attr "fp_mode" "single")])
8608
8609 (define_insn "ieee_ccmpeqsf_t"
8610 [(set (reg:SI T_REG)
8611 (ior:SI (reg:SI T_REG)
8612 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8613 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8614 "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8615 "* return output_ieee_ccmpeq (insn, operands);"
8616 [(set_attr "length" "4")])
8617
8618
8619 (define_insn "cmpgtsf_t_i4"
8620 [(set (reg:SI T_REG)
8621 (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8622 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8623 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8624 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8625 "fcmp/gt %1,%0"
8626 [(set_attr "type" "fp")
8627 (set_attr "fp_mode" "single")])
8628
8629 (define_insn "cmpeqsf_t_i4"
8630 [(set (reg:SI T_REG)
8631 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8632 (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8633 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8634 "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8635 "fcmp/eq %1,%0"
8636 [(set_attr "type" "fp")
8637 (set_attr "fp_mode" "single")])
8638
8639 (define_insn "*ieee_ccmpeqsf_t_4"
8640 [(set (reg:SI T_REG)
8641 (ior:SI (reg:SI T_REG)
8642 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8643 (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8644 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8645 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8646 "* return output_ieee_ccmpeq (insn, operands);"
8647 [(set_attr "length" "4")
8648 (set_attr "fp_mode" "single")])
8649
8650 (define_insn "cmpeqsf_media"
8651 [(set (match_operand:DI 0 "register_operand" "=r")
8652 (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8653 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8654 "TARGET_SHMEDIA_FPU"
8655 "fcmpeq.s %1, %2, %0"
8656 [(set_attr "type" "fcmp_media")])
8657
8658 (define_insn "cmpgtsf_media"
8659 [(set (match_operand:DI 0 "register_operand" "=r")
8660 (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8661 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8662 "TARGET_SHMEDIA_FPU"
8663 "fcmpgt.s %1, %2, %0"
8664 [(set_attr "type" "fcmp_media")])
8665
8666 (define_insn "cmpgesf_media"
8667 [(set (match_operand:DI 0 "register_operand" "=r")
8668 (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8669 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8670 "TARGET_SHMEDIA_FPU"
8671 "fcmpge.s %1, %2, %0"
8672 [(set_attr "type" "fcmp_media")])
8673
8674 (define_insn "cmpunsf_media"
8675 [(set (match_operand:DI 0 "register_operand" "=r")
8676 (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8677 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8678 "TARGET_SHMEDIA_FPU"
8679 "fcmpun.s %1, %2, %0"
8680 [(set_attr "type" "fcmp_media")])
8681
8682 (define_expand "cmpsf"
8683 [(set (reg:SI T_REG)
8684 (compare (match_operand:SF 0 "arith_operand" "")
8685 (match_operand:SF 1 "arith_operand" "")))]
8686 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8687 "
8688 {
8689 sh_compare_op0 = operands[0];
8690 sh_compare_op1 = operands[1];
8691 DONE;
8692 }")
8693
8694 (define_expand "negsf2"
8695 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8696 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8697 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8698 "
8699 {
8700 if (TARGET_SH2E)
8701 {
8702 expand_sf_unop (&gen_negsf2_i, operands);
8703 DONE;
8704 }
8705 }")
8706
8707 (define_insn "*negsf2_media"
8708 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8709 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8710 "TARGET_SHMEDIA_FPU"
8711 "fneg.s %1, %0"
8712 [(set_attr "type" "fmove_media")])
8713
8714 (define_insn "negsf2_i"
8715 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8716 (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8717 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8718 "TARGET_SH2E"
8719 "fneg %0"
8720 [(set_attr "type" "fmove")
8721 (set_attr "fp_mode" "single")])
8722
8723 (define_expand "sqrtsf2"
8724 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8725 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8726 "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8727 "
8728 {
8729 if (TARGET_SH3E)
8730 {
8731 expand_sf_unop (&gen_sqrtsf2_i, operands);
8732 DONE;
8733 }
8734 }")
8735
8736 (define_insn "*sqrtsf2_media"
8737 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8738 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8739 "TARGET_SHMEDIA_FPU"
8740 "fsqrt.s %1, %0"
8741 [(set_attr "type" "fdiv_media")])
8742
8743 (define_insn "sqrtsf2_i"
8744 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8745 (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8746 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8747 "TARGET_SH3E"
8748 "fsqrt %0"
8749 [(set_attr "type" "fdiv")
8750 (set_attr "fp_mode" "single")])
8751
8752 (define_insn "rsqrtsf2"
8753 [(set (match_operand:SF 0 "register_operand" "=f")
8754 (div:SF (match_operand:SF 1 "immediate_operand" "i")
8755 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8756 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8757 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8758 && operands[1] == CONST1_RTX (SFmode)"
8759 "fsrra %0"
8760 [(set_attr "type" "fsrra")
8761 (set_attr "fp_mode" "single")])
8762
8763 (define_insn "fsca"
8764 [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8765 (vec_concat:V2SF
8766 (unspec:SF [(mult:SF
8767 (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8768 (match_operand:SF 2 "immediate_operand" "i"))
8769 ] UNSPEC_FSINA)
8770 (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8771 ] UNSPEC_FCOSA)))
8772 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8773 "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8774 && operands[2] == sh_fsca_int2sf ()"
8775 "fsca fpul,%d0"
8776 [(set_attr "type" "fsca")
8777 (set_attr "fp_mode" "single")])
8778
8779 (define_expand "sinsf2"
8780 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8781 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8782 UNSPEC_FSINA))]
8783 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8784 "
8785 {
8786 rtx scaled = gen_reg_rtx (SFmode);
8787 rtx truncated = gen_reg_rtx (SImode);
8788 rtx fsca = gen_reg_rtx (V2SFmode);
8789 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8790
8791 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8792 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8793 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8794 get_fpscr_rtx ()));
8795 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8796 DONE;
8797 }")
8798
8799 (define_expand "cossf2"
8800 [(set (match_operand:SF 0 "nonimmediate_operand" "")
8801 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8802 UNSPEC_FCOSA))]
8803 "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8804 "
8805 {
8806 rtx scaled = gen_reg_rtx (SFmode);
8807 rtx truncated = gen_reg_rtx (SImode);
8808 rtx fsca = gen_reg_rtx (V2SFmode);
8809 rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8810
8811 emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8812 emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8813 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8814 get_fpscr_rtx ()));
8815 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8816 DONE;
8817 }")
8818
8819 (define_expand "sindf2"
8820 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8821 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8822 UNSPEC_FSINA))]
8823 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8824 "
8825 {
8826 rtx scaled = gen_reg_rtx (DFmode);
8827 rtx truncated = gen_reg_rtx (SImode);
8828 rtx fsca = gen_reg_rtx (V2SFmode);
8829 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8830 rtx sfresult = gen_reg_rtx (SFmode);
8831
8832 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8833 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8834 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8835 get_fpscr_rtx ()));
8836 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8837 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8838 DONE;
8839 }")
8840
8841 (define_expand "cosdf2"
8842 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8843 (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8844 UNSPEC_FCOSA))]
8845 "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8846 "
8847 {
8848 rtx scaled = gen_reg_rtx (DFmode);
8849 rtx truncated = gen_reg_rtx (SImode);
8850 rtx fsca = gen_reg_rtx (V2SFmode);
8851 rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8852 rtx sfresult = gen_reg_rtx (SFmode);
8853
8854 emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8855 emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8856 emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8857 get_fpscr_rtx ()));
8858 emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8859 emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8860 DONE;
8861 }")
8862
8863 (define_expand "abssf2"
8864 [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8865 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8866 "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8867 "
8868 {
8869 if (TARGET_SH2E)
8870 {
8871 expand_sf_unop (&gen_abssf2_i, operands);
8872 DONE;
8873 }
8874 }")
8875
8876 (define_insn "*abssf2_media"
8877 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8878 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8879 "TARGET_SHMEDIA_FPU"
8880 "fabs.s %1, %0"
8881 [(set_attr "type" "fmove_media")])
8882
8883 (define_insn "abssf2_i"
8884 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8885 (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8886 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8887 "TARGET_SH2E"
8888 "fabs %0"
8889 [(set_attr "type" "fmove")
8890 (set_attr "fp_mode" "single")])
8891
8892 (define_expand "adddf3"
8893 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8894 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8895 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8896 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8897 "
8898 {
8899 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8900 {
8901 expand_df_binop (&gen_adddf3_i, operands);
8902 DONE;
8903 }
8904 }")
8905
8906 (define_insn "*adddf3_media"
8907 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8908 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8909 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8910 "TARGET_SHMEDIA_FPU"
8911 "fadd.d %1, %2, %0"
8912 [(set_attr "type" "dfparith_media")])
8913
8914 (define_insn "adddf3_i"
8915 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8916 (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8917 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8918 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8919 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8920 "fadd %2,%0"
8921 [(set_attr "type" "dfp_arith")
8922 (set_attr "fp_mode" "double")])
8923
8924 (define_expand "subdf3"
8925 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8926 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8927 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8928 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8929 "
8930 {
8931 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8932 {
8933 expand_df_binop (&gen_subdf3_i, operands);
8934 DONE;
8935 }
8936 }")
8937
8938 (define_insn "*subdf3_media"
8939 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8940 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8941 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8942 "TARGET_SHMEDIA_FPU"
8943 "fsub.d %1, %2, %0"
8944 [(set_attr "type" "dfparith_media")])
8945
8946 (define_insn "subdf3_i"
8947 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8948 (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8949 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8950 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8951 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8952 "fsub %2,%0"
8953 [(set_attr "type" "dfp_arith")
8954 (set_attr "fp_mode" "double")])
8955
8956 (define_expand "muldf3"
8957 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8958 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8959 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8960 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8961 "
8962 {
8963 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8964 {
8965 expand_df_binop (&gen_muldf3_i, operands);
8966 DONE;
8967 }
8968 }")
8969
8970 (define_insn "*muldf3_media"
8971 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8972 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8973 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8974 "TARGET_SHMEDIA_FPU"
8975 "fmul.d %1, %2, %0"
8976 [(set_attr "type" "dfmul_media")])
8977
8978 (define_insn "muldf3_i"
8979 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8980 (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8981 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8982 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8983 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8984 "fmul %2,%0"
8985 [(set_attr "type" "dfp_arith")
8986 (set_attr "fp_mode" "double")])
8987
8988 (define_expand "divdf3"
8989 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8990 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8991 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8992 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8993 "
8994 {
8995 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8996 {
8997 expand_df_binop (&gen_divdf3_i, operands);
8998 DONE;
8999 }
9000 }")
9001
9002 (define_insn "*divdf3_media"
9003 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9004 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
9005 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9006 "TARGET_SHMEDIA_FPU"
9007 "fdiv.d %1, %2, %0"
9008 [(set_attr "type" "dfdiv_media")])
9009
9010 (define_insn "divdf3_i"
9011 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9012 (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
9013 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9014 (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9015 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9016 "fdiv %2,%0"
9017 [(set_attr "type" "dfdiv")
9018 (set_attr "fp_mode" "double")])
9019
9020 (define_insn "floatdidf2"
9021 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9022 (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
9023 "TARGET_SHMEDIA_FPU"
9024 "float.qd %1, %0"
9025 [(set_attr "type" "dfpconv_media")])
9026
9027 (define_expand "floatsidf2"
9028 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9029 (float:DF (match_operand:SI 1 "fpul_operand" "")))]
9030 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9031 "
9032 {
9033 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9034 {
9035 emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
9036 get_fpscr_rtx ()));
9037 DONE;
9038 }
9039 }")
9040
9041 (define_insn "*floatsidf2_media"
9042 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9043 (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
9044 "TARGET_SHMEDIA_FPU"
9045 "float.ld %1, %0"
9046 [(set_attr "type" "dfpconv_media")])
9047
9048 (define_insn "floatsidf2_i"
9049 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9050 (float:DF (match_operand:SI 1 "fpul_operand" "y")))
9051 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9052 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9053 "float %1,%0"
9054 [(set_attr "type" "dfp_conv")
9055 (set_attr "fp_mode" "double")])
9056
9057 (define_insn "fix_truncdfdi2"
9058 [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
9059 (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9060 "TARGET_SHMEDIA_FPU"
9061 "ftrc.dq %1, %0"
9062 [(set_attr "type" "dfpconv_media")])
9063
9064 (define_expand "fix_truncdfsi2"
9065 [(set (match_operand:SI 0 "fpul_operand" "")
9066 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9067 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9068 "
9069 {
9070 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9071 {
9072 emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9073 get_fpscr_rtx ()));
9074 DONE;
9075 }
9076 }")
9077
9078 (define_insn "*fix_truncdfsi2_media"
9079 [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9080 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9081 "TARGET_SHMEDIA_FPU"
9082 "ftrc.dl %1, %0"
9083 [(set_attr "type" "dfpconv_media")])
9084
9085 (define_insn "fix_truncdfsi2_i"
9086 [(set (match_operand:SI 0 "fpul_operand" "=y")
9087 (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9088 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9089 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9090 "ftrc %1,%0"
9091 [(set_attr "type" "dfp_conv")
9092 (set_attr "dfp_comp" "no")
9093 (set_attr "fp_mode" "double")])
9094
9095 ;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to
9096 ;; fix_truncdfsi2_i.
9097 ;; (define_insn "fix_truncdfsi2_i4"
9098 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9099 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9100 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9101 ;; (clobber (reg:SI FPUL_REG))]
9102 ;; "TARGET_SH4"
9103 ;; "#"
9104 ;; [(set_attr "length" "4")
9105 ;; (set_attr "fp_mode" "double")])
9106 ;;
9107 ;; (define_split
9108 ;; [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9109 ;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9110 ;; (use (match_operand:PSI 2 "fpscr_operand" "c"))
9111 ;; (clobber (reg:SI FPUL_REG))]
9112 ;; "TARGET_SH4"
9113 ;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9114 ;; (use (match_dup 2))])
9115 ;; (set (match_dup 0) (reg:SI FPUL_REG))])
9116
9117 (define_insn "cmpgtdf_t"
9118 [(set (reg:SI T_REG)
9119 (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9120 (match_operand:DF 1 "arith_reg_operand" "f")))
9121 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9122 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9123 "fcmp/gt %1,%0"
9124 [(set_attr "type" "dfp_cmp")
9125 (set_attr "fp_mode" "double")])
9126
9127 (define_insn "cmpeqdf_t"
9128 [(set (reg:SI T_REG)
9129 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9130 (match_operand:DF 1 "arith_reg_operand" "f")))
9131 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9132 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9133 "fcmp/eq %1,%0"
9134 [(set_attr "type" "dfp_cmp")
9135 (set_attr "fp_mode" "double")])
9136
9137 (define_insn "*ieee_ccmpeqdf_t"
9138 [(set (reg:SI T_REG)
9139 (ior:SI (reg:SI T_REG)
9140 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9141 (match_operand:DF 1 "arith_reg_operand" "f"))))
9142 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9143 "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9144 "* return output_ieee_ccmpeq (insn, operands);"
9145 [(set_attr "length" "4")
9146 (set_attr "fp_mode" "double")])
9147
9148 (define_insn "cmpeqdf_media"
9149 [(set (match_operand:DI 0 "register_operand" "=r")
9150 (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9151 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9152 "TARGET_SHMEDIA_FPU"
9153 "fcmpeq.d %1,%2,%0"
9154 [(set_attr "type" "fcmp_media")])
9155
9156 (define_insn "cmpgtdf_media"
9157 [(set (match_operand:DI 0 "register_operand" "=r")
9158 (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9159 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9160 "TARGET_SHMEDIA_FPU"
9161 "fcmpgt.d %1,%2,%0"
9162 [(set_attr "type" "fcmp_media")])
9163
9164 (define_insn "cmpgedf_media"
9165 [(set (match_operand:DI 0 "register_operand" "=r")
9166 (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9167 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9168 "TARGET_SHMEDIA_FPU"
9169 "fcmpge.d %1,%2,%0"
9170 [(set_attr "type" "fcmp_media")])
9171
9172 (define_insn "cmpundf_media"
9173 [(set (match_operand:DI 0 "register_operand" "=r")
9174 (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9175 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9176 "TARGET_SHMEDIA_FPU"
9177 "fcmpun.d %1,%2,%0"
9178 [(set_attr "type" "fcmp_media")])
9179
9180 (define_expand "cmpdf"
9181 [(set (reg:SI T_REG)
9182 (compare (match_operand:DF 0 "arith_operand" "")
9183 (match_operand:DF 1 "arith_operand" "")))]
9184 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9185 "
9186 {
9187 sh_compare_op0 = operands[0];
9188 sh_compare_op1 = operands[1];
9189 DONE;
9190 }")
9191
9192 (define_expand "negdf2"
9193 [(set (match_operand:DF 0 "arith_reg_operand" "")
9194 (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9195 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9196 "
9197 {
9198 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9199 {
9200 expand_df_unop (&gen_negdf2_i, operands);
9201 DONE;
9202 }
9203 }")
9204
9205 (define_insn "*negdf2_media"
9206 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9207 (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9208 "TARGET_SHMEDIA_FPU"
9209 "fneg.d %1, %0"
9210 [(set_attr "type" "fmove_media")])
9211
9212 (define_insn "negdf2_i"
9213 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9214 (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9215 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9216 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9217 "fneg %0"
9218 [(set_attr "type" "fmove")
9219 (set_attr "fp_mode" "double")])
9220
9221 (define_expand "sqrtdf2"
9222 [(set (match_operand:DF 0 "arith_reg_operand" "")
9223 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9224 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9225 "
9226 {
9227 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9228 {
9229 expand_df_unop (&gen_sqrtdf2_i, operands);
9230 DONE;
9231 }
9232 }")
9233
9234 (define_insn "*sqrtdf2_media"
9235 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9236 (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9237 "TARGET_SHMEDIA_FPU"
9238 "fsqrt.d %1, %0"
9239 [(set_attr "type" "dfdiv_media")])
9240
9241 (define_insn "sqrtdf2_i"
9242 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9243 (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9244 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9245 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9246 "fsqrt %0"
9247 [(set_attr "type" "dfdiv")
9248 (set_attr "fp_mode" "double")])
9249
9250 (define_expand "absdf2"
9251 [(set (match_operand:DF 0 "arith_reg_operand" "")
9252 (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9253 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9254 "
9255 {
9256 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9257 {
9258 expand_df_unop (&gen_absdf2_i, operands);
9259 DONE;
9260 }
9261 }")
9262
9263 (define_insn "*absdf2_media"
9264 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9265 (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9266 "TARGET_SHMEDIA_FPU"
9267 "fabs.d %1, %0"
9268 [(set_attr "type" "fmove_media")])
9269
9270 (define_insn "absdf2_i"
9271 [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9272 (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9273 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9274 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9275 "fabs %0"
9276 [(set_attr "type" "fmove")
9277 (set_attr "fp_mode" "double")])
9278
9279 (define_expand "extendsfdf2"
9280 [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9281 (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9282 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9283 "
9284 {
9285 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9286 {
9287 emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9288 get_fpscr_rtx ()));
9289 DONE;
9290 }
9291 }")
9292
9293 (define_insn "*extendsfdf2_media"
9294 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9295 (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9296 "TARGET_SHMEDIA_FPU"
9297 "fcnv.sd %1, %0"
9298 [(set_attr "type" "dfpconv_media")])
9299
9300 (define_insn "extendsfdf2_i4"
9301 [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9302 (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9303 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9304 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9305 "fcnvsd %1,%0"
9306 [(set_attr "type" "fp")
9307 (set_attr "fp_mode" "double")])
9308
9309 (define_expand "truncdfsf2"
9310 [(set (match_operand:SF 0 "fpul_operand" "")
9311 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9312 "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9313 "
9314 {
9315 if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9316 {
9317 emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9318 get_fpscr_rtx ()));
9319 DONE;
9320 }
9321 }")
9322
9323 (define_insn "*truncdfsf2_media"
9324 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9325 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9326 "TARGET_SHMEDIA_FPU"
9327 "fcnv.ds %1, %0"
9328 [(set_attr "type" "dfpconv_media")])
9329
9330 (define_insn "truncdfsf2_i4"
9331 [(set (match_operand:SF 0 "fpul_operand" "=y")
9332 (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9333 (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9334 "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9335 "fcnvds %1,%0"
9336 [(set_attr "type" "fp")
9337 (set_attr "fp_mode" "double")])
9338 \f
9339 ;; Bit field extract patterns. These give better code for packed bitfields,
9340 ;; because they allow auto-increment addresses to be generated.
9341
9342 (define_expand "insv"
9343 [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9344 (match_operand:SI 1 "immediate_operand" "")
9345 (match_operand:SI 2 "immediate_operand" ""))
9346 (match_operand:SI 3 "general_operand" ""))]
9347 "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9348 "
9349 {
9350 rtx addr_target, orig_address, shift_reg, qi_val;
9351 HOST_WIDE_INT bitsize, size, v = 0;
9352 rtx x = operands[3];
9353
9354 /* ??? expmed doesn't care for non-register predicates. */
9355 if (! memory_operand (operands[0], VOIDmode)
9356 || ! immediate_operand (operands[1], VOIDmode)
9357 || ! immediate_operand (operands[2], VOIDmode)
9358 || ! general_operand (x, VOIDmode))
9359 FAIL;
9360 /* If this isn't a 16 / 24 / 32 bit field, or if
9361 it doesn't start on a byte boundary, then fail. */
9362 bitsize = INTVAL (operands[1]);
9363 if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9364 || (INTVAL (operands[2]) % 8) != 0)
9365 FAIL;
9366
9367 size = bitsize / 8;
9368 orig_address = XEXP (operands[0], 0);
9369 shift_reg = gen_reg_rtx (SImode);
9370 if (GET_CODE (x) == CONST_INT)
9371 {
9372 v = INTVAL (x);
9373 qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9374 }
9375 else
9376 {
9377 emit_insn (gen_movsi (shift_reg, operands[3]));
9378 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9379 }
9380 addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9381
9382 operands[0] = replace_equiv_address (operands[0], addr_target);
9383 emit_insn (gen_movqi (operands[0], qi_val));
9384
9385 while (size -= 1)
9386 {
9387 if (GET_CODE (x) == CONST_INT)
9388 qi_val
9389 = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9390 else
9391 {
9392 emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9393 qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9394 }
9395 emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9396 emit_insn (gen_movqi (operands[0], qi_val));
9397 }
9398
9399 DONE;
9400 }")
9401
9402 (define_insn "movua"
9403 [(set (match_operand:SI 0 "register_operand" "=z")
9404 (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9405 (const_int 32) (const_int 0)))]
9406 "TARGET_SH4A_ARCH"
9407 "movua.l %1,%0"
9408 [(set_attr "type" "movua")])
9409
9410 ;; We shouldn't need this, but cse replaces increments with references
9411 ;; to other regs before flow has a chance to create post_inc
9412 ;; addressing modes, and only postreload's cse_move2add brings the
9413 ;; increments back to a usable form.
9414 (define_peephole2
9415 [(set (match_operand:SI 0 "register_operand" "")
9416 (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9417 (const_int 32) (const_int 0)))
9418 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9419 "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9420 [(set (match_operand:SI 0 "register_operand" "")
9421 (sign_extract:SI (mem:SI (post_inc:SI
9422 (match_operand:SI 1 "register_operand" "")))
9423 (const_int 32) (const_int 0)))]
9424 "")
9425
9426 (define_expand "extv"
9427 [(set (match_operand:SI 0 "register_operand" "")
9428 (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9429 (match_operand 2 "const_int_operand" "")
9430 (match_operand 3 "const_int_operand" "")))]
9431 ""
9432 {
9433 if (TARGET_SH4A_ARCH
9434 && INTVAL (operands[2]) == 32
9435 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9436 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9437 {
9438 emit_insn (gen_movua (operands[0],
9439 adjust_address (operands[1], SImode, 0)));
9440 DONE;
9441 }
9442
9443 FAIL;
9444 })
9445
9446 (define_expand "extzv"
9447 [(set (match_operand:SI 0 "register_operand" "")
9448 (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9449 (match_operand 2 "const_int_operand" "")
9450 (match_operand 3 "const_int_operand" "")))]
9451 ""
9452 {
9453 if (TARGET_SH4A_ARCH
9454 && INTVAL (operands[2]) == 32
9455 && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9456 && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9457 {
9458 emit_insn (gen_movua (operands[0],
9459 adjust_address (operands[1], SImode, 0)));
9460 DONE;
9461 }
9462
9463 FAIL;
9464 })
9465
9466 \f
9467 ;; -------------------------------------------------------------------------
9468 ;; Peepholes
9469 ;; -------------------------------------------------------------------------
9470
9471 ;; This matches cases where a stack pointer increment at the start of the
9472 ;; epilogue combines with a stack slot read loading the return value.
9473
9474 (define_peephole
9475 [(set (match_operand:SI 0 "arith_reg_operand" "")
9476 (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9477 (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9478 "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9479 "mov.l @%1+,%0")
9480
9481 ;; See the comment on the dt combiner pattern above.
9482
9483 (define_peephole
9484 [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9485 (plus:SI (match_dup 0)
9486 (const_int -1)))
9487 (set (reg:SI T_REG)
9488 (eq:SI (match_dup 0)
9489 (const_int 0)))]
9490 "TARGET_SH2"
9491 "dt %0")
9492
9493 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9494 ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by
9495 ;; reload when the constant is too large for a reg+offset address.
9496
9497 ;; ??? We would get much better code if this was done in reload. This would
9498 ;; require modifying find_reloads_address to recognize that if the constant
9499 ;; is out-of-range for an immediate add, then we get better code by reloading
9500 ;; the constant into a register than by reloading the sum into a register,
9501 ;; since the former is one instruction shorter if the address does not need
9502 ;; to be offsettable. Unfortunately this does not work, because there is
9503 ;; only one register, r0, that can be used as an index register. This register
9504 ;; is also the function return value register. So, if we try to force reload
9505 ;; to use double-reg addresses, then we end up with some instructions that
9506 ;; need to use r0 twice. The only way to fix this is to change the calling
9507 ;; convention so that r0 is not used to return values.
9508
9509 (define_peephole
9510 [(set (match_operand:SI 0 "register_operand" "=r")
9511 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9512 (set (mem:SI (match_dup 0))
9513 (match_operand:SI 2 "general_movsrc_operand" ""))]
9514 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9515 "mov.l %2,@(%0,%1)")
9516
9517 (define_peephole
9518 [(set (match_operand:SI 0 "register_operand" "=r")
9519 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9520 (set (match_operand:SI 2 "general_movdst_operand" "")
9521 (mem:SI (match_dup 0)))]
9522 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9523 "mov.l @(%0,%1),%2")
9524
9525 (define_peephole
9526 [(set (match_operand:SI 0 "register_operand" "=r")
9527 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9528 (set (mem:HI (match_dup 0))
9529 (match_operand:HI 2 "general_movsrc_operand" ""))]
9530 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9531 "mov.w %2,@(%0,%1)")
9532
9533 (define_peephole
9534 [(set (match_operand:SI 0 "register_operand" "=r")
9535 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9536 (set (match_operand:HI 2 "general_movdst_operand" "")
9537 (mem:HI (match_dup 0)))]
9538 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9539 "mov.w @(%0,%1),%2")
9540
9541 (define_peephole
9542 [(set (match_operand:SI 0 "register_operand" "=r")
9543 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9544 (set (mem:QI (match_dup 0))
9545 (match_operand:QI 2 "general_movsrc_operand" ""))]
9546 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9547 "mov.b %2,@(%0,%1)")
9548
9549 (define_peephole
9550 [(set (match_operand:SI 0 "register_operand" "=r")
9551 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9552 (set (match_operand:QI 2 "general_movdst_operand" "")
9553 (mem:QI (match_dup 0)))]
9554 "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9555 "mov.b @(%0,%1),%2")
9556
9557 (define_peephole
9558 [(set (match_operand:SI 0 "register_operand" "=r")
9559 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9560 (set (mem:SF (match_dup 0))
9561 (match_operand:SF 2 "general_movsrc_operand" ""))]
9562 "TARGET_SH1 && REGNO (operands[0]) == 0
9563 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9564 || (GET_CODE (operands[2]) == SUBREG
9565 && REGNO (SUBREG_REG (operands[2])) < 16))
9566 && reg_unused_after (operands[0], insn)"
9567 "mov.l %2,@(%0,%1)")
9568
9569 (define_peephole
9570 [(set (match_operand:SI 0 "register_operand" "=r")
9571 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9572 (set (match_operand:SF 2 "general_movdst_operand" "")
9573
9574 (mem:SF (match_dup 0)))]
9575 "TARGET_SH1 && REGNO (operands[0]) == 0
9576 && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9577 || (GET_CODE (operands[2]) == SUBREG
9578 && REGNO (SUBREG_REG (operands[2])) < 16))
9579 && reg_unused_after (operands[0], insn)"
9580 "mov.l @(%0,%1),%2")
9581
9582 (define_peephole
9583 [(set (match_operand:SI 0 "register_operand" "=r")
9584 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9585 (set (mem:SF (match_dup 0))
9586 (match_operand:SF 2 "general_movsrc_operand" ""))]
9587 "TARGET_SH2E && REGNO (operands[0]) == 0
9588 && ((GET_CODE (operands[2]) == REG
9589 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9590 || (GET_CODE (operands[2]) == SUBREG
9591 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9592 && reg_unused_after (operands[0], insn)"
9593 "fmov{.s|} %2,@(%0,%1)")
9594
9595 (define_peephole
9596 [(set (match_operand:SI 0 "register_operand" "=r")
9597 (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9598 (set (match_operand:SF 2 "general_movdst_operand" "")
9599
9600 (mem:SF (match_dup 0)))]
9601 "TARGET_SH2E && REGNO (operands[0]) == 0
9602 && ((GET_CODE (operands[2]) == REG
9603 && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9604 || (GET_CODE (operands[2]) == SUBREG
9605 && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9606 && reg_unused_after (operands[0], insn)"
9607 "fmov{.s|} @(%0,%1),%2")
9608
9609 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF). */
9610 (define_insn "sp_switch_1"
9611 [(const_int 1)]
9612 "TARGET_SH1"
9613 "*
9614 {
9615 rtx xoperands[1];
9616
9617 xoperands[0] = sp_switch;
9618 output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9619 output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9620 return \"mov r0,r15\";
9621 }"
9622 [(set_attr "length" "10")])
9623
9624 ;; Switch back to the original stack for interrupt functions with the
9625 ;; sp_switch attribute. */
9626 (define_insn "sp_switch_2"
9627 [(const_int 2)]
9628 "TARGET_SH1"
9629 "mov.l @r15+,r15\;mov.l @r15+,r0"
9630 [(set_attr "length" "4")])
9631
9632 ;; Integer vector moves
9633
9634 (define_expand "movv8qi"
9635 [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9636 (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9637 "TARGET_SHMEDIA"
9638 "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9639
9640 (define_insn "movv8qi_i"
9641 [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9642 (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9643 "TARGET_SHMEDIA
9644 && (register_operand (operands[0], V8QImode)
9645 || sh_register_operand (operands[1], V8QImode))"
9646 "@
9647 add %1, r63, %0
9648 movi %1, %0
9649 #
9650 ld%M1.q %m1, %0
9651 st%M0.q %m0, %N1"
9652 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9653 (set_attr "length" "4,4,16,4,4")])
9654
9655 (define_split
9656 [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9657 (subreg:V8QI (const_int 0) 0))]
9658 "TARGET_SHMEDIA"
9659 [(set (match_dup 0)
9660 (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9661 (const_int 0) (const_int 0) (const_int 0)
9662 (const_int 0) (const_int 0)]))])
9663
9664 (define_split
9665 [(set (match_operand 0 "arith_reg_dest" "")
9666 (match_operand 1 "sh_rep_vec" ""))]
9667 "TARGET_SHMEDIA && reload_completed
9668 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9669 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9670 && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9671 && (XVECEXP (operands[1], 0, 0) != const0_rtx
9672 || XVECEXP (operands[1], 0, 1) != const0_rtx)
9673 && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9674 || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9675 [(set (match_dup 0) (match_dup 1))
9676 (match_dup 2)]
9677 "
9678 {
9679 int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9680 rtx elt1 = XVECEXP (operands[1], 0, 1);
9681
9682 if (unit_size > 2)
9683 operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9684 else
9685 {
9686 if (unit_size < 2)
9687 operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9688 operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9689 }
9690 operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9691 operands[1] = XVECEXP (operands[1], 0, 0);
9692 if (unit_size < 2)
9693 {
9694 if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9695 operands[1]
9696 = GEN_INT (TARGET_LITTLE_ENDIAN
9697 ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9698 : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9699 else
9700 {
9701 operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9702 operands[1]
9703 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9704 }
9705 }
9706 }")
9707
9708 (define_split
9709 [(set (match_operand 0 "arith_reg_dest" "")
9710 (match_operand 1 "sh_const_vec" ""))]
9711 "TARGET_SHMEDIA && reload_completed
9712 && GET_MODE (operands[0]) == GET_MODE (operands[1])
9713 && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9714 && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9715 [(set (match_dup 0) (match_dup 1))]
9716 "
9717 {
9718 rtx v = operands[1];
9719 enum machine_mode new_mode
9720 = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9721
9722 operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9723 operands[1]
9724 = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9725 }")
9726
9727 (define_expand "movv2hi"
9728 [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9729 (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9730 "TARGET_SHMEDIA"
9731 "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9732
9733 (define_insn "movv2hi_i"
9734 [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9735 (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9736 "TARGET_SHMEDIA
9737 && (register_operand (operands[0], V2HImode)
9738 || sh_register_operand (operands[1], V2HImode))"
9739 "@
9740 addz.l %1, r63, %0
9741 movi %1, %0
9742 #
9743 ld%M1.l %m1, %0
9744 st%M0.l %m0, %N1"
9745 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9746 (set_attr "length" "4,4,16,4,4")])
9747
9748 (define_expand "movv4hi"
9749 [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9750 (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9751 "TARGET_SHMEDIA"
9752 "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9753
9754 (define_insn "movv4hi_i"
9755 [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9756 (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9757 "TARGET_SHMEDIA
9758 && (register_operand (operands[0], V4HImode)
9759 || sh_register_operand (operands[1], V4HImode))"
9760 "@
9761 add %1, r63, %0
9762 movi %1, %0
9763 #
9764 ld%M1.q %m1, %0
9765 st%M0.q %m0, %N1"
9766 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9767 (set_attr "length" "4,4,16,4,4")])
9768
9769 (define_expand "movv2si"
9770 [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9771 (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9772 "TARGET_SHMEDIA"
9773 "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9774
9775 (define_insn "movv2si_i"
9776 [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9777 (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9778 "TARGET_SHMEDIA
9779 && (register_operand (operands[0], V2SImode)
9780 || sh_register_operand (operands[1], V2SImode))"
9781 "@
9782 add %1, r63, %0
9783 #
9784 #
9785 ld%M1.q %m1, %0
9786 st%M0.q %m0, %N1"
9787 [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
9788 (set_attr "length" "4,4,16,4,4")])
9789
9790 ;; Multimedia Intrinsics
9791
9792 (define_insn "absv2si2"
9793 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9794 (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9795 "TARGET_SHMEDIA"
9796 "mabs.l %1, %0"
9797 [(set_attr "type" "mcmp_media")])
9798
9799 (define_insn "absv4hi2"
9800 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9801 (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9802 "TARGET_SHMEDIA"
9803 "mabs.w %1, %0"
9804 [(set_attr "type" "mcmp_media")])
9805
9806 (define_insn "addv2si3"
9807 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9808 (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9809 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9810 "TARGET_SHMEDIA"
9811 "madd.l %1, %2, %0"
9812 [(set_attr "type" "arith_media")])
9813
9814 (define_insn "addv4hi3"
9815 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9816 (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9817 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9818 "TARGET_SHMEDIA"
9819 "madd.w %1, %2, %0"
9820 [(set_attr "type" "arith_media")])
9821
9822 (define_insn "ssaddv2si3"
9823 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9824 (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9825 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9826 "TARGET_SHMEDIA"
9827 "madds.l %1, %2, %0"
9828 [(set_attr "type" "mcmp_media")])
9829
9830 (define_insn "usaddv8qi3"
9831 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9832 (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9833 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9834 "TARGET_SHMEDIA"
9835 "madds.ub %1, %2, %0"
9836 [(set_attr "type" "mcmp_media")])
9837
9838 (define_insn "ssaddv4hi3"
9839 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9840 (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9841 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9842 "TARGET_SHMEDIA"
9843 "madds.w %1, %2, %0"
9844 [(set_attr "type" "mcmp_media")])
9845
9846 (define_insn "negcmpeqv8qi"
9847 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9848 (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9849 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9850 "TARGET_SHMEDIA"
9851 "mcmpeq.b %N1, %N2, %0"
9852 [(set_attr "type" "mcmp_media")])
9853
9854 (define_insn "negcmpeqv2si"
9855 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9856 (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9857 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9858 "TARGET_SHMEDIA"
9859 "mcmpeq.l %N1, %N2, %0"
9860 [(set_attr "type" "mcmp_media")])
9861
9862 (define_insn "negcmpeqv4hi"
9863 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9864 (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9865 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9866 "TARGET_SHMEDIA"
9867 "mcmpeq.w %N1, %N2, %0"
9868 [(set_attr "type" "mcmp_media")])
9869
9870 (define_insn "negcmpgtuv8qi"
9871 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9872 (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9873 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9874 "TARGET_SHMEDIA"
9875 "mcmpgt.ub %N1, %N2, %0"
9876 [(set_attr "type" "mcmp_media")])
9877
9878 (define_insn "negcmpgtv2si"
9879 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9880 (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9881 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9882 "TARGET_SHMEDIA"
9883 "mcmpgt.l %N1, %N2, %0"
9884 [(set_attr "type" "mcmp_media")])
9885
9886 (define_insn "negcmpgtv4hi"
9887 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9888 (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9889 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9890 "TARGET_SHMEDIA"
9891 "mcmpgt.w %N1, %N2, %0"
9892 [(set_attr "type" "mcmp_media")])
9893
9894 (define_insn "mcmv"
9895 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9896 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9897 (match_operand:DI 2 "arith_reg_operand" "r"))
9898 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9899 (not:DI (match_dup 2)))))]
9900 "TARGET_SHMEDIA"
9901 "mcmv %N1, %2, %0"
9902 [(set_attr "type" "arith_media")])
9903
9904 (define_insn "mcnvs_lw"
9905 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9906 (vec_concat:V4HI
9907 (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9908 (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9909 "TARGET_SHMEDIA"
9910 "mcnvs.lw %N1, %N2, %0"
9911 [(set_attr "type" "mcmp_media")])
9912
9913 (define_insn "mcnvs_wb"
9914 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9915 (vec_concat:V8QI
9916 (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9917 (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9918 "TARGET_SHMEDIA"
9919 "mcnvs.wb %N1, %N2, %0"
9920 [(set_attr "type" "mcmp_media")])
9921
9922 (define_insn "mcnvs_wub"
9923 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9924 (vec_concat:V8QI
9925 (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9926 (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9927 "TARGET_SHMEDIA"
9928 "mcnvs.wub %N1, %N2, %0"
9929 [(set_attr "type" "mcmp_media")])
9930
9931 (define_insn "mextr_rl"
9932 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9933 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9934 (match_operand:HI 3 "mextr_bit_offset" "i"))
9935 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9936 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9937 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9938 "*
9939 {
9940 static char templ[16];
9941
9942 sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9943 (int) INTVAL (operands[3]) >> 3);
9944 return templ;
9945 }"
9946 [(set_attr "type" "arith_media")])
9947
9948 (define_insn "*mextr_lr"
9949 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9950 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9951 (match_operand:HI 3 "mextr_bit_offset" "i"))
9952 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9953 (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9954 "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9955 "*
9956 {
9957 static char templ[16];
9958
9959 sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9960 (int) INTVAL (operands[4]) >> 3);
9961 return templ;
9962 }"
9963 [(set_attr "type" "arith_media")])
9964
9965 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9966 ; vector then varies depending on endianness.
9967 (define_expand "mextr1"
9968 [(match_operand:DI 0 "arith_reg_dest" "")
9969 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9970 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9971 "TARGET_SHMEDIA"
9972 "
9973 {
9974 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9975 GEN_INT (1 * 8), GEN_INT (7 * 8)));
9976 DONE;
9977 }")
9978
9979 (define_expand "mextr2"
9980 [(match_operand:DI 0 "arith_reg_dest" "")
9981 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9982 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9983 "TARGET_SHMEDIA"
9984 "
9985 {
9986 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9987 GEN_INT (2 * 8), GEN_INT (6 * 8)));
9988 DONE;
9989 }")
9990
9991 (define_expand "mextr3"
9992 [(match_operand:DI 0 "arith_reg_dest" "")
9993 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9994 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9995 "TARGET_SHMEDIA"
9996 "
9997 {
9998 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9999 GEN_INT (3 * 8), GEN_INT (5 * 8)));
10000 DONE;
10001 }")
10002
10003 (define_expand "mextr4"
10004 [(match_operand:DI 0 "arith_reg_dest" "")
10005 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10006 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10007 "TARGET_SHMEDIA"
10008 "
10009 {
10010 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10011 GEN_INT (4 * 8), GEN_INT (4 * 8)));
10012 DONE;
10013 }")
10014
10015 (define_expand "mextr5"
10016 [(match_operand:DI 0 "arith_reg_dest" "")
10017 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10018 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10019 "TARGET_SHMEDIA"
10020 "
10021 {
10022 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10023 GEN_INT (5 * 8), GEN_INT (3 * 8)));
10024 DONE;
10025 }")
10026
10027 (define_expand "mextr6"
10028 [(match_operand:DI 0 "arith_reg_dest" "")
10029 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10030 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10031 "TARGET_SHMEDIA"
10032 "
10033 {
10034 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10035 GEN_INT (6 * 8), GEN_INT (2 * 8)));
10036 DONE;
10037 }")
10038
10039 (define_expand "mextr7"
10040 [(match_operand:DI 0 "arith_reg_dest" "")
10041 (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10042 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10043 "TARGET_SHMEDIA"
10044 "
10045 {
10046 emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10047 GEN_INT (7 * 8), GEN_INT (1 * 8)));
10048 DONE;
10049 }")
10050
10051 (define_expand "mmacfx_wl"
10052 [(match_operand:V2SI 0 "arith_reg_dest" "")
10053 (match_operand:V2HI 1 "extend_reg_operand" "")
10054 (match_operand:V2HI 2 "extend_reg_operand" "")
10055 (match_operand:V2SI 3 "arith_reg_operand" "")]
10056 "TARGET_SHMEDIA"
10057 "
10058 {
10059 emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
10060 operands[1], operands[2]));
10061 DONE;
10062 }")
10063
10064 (define_insn "mmacfx_wl_i"
10065 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10066 (ss_plus:V2SI
10067 (match_operand:V2SI 1 "arith_reg_operand" "0")
10068 (ss_truncate:V2SI
10069 (ashift:V2DI
10070 (sign_extend:V2DI
10071 (mult:V2SI
10072 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10073 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10074 (const_int 1)))))]
10075 "TARGET_SHMEDIA"
10076 "mmacfx.wl %2, %3, %0"
10077 [(set_attr "type" "mac_media")])
10078
10079 (define_expand "mmacnfx_wl"
10080 [(match_operand:V2SI 0 "arith_reg_dest" "")
10081 (match_operand:V2HI 1 "extend_reg_operand" "")
10082 (match_operand:V2HI 2 "extend_reg_operand" "")
10083 (match_operand:V2SI 3 "arith_reg_operand" "")]
10084 "TARGET_SHMEDIA"
10085 "
10086 {
10087 emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10088 operands[1], operands[2]));
10089 DONE;
10090 }")
10091
10092 (define_insn "mmacnfx_wl_i"
10093 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10094 (ss_minus:V2SI
10095 (match_operand:V2SI 1 "arith_reg_operand" "0")
10096 (ss_truncate:V2SI
10097 (ashift:V2DI
10098 (sign_extend:V2DI
10099 (mult:V2SI
10100 (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10101 (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10102 (const_int 1)))))]
10103 "TARGET_SHMEDIA"
10104 "mmacnfx.wl %2, %3, %0"
10105 [(set_attr "type" "mac_media")])
10106
10107 (define_insn "mulv2si3"
10108 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10109 (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10110 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10111 "TARGET_SHMEDIA"
10112 "mmul.l %1, %2, %0"
10113 [(set_attr "type" "d2mpy_media")])
10114
10115 (define_insn "mulv4hi3"
10116 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10117 (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10118 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10119 "TARGET_SHMEDIA"
10120 "mmul.w %1, %2, %0"
10121 [(set_attr "type" "dmpy_media")])
10122
10123 (define_insn "mmulfx_l"
10124 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10125 (ss_truncate:V2SI
10126 (ashiftrt:V2DI
10127 (mult:V2DI
10128 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10129 (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10130 (const_int 31))))]
10131 "TARGET_SHMEDIA"
10132 "mmulfx.l %1, %2, %0"
10133 [(set_attr "type" "d2mpy_media")])
10134
10135 (define_insn "mmulfx_w"
10136 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10137 (ss_truncate:V4HI
10138 (ashiftrt:V4SI
10139 (mult:V4SI
10140 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10141 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10142 (const_int 15))))]
10143 "TARGET_SHMEDIA"
10144 "mmulfx.w %1, %2, %0"
10145 [(set_attr "type" "dmpy_media")])
10146
10147 (define_insn "mmulfxrp_w"
10148 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10149 (ss_truncate:V4HI
10150 (ashiftrt:V4SI
10151 (plus:V4SI
10152 (mult:V4SI
10153 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10154 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10155 (const_int 16384))
10156 (const_int 15))))]
10157 "TARGET_SHMEDIA"
10158 "mmulfxrp.w %1, %2, %0"
10159 [(set_attr "type" "dmpy_media")])
10160
10161 (define_expand "mmulhi_wl"
10162 [(match_operand:V2SI 0 "arith_reg_dest" "")
10163 (match_operand:V4HI 1 "arith_reg_operand" "")
10164 (match_operand:V4HI 2 "arith_reg_operand" "")]
10165 "TARGET_SHMEDIA"
10166 "
10167 {
10168 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10169 (operands[0], operands[1], operands[2]));
10170 DONE;
10171 }")
10172
10173 (define_expand "mmullo_wl"
10174 [(match_operand:V2SI 0 "arith_reg_dest" "")
10175 (match_operand:V4HI 1 "arith_reg_operand" "")
10176 (match_operand:V4HI 2 "arith_reg_operand" "")]
10177 "TARGET_SHMEDIA"
10178 "
10179 {
10180 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10181 (operands[0], operands[1], operands[2]));
10182 DONE;
10183 }")
10184
10185 (define_insn "mmul23_wl"
10186 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10187 (vec_select:V2SI
10188 (mult:V4SI
10189 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10190 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10191 (parallel [(const_int 2) (const_int 3)])))]
10192 "TARGET_SHMEDIA"
10193 "* return (TARGET_LITTLE_ENDIAN
10194 ? \"mmulhi.wl %1, %2, %0\"
10195 : \"mmullo.wl %1, %2, %0\");"
10196 [(set_attr "type" "dmpy_media")])
10197
10198 (define_insn "mmul01_wl"
10199 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10200 (vec_select:V2SI
10201 (mult:V4SI
10202 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10203 (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10204 (parallel [(const_int 0) (const_int 1)])))]
10205 "TARGET_SHMEDIA"
10206 "* return (TARGET_LITTLE_ENDIAN
10207 ? \"mmullo.wl %1, %2, %0\"
10208 : \"mmulhi.wl %1, %2, %0\");"
10209 [(set_attr "type" "dmpy_media")])
10210
10211 (define_expand "mmulsum_wq"
10212 [(match_operand:DI 0 "arith_reg_dest" "")
10213 (match_operand:V4HI 1 "arith_reg_operand" "")
10214 (match_operand:V4HI 2 "arith_reg_operand" "")
10215 (match_operand:DI 3 "arith_reg_operand" "")]
10216 "TARGET_SHMEDIA"
10217 "
10218 {
10219 emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10220 operands[1], operands[2]));
10221 DONE;
10222 }")
10223
10224 (define_insn "mmulsum_wq_i"
10225 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10226 (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10227 (plus:DI
10228 (plus:DI
10229 (vec_select:DI
10230 (mult:V4DI
10231 (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10232 (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10233 (parallel [(const_int 0)]))
10234 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10235 (sign_extend:V4DI (match_dup 3)))
10236 (parallel [(const_int 1)])))
10237 (plus:DI
10238 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10239 (sign_extend:V4DI (match_dup 3)))
10240 (parallel [(const_int 2)]))
10241 (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10242 (sign_extend:V4DI (match_dup 3)))
10243 (parallel [(const_int 3)]))))))]
10244 "TARGET_SHMEDIA"
10245 "mmulsum.wq %2, %3, %0"
10246 [(set_attr "type" "mac_media")])
10247
10248 (define_expand "mperm_w"
10249 [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10250 (match_operand:V4HI 1 "arith_reg_operand" "r")
10251 (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10252 "TARGET_SHMEDIA"
10253 "
10254 {
10255 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10256 (operands[0], operands[1], operands[2]));
10257 DONE;
10258 }")
10259
10260 ; This use of vec_select isn't exactly correct according to rtl.texi
10261 ; (because not constant), but it seems a straightforward extension.
10262 (define_insn "mperm_w_little"
10263 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10264 (vec_select:V4HI
10265 (match_operand:V4HI 1 "arith_reg_operand" "r")
10266 (parallel
10267 [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10268 (const_int 2) (const_int 0))
10269 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10270 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10271 (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10272 "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10273 "mperm.w %1, %N2, %0"
10274 [(set_attr "type" "arith_media")])
10275
10276 (define_insn "mperm_w_big"
10277 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10278 (vec_select:V4HI
10279 (match_operand:V4HI 1 "arith_reg_operand" "r")
10280 (parallel
10281 [(zero_extract:QI (not:QI (match_operand:QI 2
10282 "extend_reg_or_0_operand" "rZ"))
10283 (const_int 2) (const_int 0))
10284 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10285 (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10286 (zero_extract:QI (not:QI (match_dup 2))
10287 (const_int 2) (const_int 6))])))]
10288 "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10289 "mperm.w %1, %N2, %0"
10290 [(set_attr "type" "arith_media")])
10291
10292 (define_insn "mperm_w0"
10293 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10294 (vec_duplicate:V4HI (truncate:HI (match_operand 1
10295 "trunc_hi_operand" "r"))))]
10296 "TARGET_SHMEDIA"
10297 "mperm.w %1, r63, %0"
10298 [(set_attr "type" "arith_media")])
10299
10300 (define_expand "msad_ubq"
10301 [(match_operand:DI 0 "arith_reg_dest" "")
10302 (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10303 (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10304 (match_operand:DI 3 "arith_reg_operand" "")]
10305 "TARGET_SHMEDIA"
10306 "
10307 {
10308 emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10309 operands[1], operands[2]));
10310 DONE;
10311 }")
10312
10313 (define_insn "msad_ubq_i"
10314 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10315 (plus:DI
10316 (plus:DI
10317 (plus:DI
10318 (plus:DI
10319 (match_operand:DI 1 "arith_reg_operand" "0")
10320 (abs:DI (vec_select:DI
10321 (minus:V8DI
10322 (zero_extend:V8DI
10323 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10324 (zero_extend:V8DI
10325 (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10326 (parallel [(const_int 0)]))))
10327 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10328 (zero_extend:V8DI (match_dup 3)))
10329 (parallel [(const_int 1)]))))
10330 (plus:DI
10331 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10332 (zero_extend:V8DI (match_dup 3)))
10333 (parallel [(const_int 2)])))
10334 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10335 (zero_extend:V8DI (match_dup 3)))
10336 (parallel [(const_int 3)])))))
10337 (plus:DI
10338 (plus:DI
10339 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10340 (zero_extend:V8DI (match_dup 3)))
10341 (parallel [(const_int 4)])))
10342 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10343 (zero_extend:V8DI (match_dup 3)))
10344 (parallel [(const_int 5)]))))
10345 (plus:DI
10346 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10347 (zero_extend:V8DI (match_dup 3)))
10348 (parallel [(const_int 6)])))
10349 (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10350 (zero_extend:V8DI (match_dup 3)))
10351 (parallel [(const_int 7)])))))))]
10352 "TARGET_SHMEDIA"
10353 "msad.ubq %N2, %N3, %0"
10354 [(set_attr "type" "mac_media")])
10355
10356 (define_insn "mshalds_l"
10357 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10358 (ss_truncate:V2SI
10359 (ashift:V2DI
10360 (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10361 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10362 (const_int 31)))))]
10363 "TARGET_SHMEDIA"
10364 "mshalds.l %1, %2, %0"
10365 [(set_attr "type" "mcmp_media")])
10366
10367 (define_insn "mshalds_w"
10368 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10369 (ss_truncate:V4HI
10370 (ashift:V4SI
10371 (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10372 (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10373 (const_int 15)))))]
10374 "TARGET_SHMEDIA"
10375 "mshalds.w %1, %2, %0"
10376 [(set_attr "type" "mcmp_media")])
10377
10378 (define_insn "ashrv2si3"
10379 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10380 (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10381 (match_operand:DI 2 "arith_reg_operand" "r")))]
10382 "TARGET_SHMEDIA"
10383 "mshard.l %1, %2, %0"
10384 [(set_attr "type" "arith_media")])
10385
10386 (define_insn "ashrv4hi3"
10387 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10388 (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10389 (match_operand:DI 2 "arith_reg_operand" "r")))]
10390 "TARGET_SHMEDIA"
10391 "mshard.w %1, %2, %0"
10392 [(set_attr "type" "arith_media")])
10393
10394 (define_insn "mshards_q"
10395 [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10396 (ss_truncate:HI
10397 (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10398 (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10399 "TARGET_SHMEDIA"
10400 "mshards.q %1, %N2, %0"
10401 [(set_attr "type" "mcmp_media")])
10402
10403 (define_expand "mshfhi_b"
10404 [(match_operand:V8QI 0 "arith_reg_dest" "")
10405 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10406 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10407 "TARGET_SHMEDIA"
10408 "
10409 {
10410 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10411 (operands[0], operands[1], operands[2]));
10412 DONE;
10413 }")
10414
10415 (define_expand "mshflo_b"
10416 [(match_operand:V8QI 0 "arith_reg_dest" "")
10417 (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10418 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10419 "TARGET_SHMEDIA"
10420 "
10421 {
10422 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10423 (operands[0], operands[1], operands[2]));
10424 DONE;
10425 }")
10426
10427 (define_insn "mshf4_b"
10428 [(set
10429 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10430 (vec_select:V8QI
10431 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10432 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10433 (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10434 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10435 "TARGET_SHMEDIA"
10436 "* return (TARGET_LITTLE_ENDIAN
10437 ? \"mshfhi.b %N1, %N2, %0\"
10438 : \"mshflo.b %N1, %N2, %0\");"
10439 [(set_attr "type" "arith_media")])
10440
10441 (define_insn "mshf0_b"
10442 [(set
10443 (match_operand:V8QI 0 "arith_reg_dest" "=r")
10444 (vec_select:V8QI
10445 (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10446 (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10447 (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10448 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10449 "TARGET_SHMEDIA"
10450 "* return (TARGET_LITTLE_ENDIAN
10451 ? \"mshflo.b %N1, %N2, %0\"
10452 : \"mshfhi.b %N1, %N2, %0\");"
10453 [(set_attr "type" "arith_media")])
10454
10455 (define_expand "mshfhi_l"
10456 [(match_operand:V2SI 0 "arith_reg_dest" "")
10457 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10458 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10459 "TARGET_SHMEDIA"
10460 "
10461 {
10462 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10463 (operands[0], operands[1], operands[2]));
10464 DONE;
10465 }")
10466
10467 (define_expand "mshflo_l"
10468 [(match_operand:V2SI 0 "arith_reg_dest" "")
10469 (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10470 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10471 "TARGET_SHMEDIA"
10472 "
10473 {
10474 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10475 (operands[0], operands[1], operands[2]));
10476 DONE;
10477 }")
10478
10479 (define_insn "mshf4_l"
10480 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10481 (vec_select:V2SI
10482 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10483 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10484 (parallel [(const_int 1) (const_int 3)])))]
10485 "TARGET_SHMEDIA"
10486 "* return (TARGET_LITTLE_ENDIAN
10487 ? \"mshfhi.l %N1, %N2, %0\"
10488 : \"mshflo.l %N1, %N2, %0\");"
10489 [(set_attr "type" "arith_media")])
10490
10491 (define_insn "mshf0_l"
10492 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10493 (vec_select:V2SI
10494 (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10495 (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10496 (parallel [(const_int 0) (const_int 2)])))]
10497 "TARGET_SHMEDIA"
10498 "* return (TARGET_LITTLE_ENDIAN
10499 ? \"mshflo.l %N1, %N2, %0\"
10500 : \"mshfhi.l %N1, %N2, %0\");"
10501 [(set_attr "type" "arith_media")])
10502
10503 (define_expand "mshfhi_w"
10504 [(match_operand:V4HI 0 "arith_reg_dest" "")
10505 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10506 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10507 "TARGET_SHMEDIA"
10508 "
10509 {
10510 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10511 (operands[0], operands[1], operands[2]));
10512 DONE;
10513 }")
10514
10515 (define_expand "mshflo_w"
10516 [(match_operand:V4HI 0 "arith_reg_dest" "")
10517 (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10518 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10519 "TARGET_SHMEDIA"
10520 "
10521 {
10522 emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10523 (operands[0], operands[1], operands[2]));
10524 DONE;
10525 }")
10526
10527 (define_insn "mshf4_w"
10528 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10529 (vec_select:V4HI
10530 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10531 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10532 (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10533 "TARGET_SHMEDIA"
10534 "* return (TARGET_LITTLE_ENDIAN
10535 ? \"mshfhi.w %N1, %N2, %0\"
10536 : \"mshflo.w %N1, %N2, %0\");"
10537 [(set_attr "type" "arith_media")])
10538
10539 (define_insn "mshf0_w"
10540 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10541 (vec_select:V4HI
10542 (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10543 (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10544 (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10545 "TARGET_SHMEDIA"
10546 "* return (TARGET_LITTLE_ENDIAN
10547 ? \"mshflo.w %N1, %N2, %0\"
10548 : \"mshfhi.w %N1, %N2, %0\");"
10549 [(set_attr "type" "arith_media")])
10550
10551 (define_insn "mshflo_w_x"
10552 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10553 (vec_select:V4HI
10554 (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10555 (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10556 (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10557 "TARGET_SHMEDIA"
10558 "mshflo.w %N1, %N2, %0"
10559 [(set_attr "type" "arith_media")])
10560
10561 /* These are useful to expand ANDs and as combiner patterns. */
10562 (define_insn_and_split "mshfhi_l_di"
10563 [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10564 (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10565 (const_int 32))
10566 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10567 (const_int -4294967296))))]
10568 "TARGET_SHMEDIA"
10569 "@
10570 mshfhi.l %N1, %N2, %0
10571 #"
10572 "TARGET_SHMEDIA && reload_completed
10573 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10574 [(set (match_dup 3) (match_dup 4))
10575 (set (match_dup 5) (match_dup 6))]
10576 "
10577 {
10578 operands[3] = gen_lowpart (SImode, operands[0]);
10579 operands[4] = gen_highpart (SImode, operands[1]);
10580 operands[5] = gen_highpart (SImode, operands[0]);
10581 operands[6] = gen_highpart (SImode, operands[2]);
10582 }"
10583 [(set_attr "type" "arith_media")])
10584
10585 (define_insn "*mshfhi_l_di_rev"
10586 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10587 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10588 (const_int -4294967296))
10589 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10590 (const_int 32))))]
10591 "TARGET_SHMEDIA"
10592 "mshfhi.l %N2, %N1, %0"
10593 [(set_attr "type" "arith_media")])
10594
10595 (define_split
10596 [(set (match_operand:DI 0 "arith_reg_dest" "")
10597 (ior:DI (zero_extend:DI (match_operand:SI 1
10598 "extend_reg_or_0_operand" ""))
10599 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10600 (const_int -4294967296))))
10601 (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10602 "TARGET_SHMEDIA"
10603 [(const_int 0)]
10604 "
10605 {
10606 emit_insn (gen_ashldi3_media (operands[3],
10607 simplify_gen_subreg (DImode, operands[1],
10608 SImode, 0),
10609 GEN_INT (32)));
10610 emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10611 DONE;
10612 }")
10613
10614 (define_insn "mshflo_l_di"
10615 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10616 (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10617 (const_int 4294967295))
10618 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10619 (const_int 32))))]
10620
10621 "TARGET_SHMEDIA"
10622 "mshflo.l %N1, %N2, %0"
10623 [(set_attr "type" "arith_media")])
10624
10625 (define_insn "*mshflo_l_di_rev"
10626 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10627 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10628 (const_int 32))
10629 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10630 (const_int 4294967295))))]
10631
10632 "TARGET_SHMEDIA"
10633 "mshflo.l %N2, %N1, %0"
10634 [(set_attr "type" "arith_media")])
10635
10636 ;; Combiner pattern for trampoline initialization.
10637 (define_insn_and_split "*double_shori"
10638 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10639 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10640 (const_int 32))
10641 (match_operand:DI 2 "const_int_operand" "n")))]
10642 "TARGET_SHMEDIA
10643 && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10644 "#"
10645 "rtx_equal_p (operands[0], operands[1])"
10646 [(const_int 0)]
10647 "
10648 {
10649 HOST_WIDE_INT v = INTVAL (operands[2]);
10650
10651 emit_insn (gen_shori_media (operands[0], operands[0],
10652 gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10653 emit_insn (gen_shori_media (operands[0], operands[0],
10654 gen_int_mode (v, HImode)));
10655 DONE;
10656 }")
10657
10658
10659 (define_insn "*mshflo_l_di_x"
10660 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10661 (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10662 "rZ"))
10663 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10664 (const_int 32))))]
10665
10666 "TARGET_SHMEDIA"
10667 "mshflo.l %N1, %N2, %0"
10668 [(set_attr "type" "arith_media")])
10669
10670 (define_insn_and_split "concat_v2sf"
10671 [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10672 ;; (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10673 (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10674 (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10675
10676 "TARGET_SHMEDIA"
10677 "@
10678 mshflo.l %N1, %N2, %0
10679 #
10680 #"
10681 "TARGET_SHMEDIA && reload_completed
10682 && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10683 [(set (match_dup 3) (match_dup 1))
10684 (set (match_dup 4) (match_dup 2))]
10685 "
10686 {
10687 operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10688 operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10689 }"
10690 [(set_attr "type" "arith_media")])
10691
10692 (define_insn "*mshflo_l_di_x_rev"
10693 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10694 (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10695 (const_int 32))
10696 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10697
10698 "TARGET_SHMEDIA"
10699 "mshflo.l %N2, %N1, %0"
10700 [(set_attr "type" "arith_media")])
10701
10702 (define_insn "ashlv2si3"
10703 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10704 (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10705 (match_operand:DI 2 "arith_reg_operand" "r")))]
10706 "TARGET_SHMEDIA"
10707 "mshlld.l %1, %2, %0"
10708 [(set_attr "type" "arith_media")])
10709
10710 (define_insn "ashlv4hi3"
10711 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10712 (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10713 (match_operand:DI 2 "arith_reg_operand" "r")))]
10714 "TARGET_SHMEDIA"
10715 "mshlld.w %1, %2, %0"
10716 [(set_attr "type" "arith_media")])
10717
10718 (define_insn "lshrv2si3"
10719 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10720 (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10721 (match_operand:DI 2 "arith_reg_operand" "r")))]
10722 "TARGET_SHMEDIA"
10723 "mshlrd.l %1, %2, %0"
10724 [(set_attr "type" "arith_media")])
10725
10726 (define_insn "lshrv4hi3"
10727 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10728 (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10729 (match_operand:DI 2 "arith_reg_operand" "r")))]
10730 "TARGET_SHMEDIA"
10731 "mshlrd.w %1, %2, %0"
10732 [(set_attr "type" "arith_media")])
10733
10734 (define_insn "subv2si3"
10735 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10736 (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10737 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10738 "TARGET_SHMEDIA"
10739 "msub.l %N1, %2, %0"
10740 [(set_attr "type" "arith_media")])
10741
10742 (define_insn "subv4hi3"
10743 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10744 (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10745 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10746 "TARGET_SHMEDIA"
10747 "msub.w %N1, %2, %0"
10748 [(set_attr "type" "arith_media")])
10749
10750 (define_insn "sssubv2si3"
10751 [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10752 (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10753 (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10754 "TARGET_SHMEDIA"
10755 "msubs.l %N1, %2, %0"
10756 [(set_attr "type" "mcmp_media")])
10757
10758 (define_insn "ussubv8qi3"
10759 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10760 (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10761 (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10762 "TARGET_SHMEDIA"
10763 "msubs.ub %1, %2, %0"
10764 [(set_attr "type" "mcmp_media")])
10765
10766 (define_insn "sssubv4hi3"
10767 [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10768 (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10769 (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10770 "TARGET_SHMEDIA"
10771 "msubs.w %N1, %2, %0"
10772 [(set_attr "type" "mcmp_media")])
10773
10774 ;; Floating Point Intrinsics
10775
10776 (define_insn "fcosa_s"
10777 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10778 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10779 UNSPEC_FCOSA))]
10780 "TARGET_SHMEDIA"
10781 "fcosa.s %1, %0"
10782 [(set_attr "type" "atrans_media")])
10783
10784 (define_insn "fsina_s"
10785 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10786 (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10787 UNSPEC_FSINA))]
10788 "TARGET_SHMEDIA"
10789 "fsina.s %1, %0"
10790 [(set_attr "type" "atrans_media")])
10791
10792 (define_insn "fipr"
10793 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10794 (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10795 "fp_arith_reg_operand" "f")
10796 (match_operand:V4SF 2
10797 "fp_arith_reg_operand" "f"))
10798 (parallel [(const_int 0)]))
10799 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10800 (parallel [(const_int 1)])))
10801 (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10802 (parallel [(const_int 2)]))
10803 (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10804 (parallel [(const_int 3)])))))]
10805 "TARGET_SHMEDIA"
10806 "fipr.s %1, %2, %0"
10807 [(set_attr "type" "fparith_media")])
10808
10809 (define_insn "fsrra_s"
10810 [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10811 (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10812 UNSPEC_FSRRA))]
10813 "TARGET_SHMEDIA"
10814 "fsrra.s %1, %0"
10815 [(set_attr "type" "atrans_media")])
10816
10817 (define_insn "ftrv"
10818 [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10819 (plus:V4SF
10820 (plus:V4SF
10821 (mult:V4SF
10822 (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10823 (parallel [(const_int 0) (const_int 5)
10824 (const_int 10) (const_int 15)]))
10825 (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10826 (mult:V4SF
10827 (vec_select:V4SF (match_dup 1)
10828 (parallel [(const_int 4) (const_int 9)
10829 (const_int 14) (const_int 3)]))
10830 (vec_select:V4SF (match_dup 2)
10831 (parallel [(const_int 1) (const_int 2)
10832 (const_int 3) (const_int 0)]))))
10833 (plus:V4SF
10834 (mult:V4SF
10835 (vec_select:V4SF (match_dup 1)
10836 (parallel [(const_int 8) (const_int 13)
10837 (const_int 2) (const_int 7)]))
10838 (vec_select:V4SF (match_dup 2)
10839 (parallel [(const_int 2) (const_int 3)
10840 (const_int 0) (const_int 1)])))
10841 (mult:V4SF
10842 (vec_select:V4SF (match_dup 1)
10843 (parallel [(const_int 12) (const_int 1)
10844 (const_int 6) (const_int 11)]))
10845 (vec_select:V4SF (match_dup 2)
10846 (parallel [(const_int 3) (const_int 0)
10847 (const_int 1) (const_int 2)]))))))]
10848 "TARGET_SHMEDIA"
10849 "ftrv.s %1, %2, %0"
10850 [(set_attr "type" "fparith_media")])
10851
10852 (define_insn "nsb"
10853 [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10854 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10855 UNSPEC_NSB))]
10856 "TARGET_SHMEDIA"
10857 "nsb %1, %0"
10858 [(set_attr "type" "arith_media")])
10859
10860 (define_insn "nsbsi"
10861 [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10862 (zero_extend:SI
10863 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10864 UNSPEC_NSB)))]
10865 "TARGET_SHMEDIA"
10866 "nsb %1, %0"
10867 [(set_attr "type" "arith_media")])
10868
10869 (define_insn "nsbdi"
10870 [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10871 (zero_extend:DI
10872 (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10873 UNSPEC_NSB)))]
10874 "TARGET_SHMEDIA"
10875 "nsb %1, %0"
10876 [(set_attr "type" "arith_media")])
10877
10878 (define_expand "ffsdi2"
10879 [(set (match_operand:DI 0 "arith_reg_dest" "")
10880 (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10881 "TARGET_SHMEDIA"
10882 "
10883 {
10884 rtx scratch = gen_reg_rtx (DImode);
10885 rtx last;
10886
10887 emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10888 emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10889 emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10890 emit_insn (gen_nsbdi (scratch, scratch));
10891 emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10892 emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10893 last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10894 REG_NOTES (last)
10895 = gen_rtx_EXPR_LIST (REG_EQUAL,
10896 gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10897 DONE;
10898 }")
10899
10900 (define_expand "ffssi2"
10901 [(set (match_operand:SI 0 "arith_reg_dest" "")
10902 (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10903 "TARGET_SHMEDIA"
10904 "
10905 {
10906 rtx scratch = gen_reg_rtx (SImode);
10907 rtx discratch = gen_reg_rtx (DImode);
10908 rtx last;
10909
10910 emit_insn (gen_adddi3 (discratch,
10911 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10912 constm1_rtx));
10913 emit_insn (gen_andcdi3 (discratch,
10914 simplify_gen_subreg (DImode, operands[1], SImode, 0),
10915 discratch));
10916 emit_insn (gen_nsbsi (scratch, discratch));
10917 last = emit_insn (gen_subsi3 (operands[0],
10918 force_reg (SImode, GEN_INT (63)), scratch));
10919 REG_NOTES (last)
10920 = gen_rtx_EXPR_LIST (REG_EQUAL,
10921 gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10922 DONE;
10923 }")
10924
10925 (define_insn "byterev"
10926 [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10927 (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10928 (parallel [(const_int 7) (const_int 6) (const_int 5)
10929 (const_int 4) (const_int 3) (const_int 2)
10930 (const_int 1) (const_int 0)])))]
10931 "TARGET_SHMEDIA"
10932 "byterev %1, %0"
10933 [(set_attr "type" "arith_media")])
10934
10935 (define_insn "prefetch"
10936 [(prefetch (match_operand:QI 0 "address_operand" "p")
10937 (match_operand:SI 1 "const_int_operand" "n")
10938 (match_operand:SI 2 "const_int_operand" "n"))]
10939 "TARGET_SHMEDIA || TARGET_HARD_SH4"
10940 "*
10941 {
10942 if (TARGET_HARD_SH4)
10943 return \"pref @%0\";
10944 operands[0] = gen_rtx_MEM (QImode, operands[0]);
10945 output_asm_insn (\"ld%M0.b %m0,r63\", operands);
10946 return \"\";
10947 }"
10948 [(set_attr "type" "other")])
10949