OSDN Git Service

* targhooks.c: New file.
[pf3gnuchains/gcc-fork.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, 2003
3 ;;  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 GNU CC.
8
9 ;; GNU CC 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 ;; GNU CC 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 GNU CC; 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,sh3,sh3e,sh4,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 ;; tls_load     load TLS related address 
222 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
223 ;; cbranch_media SHmedia conditional branch instructions
224 ;; cmp_media    SHmedia compare instructions
225 ;; dfdiv_media  SHmedia double precision divide and square root
226 ;; dfmul_media  SHmedia double precision multiply instruction
227 ;; dfparith_media SHmedia double precision floating point arithmetic
228 ;; dfpconv_media SHmedia double precision floating point conversions
229 ;; dmpy_media   SHmedia longword multiply
230 ;; fcmp_media   SHmedia floating point compare instructions
231 ;; fdiv_media   SHmedia single precision divide and square root
232 ;; fload_media  SHmedia floating point register load instructions
233 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
234 ;; fparith_media SHmedia single precision floating point arithmetic
235 ;; fpconv_media SHmedia single precision floating point conversions
236 ;; fstore_media SHmedia floating point register store instructions
237 ;; gettr_media  SHmedia gettr instruction
238 ;; invalidate_line_media SHmedia invalidate_line sequence
239 ;; jump_media   SHmedia unconditional branch instructions
240 ;; load_media   SHmedia general register load instructions
241 ;; pt_media     SHmedia pt instruction (expanded by assembler)
242 ;; ptabs_media  SHmedia ptabs instruction
243 ;; store_media  SHmedia general register store instructions
244 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
245 ;; mac_media    SHmedia mac-style fixed point operations
246 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
247 ;; atrans       SHmedia approximate transcendental functions
248 ;; ustore_media SHmedia unaligned stores
249 ;; nil          no-op move, will be deleted.
250
251 (define_attr "type"
252  "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,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"
253   (const_string "other"))
254
255 ;; We define a new attribute namely "insn_class".We use
256 ;; this for the DFA based pipeline description.
257 ;;
258 ;; mt_group      SH4 "mt" group instructions.
259 ;;
260 ;; ex_group      SH4 "ex" group instructions.
261 ;;
262 ;; ls_group      SH4 "ls" group instructions.
263 ;;
264
265 (define_attr "insn_class"
266   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270          (eq_attr "type" "cbranch,jump") (const_string "br_group")
271          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272            (const_string "fe_group")
273          (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")]
274         (const_string "none")))
275 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276 ;; so these do not belong in an insn group, although they are modeled
277 ;; with their own define_insn_reservations.
278
279 ;; Indicate what precision must be selected in fpscr for this insn, if any.
280
281 (define_attr "fp_mode" "single,double,none" (const_string "none"))
282
283 ; If a conditional branch destination is within -252..258 bytes away
284 ; from the instruction it can be 2 bytes long.  Something in the
285 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
286 ; branches are initially assumed to be 16 bytes long.
287 ; In machine_dependent_reorg, we split all branches that are longer than
288 ; 2 bytes.
289
290 ;; The maximum range used for SImode constant pool entries is 1018.  A final
291 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
292 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
293 ;; instruction around the pool table, 2 bytes of alignment before the table,
294 ;; and 30 bytes of alignment after the table.  That gives a maximum total
295 ;; pool size of 1058 bytes.
296 ;; Worst case code/pool content size ratio is 1:2 (using asms).
297 ;; Thus, in the worst case, there is one instruction in front of a maximum
298 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
299 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
300 ;; If we have a forward branch, the initial table will be put after the
301 ;; unconditional branch.
302 ;;
303 ;; ??? We could do much better by keeping track of the actual pcloads within
304 ;; the branch range and in the pcload range in front of the branch range.
305
306 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
307 ;; inside an le.
308 (define_attr "short_cbranch_p" "no,yes"
309   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
310          (const_string "no")
311          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
312          (const_string "yes")
313          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
314          (const_string "no")
315          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
316          (const_string "yes")
317          ] (const_string "no")))
318
319 (define_attr "med_branch_p" "no,yes"
320   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
321               (const_int 1988))
322          (const_string "yes")
323          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
324          (const_string "no")
325          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
326               (const_int 8186))
327          (const_string "yes")
328          ] (const_string "no")))
329
330 (define_attr "med_cbranch_p" "no,yes"
331   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
332               (const_int 1986))
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 4090))
337                (const_int 8184))
338          (const_string "yes")
339          ] (const_string "no")))
340
341 (define_attr "braf_branch_p" "no,yes"
342   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
343          (const_string "no")
344          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
345               (const_int 20660))
346          (const_string "yes")
347          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
348          (const_string "no")
349          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
350               (const_int 65530))
351          (const_string "yes")
352          ] (const_string "no")))
353
354 (define_attr "braf_cbranch_p" "no,yes"
355   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
356          (const_string "no")
357          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
358               (const_int 20658))
359          (const_string "yes")
360          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
361          (const_string "no")
362          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
363               (const_int 65528))
364          (const_string "yes")
365          ] (const_string "no")))
366
367 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
368 ; For wider ranges, we need a combination of a code and a data part.
369 ; If we can get a scratch register for a long range jump, the code
370 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
371 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
372 ; long; otherwise, it must be 6 bytes long.
373
374 ; All other instructions are two bytes long by default.
375
376 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
377 ;; but getattrtab doesn't understand this.
378 (define_attr "length" ""
379   (cond [(eq_attr "type" "cbranch")
380          (cond [(eq_attr "short_cbranch_p" "yes")
381                 (const_int 2)
382                 (eq_attr "med_cbranch_p" "yes")
383                 (const_int 6)
384                 (eq_attr "braf_cbranch_p" "yes")
385                 (const_int 12)
386 ;; ??? using pc is not computed transitively.
387                 (ne (match_dup 0) (match_dup 0))
388                 (const_int 14)
389                 (ne (symbol_ref ("flag_pic")) (const_int 0))
390                 (const_int 24)
391                 ] (const_int 16))
392          (eq_attr "type" "jump")
393          (cond [(eq_attr "med_branch_p" "yes")
394                 (const_int 2)
395                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
396                          (symbol_ref "INSN"))
397                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
398                          (symbol_ref "code_for_indirect_jump_scratch")))
399                 (if_then_else (eq_attr "braf_branch_p" "yes")
400                               (const_int 6)
401                               (const_int 10))
402                 (eq_attr "braf_branch_p" "yes")
403                 (const_int 10)
404 ;; ??? using pc is not computed transitively.
405                 (ne (match_dup 0) (match_dup 0))
406                 (const_int 12)
407                 (ne (symbol_ref ("flag_pic")) (const_int 0))
408                 (const_int 22)
409                 ] (const_int 14))
410          (eq_attr "type" "pt_media")
411          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
412                        (const_int 20) (const_int 12))
413          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
414                          (const_int 4)
415                          (const_int 2))))
416
417 ;; (define_function_unit {name} {num-units} {n-users} {test}
418 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
419
420 ;; Load and store instructions save a cycle if they are aligned on a
421 ;; four byte boundary.  Using a function unit for stores encourages
422 ;; gcc to separate load and store instructions by one instruction,
423 ;; which makes it more likely that the linker will be able to word
424 ;; align them when relaxing.
425
426 ;; Loads have a latency of two.
427 ;; However, call insns can have a delay slot, so that we want one more
428 ;; insn to be scheduled between the load of the function address and the call.
429 ;; This is equivalent to a latency of three.
430 ;; We cannot use a conflict list for this, because we need to distinguish
431 ;; between the actual call address and the function arguments.
432 ;; ADJUST_COST can only properly handle reductions of the cost, so we
433 ;; use a latency of three here.
434 ;; We only do this for SImode loads of general registers, to make the work
435 ;; for ADJUST_COST easier.
436 (define_function_unit "memory" 1 0
437   (and (eq_attr "pipe_model" "sh1")
438        (eq_attr "type" "load_si,pcload_si"))
439   3 2)
440 (define_function_unit "memory" 1 0
441   (and (eq_attr "pipe_model" "sh1")
442        (eq_attr "type" "load,pcload,pload,store,pstore"))
443   2 2)
444
445 (define_function_unit "int"    1 0
446   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
447
448 (define_function_unit "int"    1 0
449   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
450
451 (define_function_unit "int"    1 0
452   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
453
454 ;; ??? These are approximations.
455 (define_function_unit "mpy"    1 0
456   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
457 (define_function_unit "mpy"    1 0
458   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
459
460 (define_function_unit "fp"     1 0
461   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
462 (define_function_unit "fp"     1 0
463   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
464
465
466 ;; SH-5 SHmedia scheduling
467 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
468 ;; single-issue machine.  It has four pipelines, the branch unit (br),
469 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
470 ;; the floating point unit (fpu).
471 ;; Here model the instructions with a latency greater than one cycle.
472
473 ;; Every instruction on SH-5 occupies the issue resource for at least one
474 ;; cycle.
475 (define_function_unit "sh5issue" 1 0
476   (and (eq_attr "pipe_model" "sh5media")
477        (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
478
479 ;; Specify the various types of instruction which have latency > 1
480 (define_function_unit "sh5issue" 1 0
481   (and (eq_attr "pipe_model" "sh5media")
482        (eq_attr "type" "mcmp_media")) 2 1)
483
484 (define_function_unit "sh5issue" 1 0
485   (and (eq_attr "pipe_model" "sh5media")
486        (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
487 ;; but see sh_adjust_cost for mac_media exception.
488
489 (define_function_unit "sh5issue" 1 0
490   (and (eq_attr "pipe_model" "sh5media")
491        (eq_attr "type" "fload_media,fmove_media")) 4 1)
492
493 (define_function_unit "sh5issue" 1 0
494   (and (eq_attr "pipe_model" "sh5media")
495        (eq_attr "type" "d2mpy_media")) 4 2)
496
497 (define_function_unit "sh5issue" 1 0
498   (and (eq_attr "pipe_model" "sh5media")
499        (eq_attr "type" "pt_media,ptabs_media")) 5 1)
500
501 (define_function_unit "sh5issue" 1 0
502   (and (eq_attr "pipe_model" "sh5media")
503        (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
504
505 (define_function_unit "sh5issue" 1 0
506   (and (eq_attr "pipe_model" "sh5media")
507        (eq_attr "type" "invalidate_line_media")) 7 7)
508
509 (define_function_unit "sh5issue" 1 0
510   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
511
512 (define_function_unit "sh5issue" 1 0
513   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
514
515 ;; Floating-point divide and square-root occupy an additional resource,
516 ;; which is not internally pipelined.  However, other instructions
517 ;; can continue to issue.
518 (define_function_unit "sh5fds" 1 0
519   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media"))  19 19)
520
521 (define_function_unit "sh5fds" 1 0
522   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
523
524 ; Definitions for filling branch delay slots.
525
526 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
527
528 ;; ??? This should be (nil) instead of (const_int 0)
529 (define_attr "hit_stack" "yes,no"
530         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
531                    (const_int 0))
532                (const_string "no")]
533               (const_string "yes")))
534
535 (define_attr "interrupt_function" "no,yes"
536   (const (symbol_ref "current_function_interrupt")))
537
538 (define_attr "in_delay_slot" "yes,no"
539   (cond [(eq_attr "type" "cbranch") (const_string "no")
540          (eq_attr "type" "pcload,pcload_si") (const_string "no")
541          (eq_attr "needs_delay_slot" "yes") (const_string "no")
542          (eq_attr "length" "2") (const_string "yes")
543          ] (const_string "no")))
544
545 (define_attr "cond_delay_slot" "yes,no"
546   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
547          ] (const_string "no")))
548
549 (define_attr "is_sfunc" ""
550   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
551
552 (define_attr "is_mac_media" ""
553   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
554
555 (define_attr "branch_zero" "yes,no"
556   (cond [(eq_attr "type" "!cbranch") (const_string "no")
557          (ne (symbol_ref "(next_active_insn (insn)\
558                            == (prev_active_insn\
559                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
560                           && get_attr_length (next_active_insn (insn)) == 2")
561              (const_int 0))
562          (const_string "yes")]
563         (const_string "no")))
564
565 ;; SH4 Double-precision computation with double-precision result -
566 ;; the two halves are ready at different times.
567 (define_attr "dfp_comp" "yes,no"
568   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
569         (const_string "no")))
570
571 ;; Insns for which the latency of a preceding fp insn is decreased by one.
572 (define_attr "late_fp_use" "yes,no" (const_string "no"))
573 ;; And feeding insns for which this relevant.
574 (define_attr "any_fp_comp" "yes,no"
575   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
576          (const_string "yes")]
577         (const_string "no")))
578
579 (define_attr "any_int_load" "yes,no"
580   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
581          (const_string "yes")]
582         (const_string "no")))
583
584 (define_delay
585   (eq_attr "needs_delay_slot" "yes")
586   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
587
588 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
589 ;; and thus we can't put a pop instruction in its delay slot.
590 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
591 ;; instruction can go in the delay slot.
592
593 ;; Since a normal return (rts) implicitly uses the PR register,
594 ;; we can't allow PR register loads in an rts delay slot.
595
596 (define_delay
597   (eq_attr "type" "return")
598   [(and (eq_attr "in_delay_slot" "yes")
599         (ior (and (eq_attr "interrupt_function" "no")
600                   (eq_attr "type" "!pload,prset"))
601              (and (eq_attr "interrupt_function" "yes")
602                   (ior
603                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
604                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
605
606 ;; Since a call implicitly uses the PR register, we can't allow
607 ;; a PR register store in a jsr delay slot.
608
609 (define_delay
610   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
611   [(and (eq_attr "in_delay_slot" "yes")
612         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
613
614 ;; Say that we have annulled true branches, since this gives smaller and
615 ;; faster code when branches are predicted as not taken.
616
617 (define_delay
618   (and (eq_attr "type" "cbranch")
619        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
620   ;; SH2e has a hardware bug that pretty much prohibits the use of
621   ;; annuled delay slots.
622   [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
623                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
624 \f
625 ;; -------------------------------------------------------------------------
626 ;; SImode signed integer comparisons
627 ;; -------------------------------------------------------------------------
628
629 (define_insn ""
630   [(set (reg:SI T_REG)
631         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
632                        (match_operand:SI 1 "arith_operand" "K08,r"))
633                (const_int 0)))]
634   "TARGET_SH1"
635   "tst  %1,%0"
636   [(set_attr "type" "mt_group")])
637
638 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
639 ;; That would still allow reload to create cmpi instructions, but would
640 ;; perhaps allow forcing the constant into a register when that is better.
641 ;; Probably should use r0 for mem/imm compares, but force constant into a
642 ;; register for pseudo/imm compares.
643
644 (define_insn "cmpeqsi_t"
645   [(set (reg:SI T_REG)
646         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
647                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
648   "TARGET_SH1"
649   "@
650         tst     %0,%0
651         cmp/eq  %1,%0
652         cmp/eq  %1,%0"
653    [(set_attr "type" "mt_group")])
654
655 (define_insn "cmpgtsi_t"
656   [(set (reg:SI T_REG)
657         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
658                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
659   "TARGET_SH1"
660   "@
661         cmp/gt  %1,%0
662         cmp/pl  %0"
663    [(set_attr "type" "mt_group")])
664
665 (define_insn "cmpgesi_t"
666   [(set (reg:SI T_REG)
667         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
668                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
669   "TARGET_SH1"
670   "@
671         cmp/ge  %1,%0
672         cmp/pz  %0"
673    [(set_attr "type" "mt_group")])
674
675 ;; -------------------------------------------------------------------------
676 ;; SImode unsigned integer comparisons
677 ;; -------------------------------------------------------------------------
678
679 (define_insn "cmpgeusi_t"
680   [(set (reg:SI T_REG)
681         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
682                 (match_operand:SI 1 "arith_reg_operand" "r")))]
683   "TARGET_SH1"
684   "cmp/hs       %1,%0"
685    [(set_attr "type" "mt_group")])
686
687 (define_insn "cmpgtusi_t"
688   [(set (reg:SI T_REG)
689         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
690                 (match_operand:SI 1 "arith_reg_operand" "r")))]
691   "TARGET_SH1"
692   "cmp/hi       %1,%0"
693    [(set_attr "type" "mt_group")])
694
695 ;; We save the compare operands in the cmpxx patterns and use them when
696 ;; we generate the branch.
697
698 (define_expand "cmpsi"
699   [(set (reg:SI T_REG)
700         (compare (match_operand:SI 0 "arith_operand" "")
701                  (match_operand:SI 1 "arith_operand" "")))]
702   "TARGET_SH1"
703   "
704 {
705   sh_compare_op0 = operands[0];
706   sh_compare_op1 = operands[1];
707   DONE;
708 }")
709 \f
710 ;; -------------------------------------------------------------------------
711 ;; DImode signed integer comparisons
712 ;; -------------------------------------------------------------------------
713
714 ;; ??? Could get better scheduling by splitting the initial test from the
715 ;; rest of the insn after reload.  However, the gain would hardly justify
716 ;; the sh.md size increase necessary to do that.
717
718 (define_insn ""
719   [(set (reg:SI T_REG)
720         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
721                        (match_operand:DI 1 "arith_operand" "r"))
722                (const_int 0)))]
723   "TARGET_SH1"
724   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
725                                  insn, operands);"
726   [(set_attr "length" "6")
727    (set_attr "type" "arith3b")])
728
729 (define_insn "cmpeqdi_t"
730   [(set (reg:SI T_REG)
731         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
732                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
733   "TARGET_SH1"
734   "@
735         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
736         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
737   [(set_attr "length" "6")
738    (set_attr "type" "arith3b")])
739
740 (define_split
741   [(set (reg:SI T_REG)
742         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
743                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
744 ;; If we applied this split when not optimizing, it would only be
745 ;; applied during the machine-dependent reorg, when no new basic blocks
746 ;; may be created.
747   "TARGET_SH1 && reload_completed && optimize"
748   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
749    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
750                            (label_ref (match_dup 6))
751                            (pc)))
752    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
753    (match_dup 6)]
754   "
755 {
756   operands[2]
757     = gen_rtx_REG (SImode,
758                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
759   operands[3]
760     = (operands[1] == const0_rtx
761        ? const0_rtx
762        : gen_rtx_REG (SImode,
763                       true_regnum (operands[1])
764                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
765   operands[4] = gen_lowpart (SImode, operands[0]);
766   operands[5] = gen_lowpart (SImode, operands[1]);
767   operands[6] = gen_label_rtx ();
768 }")
769
770 (define_insn "cmpgtdi_t"
771   [(set (reg:SI T_REG)
772         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
773                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
774   "TARGET_SH2"
775   "@
776         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
777         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
778   [(set_attr "length" "8")
779    (set_attr "type" "arith3")])
780
781 (define_insn "cmpgedi_t"
782   [(set (reg:SI T_REG)
783         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
784                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
785   "TARGET_SH2"
786   "@
787         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
788         cmp/pz\\t%S0"
789   [(set_attr "length" "8,2")
790    (set_attr "type" "arith3,mt_group")])
791 \f
792 ;; -------------------------------------------------------------------------
793 ;; DImode unsigned integer comparisons
794 ;; -------------------------------------------------------------------------
795
796 (define_insn "cmpgeudi_t"
797   [(set (reg:SI T_REG)
798         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
799                 (match_operand:DI 1 "arith_reg_operand" "r")))]
800   "TARGET_SH2"
801   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
802   [(set_attr "length" "8")
803    (set_attr "type" "arith3")])
804
805 (define_insn "cmpgtudi_t"
806   [(set (reg:SI T_REG)
807         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
808                 (match_operand:DI 1 "arith_reg_operand" "r")))]
809   "TARGET_SH2"
810   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
811   [(set_attr "length" "8")
812    (set_attr "type" "arith3")])
813
814 (define_insn "cmpeqdi_media"
815   [(set (match_operand:DI 0 "register_operand" "=r")
816         (eq:DI (match_operand:DI 1 "register_operand" "%r")
817                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
818   "TARGET_SHMEDIA"
819   "cmpeq        %1, %N2, %0"
820   [(set_attr "type" "cmp_media")])
821
822 (define_insn "cmpgtdi_media"
823   [(set (match_operand:DI 0 "register_operand" "=r")
824         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
825                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
826   "TARGET_SHMEDIA"
827   "cmpgt        %N1, %N2, %0"
828   [(set_attr "type" "cmp_media")])
829
830 (define_insn "cmpgtudi_media"
831   [(set (match_operand:DI 0 "register_operand" "=r")
832         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
833                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
834   "TARGET_SHMEDIA"
835   "cmpgtu       %N1, %N2, %0"
836   [(set_attr "type" "cmp_media")])
837
838 ;; We save the compare operands in the cmpxx patterns and use them when
839 ;; we generate the branch.
840
841 (define_expand "cmpdi"
842   [(set (reg:SI T_REG)
843         (compare (match_operand:DI 0 "arith_operand" "")
844                  (match_operand:DI 1 "arith_operand" "")))]
845   "TARGET_SH2 || TARGET_SHMEDIA"
846   "
847 {
848   sh_compare_op0 = operands[0];
849   sh_compare_op1 = operands[1];
850   DONE;
851 }")
852 ;; -------------------------------------------------------------------------
853 ;; Conditional move instructions
854 ;; -------------------------------------------------------------------------
855
856 ;; The insn names may seem reversed, but note that cmveq performs the move
857 ;; if op1 == 0, and cmvne does it if op1 != 0.
858
859 (define_insn "movdicc_false"
860   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
861         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
862                              (const_int 0))
863          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
864          (match_operand:DI 3 "arith_reg_operand" "0")))]
865   "TARGET_SHMEDIA"
866   "cmveq        %1, %N2, %0"
867   [(set_attr "type" "arith_media")])
868
869 (define_insn "movdicc_true"
870   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
871         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
872                              (const_int 0))
873          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
874          (match_operand:DI 3 "arith_reg_operand" "0")))]
875   "TARGET_SHMEDIA"
876   "cmvne        %1, %N2, %0"
877   [(set_attr "type" "arith_media")])
878
879 (define_expand "movdicc"
880   [(set (match_operand:DI 0 "register_operand" "")
881         (if_then_else:DI (match_operand 1 "comparison_operator" "")
882                          (match_operand:DI 2 "register_operand" "")
883                          (match_operand:DI 3 "register_operand" "")))]
884   "TARGET_SHMEDIA"
885   "
886 {
887   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
888       && GET_MODE (sh_compare_op0) == DImode
889       && sh_compare_op1 == const0_rtx)
890     operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
891                            sh_compare_op0, sh_compare_op1);
892   else
893     {
894       rtx tmp;
895
896       if (no_new_pseudos)
897         FAIL;
898
899       tmp = gen_reg_rtx (DImode);
900
901       switch (GET_CODE (operands[1]))
902         {
903         case EQ:
904           emit_insn (gen_seq (tmp));
905           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
906           break;
907
908         case NE:
909           emit_insn (gen_seq (tmp));
910           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
911           break;
912
913         case GT:
914           emit_insn (gen_sgt (tmp));
915           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
916           break;
917
918         case LT:
919           emit_insn (gen_slt (tmp));
920           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
921           break;
922
923         case GE:
924           emit_insn (gen_slt (tmp));
925           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
926           break;
927
928         case LE:
929           emit_insn (gen_sgt (tmp));
930           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
931           break;
932
933         case GTU:
934           emit_insn (gen_sgtu (tmp));
935           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
936           break;
937
938         case LTU:
939           emit_insn (gen_sltu (tmp));
940           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
941           break;
942
943         case GEU:
944           emit_insn (gen_sltu (tmp));
945           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
946           break;
947
948         case LEU:
949           emit_insn (gen_sgtu (tmp));
950           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
951           break;
952
953         case UNORDERED:
954           emit_insn (gen_sunordered (tmp));
955           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
956           break;
957
958         case ORDERED:
959           emit_insn (gen_sunordered (tmp));
960           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
961           break;
962
963         case UNEQ:
964         case UNGE:
965         case UNGT:
966         case UNLE:
967         case UNLT:
968         case LTGT:
969           FAIL;
970
971         default:
972           abort ();
973         }
974     }
975 }")
976 \f
977 ;; -------------------------------------------------------------------------
978 ;; Addition instructions
979 ;; -------------------------------------------------------------------------
980
981 (define_expand "adddi3"
982   [(set (match_operand:DI 0 "arith_reg_operand" "")
983         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
984                  (match_operand:DI 2 "arith_operand" "")))]
985   ""
986   "
987 {
988   if (TARGET_SH1)
989     {
990       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
991         FAIL;
992       operands[2] = force_reg (DImode, operands[2]);
993       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
994       DONE;
995     }
996 }")
997
998 (define_insn "*adddi3_media"
999   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1000         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1001                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1002   "TARGET_SHMEDIA"
1003   "@
1004         add     %1, %2, %0
1005         addi    %1, %2, %0"
1006   [(set_attr "type" "arith_media")])
1007
1008 (define_insn "adddi3z_media"
1009   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1010         (zero_extend:DI
1011          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1012                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1013   "TARGET_SHMEDIA"
1014   "addz.l       %1, %N2, %0"
1015   [(set_attr "type" "arith_media")])
1016
1017 (define_insn "adddi3_compact"
1018   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1019         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1020                  (match_operand:DI 2 "arith_reg_operand" "r")))
1021    (clobber (reg:SI T_REG))]
1022   "TARGET_SH1"
1023   "#"
1024   [(set_attr "length" "6")])
1025
1026 (define_split
1027   [(set (match_operand:DI 0 "arith_reg_operand" "")
1028         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1029                  (match_operand:DI 2 "arith_reg_operand" "")))
1030    (clobber (reg:SI T_REG))]
1031   "TARGET_SH1 && reload_completed"
1032   [(const_int 0)]
1033   "
1034 {
1035   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1036   high0 = gen_rtx_REG (SImode,
1037                        true_regnum (operands[0])
1038                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1039   high2 = gen_rtx_REG (SImode,
1040                        true_regnum (operands[2])
1041                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1042   emit_insn (gen_clrt ());
1043   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1044   emit_insn (gen_addc1 (high0, high0, high2));
1045   DONE;
1046 }")
1047
1048 (define_insn "addc"
1049   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1050         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1051                           (match_operand:SI 2 "arith_reg_operand" "r"))
1052                  (reg:SI T_REG)))
1053    (set (reg:SI T_REG)
1054         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1055   "TARGET_SH1"
1056   "addc %2,%0"
1057   [(set_attr "type" "arith")])
1058
1059 (define_insn "addc1"
1060   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1061         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1062                           (match_operand:SI 2 "arith_reg_operand" "r"))
1063                  (reg:SI T_REG)))
1064    (clobber (reg:SI T_REG))]
1065   "TARGET_SH1"
1066   "addc %2,%0"
1067   [(set_attr "type" "arith")])
1068
1069 (define_expand "addsi3"
1070   [(set (match_operand:SI 0 "arith_reg_operand" "")
1071         (plus:SI (match_operand:SI 1 "arith_operand" "")
1072                  (match_operand:SI 2 "arith_operand" "")))]
1073   ""
1074   "
1075 {
1076   if (TARGET_SHMEDIA)
1077     operands[1] = force_reg (SImode, operands[1]);
1078 }")
1079
1080 (define_insn "addsi3_media"
1081   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1082         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1083                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1084   "TARGET_SHMEDIA"
1085   "@
1086         add.l   %1, %2, %0
1087         addi.l  %1, %2, %0"
1088   [(set_attr "type" "arith_media")])
1089
1090 (define_insn "*addsi3_compact"
1091   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1092         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1093                  (match_operand:SI 2 "arith_operand" "rI08")))]
1094   "TARGET_SH1"
1095   "add  %2,%0"
1096   [(set_attr "type" "arith")])
1097
1098 ;; -------------------------------------------------------------------------
1099 ;; Subtraction instructions
1100 ;; -------------------------------------------------------------------------
1101
1102 (define_expand "subdi3"
1103   [(set (match_operand:DI 0 "arith_reg_operand" "")
1104         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1105                   (match_operand:DI 2 "arith_reg_operand" "")))]
1106   ""
1107   "
1108 {
1109   if (TARGET_SH1)
1110     {
1111       operands[1] = force_reg (DImode, operands[1]);
1112       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1113       DONE;
1114     }
1115 }")
1116
1117 (define_insn "*subdi3_media"
1118   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1119         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1120                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1121   "TARGET_SHMEDIA"
1122   "sub  %N1, %2, %0"
1123   [(set_attr "type" "arith_media")])
1124
1125 (define_insn "subdi3_compact"
1126   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1127         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1128                  (match_operand:DI 2 "arith_reg_operand" "r")))
1129    (clobber (reg:SI T_REG))]
1130   "TARGET_SH1"
1131   "#"
1132   [(set_attr "length" "6")])
1133
1134 (define_split
1135   [(set (match_operand:DI 0 "arith_reg_operand" "")
1136         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1137                   (match_operand:DI 2 "arith_reg_operand" "")))
1138    (clobber (reg:SI T_REG))]
1139   "TARGET_SH1 && reload_completed"
1140   [(const_int 0)]
1141   "
1142 {
1143   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1144   high0 = gen_rtx_REG (SImode,
1145                        true_regnum (operands[0])
1146                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1147   high2 = gen_rtx_REG (SImode,
1148                        true_regnum (operands[2])
1149                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1150   emit_insn (gen_clrt ());
1151   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1152   emit_insn (gen_subc1 (high0, high0, high2));
1153   DONE;
1154 }")
1155
1156 (define_insn "subc"
1157   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1158         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1159                             (match_operand:SI 2 "arith_reg_operand" "r"))
1160                   (reg:SI T_REG)))
1161    (set (reg:SI T_REG)
1162         (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1163   "TARGET_SH1"
1164   "subc %2,%0"
1165   [(set_attr "type" "arith")])
1166
1167 (define_insn "subc1"
1168   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1169         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1170                             (match_operand:SI 2 "arith_reg_operand" "r"))
1171                   (reg:SI T_REG)))
1172    (clobber (reg:SI T_REG))]
1173   "TARGET_SH1"
1174   "subc %2,%0"
1175   [(set_attr "type" "arith")])
1176
1177 (define_insn "*subsi3_internal"
1178   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1179         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1180                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1181   "TARGET_SH1"
1182   "sub  %2,%0"
1183   [(set_attr "type" "arith")])
1184
1185 (define_insn "*subsi3_media"
1186   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1187         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1188                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1189   "TARGET_SHMEDIA"
1190   "sub.l        %N1, %2, %0"
1191   [(set_attr "type" "arith_media")])
1192
1193 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1194 ;; will sometimes save one instruction.  Otherwise we might get
1195 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1196 ;; are the same.
1197
1198 (define_expand "subsi3"
1199   [(set (match_operand:SI 0 "arith_reg_operand" "")
1200         (minus:SI (match_operand:SI 1 "arith_operand" "")
1201                   (match_operand:SI 2 "arith_reg_operand" "")))]
1202   ""
1203   "
1204 {
1205   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1206     {
1207       emit_insn (gen_negsi2 (operands[0], operands[2]));
1208       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1209       DONE;
1210     }
1211   if (TARGET_SHMEDIA)
1212     {
1213       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1214         FAIL;
1215       if (operands[1] != const0_rtx)
1216         operands[1] = force_reg (SImode, operands[1]);
1217     }
1218 }")
1219 \f
1220 ;; -------------------------------------------------------------------------
1221 ;; Division instructions
1222 ;; -------------------------------------------------------------------------
1223
1224 ;; We take advantage of the library routines which don't clobber as many
1225 ;; registers as a normal function call would.
1226
1227 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1228 ;; also has an effect on the register that holds the address of the sfunc.
1229 ;; To make this work, we have an extra dummy insn that shows the use
1230 ;; of this register for reorg.
1231
1232 (define_insn "use_sfunc_addr"
1233   [(set (reg:SI PR_REG)
1234         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1235   "TARGET_SH1"
1236   ""
1237   [(set_attr "length" "0")])
1238
1239 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1240 ;; hard register 0.  If we used hard register 0, then the next instruction
1241 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1242 ;; gets allocated to a stack slot that needs its address reloaded, then
1243 ;; there is nothing to prevent reload from using r0 to reload the address.
1244 ;; This reload would clobber the value in r0 we are trying to store.
1245 ;; If we let reload allocate r0, then this problem can never happen.
1246
1247 (define_insn "udivsi3_i1"
1248   [(set (match_operand:SI 0 "register_operand" "=z")
1249         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1250    (clobber (reg:SI T_REG))
1251    (clobber (reg:SI PR_REG))
1252    (clobber (reg:SI R4_REG))
1253    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1254   "TARGET_SH1 && ! TARGET_SH4"
1255   "jsr  @%1%#"
1256   [(set_attr "type" "sfunc")
1257    (set_attr "needs_delay_slot" "yes")])
1258
1259 ; Since shmedia-nofpu code could be linked against shcompact code, and
1260 ; the udivsi3 libcall has the same name, we must consider all registers
1261 ; clobbered that are in the union of the registers clobbered by the
1262 ; shmedia and the shcompact implementation.  Note, if the shcompact
1263 ; implementation actually used shcompact code, we'd need to clobber
1264 ; also r23 and fr23.
1265 (define_insn "udivsi3_i1_media"
1266   [(set (match_operand:SI 0 "register_operand" "=z")
1267         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1268    (clobber (reg:SI T_MEDIA_REG))
1269    (clobber (reg:SI PR_MEDIA_REG))
1270    (clobber (reg:SI R20_REG))
1271    (clobber (reg:SI R21_REG))
1272    (clobber (reg:SI R22_REG))
1273    (clobber (reg:DI TR0_REG))
1274    (clobber (reg:DI TR1_REG))
1275    (clobber (reg:DI TR2_REG))
1276    (use (match_operand:DI 1 "target_operand" "b"))]
1277   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1278   "blink        %1, r18"
1279   [(set_attr "type" "sfunc")
1280    (set_attr "needs_delay_slot" "yes")])
1281
1282 (define_expand "udivsi3_i4_media"
1283   [(set (match_dup 3)
1284         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1285    (set (match_dup 4)
1286         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1287    (set (match_dup 5) (float:DF (match_dup 3)))
1288    (set (match_dup 6) (float:DF (match_dup 4)))
1289    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1290    (set (match_dup 8) (fix:DI (match_dup 7)))
1291    (set (match_operand:SI 0 "register_operand" "")
1292         (truncate:SI (match_dup 8)))]
1293   "TARGET_SHMEDIA_FPU"
1294   "
1295 {
1296   operands[3] = gen_reg_rtx (DImode);
1297   operands[4] = gen_reg_rtx (DImode);
1298   operands[5] = gen_reg_rtx (DFmode);
1299   operands[6] = gen_reg_rtx (DFmode);
1300   operands[7] = gen_reg_rtx (DFmode);
1301   operands[8] = gen_reg_rtx (DImode);
1302 }")
1303
1304 (define_insn "udivsi3_i4"
1305   [(set (match_operand:SI 0 "register_operand" "=y")
1306         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1307    (clobber (reg:SI T_REG))
1308    (clobber (reg:SI PR_REG))
1309    (clobber (reg:DF DR0_REG))
1310    (clobber (reg:DF DR2_REG))
1311    (clobber (reg:DF DR4_REG))
1312    (clobber (reg:SI R0_REG))
1313    (clobber (reg:SI R1_REG))
1314    (clobber (reg:SI R4_REG))
1315    (clobber (reg:SI R5_REG))
1316    (use (reg:PSI FPSCR_REG))
1317    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1318   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1319   "jsr  @%1%#"
1320   [(set_attr "type" "sfunc")
1321    (set_attr "fp_mode" "double")
1322    (set_attr "needs_delay_slot" "yes")])
1323
1324 (define_insn "udivsi3_i4_single"
1325   [(set (match_operand:SI 0 "register_operand" "=y")
1326         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1327    (clobber (reg:SI T_REG))
1328    (clobber (reg:SI PR_REG))
1329    (clobber (reg:DF DR0_REG))
1330    (clobber (reg:DF DR2_REG))
1331    (clobber (reg:DF DR4_REG))
1332    (clobber (reg:SI R0_REG))
1333    (clobber (reg:SI R1_REG))
1334    (clobber (reg:SI R4_REG))
1335    (clobber (reg:SI R5_REG))
1336    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1337   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1338   "jsr  @%1%#"
1339   [(set_attr "type" "sfunc")
1340    (set_attr "needs_delay_slot" "yes")])
1341
1342 (define_expand "udivsi3"
1343   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1344    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1345    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1346    (parallel [(set (match_operand:SI 0 "register_operand" "")
1347                    (udiv:SI (reg:SI R4_REG)
1348                             (reg:SI R5_REG)))
1349               (clobber (reg:SI T_REG))
1350               (clobber (reg:SI PR_REG))
1351               (clobber (reg:SI R4_REG))
1352               (use (match_dup 3))])]
1353   ""
1354   "
1355 {
1356   rtx first, last;
1357
1358   operands[3] = gen_reg_rtx (Pmode);
1359   /* Emit the move of the address to a pseudo outside of the libcall.  */
1360   if (TARGET_HARD_SH4 && TARGET_SH2E)
1361     {
1362       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1363       if (TARGET_FPU_SINGLE)
1364         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1365       else
1366         last = gen_udivsi3_i4 (operands[0], operands[3]);
1367     }
1368   else if (TARGET_SHMEDIA_FPU)
1369     {
1370       operands[1] = force_reg (SImode, operands[1]);
1371       operands[2] = force_reg (SImode, operands[2]);
1372       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1373       DONE;
1374     }
1375   else if (TARGET_SH5)
1376     {
1377       emit_move_insn (operands[3],
1378                       function_symbol (TARGET_FPU_ANY
1379                                        ? \"__udivsi3_i4\"
1380                                        : \"__udivsi3\"));
1381
1382       if (TARGET_SHMEDIA)
1383         last = gen_udivsi3_i1_media (operands[0],
1384                                      Pmode == DImode
1385                                      ? operands[3]
1386                                      : gen_rtx_SUBREG (DImode, operands[3],
1387                                                        0));
1388       else if (TARGET_FPU_ANY)
1389         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1390       else
1391         last = gen_udivsi3_i1 (operands[0], operands[3]);
1392     }
1393   else
1394     {
1395       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1396       last = gen_udivsi3_i1 (operands[0], operands[3]);
1397     }
1398   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1399   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1400   last = emit_insn (last);
1401   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1402      invariant code motion can move it.  */
1403   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1404   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1405   DONE;
1406 }")
1407
1408 (define_insn "divsi3_i1"
1409   [(set (match_operand:SI 0 "register_operand" "=z")
1410         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1411    (clobber (reg:SI T_REG))
1412    (clobber (reg:SI PR_REG))
1413    (clobber (reg:SI R1_REG))
1414    (clobber (reg:SI R2_REG))
1415    (clobber (reg:SI R3_REG))
1416    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1417   "TARGET_SH1 && ! TARGET_SH4"
1418   "jsr  @%1%#"
1419   [(set_attr "type" "sfunc")
1420    (set_attr "needs_delay_slot" "yes")])
1421
1422 ; Since shmedia-nofpu code could be linked against shcompact code, and
1423 ; the sdivsi3 libcall has the same name, we must consider all registers
1424 ; clobbered that are in the union of the registers clobbered by the
1425 ; shmedia and the shcompact implementation.  Note, if the shcompact
1426 ; implementation actually used shcompact code, we'd need to clobber
1427 ; also r22, r23 and fr23.
1428 (define_insn "divsi3_i1_media"
1429   [(set (match_operand:SI 0 "register_operand" "=z")
1430         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1431    (clobber (reg:SI T_MEDIA_REG))
1432    (clobber (reg:SI PR_MEDIA_REG))
1433    (clobber (reg:SI R1_REG))
1434    (clobber (reg:SI R2_REG))
1435    (clobber (reg:SI R3_REG))
1436    (clobber (reg:SI R20_REG))
1437    (clobber (reg:SI R21_REG))
1438    (clobber (reg:DI TR0_REG))
1439    (clobber (reg:DI TR1_REG))
1440    (clobber (reg:DI TR2_REG))
1441    (use (match_operand:DI 1 "target_operand" "b"))]
1442   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1443   "blink        %1, r18"
1444   [(set_attr "type" "sfunc")])
1445
1446 (define_expand "divsi3_i4_media"
1447   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1448    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1449    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1450    (set (match_operand:SI 0 "register_operand" "=r")
1451         (fix:SI (match_dup 5)))]
1452   "TARGET_SHMEDIA_FPU"
1453   "
1454 {
1455   operands[3] = gen_reg_rtx (DFmode);
1456   operands[4] = gen_reg_rtx (DFmode);
1457   operands[5] = gen_reg_rtx (DFmode);
1458 }")
1459
1460 (define_insn "divsi3_i4"
1461   [(set (match_operand:SI 0 "register_operand" "=y")
1462         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1463    (clobber (reg:SI PR_REG))
1464    (clobber (reg:DF DR0_REG))
1465    (clobber (reg:DF DR2_REG))
1466    (use (reg:PSI FPSCR_REG))
1467    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1468   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1469   "jsr  @%1%#"
1470   [(set_attr "type" "sfunc")
1471    (set_attr "fp_mode" "double")
1472    (set_attr "needs_delay_slot" "yes")])
1473
1474 (define_insn "divsi3_i4_single"
1475   [(set (match_operand:SI 0 "register_operand" "=y")
1476         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1477    (clobber (reg:SI PR_REG))
1478    (clobber (reg:DF DR0_REG))
1479    (clobber (reg:DF DR2_REG))
1480    (clobber (reg:SI R2_REG))
1481    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1482   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1483   "jsr  @%1%#"
1484   [(set_attr "type" "sfunc")
1485    (set_attr "needs_delay_slot" "yes")])
1486
1487 (define_expand "divsi3"
1488   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1489    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1490    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1491    (parallel [(set (match_operand:SI 0 "register_operand" "")
1492                    (div:SI (reg:SI R4_REG)
1493                            (reg:SI R5_REG)))
1494               (clobber (reg:SI T_REG))
1495               (clobber (reg:SI PR_REG))
1496               (clobber (reg:SI R1_REG))
1497               (clobber (reg:SI R2_REG))
1498               (clobber (reg:SI R3_REG))
1499               (use (match_dup 3))])]
1500   ""
1501   "
1502 {
1503   rtx first, last;
1504
1505   operands[3] = gen_reg_rtx (Pmode);
1506   /* Emit the move of the address to a pseudo outside of the libcall.  */
1507   if (TARGET_HARD_SH4 && TARGET_SH2E)
1508     {
1509       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1510       if (TARGET_FPU_SINGLE)
1511         last = gen_divsi3_i4_single (operands[0], operands[3]);
1512       else
1513         last = gen_divsi3_i4 (operands[0], operands[3]);
1514     }
1515   else if (TARGET_SHMEDIA_FPU)
1516     {
1517       operands[1] = force_reg (SImode, operands[1]);
1518       operands[2] = force_reg (SImode, operands[2]);
1519       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1520       DONE;
1521     }
1522   else if (TARGET_SH5)
1523     {
1524       emit_move_insn (operands[3],
1525                       function_symbol (TARGET_FPU_ANY
1526                                        ? \"__sdivsi3_i4\"
1527                                        : \"__sdivsi3\"));
1528
1529       if (TARGET_SHMEDIA)
1530         last = gen_divsi3_i1_media (operands[0],
1531                                     Pmode == DImode
1532                                     ? operands[3]
1533                                     : gen_rtx_SUBREG (DImode, operands[3],
1534                                                       0));
1535       else if (TARGET_FPU_ANY)
1536         last = gen_divsi3_i4_single (operands[0], operands[3]);
1537       else
1538         last = gen_divsi3_i1 (operands[0], operands[3]);
1539     }
1540   else
1541     {
1542       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1543       last = gen_divsi3_i1 (operands[0], operands[3]);
1544     }
1545   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1546   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1547   last = emit_insn (last);
1548   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1549      invariant code motion can move it.  */
1550   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1551   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1552   DONE;
1553 }")
1554 \f
1555 ;; -------------------------------------------------------------------------
1556 ;; Multiplication instructions
1557 ;; -------------------------------------------------------------------------
1558
1559 (define_insn "umulhisi3_i"
1560   [(set (reg:SI MACL_REG)
1561         (mult:SI (zero_extend:SI
1562                   (match_operand:HI 0 "arith_reg_operand" "r"))
1563                  (zero_extend:SI
1564                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1565   "TARGET_SH1"
1566   "mulu.w       %1,%0"
1567   [(set_attr "type" "smpy")])
1568
1569 (define_insn "mulhisi3_i"
1570   [(set (reg:SI MACL_REG)
1571         (mult:SI (sign_extend:SI
1572                   (match_operand:HI 0 "arith_reg_operand" "r"))
1573                  (sign_extend:SI
1574                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1575   "TARGET_SH1"
1576   "muls.w       %1,%0"
1577   [(set_attr "type" "smpy")])
1578
1579 (define_expand "mulhisi3"
1580   [(set (reg:SI MACL_REG)
1581         (mult:SI (sign_extend:SI
1582                   (match_operand:HI 1 "arith_reg_operand" ""))
1583                  (sign_extend:SI
1584                   (match_operand:HI 2 "arith_reg_operand" ""))))
1585    (set (match_operand:SI 0 "arith_reg_operand" "")
1586         (reg:SI MACL_REG))]
1587   "TARGET_SH1"
1588   "
1589 {
1590   rtx first, last;
1591
1592   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1593   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1594   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1595      invariant code motion can move it.  */
1596   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1597   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1598   /* expand_binop can't find a suitable code in umul_widen_optab to
1599      make a REG_EQUAL note from, so make one here.
1600      See also smulsi3_highpart.
1601      ??? Alternatively, we could put this at the calling site of expand_binop,
1602      i.e. expand_expr.  */
1603   REG_NOTES (last)
1604     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1605                          REG_NOTES (last));
1606   DONE;
1607 }")
1608
1609 (define_expand "umulhisi3"
1610   [(set (reg:SI MACL_REG)
1611         (mult:SI (zero_extend:SI
1612                   (match_operand:HI 1 "arith_reg_operand" ""))
1613                  (zero_extend:SI
1614                   (match_operand:HI 2 "arith_reg_operand" ""))))
1615    (set (match_operand:SI 0 "arith_reg_operand" "")
1616         (reg:SI MACL_REG))]
1617   "TARGET_SH1"
1618   "
1619 {
1620   rtx first, last;
1621
1622   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1623   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1624   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1625      invariant code motion can move it.  */
1626   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1627   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1628   /* expand_binop can't find a suitable code in umul_widen_optab to
1629      make a REG_EQUAL note from, so make one here.
1630      See also smulsi3_highpart.
1631      ??? Alternatively, we could put this at the calling site of expand_binop,
1632      i.e. expand_expr.  */
1633   REG_NOTES (last)
1634     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1635                          REG_NOTES (last));
1636   DONE;
1637 }")
1638
1639 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1640 ;; a call to a routine which clobbers known registers.
1641
1642 (define_insn ""
1643   [(set (match_operand:SI 1 "register_operand" "=z")
1644         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1645    (clobber (reg:SI MACL_REG))
1646    (clobber (reg:SI T_REG))
1647    (clobber (reg:SI PR_REG))
1648    (clobber (reg:SI R3_REG))
1649    (clobber (reg:SI R2_REG))
1650    (clobber (reg:SI R1_REG))
1651    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1652   "TARGET_SH1"
1653   "jsr  @%0%#"
1654   [(set_attr "type" "sfunc")
1655    (set_attr "needs_delay_slot" "yes")])
1656
1657 (define_expand "mulsi3_call"
1658   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1659    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1660    (parallel[(set (match_operand:SI 0 "register_operand" "")
1661                   (mult:SI (reg:SI R4_REG)
1662                            (reg:SI R5_REG)))
1663              (clobber (reg:SI MACL_REG))
1664              (clobber (reg:SI T_REG))
1665              (clobber (reg:SI PR_REG))
1666              (clobber (reg:SI R3_REG))
1667              (clobber (reg:SI R2_REG))
1668              (clobber (reg:SI R1_REG))
1669              (use (match_operand:SI 3 "register_operand" ""))])]
1670   "TARGET_SH1"
1671   "")
1672
1673 (define_insn "mul_l"
1674   [(set (reg:SI MACL_REG)
1675         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1676                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1677   "TARGET_SH2"
1678   "mul.l        %1,%0"
1679   [(set_attr "type" "dmpy")])
1680
1681 (define_expand "mulsi3"
1682   [(set (reg:SI MACL_REG)
1683         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1684                   (match_operand:SI 2 "arith_reg_operand" "")))
1685    (set (match_operand:SI 0 "arith_reg_operand" "")
1686         (reg:SI MACL_REG))]
1687   "TARGET_SH1"
1688   "
1689 {
1690   rtx first, last;
1691
1692   if (!TARGET_SH2)
1693     {
1694       /* The address must be set outside the libcall,
1695          since it goes into a pseudo.  */
1696       rtx sym = function_symbol (\"__mulsi3\");
1697       rtx addr = force_reg (SImode, sym);
1698       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1699                                    operands[2], addr);
1700       first = insns;
1701       last = emit_insn (insns);
1702     }
1703   else
1704     {
1705       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1706
1707       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1708       /* consec_sets_giv can only recognize the first insn that sets a
1709          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1710          note.  */
1711       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1712     }
1713   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1714      invariant code motion can move it.  */
1715   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1716   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1717   DONE;
1718 }")
1719
1720 (define_insn "mulsidi3_i"
1721   [(set (reg:SI MACH_REG)
1722         (truncate:SI
1723          (lshiftrt:DI
1724           (mult:DI
1725            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1726            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1727           (const_int 32))))
1728    (set (reg:SI MACL_REG)
1729         (mult:SI (match_dup 0)
1730                  (match_dup 1)))]
1731   "TARGET_SH2"
1732   "dmuls.l      %1,%0"
1733   [(set_attr "type" "dmpy")])
1734
1735 (define_expand "mulsidi3"
1736   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1737         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1738                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1739   "TARGET_SH2 || TARGET_SHMEDIA"
1740   "
1741 {
1742   if (TARGET_SH2)
1743     {
1744        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1745                                         operands[2]));
1746        DONE;
1747     }
1748 }")
1749
1750 (define_insn "mulsidi3_media"
1751   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1752         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1753                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1754   "TARGET_SHMEDIA"
1755   "muls.l       %1, %2, %0"
1756   [(set_attr "type" "dmpy_media")])
1757
1758 (define_insn "mulsidi3_compact"
1759   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1760         (mult:DI
1761          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1762          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1763    (clobber (reg:SI MACH_REG))
1764    (clobber (reg:SI MACL_REG))]
1765   "TARGET_SH2"
1766   "#")
1767
1768 (define_split
1769   [(set (match_operand:DI 0 "arith_reg_operand" "")
1770         (mult:DI
1771          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1772          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1773    (clobber (reg:SI MACH_REG))
1774    (clobber (reg:SI MACL_REG))]
1775   "TARGET_SH2"
1776   [(const_int 0)]
1777   "
1778 {
1779   rtx low_dst = gen_lowpart (SImode, operands[0]);
1780   rtx high_dst = gen_highpart (SImode, operands[0]);
1781
1782   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1783
1784   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1785   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1786   /* We need something to tag the possible REG_EQUAL notes on to.  */
1787   emit_move_insn (operands[0], operands[0]);
1788   DONE;
1789 }")
1790
1791 (define_insn "umulsidi3_i"
1792   [(set (reg:SI MACH_REG)
1793         (truncate:SI
1794          (lshiftrt:DI
1795           (mult:DI
1796            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1797            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1798           (const_int 32))))
1799    (set (reg:SI MACL_REG)
1800         (mult:SI (match_dup 0)
1801                  (match_dup 1)))]
1802   "TARGET_SH2"
1803   "dmulu.l      %1,%0"
1804   [(set_attr "type" "dmpy")])
1805
1806 (define_expand "umulsidi3"
1807   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1808         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1809                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1810   "TARGET_SH2 || TARGET_SHMEDIA"
1811   "
1812 {
1813   if (TARGET_SH2)
1814     {
1815        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1816                                          operands[2]));
1817        DONE;
1818     }
1819 }")
1820
1821 (define_insn "umulsidi3_media"
1822   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1823         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1824                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1825   "TARGET_SHMEDIA"
1826   "mulu.l       %1, %2, %0"
1827   [(set_attr "type" "dmpy_media")])
1828
1829 (define_insn "umulsidi3_compact"
1830   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1831         (mult:DI
1832          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1833          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1834    (clobber (reg:SI MACH_REG))
1835    (clobber (reg:SI MACL_REG))]
1836   "TARGET_SH2"
1837   "#")
1838
1839 (define_split
1840   [(set (match_operand:DI 0 "arith_reg_operand" "")
1841         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1842                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1843    (clobber (reg:SI MACH_REG))
1844    (clobber (reg:SI MACL_REG))]
1845   "TARGET_SH2"
1846   [(const_int 0)]
1847   "
1848 {
1849   rtx low_dst = gen_lowpart (SImode, operands[0]);
1850   rtx high_dst = gen_highpart (SImode, operands[0]);
1851
1852   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1853
1854   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1855   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1856   /* We need something to tag the possible REG_EQUAL notes on to.  */
1857   emit_move_insn (operands[0], operands[0]);
1858   DONE;
1859 }")
1860
1861 (define_insn "smulsi3_highpart_i"
1862   [(set (reg:SI MACH_REG)
1863         (truncate:SI
1864          (lshiftrt:DI
1865           (mult:DI
1866            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1867            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1868           (const_int 32))))
1869    (clobber (reg:SI MACL_REG))]
1870   "TARGET_SH2"
1871   "dmuls.l      %1,%0"
1872   [(set_attr "type" "dmpy")])
1873
1874 (define_expand "smulsi3_highpart"
1875   [(parallel
1876     [(set (reg:SI MACH_REG)
1877           (truncate:SI
1878            (lshiftrt:DI
1879             (mult:DI
1880              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1881              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1882             (const_int 32))))
1883     (clobber (reg:SI MACL_REG))])
1884    (set (match_operand:SI 0 "arith_reg_operand" "")
1885         (reg:SI MACH_REG))]
1886   "TARGET_SH2"
1887   "
1888 {
1889   rtx first, last;
1890
1891   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1892   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1893   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1894      invariant code motion can move it.  */
1895   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1896   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1897   /* expand_binop can't find a suitable code in mul_highpart_optab to
1898      make a REG_EQUAL note from, so make one here.
1899      See also {,u}mulhisi.
1900      ??? Alternatively, we could put this at the calling site of expand_binop,
1901      i.e. expand_mult_highpart.  */
1902   REG_NOTES (last)
1903     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1904                          REG_NOTES (last));
1905   DONE;
1906 }")
1907
1908 (define_insn "umulsi3_highpart_i"
1909   [(set (reg:SI MACH_REG)
1910         (truncate:SI
1911          (lshiftrt:DI
1912           (mult:DI
1913            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1914            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1915           (const_int 32))))
1916    (clobber (reg:SI MACL_REG))]
1917   "TARGET_SH2"
1918   "dmulu.l      %1,%0"
1919   [(set_attr "type" "dmpy")])
1920
1921 (define_expand "umulsi3_highpart"
1922   [(parallel
1923     [(set (reg:SI MACH_REG)
1924           (truncate:SI
1925            (lshiftrt:DI
1926             (mult:DI
1927              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1928              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1929             (const_int 32))))
1930     (clobber (reg:SI MACL_REG))])
1931    (set (match_operand:SI 0 "arith_reg_operand" "")
1932         (reg:SI MACH_REG))]
1933   "TARGET_SH2"
1934   "
1935 {
1936   rtx first, last;
1937
1938   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1939   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1940   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1941      invariant code motion can move it.  */
1942   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1943   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1944   DONE;
1945 }")
1946 \f
1947 ;; -------------------------------------------------------------------------
1948 ;; Logical operations
1949 ;; -------------------------------------------------------------------------
1950
1951 (define_insn "*andsi3_compact"
1952   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1953         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1954                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1955   "TARGET_SH1"
1956   "and  %2,%0"
1957   [(set_attr "type" "arith")])
1958
1959 ;; If the constant is 255, then emit an extu.b instruction instead of an
1960 ;; and, since that will give better code.
1961
1962 (define_expand "andsi3"
1963   [(set (match_operand:SI 0 "arith_reg_operand" "")
1964         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1965                 (match_operand:SI 2 "logical_operand" "")))]
1966   "TARGET_SH1"
1967   "
1968 {
1969   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1970     {
1971       emit_insn (gen_zero_extendqisi2 (operands[0],
1972                                        gen_lowpart (QImode, operands[1])));
1973       DONE;
1974     }
1975 }")
1976
1977 (define_insn_and_split "anddi3"
1978   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1979         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1980                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1981   "TARGET_SHMEDIA"
1982   "@
1983         and     %1, %2, %0
1984         andi    %1, %2, %0
1985         #"
1986   "reload_completed
1987    && ! logical_operand (operands[2], DImode)"
1988   [(const_int 0)]
1989   "
1990 {
1991   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1992     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1993   else
1994     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1995   DONE;
1996 }"
1997   [(set_attr "type" "arith_media")])
1998
1999 (define_insn "andcdi3"
2000   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2001         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2002                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2003   "TARGET_SHMEDIA"
2004   "andc %1,%2,%0"
2005   [(set_attr "type" "arith_media")])
2006
2007 (define_insn "iorsi3"
2008   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2009         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2010                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2011   "TARGET_SH1"
2012   "or   %2,%0"
2013   [(set_attr "type" "arith")])
2014
2015 (define_insn "iordi3"
2016   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2017         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2018                 (match_operand:DI 2 "logical_operand" "r,I10")))]
2019   "TARGET_SHMEDIA"
2020   "@
2021         or      %1, %2, %0
2022         ori     %1, %2, %0"
2023   [(set_attr "type" "arith_media")])
2024
2025 (define_insn "xorsi3"
2026   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2027         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2028                 (match_operand:SI 2 "logical_operand" "K08,r")))]
2029   "TARGET_SH1"
2030   "xor  %2,%0"
2031   [(set_attr "type" "arith")])
2032
2033 (define_insn "xordi3"
2034   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2035         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2036                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2037   "TARGET_SHMEDIA"
2038   "@
2039         xor     %1, %2, %0
2040         xori    %1, %2, %0"
2041   [(set_attr "type" "arith_media")])
2042
2043 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2044 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2045 (define_split
2046   [(set (match_operand:DI 0 "arith_reg_operand" "")
2047         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2048                           [(match_operand 1 "any_register_operand" "")
2049                            (match_operand 2 "any_register_operand" "")])))]
2050   "TARGET_SHMEDIA"
2051   [(set (match_dup 5) (match_dup 4))
2052    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2053 "
2054 {
2055   enum machine_mode inmode = GET_MODE (operands[1]);
2056   int offset = 0;
2057
2058   if (GET_CODE (operands[0]) == SUBREG)
2059     {
2060       offset = SUBREG_BYTE (operands[0]);
2061       operands[0] = SUBREG_REG (operands[0]);
2062     }
2063   if (GET_CODE (operands[0]) != REG)
2064     abort ();
2065   if (! TARGET_LITTLE_ENDIAN)
2066     offset += 8 - GET_MODE_SIZE (inmode);
2067   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2068 }")
2069 \f
2070 ;; -------------------------------------------------------------------------
2071 ;; Shifts and rotates
2072 ;; -------------------------------------------------------------------------
2073
2074 (define_expand "rotldi3"
2075   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2076         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2077                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2078   "TARGET_SHMEDIA"
2079   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2080
2081 (define_insn "rotldi3_mextr"
2082   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2083         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2084                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2085   "TARGET_SHMEDIA"
2086   "*
2087 {
2088   static char templ[16];
2089
2090   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2091            8 - (int) (INTVAL (operands[2]) >> 3));
2092   return templ;
2093 }"
2094   [(set_attr "type" "arith_media")])
2095
2096 (define_expand "rotrdi3"
2097   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2098         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2099                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2100   "TARGET_SHMEDIA"
2101   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2102
2103 (define_insn "rotrdi3_mextr"
2104   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2105         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2106                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2107   "TARGET_SHMEDIA"
2108   "*
2109 {
2110   static char templ[16];
2111
2112   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2113   return templ;
2114 }"
2115   [(set_attr "type" "arith_media")])
2116
2117 (define_insn "rotlsi3_1"
2118   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2119         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2120                    (const_int 1)))
2121    (set (reg:SI T_REG)
2122         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2123   "TARGET_SH1"
2124   "rotl %0"
2125   [(set_attr "type" "arith")])
2126
2127 (define_insn "rotlsi3_31"
2128   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2129         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2130                    (const_int 31)))
2131    (clobber (reg:SI T_REG))]
2132   "TARGET_SH1"
2133   "rotr %0"
2134   [(set_attr "type" "arith")])
2135
2136 (define_insn "rotlsi3_16"
2137   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2138         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2139                    (const_int 16)))]
2140   "TARGET_SH1"
2141   "swap.w       %1,%0"
2142   [(set_attr "type" "arith")])
2143
2144 (define_expand "rotlsi3"
2145   [(set (match_operand:SI 0 "arith_reg_operand" "")
2146         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2147                    (match_operand:SI 2 "immediate_operand" "")))]
2148   "TARGET_SH1"
2149   "
2150 {
2151   static const char rot_tab[] = {
2152     000, 000, 000, 000, 000, 000, 010, 001,
2153     001, 001, 011, 013, 003, 003, 003, 003,
2154     003, 003, 003, 003, 003, 013, 012, 002,
2155     002, 002, 010, 000, 000, 000, 000, 000,
2156   };
2157
2158   int count, choice;
2159
2160   if (GET_CODE (operands[2]) != CONST_INT)
2161     FAIL;
2162   count = INTVAL (operands[2]);
2163   choice = rot_tab[count];
2164   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2165     FAIL;
2166   choice &= 7;
2167   switch (choice)
2168     {
2169     case 0:
2170       emit_move_insn (operands[0], operands[1]);
2171       count -= (count & 16) * 2;
2172       break;
2173     case 3:
2174      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2175      count -= 16;
2176      break;
2177     case 1:
2178     case 2:
2179       {
2180         rtx parts[2];
2181         parts[0] = gen_reg_rtx (SImode);
2182         parts[1] = gen_reg_rtx (SImode);
2183         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2184         parts[choice-1] = operands[1];
2185         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2186         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2187         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2188         count = (count & ~16) - 8;
2189       }
2190     }
2191
2192   for (; count > 0; count--)
2193     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2194   for (; count < 0; count++)
2195     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2196
2197   DONE;
2198 }")
2199
2200 (define_insn "*rotlhi3_8"
2201   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2202         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2203                    (const_int 8)))]
2204   "TARGET_SH1"
2205   "swap.b       %1,%0"
2206   [(set_attr "type" "arith")])
2207
2208 (define_expand "rotlhi3"
2209   [(set (match_operand:HI 0 "arith_reg_operand" "")
2210         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2211                    (match_operand:HI 2 "immediate_operand" "")))]
2212   "TARGET_SH1"
2213   "
2214 {
2215   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2216     FAIL;
2217 }")
2218
2219 ;;
2220 ;; shift left
2221
2222 ;; This pattern is used by init_expmed for computing the costs of shift
2223 ;; insns.
2224
2225 (define_insn_and_split "ashlsi3_std"
2226   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2227         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2228                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2229    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2230   "TARGET_SH3
2231    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2232        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2233   "@
2234    shld %2,%0
2235    add  %0,%0
2236    shll%O2      %0
2237    #"
2238   "TARGET_SH3
2239    && reload_completed
2240    && GET_CODE (operands[2]) == CONST_INT
2241    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2242   [(set (match_dup 3) (match_dup 2))
2243    (parallel
2244     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2245      (clobber (match_dup 4))])]
2246   "operands[4] = gen_rtx_SCRATCH (SImode);"
2247   [(set_attr "length" "*,*,*,4")
2248    (set_attr "type" "dyn_shift,arith,arith,arith")])
2249
2250 (define_insn "ashlhi3_k"
2251   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2252         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2253                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2254   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2255   "@
2256         add     %0,%0
2257         shll%O2 %0"
2258   [(set_attr "type" "arith")])
2259
2260 (define_insn "ashlsi3_n"
2261   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2262         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2263                    (match_operand:SI 2 "const_int_operand" "n")))
2264    (clobber (reg:SI T_REG))]
2265   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2266   "#"
2267   [(set (attr "length")
2268         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2269                (const_string "2")
2270                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2271                (const_string "4")
2272                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2273                (const_string "6")]
2274               (const_string "8")))
2275    (set_attr "type" "arith")])
2276
2277 (define_split
2278   [(set (match_operand:SI 0 "arith_reg_operand" "")
2279         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2280                    (match_operand:SI 2 "const_int_operand" "")))
2281    (clobber (reg:SI T_REG))]
2282   "TARGET_SH1 && reload_completed"
2283   [(use (reg:SI R0_REG))]
2284   "
2285 {
2286   gen_shifty_op (ASHIFT, operands);
2287   DONE;
2288 }")
2289
2290 (define_insn "ashlsi3_media"
2291   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2292         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2293                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2294   "TARGET_SHMEDIA"
2295   "@
2296         shlld.l %1, %2, %0
2297         shlli.l %1, %2, %0"
2298   [(set_attr "type" "arith_media")])
2299
2300 (define_expand "ashlsi3"
2301   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2302                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2303                               (match_operand:SI 2 "nonmemory_operand" "")))
2304               (clobber (reg:SI T_REG))])]
2305   ""
2306   "
2307 {
2308   if (TARGET_SHMEDIA)
2309     {
2310       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2311       DONE;
2312     }
2313   if (GET_CODE (operands[2]) == CONST_INT
2314       && sh_dynamicalize_shift_p (operands[2]))
2315     operands[2] = force_reg (SImode, operands[2]);
2316   if (TARGET_SH3)
2317     {
2318       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2319       DONE;
2320     }
2321   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2322     FAIL;
2323 }")
2324
2325 (define_insn "ashlhi3"
2326   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2327         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2328                    (match_operand:HI 2 "const_int_operand" "n")))
2329    (clobber (reg:SI T_REG))]
2330   "TARGET_SH1"
2331   "#"
2332   [(set (attr "length")
2333         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2334                (const_string "2")
2335                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2336                (const_string "4")]
2337               (const_string "6")))
2338    (set_attr "type" "arith")])
2339
2340 (define_split
2341   [(set (match_operand:HI 0 "arith_reg_operand" "")
2342         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2343                    (match_operand:HI 2 "const_int_operand" "")))
2344    (clobber (reg:SI T_REG))]
2345   "TARGET_SH1 && reload_completed"
2346   [(use (reg:SI R0_REG))]
2347   "
2348 {
2349   gen_shifty_hi_op (ASHIFT, operands);
2350   DONE;
2351 }")
2352
2353 ;
2354 ; arithmetic shift right
2355 ;
2356
2357 (define_insn "ashrsi3_k"
2358   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2359         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2360                      (match_operand:SI 2 "const_int_operand" "M")))
2361    (clobber (reg:SI T_REG))]
2362   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2363   "shar %0"
2364   [(set_attr "type" "arith")])
2365
2366 ;; We can't do HImode right shifts correctly unless we start out with an
2367 ;; explicit zero / sign extension; doing that would result in worse overall
2368 ;; code, so just let the machine independent code widen the mode.
2369 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2370
2371
2372 ;; ??? This should be a define expand.
2373
2374 (define_insn "ashrsi2_16"
2375   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2376         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2377                      (const_int 16)))]
2378   "TARGET_SH1"
2379   "#"
2380   [(set_attr "length" "4")])
2381
2382 (define_split
2383   [(set (match_operand:SI 0 "arith_reg_operand" "")
2384         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2385                      (const_int 16)))]
2386   "TARGET_SH1"
2387   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2388    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2389   "operands[2] = gen_lowpart (HImode, operands[0]);")
2390
2391 ;; ??? This should be a define expand.
2392
2393 (define_insn "ashrsi2_31"
2394   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2395         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2396                      (const_int 31)))
2397    (clobber (reg:SI T_REG))]
2398   "TARGET_SH1"
2399   "#"
2400   [(set_attr "length" "4")])
2401
2402 (define_split
2403   [(set (match_operand:SI 0 "arith_reg_operand" "")
2404         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2405                      (const_int 31)))
2406    (clobber (reg:SI T_REG))]
2407   "TARGET_SH1"
2408   [(const_int 0)]
2409   "
2410 {
2411   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2412   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2413   DONE;
2414 }")
2415
2416 (define_insn "ashlsi_c"
2417   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2418         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2419    (set (reg:SI T_REG)
2420         (lt:SI (match_dup 1) (const_int 0)))]
2421   "TARGET_SH1"
2422   "shll %0"
2423   [(set_attr "type" "arith")])
2424
2425 (define_insn "ashrsi3_d"
2426   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2427         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2428                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2429   "TARGET_SH3"
2430   "shad %2,%0"
2431   [(set_attr "type" "dyn_shift")])
2432
2433 (define_insn "ashrsi3_n"
2434   [(set (reg:SI R4_REG)
2435         (ashiftrt:SI (reg:SI R4_REG)
2436                      (match_operand:SI 0 "const_int_operand" "i")))
2437    (clobber (reg:SI T_REG))
2438    (clobber (reg:SI PR_REG))
2439    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2440   "TARGET_SH1"
2441   "jsr  @%1%#"
2442   [(set_attr "type" "sfunc")
2443    (set_attr "needs_delay_slot" "yes")])
2444
2445 (define_insn "ashrsi3_media"
2446   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2447         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2448                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2449   "TARGET_SHMEDIA"
2450   "@
2451         shard.l %1, %2, %0
2452         shari.l %1, %2, %0"
2453   [(set_attr "type" "arith_media")])
2454
2455 (define_expand "ashrsi3"
2456   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2457                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2458                                 (match_operand:SI 2 "nonmemory_operand" "")))
2459               (clobber (reg:SI T_REG))])]
2460   ""
2461   "
2462 {
2463   if (TARGET_SHMEDIA)
2464     {
2465       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2466       DONE;
2467     }
2468   if (expand_ashiftrt (operands))
2469     DONE;
2470   else
2471     FAIL;
2472 }")
2473
2474 ;; logical shift right
2475
2476 (define_insn "lshrsi3_d"
2477   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2478         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2479                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2480   "TARGET_SH3"
2481   "shld %2,%0"
2482   [(set_attr "type" "dyn_shift")])
2483
2484 ;;  Only the single bit shift clobbers the T bit.
2485
2486 (define_insn "lshrsi3_m"
2487   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2488         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2489                      (match_operand:SI 2 "const_int_operand" "M")))
2490    (clobber (reg:SI T_REG))]
2491   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2492   "shlr %0"
2493   [(set_attr "type" "arith")])
2494
2495 (define_insn "lshrsi3_k"
2496   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2497         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2498                      (match_operand:SI 2 "const_int_operand" "P27")))]
2499   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2500    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2501   "shlr%O2      %0"
2502   [(set_attr "type" "arith")])
2503
2504 (define_insn "lshrsi3_n"
2505   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2506         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2507                      (match_operand:SI 2 "const_int_operand" "n")))
2508    (clobber (reg:SI T_REG))]
2509   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2510   "#"
2511   [(set (attr "length")
2512         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2513                (const_string "2")
2514                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2515                (const_string "4")
2516                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2517                (const_string "6")]
2518               (const_string "8")))
2519    (set_attr "type" "arith")])
2520
2521 (define_split
2522   [(set (match_operand:SI 0 "arith_reg_operand" "")
2523         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2524                      (match_operand:SI 2 "const_int_operand" "")))
2525    (clobber (reg:SI T_REG))]
2526   "TARGET_SH1 && reload_completed"
2527   [(use (reg:SI R0_REG))]
2528   "
2529 {
2530   gen_shifty_op (LSHIFTRT, operands);
2531   DONE;
2532 }")
2533
2534 (define_insn "lshrsi3_media"
2535   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2536         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2537                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2538   "TARGET_SHMEDIA"
2539   "@
2540         shlrd.l %1, %2, %0
2541         shlri.l %1, %2, %0"
2542   [(set_attr "type" "arith_media")])
2543
2544 (define_expand "lshrsi3"
2545   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2546                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2547                                 (match_operand:SI 2 "nonmemory_operand" "")))
2548               (clobber (reg:SI T_REG))])]
2549   ""
2550   "
2551 {
2552   if (TARGET_SHMEDIA)
2553     {
2554       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2555       DONE;
2556     }
2557   if (GET_CODE (operands[2]) == CONST_INT
2558       && sh_dynamicalize_shift_p (operands[2]))
2559     operands[2] = force_reg (SImode, operands[2]);
2560   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2561     {
2562       rtx count = copy_to_mode_reg (SImode, operands[2]);
2563       emit_insn (gen_negsi2 (count, count));
2564       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2565       DONE;
2566     }
2567   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2568     FAIL;
2569 }")
2570
2571 ;; ??? This should be a define expand.
2572
2573 (define_insn "ashldi3_k"
2574   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2575         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2576                    (const_int 1)))
2577    (clobber (reg:SI T_REG))]
2578   "TARGET_SH1"
2579   "shll %R0\;rotcl      %S0"
2580   [(set_attr "length" "4")
2581    (set_attr "type" "arith")])
2582
2583 (define_insn "ashldi3_media"
2584   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2585         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2586                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2587   "TARGET_SHMEDIA"
2588   "@
2589         shlld   %1, %2, %0
2590         shlli   %1, %2, %0"
2591   [(set_attr "type" "arith_media")])
2592
2593 (define_expand "ashldi3"
2594   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2595                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2596                               (match_operand:DI 2 "immediate_operand" "")))
2597               (clobber (reg:SI T_REG))])]
2598   ""
2599   "
2600 {
2601   if (TARGET_SHMEDIA)
2602     {
2603       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2604       DONE;
2605     }
2606   if (GET_CODE (operands[2]) != CONST_INT
2607       || INTVAL (operands[2]) != 1)
2608     FAIL;
2609 }")
2610
2611 ;; ??? This should be a define expand.
2612
2613 (define_insn "lshrdi3_k"
2614   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2615         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2616                      (const_int 1)))
2617    (clobber (reg:SI T_REG))]
2618   "TARGET_SH1"
2619   "shlr %S0\;rotcr      %R0"
2620   [(set_attr "length" "4")
2621    (set_attr "type" "arith")])
2622
2623 (define_insn "lshrdi3_media"
2624   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2625         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2626                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2627   "TARGET_SHMEDIA"
2628   "@
2629         shlrd   %1, %2, %0
2630         shlri   %1, %2, %0"
2631   [(set_attr "type" "arith_media")])
2632
2633 (define_expand "lshrdi3"
2634   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2635                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2636                                (match_operand:DI 2 "immediate_operand" "")))
2637              (clobber (reg:SI T_REG))])]
2638   ""
2639   "
2640 {
2641   if (TARGET_SHMEDIA)
2642     {
2643       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2644       DONE;
2645     }
2646   if (GET_CODE (operands[2]) != CONST_INT
2647       || INTVAL (operands[2]) != 1)
2648     FAIL;
2649 }")
2650
2651 ;; ??? This should be a define expand.
2652
2653 (define_insn "ashrdi3_k"
2654   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2655         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2656                      (const_int 1)))
2657    (clobber (reg:SI T_REG))]
2658   "TARGET_SH1"
2659   "shar %S0\;rotcr      %R0"
2660   [(set_attr "length" "4")
2661    (set_attr "type" "arith")])
2662
2663 (define_insn "ashrdi3_media"
2664   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2665         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2666                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2667   "TARGET_SHMEDIA"
2668   "@
2669         shard   %1, %2, %0
2670         shari   %1, %2, %0"
2671   [(set_attr "type" "arith_media")])
2672
2673 (define_expand "ashrdi3"
2674   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2675                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2676                                 (match_operand:DI 2 "immediate_operand" "")))
2677               (clobber (reg:SI T_REG))])]
2678   ""
2679   "
2680 {
2681   if (TARGET_SHMEDIA)
2682     {
2683       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2684       DONE;
2685     }
2686   if (GET_CODE (operands[2]) != CONST_INT
2687       || INTVAL (operands[2]) != 1)
2688     FAIL;
2689 }")
2690
2691 ;; combined left/right shift
2692
2693 (define_split
2694   [(set (match_operand:SI 0 "register_operand" "")
2695         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2696                            (match_operand:SI 2 "const_int_operand" ""))
2697                 (match_operand:SI 3 "const_int_operand" "")))]
2698   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2699   [(use (reg:SI R0_REG))]
2700   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2701    DONE;")
2702
2703 (define_split
2704   [(set (match_operand:SI 0 "register_operand" "")
2705         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2706                            (match_operand:SI 2 "const_int_operand" ""))
2707                 (match_operand:SI 3 "const_int_operand" "")))
2708    (clobber (reg:SI T_REG))]
2709   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2710   [(use (reg:SI R0_REG))]
2711   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2712    DONE;")
2713
2714 (define_insn ""
2715   [(set (match_operand:SI 0 "register_operand" "=r")
2716         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2717                            (match_operand:SI 2 "const_int_operand" "n"))
2718                 (match_operand:SI 3 "const_int_operand" "n")))
2719    (clobber (reg:SI T_REG))]
2720   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2721  "#"
2722   [(set (attr "length")
2723         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2724                (const_string "4")
2725                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2726                (const_string "6")
2727                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2728                (const_string "8")
2729                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2730                (const_string "10")
2731                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2732                (const_string "12")
2733                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2734                (const_string "14")
2735                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2736                (const_string "16")]
2737               (const_string "18")))
2738    (set_attr "type" "arith")])
2739
2740 (define_insn ""
2741   [(set (match_operand:SI 0 "register_operand" "=z")
2742         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2743                            (match_operand:SI 2 "const_int_operand" "n"))
2744                 (match_operand:SI 3 "const_int_operand" "n")))
2745    (clobber (reg:SI T_REG))]
2746   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2747  "#"
2748   [(set (attr "length")
2749         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2750                (const_string "4")
2751                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2752                (const_string "6")
2753                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2754                (const_string "8")]
2755               (const_string "10")))
2756    (set_attr "type" "arith")])
2757
2758 ;; shift left / and combination with a scratch register: The combine pass
2759 ;; does not accept the individual instructions, even though they are
2760 ;; cheap.  But it needs a precise description so that it is usable after
2761 ;; reload.
2762 (define_insn "and_shl_scratch"
2763   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2764         (lshiftrt:SI
2765          (ashift:SI
2766           (and:SI
2767            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2768                         (match_operand:SI 2 "const_int_operand" "N,n"))
2769            (match_operand:SI 3 "" "0,r"))
2770           (match_operand:SI 4 "const_int_operand" "n,n"))
2771          (match_operand:SI 5 "const_int_operand" "n,n")))
2772    (clobber (reg:SI T_REG))]
2773   "TARGET_SH1"
2774   "#"
2775   [(set (attr "length")
2776         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2777                (const_string "4")
2778                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2779                (const_string "6")
2780                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2781                (const_string "8")
2782                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2783                (const_string "10")]
2784               (const_string "12")))
2785    (set_attr "type" "arith")])
2786
2787 (define_split
2788   [(set (match_operand:SI 0 "register_operand" "")
2789         (lshiftrt:SI
2790          (ashift:SI
2791           (and:SI
2792            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2793                         (match_operand:SI 2 "const_int_operand" ""))
2794            (match_operand:SI 3 "register_operand" ""))
2795           (match_operand:SI 4 "const_int_operand" ""))
2796          (match_operand:SI 5 "const_int_operand" "")))
2797    (clobber (reg:SI T_REG))]
2798   "TARGET_SH1"
2799   [(use (reg:SI R0_REG))]
2800   "
2801 {
2802   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2803
2804   if (INTVAL (operands[2]))
2805     {
2806       gen_shifty_op (LSHIFTRT, operands);
2807     }
2808   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2809   operands[2] = operands[4];
2810   gen_shifty_op (ASHIFT, operands);
2811   if (INTVAL (operands[5]))
2812     {
2813       operands[2] = operands[5];
2814       gen_shifty_op (LSHIFTRT, operands);
2815     }
2816   DONE;
2817 }")
2818
2819 ;; signed left/right shift combination.
2820 (define_split
2821   [(set (match_operand:SI 0 "register_operand" "")
2822         (sign_extract:SI
2823          (ashift:SI (match_operand:SI 1 "register_operand" "")
2824                     (match_operand:SI 2 "const_int_operand" ""))
2825          (match_operand:SI 3 "const_int_operand" "")
2826          (const_int 0)))
2827    (clobber (reg:SI T_REG))]
2828   "TARGET_SH1"
2829   [(use (reg:SI R0_REG))]
2830   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2831    DONE;")
2832
2833 (define_insn "shl_sext_ext"
2834   [(set (match_operand:SI 0 "register_operand" "=r")
2835         (sign_extract:SI
2836          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2837                     (match_operand:SI 2 "const_int_operand" "n"))
2838          (match_operand:SI 3 "const_int_operand" "n")
2839          (const_int 0)))
2840    (clobber (reg:SI T_REG))]
2841   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2842   "#"
2843   [(set (attr "length")
2844         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2845                (const_string "2")
2846                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2847                (const_string "4")
2848                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2849                (const_string "6")
2850                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2851                (const_string "8")
2852                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2853                (const_string "10")
2854                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2855                (const_string "12")
2856                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2857                (const_string "14")
2858                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2859                (const_string "16")]
2860               (const_string "18")))
2861     (set_attr "type" "arith")])
2862
2863 (define_insn "shl_sext_sub"
2864   [(set (match_operand:SI 0 "register_operand" "=z")
2865         (sign_extract:SI
2866          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2867                     (match_operand:SI 2 "const_int_operand" "n"))
2868          (match_operand:SI 3 "const_int_operand" "n")
2869          (const_int 0)))
2870    (clobber (reg:SI T_REG))]
2871   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2872   "#"
2873   [(set (attr "length")
2874         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2875                (const_string "6")
2876                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2877                (const_string "8")
2878                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2879                (const_string "10")
2880                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2881                (const_string "12")]
2882               (const_string "14")))
2883     (set_attr "type" "arith")])
2884
2885 ;; These patterns are found in expansions of DImode shifts by 16, and
2886 ;; allow the xtrct instruction to be generated from C source.
2887
2888 (define_insn "xtrct_left"
2889   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2890         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2891                            (const_int 16))
2892                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2893                              (const_int 16))))]
2894   "TARGET_SH1"
2895   "xtrct        %1,%0"
2896   [(set_attr "type" "arith")])
2897
2898 (define_insn "xtrct_right"
2899   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2900         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2901                              (const_int 16))
2902                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2903                            (const_int 16))))]
2904   "TARGET_SH1"
2905   "xtrct        %2,%0"
2906   [(set_attr "type" "arith")])
2907
2908 ;; -------------------------------------------------------------------------
2909 ;; Unary arithmetic
2910 ;; -------------------------------------------------------------------------
2911
2912 (define_insn "negc"
2913   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2914         (neg:SI (plus:SI (reg:SI T_REG)
2915                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2916    (set (reg:SI T_REG)
2917         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2918                (const_int 0)))]
2919   "TARGET_SH1"
2920   "negc %1,%0"
2921   [(set_attr "type" "arith")])
2922
2923 (define_insn "*negdi_media"
2924   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2925         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2926   "TARGET_SHMEDIA"
2927   "sub  r63, %1, %0"
2928   [(set_attr "type" "arith_media")])
2929
2930 (define_expand "negdi2"
2931   [(set (match_operand:DI 0 "arith_reg_operand" "")
2932         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2933   ""
2934   "
2935 {
2936   if (TARGET_SH1)
2937     {
2938       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2939       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2940
2941       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2942       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2943
2944       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2945       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2946
2947       emit_insn (gen_clrt ());
2948       emit_insn (gen_negc (low_dst, low_src));
2949       emit_insn (gen_negc (high_dst, high_src));
2950       DONE;
2951     }
2952 }")
2953
2954 (define_insn "negsi2"
2955   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2956         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2957   "TARGET_SH1"
2958   "neg  %1,%0"
2959   [(set_attr "type" "arith")])
2960
2961 (define_insn "one_cmplsi2"
2962   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2963         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2964   "TARGET_SH1"
2965   "not  %1,%0"
2966   [(set_attr "type" "arith")])
2967
2968 (define_expand "one_cmpldi2"
2969   [(set (match_operand:DI 0 "arith_reg_operand" "")
2970         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2971                 (const_int -1)))]
2972   "TARGET_SHMEDIA" "")
2973 \f
2974 ;; -------------------------------------------------------------------------
2975 ;; Zero extension instructions
2976 ;; -------------------------------------------------------------------------
2977
2978 (define_insn "zero_extendsidi2"
2979   [(set (match_operand:DI 0 "register_operand" "=r")
2980         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2981   "TARGET_SHMEDIA"
2982   "addz.l       %1, r63, %0"
2983   [(set_attr "type" "arith_media")])
2984
2985 (define_insn "zero_extendhidi2"
2986   [(set (match_operand:DI 0 "register_operand" "=r,r")
2987         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2988   "TARGET_SHMEDIA"
2989   "@
2990         #
2991         ld%M1.uw        %m1, %0"
2992   [(set_attr "type" "*,load_media")])
2993
2994 (define_split
2995   [(set (match_operand:DI 0 "register_operand" "")
2996         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2997   "TARGET_SHMEDIA && reload_completed"
2998   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2999    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3000   "
3001 {
3002   if (GET_CODE (operands[1]) == TRUNCATE)
3003     operands[1] = XEXP (operands[1], 0);
3004 }")
3005
3006 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3007 ;; reload the entire truncate expression.
3008 (define_insn_and_split "*loaddi_trunc"
3009   [(set (match_operand 0 "int_gpr_dest" "=r")
3010         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3011   "TARGET_SHMEDIA && reload_completed"
3012   "#"
3013   "TARGET_SHMEDIA && reload_completed"
3014   [(set (match_dup 0) (match_dup 1))]
3015   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3016
3017 (define_insn "zero_extendqidi2"
3018   [(set (match_operand:DI 0 "register_operand" "=r,r")
3019         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3020   "TARGET_SHMEDIA"
3021   "@
3022         andi    %1, 255, %0
3023         ld%M1.ub        %m1, %0"
3024   [(set_attr "type" "arith_media,load_media")])
3025
3026 (define_expand "zero_extendhisi2"
3027   [(set (match_operand:SI 0 "arith_reg_operand" "")
3028         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3029   ""
3030   "
3031 {
3032   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3033     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3034 }")
3035
3036 (define_insn "*zero_extendhisi2_compact"
3037   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3038         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3039   "TARGET_SH1"
3040   "extu.w       %1,%0"
3041   [(set_attr "type" "arith")])
3042
3043 (define_insn "*zero_extendhisi2_media"
3044   [(set (match_operand:SI 0 "register_operand" "=r,r")
3045         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3046   "TARGET_SHMEDIA"
3047   "@
3048         #
3049         ld%M1.uw        %m1, %0"
3050   [(set_attr "type" "arith_media,load_media")])
3051
3052 (define_split
3053   [(set (match_operand:SI 0 "register_operand" "")
3054         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3055   "TARGET_SHMEDIA && reload_completed"
3056   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3057    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3058   "
3059 {
3060   if (GET_CODE (operands[1]) == TRUNCATE)
3061     operands[1] = XEXP (operands[1], 0);
3062 }")
3063
3064 (define_expand "zero_extendqisi2"
3065   [(set (match_operand:SI 0 "arith_reg_operand" "")
3066         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3067   ""
3068   "
3069 {
3070   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3071     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3072 }")
3073
3074 (define_insn "*zero_extendqisi2_compact"
3075   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3076         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3077   "TARGET_SH1"
3078   "extu.b       %1,%0"
3079   [(set_attr "type" "arith")])
3080
3081 (define_insn "*zero_extendqisi2_media"
3082   [(set (match_operand:SI 0 "register_operand" "=r,r")
3083         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3084   "TARGET_SHMEDIA"
3085   "@
3086         andi    %1, 255, %0
3087         ld%M1.ub        %m1, %0"
3088   [(set_attr "type" "arith_media,load_media")])
3089
3090 (define_insn "zero_extendqihi2"
3091   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3092         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3093   "TARGET_SH1"
3094   "extu.b       %1,%0"
3095   [(set_attr "type" "arith")])
3096
3097 ;; -------------------------------------------------------------------------
3098 ;; Sign extension instructions
3099 ;; -------------------------------------------------------------------------
3100
3101 ;; ??? This should be a define expand.
3102 ;; ??? Or perhaps it should be dropped?
3103
3104 ;; convert_move generates good code for SH[1-4].
3105 (define_insn "extendsidi2"
3106   [(set (match_operand:DI 0 "register_operand" "=r,r")
3107         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3108   "TARGET_SHMEDIA"
3109   "@
3110         add.l   %1, r63, %0
3111         ld%M1.l %m1, %0"
3112   [(set_attr "type" "arith_media,load_media")])
3113
3114 (define_insn "extendhidi2"
3115   [(set (match_operand:DI 0 "register_operand" "=r,r")
3116         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3117   "TARGET_SHMEDIA"
3118   "@
3119         #
3120         ld%M1.w %m1, %0"
3121   [(set_attr "type" "*,load_media")])
3122
3123 (define_split
3124   [(set (match_operand:DI 0 "register_operand" "")
3125         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3126   "TARGET_SHMEDIA && reload_completed"
3127   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3128    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3129   "
3130 {
3131   if (GET_CODE (operands[1]) == TRUNCATE)
3132     operands[1] = XEXP (operands[1], 0);
3133 }")
3134
3135 (define_insn "extendqidi2"
3136   [(set (match_operand:DI 0 "register_operand" "=r,r")
3137         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3138   "TARGET_SHMEDIA"
3139   "@
3140         #
3141         ld%M1.b %m1, %0"
3142   [(set_attr "type" "*,load_media")])
3143
3144 (define_split
3145   [(set (match_operand:DI 0 "register_operand" "")
3146         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3147   "TARGET_SHMEDIA && reload_completed"
3148   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3149    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3150   "
3151 {
3152   if (GET_CODE (operands[1]) == TRUNCATE)
3153     operands[1] = XEXP (operands[1], 0);
3154 }")
3155
3156 (define_expand "extendhisi2"
3157   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3158        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3159   ""
3160   "")
3161
3162 (define_insn "*extendhisi2_compact"
3163   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3164         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3165   "TARGET_SH1"
3166   "@
3167         exts.w  %1,%0
3168         mov.w   %1,%0"
3169   [(set_attr "type" "arith,load")])
3170
3171 (define_insn "*extendhisi2_media"
3172   [(set (match_operand:SI 0 "register_operand" "=r,r")
3173         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3174   "TARGET_SHMEDIA"
3175   "@
3176         #
3177         ld%M1.w %m1, %0"
3178   [(set_attr "type" "arith_media,load_media")])
3179
3180 (define_split
3181   [(set (match_operand:SI 0 "register_operand" "")
3182         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3183   "TARGET_SHMEDIA && reload_completed"
3184   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3185    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3186   "
3187 {
3188   if (GET_CODE (operands[1]) == TRUNCATE)
3189     operands[1] = XEXP (operands[1], 0);
3190 }")
3191
3192 (define_expand "extendqisi2"
3193   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3194         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3195   ""
3196   "")
3197
3198 (define_insn "*extendqisi2_compact"
3199   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3200         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3201   "TARGET_SH1"
3202   "@
3203         exts.b  %1,%0
3204         mov.b   %1,%0"
3205   [(set_attr "type" "arith,load")])
3206
3207 (define_insn "*extendqisi2_media"
3208   [(set (match_operand:SI 0 "register_operand" "=r,r")
3209         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3210   "TARGET_SHMEDIA"
3211   "@
3212         #
3213         ld%M1.b %m1, %0"
3214   [(set_attr "type" "arith_media,load_media")])
3215
3216 (define_split
3217   [(set (match_operand:SI 0 "register_operand" "")
3218         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3219   "TARGET_SHMEDIA && reload_completed"
3220   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3221    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3222    "
3223 {
3224   if (GET_CODE (operands[1]) == TRUNCATE)
3225     operands[1] = XEXP (operands[1], 0);
3226 }")
3227
3228 (define_insn "extendqihi2"
3229   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3230         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3231   "TARGET_SH1"
3232   "@
3233         exts.b  %1,%0
3234         mov.b   %1,%0"
3235   [(set_attr "type" "arith,load")])
3236
3237 /* It would seem useful to combine the truncXi patterns into the movXi
3238    patterns, but unary operators are ignored when matching constraints,
3239    so we need separate patterns.  */
3240 (define_insn "truncdisi2"
3241   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3242         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3243   "TARGET_SHMEDIA"
3244   "@
3245         add.l   %1, r63, %0
3246         st%M0.l %m0, %1
3247         fst%M0.s        %m0, %T1
3248         fmov.ls %1, %0
3249         fmov.sl %T1, %0
3250         fmov.s  %T1, %0"
3251   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3252
3253
3254 (define_insn "truncdihi2"
3255   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3256         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3257   "TARGET_SHMEDIA"
3258   "@
3259         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3260         st%M0.w %m0, %1"
3261   [(set_attr "type"   "arith_media,store_media")
3262    (set_attr "length" "8,4")])
3263
3264 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3265 ; Because we use zero extension, we can't provide signed QImode compares
3266 ; using a simple compare or conditional banch insn.
3267 (define_insn "truncdiqi2"
3268   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3269         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3270   "TARGET_SHMEDIA"
3271   "@
3272         and     %1, 255, %0
3273         st%M0.b %m0, %1"
3274   [(set_attr "type"   "arith_media,store")])
3275
3276 ;; -------------------------------------------------------------------------
3277 ;; Move instructions
3278 ;; -------------------------------------------------------------------------
3279
3280 ;; define push and pop so it is easy for sh.c
3281 ;; We can't use push and pop on SHcompact because the stack must always
3282 ;; be 8-byte aligned.
3283
3284 (define_expand "push"
3285   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3286         (match_operand:SI 0 "register_operand" "r,l,x"))]
3287   "TARGET_SH1 && ! TARGET_SH5"
3288   "")
3289
3290 (define_expand "pop"
3291   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3292         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3293   "TARGET_SH1 && ! TARGET_SH5"
3294   "")
3295
3296 (define_expand "push_e"
3297   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3298                    (match_operand:SF 0 "" ""))
3299               (use (reg:PSI FPSCR_REG))
3300               (clobber (scratch:SI))])]
3301   "TARGET_SH1 && ! TARGET_SH5"
3302   "")
3303
3304 (define_insn "push_fpul"
3305   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3306   "TARGET_SH2E && ! TARGET_SH5"
3307   "sts.l        fpul,@-r15"
3308   [(set_attr "type" "store")
3309    (set_attr "late_fp_use" "yes")
3310    (set_attr "hit_stack" "yes")])
3311
3312 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3313 ;; so use that.
3314 (define_expand "push_4"
3315   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3316                    (match_operand:DF 0 "" ""))
3317               (use (reg:PSI FPSCR_REG))
3318               (clobber (scratch:SI))])]
3319   "TARGET_SH1 && ! TARGET_SH5"
3320   "")
3321
3322 (define_expand "pop_e"
3323   [(parallel [(set (match_operand:SF 0 "" "")
3324               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3325               (use (reg:PSI FPSCR_REG))
3326               (clobber (scratch:SI))])]
3327   "TARGET_SH1 && ! TARGET_SH5"
3328   "")
3329
3330 (define_insn "pop_fpul"
3331   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3332   "TARGET_SH2E && ! TARGET_SH5"
3333   "lds.l        @r15+,fpul"
3334   [(set_attr "type" "load")
3335    (set_attr "hit_stack" "yes")])
3336
3337 (define_expand "pop_4"
3338   [(parallel [(set (match_operand:DF 0 "" "")
3339                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3340               (use (reg:PSI FPSCR_REG))
3341               (clobber (scratch:SI))])]
3342   "TARGET_SH1 && ! TARGET_SH5"
3343   "")
3344
3345 (define_expand "push_fpscr"
3346   [(const_int 0)]
3347   "TARGET_SH2E"
3348   "
3349 {
3350   rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3351                                                  gen_rtx (PRE_DEC, Pmode,
3352                                                           stack_pointer_rtx)),
3353                                         get_fpscr_rtx ()));
3354   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3355   DONE;
3356 }")
3357
3358 (define_expand "pop_fpscr"
3359   [(const_int 0)]
3360   "TARGET_SH2E"
3361   "
3362 {
3363   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3364                                         gen_rtx (MEM, PSImode,
3365                                                  gen_rtx (POST_INC, Pmode,
3366                                                           stack_pointer_rtx))));
3367   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3368   DONE;
3369 }")
3370
3371 ;; These two patterns can happen as the result of optimization, when
3372 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3373 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3374
3375 (define_insn "clrt"
3376   [(set (reg:SI T_REG) (const_int 0))]
3377   "TARGET_SH1"
3378   "clrt")
3379
3380 (define_insn "sett"
3381   [(set (reg:SI T_REG) (const_int 1))]
3382   "TARGET_SH1"
3383   "sett")
3384
3385 ;; t/r must come after r/r, lest reload will try to reload stuff like
3386 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3387 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3388 (define_insn "movsi_i"
3389   [(set (match_operand:SI 0 "general_movdst_operand"
3390             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3391         (match_operand:SI 1 "general_movsrc_operand"
3392          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3393   "TARGET_SH1
3394    && ! TARGET_SH2E
3395    && (register_operand (operands[0], SImode)
3396        || register_operand (operands[1], SImode))"
3397   "@
3398         mov.l   %1,%0
3399         mov     %1,%0
3400         cmp/pl  %1
3401         mov.l   %1,%0
3402         sts     %1,%0
3403         sts     %1,%0
3404         movt    %0
3405         mov.l   %1,%0
3406         sts.l   %1,%0
3407         sts.l   %1,%0
3408         lds     %1,%0
3409         lds     %1,%0
3410         lds.l   %1,%0
3411         lds.l   %1,%0
3412         fake    %1,%0"
3413   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3414    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3415
3416 ;; t/r must come after r/r, lest reload will try to reload stuff like
3417 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3418 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3419 ;; will require a reload.
3420 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3421 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3422 (define_insn "movsi_ie"
3423   [(set (match_operand:SI 0 "general_movdst_operand"
3424             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3425         (match_operand:SI 1 "general_movsrc_operand"
3426          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3427   "TARGET_SH2E
3428    && (register_operand (operands[0], SImode)
3429        || register_operand (operands[1], SImode))"
3430   "@
3431         mov.l   %1,%0
3432         mov     %1,%0
3433         cmp/pl  %1
3434         mov.l   %1,%0
3435         sts     %1,%0
3436         sts     %1,%0
3437         movt    %0
3438         mov.l   %1,%0
3439         sts.l   %1,%0
3440         sts.l   %1,%0
3441         lds     %1,%0
3442         lds     %1,%0
3443         lds.l   %1,%0
3444         lds.l   %1,%0
3445         lds.l   %1,%0
3446         sts.l   %1,%0
3447         fake    %1,%0
3448         lds     %1,%0
3449         sts     %1,%0
3450         fsts    fpul,%0
3451         flds    %1,fpul
3452         fmov    %1,%0
3453         ! move optimized away"
3454   [(set_attr "type" "pcload_si,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")
3455    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3456    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3457
3458 (define_insn "movsi_i_lowpart"
3459   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3460         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3461    "TARGET_SH1
3462     && (register_operand (operands[0], SImode)
3463         || register_operand (operands[1], SImode))"
3464   "@
3465         mov.l   %1,%0
3466         mov     %1,%0
3467         mov.l   %1,%0
3468         sts     %1,%0
3469         sts     %1,%0
3470         movt    %0
3471         mov.l   %1,%0
3472         fake    %1,%0"
3473   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3474
3475 (define_insn_and_split "load_ra"
3476   [(set (match_operand:SI 0 "general_movdst_operand" "")
3477         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3478   "TARGET_SH1"
3479   "#"
3480   "&& ! rtx_equal_function_value_matters"
3481   [(set (match_dup 0) (match_dup 1))]
3482   "
3483 {
3484   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3485     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3486 }")
3487
3488 (define_insn "*movsi_media"
3489   [(set (match_operand:SI 0 "general_movdst_operand"
3490                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3491         (match_operand:SI 1 "general_movsrc_operand"
3492          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3493   "TARGET_SHMEDIA_FPU
3494    && (register_operand (operands[0], SImode)
3495        || sh_register_operand (operands[1], SImode))"
3496   "@
3497         add.l   %1, r63, %0
3498         movi    %1, %0
3499         #
3500         ld%M1.l %m1, %0
3501         st%M0.l %m0, %N1
3502         fld%M1.s        %m1, %0
3503         fst%M0.s        %m0, %1
3504         fmov.ls %N1, %0
3505         fmov.sl %1, %0
3506         fmov.s  %1, %0
3507         ptabs   %1, %0
3508         gettr   %1, %0
3509         pt      %1, %0"
3510   [(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")
3511    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3512
3513 (define_insn "*movsi_media_nofpu"
3514   [(set (match_operand:SI 0 "general_movdst_operand"
3515                 "=r,r,r,r,m,*b,r,b")
3516         (match_operand:SI 1 "general_movsrc_operand"
3517          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3518   "TARGET_SHMEDIA
3519    && (register_operand (operands[0], SImode)
3520        || sh_register_operand (operands[1], SImode))"
3521   "@
3522         add.l   %1, r63, %0
3523         movi    %1, %0
3524         #
3525         ld%M1.l %m1, %0
3526         st%M0.l %m0, %N1
3527         ptabs   %1, %0
3528         gettr   %1, %0
3529         pt      %1, %0"
3530   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3531    (set_attr "length" "4,4,8,4,4,4,4,12")])
3532
3533 (define_split
3534   [(set (match_operand:SI 0 "arith_reg_operand" "")
3535         (match_operand:SI 1 "immediate_operand" ""))]
3536   "TARGET_SHMEDIA && reload_completed
3537    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3538   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3539   "
3540 {
3541   operands[2] = shallow_copy_rtx (operands[1]);
3542   PUT_MODE (operands[2], DImode);
3543 }")
3544
3545 (define_split
3546   [(set (match_operand:SI 0 "register_operand" "")
3547         (match_operand:SI 1 "immediate_operand" ""))]
3548   "TARGET_SHMEDIA && reload_completed
3549    && ((GET_CODE (operands[1]) == CONST_INT
3550         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3551        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3552   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3553
3554 (define_expand "movsi"
3555   [(set (match_operand:SI 0 "general_movdst_operand" "")
3556         (match_operand:SI 1 "general_movsrc_operand" ""))]
3557   ""
3558   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3559
3560 (define_expand "ic_invalidate_line"
3561   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3562                                 (match_dup 1)] UNSPEC_ICACHE)
3563               (clobber (scratch:SI))])]
3564   "TARGET_HARD_SH4 || TARGET_SH5"
3565   "
3566 {
3567   if (TARGET_SHMEDIA)
3568     {
3569       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3570       DONE;
3571     }
3572   else if (TARGET_SHCOMPACT)
3573     {
3574       operands[1] = function_symbol (\"__ic_invalidate\");
3575       operands[1] = force_reg (Pmode, operands[1]);
3576       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3577       DONE;
3578     }
3579   operands[0] = force_reg (Pmode, operands[0]);
3580   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3581                                                                Pmode)));
3582 }")
3583
3584 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3585 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3586 ;; the requirement *1*00 for associative address writes.  The alignment of
3587 ;; %0 implies that its least significant bit is cleared,
3588 ;; thus we clear the V bit of a matching entry if there is one.
3589 (define_insn "ic_invalidate_line_i"
3590   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3591                      (match_operand:SI 1 "register_operand" "r")]
3592                      UNSPEC_ICACHE)
3593    (clobber (match_scratch:SI 2 "=&r"))]
3594   "TARGET_HARD_SH4"
3595   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3596   [(set_attr "length" "8")
3597    (set_attr "type" "cwb")])
3598
3599 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3600 ;; an add in the code that calculates the address.
3601 (define_insn "ic_invalidate_line_media"
3602   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3603                     UNSPEC_ICACHE)]
3604   "TARGET_SHMEDIA"
3605   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3606   [(set_attr "length" "16")
3607    (set_attr "type" "invalidate_line_media")])
3608
3609 (define_insn "ic_invalidate_line_compact"
3610   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3611                      (match_operand:SI 1 "register_operand" "r")]
3612                     UNSPEC_ICACHE)
3613    (clobber (reg:SI PR_REG))]
3614   "TARGET_SHCOMPACT"
3615   "jsr @%1%#"
3616   [(set_attr "type" "sfunc")
3617    (set_attr "needs_delay_slot" "yes")])
3618
3619 (define_expand "initialize_trampoline"
3620   [(match_operand:SI 0 "" "")
3621    (match_operand:SI 1 "" "")
3622    (match_operand:SI 2 "" "")]
3623   "TARGET_SHCOMPACT"
3624   "
3625 {
3626   rtx sfun, tramp;
3627
3628   tramp = force_reg (Pmode, operands[0]);
3629   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3630   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3631   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3632
3633   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3634   DONE;
3635 }")
3636
3637 (define_insn "initialize_trampoline_compact"
3638   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3639                      (match_operand:SI 1 "register_operand" "r")
3640                      (reg:SI R2_REG) (reg:SI R3_REG)]
3641                     UNSPEC_INIT_TRAMP)
3642
3643    (clobber (reg:SI PR_REG))]
3644   "TARGET_SHCOMPACT"
3645   "jsr @%1%#"
3646   [(set_attr "type" "sfunc")
3647    (set_attr "needs_delay_slot" "yes")])
3648
3649 (define_insn "movqi_i"
3650   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3651         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3652   "TARGET_SH1
3653    && (arith_reg_operand (operands[0], QImode)
3654        || arith_reg_operand (operands[1], QImode))"
3655   "@
3656         mov     %1,%0
3657         mov.b   %1,%0
3658         mov.b   %1,%0
3659         movt    %0
3660         sts     %1,%0
3661         lds     %1,%0"
3662  [(set_attr "type" "move,load,store,move,move,move")])
3663
3664 (define_insn "*movqi_media"
3665   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3666         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3667   "TARGET_SHMEDIA
3668    && (arith_reg_operand (operands[0], QImode)
3669        || arith_reg_or_0_operand (operands[1], QImode))"
3670   "@
3671         add.l   %1, r63, %0
3672         movi    %1, %0
3673         ld%M1.ub        %m1, %0
3674         st%M0.b %m0, %N1"
3675   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3676
3677 (define_expand "movqi"
3678   [(set (match_operand:QI 0 "general_operand" "")
3679         (match_operand:QI 1 "general_operand"  ""))]
3680   ""
3681   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3682
3683 (define_expand "reload_inqi"
3684   [(set (match_operand:SI 2 "" "=&r")
3685         (match_operand:QI 1 "inqhi_operand" ""))
3686    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3687         (truncate:QI (match_dup 3)))]
3688   "TARGET_SHMEDIA"
3689   "
3690 {
3691   rtx inner = XEXP (operands[1], 0);
3692   int regno = REGNO (inner);
3693
3694   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3695   operands[1] = gen_rtx_REG (SImode, regno);
3696   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3697 }")
3698
3699 /* When storing r0, we have to avoid reg+reg addressing.  */
3700 (define_insn "movhi_i"
3701   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3702         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3703   "TARGET_SH1
3704    && (arith_reg_operand (operands[0], HImode)
3705        || arith_reg_operand (operands[1], HImode))
3706    && (GET_CODE (operands[0]) != MEM
3707        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3708        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3709        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3710   "@
3711         mov.w   %1,%0
3712         mov     %1,%0
3713         mov.w   %1,%0
3714         movt    %0
3715         mov.w   %1,%0
3716         sts     %1,%0
3717         lds     %1,%0
3718         fake    %1,%0"
3719   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3720
3721 (define_insn "*movhi_media"
3722   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3723         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3724   "TARGET_SHMEDIA
3725    && (arith_reg_operand (operands[0], HImode)
3726        || arith_reg_or_0_operand (operands[1], HImode))"
3727   "@
3728         add.l   %1, r63, %0
3729         movi    %1, %0
3730         #
3731         ld%M1.w %m1, %0
3732         st%M0.w %m0, %N1"
3733   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3734
3735 (define_split
3736   [(set (match_operand:HI 0 "register_operand" "")
3737         (match_operand:HI 1 "immediate_operand" ""))]
3738   "TARGET_SHMEDIA && reload_completed
3739    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3740   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3741
3742 (define_expand "movhi"
3743   [(set (match_operand:HI 0 "general_movdst_operand" "")
3744         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3745   ""
3746   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3747
3748 (define_expand "reload_inhi"
3749   [(set (match_operand:SI 2 "" "=&r")
3750         (match_operand:HI 1 "inqhi_operand" ""))
3751    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3752         (truncate:HI (match_dup 3)))]
3753   "TARGET_SHMEDIA"
3754   "
3755 {
3756   rtx inner = XEXP (operands[1], 0);
3757   int regno = REGNO (inner);
3758
3759   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3760   operands[1] = gen_rtx_REG (SImode, regno);
3761   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3762 }")
3763
3764 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3765 ;; compiled with -m2 -ml -O3 -funroll-loops
3766 (define_insn "*movdi_i"
3767   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3768         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3769   "TARGET_SH1
3770    && (arith_reg_operand (operands[0], DImode)
3771        || arith_reg_operand (operands[1], DImode))"
3772   "* return output_movedouble (insn, operands, DImode);"
3773   [(set_attr "length" "4")
3774    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3775
3776 ;; If the output is a register and the input is memory or a register, we have
3777 ;; to be careful and see which word needs to be loaded first.
3778
3779 (define_split
3780   [(set (match_operand:DI 0 "general_movdst_operand" "")
3781         (match_operand:DI 1 "general_movsrc_operand" ""))]
3782   "TARGET_SH1 && reload_completed"
3783   [(set (match_dup 2) (match_dup 3))
3784    (set (match_dup 4) (match_dup 5))]
3785   "
3786 {
3787   int regno;
3788
3789   if ((GET_CODE (operands[0]) == MEM
3790        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3791       || (GET_CODE (operands[1]) == MEM
3792           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3793     FAIL;
3794
3795   if (GET_CODE (operands[0]) == REG)
3796     regno = REGNO (operands[0]);
3797   else if (GET_CODE (operands[0]) == SUBREG)
3798     regno = subreg_regno (operands[0]);
3799   else if (GET_CODE (operands[0]) == MEM)
3800     regno = -1;
3801   else
3802     abort ();
3803
3804   if (regno == -1
3805       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3806     {
3807       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3808       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3809       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3810       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3811     }
3812   else
3813     {
3814       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3815       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3816       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3817       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3818     }
3819
3820   if (operands[2] == 0 || operands[3] == 0
3821       || operands[4] == 0 || operands[5] == 0)
3822     FAIL;
3823 }")
3824
3825 (define_insn "*movdi_media"
3826   [(set (match_operand:DI 0 "general_movdst_operand"
3827                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3828         (match_operand:DI 1 "general_movsrc_operand"
3829          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3830   "TARGET_SHMEDIA_FPU
3831    && (register_operand (operands[0], DImode)
3832        || sh_register_operand (operands[1], DImode))"
3833   "@
3834         add     %1, r63, %0
3835         movi    %1, %0
3836         #
3837         ld%M1.q %m1, %0
3838         st%M0.q %m0, %N1
3839         fld%M1.d        %m1, %0
3840         fst%M0.d        %m0, %1
3841         fmov.qd %N1, %0
3842         fmov.dq %1, %0
3843         fmov.d  %1, %0
3844         ptabs   %1, %0
3845         gettr   %1, %0
3846         pt      %1, %0"
3847   [(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")
3848    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3849
3850 (define_insn "*movdi_media_nofpu"
3851   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3852         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3853   "TARGET_SHMEDIA
3854    && (register_operand (operands[0], DImode)
3855        || sh_register_operand (operands[1], DImode))"
3856   "@
3857         add     %1, r63, %0
3858         movi    %1, %0
3859         #
3860         ld%M1.q %m1, %0
3861         st%M0.q %m0, %N1
3862         ptabs   %1, %0
3863         gettr   %1, %0
3864         pt      %1, %0"
3865   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3866    (set_attr "length" "4,4,16,4,4,4,4,*")])
3867
3868 (define_split
3869   [(set (match_operand:DI 0 "arith_reg_operand" "")
3870         (match_operand:DI 1 "immediate_operand" ""))]
3871   "TARGET_SHMEDIA && reload_completed
3872    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3873   [(set (match_dup 0) (match_dup 1))]
3874   "
3875 {
3876   rtx insn;
3877
3878   if (TARGET_SHMEDIA64)
3879     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3880   else
3881     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3882
3883   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3884                                         REG_NOTES (insn));
3885
3886   DONE;
3887 }")
3888
3889 (define_expand "movdi_const"
3890   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3891         (const:DI (sign_extend:DI
3892                    (truncate:HI
3893                     (ashiftrt:DI
3894                      (match_operand:DI 1 "immediate_operand" "s")
3895                      (const_int 48))))))
3896    (set (match_dup 0)
3897         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3898                 (zero_extend:DI
3899                  (truncate:HI
3900                   (const:DI
3901                    (sign_extend:DI
3902                     (truncate:HI
3903                      (ashiftrt:SI
3904                       (match_dup 1)
3905                       (const_int 32)))))))))
3906    (set (match_dup 0)
3907         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3908                 (zero_extend:DI
3909                  (truncate:HI
3910                   (const:DI
3911                    (sign_extend:DI
3912                     (truncate:HI
3913                      (ashiftrt:SI
3914                       (match_dup 1)
3915                       (const_int 16)))))))))
3916    (set (match_dup 0)
3917         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3918                 (zero_extend:DI
3919                  (truncate:HI
3920                   (const:DI
3921                    (sign_extend:DI
3922                     (truncate:HI
3923                      (match_dup 1))))))))]
3924   "TARGET_SHMEDIA64 && reload_completed
3925    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3926   "
3927 {
3928   sh_mark_label (operands[1], 4);
3929 }")
3930
3931 (define_expand "movdi_const_32bit"
3932   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3933         (const:DI (sign_extend:DI
3934                    (truncate:HI
3935                     (ashiftrt:DI
3936                      (match_operand:DI 1 "immediate_operand" "s")
3937                      (const_int 16))))))
3938    (set (match_dup 0)
3939         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3940                 (zero_extend:DI
3941                  (truncate:HI
3942                   (const:DI
3943                    (sign_extend:DI
3944                     (truncate:HI
3945                      (match_dup 1))))))))]
3946   "TARGET_SHMEDIA32 && reload_completed
3947    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3948   "
3949 {
3950   sh_mark_label (operands[1], 2);
3951 }")
3952
3953 (define_expand "movdi_const_16bit"
3954   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3955         (const:DI (sign_extend:DI
3956                    (truncate:HI
3957                     (match_operand:DI 1 "immediate_operand" "s")))))]
3958   "TARGET_SHMEDIA && flag_pic && reload_completed
3959    && GET_CODE (operands[1]) == SYMBOL_REF"
3960   "")
3961
3962 (define_split
3963   [(set (match_operand:DI 0 "arith_reg_operand" "")
3964         (match_operand:DI 1 "immediate_operand" ""))]
3965   "TARGET_SHMEDIA && reload_completed
3966    && GET_CODE (operands[1]) == CONST_INT
3967    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3968   [(set (match_dup 0) (match_dup 2))
3969    (match_dup 1)]
3970   "
3971 {
3972   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3973   unsigned HOST_WIDE_INT low = val;
3974   unsigned HOST_WIDE_INT high = val;
3975   unsigned HOST_WIDE_INT sign;
3976   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3977
3978   /* Sign-extend the 16 least-significant bits.  */
3979   low &= 0xffff;
3980   low ^= 0x8000;
3981   low -= 0x8000;
3982
3983   /* Arithmetic shift right the word by 16 bits.  */
3984   high >>= 16;
3985   sign = 1;
3986   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3987   high ^= sign;
3988   high -= sign;
3989   do
3990     {
3991       /* If we can't generate the constant with a two-insn movi / shori
3992          sequence, try some other strategies.  */
3993       if (! CONST_OK_FOR_I16 (high))
3994         {
3995           /* Try constant load / left shift.  We know VAL != 0.  */
3996           val2 = val ^ (val-1);
3997           if (val2 > 0x1ffff)
3998             {
3999               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4000
4001               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4002                   || (! CONST_OK_FOR_I16 (high >> 16)
4003                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4004                 {
4005                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4006                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4007                                                    GEN_INT (trailing_zeroes));
4008                   break;
4009                 }
4010             }
4011           /* Try constant load / right shift.  */
4012           val2 = (val >> 15) + 1;
4013           if (val2 == (val2 & -val2))
4014             {
4015               int shift = 49 - exact_log2 (val2);
4016
4017               val2 = trunc_int_for_mode (val << shift, DImode);
4018               if (CONST_OK_FOR_I16 (val2))
4019                 {
4020                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4021                                                    GEN_INT (shift));
4022                   break;
4023                 }
4024             }
4025           /* Try mperm.w .  */
4026           val2 = val & 0xffff;
4027           if ((val >> 16 & 0xffff) == val2
4028               && (val >> 32 & 0xffff) == val2
4029               && (val >> 48 & 0xffff) == val2)
4030             {
4031               val2 = (HOST_WIDE_INT) val >> 48;
4032               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4033               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4034               break;
4035             }
4036           /* Try movi / mshflo.l  */
4037           val2 = (HOST_WIDE_INT) val >> 32;
4038           if (val2 == 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                                              GEN_INT (0));
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 || 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
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 2) (const_int 6))
4223       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (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 && 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
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 && 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 "X"))]
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 "X"))]
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_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_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_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)
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 * 2);
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 * 2);
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,*,*,*,*,*,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
5567 ;; This is a pc-rel call, using bsrf, for use with PIC.
5568
5569 (define_insn "calli_pcrel"
5570   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5571          (match_operand 1 "" ""))
5572    (use (reg:PSI FPSCR_REG))
5573    (use (reg:SI PIC_REG))
5574    (use (match_operand 2 "" ""))
5575    (clobber (reg:SI PR_REG))]
5576   "TARGET_SH2"
5577   "bsrf %0\\n%O2:%#"
5578   [(set_attr "type" "call")
5579    (set (attr "fp_mode")
5580         (if_then_else (eq_attr "fpu_single" "yes")
5581                       (const_string "single") (const_string "double")))
5582    (set_attr "needs_delay_slot" "yes")])
5583
5584 (define_insn_and_split "call_pcrel"
5585   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5586          (match_operand 1 "" ""))
5587    (use (reg:PSI FPSCR_REG))
5588    (use (reg:SI PIC_REG))
5589    (clobber (reg:SI PR_REG))
5590    (clobber (match_scratch:SI 2 "=r"))]
5591   "TARGET_SH2"
5592   "#"
5593   "reload_completed"
5594   [(const_int 0)]
5595   "
5596 {
5597   rtx lab = PATTERN (gen_call_site ());
5598
5599   if (SYMBOL_REF_LOCAL_P (operands[0]))
5600     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5601   else
5602     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5603   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5604   DONE;
5605 }"
5606   [(set_attr "type" "call")
5607    (set (attr "fp_mode")
5608         (if_then_else (eq_attr "fpu_single" "yes")
5609                       (const_string "single") (const_string "double")))
5610    (set_attr "needs_delay_slot" "yes")])
5611
5612 (define_insn "call_compact"
5613   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5614          (match_operand 1 "" ""))
5615    (match_operand 2 "immediate_operand" "n")
5616    (use (reg:SI R0_REG))
5617    (use (reg:SI R1_REG))
5618    (use (reg:PSI FPSCR_REG))
5619    (clobber (reg:SI PR_REG))]
5620   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5621   "jsr  @%0%#"
5622   [(set_attr "type" "call")
5623    (set (attr "fp_mode")
5624         (if_then_else (eq_attr "fpu_single" "yes")
5625                       (const_string "single") (const_string "double")))
5626    (set_attr "needs_delay_slot" "yes")])
5627
5628 (define_insn "call_compact_rettramp"
5629   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5630          (match_operand 1 "" ""))
5631    (match_operand 2 "immediate_operand" "n")
5632    (use (reg:SI R0_REG))
5633    (use (reg:SI R1_REG))
5634    (use (reg:PSI FPSCR_REG))
5635    (clobber (reg:SI R10_REG))
5636    (clobber (reg:SI PR_REG))]
5637   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5638   "jsr  @%0%#"
5639   [(set_attr "type" "call")
5640    (set (attr "fp_mode")
5641         (if_then_else (eq_attr "fpu_single" "yes")
5642                       (const_string "single") (const_string "double")))
5643    (set_attr "needs_delay_slot" "yes")])
5644
5645 (define_insn "call_media"
5646   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5647          (match_operand 1 "" ""))
5648    (clobber (reg:DI PR_MEDIA_REG))]
5649   "TARGET_SHMEDIA"
5650   "blink        %0, r18"
5651   [(set_attr "type" "jump_media")])
5652
5653 (define_insn "call_valuei"
5654   [(set (match_operand 0 "" "=rf")
5655         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5656               (match_operand 2 "" "")))
5657    (use (reg:PSI FPSCR_REG))
5658    (clobber (reg:SI PR_REG))]
5659   "TARGET_SH1"
5660   "jsr  @%1%#"
5661   [(set_attr "type" "call")
5662    (set (attr "fp_mode")
5663         (if_then_else (eq_attr "fpu_single" "yes")
5664                       (const_string "single") (const_string "double")))
5665    (set_attr "needs_delay_slot" "yes")])
5666
5667 (define_insn "call_valuei_pcrel"
5668   [(set (match_operand 0 "" "=rf")
5669         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5670               (match_operand 2 "" "")))
5671    (use (reg:PSI FPSCR_REG))
5672    (use (reg:SI PIC_REG))
5673    (use (match_operand 3 "" ""))
5674    (clobber (reg:SI PR_REG))]
5675   "TARGET_SH2"
5676   "bsrf %1\\n%O3:%#"
5677   [(set_attr "type" "call")
5678    (set (attr "fp_mode")
5679         (if_then_else (eq_attr "fpu_single" "yes")
5680                       (const_string "single") (const_string "double")))
5681    (set_attr "needs_delay_slot" "yes")])
5682
5683 (define_insn_and_split "call_value_pcrel"
5684   [(set (match_operand 0 "" "=rf")
5685         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5686               (match_operand 2 "" "")))
5687    (use (reg:PSI FPSCR_REG))
5688    (use (reg:SI PIC_REG))
5689    (clobber (reg:SI PR_REG))
5690    (clobber (match_scratch:SI 3 "=r"))]
5691   "TARGET_SH2"
5692   "#"
5693   "reload_completed"
5694   [(const_int 0)]
5695   "
5696 {
5697   rtx lab = PATTERN (gen_call_site ());
5698
5699   if (SYMBOL_REF_LOCAL_P (operands[1]))
5700     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5701   else
5702     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5703   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5704                                          operands[2], lab));
5705   DONE;
5706 }"
5707   [(set_attr "type" "call")
5708    (set (attr "fp_mode")
5709         (if_then_else (eq_attr "fpu_single" "yes")
5710                       (const_string "single") (const_string "double")))
5711    (set_attr "needs_delay_slot" "yes")])
5712
5713 (define_insn "call_value_compact"
5714   [(set (match_operand 0 "" "=rf")
5715         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5716               (match_operand 2 "" "")))
5717    (match_operand 3 "immediate_operand" "n")
5718    (use (reg:SI R0_REG))
5719    (use (reg:SI R1_REG))
5720    (use (reg:PSI FPSCR_REG))
5721    (clobber (reg:SI PR_REG))]
5722   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5723   "jsr  @%1%#"
5724   [(set_attr "type" "call")
5725    (set (attr "fp_mode")
5726         (if_then_else (eq_attr "fpu_single" "yes")
5727                       (const_string "single") (const_string "double")))
5728    (set_attr "needs_delay_slot" "yes")])
5729
5730 (define_insn "call_value_compact_rettramp"
5731   [(set (match_operand 0 "" "=rf")
5732         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5733               (match_operand 2 "" "")))
5734    (match_operand 3 "immediate_operand" "n")
5735    (use (reg:SI R0_REG))
5736    (use (reg:SI R1_REG))
5737    (use (reg:PSI FPSCR_REG))
5738    (clobber (reg:SI R10_REG))
5739    (clobber (reg:SI PR_REG))]
5740   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5741   "jsr  @%1%#"
5742   [(set_attr "type" "call")
5743    (set (attr "fp_mode")
5744         (if_then_else (eq_attr "fpu_single" "yes")
5745                       (const_string "single") (const_string "double")))
5746    (set_attr "needs_delay_slot" "yes")])
5747
5748 (define_insn "call_value_media"
5749   [(set (match_operand 0 "" "=rf")
5750         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5751               (match_operand 2 "" "")))
5752    (clobber (reg:DI PR_MEDIA_REG))]
5753   "TARGET_SHMEDIA"
5754   "blink        %1, r18"
5755   [(set_attr "type" "jump_media")])
5756
5757 (define_expand "call"
5758   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5759                             (match_operand 1 "" ""))
5760               (match_operand 2 "" "")
5761               (use (reg:PSI FPSCR_REG))
5762               (clobber (reg:SI PR_REG))])]
5763   ""
5764   "
5765 {
5766   if (TARGET_SHMEDIA)
5767     {
5768       operands[0] = XEXP (operands[0], 0);
5769       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5770         {
5771           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5772             {
5773               rtx reg = gen_reg_rtx (Pmode);
5774
5775               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5776               operands[0] = reg;
5777             }
5778           else
5779             {
5780               operands[0] = gen_sym2PIC (operands[0]);
5781               PUT_MODE (operands[0], Pmode);
5782             }
5783         }
5784       if (GET_MODE (operands[0]) == SImode)
5785         {
5786           if (GET_CODE (operands[0]) == REG)
5787             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5788           else if (GET_CODE (operands[0]) == SUBREG)
5789             {
5790               operands[0] = SUBREG_REG (operands[0]);
5791               if (GET_MODE (operands[0]) != DImode)
5792                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5793             }
5794           else
5795             {
5796               operands[0] = shallow_copy_rtx (operands[0]);
5797               PUT_MODE (operands[0], DImode);
5798             }
5799         }
5800       if (! target_reg_operand (operands[0], DImode))
5801         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5802       emit_call_insn (gen_call_media (operands[0], operands[1]));
5803       DONE;
5804     }
5805   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5806     {
5807       rtx cookie_rtx = operands[2];
5808       long cookie = INTVAL (cookie_rtx);
5809       rtx func = XEXP (operands[0], 0);
5810       rtx r0, r1;
5811
5812       if (flag_pic)
5813         {
5814           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5815             {
5816               rtx reg = gen_reg_rtx (Pmode);
5817
5818               emit_insn (gen_symGOTPLT2reg (reg, func));
5819               func = reg;
5820             }
5821           else
5822             func = legitimize_pic_address (func, Pmode, 0);
5823         }
5824
5825       r0 = gen_rtx_REG (SImode, R0_REG);
5826       r1 = gen_rtx_REG (SImode, R1_REG);
5827
5828       /* Since such a call function may use all call-clobbered
5829          registers, we force a mode switch earlier, so that we don't
5830          run out of registers when adjusting fpscr for the call.  */
5831       emit_insn (gen_force_mode_for_call ());
5832
5833       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5834       if (flag_pic)
5835         {
5836           rtx reg = gen_reg_rtx (Pmode);
5837
5838           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5839           operands[0] = reg;
5840         }
5841       operands[0] = force_reg (SImode, operands[0]);
5842
5843       emit_move_insn (r0, func);
5844       emit_move_insn (r1, cookie_rtx);
5845
5846       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5847         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5848                                                    operands[2]));
5849       else
5850         emit_call_insn (gen_call_compact (operands[0], operands[1],
5851                                           operands[2]));
5852
5853       DONE;
5854     }
5855   else if (TARGET_SHCOMPACT && flag_pic
5856            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5857            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5858     {
5859       rtx reg = gen_reg_rtx (Pmode);
5860
5861       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5862       XEXP (operands[0], 0) = reg;
5863     }
5864   if (flag_pic && TARGET_SH2
5865       && GET_CODE (operands[0]) == MEM
5866       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5867     {
5868       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5869       DONE;
5870     }
5871   else
5872   {
5873     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5874     operands[1] = operands[2];
5875   }
5876
5877   emit_call_insn (gen_calli (operands[0], operands[1]));
5878   DONE;
5879 }")
5880
5881 (define_insn "call_pop_compact"
5882   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5883          (match_operand 1 "" ""))
5884    (match_operand 2 "immediate_operand" "n")
5885    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5886                                  (match_operand 3 "immediate_operand" "n")))
5887    (use (reg:SI R0_REG))
5888    (use (reg:SI R1_REG))
5889    (use (reg:PSI FPSCR_REG))
5890    (clobber (reg:SI PR_REG))]
5891   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5892   "jsr  @%0%#"
5893   [(set_attr "type" "call")
5894    (set (attr "fp_mode")
5895         (if_then_else (eq_attr "fpu_single" "yes")
5896                       (const_string "single") (const_string "double")))
5897    (set_attr "needs_delay_slot" "yes")])
5898
5899 (define_insn "call_pop_compact_rettramp"
5900   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5901          (match_operand 1 "" ""))
5902    (match_operand 2 "immediate_operand" "n")
5903    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5904                                  (match_operand 3 "immediate_operand" "n")))
5905    (use (reg:SI R0_REG))
5906    (use (reg:SI R1_REG))
5907    (use (reg:PSI FPSCR_REG))
5908    (clobber (reg:SI R10_REG))
5909    (clobber (reg:SI PR_REG))]
5910   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5911   "jsr  @%0%#"
5912   [(set_attr "type" "call")
5913    (set (attr "fp_mode")
5914         (if_then_else (eq_attr "fpu_single" "yes")
5915                       (const_string "single") (const_string "double")))
5916    (set_attr "needs_delay_slot" "yes")])
5917
5918 (define_expand "call_pop"
5919   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5920                     (match_operand 1 "" ""))
5921              (match_operand 2 "" "")
5922              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5923                                            (match_operand 3 "" "")))])]
5924   "TARGET_SHCOMPACT"
5925   "
5926 {
5927   if (operands[2] && INTVAL (operands[2]))
5928     {
5929       rtx cookie_rtx = operands[2];
5930       long cookie = INTVAL (cookie_rtx);
5931       rtx func = XEXP (operands[0], 0);
5932       rtx r0, r1;
5933
5934       if (flag_pic)
5935         {
5936           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5937             {
5938               rtx reg = gen_reg_rtx (Pmode);
5939
5940               emit_insn (gen_symGOTPLT2reg (reg, func));
5941               func = reg;
5942             }
5943           else
5944             func = legitimize_pic_address (func, Pmode, 0);
5945         }
5946
5947       r0 = gen_rtx_REG (SImode, R0_REG);
5948       r1 = gen_rtx_REG (SImode, R1_REG);
5949
5950       /* Since such a call function may use all call-clobbered
5951          registers, we force a mode switch earlier, so that we don't
5952          run out of registers when adjusting fpscr for the call.  */
5953       emit_insn (gen_force_mode_for_call ());
5954
5955       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5956       if (flag_pic)
5957         {
5958           rtx reg = gen_reg_rtx (Pmode);
5959
5960           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5961           operands[0] = reg;
5962         }
5963       operands[0] = force_reg (SImode, operands[0]);
5964
5965       emit_move_insn (r0, func);
5966       emit_move_insn (r1, cookie_rtx);
5967
5968       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5969         emit_call_insn (gen_call_pop_compact_rettramp
5970                         (operands[0], operands[1], operands[2], operands[3]));
5971       else
5972         emit_call_insn (gen_call_pop_compact
5973                         (operands[0], operands[1], operands[2], operands[3]));
5974
5975       DONE;
5976     }
5977
5978   abort ();
5979 }")
5980
5981 (define_expand "call_value"
5982   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5983                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5984                                  (match_operand 2 "" "")))
5985               (match_operand 3 "" "")
5986               (use (reg:PSI FPSCR_REG))
5987               (clobber (reg:SI PR_REG))])]
5988   ""
5989   "
5990 {
5991   if (TARGET_SHMEDIA)
5992     {
5993       operands[1] = XEXP (operands[1], 0);
5994       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5995         {
5996           if (! SYMBOL_REF_LOCAL_P (operands[1]))
5997             {
5998               rtx reg = gen_reg_rtx (Pmode);
5999
6000               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6001               operands[1] = reg;
6002             }
6003           else
6004             {
6005               operands[1] = gen_sym2PIC (operands[1]);
6006               PUT_MODE (operands[1], Pmode);
6007             }
6008         }
6009       if (GET_MODE (operands[1]) == SImode)
6010         {
6011           if (GET_CODE (operands[1]) == REG)
6012             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6013           else if (GET_CODE (operands[1]) == SUBREG)
6014             {
6015               operands[1] = SUBREG_REG (operands[1]);
6016               if (GET_MODE (operands[1]) != DImode)
6017                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6018             }
6019           else
6020             {
6021               operands[1] = shallow_copy_rtx (operands[1]);
6022               PUT_MODE (operands[1], DImode);
6023             }
6024         }
6025       if (! target_reg_operand (operands[1], DImode))
6026         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6027       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6028                                             operands[2]));
6029       DONE;
6030     }
6031   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6032     {
6033       rtx cookie_rtx = operands[3];
6034       long cookie = INTVAL (cookie_rtx);
6035       rtx func = XEXP (operands[1], 0);
6036       rtx r0, r1;
6037
6038       if (flag_pic)
6039         {
6040           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6041             {
6042               rtx reg = gen_reg_rtx (Pmode);
6043
6044               emit_insn (gen_symGOTPLT2reg (reg, func));
6045               func = reg;
6046             }
6047           else
6048             func = legitimize_pic_address (func, Pmode, 0);
6049         }
6050
6051       r0 = gen_rtx_REG (SImode, R0_REG);
6052       r1 = gen_rtx_REG (SImode, R1_REG);
6053
6054       /* Since such a call function may use all call-clobbered
6055          registers, we force a mode switch earlier, so that we don't
6056          run out of registers when adjusting fpscr for the call.  */
6057       emit_insn (gen_force_mode_for_call ());
6058
6059       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6060       if (flag_pic)
6061         {
6062           rtx reg = gen_reg_rtx (Pmode);
6063
6064           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6065           operands[1] = reg;
6066         }
6067       operands[1] = force_reg (SImode, operands[1]);
6068
6069       emit_move_insn (r0, func);
6070       emit_move_insn (r1, cookie_rtx);
6071
6072       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6073         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6074                                                          operands[1],
6075                                                          operands[2],
6076                                                          operands[3]));
6077       else
6078         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6079                                                 operands[2], operands[3]));
6080
6081       DONE;
6082     }
6083   else if (TARGET_SHCOMPACT && flag_pic
6084            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6085            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6086     {
6087       rtx reg = gen_reg_rtx (Pmode);
6088
6089       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6090       XEXP (operands[1], 0) = reg;
6091     }
6092   if (flag_pic && TARGET_SH2
6093       && GET_CODE (operands[1]) == MEM
6094       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6095     {
6096       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6097                                             operands[2]));
6098       DONE;
6099     }
6100   else
6101     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6102
6103   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6104   DONE;
6105 }")
6106
6107 (define_insn "sibcalli"
6108   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6109          (match_operand 1 "" ""))
6110    (use (reg:PSI FPSCR_REG))
6111    (return)]
6112   "TARGET_SH1"
6113   "jmp  @%0%#"
6114   [(set_attr "needs_delay_slot" "yes")
6115    (set (attr "fp_mode")
6116         (if_then_else (eq_attr "fpu_single" "yes")
6117                       (const_string "single") (const_string "double")))
6118    (set_attr "type" "jump_ind")])
6119
6120 (define_insn "sibcalli_pcrel"
6121   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6122          (match_operand 1 "" ""))
6123    (use (match_operand 2 "" ""))
6124    (use (reg:PSI FPSCR_REG))
6125    (return)]
6126   "TARGET_SH2"
6127   "braf %0\\n%O2:%#"
6128   [(set_attr "needs_delay_slot" "yes")
6129    (set (attr "fp_mode")
6130         (if_then_else (eq_attr "fpu_single" "yes")
6131                       (const_string "single") (const_string "double")))
6132    (set_attr "type" "jump_ind")])
6133
6134 (define_insn_and_split "sibcall_pcrel"
6135   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6136          (match_operand 1 "" ""))
6137    (use (reg:PSI FPSCR_REG))
6138    (clobber (match_scratch:SI 2 "=k"))
6139    (return)]
6140   "TARGET_SH2"
6141   "#"
6142   "reload_completed"
6143   [(const_int 0)]
6144   "
6145 {
6146   rtx lab = PATTERN (gen_call_site ());
6147   rtx call_insn;
6148
6149   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6150   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6151                                                   lab));
6152   SIBLING_CALL_P (call_insn) = 1;
6153   DONE;
6154 }"
6155   [(set_attr "needs_delay_slot" "yes")
6156    (set (attr "fp_mode")
6157         (if_then_else (eq_attr "fpu_single" "yes")
6158                       (const_string "single") (const_string "double")))
6159    (set_attr "type" "jump_ind")])
6160
6161 (define_insn "sibcall_compact"
6162   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6163          (match_operand 1 "" ""))
6164    (return)
6165    (use (match_operand:SI 2 "register_operand" "z,x"))
6166    (use (reg:SI R1_REG))
6167    (use (reg:PSI FPSCR_REG))
6168    ;; We want to make sure the `x' above will only match MACH_REG
6169    ;; because sibcall_epilogue may clobber MACL_REG.
6170    (clobber (reg:SI MACL_REG))]
6171   "TARGET_SHCOMPACT"
6172   "@
6173         jmp     @%0%#
6174         jmp     @%0\\n  sts     %2, r0"
6175   [(set_attr "needs_delay_slot" "yes,no")
6176    (set_attr "length" "2,4")
6177    (set (attr "fp_mode") (const_string "single"))
6178    (set_attr "type" "jump_ind")])
6179
6180 (define_insn "sibcall_media"
6181   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6182          (match_operand 1 "" ""))
6183    (use (reg:SI PR_MEDIA_REG))
6184    (return)]
6185   "TARGET_SHMEDIA"
6186   "blink        %0, r63"
6187   [(set_attr "type" "jump_media")])
6188
6189 (define_expand "sibcall"
6190   [(parallel
6191     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6192            (match_operand 1 "" ""))
6193      (match_operand 2 "" "")
6194      (use (reg:PSI FPSCR_REG))
6195      (return)])]
6196   ""
6197   "
6198 {
6199   if (TARGET_SHMEDIA)
6200     {
6201       operands[0] = XEXP (operands[0], 0);
6202       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6203         {
6204           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6205             {
6206               rtx reg = gen_reg_rtx (Pmode);
6207
6208               /* We must not use GOTPLT for sibcalls, because PIC_REG
6209                  must be restored before the PLT code gets to run.  */
6210               emit_insn (gen_symGOT2reg (reg, operands[0]));
6211               operands[0] = reg;
6212             }
6213           else
6214             {
6215               operands[0] = gen_sym2PIC (operands[0]);
6216               PUT_MODE (operands[0], Pmode);
6217             }
6218         }
6219       if (GET_MODE (operands[0]) == SImode)
6220         {
6221           if (GET_CODE (operands[0]) == REG)
6222             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6223           else if (GET_CODE (operands[0]) == SUBREG)
6224             {
6225               operands[0] = SUBREG_REG (operands[0]);
6226               if (GET_MODE (operands[0]) != DImode)
6227                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6228             }
6229           else
6230             {
6231               operands[0] = shallow_copy_rtx (operands[0]);
6232               PUT_MODE (operands[0], DImode);
6233             }
6234         }
6235       if (! target_reg_operand (operands[0], DImode))
6236         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6237       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6238       DONE;
6239     }
6240   else if (TARGET_SHCOMPACT && operands[2]
6241            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6242     {
6243       rtx cookie_rtx = operands[2];
6244       long cookie = INTVAL (cookie_rtx);
6245       rtx func = XEXP (operands[0], 0);
6246       rtx mach, r1;
6247
6248       if (flag_pic)
6249         {
6250           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6251             {
6252               rtx reg = gen_reg_rtx (Pmode);
6253
6254               emit_insn (gen_symGOT2reg (reg, func));
6255               func = reg;
6256             }
6257           else
6258             func = legitimize_pic_address (func, Pmode, 0);
6259         }
6260
6261       /* FIXME: if we could tell whether all argument registers are
6262          already taken, we could decide whether to force the use of
6263          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6264          simple way to tell.  We could use the CALL_COOKIE, but we
6265          can't currently tell a register used for regular argument
6266          passing from one that is unused.  If we leave it up to reload
6267          to decide which register to use, it seems to always choose
6268          R0_REG, which leaves no available registers in SIBCALL_REGS
6269          to hold the address of the trampoline.  */
6270       mach = gen_rtx_REG (SImode, MACH_REG);
6271       r1 = gen_rtx_REG (SImode, R1_REG);
6272
6273       /* Since such a call function may use all call-clobbered
6274          registers, we force a mode switch earlier, so that we don't
6275          run out of registers when adjusting fpscr for the call.  */
6276       emit_insn (gen_force_mode_for_call ());
6277
6278       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6279       if (flag_pic)
6280         {
6281           rtx reg = gen_reg_rtx (Pmode);
6282
6283           emit_insn (gen_symGOT2reg (reg, operands[0]));
6284           operands[0] = reg;
6285         }
6286       operands[0] = force_reg (SImode, operands[0]);
6287
6288       /* We don't need a return trampoline, since the callee will
6289          return directly to the upper caller.  */
6290       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6291         {
6292           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6293           cookie_rtx = GEN_INT (cookie);
6294         }
6295
6296       emit_move_insn (mach, func);
6297       emit_move_insn (r1, cookie_rtx);
6298
6299       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6300       DONE;
6301     }
6302   else if (TARGET_SHCOMPACT && flag_pic
6303            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6304            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6305     {
6306       rtx reg = gen_reg_rtx (Pmode);
6307
6308       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6309       XEXP (operands[0], 0) = reg;
6310     }
6311   if (flag_pic && TARGET_SH2
6312       && GET_CODE (operands[0]) == MEM
6313       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6314       /* The PLT needs the PIC register, but the epilogue would have
6315          to restore it, so we can only use PC-relative PIC calls for
6316          static functions.  */
6317       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6318     {
6319       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6320       DONE;
6321     }
6322   else
6323     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6324
6325   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6326   DONE;
6327 }")
6328
6329 (define_expand "sibcall_value"
6330   [(set (match_operand 0 "" "")
6331         (call (match_operand 1 "" "")
6332               (match_operand 2 "" "")))
6333    (match_operand 3 "" "")]
6334   ""
6335   "
6336 {
6337   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6338   DONE;
6339 }")
6340
6341 (define_insn "call_value_pop_compact"
6342   [(set (match_operand 0 "" "=rf")
6343         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6344               (match_operand 2 "" "")))
6345    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6346                                  (match_operand 4 "immediate_operand" "n")))
6347    (match_operand 3 "immediate_operand" "n")
6348    (use (reg:SI R0_REG))
6349    (use (reg:SI R1_REG))
6350    (use (reg:PSI FPSCR_REG))
6351    (clobber (reg:SI PR_REG))]
6352   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6353   "jsr  @%1%#"
6354   [(set_attr "type" "call")
6355    (set (attr "fp_mode")
6356         (if_then_else (eq_attr "fpu_single" "yes")
6357                       (const_string "single") (const_string "double")))
6358    (set_attr "needs_delay_slot" "yes")])
6359
6360 (define_insn "call_value_pop_compact_rettramp"
6361   [(set (match_operand 0 "" "=rf")
6362         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6363               (match_operand 2 "" "")))
6364    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6365                                  (match_operand 4 "immediate_operand" "n")))
6366    (match_operand 3 "immediate_operand" "n")
6367    (use (reg:SI R0_REG))
6368    (use (reg:SI R1_REG))
6369    (use (reg:PSI FPSCR_REG))
6370    (clobber (reg:SI R10_REG))
6371    (clobber (reg:SI PR_REG))]
6372   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6373   "jsr  @%1%#"
6374   [(set_attr "type" "call")
6375    (set (attr "fp_mode")
6376         (if_then_else (eq_attr "fpu_single" "yes")
6377                       (const_string "single") (const_string "double")))
6378    (set_attr "needs_delay_slot" "yes")])
6379
6380 (define_expand "call_value_pop"
6381   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6382                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6383                                  (match_operand 2 "" "")))
6384               (match_operand 3 "" "")
6385               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6386                                             (match_operand 4 "" "")))])]
6387   "TARGET_SHCOMPACT"
6388   "
6389 {
6390   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6391     {
6392       rtx cookie_rtx = operands[3];
6393       long cookie = INTVAL (cookie_rtx);
6394       rtx func = XEXP (operands[1], 0);
6395       rtx r0, r1;
6396
6397       if (flag_pic)
6398         {
6399           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6400             {
6401               rtx reg = gen_reg_rtx (Pmode);
6402
6403               emit_insn (gen_symGOTPLT2reg (reg, func));
6404               func = reg;
6405             }
6406           else
6407             func = legitimize_pic_address (func, Pmode, 0);
6408         }
6409
6410       r0 = gen_rtx_REG (SImode, R0_REG);
6411       r1 = gen_rtx_REG (SImode, R1_REG);
6412
6413       /* Since such a call function may use all call-clobbered
6414          registers, we force a mode switch earlier, so that we don't
6415          run out of registers when adjusting fpscr for the call.  */
6416       emit_insn (gen_force_mode_for_call ());
6417
6418       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6419       if (flag_pic)
6420         {
6421           rtx reg = gen_reg_rtx (Pmode);
6422
6423           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6424           operands[1] = reg;
6425         }
6426       operands[1] = force_reg (SImode, operands[1]);
6427
6428       emit_move_insn (r0, func);
6429       emit_move_insn (r1, cookie_rtx);
6430
6431       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6432         emit_call_insn (gen_call_value_pop_compact_rettramp
6433                         (operands[0], operands[1], operands[2],
6434                          operands[3], operands[4]));
6435       else
6436         emit_call_insn (gen_call_value_pop_compact
6437                         (operands[0], operands[1], operands[2],
6438                          operands[3], operands[4]));
6439
6440       DONE;
6441     }
6442
6443   abort ();
6444 }")
6445
6446 (define_expand "sibcall_epilogue"
6447   [(return)]
6448   ""
6449   "
6450 {
6451   sh_expand_epilogue ();
6452   if (TARGET_SHCOMPACT)
6453     {
6454       rtx insn, set;
6455
6456       /* If epilogue clobbers r0, preserve it in macl.  */
6457       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6458         if ((set = single_set (insn))
6459             && GET_CODE (SET_DEST (set)) == REG
6460             && REGNO (SET_DEST (set)) == R0_REG)
6461           {
6462             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6463             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6464             rtx i;
6465
6466             /* We can't tell at this point whether the sibcall is a
6467                sibcall_compact and, if it is, whether it uses r0 or
6468                mach as operand 2, so let the instructions that
6469                preserve r0 be optimized away if r0 turns out to be
6470                dead.  */
6471             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6472             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6473                                                REG_NOTES (i));
6474             i = emit_move_insn (r0, tmp);
6475             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6476                                                REG_NOTES (i));
6477             break;
6478           }
6479     }
6480   DONE;
6481 }")
6482
6483 (define_insn "indirect_jump_compact"
6484   [(set (pc)
6485         (match_operand:SI 0 "arith_reg_operand" "r"))]
6486   "TARGET_SH1"
6487   "jmp  @%0%#"
6488   [(set_attr "needs_delay_slot" "yes")
6489    (set_attr "type" "jump_ind")])
6490
6491 (define_expand "indirect_jump"
6492   [(set (pc)
6493         (match_operand 0 "register_operand" ""))]
6494   ""
6495   "
6496 {
6497   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6498     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6499 }")
6500
6501 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6502 ;; which can be present in structured code from indirect jumps which can not
6503 ;; be present in structured code.  This allows -fprofile-arcs to work.
6504
6505 ;; For SH1 processors.
6506 (define_insn "casesi_jump_1"
6507   [(set (pc)
6508         (match_operand:SI 0 "register_operand" "r"))
6509    (use (label_ref (match_operand 1 "" "")))]
6510   "TARGET_SH1"
6511   "jmp  @%0%#"
6512   [(set_attr "needs_delay_slot" "yes")
6513    (set_attr "type" "jump_ind")])
6514
6515 ;; For all later processors.
6516 (define_insn "casesi_jump_2"
6517   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6518                       (label_ref (match_operand 1 "" ""))))
6519    (use (label_ref (match_operand 2 "" "")))]
6520   "TARGET_SH2
6521    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6522   "braf %0%#"
6523   [(set_attr "needs_delay_slot" "yes")
6524    (set_attr "type" "jump_ind")])
6525
6526 (define_insn "casesi_jump_media"
6527   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6528    (use (label_ref (match_operand 1 "" "")))]
6529   "TARGET_SHMEDIA"
6530   "blink        %0, r63"
6531   [(set_attr "type" "jump_media")])
6532
6533 ;; Call subroutine returning any type.
6534 ;; ??? This probably doesn't work.
6535
6536 (define_expand "untyped_call"
6537   [(parallel [(call (match_operand 0 "" "")
6538                     (const_int 0))
6539               (match_operand 1 "" "")
6540               (match_operand 2 "" "")])]
6541   "TARGET_SH2E || TARGET_SHMEDIA"
6542   "
6543 {
6544   int i;
6545
6546   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6547
6548   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6549     {
6550       rtx set = XVECEXP (operands[2], 0, i);
6551       emit_move_insn (SET_DEST (set), SET_SRC (set));
6552     }
6553
6554   /* The optimizer does not know that the call sets the function value
6555      registers we stored in the result block.  We avoid problems by
6556      claiming that all hard registers are used and clobbered at this
6557      point.  */
6558   emit_insn (gen_blockage ());
6559
6560   DONE;
6561 }")
6562 \f
6563 ;; ------------------------------------------------------------------------
6564 ;; Misc insns
6565 ;; ------------------------------------------------------------------------
6566
6567 (define_insn "dect"
6568   [(set (reg:SI T_REG)
6569         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6570    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6571   "TARGET_SH2"
6572   "dt   %0"
6573   [(set_attr "type" "arith")])
6574
6575 (define_insn "nop"
6576   [(const_int 0)]
6577   ""
6578   "nop")
6579
6580 ;; Load address of a label. This is only generated by the casesi expand,
6581 ;; and by machine_dependent_reorg (fixing up fp moves).
6582 ;; This must use unspec, because this only works for labels that are
6583 ;; within range,
6584
6585 (define_insn "mova"
6586   [(set (reg:SI R0_REG)
6587         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6588   "TARGET_SH1"
6589   "mova %O0,r0"
6590   [(set_attr "in_delay_slot" "no")
6591    (set_attr "type" "arith")])
6592
6593 ;; machine_dependent_reorg will make this a `mova'.
6594 (define_insn "mova_const"
6595   [(set (reg:SI R0_REG)
6596         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6597   "TARGET_SH1"
6598   "#"
6599   [(set_attr "in_delay_slot" "no")
6600    (set_attr "type" "arith")])
6601
6602 (define_expand "GOTaddr2picreg"
6603   [(set (reg:SI R0_REG)
6604         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6605                    UNSPEC_MOVA))
6606    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6607    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6608   "" "
6609 {
6610   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6611   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6612
6613   if (TARGET_SH5)
6614     operands[1] = gen_datalabel_ref (operands[1]);
6615
6616   if (TARGET_SHMEDIA)
6617     {
6618       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6619       rtx dipic = operands[0];
6620       rtx lab = PATTERN (gen_call_site ());
6621       rtx insn, equiv;
6622
6623       equiv = operands[1];
6624       operands[1] = gen_rtx_MINUS (DImode,
6625                                    operands[1],
6626                                    gen_rtx_CONST
6627                                    (DImode,
6628                                     gen_rtx_MINUS (DImode,
6629                                                    gen_rtx_CONST (DImode,
6630                                                                   lab),
6631                                                    pc_rtx)));
6632       operands[1] = gen_sym2PIC (operands[1]);
6633       PUT_MODE (operands[1], DImode);
6634
6635       if (GET_MODE (dipic) != DImode)
6636         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6637
6638       if (TARGET_SHMEDIA64)
6639         emit_insn (gen_movdi_const (dipic, operands[1]));
6640       else
6641         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6642
6643       emit_insn (gen_ptrel (tr, dipic, lab));
6644
6645       if (GET_MODE (operands[0]) != GET_MODE (tr))
6646         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6647
6648       insn = emit_move_insn (operands[0], tr);
6649
6650       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6651                                             REG_NOTES (insn));
6652
6653       DONE;
6654     }
6655 }
6656 ")
6657
6658 (define_insn "*ptb"
6659   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6660         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6661                              UNSPEC_DATALABEL)))]
6662   "TARGET_SHMEDIA && flag_pic
6663    && EXTRA_CONSTRAINT_Csy (operands[1])"
6664   "ptb/u        datalabel %1, %0"
6665   [(set_attr "type" "pt_media")
6666    (set_attr "length" "*")])
6667
6668 (define_insn "ptrel"
6669   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6670         (plus:DI (match_operand:DI 1 "register_operand" "r")
6671               (pc)))
6672    (match_operand:DI 2 "" "")]
6673   "TARGET_SHMEDIA"
6674   "%O2: ptrel/u %1, %0"
6675   [(set_attr "type" "ptabs_media")])
6676
6677 (define_expand "builtin_setjmp_receiver"
6678   [(match_operand 0 "" "")]
6679   "flag_pic"
6680   "
6681 {
6682   emit_insn (gen_GOTaddr2picreg ());
6683   DONE;
6684 }")
6685
6686 (define_expand "call_site"
6687   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6688   "TARGET_SH1"
6689   "
6690 {
6691   static HOST_WIDE_INT i = 0;
6692   operands[0] = GEN_INT (i);
6693   i++;
6694 }")
6695
6696 (define_expand "sym_label2reg"
6697   [(set (match_operand:SI 0 "" "")
6698         (const:SI (minus:SI
6699                    (const:SI
6700                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6701                    (const:SI
6702                     (plus:SI
6703                      (match_operand:SI 2 "" "")
6704                      (const_int 2))))))]
6705   "TARGET_SH1" "")
6706
6707 (define_expand "symGOT_load"
6708   [(set (match_dup 2) (match_operand 1 "" ""))
6709    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6710    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6711   ""
6712   "
6713 {
6714   rtx insn;
6715
6716   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6717   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6718
6719   if (TARGET_SHMEDIA)
6720     {
6721       rtx reg = operands[2];
6722
6723       if (GET_MODE (reg) != DImode)
6724         reg = gen_rtx_SUBREG (DImode, reg, 0);
6725
6726       if (flag_pic > 1)
6727         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6728       else
6729         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6730     }
6731   else
6732     emit_move_insn (operands[2], operands[1]);
6733
6734   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6735                                              operands[2],
6736                                              gen_rtx_REG (Pmode, PIC_REG)));
6737
6738   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6739
6740   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6741                                                                   0), 0, 0),
6742                                         REG_NOTES (insn));
6743
6744   DONE;
6745 }")
6746
6747 (define_expand "sym2GOT"
6748   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6749   ""
6750   "")
6751
6752 (define_expand "symGOT2reg"
6753   [(match_operand 0 "" "") (match_operand 1 "" "")]
6754   ""
6755   "
6756 {
6757   rtx gotsym, insn;
6758
6759   gotsym = gen_sym2GOT (operands[1]);
6760   PUT_MODE (gotsym, Pmode);
6761   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6762
6763   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6764
6765   DONE;
6766 }")
6767
6768 (define_expand "sym2GOTPLT"
6769   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6770   ""
6771   "")
6772
6773 (define_expand "symGOTPLT2reg"
6774   [(match_operand 0 "" "") (match_operand 1 "" "")]
6775   ""
6776   "
6777 {
6778   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6779   DONE;
6780 }")
6781
6782 (define_expand "sym2GOTOFF"
6783   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6784   ""
6785   "")
6786
6787 (define_expand "symGOTOFF2reg"
6788   [(match_operand 0 "" "") (match_operand 1 "" "")]
6789   ""
6790   "
6791 {
6792   rtx gotoffsym, insn;
6793   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6794
6795   gotoffsym = gen_sym2GOTOFF (operands[1]);
6796   PUT_MODE (gotoffsym, Pmode);
6797   emit_move_insn (t, gotoffsym);
6798   insn = emit_move_insn (operands[0],
6799                          gen_rtx_PLUS (Pmode, t,
6800                                        gen_rtx_REG (Pmode, PIC_REG)));
6801
6802   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6803                                         REG_NOTES (insn));
6804
6805   DONE;
6806 }")
6807
6808 (define_expand "symPLT_label2reg"
6809   [(set (match_operand:SI 0 "" "")
6810         (const:SI (minus:SI
6811                    (const:SI
6812                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6813                    (const:SI
6814                     (minus:SI
6815                      (const:SI (plus:SI
6816                                 (match_operand:SI 2 "" "")
6817                                 (const_int 2)))
6818                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6819    ;; Even though the PIC register is not really used by the call
6820    ;; sequence in which this is expanded, the PLT code assumes the PIC
6821    ;; register is set, so we must not skip its initialization.  Since
6822    ;; we only use this expand as part of calling sequences, and never
6823    ;; to take the address of a function, this is the best point to
6824    ;; insert the (use).  Using the PLT to take the address of a
6825    ;; function would be wrong, not only because the PLT entry could
6826    ;; then be called from a function that doesn't initialize the PIC
6827    ;; register to the proper GOT, but also because pointers to the
6828    ;; same function might not compare equal, should they be set by
6829    ;; different shared libraries.
6830    (use (reg:SI PIC_REG))]
6831   "TARGET_SH1"
6832   "")
6833
6834 (define_expand "sym2PIC"
6835   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6836   ""
6837   "")
6838
6839 ;; TLS code generation.
6840 ;; ??? this should be a define_insn_and_split
6841 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6842 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6843 ;; for details.
6844
6845 (define_insn "tls_global_dynamic"
6846   [(set (match_operand:SI 0 "register_operand" "=&z")
6847         (unspec:SI [(match_operand:SI 1 "" "")]
6848                     UNSPEC_TLSGD))
6849    (use (reg:PSI FPSCR_REG))
6850    (use (reg:SI PIC_REG))
6851    (clobber (reg:SI PR_REG))
6852    (clobber (scratch:SI))]
6853   "TARGET_SH1"
6854   "*
6855 {
6856   return \"\\
6857 mov.l\\t1f,r4\\n\\
6858 \\tmova\\t2f,r0\\n\\
6859 \\tmov.l\\t2f,r1\\n\\
6860 \\tadd\\tr0,r1\\n\\
6861 \\tjsr\\t@r1\\n\\
6862 \\tadd\\tr12,r4\\n\\
6863 \\tbra\\t3f\\n\\
6864 \\tnop\\n\\
6865 \\t.align\\t2\\n\\
6866 1:\\t.long\\t%a1@TLSGD\\n\\
6867 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6868 3:\";
6869 }"
6870   [(set_attr "type" "tls_load")
6871    (set_attr "length" "26")])
6872
6873 (define_insn "tls_local_dynamic"
6874   [(set (match_operand:SI 0 "register_operand" "=&z")
6875         (unspec:SI [(match_operand:SI 1 "" "")]
6876                     UNSPEC_TLSLDM))
6877    (use (reg:PSI FPSCR_REG))
6878    (use (reg:SI PIC_REG))
6879    (clobber (reg:SI PR_REG))
6880    (clobber (scratch:SI))]
6881   "TARGET_SH1"
6882   "*
6883 {
6884   return \"\\
6885 mov.l\\t1f,r4\\n\\
6886 \\tmova\\t2f,r0\\n\\
6887 \\tmov.l\\t2f,r1\\n\\
6888 \\tadd\\tr0,r1\\n\\
6889 \\tjsr\\t@r1\\n\\
6890 \\tadd\\tr12,r4\\n\\
6891 \\tbra\\t3f\\n\\
6892 \\tnop\\n\\
6893 \\t.align\\t2\\n\\
6894 1:\\t.long\\t%a1@TLSLDM\\n\\
6895 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6896 3:\";
6897 }"
6898   [(set_attr "type" "tls_load")
6899    (set_attr "length" "26")])
6900
6901 (define_expand "sym2DTPOFF"
6902   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6903   ""
6904   "")
6905
6906 (define_expand "symDTPOFF2reg"
6907   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6908   ""
6909   "
6910 {
6911   rtx dtpoffsym, insn;
6912   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6913
6914   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6915   PUT_MODE (dtpoffsym, Pmode);
6916   emit_move_insn (t, dtpoffsym);
6917   insn = emit_move_insn (operands[0],
6918                          gen_rtx_PLUS (Pmode, t, operands[2]));
6919   DONE;
6920 }")
6921
6922 (define_expand "sym2GOTTPOFF"
6923   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6924   ""
6925   "")
6926
6927 (define_insn "tls_initial_exec"
6928   [(set (match_operand:SI 0 "register_operand" "=&r")
6929         (unspec:SI [(match_operand:SI 1 "" "")]
6930                     UNSPEC_TLSIE))
6931    (use (reg:SI GBR_REG))
6932    (use (reg:SI PIC_REG))
6933    (clobber (reg:SI R0_REG))]
6934   ""
6935   "*
6936 {
6937   return \"\\
6938 mov.l\\t1f,r0\\n\\
6939 \\tstc\\tgbr,%0\\n\\
6940 \\tmov.l\\t@(r0,r12),r0\\n\\
6941 \\tbra\\t2f\\n\\
6942 \\tadd\\tr0,%0\\n\\
6943 \\t.align\\t2\\n\\
6944 1:\\t.long\\t%a1\\n\\
6945 2:\";
6946 }"
6947   [(set_attr "type" "tls_load")
6948    (set_attr "length" "16")])
6949
6950 (define_expand "sym2TPOFF"
6951   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6952   ""
6953   "")
6954
6955 (define_expand "symTPOFF2reg"
6956   [(match_operand 0 "" "") (match_operand 1 "" "")]
6957   ""
6958   "
6959 {
6960   rtx tpoffsym, insn;
6961
6962   tpoffsym = gen_sym2TPOFF (operands[1]);
6963   PUT_MODE (tpoffsym, Pmode);
6964   insn = emit_move_insn (operands[0], tpoffsym);
6965   DONE;
6966 }")
6967
6968 (define_insn "load_gbr"
6969   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6970    (use (reg:SI GBR_REG))]
6971   ""
6972   "stc  gbr,%0"
6973   [(set_attr "type" "tls_load")])
6974
6975 ;; case instruction for switch statements.
6976
6977 ;; Operand 0 is index
6978 ;; operand 1 is the minimum bound
6979 ;; operand 2 is the maximum bound - minimum bound + 1
6980 ;; operand 3 is CODE_LABEL for the table;
6981 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6982
6983 (define_expand "casesi"
6984   [(match_operand:SI 0 "arith_reg_operand" "")
6985    (match_operand:SI 1 "arith_reg_operand" "")
6986    (match_operand:SI 2 "arith_reg_operand" "")
6987    (match_operand 3 "" "") (match_operand 4 "" "")]
6988   ""
6989   "
6990 {
6991   rtx reg = gen_reg_rtx (SImode);
6992   rtx reg2 = gen_reg_rtx (SImode);
6993   if (TARGET_SHMEDIA)
6994     {
6995       rtx reg = gen_reg_rtx (DImode);
6996       rtx reg2 = gen_reg_rtx (DImode);
6997       rtx reg3 = gen_reg_rtx (DImode);
6998       rtx reg4 = gen_reg_rtx (DImode);
6999       rtx reg5 = gen_reg_rtx (DImode);
7000
7001       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7002       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7003       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7004
7005       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7006       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7007       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7008       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7009       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7010                                                (DImode, operands[3])));
7011       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7012       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7013       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7014       emit_barrier ();
7015       DONE;
7016     }
7017   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7018   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7019   /* If optimizing, casesi_worker depends on the mode of the instruction
7020      before label it 'uses' - operands[3].  */
7021   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7022                            reg));
7023   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7024   if (TARGET_SH2)
7025     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7026   else
7027     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7028   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7029      operands[3], but to lab.  We will fix this up in
7030      machine_dependent_reorg.  */
7031   emit_barrier ();
7032   DONE;
7033 }")
7034
7035 (define_expand "casesi_0"
7036   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7037    (set (match_dup 4) (minus:SI (match_dup 4)
7038                                 (match_operand:SI 1 "arith_operand" "")))
7039    (set (reg:SI T_REG)
7040         (gtu:SI (match_dup 4)
7041                 (match_operand:SI 2 "arith_reg_operand" "")))
7042    (set (pc)
7043         (if_then_else (ne (reg:SI T_REG)
7044                           (const_int 0))
7045                       (label_ref (match_operand 3 "" ""))
7046                       (pc)))]
7047   "TARGET_SH1"
7048   "")
7049
7050 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7051 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7052 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7053
7054 (define_insn "casesi_worker_0"
7055   [(set (match_operand:SI 0 "register_operand" "=r,r")
7056         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7057                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7058    (clobber (match_scratch:SI 3 "=X,1"))
7059    (clobber (match_scratch:SI 4 "=&z,z"))]
7060   "TARGET_SH1"
7061   "#")
7062
7063 (define_split
7064   [(set (match_operand:SI 0 "register_operand" "")
7065         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7066                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7067    (clobber (match_scratch:SI 3 ""))
7068    (clobber (match_scratch:SI 4 ""))]
7069   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7070   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7071    (parallel [(set (match_dup 0)
7072               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7073                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7074               (clobber (match_dup 3))])
7075    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7076   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7077
7078 (define_split
7079   [(set (match_operand:SI 0 "register_operand" "")
7080         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7081                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7082    (clobber (match_scratch:SI 3 ""))
7083    (clobber (match_scratch:SI 4 ""))]
7084   "TARGET_SH2 && reload_completed"
7085   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7086    (parallel [(set (match_dup 0)
7087               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7088                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7089               (clobber (match_dup 3))])]
7090   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7091
7092 (define_insn "*casesi_worker"
7093   [(set (match_operand:SI 0 "register_operand" "=r,r")
7094         (unspec:SI [(reg:SI R0_REG)
7095                     (match_operand:SI 1 "register_operand" "0,r")
7096                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7097    (clobber (match_scratch:SI 3 "=X,1"))]
7098   "TARGET_SH1"
7099   "*
7100 {
7101   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7102
7103   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7104     abort ();
7105
7106   switch (GET_MODE (diff_vec))
7107     {
7108     case SImode:
7109       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7110     case HImode:
7111       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7112     case QImode:
7113       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7114         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7115       return \"mov.b    @(r0,%1),%0\";
7116     default:
7117       abort ();
7118     }
7119 }"
7120   [(set_attr "length" "4")])
7121
7122 (define_insn "casesi_shift_media"
7123   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7124         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7125                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7126                     UNSPEC_CASESI)))]
7127   "TARGET_SHMEDIA"
7128   "*
7129 {
7130   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7131
7132   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7133     abort ();
7134
7135   switch (GET_MODE (diff_vec))
7136     {
7137     case SImode:
7138       return \"shlli    %1, 2, %0\";
7139     case HImode:
7140       return \"shlli    %1, 1, %0\";
7141     case QImode:
7142       if (rtx_equal_p (operands[0], operands[1]))
7143         return \"\";
7144       return \"add      %1, r63, %0\";
7145     default:
7146       abort ();
7147     }
7148 }"
7149   [(set_attr "type" "arith_media")])
7150
7151 (define_insn "casesi_load_media"
7152   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7153         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7154                          (match_operand 2 "arith_reg_operand" "r")
7155                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7156   "TARGET_SHMEDIA"
7157   "*
7158 {
7159   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7160
7161   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7162     abort ();
7163
7164   switch (GET_MODE (diff_vec))
7165     {
7166     case SImode:
7167       return \"ldx.l    %1, %2, %0\";
7168     case HImode:
7169 #if 0
7170       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7171         return \"ldx.uw %1, %2, %0\";
7172 #endif
7173       return \"ldx.w    %1, %2, %0\";
7174     case QImode:
7175       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7176         return \"ldx.ub %1, %2, %0\";
7177       return \"ldx.b    %1, %2, %0\";
7178     default:
7179       abort ();
7180     }
7181 }"
7182   [(set_attr "type" "load_media")])
7183
7184 (define_expand "return"
7185   [(return)]
7186   "reload_completed && ! sh_need_epilogue ()"
7187   "
7188 {
7189   if (TARGET_SHMEDIA)
7190     {
7191       emit_jump_insn (gen_return_media ());
7192       DONE;
7193     }
7194
7195   if (TARGET_SHCOMPACT
7196       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7197     {
7198       emit_jump_insn (gen_shcompact_return_tramp ());
7199       DONE;
7200     }
7201 }")
7202
7203 (define_insn "*return_i"
7204   [(return)]
7205   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7206                     && (current_function_args_info.call_cookie
7207                         & CALL_COOKIE_RET_TRAMP (1)))
7208    && reload_completed"
7209   "%@   %#"
7210   [(set_attr "type" "return")
7211    (set_attr "needs_delay_slot" "yes")])
7212
7213 (define_expand "shcompact_return_tramp"
7214   [(return)]
7215   "TARGET_SHCOMPACT
7216    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7217   "
7218 {
7219   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7220   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7221
7222   if (flag_pic)
7223     emit_insn (gen_symGOTPLT2reg (reg, sym));
7224   else
7225     emit_move_insn (reg, sym);
7226
7227   emit_jump_insn (gen_shcompact_return_tramp_i ());
7228   DONE;
7229 }")
7230
7231 (define_insn "shcompact_return_tramp_i"
7232   [(parallel [(return) (use (reg:SI R0_REG))])]
7233   "TARGET_SHCOMPACT
7234    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7235   "jmp  @r0%#"
7236   [(set_attr "type" "jump_ind")
7237    (set_attr "needs_delay_slot" "yes")])
7238
7239 (define_insn "return_media_i"
7240   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7241   "TARGET_SHMEDIA && reload_completed"
7242   "blink        %0, r63"
7243   [(set_attr "type" "jump_media")])
7244
7245 (define_insn "return_media_rte"
7246   [(return)]
7247   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7248   "rte"
7249   [(set_attr "type" "jump_media")])
7250
7251 (define_expand "return_media"
7252   [(return)]
7253   "TARGET_SHMEDIA && reload_completed"
7254   "
7255 {
7256   int tr_regno = sh_media_register_for_return ();
7257   rtx tr;
7258
7259   if (current_function_interrupt)
7260     {
7261       emit_jump_insn (gen_return_media_rte ());
7262       DONE;
7263     }
7264   if (tr_regno < 0)
7265     {
7266       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7267
7268       if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7269         abort ();
7270       tr_regno = TR0_REG;
7271       tr = gen_rtx_REG (DImode, tr_regno);
7272       emit_move_insn (tr, r18);
7273     }
7274   else
7275     tr = gen_rtx_REG (DImode, tr_regno);
7276
7277   emit_jump_insn (gen_return_media_i (tr));
7278   DONE;
7279 }")
7280
7281 (define_insn "shcompact_preserve_incoming_args"
7282   [(set (match_operand:SI 0 "register_operand" "+r")
7283         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7284   "TARGET_SHCOMPACT"
7285   ""
7286   [(set_attr "length" "0")])
7287
7288 (define_insn "shcompact_incoming_args"
7289   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7290    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7291    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7292    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7293    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7294    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7295    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7296    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7297    (set (mem:BLK (reg:SI MACL_REG))
7298         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7299    (use (reg:SI R0_REG))
7300    (clobber (reg:SI R0_REG))
7301    (clobber (reg:SI MACL_REG))
7302    (clobber (reg:SI MACH_REG))
7303    (clobber (reg:SI PR_REG))]
7304   "TARGET_SHCOMPACT"
7305   "jsr  @r0%#"
7306   [(set_attr "needs_delay_slot" "yes")])
7307
7308 (define_insn "shmedia_save_restore_regs_compact"
7309   [(set (reg:SI SP_REG)
7310         (plus:SI (reg:SI SP_REG)
7311                  (match_operand:SI 0 "immediate_operand" "i")))
7312    (use (reg:SI R0_REG))
7313    (clobber (reg:SI PR_REG))]
7314   "TARGET_SHCOMPACT
7315    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7316        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7317   "jsr @r0%#"
7318   [(set_attr "needs_delay_slot" "yes")])
7319
7320 (define_expand "prologue"
7321   [(const_int 0)]
7322   ""
7323   "sh_expand_prologue (); DONE;")
7324
7325 (define_expand "epilogue"
7326   [(return)]
7327   ""
7328   "
7329 {
7330   sh_expand_epilogue ();
7331   emit_jump_insn (gen_return ());
7332   DONE;
7333 }")
7334
7335 (define_expand "eh_return"
7336   [(use (match_operand 0 "register_operand" ""))]
7337   ""
7338 {
7339   rtx tmp, ra = operands[0];
7340
7341   if (TARGET_SHMEDIA64)
7342     emit_insn (gen_eh_set_ra_di (ra));
7343   else
7344     emit_insn (gen_eh_set_ra_si (ra));
7345
7346   DONE;
7347 })
7348
7349 ;; Clobber the return address on the stack.  We can't expand this
7350 ;; until we know where it will be put in the stack frame.
7351
7352 (define_insn "eh_set_ra_si"
7353   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7354    (clobber (match_scratch:SI 1 "=&r"))]
7355   "! TARGET_SHMEDIA64"
7356   "#")
7357
7358 (define_insn "eh_set_ra_di"
7359   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7360    (clobber (match_scratch:DI 1 "=&r"))]
7361   "TARGET_SHMEDIA64"
7362   "#")
7363
7364 (define_split
7365   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7366    (clobber (match_scratch 1 ""))]
7367   "reload_completed"
7368   [(const_int 0)]
7369   "
7370 {
7371   sh_set_return_address (operands[0], operands[1]);
7372   DONE;
7373 }")
7374
7375 (define_insn "blockage"
7376   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7377   ""
7378   ""
7379   [(set_attr "length" "0")])
7380 \f
7381 ;; ------------------------------------------------------------------------
7382 ;; Scc instructions
7383 ;; ------------------------------------------------------------------------
7384
7385 (define_insn "movt"
7386   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7387         (eq:SI (reg:SI T_REG) (const_int 1)))]
7388   "TARGET_SH1"
7389   "movt %0"
7390   [(set_attr "type" "arith")])
7391
7392 (define_expand "seq"
7393   [(set (match_operand:SI 0 "arith_reg_operand" "")
7394         (match_dup 1))]
7395   ""
7396   "
7397 {
7398   if (TARGET_SHMEDIA)
7399     {
7400       if (GET_MODE (operands[0]) != DImode)
7401         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7402       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7403       if (sh_compare_op1 != const0_rtx)
7404         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7405                                     ? GET_MODE (sh_compare_op0)
7406                                     : GET_MODE (sh_compare_op1),
7407                                     sh_compare_op1);
7408
7409       switch (GET_MODE (sh_compare_op0))
7410         {
7411         case DImode:
7412           emit_insn (gen_cmpeqdi_media (operands[0],
7413                                         sh_compare_op0, sh_compare_op1));
7414           break;
7415
7416         case SFmode:
7417           if (! TARGET_SHMEDIA_FPU)
7418             FAIL;
7419           emit_insn (gen_cmpeqsf_media (operands[0],
7420                                         sh_compare_op0, sh_compare_op1));
7421           break;
7422
7423         case DFmode:
7424           if (! TARGET_SHMEDIA_FPU)
7425             FAIL;
7426           emit_insn (gen_cmpeqdf_media (operands[0],
7427                                         sh_compare_op0, sh_compare_op1));
7428           break;
7429
7430         default:
7431           FAIL;
7432         }
7433       DONE;
7434     }
7435   operands[1] = prepare_scc_operands (EQ);
7436 }")
7437
7438 (define_expand "slt"
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_cmpgtdi_media (operands[0],
7459                                         sh_compare_op1, sh_compare_op0));
7460           break;
7461
7462         case SFmode:
7463           if (! TARGET_SHMEDIA_FPU)
7464             FAIL;
7465           emit_insn (gen_cmpgtsf_media (operands[0],
7466                                         sh_compare_op1, sh_compare_op0));
7467           break;
7468
7469         case DFmode:
7470           if (! TARGET_SHMEDIA_FPU)
7471             FAIL;
7472           emit_insn (gen_cmpgtdf_media (operands[0],
7473                                         sh_compare_op1, sh_compare_op0));
7474           break;
7475
7476         default:
7477           FAIL;
7478         }
7479       DONE;
7480     }
7481   operands[1] = prepare_scc_operands (LT);
7482 }")
7483
7484 (define_expand "sle"
7485   [(match_operand:SI 0 "arith_reg_operand" "")]
7486   ""
7487   "
7488 {
7489   rtx tmp = sh_compare_op0;
7490
7491   if (TARGET_SHMEDIA)
7492     {
7493       if (GET_MODE (operands[0]) != DImode)
7494         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7495       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7496       if (sh_compare_op1 != const0_rtx)
7497         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7498                                     ? GET_MODE (sh_compare_op0)
7499                                     : GET_MODE (sh_compare_op1),
7500                                     sh_compare_op1);
7501
7502       switch (GET_MODE (sh_compare_op0))
7503         {
7504         case DImode:
7505           {
7506             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7507
7508             emit_insn (gen_cmpgtdi_media (tmp,
7509                                           sh_compare_op0, sh_compare_op1));
7510             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7511             break;
7512           }
7513
7514         case SFmode:
7515           if (! TARGET_SHMEDIA_FPU)
7516             FAIL;
7517           emit_insn (gen_cmpgesf_media (operands[0],
7518                                         sh_compare_op1, sh_compare_op0));
7519           break;
7520
7521         case DFmode:
7522           if (! TARGET_SHMEDIA_FPU)
7523             FAIL;
7524           emit_insn (gen_cmpgedf_media (operands[0],
7525                                         sh_compare_op1, sh_compare_op0));
7526           break;
7527
7528         default:
7529           FAIL;
7530         }
7531       DONE;
7532     }
7533
7534   sh_compare_op0 = sh_compare_op1;
7535   sh_compare_op1 = tmp;
7536   emit_insn (gen_sge (operands[0]));
7537   DONE;
7538 }")
7539
7540 (define_expand "sgt"
7541   [(set (match_operand:SI 0 "arith_reg_operand" "")
7542         (match_dup 1))]
7543   ""
7544   "
7545 {
7546   if (TARGET_SHMEDIA)
7547     {
7548       if (GET_MODE (operands[0]) != DImode)
7549         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7550       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7551       if (sh_compare_op1 != const0_rtx)
7552         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7553                                     ? GET_MODE (sh_compare_op0)
7554                                     : GET_MODE (sh_compare_op1),
7555                                     sh_compare_op1);
7556
7557       switch (GET_MODE (sh_compare_op0))
7558         {
7559         case DImode:
7560           emit_insn (gen_cmpgtdi_media (operands[0],
7561                                         sh_compare_op0, sh_compare_op1));
7562           break;
7563
7564         case SFmode:
7565           if (! TARGET_SHMEDIA_FPU)
7566             FAIL;
7567           emit_insn (gen_cmpgtsf_media (operands[0],
7568                                         sh_compare_op0, sh_compare_op1));
7569           break;
7570
7571         case DFmode:
7572           if (! TARGET_SHMEDIA_FPU)
7573             FAIL;
7574           emit_insn (gen_cmpgtdf_media (operands[0],
7575                                         sh_compare_op0, sh_compare_op1));
7576           break;
7577
7578         default:
7579           FAIL;
7580         }
7581       DONE;
7582     }
7583   operands[1] = prepare_scc_operands (GT);
7584 }")
7585
7586 (define_expand "sge"
7587   [(set (match_operand:SI 0 "arith_reg_operand" "")
7588         (match_dup 1))]
7589   ""
7590   "
7591 {
7592   if (TARGET_SHMEDIA)
7593     {
7594       if (GET_MODE (operands[0]) != DImode)
7595         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7596       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7597       if (sh_compare_op1 != const0_rtx)
7598         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7599                                     ? GET_MODE (sh_compare_op0)
7600                                     : GET_MODE (sh_compare_op1),
7601                                     sh_compare_op1);
7602
7603       switch (GET_MODE (sh_compare_op0))
7604         {
7605         case DImode:
7606           {
7607             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7608
7609             emit_insn (gen_cmpgtdi_media (tmp,
7610                                           sh_compare_op1, sh_compare_op0));
7611             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7612             break;
7613           }
7614
7615         case SFmode:
7616           if (! TARGET_SHMEDIA_FPU)
7617             FAIL;
7618           emit_insn (gen_cmpgesf_media (operands[0],
7619                                         sh_compare_op0, sh_compare_op1));
7620           break;
7621
7622         case DFmode:
7623           if (! TARGET_SHMEDIA_FPU)
7624             FAIL;
7625           emit_insn (gen_cmpgedf_media (operands[0],
7626                                         sh_compare_op0, sh_compare_op1));
7627           break;
7628
7629         default:
7630           FAIL;
7631         }
7632       DONE;
7633     }
7634
7635   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7636     {
7637       if (TARGET_IEEE)
7638         {
7639           rtx lab = gen_label_rtx ();
7640           prepare_scc_operands (EQ);
7641           emit_jump_insn (gen_branch_true (lab));
7642           prepare_scc_operands (GT);
7643           emit_label (lab);
7644           emit_insn (gen_movt (operands[0]));
7645         }
7646       else
7647         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7648       DONE;
7649     }
7650   operands[1] = prepare_scc_operands (GE);
7651 }")
7652
7653 (define_expand "sgtu"
7654   [(set (match_operand:SI 0 "arith_reg_operand" "")
7655         (match_dup 1))]
7656   ""
7657   "
7658 {
7659   if (TARGET_SHMEDIA)
7660     {
7661       if (GET_MODE (operands[0]) != DImode)
7662         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7663       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7664       if (sh_compare_op1 != const0_rtx)
7665         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7666                                     ? GET_MODE (sh_compare_op0)
7667                                     : GET_MODE (sh_compare_op1),
7668                                     sh_compare_op1);
7669
7670       emit_insn (gen_cmpgtudi_media (operands[0],
7671                                      sh_compare_op0, sh_compare_op1));
7672       DONE;
7673     }
7674   operands[1] = prepare_scc_operands (GTU);
7675 }")
7676
7677 (define_expand "sltu"
7678   [(set (match_operand:SI 0 "arith_reg_operand" "")
7679         (match_dup 1))]
7680   ""
7681   "
7682 {
7683   if (TARGET_SHMEDIA)
7684     {
7685       if (GET_MODE (operands[0]) != DImode)
7686         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7687       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7688       if (sh_compare_op1 != const0_rtx)
7689         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7690                                     ? GET_MODE (sh_compare_op0)
7691                                     : GET_MODE (sh_compare_op1),
7692                                     sh_compare_op1);
7693
7694       emit_insn (gen_cmpgtudi_media (operands[0],
7695                                      sh_compare_op1, sh_compare_op0));
7696       DONE;
7697     }
7698   operands[1] = prepare_scc_operands (LTU);
7699 }")
7700
7701 (define_expand "sleu"
7702   [(set (match_operand:SI 0 "arith_reg_operand" "")
7703         (match_dup 1))]
7704   ""
7705   "
7706 {
7707   if (TARGET_SHMEDIA)
7708     {
7709       rtx tmp;
7710
7711       if (GET_MODE (operands[0]) != DImode)
7712         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7713       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7714       if (sh_compare_op1 != const0_rtx)
7715         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7716                                     ? GET_MODE (sh_compare_op0)
7717                                     : GET_MODE (sh_compare_op1),
7718                                     sh_compare_op1);
7719
7720       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7721
7722       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7723       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7724
7725       DONE;
7726     }
7727   operands[1] = prepare_scc_operands (LEU);
7728 }")
7729
7730 (define_expand "sgeu"
7731   [(set (match_operand:SI 0 "arith_reg_operand" "")
7732         (match_dup 1))]
7733   ""
7734   "
7735 {
7736   if (TARGET_SHMEDIA)
7737     {
7738       rtx tmp;
7739
7740       if (GET_MODE (operands[0]) != DImode)
7741         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7742       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7743       if (sh_compare_op1 != const0_rtx)
7744         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7745                                     ? GET_MODE (sh_compare_op0)
7746                                     : GET_MODE (sh_compare_op1),
7747                                     sh_compare_op1);
7748
7749       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7750
7751       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7752       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7753
7754       DONE;
7755     }
7756
7757   operands[1] = prepare_scc_operands (GEU);
7758 }")
7759
7760 ;; sne moves the complement of the T reg to DEST like this:
7761 ;;      cmp/eq ...
7762 ;;      mov    #-1,temp
7763 ;;      negc   temp,dest
7764 ;;   This is better than xoring compare result with 1 because it does
7765 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7766 ;;   loop.
7767
7768 (define_expand "sne"
7769   [(set (match_dup 2) (const_int -1))
7770    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7771                    (neg:SI (plus:SI (match_dup 1)
7772                                     (match_dup 2))))
7773               (set (reg:SI T_REG)
7774                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7775                           (const_int 0)))])]
7776   ""
7777   "
7778 {
7779   if (TARGET_SHMEDIA)
7780     {
7781       rtx tmp;
7782
7783       if (GET_MODE (operands[0]) != DImode)
7784         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7785
7786       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7787         FAIL;
7788
7789       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7790       if (sh_compare_op1 != const0_rtx)
7791         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7792                                     ? GET_MODE (sh_compare_op0)
7793                                     : GET_MODE (sh_compare_op1),
7794                                     sh_compare_op1);
7795
7796       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7797
7798       emit_insn (gen_seq (tmp));
7799       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7800
7801       DONE;
7802     }
7803
7804    operands[1] = prepare_scc_operands (EQ);
7805    operands[2] = gen_reg_rtx (SImode);
7806 }")
7807
7808 (define_expand "sunordered"
7809   [(set (match_operand:DI 0 "arith_reg_operand" "")
7810         (unordered:DI (match_dup 1) (match_dup 2)))]
7811   "TARGET_SHMEDIA_FPU"
7812   "
7813 {
7814   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7815   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7816 }")
7817
7818 ;; Use the same trick for FP sle / sge
7819 (define_expand "movnegt"
7820   [(set (match_dup 2) (const_int -1))
7821    (parallel [(set (match_operand 0 "" "")
7822                    (neg:SI (plus:SI (match_dup 1)
7823                                     (match_dup 2))))
7824               (set (reg:SI T_REG)
7825                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7826                           (const_int 0)))])]
7827   "TARGET_SH1"
7828   "operands[2] = gen_reg_rtx (SImode);")
7829
7830 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7831 ;; This prevents a regression that occurred when we switched from xor to
7832 ;; mov/neg for sne.
7833
7834 (define_split
7835   [(set (match_operand:SI 0 "arith_reg_operand" "")
7836         (plus:SI (reg:SI T_REG)
7837                  (const_int -1)))]
7838   "TARGET_SH1"
7839   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7840    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7841   "")
7842
7843 ;; -------------------------------------------------------------------------
7844 ;; Instructions to cope with inline literal tables
7845 ;; -------------------------------------------------------------------------
7846
7847 ; 2 byte integer in line
7848
7849 (define_insn "consttable_2"
7850  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7851                     (match_operand 1 "" "")]
7852                    UNSPECV_CONST2)]
7853  ""
7854  "*
7855 {
7856   if (operands[1] != const0_rtx)
7857     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7858   return \"\";
7859 }"
7860  [(set_attr "length" "2")
7861  (set_attr "in_delay_slot" "no")])
7862
7863 ; 4 byte integer in line
7864
7865 (define_insn "consttable_4"
7866  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7867                     (match_operand 1 "" "")]
7868                    UNSPECV_CONST4)]
7869  ""
7870  "*
7871 {
7872   if (operands[1] != const0_rtx)
7873     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7874   return \"\";
7875 }"
7876  [(set_attr "length" "4")
7877   (set_attr "in_delay_slot" "no")])
7878
7879 ; 8 byte integer in line
7880
7881 (define_insn "consttable_8"
7882  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7883                     (match_operand 1 "" "")]
7884                    UNSPECV_CONST8)]
7885  ""
7886  "*
7887 {
7888   if (operands[1] != const0_rtx)
7889     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7890   return \"\";
7891 }"
7892  [(set_attr "length" "8")
7893   (set_attr "in_delay_slot" "no")])
7894
7895 ; 4 byte floating point
7896
7897 (define_insn "consttable_sf"
7898  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7899                     (match_operand 1 "" "")]
7900                    UNSPECV_CONST4)]
7901  ""
7902  "*
7903 {
7904   if (operands[1] != const0_rtx)
7905     {
7906       REAL_VALUE_TYPE d;
7907       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7908       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7909     }
7910   return \"\";
7911 }"
7912  [(set_attr "length" "4")
7913   (set_attr "in_delay_slot" "no")])
7914
7915 ; 8 byte floating point
7916
7917 (define_insn "consttable_df"
7918  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7919                     (match_operand 1 "" "")]
7920                    UNSPECV_CONST8)]
7921  ""
7922  "*
7923 {
7924   if (operands[1] != const0_rtx)
7925     {
7926       REAL_VALUE_TYPE d;
7927       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7928       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7929     }
7930   return \"\";
7931 }"
7932  [(set_attr "length" "8")
7933   (set_attr "in_delay_slot" "no")])
7934
7935 ;; Alignment is needed for some constant tables; it may also be added for
7936 ;; Instructions at the start of loops, or after unconditional branches.
7937 ;; ??? We would get more accurate lengths if we did instruction
7938 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7939 ;; here is too conservative.
7940
7941 ; align to a two byte boundary
7942
7943 (define_expand "align_2"
7944  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7945  ""
7946  "")
7947
7948 ; align to a four byte boundary
7949 ;; align_4 and align_log are instructions for the starts of loops, or
7950 ;; after unconditional branches, which may take up extra room.
7951
7952 (define_expand "align_4"
7953  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7954  ""
7955  "")
7956
7957 ; align to a cache line boundary
7958
7959 (define_insn "align_log"
7960  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7961  ""
7962  ""
7963  [(set_attr "length" "0")
7964   (set_attr "in_delay_slot" "no")])
7965
7966 ; emitted at the end of the literal table, used to emit the
7967 ; 32bit branch labels if needed.
7968
7969 (define_insn "consttable_end"
7970   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7971   ""
7972   "* return output_jump_label_table ();"
7973   [(set_attr "in_delay_slot" "no")])
7974
7975 ; emitted at the end of the window in the literal table.
7976
7977 (define_insn "consttable_window_end"
7978   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7979   ""
7980   ""
7981   [(set_attr "length" "0")
7982    (set_attr "in_delay_slot" "no")])
7983
7984 ;; -------------------------------------------------------------------------
7985 ;; Misc
7986 ;; -------------------------------------------------------------------------
7987
7988 ;; String/block move insn.
7989
7990 (define_expand "movstrsi"
7991   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7992                    (mem:BLK (match_operand:BLK 1 "" "")))
7993               (use (match_operand:SI 2 "nonmemory_operand" ""))
7994               (use (match_operand:SI 3 "immediate_operand" ""))
7995               (clobber (reg:SI PR_REG))
7996               (clobber (reg:SI R4_REG))
7997               (clobber (reg:SI R5_REG))
7998               (clobber (reg:SI R0_REG))])]
7999   "TARGET_SH1 && ! TARGET_SH5"
8000   "
8001 {
8002   if(expand_block_move (operands))
8003      DONE;
8004   else FAIL;
8005 }")
8006
8007 (define_insn "block_move_real"
8008   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8009                    (mem:BLK (reg:SI R5_REG)))
8010               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8011               (clobber (reg:SI PR_REG))
8012               (clobber (reg:SI R0_REG))])]
8013   "TARGET_SH1 && ! TARGET_HARD_SH4"
8014   "jsr  @%0%#"
8015   [(set_attr "type" "sfunc")
8016    (set_attr "needs_delay_slot" "yes")])
8017
8018 (define_insn "block_lump_real"
8019   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8020                    (mem:BLK (reg:SI R5_REG)))
8021               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8022               (use (reg:SI R6_REG))
8023               (clobber (reg:SI PR_REG))
8024               (clobber (reg:SI T_REG))
8025               (clobber (reg:SI R4_REG))
8026               (clobber (reg:SI R5_REG))
8027               (clobber (reg:SI R6_REG))
8028               (clobber (reg:SI R0_REG))])]
8029   "TARGET_SH1 && ! TARGET_HARD_SH4"
8030   "jsr  @%0%#"
8031   [(set_attr "type" "sfunc")
8032    (set_attr "needs_delay_slot" "yes")])
8033
8034 (define_insn "block_move_real_i4"
8035   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8036                    (mem:BLK (reg:SI R5_REG)))
8037               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8038               (clobber (reg:SI PR_REG))
8039               (clobber (reg:SI R0_REG))
8040               (clobber (reg:SI R1_REG))
8041               (clobber (reg:SI R2_REG))])]
8042   "TARGET_HARD_SH4"
8043   "jsr  @%0%#"
8044   [(set_attr "type" "sfunc")
8045    (set_attr "needs_delay_slot" "yes")])
8046
8047 (define_insn "block_lump_real_i4"
8048   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8049                    (mem:BLK (reg:SI R5_REG)))
8050               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8051               (use (reg:SI R6_REG))
8052               (clobber (reg:SI PR_REG))
8053               (clobber (reg:SI T_REG))
8054               (clobber (reg:SI R4_REG))
8055               (clobber (reg:SI R5_REG))
8056               (clobber (reg:SI R6_REG))
8057               (clobber (reg:SI R0_REG))
8058               (clobber (reg:SI R1_REG))
8059               (clobber (reg:SI R2_REG))
8060               (clobber (reg:SI R3_REG))])]
8061   "TARGET_HARD_SH4"
8062   "jsr  @%0%#"
8063   [(set_attr "type" "sfunc")
8064    (set_attr "needs_delay_slot" "yes")])
8065 \f
8066 ;; -------------------------------------------------------------------------
8067 ;; Floating point instructions.
8068 ;; -------------------------------------------------------------------------
8069
8070 ;; ??? All patterns should have a type attribute.
8071
8072 (define_expand "fpu_switch0"
8073   [(set (match_operand:SI 0 "" "") (match_dup 2))
8074    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8075   "TARGET_SH4"
8076   "
8077 {
8078   operands[1] = get_fpscr_rtx ();
8079   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8080   if (flag_pic)
8081     operands[2] = legitimize_pic_address (operands[2], SImode,
8082                                           no_new_pseudos ? operands[0] : 0);
8083 }")
8084
8085 (define_expand "fpu_switch1"
8086   [(set (match_operand:SI 0 "" "") (match_dup 2))
8087    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8088    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8089   "TARGET_SH4"
8090   "
8091 {
8092   operands[1] = get_fpscr_rtx ();
8093   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8094   if (flag_pic)
8095     operands[2] = legitimize_pic_address (operands[2], SImode,
8096                                           no_new_pseudos ? operands[0] : 0);
8097   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8098 }")
8099
8100 (define_expand "movpsi"
8101   [(set (match_operand:PSI 0 "register_operand" "")
8102         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8103   "TARGET_SH4"
8104   "")
8105
8106 ;; The c / m alternative is a fake to guide reload to load directly into
8107 ;; fpscr, since reload doesn't know how to use post-increment.
8108 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8109 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8110 ;; predicate after reload.
8111 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8112 ;; like a mac -> gpr move.
8113 (define_insn "fpu_switch"
8114   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8115         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8116   "TARGET_SH2E
8117    && (! reload_completed
8118        || true_regnum (operands[0]) != FPSCR_REG
8119        || GET_CODE (operands[1]) != MEM
8120        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8121   "@
8122         ! precision stays the same
8123         lds.l   %1,fpscr
8124         mov.l   %1,%0
8125         #
8126         lds     %1,fpscr
8127         mov     %1,%0
8128         mov.l   %1,%0
8129         sts     fpscr,%0
8130         sts.l   fpscr,%0"
8131   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8132    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8133
8134 (define_split
8135   [(set (reg:PSI FPSCR_REG)
8136         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8137   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8138   [(set (match_dup 0) (match_dup 0))]
8139   "
8140 {
8141   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8142                                         gen_rtx (MEM, PSImode,
8143                                                  gen_rtx (POST_INC, Pmode,
8144                                                           operands[0]))));
8145   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8146 }")
8147
8148 (define_split
8149   [(set (reg:PSI FPSCR_REG)
8150         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8151   "TARGET_SH4"
8152   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8153   "
8154 {
8155   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8156                                         gen_rtx (MEM, PSImode,
8157                                                  gen_rtx (POST_INC, Pmode,
8158                                                           operands[0]))));
8159   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8160 }")
8161
8162 ;; ??? This uses the fp unit, but has no type indicating that.
8163 ;; If we did that, this would either give a bogus latency or introduce
8164 ;; a bogus FIFO constraint.
8165 ;; Since this insn is currently only used for prologues/epilogues,
8166 ;; it is probably best to claim no function unit, which matches the
8167 ;; current setting.
8168 (define_insn "toggle_sz"
8169   [(set (reg:PSI FPSCR_REG)
8170         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8171   "TARGET_SH4"
8172   "fschg")
8173
8174 (define_expand "addsf3"
8175   [(set (match_operand:SF 0 "arith_reg_operand" "")
8176         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8177                  (match_operand:SF 2 "arith_reg_operand" "")))]
8178   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8179   "
8180 {
8181   if (TARGET_SH2E)
8182     {
8183       expand_sf_binop (&gen_addsf3_i, operands);
8184       DONE;
8185     }
8186 }")
8187
8188 (define_insn "*addsf3_media"
8189   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8190         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8191                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8192   "TARGET_SHMEDIA_FPU"
8193   "fadd.s       %1, %2, %0"
8194   [(set_attr "type" "fparith_media")])
8195
8196 (define_insn_and_split "unary_sf_op"
8197   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8198         (vec_select:V2SF
8199          (vec_concat:V2SF
8200           (vec_select:SF
8201            (match_dup 0)
8202            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8203           (match_operator:SF 2 "unary_float_operator"
8204             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8205                             (parallel [(match_operand 4
8206                                         "const_int_operand" "n")]))]))
8207          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8208   "TARGET_SHMEDIA_FPU"
8209   "#"
8210   "TARGET_SHMEDIA_FPU && reload_completed"
8211   [(set (match_dup 5) (match_dup 6))]
8212   "
8213 {
8214   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8215   rtx op1 = gen_rtx_REG (SFmode,
8216                          (true_regnum (operands[1])
8217                           + (INTVAL (operands[4]) ^ endian)));
8218
8219   operands[7] = gen_rtx_REG (SFmode,
8220                              (true_regnum (operands[0])
8221                               + (INTVAL (operands[3]) ^ endian)));
8222   operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8223 }"
8224   [(set_attr "type" "fparith_media")])
8225
8226 (define_insn_and_split "binary_sf_op"
8227   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8228         (vec_select:V2SF
8229          (vec_concat:V2SF
8230           (vec_select:SF
8231            (match_dup 0)
8232            (parallel [(match_operand 7 "const_int_operand" "n")]))
8233           (match_operator:SF 3 "binary_float_operator"
8234             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8235                             (parallel [(match_operand 5
8236                                         "const_int_operand" "n")]))
8237              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8238                             (parallel [(match_operand 6
8239                                         "const_int_operand" "n")]))]))
8240          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8241   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8242   "#"
8243   "&& reload_completed"
8244   [(set (match_dup 8) (match_dup 9))]
8245   "
8246 {
8247   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8248   rtx op1 = gen_rtx_REG (SFmode,
8249                          (true_regnum (operands[1])
8250                           + (INTVAL (operands[5]) ^ endian)));
8251   rtx op2 = gen_rtx_REG (SFmode,
8252                          (true_regnum (operands[2])
8253                           + (INTVAL (operands[6]) ^ endian)));
8254
8255   operands[8] = gen_rtx_REG (SFmode,
8256                              (true_regnum (operands[0])
8257                               + (INTVAL (operands[4]) ^ endian)));
8258   operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8259 }"
8260   [(set_attr "type" "fparith_media")])
8261
8262 (define_insn "addsf3_i"
8263   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8264         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8265                  (match_operand:SF 2 "arith_reg_operand" "f")))
8266    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8267   "TARGET_SH2E"
8268   "fadd %2,%0"
8269   [(set_attr "type" "fp")
8270    (set_attr "fp_mode" "single")])
8271
8272 (define_expand "subsf3"
8273   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8274         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8275                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8276   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8277   "
8278 {
8279   if (TARGET_SH2E)
8280     {
8281       expand_sf_binop (&gen_subsf3_i, operands);
8282       DONE;
8283     }
8284 }")
8285
8286 (define_insn "*subsf3_media"
8287   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8288         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8289                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8290   "TARGET_SHMEDIA_FPU"
8291   "fsub.s       %1, %2, %0"
8292   [(set_attr "type" "fparith_media")])
8293
8294 (define_insn "subsf3_i"
8295   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8296         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8297                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8298    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8299   "TARGET_SH2E"
8300   "fsub %2,%0"
8301   [(set_attr "type" "fp")
8302    (set_attr "fp_mode" "single")])
8303
8304 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8305 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8306 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8307 ;; SH3E, we use a separate insn for SH3E mulsf3.
8308
8309 (define_expand "mulsf3"
8310   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8311         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8312                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8313   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8314   "
8315 {
8316   if (TARGET_SH4)
8317     expand_sf_binop (&gen_mulsf3_i4, operands);
8318   else if (TARGET_SH2E)
8319     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8320   if (! TARGET_SHMEDIA)
8321     DONE;
8322 }")
8323
8324 (define_insn "*mulsf3_media"
8325   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8326         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8327                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8328   "TARGET_SHMEDIA_FPU"
8329   "fmul.s       %1, %2, %0"
8330   [(set_attr "type" "fparith_media")])
8331
8332 (define_insn "mulsf3_i4"
8333   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8334         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8335                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8336    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8337   "TARGET_SH2E"
8338   "fmul %2,%0"
8339   [(set_attr "type" "fp")
8340    (set_attr "fp_mode" "single")])
8341
8342 (define_insn "mulsf3_ie"
8343   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8344         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8345                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8346   "TARGET_SH2E && ! TARGET_SH4"
8347   "fmul %2,%0"
8348   [(set_attr "type" "fp")])
8349
8350 (define_insn "*mac_media"
8351   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8352         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8353                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8354                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8355   "TARGET_SHMEDIA_FPU"
8356   "fmac.s %1, %2, %0"
8357   [(set_attr "type" "fparith_media")])
8358
8359 (define_insn "*macsf3"
8360   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8361         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8362                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8363                  (match_operand:SF 3 "arith_reg_operand" "0")))
8364    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8365   "TARGET_SH2E && ! TARGET_SH4"
8366   "fmac fr0,%2,%0"
8367   [(set_attr "type" "fp")
8368    (set_attr "fp_mode" "single")])
8369
8370 (define_expand "divsf3"
8371   [(set (match_operand:SF 0 "arith_reg_operand" "")
8372         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8373                 (match_operand:SF 2 "arith_reg_operand" "")))]
8374   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8375   "
8376 {
8377   if (TARGET_SH2E)
8378     {
8379       expand_sf_binop (&gen_divsf3_i, operands);
8380       DONE;
8381     }
8382 }")
8383
8384 (define_insn "*divsf3_media"
8385   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8386         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8387                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8388   "TARGET_SHMEDIA_FPU"
8389   "fdiv.s       %1, %2, %0"
8390   [(set_attr "type" "fdiv_media")])
8391
8392 (define_insn "divsf3_i"
8393   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8394         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8395                  (match_operand:SF 2 "arith_reg_operand" "f")))
8396    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8397   "TARGET_SH2E"
8398   "fdiv %2,%0"
8399   [(set_attr "type" "fdiv")
8400    (set_attr "fp_mode" "single")])
8401
8402 (define_insn "floatdisf2"
8403   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8404         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8405   "TARGET_SHMEDIA_FPU"
8406   "float.qs %1, %0"
8407   [(set_attr "type" "fpconv_media")])
8408
8409 (define_expand "floatsisf2"
8410   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8411         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8412   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8413   "
8414 {
8415   if (TARGET_SH4)
8416     {
8417       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8418       DONE;
8419     }
8420 }")
8421
8422 (define_insn "*floatsisf2_media"
8423   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8424         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8425   "TARGET_SHMEDIA_FPU"
8426   "float.ls     %1, %0"
8427   [(set_attr "type" "fpconv_media")])
8428
8429 (define_insn "floatsisf2_i4"
8430   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8431         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8432    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8433   "TARGET_SH4"
8434   "float        %1,%0"
8435   [(set_attr "type" "fp")
8436    (set_attr "fp_mode" "single")])
8437
8438 (define_insn "*floatsisf2_ie"
8439   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8440         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8441   "TARGET_SH2E && ! TARGET_SH4"
8442   "float        %1,%0"
8443   [(set_attr "type" "fp")])
8444
8445 (define_insn "fix_truncsfdi2"
8446   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8447         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8448   "TARGET_SHMEDIA_FPU"
8449   "ftrc.sq %1, %0"
8450   [(set_attr "type" "fpconv_media")])
8451
8452 (define_expand "fix_truncsfsi2"
8453   [(set (match_operand:SI 0 "fpul_operand" "=y")
8454         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8455   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8456   "
8457 {
8458   if (TARGET_SH4)
8459     {
8460       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8461       DONE;
8462     }
8463 }")
8464
8465 (define_insn "*fix_truncsfsi2_media"
8466   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8467         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8468   "TARGET_SHMEDIA_FPU"
8469   "ftrc.sl      %1, %0"
8470   [(set_attr "type" "fpconv_media")])
8471
8472 (define_insn "fix_truncsfsi2_i4"
8473   [(set (match_operand:SI 0 "fpul_operand" "=y")
8474         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8475    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8476   "TARGET_SH4"
8477   "ftrc %1,%0"
8478   [(set_attr "type" "ftrc_s")
8479    (set_attr "fp_mode" "single")])
8480
8481 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8482 ;; fix_truncsfsi2_i4.
8483 ;; (define_insn "fix_truncsfsi2_i4_2"
8484 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8485 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8486 ;;   (use (reg:PSI FPSCR_REG))
8487 ;;   (clobber (reg:SI FPUL_REG))]
8488 ;;  "TARGET_SH4"
8489 ;;  "#"
8490 ;;  [(set_attr "length" "4")
8491 ;;   (set_attr "fp_mode" "single")])
8492
8493 ;;(define_split
8494 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8495 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8496 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8497 ;;   (clobber (reg:SI FPUL_REG))]
8498 ;;  "TARGET_SH4"
8499 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8500 ;;            (use (match_dup 2))])
8501 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8502
8503 (define_insn "*fixsfsi"
8504   [(set (match_operand:SI 0 "fpul_operand" "=y")
8505         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8506   "TARGET_SH2E && ! TARGET_SH4"
8507   "ftrc %1,%0"
8508   [(set_attr "type" "fp")])
8509
8510 (define_insn "cmpgtsf_t"
8511   [(set (reg:SI T_REG)
8512         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8513                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8514   "TARGET_SH2E && ! TARGET_SH4"
8515   "fcmp/gt      %1,%0"
8516   [(set_attr "type" "fp")
8517    (set_attr "fp_mode" "single")])
8518
8519 (define_insn "cmpeqsf_t"
8520   [(set (reg:SI T_REG)
8521         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8522                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8523   "TARGET_SH2E && ! TARGET_SH4"
8524   "fcmp/eq      %1,%0"
8525   [(set_attr "type" "fp")
8526    (set_attr "fp_mode" "single")])
8527
8528 (define_insn "ieee_ccmpeqsf_t"
8529   [(set (reg:SI T_REG)
8530         (ior:SI (reg:SI T_REG)
8531                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8532                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8533   "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8534   "* return output_ieee_ccmpeq (insn, operands);"
8535   [(set_attr "length" "4")])
8536
8537
8538 (define_insn "cmpgtsf_t_i4"
8539   [(set (reg:SI T_REG)
8540         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8541                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8542    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8543   "TARGET_SH4"
8544   "fcmp/gt      %1,%0"
8545   [(set_attr "type" "fp")
8546    (set_attr "fp_mode" "single")])
8547
8548 (define_insn "cmpeqsf_t_i4"
8549   [(set (reg:SI T_REG)
8550         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8551                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8552    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8553   "TARGET_SH4"
8554   "fcmp/eq      %1,%0"
8555   [(set_attr "type" "fp")
8556    (set_attr "fp_mode" "single")])
8557
8558 (define_insn "*ieee_ccmpeqsf_t_4"
8559   [(set (reg:SI T_REG)
8560         (ior:SI (reg:SI T_REG)
8561                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8562                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8563    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8564   "TARGET_IEEE && TARGET_SH4"
8565   "* return output_ieee_ccmpeq (insn, operands);"
8566   [(set_attr "length" "4")
8567    (set_attr "fp_mode" "single")])
8568
8569 (define_insn "cmpeqsf_media"
8570   [(set (match_operand:DI 0 "register_operand" "=r")
8571         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8572                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8573   "TARGET_SHMEDIA_FPU"
8574   "fcmpeq.s     %1, %2, %0"
8575   [(set_attr "type" "fcmp_media")])
8576
8577 (define_insn "cmpgtsf_media"
8578   [(set (match_operand:DI 0 "register_operand" "=r")
8579         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8580                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8581   "TARGET_SHMEDIA_FPU"
8582   "fcmpgt.s     %1, %2, %0"
8583   [(set_attr "type" "fcmp_media")])
8584
8585 (define_insn "cmpgesf_media"
8586   [(set (match_operand:DI 0 "register_operand" "=r")
8587         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8588                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8589   "TARGET_SHMEDIA_FPU"
8590   "fcmpge.s     %1, %2, %0"
8591   [(set_attr "type" "fcmp_media")])
8592
8593 (define_insn "cmpunsf_media"
8594   [(set (match_operand:DI 0 "register_operand" "=r")
8595         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8596                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8597   "TARGET_SHMEDIA_FPU"
8598   "fcmpun.s     %1, %2, %0"
8599   [(set_attr "type" "fcmp_media")])
8600
8601 (define_expand "cmpsf"
8602   [(set (reg:SI T_REG)
8603         (compare (match_operand:SF 0 "arith_operand" "")
8604                  (match_operand:SF 1 "arith_operand" "")))]
8605   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8606   "
8607 {
8608   sh_compare_op0 = operands[0];
8609   sh_compare_op1 = operands[1];
8610   DONE;
8611 }")
8612
8613 (define_expand "negsf2"
8614   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8615         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8616   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8617   "
8618 {
8619   if (TARGET_SH2E)
8620     {
8621       expand_sf_unop (&gen_negsf2_i, operands);
8622       DONE;
8623     }
8624 }")
8625
8626 (define_insn "*negsf2_media"
8627   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8628         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8629   "TARGET_SHMEDIA_FPU"
8630   "fneg.s       %1, %0"
8631   [(set_attr "type" "fmove_media")])
8632
8633 (define_insn "negsf2_i"
8634   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8635         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8636    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8637   "TARGET_SH2E"
8638   "fneg %0"
8639   [(set_attr "type" "fmove")
8640    (set_attr "fp_mode" "single")])
8641
8642 (define_expand "sqrtsf2"
8643   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8644         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8645   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8646   "
8647 {
8648   if (TARGET_SH3E)
8649     {
8650       expand_sf_unop (&gen_sqrtsf2_i, operands);
8651       DONE;
8652     }
8653 }")
8654
8655 (define_insn "*sqrtsf2_media"
8656   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8657         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8658   "TARGET_SHMEDIA_FPU"
8659   "fsqrt.s      %1, %0"
8660   [(set_attr "type" "fdiv_media")])
8661
8662 (define_insn "sqrtsf2_i"
8663   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8664         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8665    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8666   "TARGET_SH3E"
8667   "fsqrt        %0"
8668   [(set_attr "type" "fdiv")
8669    (set_attr "fp_mode" "single")])
8670
8671 (define_expand "abssf2"
8672   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8673         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8674   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8675   "
8676 {
8677   if (TARGET_SH2E)
8678     {
8679       expand_sf_unop (&gen_abssf2_i, operands);
8680       DONE;
8681     }
8682 }")
8683
8684 (define_insn "*abssf2_media"
8685   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8686         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8687   "TARGET_SHMEDIA_FPU"
8688   "fabs.s       %1, %0"
8689   [(set_attr "type" "fmove_media")])
8690
8691 (define_insn "abssf2_i"
8692   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8693         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8694    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8695   "TARGET_SH2E"
8696   "fabs %0"
8697   [(set_attr "type" "fmove")
8698    (set_attr "fp_mode" "single")])
8699
8700 (define_expand "adddf3"
8701   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8702         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8703                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8704   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8705   "
8706 {
8707   if (TARGET_SH4)
8708     {
8709       expand_df_binop (&gen_adddf3_i, operands);
8710       DONE;
8711     }
8712 }")
8713
8714 (define_insn "*adddf3_media"
8715   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8716         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8717                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8718   "TARGET_SHMEDIA_FPU"
8719   "fadd.d       %1, %2, %0"
8720   [(set_attr "type" "dfparith_media")])
8721
8722 (define_insn "adddf3_i"
8723   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8724         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8725                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8726    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8727   "TARGET_SH4"
8728   "fadd %2,%0"
8729   [(set_attr "type" "dfp_arith")
8730    (set_attr "fp_mode" "double")])
8731
8732 (define_expand "subdf3"
8733   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8734         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8735                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8736   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8737   "
8738 {
8739   if (TARGET_SH4)
8740     {
8741       expand_df_binop (&gen_subdf3_i, operands);
8742       DONE;
8743     }
8744 }")
8745
8746 (define_insn "*subdf3_media"
8747   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8748         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8749                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8750   "TARGET_SHMEDIA_FPU"
8751   "fsub.d       %1, %2, %0"
8752   [(set_attr "type" "dfparith_media")])
8753
8754 (define_insn "subdf3_i"
8755   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8756         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8757                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8758    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8759   "TARGET_SH4"
8760   "fsub %2,%0"
8761   [(set_attr "type" "dfp_arith")
8762    (set_attr "fp_mode" "double")])
8763
8764 (define_expand "muldf3"
8765   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8766         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8767                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8768   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8769   "
8770 {
8771   if (TARGET_SH4)
8772     {
8773       expand_df_binop (&gen_muldf3_i, operands);
8774       DONE;
8775     }
8776 }")
8777
8778 (define_insn "*muldf3_media"
8779   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8780         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8781                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8782   "TARGET_SHMEDIA_FPU"
8783   "fmul.d       %1, %2, %0"
8784   [(set_attr "type" "dfmul_media")])
8785
8786 (define_insn "muldf3_i"
8787   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8788         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8789                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8790    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8791   "TARGET_SH4"
8792   "fmul %2,%0"
8793   [(set_attr "type" "dfp_arith")
8794    (set_attr "fp_mode" "double")])
8795
8796 (define_expand "divdf3"
8797   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8798         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8799                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8800   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8801   "
8802 {
8803   if (TARGET_SH4)
8804     {
8805       expand_df_binop (&gen_divdf3_i, operands);
8806       DONE;
8807     }
8808 }")
8809
8810 (define_insn "*divdf3_media"
8811   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8812         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8813                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8814   "TARGET_SHMEDIA_FPU"
8815   "fdiv.d       %1, %2, %0"
8816   [(set_attr "type" "dfdiv_media")])
8817
8818 (define_insn "divdf3_i"
8819   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8820         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8821                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8822    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8823   "TARGET_SH4"
8824   "fdiv %2,%0"
8825   [(set_attr "type" "dfdiv")
8826    (set_attr "fp_mode" "double")])
8827
8828 (define_insn "floatdidf2"
8829   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8830         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8831   "TARGET_SHMEDIA_FPU"
8832   "float.qd     %1, %0"
8833   [(set_attr "type" "dfpconv_media")])
8834
8835 (define_expand "floatsidf2"
8836   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8837         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8838   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8839   "
8840 {
8841   if (TARGET_SH4)
8842     {
8843       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8844                                       get_fpscr_rtx ()));
8845       DONE;
8846     }
8847 }")
8848
8849 (define_insn "*floatsidf2_media"
8850   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8851         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8852   "TARGET_SHMEDIA_FPU"
8853   "float.ld     %1, %0"
8854   [(set_attr "type" "dfpconv_media")])
8855
8856 (define_insn "floatsidf2_i"
8857   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8858         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8859    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8860   "TARGET_SH4"
8861   "float        %1,%0"
8862   [(set_attr "type" "dfp_conv")
8863    (set_attr "fp_mode" "double")])
8864
8865 (define_insn "fix_truncdfdi2"
8866   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8867         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8868   "TARGET_SHMEDIA_FPU"
8869   "ftrc.dq      %1, %0"
8870   [(set_attr "type" "dfpconv_media")])
8871
8872 (define_expand "fix_truncdfsi2"
8873   [(set (match_operand:SI 0 "fpul_operand" "")
8874         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8875   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8876   "
8877 {
8878   if (TARGET_SH4)
8879     {
8880       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8881                                           get_fpscr_rtx ()));
8882       DONE;
8883     }
8884 }")
8885
8886 (define_insn "*fix_truncdfsi2_media"
8887   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8888         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8889   "TARGET_SHMEDIA_FPU"
8890   "ftrc.dl      %1, %0"
8891   [(set_attr "type" "dfpconv_media")])
8892
8893 (define_insn "fix_truncdfsi2_i"
8894   [(set (match_operand:SI 0 "fpul_operand" "=y")
8895         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8896    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8897   "TARGET_SH4"
8898   "ftrc %1,%0"
8899   [(set_attr "type" "dfp_conv")
8900    (set_attr "dfp_comp" "no")
8901    (set_attr "fp_mode" "double")])
8902
8903 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8904 ;; fix_truncdfsi2_i.
8905 ;; (define_insn "fix_truncdfsi2_i4"
8906 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8907 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8908 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8909 ;;    (clobber (reg:SI FPUL_REG))]
8910 ;;   "TARGET_SH4"
8911 ;;   "#"
8912 ;;   [(set_attr "length" "4")
8913 ;;    (set_attr "fp_mode" "double")])
8914 ;;
8915 ;; (define_split
8916 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8917 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8918 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8919 ;;    (clobber (reg:SI FPUL_REG))]
8920 ;;   "TARGET_SH4"
8921 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8922 ;;            (use (match_dup 2))])
8923 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
8924
8925 (define_insn "cmpgtdf_t"
8926   [(set (reg:SI T_REG)
8927         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8928                (match_operand:DF 1 "arith_reg_operand" "f")))
8929    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8930   "TARGET_SH4"
8931   "fcmp/gt      %1,%0"
8932   [(set_attr "type" "dfp_cmp")
8933    (set_attr "fp_mode" "double")])
8934
8935 (define_insn "cmpeqdf_t"
8936   [(set (reg:SI T_REG)
8937         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8938                (match_operand:DF 1 "arith_reg_operand" "f")))
8939    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8940   "TARGET_SH4"
8941   "fcmp/eq      %1,%0"
8942   [(set_attr "type" "dfp_cmp")
8943    (set_attr "fp_mode" "double")])
8944
8945 (define_insn "*ieee_ccmpeqdf_t"
8946   [(set (reg:SI T_REG)
8947         (ior:SI (reg:SI T_REG)
8948                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8949                        (match_operand:DF 1 "arith_reg_operand" "f"))))
8950    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8951   "TARGET_IEEE && TARGET_SH4"
8952   "* return output_ieee_ccmpeq (insn, operands);"
8953   [(set_attr "length" "4")
8954    (set_attr "fp_mode" "double")])
8955
8956 (define_insn "cmpeqdf_media"
8957   [(set (match_operand:DI 0 "register_operand" "=r")
8958         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8959                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8960   "TARGET_SHMEDIA_FPU"
8961   "fcmpeq.d     %1,%2,%0"
8962   [(set_attr "type" "fcmp_media")])
8963
8964 (define_insn "cmpgtdf_media"
8965   [(set (match_operand:DI 0 "register_operand" "=r")
8966         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8967                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8968   "TARGET_SHMEDIA_FPU"
8969   "fcmpgt.d     %1,%2,%0"
8970   [(set_attr "type" "fcmp_media")])
8971
8972 (define_insn "cmpgedf_media"
8973   [(set (match_operand:DI 0 "register_operand" "=r")
8974         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8975                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8976   "TARGET_SHMEDIA_FPU"
8977   "fcmpge.d     %1,%2,%0"
8978   [(set_attr "type" "fcmp_media")])
8979
8980 (define_insn "cmpundf_media"
8981   [(set (match_operand:DI 0 "register_operand" "=r")
8982         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8983                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8984   "TARGET_SHMEDIA_FPU"
8985   "fcmpun.d     %1,%2,%0"
8986   [(set_attr "type" "fcmp_media")])
8987
8988 (define_expand "cmpdf"
8989   [(set (reg:SI T_REG)
8990         (compare (match_operand:DF 0 "arith_operand" "")
8991                  (match_operand:DF 1 "arith_operand" "")))]
8992   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8993   "
8994 {
8995   sh_compare_op0 = operands[0];
8996   sh_compare_op1 = operands[1];
8997   DONE;
8998 }")
8999
9000 (define_expand "negdf2"
9001   [(set (match_operand:DF 0 "arith_reg_operand" "")
9002         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9003   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9004   "
9005 {
9006   if (TARGET_SH4)
9007     {
9008       expand_df_unop (&gen_negdf2_i, operands);
9009       DONE;
9010     }
9011 }")
9012
9013 (define_insn "*negdf2_media"
9014   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9015         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9016   "TARGET_SHMEDIA_FPU"
9017   "fneg.d       %1, %0"
9018   [(set_attr "type" "fmove_media")])
9019
9020 (define_insn "negdf2_i"
9021   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9022         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9023    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9024   "TARGET_SH4"
9025   "fneg %0"
9026   [(set_attr "type" "fmove")
9027    (set_attr "fp_mode" "double")])
9028
9029 (define_expand "sqrtdf2"
9030   [(set (match_operand:DF 0 "arith_reg_operand" "")
9031         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9032   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9033   "
9034 {
9035   if (TARGET_SH4)
9036     {
9037       expand_df_unop (&gen_sqrtdf2_i, operands);
9038       DONE;
9039     }
9040 }")
9041
9042 (define_insn "*sqrtdf2_media"
9043   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9044         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9045   "TARGET_SHMEDIA_FPU"
9046   "fsqrt.d      %1, %0"
9047   [(set_attr "type" "dfdiv_media")])
9048
9049 (define_insn "sqrtdf2_i"
9050   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9051         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9052    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9053   "TARGET_SH4"
9054   "fsqrt        %0"
9055   [(set_attr "type" "dfdiv")
9056    (set_attr "fp_mode" "double")])
9057
9058 (define_expand "absdf2"
9059   [(set (match_operand:DF 0 "arith_reg_operand" "")
9060         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9061   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9062   "
9063 {
9064   if (TARGET_SH4)
9065     {
9066       expand_df_unop (&gen_absdf2_i, operands);
9067       DONE;
9068     }
9069 }")
9070
9071 (define_insn "*absdf2_media"
9072   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9073         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9074   "TARGET_SHMEDIA_FPU"
9075   "fabs.d       %1, %0"
9076   [(set_attr "type" "fmove_media")])
9077
9078 (define_insn "absdf2_i"
9079   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9080         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9081    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9082   "TARGET_SH4"
9083   "fabs %0"
9084   [(set_attr "type" "fmove")
9085    (set_attr "fp_mode" "double")])
9086
9087 (define_expand "extendsfdf2"
9088   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9089         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9090   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9091   "
9092 {
9093   if (TARGET_SH4)
9094     {
9095       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9096                                         get_fpscr_rtx ()));
9097       DONE;
9098     }
9099 }")
9100
9101 (define_insn "*extendsfdf2_media"
9102   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9103         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9104   "TARGET_SHMEDIA_FPU"
9105   "fcnv.sd      %1, %0"
9106   [(set_attr "type" "dfpconv_media")])
9107
9108 (define_insn "extendsfdf2_i4"
9109   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9110         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9111    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9112   "TARGET_SH4"
9113   "fcnvsd  %1,%0"
9114   [(set_attr "type" "fp")
9115    (set_attr "fp_mode" "double")])
9116
9117 (define_expand "truncdfsf2"
9118   [(set (match_operand:SF 0 "fpul_operand" "")
9119         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9120   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9121   "
9122 {
9123   if (TARGET_SH4)
9124     {
9125       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9126                                        get_fpscr_rtx ()));
9127       DONE;
9128     }
9129 }")
9130
9131 (define_insn "*truncdfsf2_media"
9132   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9133         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9134   "TARGET_SHMEDIA_FPU"
9135   "fcnv.ds      %1, %0"
9136   [(set_attr "type" "dfpconv_media")])
9137
9138 (define_insn "truncdfsf2_i4"
9139   [(set (match_operand:SF 0 "fpul_operand" "=y")
9140         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9141    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9142   "TARGET_SH4"
9143   "fcnvds  %1,%0"
9144   [(set_attr "type" "fp")
9145    (set_attr "fp_mode" "double")])
9146 \f
9147 ;; Bit field extract patterns.  These give better code for packed bitfields,
9148 ;; because they allow auto-increment addresses to be generated.
9149
9150 (define_expand "insv"
9151   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9152                          (match_operand:SI 1 "immediate_operand" "")
9153                          (match_operand:SI 2 "immediate_operand" ""))
9154         (match_operand:SI 3 "general_operand" ""))]
9155   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9156   "
9157 {
9158   rtx addr_target, orig_address, shift_reg, qi_val;
9159   HOST_WIDE_INT bitsize, size, v;
9160   rtx x = operands[3];
9161
9162   /* ??? expmed doesn't care for non-register predicates.  */
9163   if (! memory_operand (operands[0], VOIDmode)
9164       || ! immediate_operand (operands[1], VOIDmode)
9165       || ! immediate_operand (operands[2], VOIDmode)
9166       || ! general_operand (x, VOIDmode))
9167     FAIL;
9168   /* If this isn't a 16 / 24 / 32 bit field, or if
9169      it doesn't start on a byte boundary, then fail.  */
9170   bitsize = INTVAL (operands[1]);
9171   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9172       || (INTVAL (operands[2]) % 8) != 0)
9173     FAIL;
9174
9175   size = bitsize / 8;
9176   orig_address = XEXP (operands[0], 0);
9177   shift_reg = gen_reg_rtx (SImode);
9178   if (GET_CODE (x) == CONST_INT)
9179     {
9180       v = INTVAL (x);
9181       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9182     }
9183   else
9184     {
9185       emit_insn (gen_movsi (shift_reg, operands[3]));
9186       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9187     }
9188   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9189
9190   operands[0] = replace_equiv_address (operands[0], addr_target);
9191   emit_insn (gen_movqi (operands[0], qi_val));
9192
9193   while (size -= 1)
9194     {
9195       if (GET_CODE (x) == CONST_INT)
9196         qi_val
9197           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9198       else
9199         {
9200           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9201           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9202         }
9203       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9204       emit_insn (gen_movqi (operands[0], qi_val));
9205     }
9206
9207   DONE;
9208 }")
9209 \f
9210 ;; -------------------------------------------------------------------------
9211 ;; Peepholes
9212 ;; -------------------------------------------------------------------------
9213
9214 ;; This matches cases where a stack pointer increment at the start of the
9215 ;; epilogue combines with a stack slot read loading the return value.
9216
9217 (define_peephole
9218   [(set (match_operand:SI 0 "arith_reg_operand" "")
9219         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9220    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9221   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9222   "mov.l        @%1+,%0")
9223
9224 ;; See the comment on the dt combiner pattern above.
9225
9226 (define_peephole
9227   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9228         (plus:SI (match_dup 0)
9229                  (const_int -1)))
9230    (set (reg:SI T_REG)
9231         (eq:SI (match_dup 0)
9232                (const_int 0)))]
9233   "TARGET_SH2"
9234   "dt   %0")
9235
9236 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9237 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9238 ;; reload when the constant is too large for a reg+offset address.
9239
9240 ;; ??? We would get much better code if this was done in reload.  This would
9241 ;; require modifying find_reloads_address to recognize that if the constant
9242 ;; is out-of-range for an immediate add, then we get better code by reloading
9243 ;; the constant into a register than by reloading the sum into a register,
9244 ;; since the former is one instruction shorter if the address does not need
9245 ;; to be offsettable.  Unfortunately this does not work, because there is
9246 ;; only one register, r0, that can be used as an index register.  This register
9247 ;; is also the function return value register.  So, if we try to force reload
9248 ;; to use double-reg addresses, then we end up with some instructions that
9249 ;; need to use r0 twice.  The only way to fix this is to change the calling
9250 ;; convention so that r0 is not used to return values.
9251
9252 (define_peephole
9253   [(set (match_operand:SI 0 "register_operand" "=r")
9254         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9255    (set (mem:SI (match_dup 0))
9256         (match_operand:SI 2 "general_movsrc_operand" ""))]
9257   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9258   "mov.l        %2,@(%0,%1)")
9259
9260 (define_peephole
9261   [(set (match_operand:SI 0 "register_operand" "=r")
9262         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9263    (set (match_operand:SI 2 "general_movdst_operand" "")
9264         (mem:SI (match_dup 0)))]
9265   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9266   "mov.l        @(%0,%1),%2")
9267
9268 (define_peephole
9269   [(set (match_operand:SI 0 "register_operand" "=r")
9270         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9271    (set (mem:HI (match_dup 0))
9272         (match_operand:HI 2 "general_movsrc_operand" ""))]
9273   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9274   "mov.w        %2,@(%0,%1)")
9275
9276 (define_peephole
9277   [(set (match_operand:SI 0 "register_operand" "=r")
9278         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9279    (set (match_operand:HI 2 "general_movdst_operand" "")
9280         (mem:HI (match_dup 0)))]
9281   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9282   "mov.w        @(%0,%1),%2")
9283
9284 (define_peephole
9285   [(set (match_operand:SI 0 "register_operand" "=r")
9286         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9287    (set (mem:QI (match_dup 0))
9288         (match_operand:QI 2 "general_movsrc_operand" ""))]
9289   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9290   "mov.b        %2,@(%0,%1)")
9291
9292 (define_peephole
9293   [(set (match_operand:SI 0 "register_operand" "=r")
9294         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9295    (set (match_operand:QI 2 "general_movdst_operand" "")
9296         (mem:QI (match_dup 0)))]
9297   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9298   "mov.b        @(%0,%1),%2")
9299
9300 (define_peephole
9301   [(set (match_operand:SI 0 "register_operand" "=r")
9302         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9303    (set (mem:SF (match_dup 0))
9304         (match_operand:SF 2 "general_movsrc_operand" ""))]
9305   "TARGET_SH1 && REGNO (operands[0]) == 0
9306    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9307        || (GET_CODE (operands[2]) == SUBREG
9308            && REGNO (SUBREG_REG (operands[2])) < 16))
9309    && reg_unused_after (operands[0], insn)"
9310   "mov.l        %2,@(%0,%1)")
9311
9312 (define_peephole
9313   [(set (match_operand:SI 0 "register_operand" "=r")
9314         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9315    (set (match_operand:SF 2 "general_movdst_operand" "")
9316
9317         (mem:SF (match_dup 0)))]
9318   "TARGET_SH1 && REGNO (operands[0]) == 0
9319    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9320        || (GET_CODE (operands[2]) == SUBREG
9321            && REGNO (SUBREG_REG (operands[2])) < 16))
9322    && reg_unused_after (operands[0], insn)"
9323   "mov.l        @(%0,%1),%2")
9324
9325 (define_peephole
9326   [(set (match_operand:SI 0 "register_operand" "=r")
9327         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9328    (set (mem:SF (match_dup 0))
9329         (match_operand:SF 2 "general_movsrc_operand" ""))]
9330   "TARGET_SH2E && REGNO (operands[0]) == 0
9331    && ((GET_CODE (operands[2]) == REG
9332         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9333        || (GET_CODE (operands[2]) == SUBREG
9334            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9335    && reg_unused_after (operands[0], insn)"
9336   "fmov{.s|}    %2,@(%0,%1)")
9337
9338 (define_peephole
9339   [(set (match_operand:SI 0 "register_operand" "=r")
9340         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9341    (set (match_operand:SF 2 "general_movdst_operand" "")
9342
9343         (mem:SF (match_dup 0)))]
9344   "TARGET_SH2E && REGNO (operands[0]) == 0
9345    && ((GET_CODE (operands[2]) == REG
9346         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9347        || (GET_CODE (operands[2]) == SUBREG
9348            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9349    && reg_unused_after (operands[0], insn)"
9350   "fmov{.s|}    @(%0,%1),%2")
9351
9352 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9353 (define_insn "sp_switch_1"
9354   [(const_int 1)]
9355   "TARGET_SH1"
9356   "*
9357 {
9358   rtx xoperands[1];
9359
9360   xoperands[0] = sp_switch;
9361   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9362   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9363   return \"mov r0,r15\";
9364 }"
9365   [(set_attr "length" "10")])
9366
9367 ;; Switch back to the original stack for interrupt functions with the
9368 ;; sp_switch attribute.  */
9369 (define_insn "sp_switch_2"
9370   [(const_int 2)]
9371   "TARGET_SH1"
9372   "mov.l @r15+,r15\;mov.l @r15+,r0"
9373   [(set_attr "length" "4")])
9374
9375 ;; Integer vector moves
9376
9377 (define_expand "movv8qi"
9378   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9379         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9380   "TARGET_SHMEDIA"
9381   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9382
9383 (define_insn "movv8qi_i"
9384   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9385         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9386   "TARGET_SHMEDIA
9387    && (register_operand (operands[0], V8QImode)
9388        || sh_register_operand (operands[1], V8QImode))"
9389   "@
9390         add     %1, r63, %0
9391         movi    %1, %0
9392         #
9393         ld%M1.q %m1, %0
9394         st%M0.q %m0, %N1"
9395   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9396    (set_attr "length" "4,4,16,4,4")])
9397
9398 (define_split
9399   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9400         (subreg:V8QI (const_int 0) 0))]
9401   "TARGET_SHMEDIA"
9402   [(set (match_dup 0)
9403         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9404                             (const_int 0) (const_int 0) (const_int 0)
9405                             (const_int 0) (const_int 0)]))])
9406
9407 (define_split
9408   [(set (match_operand 0 "arith_reg_dest" "")
9409         (match_operand 1 "sh_rep_vec" ""))]
9410   "TARGET_SHMEDIA && reload_completed
9411    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9412    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9413    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9414    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9415        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9416    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9417        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9418   [(set (match_dup 0) (match_dup 1))
9419    (match_dup 2)]
9420   "
9421 {
9422   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9423   rtx elt1 = XVECEXP (operands[1], 0, 1);
9424
9425   if (unit_size > 2)
9426     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9427   else
9428     {
9429       if (unit_size < 2)
9430         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9431       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9432     }
9433   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9434   operands[1] = XVECEXP (operands[1], 0, 0);
9435   if (unit_size < 2)
9436     {
9437       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9438         operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9439                                ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9440                                : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9441       else
9442         {
9443           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9444           operands[1]
9445             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9446         }
9447     }
9448 }")
9449
9450 (define_split
9451   [(set (match_operand 0 "arith_reg_dest" "")
9452         (match_operand 1 "sh_const_vec" ""))]
9453   "TARGET_SHMEDIA && reload_completed
9454    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9455    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9456    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9457   [(set (match_dup 0) (match_dup 1))]
9458   "
9459 {
9460   rtx v = operands[1];
9461   enum machine_mode new_mode
9462     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9463
9464   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9465   operands[1]
9466     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9467 }")
9468
9469 (define_expand "movv2hi"
9470   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9471         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9472   "TARGET_SHMEDIA"
9473   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9474
9475 (define_insn "movv2hi_i"
9476   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9477         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9478   "TARGET_SHMEDIA
9479    && (register_operand (operands[0], V2HImode)
9480        || sh_register_operand (operands[1], V2HImode))"
9481   "@
9482         addz.l  %1, r63, %0
9483         movi    %1, %0
9484         #
9485         ld%M1.l %m1, %0
9486         st%M0.l %m0, %N1"
9487   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9488    (set_attr "length" "4,4,16,4,4")])
9489
9490 (define_expand "movv4hi"
9491   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9492         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9493   "TARGET_SHMEDIA"
9494   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9495
9496 (define_insn "movv4hi_i"
9497   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9498         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9499   "TARGET_SHMEDIA
9500    && (register_operand (operands[0], V4HImode)
9501        || sh_register_operand (operands[1], V4HImode))"
9502   "@
9503         add     %1, r63, %0
9504         movi    %1, %0
9505         #
9506         ld%M1.q %m1, %0
9507         st%M0.q %m0, %N1"
9508   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9509    (set_attr "length" "4,4,16,4,4")])
9510
9511 (define_expand "movv2si"
9512   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9513         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9514   "TARGET_SHMEDIA"
9515   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9516
9517 (define_insn "movv2si_i"
9518   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9519         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9520   "TARGET_SHMEDIA
9521    && (register_operand (operands[0], V2SImode)
9522        || sh_register_operand (operands[1], V2SImode))"
9523   "@
9524         add     %1, r63, %0
9525         #
9526         #
9527         ld%M1.q %m1, %0
9528         st%M0.q %m0, %N1"
9529   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9530    (set_attr "length" "4,4,16,4,4")])
9531
9532 ;; Multimedia Intrinsics
9533
9534 (define_insn "absv2si2"
9535   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9536         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9537   "TARGET_SHMEDIA"
9538   "mabs.l       %1, %0"
9539   [(set_attr "type" "mcmp_media")])
9540
9541 (define_insn "absv4hi2"
9542   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9543         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9544   "TARGET_SHMEDIA"
9545   "mabs.w       %1, %0"
9546   [(set_attr "type" "mcmp_media")])
9547
9548 (define_insn "addv2si3"
9549   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9550         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9551                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9552   "TARGET_SHMEDIA"
9553   "madd.l       %1, %2, %0"
9554   [(set_attr "type" "arith_media")])
9555
9556 (define_insn "addv4hi3"
9557   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9558         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9559                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9560   "TARGET_SHMEDIA"
9561   "madd.w       %1, %2, %0"
9562   [(set_attr "type" "arith_media")])
9563
9564 (define_insn "ssaddv2si3"
9565   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9566         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9567                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9568   "TARGET_SHMEDIA"
9569   "madds.l      %1, %2, %0"
9570   [(set_attr "type" "mcmp_media")])
9571
9572 (define_insn "usaddv8qi3"
9573   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9574         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9575                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9576   "TARGET_SHMEDIA"
9577   "madds.ub     %1, %2, %0"
9578   [(set_attr "type" "mcmp_media")])
9579
9580 (define_insn "ssaddv4hi3"
9581   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9582         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9583                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9584   "TARGET_SHMEDIA"
9585   "madds.w      %1, %2, %0"
9586   [(set_attr "type" "mcmp_media")])
9587
9588 (define_insn "negcmpeqv8qi"
9589   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9590         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9591                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9592   "TARGET_SHMEDIA"
9593   "mcmpeq.b     %N1, %N2, %0"
9594   [(set_attr "type" "mcmp_media")])
9595
9596 (define_insn "negcmpeqv2si"
9597   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9598         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9599                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9600   "TARGET_SHMEDIA"
9601   "mcmpeq.l     %N1, %N2, %0"
9602   [(set_attr "type" "mcmp_media")])
9603
9604 (define_insn "negcmpeqv4hi"
9605   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9606         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9607                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9608   "TARGET_SHMEDIA"
9609   "mcmpeq.w     %N1, %N2, %0"
9610   [(set_attr "type" "mcmp_media")])
9611
9612 (define_insn "negcmpgtuv8qi"
9613   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9614         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9615                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9616   "TARGET_SHMEDIA"
9617   "mcmpgt.ub    %N1, %N2, %0"
9618   [(set_attr "type" "mcmp_media")])
9619
9620 (define_insn "negcmpgtv2si"
9621   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9622         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9623                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9624   "TARGET_SHMEDIA"
9625   "mcmpgt.l     %N1, %N2, %0"
9626   [(set_attr "type" "mcmp_media")])
9627
9628 (define_insn "negcmpgtv4hi"
9629   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9630         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9631                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9632   "TARGET_SHMEDIA"
9633   "mcmpgt.w     %N1, %N2, %0"
9634   [(set_attr "type" "mcmp_media")])
9635
9636 (define_insn "mcmv"
9637   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9638         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9639                         (match_operand:DI 2 "arith_reg_operand" "r"))
9640                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9641                         (not:DI (match_dup 2)))))]
9642   "TARGET_SHMEDIA"
9643   "mcmv %N1, %2, %0"
9644   [(set_attr "type" "arith_media")])
9645
9646 (define_insn "mcnvs_lw"
9647   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9648         (vec_concat:V4HI
9649          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9650          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9651   "TARGET_SHMEDIA"
9652   "mcnvs.lw     %N1, %N2, %0"
9653   [(set_attr "type" "mcmp_media")])
9654
9655 (define_insn "mcnvs_wb"
9656   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9657         (vec_concat:V8QI
9658          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9659          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9660   "TARGET_SHMEDIA"
9661   "mcnvs.wb     %N1, %N2, %0"
9662   [(set_attr "type" "mcmp_media")])
9663
9664 (define_insn "mcnvs_wub"
9665   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9666         (vec_concat:V8QI
9667          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9668          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9669   "TARGET_SHMEDIA"
9670   "mcnvs.wub    %N1, %N2, %0"
9671   [(set_attr "type" "mcmp_media")])
9672
9673 (define_insn "mextr_rl"
9674   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9675         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9676                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9677                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9678                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9679   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9680   "*
9681 {
9682   static char templ[16];
9683
9684   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9685            (int) INTVAL (operands[3]) >> 3);
9686   return templ;
9687 }"
9688   [(set_attr "type" "arith_media")])
9689
9690 (define_insn "*mextr_lr"
9691   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9692         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9693                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9694                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9695                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9696   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9697   "*
9698 {
9699   static char templ[16];
9700
9701   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9702            (int) INTVAL (operands[4]) >> 3);
9703   return templ;
9704 }"
9705   [(set_attr "type" "arith_media")])
9706
9707 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9708 ; vector then varies depending on endianness.
9709 (define_expand "mextr1"
9710   [(match_operand:DI 0 "arith_reg_dest" "")
9711    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9712    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9713   "TARGET_SHMEDIA"
9714   "
9715 {
9716   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9717                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9718   DONE;
9719 }")
9720
9721 (define_expand "mextr2"
9722   [(match_operand:DI 0 "arith_reg_dest" "")
9723    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9724    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9725   "TARGET_SHMEDIA"
9726   "
9727 {
9728   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9729                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9730   DONE;
9731 }")
9732
9733 (define_expand "mextr3"
9734   [(match_operand:DI 0 "arith_reg_dest" "")
9735    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9736    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9737   "TARGET_SHMEDIA"
9738   "
9739 {
9740   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9741                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9742   DONE;
9743 }")
9744
9745 (define_expand "mextr4"
9746   [(match_operand:DI 0 "arith_reg_dest" "")
9747    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9748    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9749   "TARGET_SHMEDIA"
9750   "
9751 {
9752   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9753                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9754   DONE;
9755 }")
9756
9757 (define_expand "mextr5"
9758   [(match_operand:DI 0 "arith_reg_dest" "")
9759    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9760    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9761   "TARGET_SHMEDIA"
9762   "
9763 {
9764   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9765                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9766   DONE;
9767 }")
9768
9769 (define_expand "mextr6"
9770   [(match_operand:DI 0 "arith_reg_dest" "")
9771    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9772    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9773   "TARGET_SHMEDIA"
9774   "
9775 {
9776   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9777                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9778   DONE;
9779 }")
9780
9781 (define_expand "mextr7"
9782   [(match_operand:DI 0 "arith_reg_dest" "")
9783    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9784    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9785   "TARGET_SHMEDIA"
9786   "
9787 {
9788   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9789                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9790   DONE;
9791 }")
9792
9793 (define_expand "mmacfx_wl"
9794   [(match_operand:V2SI 0 "arith_reg_dest" "")
9795    (match_operand:V2HI 1 "extend_reg_operand" "")
9796    (match_operand:V2HI 2 "extend_reg_operand" "")
9797    (match_operand:V2SI 3 "arith_reg_operand" "")]
9798   "TARGET_SHMEDIA"
9799   "
9800 {
9801   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9802                               operands[1], operands[2]));
9803   DONE;
9804 }")
9805
9806 (define_insn "mmacfx_wl_i"
9807   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9808         (ss_plus:V2SI
9809          (match_operand:V2SI 1 "arith_reg_operand" "0")
9810          (ss_truncate:V2SI
9811           (ashift:V2DI
9812            (sign_extend:V2DI
9813             (mult:V2SI
9814              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9815              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9816            (const_int 1)))))]
9817   "TARGET_SHMEDIA"
9818   "mmacfx.wl    %2, %3, %0"
9819   [(set_attr "type" "mac_media")])
9820
9821 (define_expand "mmacnfx_wl"
9822   [(match_operand:V2SI 0 "arith_reg_dest" "")
9823    (match_operand:V2HI 1 "extend_reg_operand" "")
9824    (match_operand:V2HI 2 "extend_reg_operand" "")
9825    (match_operand:V2SI 3 "arith_reg_operand" "")]
9826   "TARGET_SHMEDIA"
9827   "
9828 {
9829   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9830                                operands[1], operands[2]));
9831   DONE;
9832 }")
9833
9834 (define_insn "mmacnfx_wl_i"
9835   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9836         (ss_minus:V2SI
9837          (match_operand:V2SI 1 "arith_reg_operand" "0")
9838          (ss_truncate:V2SI
9839           (ashift:V2DI
9840            (sign_extend:V2DI
9841             (mult:V2SI
9842              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9843              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9844            (const_int 1)))))]
9845   "TARGET_SHMEDIA"
9846   "mmacnfx.wl   %2, %3, %0"
9847   [(set_attr "type" "mac_media")])
9848
9849 (define_insn "mulv2si3"
9850   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9851         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9852                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9853   "TARGET_SHMEDIA"
9854   "mmul.l       %1, %2, %0"
9855   [(set_attr "type" "d2mpy_media")])
9856
9857 (define_insn "mulv4hi3"
9858   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9859         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9860                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9861   "TARGET_SHMEDIA"
9862   "mmul.w       %1, %2, %0"
9863   [(set_attr "type" "dmpy_media")])
9864
9865 (define_insn "mmulfx_l"
9866   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9867         (ss_truncate:V2SI
9868          (ashiftrt:V2DI
9869           (mult:V2DI
9870            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9871            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9872           (const_int 31))))]
9873   "TARGET_SHMEDIA"
9874   "mmulfx.l     %1, %2, %0"
9875   [(set_attr "type" "d2mpy_media")])
9876
9877 (define_insn "mmulfx_w"
9878   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9879         (ss_truncate:V4HI
9880          (ashiftrt:V4SI
9881           (mult:V4SI
9882            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9883            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9884           (const_int 15))))]
9885   "TARGET_SHMEDIA"
9886   "mmulfx.w     %1, %2, %0"
9887   [(set_attr "type" "dmpy_media")])
9888
9889 (define_insn "mmulfxrp_w"
9890   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9891         (ss_truncate:V4HI
9892          (ashiftrt:V4SI
9893           (plus:V4SI
9894            (mult:V4SI
9895             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9896             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9897            (const_int 16384))
9898           (const_int 15))))]
9899   "TARGET_SHMEDIA"
9900   "mmulfxrp.w   %1, %2, %0"
9901   [(set_attr "type" "dmpy_media")])
9902
9903 (define_expand "mmulhi_wl"
9904   [(match_operand:V2SI 0 "arith_reg_dest" "")
9905    (match_operand:V4HI 1 "arith_reg_operand" "")
9906    (match_operand:V4HI 2 "arith_reg_operand" "")]
9907   "TARGET_SHMEDIA"
9908   "
9909 {
9910   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9911              (operands[0], operands[1], operands[2]));
9912   DONE;
9913 }")
9914
9915 (define_expand "mmullo_wl"
9916   [(match_operand:V2SI 0 "arith_reg_dest" "")
9917    (match_operand:V4HI 1 "arith_reg_operand" "")
9918    (match_operand:V4HI 2 "arith_reg_operand" "")]
9919   "TARGET_SHMEDIA"
9920   "
9921 {
9922   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9923              (operands[0], operands[1], operands[2]));
9924   DONE;
9925 }")
9926
9927 (define_insn "mmul23_wl"
9928   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9929         (vec_select:V2SI
9930          (mult:V4SI
9931           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9932           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9933          (parallel [(const_int 2) (const_int 3)])))]
9934   "TARGET_SHMEDIA"
9935   "* return (TARGET_LITTLE_ENDIAN
9936              ? \"mmulhi.wl      %1, %2, %0\"
9937              : \"mmullo.wl      %1, %2, %0\");"
9938   [(set_attr "type" "dmpy_media")])
9939
9940 (define_insn "mmul01_wl"
9941   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9942         (vec_select:V2SI
9943          (mult:V4SI
9944           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9945           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9946          (parallel [(const_int 0) (const_int 1)])))]
9947   "TARGET_SHMEDIA"
9948   "* return (TARGET_LITTLE_ENDIAN
9949              ? \"mmullo.wl      %1, %2, %0\"
9950              : \"mmulhi.wl      %1, %2, %0\");"
9951   [(set_attr "type" "dmpy_media")])
9952
9953 (define_expand "mmulsum_wq"
9954   [(match_operand:DI 0 "arith_reg_dest" "")
9955    (match_operand:V4HI 1 "arith_reg_operand" "")
9956    (match_operand:V4HI 2 "arith_reg_operand" "")
9957    (match_operand:DI 3 "arith_reg_operand" "")]
9958   "TARGET_SHMEDIA"
9959   "
9960 {
9961   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9962                                operands[1], operands[2]));
9963   DONE;
9964 }")
9965
9966 (define_insn "mmulsum_wq_i"
9967   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9968         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9969          (plus:DI
9970           (plus:DI
9971            (vec_select:DI
9972             (mult:V4DI
9973              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9974              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9975             (parallel [(const_int 0)]))
9976            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9977                                      (sign_extend:V4DI (match_dup 3)))
9978                           (parallel [(const_int 1)])))
9979           (plus:DI
9980            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9981                                      (sign_extend:V4DI (match_dup 3)))
9982                           (parallel [(const_int 2)]))
9983            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9984                                      (sign_extend:V4DI (match_dup 3)))
9985                           (parallel [(const_int 3)]))))))]
9986   "TARGET_SHMEDIA"
9987   "mmulsum.wq   %2, %3, %0"
9988   [(set_attr "type" "mac_media")])
9989
9990 (define_expand "mperm_w"
9991   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9992    (match_operand:V4HI 1 "arith_reg_operand" "r")
9993    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
9994   "TARGET_SHMEDIA"
9995   "
9996 {
9997   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9998              (operands[0], operands[1], operands[2]));
9999   DONE;
10000 }")
10001
10002 ; This use of vec_select isn't exactly correct according to rtl.texi
10003 ; (because not constant), but it seems a straightforward extension.
10004 (define_insn "mperm_w_little"
10005   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10006         (vec_select:V4HI
10007          (match_operand:V4HI 1 "arith_reg_operand" "r")
10008          (parallel
10009           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10010                             (const_int 2) (const_int 0))
10011            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10012            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10013            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10014   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10015   "mperm.w      %1, %N2, %0"
10016   [(set_attr "type" "arith_media")])
10017
10018 (define_insn "mperm_w_big"
10019   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10020         (vec_select:V4HI
10021          (match_operand:V4HI 1 "arith_reg_operand" "r")
10022          (parallel
10023           [(zero_extract:QI (not:QI (match_operand:QI 2
10024                                      "extend_reg_or_0_operand" "rZ"))
10025                             (const_int 2) (const_int 0))
10026            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10027            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10028            (zero_extract:QI (not:QI (match_dup 2))
10029                             (const_int 2) (const_int 6))])))]
10030   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10031   "mperm.w      %1, %N2, %0"
10032   [(set_attr "type" "arith_media")])
10033
10034 (define_insn "mperm_w0"
10035   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10036         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10037                                           "trunc_hi_operand" "r"))))]
10038   "TARGET_SHMEDIA"
10039   "mperm.w      %1, r63, %0"
10040   [(set_attr "type" "arith_media")])
10041
10042 (define_expand "msad_ubq"
10043   [(match_operand:DI 0 "arith_reg_dest" "")
10044    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10045    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10046    (match_operand:DI 3 "arith_reg_operand" "")]
10047   "TARGET_SHMEDIA"
10048   "
10049 {
10050   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10051                              operands[1], operands[2]));
10052   DONE;
10053 }")
10054
10055 (define_insn "msad_ubq_i"
10056   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10057         (plus:DI
10058          (plus:DI
10059           (plus:DI
10060            (plus:DI
10061             (match_operand:DI 1 "arith_reg_operand" "0")
10062             (abs:DI (vec_select:DI
10063                      (minus:V8DI
10064                       (zero_extend:V8DI
10065                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10066                       (zero_extend:V8DI
10067                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10068                      (parallel [(const_int 0)]))))
10069            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10070                                               (zero_extend:V8DI (match_dup 3)))
10071                                   (parallel [(const_int 1)]))))
10072           (plus:DI
10073            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10074                                               (zero_extend:V8DI (match_dup 3)))
10075                                   (parallel [(const_int 2)])))
10076            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10077                                               (zero_extend:V8DI (match_dup 3)))
10078                                   (parallel [(const_int 3)])))))
10079          (plus:DI
10080           (plus:DI
10081            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10082                                               (zero_extend:V8DI (match_dup 3)))
10083                                   (parallel [(const_int 4)])))
10084            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10085                                               (zero_extend:V8DI (match_dup 3)))
10086                                   (parallel [(const_int 5)]))))
10087           (plus:DI
10088            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10089                                               (zero_extend:V8DI (match_dup 3)))
10090                                   (parallel [(const_int 6)])))
10091            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10092                                               (zero_extend:V8DI (match_dup 3)))
10093                                   (parallel [(const_int 7)])))))))]
10094   "TARGET_SHMEDIA"
10095   "msad.ubq     %N2, %N3, %0"
10096   [(set_attr "type" "mac_media")])
10097
10098 (define_insn "mshalds_l"
10099   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10100         (ss_truncate:V2SI
10101          (ashift:V2DI
10102           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10103           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10104                   (const_int 31)))))]
10105   "TARGET_SHMEDIA"
10106   "mshalds.l    %1, %2, %0"
10107   [(set_attr "type" "mcmp_media")])
10108
10109 (define_insn "mshalds_w"
10110   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10111         (ss_truncate:V4HI
10112          (ashift:V4SI
10113           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10114           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10115                   (const_int 15)))))]
10116   "TARGET_SHMEDIA"
10117   "mshalds.w    %1, %2, %0"
10118   [(set_attr "type" "mcmp_media")])
10119
10120 (define_insn "ashrv2si3"
10121   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10122         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10123                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10124   "TARGET_SHMEDIA"
10125   "mshard.l     %1, %2, %0"
10126   [(set_attr "type" "arith_media")])
10127
10128 (define_insn "ashrv4hi3"
10129   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10130         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10131                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10132   "TARGET_SHMEDIA"
10133   "mshard.w     %1, %2, %0"
10134   [(set_attr "type" "arith_media")])
10135
10136 (define_insn "mshards_q"
10137   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10138         (ss_truncate:HI
10139          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10140                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10141   "TARGET_SHMEDIA"
10142   "mshards.q    %1, %N2, %0"
10143   [(set_attr "type" "mcmp_media")])
10144
10145 (define_expand "mshfhi_b"
10146   [(match_operand:V8QI 0 "arith_reg_dest" "")
10147    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10148    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10149   "TARGET_SHMEDIA"
10150   "
10151 {
10152   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10153              (operands[0], operands[1], operands[2]));
10154   DONE;
10155 }")
10156
10157 (define_expand "mshflo_b"
10158   [(match_operand:V8QI 0 "arith_reg_dest" "")
10159    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10160    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10161   "TARGET_SHMEDIA"
10162   "
10163 {
10164   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10165              (operands[0], operands[1], operands[2]));
10166   DONE;
10167 }")
10168
10169 (define_insn "mshf4_b"
10170   [(set
10171     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10172     (vec_select:V8QI
10173      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10174                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10175      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10176                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10177   "TARGET_SHMEDIA"
10178   "* return (TARGET_LITTLE_ENDIAN
10179              ? \"mshfhi.b       %N1, %N2, %0\"
10180              : \"mshflo.b       %N1, %N2, %0\");"
10181   [(set_attr "type" "arith_media")])
10182
10183 (define_insn "mshf0_b"
10184   [(set
10185     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10186     (vec_select:V8QI
10187      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10188                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10189      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10190                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10191   "TARGET_SHMEDIA"
10192   "* return (TARGET_LITTLE_ENDIAN
10193              ? \"mshflo.b       %N1, %N2, %0\"
10194              : \"mshfhi.b       %N1, %N2, %0\");"
10195   [(set_attr "type" "arith_media")])
10196
10197 (define_expand "mshfhi_l"
10198   [(match_operand:V2SI 0 "arith_reg_dest" "")
10199    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10200    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10201   "TARGET_SHMEDIA"
10202   "
10203 {
10204   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10205              (operands[0], operands[1], operands[2]));
10206   DONE;
10207 }")
10208
10209 (define_expand "mshflo_l"
10210   [(match_operand:V2SI 0 "arith_reg_dest" "")
10211    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10212    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10213   "TARGET_SHMEDIA"
10214   "
10215 {
10216   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10217              (operands[0], operands[1], operands[2]));
10218   DONE;
10219 }")
10220
10221 (define_insn "mshf4_l"
10222   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10223         (vec_select:V2SI
10224          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10225                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10226          (parallel [(const_int 1) (const_int 3)])))]
10227   "TARGET_SHMEDIA"
10228   "* return (TARGET_LITTLE_ENDIAN
10229              ? \"mshfhi.l       %N1, %N2, %0\"
10230              : \"mshflo.l       %N1, %N2, %0\");"
10231   [(set_attr "type" "arith_media")])
10232
10233 (define_insn "mshf0_l"
10234   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10235         (vec_select:V2SI
10236          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10237                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10238          (parallel [(const_int 0) (const_int 2)])))]
10239   "TARGET_SHMEDIA"
10240   "* return (TARGET_LITTLE_ENDIAN
10241              ? \"mshflo.l       %N1, %N2, %0\"
10242              : \"mshfhi.l       %N1, %N2, %0\");"
10243   [(set_attr "type" "arith_media")])
10244
10245 (define_expand "mshfhi_w"
10246   [(match_operand:V4HI 0 "arith_reg_dest" "")
10247    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10248    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10249   "TARGET_SHMEDIA"
10250   "
10251 {
10252   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10253              (operands[0], operands[1], operands[2]));
10254   DONE;
10255 }")
10256
10257 (define_expand "mshflo_w"
10258   [(match_operand:V4HI 0 "arith_reg_dest" "")
10259    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10260    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10261   "TARGET_SHMEDIA"
10262   "
10263 {
10264   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10265              (operands[0], operands[1], operands[2]));
10266   DONE;
10267 }")
10268
10269 (define_insn "mshf4_w"
10270   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10271         (vec_select:V4HI
10272          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10273                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10274          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10275   "TARGET_SHMEDIA"
10276   "* return (TARGET_LITTLE_ENDIAN
10277              ? \"mshfhi.w       %N1, %N2, %0\"
10278              : \"mshflo.w       %N1, %N2, %0\");"
10279   [(set_attr "type" "arith_media")])
10280
10281 (define_insn "mshf0_w"
10282   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10283         (vec_select:V4HI
10284          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10285                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10286          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10287   "TARGET_SHMEDIA"
10288   "* return (TARGET_LITTLE_ENDIAN
10289              ? \"mshflo.w       %N1, %N2, %0\"
10290              : \"mshfhi.w       %N1, %N2, %0\");"
10291   [(set_attr "type" "arith_media")])
10292
10293 (define_insn "mshflo_w_x"
10294   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10295         (vec_select:V4HI
10296          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10297                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10298          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10299   "TARGET_SHMEDIA"
10300   "mshflo.w     %N1, %N2, %0"
10301   [(set_attr "type" "arith_media")])
10302
10303 /* These are useful to expand ANDs and as combiner patterns.  */
10304 (define_insn_and_split "mshfhi_l_di"
10305   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10306         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10307                              (const_int 32))
10308                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10309                         (const_int -4294967296))))]
10310   "TARGET_SHMEDIA"
10311   "@
10312         mshfhi.l        %N1, %N2, %0
10313         #"
10314   "TARGET_SHMEDIA && reload_completed
10315    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10316   [(set (match_dup 3) (match_dup 4))
10317    (set (match_dup 5) (match_dup 6))]
10318   "
10319 {
10320   operands[3] = gen_lowpart (SImode, operands[0]);
10321   operands[4] = gen_highpart (SImode, operands[1]);
10322   operands[5] = gen_highpart (SImode, operands[0]);
10323   operands[6] = gen_highpart (SImode, operands[2]);
10324 }"
10325   [(set_attr "type" "arith_media")])
10326
10327 (define_insn "*mshfhi_l_di_rev"
10328   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10329         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10330                         (const_int -4294967296))
10331                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10332                              (const_int 32))))]
10333   "TARGET_SHMEDIA"
10334   "mshfhi.l     %N2, %N1, %0"
10335   [(set_attr "type" "arith_media")])
10336
10337 (define_split
10338   [(set (match_operand:DI 0 "arith_reg_dest" "")
10339         (ior:DI (zero_extend:DI (match_operand:SI 1
10340                                               "extend_reg_or_0_operand" ""))
10341                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10342                         (const_int -4294967296))))
10343    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10344   "TARGET_SHMEDIA"
10345   [(const_int 0)]
10346   "
10347 {
10348   emit_insn (gen_ashldi3_media (operands[3],
10349                                 simplify_gen_subreg (DImode, operands[1],
10350                                                      SImode, 0),
10351                                 GEN_INT (32)));
10352   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10353   DONE;
10354 }")
10355
10356 (define_insn "mshflo_l_di"
10357   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10358         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10359                         (const_int 4294967295))
10360                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10361                            (const_int 32))))]
10362                                 
10363   "TARGET_SHMEDIA"
10364   "mshflo.l     %N1, %N2, %0"
10365   [(set_attr "type" "arith_media")])
10366
10367 (define_insn "*mshflo_l_di_rev"
10368   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10369         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10370                            (const_int 32))
10371                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10372                         (const_int 4294967295))))]
10373                                 
10374   "TARGET_SHMEDIA"
10375   "mshflo.l     %N2, %N1, %0"
10376   [(set_attr "type" "arith_media")])
10377
10378 ;; Combiner pattern for trampoline initialization.
10379 (define_insn_and_split "*double_shori"
10380   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10381         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10382                            (const_int 32))
10383                 (match_operand:DI 2 "const_int_operand" "n")))]
10384   "TARGET_SHMEDIA
10385    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10386   "#"
10387   "rtx_equal_p (operands[0], operands[1])"
10388   [(const_int 0)]
10389   "
10390 {
10391   HOST_WIDE_INT v = INTVAL (operands[2]);
10392
10393   emit_insn (gen_shori_media (operands[0], operands[0],
10394              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10395   emit_insn (gen_shori_media (operands[0], operands[0],
10396                               gen_int_mode (v, HImode)));
10397   DONE;
10398 }")
10399
10400
10401 (define_insn "*mshflo_l_di_x"
10402   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10403         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10404                                  "rZ"))
10405                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10406                            (const_int 32))))]
10407                                 
10408   "TARGET_SHMEDIA"
10409   "mshflo.l     %N1, %N2, %0"
10410   [(set_attr "type" "arith_media")])
10411
10412 (define_insn_and_split "concat_v2sf"
10413   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10414 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10415         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10416                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10417                                 
10418   "TARGET_SHMEDIA"
10419   "@
10420         mshflo.l        %N1, %N2, %0
10421         #
10422         #"
10423   "TARGET_SHMEDIA && reload_completed
10424    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10425   [(set (match_dup 3) (match_dup 1))
10426    (set (match_dup 4) (match_dup 2))]
10427   "
10428 {
10429   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10430   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10431 }"
10432   [(set_attr "type" "arith_media")])
10433
10434 (define_insn "*mshflo_l_di_x_rev"
10435   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10436         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10437                            (const_int 32))
10438                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10439                                 
10440   "TARGET_SHMEDIA"
10441   "mshflo.l     %N2, %N1, %0"
10442   [(set_attr "type" "arith_media")])
10443
10444 (define_insn "ashlv2si3"
10445   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10446         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10447                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10448   "TARGET_SHMEDIA"
10449   "mshlld.l     %1, %2, %0"
10450   [(set_attr "type" "arith_media")])
10451
10452 (define_insn "ashlv4hi3"
10453   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10454         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10455                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10456   "TARGET_SHMEDIA"
10457   "mshlld.w     %1, %2, %0"
10458   [(set_attr "type" "arith_media")])
10459
10460 (define_insn "lshrv2si3"
10461   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10462         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10463                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10464   "TARGET_SHMEDIA"
10465   "mshlrd.l     %1, %2, %0"
10466   [(set_attr "type" "arith_media")])
10467
10468 (define_insn "lshrv4hi3"
10469   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10470         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10471                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10472   "TARGET_SHMEDIA"
10473   "mshlrd.w     %1, %2, %0"
10474   [(set_attr "type" "arith_media")])
10475
10476 (define_insn "subv2si3"
10477   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10478         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10479                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10480   "TARGET_SHMEDIA"
10481   "msub.l       %N1, %2, %0"
10482   [(set_attr "type" "arith_media")])
10483
10484 (define_insn "subv4hi3"
10485   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10486         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10487                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10488   "TARGET_SHMEDIA"
10489   "msub.w       %N1, %2, %0"
10490   [(set_attr "type" "arith_media")])
10491
10492 (define_insn "sssubv2si3"
10493   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10494         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10495                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10496   "TARGET_SHMEDIA"
10497   "msubs.l      %N1, %2, %0"
10498   [(set_attr "type" "mcmp_media")])
10499
10500 (define_insn "ussubv8qi3"
10501   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10502         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10503                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10504   "TARGET_SHMEDIA"
10505   "msubs.ub     %1, %2, %0"
10506   [(set_attr "type" "mcmp_media")])
10507
10508 (define_insn "sssubv4hi3"
10509   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10510         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10511                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10512   "TARGET_SHMEDIA"
10513   "msubs.w      %N1, %2, %0"
10514   [(set_attr "type" "mcmp_media")])
10515
10516 ;; Floating Point Intrinsics
10517
10518 (define_insn "fcosa_s"
10519   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10520         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10521                    UNSPEC_FCOSA))]
10522   "TARGET_SHMEDIA"
10523   "fcosa.s      %1, %0"
10524   [(set_attr "type" "atrans_media")])
10525
10526 (define_insn "fsina_s"
10527   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10528         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10529                    UNSPEC_FSINA))]
10530   "TARGET_SHMEDIA"
10531   "fsina.s      %1, %0"
10532   [(set_attr "type" "atrans_media")])
10533
10534 (define_insn "fipr"
10535   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10536         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10537                                                     "fp_arith_reg_operand" "f")
10538                                                    (match_operand:V4SF 2
10539                                                     "fp_arith_reg_operand" "f"))
10540                                          (parallel [(const_int 0)]))
10541                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10542                                          (parallel [(const_int 1)])))
10543                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10544                                          (parallel [(const_int 2)]))
10545                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10546                                          (parallel [(const_int 3)])))))]
10547   "TARGET_SHMEDIA"
10548   "fipr %1, %2, %0"
10549   [(set_attr "type" "fparith_media")])
10550
10551 (define_insn "fsrra_s"
10552   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10553         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10554                    UNSPEC_FSRRA))]
10555   "TARGET_SHMEDIA"
10556   "fsrra.s      %1, %0"
10557   [(set_attr "type" "atrans_media")])
10558
10559 (define_insn "ftrv"
10560   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10561         (plus:V4SF
10562          (plus:V4SF
10563           (mult:V4SF
10564            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10565                             (parallel [(const_int 0) (const_int 5)
10566                                        (const_int 10) (const_int 15)]))
10567            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10568           (mult:V4SF
10569            (vec_select:V4SF (match_dup 1)
10570                             (parallel [(const_int 4) (const_int 9)
10571                                        (const_int 14) (const_int 3)]))
10572            (vec_select:V4SF (match_dup 2)
10573                             (parallel [(const_int 1) (const_int 2)
10574                                       (const_int 3) (const_int 0)]))))
10575          (plus:V4SF
10576           (mult:V4SF
10577            (vec_select:V4SF (match_dup 1)
10578                             (parallel [(const_int 8) (const_int 13)
10579                                        (const_int 2) (const_int 7)]))
10580            (vec_select:V4SF (match_dup 2)
10581                             (parallel [(const_int 2) (const_int 3)
10582                                        (const_int 0) (const_int 1)])))
10583           (mult:V4SF
10584            (vec_select:V4SF (match_dup 1)
10585                             (parallel [(const_int 12) (const_int 1)
10586                                        (const_int 6) (const_int 11)]))
10587            (vec_select:V4SF (match_dup 2)
10588                             (parallel [(const_int 3) (const_int 0)
10589                                        (const_int 1) (const_int 2)]))))))]
10590   "TARGET_SHMEDIA"
10591   "ftrv %1, %2, %0"
10592   [(set_attr "type" "fparith_media")])
10593
10594 (define_insn "nsb"
10595   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10596         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10597                    UNSPEC_NSB))]
10598   "TARGET_SHMEDIA"
10599   "nsb  %1, %0"
10600   [(set_attr "type" "arith_media")])
10601
10602 (define_insn "nsbsi"
10603   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10604         (zero_extend:SI
10605          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10606                     UNSPEC_NSB)))]
10607   "TARGET_SHMEDIA"
10608   "nsb  %1, %0"
10609   [(set_attr "type" "arith_media")])
10610
10611 (define_insn "nsbdi"
10612   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10613         (zero_extend:DI
10614          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10615                     UNSPEC_NSB)))]
10616   "TARGET_SHMEDIA"
10617   "nsb  %1, %0"
10618   [(set_attr "type" "arith_media")])
10619
10620 (define_expand "ffsdi2"
10621   [(set (match_operand:DI 0 "arith_reg_dest" "")
10622         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10623   "TARGET_SHMEDIA"
10624   "
10625 {
10626   rtx scratch = gen_reg_rtx (DImode);
10627   rtx last;
10628
10629   emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10630   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10631   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10632   emit_insn (gen_nsbdi (scratch, scratch));
10633   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10634   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10635   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10636   REG_NOTES (last)
10637     = gen_rtx_EXPR_LIST (REG_EQUAL,
10638                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10639   DONE;
10640 }")
10641
10642 (define_expand "ffssi2"
10643   [(set (match_operand:SI 0 "arith_reg_dest" "")
10644         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10645   "TARGET_SHMEDIA"
10646   "
10647 {
10648   rtx scratch = gen_reg_rtx (SImode);
10649   rtx discratch = gen_reg_rtx (DImode);
10650   rtx last;
10651
10652   emit_insn (gen_adddi3 (discratch,
10653                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10654                          GEN_INT (-1)));
10655   emit_insn (gen_andcdi3 (discratch,
10656                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10657                           discratch));
10658   emit_insn (gen_nsbsi (scratch, discratch));
10659   last = emit_insn (gen_subsi3 (operands[0],
10660                                 force_reg (SImode, GEN_INT (63)), scratch));
10661   REG_NOTES (last)
10662     = gen_rtx_EXPR_LIST (REG_EQUAL,
10663                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10664   DONE;
10665 }")
10666
10667 (define_insn "byterev"
10668   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10669         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10670                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10671                                     (const_int 4) (const_int 3) (const_int 2)
10672                                     (const_int 1) (const_int 0)])))]
10673   "TARGET_SHMEDIA"
10674   "byterev      %1, %0"
10675   [(set_attr "type" "arith_media")])
10676
10677 ;; The following description  models the
10678 ;; SH4 pipeline using the DFA based scheduler. 
10679 ;; The DFA based description is better way to model 
10680 ;; a superscalar pipeline as compared to function unit
10681 ;; reservation model.   
10682 ;; 1. The function unit based model is oriented to describe at most one 
10683 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple 
10684 ;;    pipeline units by same insn. This can be done using DFA based description.
10685 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10686 ;; 3. Writing all unit reservations for an instruction class is more natural description 
10687 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the 
10688 ;;    old function unit based model.
10689 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10690
10691
10692 ;; Two automata are defined to reduce number of states
10693 ;; which a single large automaton will have.(Factoring)
10694
10695 (define_automaton "inst_pipeline,fpu_pipe")
10696
10697 ;; This unit is basically the decode unit of the processor.
10698 ;; Since SH4 is a dual issue machine,it is as if there are two 
10699 ;; units so that any insn can be processed by either one
10700 ;; of the decoding unit.
10701
10702 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10703
10704
10705 ;; The fixed point arithmetic calculator(?? EX Unit).
10706
10707 (define_cpu_unit  "int" "inst_pipeline")
10708
10709 ;; f1_1 and f1_2 are floating point units.Actually there is
10710 ;; a f1 unit which can overlap with other f1 unit but
10711 ;; not another F1 unit.It is as though there were two
10712 ;; f1 units.
10713
10714 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10715
10716 ;; The floating point units (except FS - F2 always precedes it.)
10717
10718 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10719
10720 ;; This is basically the MA unit of SH4
10721 ;; used in LOAD/STORE pipeline.
10722
10723 (define_cpu_unit "memory" "inst_pipeline")
10724
10725 ;; However, there are LS group insns that don't use it, even ones that
10726 ;; complete in 0 cycles.  So we use an extra unit for the issue of LS insns.
10727 (define_cpu_unit "load_store" "inst_pipeline")
10728
10729 ;; The address calculator used for branch instructions.
10730 ;; This will be reserved after "issue" of branch instructions
10731 ;; and this is to make sure that no two branch instructions 
10732 ;; can be issued in parallel. 
10733
10734 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10735
10736 ;; ----------------------------------------------------
10737 ;; This reservation is to simplify the dual issue description.
10738
10739 (define_reservation  "issue"  "pipe_01|pipe_02")
10740
10741 ;; This is to express the locking of D stage.
10742 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10743
10744 (define_reservation  "d_lock" "pipe_01+pipe_02")
10745
10746 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10747 (define_reservation "F01" "F0+F1")
10748
10749 ;; This is to simplify description where F1,F2,FS
10750 ;; are used simultaneously.
10751
10752 (define_reservation "fpu" "F1+F2")
10753
10754 ;; This is to highlight the fact that f1 
10755 ;; cannot overlap with F1.
10756
10757 (exclusion_set  "f1_1,f1_2" "F1")
10758
10759 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10760
10761 ;; Although reg moves have a latency of zero 
10762 ;; we need to highlight that they use D stage
10763 ;; for one cycle.
10764
10765 ;; Group:       MT
10766
10767 (define_insn_reservation "reg_mov" 0
10768   (and (eq_attr "pipe_model" "sh4")
10769        (eq_attr "type" "move"))
10770   "issue")
10771
10772 ;; Group:       LS
10773
10774 (define_insn_reservation "freg_mov" 0
10775   (and (eq_attr "pipe_model" "sh4")
10776        (eq_attr "type" "fmove"))
10777   "issue+load_store")
10778
10779 ;; We don't model all pipeline stages; we model the issue ('D') stage
10780 ;; inasmuch as we allow only two instructions to issue simultaneously,
10781 ;; and CO instructions prevent any simultaneous issue of another instruction.
10782 ;; (This uses pipe_01 and pipe_02).
10783 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10784 ;; Double issue of EX / BR insns is prevented by using the int unit /
10785 ;; pcr_addrcalc unit in the EX stage.
10786 ;; Double issue of BR / LS instructions is prevented by using the
10787 ;; pcr_addrcalc / load_store unit in the issue cycle.
10788 ;; Double issue of FE instructions is prevented by using F0 in the first
10789 ;; pipeline stage after the first D stage.
10790 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10791 ;; (except in the cases outlined above), nor to describe the FS stage after
10792 ;; the F2 stage.
10793
10794 ;; Other MT  group instructions(1 step operations)
10795 ;; Group:       MT
10796 ;; Latency:     1
10797 ;; Issue Rate:  1
10798
10799 (define_insn_reservation "mt" 1
10800   (and (eq_attr "pipe_model" "sh4")
10801        (eq_attr "type" "mt_group"))
10802   "issue")
10803
10804 ;; Fixed Point Arithmetic Instructions(1 step operations)
10805 ;; Group:       EX
10806 ;; Latency:     1
10807 ;; Issue Rate:  1
10808
10809 (define_insn_reservation "sh4_simple_arith" 1 
10810   (and (eq_attr "pipe_model" "sh4")
10811        (eq_attr "insn_class" "ex_group"))
10812   "issue,int")
10813
10814 ;; Load and store instructions have no alignment peculiarities for the SH4,
10815 ;; but they use the load-store unit, which they share with the fmove type
10816 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10817 ;; Loads have a latency of two.
10818 ;; However, call insns can only paired with a preceding insn, and have
10819 ;; a delay slot, so that we want two more insns to be scheduled between the
10820 ;; load of the function address and the call.  This is equivalent to a
10821 ;; latency of three.
10822 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10823 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10824 ;; We only do this for SImode loads of general registers, to make the work
10825 ;; for ADJUST_COST easier.
10826
10827 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10828 ;; Group:       LS
10829 ;; Latency:     2
10830 ;; Issue Rate:  1
10831
10832 (define_insn_reservation "sh4_load" 2
10833   (and (eq_attr "pipe_model" "sh4")
10834        (eq_attr "type" "load,pcload"))
10835   "issue+load_store,nothing,memory")
10836
10837 ;; calls / sfuncs need an extra instruction for their delay slot.
10838 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10839 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10840 ;; count of a dynamic shift.
10841 (define_insn_reservation "sh4_load_si" 3
10842   (and (eq_attr "pipe_model" "sh4")
10843        (eq_attr "type" "load_si,pcload_si"))
10844   "issue+load_store,nothing,memory")
10845
10846 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10847
10848 ;; The load latency is upped to three higher if the dependent insn does
10849 ;; double precision computation.  We want the 'default' latency to reflect
10850 ;; that increased latency because otherwise the insn priorities won't
10851 ;; allow proper scheduling.
10852 (define_insn_reservation "sh4_fload" 3
10853   (and (eq_attr "pipe_model" "sh4")
10854        (eq_attr "type" "fload,pcfload"))
10855   "issue+load_store,nothing,memory")
10856
10857 ;; (define_bypass 2 "sh4_fload" "!")
10858
10859 (define_insn_reservation "sh4_store" 1
10860   (and (eq_attr "pipe_model" "sh4")
10861        (eq_attr "type" "store"))
10862   "issue+load_store,nothing,memory")
10863
10864 ;; Load Store instructions.
10865 ;; Group:       LS
10866 ;; Latency:     1
10867 ;; Issue Rate:  1
10868
10869 (define_insn_reservation "sh4_gp_fpul" 1
10870   (and (eq_attr "pipe_model" "sh4")
10871        (eq_attr "type" "gp_fpul"))
10872   "issue+load_store")
10873
10874 ;; Load Store instructions.
10875 ;; Group:       LS
10876 ;; Latency:     3
10877 ;; Issue Rate:  1
10878
10879 (define_insn_reservation "sh4_fpul_gp" 3
10880   (and (eq_attr "pipe_model" "sh4")
10881        (eq_attr "type" "fpul_gp"))
10882   "issue+load_store")
10883
10884 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10885 ;; Group:       BR
10886 ;; Latency when taken:  2 (or 1)
10887 ;; Issue Rate:  1
10888 ;; The latency is 1 when displacement is 0.
10889 ;; We can't really do much with the latency, even if we could express it,
10890 ;; but the pairing restrictions are useful to take into account.
10891 ;; ??? If the branch is likely, we might want to fill the delay slot;
10892 ;; if the branch is likely, but not very likely, should we pretend to use
10893 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10894
10895 (define_insn_reservation "sh4_branch"  1
10896   (and (eq_attr "pipe_model" "sh4")
10897        (eq_attr "type" "cbranch,jump"))
10898   "issue+pcr_addrcalc")
10899
10900 ;; Branch Far (JMP,RTS,BRAF)
10901 ;; Group:       CO
10902 ;; Latency:     3
10903 ;; Issue Rate:  2
10904 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10905 ;; can't be distinguished from bra for the "jump" pattern.
10906
10907 (define_insn_reservation "sh4_return" 3
10908   (and (eq_attr "pipe_model" "sh4")
10909        (eq_attr "type" "return,jump_ind"))
10910          "d_lock*2")
10911
10912 ;; RTE
10913 ;; Group:       CO
10914 ;; Latency:     5
10915 ;; Issue Rate:  5
10916 ;; this instruction can be executed in any of the pipelines 
10917 ;; and blocks the pipeline for next 4 stages.
10918
10919 (define_insn_reservation "sh4_return_from_exp" 5
10920   (and (eq_attr "pipe_model" "sh4")
10921        (eq_attr "type" "rte"))
10922   "d_lock*5")
10923
10924 ;; OCBP, OCBWB
10925 ;; Group:       CO
10926 ;; Latency:     1-5
10927 ;; Issue Rate:  1
10928
10929 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10930 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10931 (define_insn_reservation "ocbwb"  6
10932   (and (eq_attr "pipe_model" "sh4")
10933        (eq_attr "type" "cwb"))
10934   "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10935                 
10936 ;; LDS to PR,JSR
10937 ;; Group:       CO
10938 ;; Latency:     3
10939 ;; Issue Rate:  2
10940 ;; The SX stage is blocked for last 2 cycles.
10941 ;; OTOH, the only time that has an effect for insns generated by the compiler
10942 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10943 ;; or when we are doing a function call - and we don't do inter-function
10944 ;; scheduling.  For the function call case, it's really best that we end with
10945 ;; something that models an rts.
10946
10947 (define_insn_reservation "sh4_lds_to_pr" 3 
10948   (and (eq_attr "pipe_model" "sh4")
10949        (eq_attr "type" "prset") )
10950   "d_lock*2")
10951
10952 ;; calls introduce a longisch delay that is likely to flush the pipelines
10953 ;; of the caller's instructions.  Ordinary functions tend to end with a
10954 ;; load to restore a register (in the delay slot of rts), while sfuncs
10955 ;; tend to end with an EX or MT insn.  But that is not actually relevant,
10956 ;; since there are no instructions that contend for memory access early.
10957 ;; We could, of course, provide exact scheduling information for specific
10958 ;; sfuncs, if that should prove useful.
10959
10960 (define_insn_reservation "sh4_call" 16 
10961   (and (eq_attr "pipe_model" "sh4")
10962        (eq_attr "type" "call,sfunc"))
10963   "d_lock*16")
10964
10965 ;; LDS.L to PR 
10966 ;; Group:       CO
10967 ;; Latency:     3
10968 ;; Issue Rate:  2
10969 ;; The SX unit is blocked for last 2 cycles.
10970  
10971 (define_insn_reservation "ldsmem_to_pr"  3
10972   (and (eq_attr "pipe_model" "sh4")
10973        (eq_attr "type" "pload"))
10974   "d_lock*2")
10975
10976 ;; STS from PR
10977 ;; Group:       CO
10978 ;; Latency:     2
10979 ;; Issue Rate:  2
10980 ;; The SX unit in second and third cycles.
10981
10982 (define_insn_reservation "sts_from_pr" 2
10983   (and (eq_attr "pipe_model" "sh4")
10984        (eq_attr "type" "prget"))
10985   "d_lock*2")
10986
10987 ;; STS.L from PR
10988 ;; Group:       CO
10989 ;; Latency:     2
10990 ;; Issue Rate:  2
10991
10992 (define_insn_reservation "sh4_prstore_mem" 2 
10993   (and (eq_attr "pipe_model" "sh4")
10994        (eq_attr "type" "pstore"))
10995   "d_lock*2,nothing,memory")
10996
10997 ;; LDS to FPSCR
10998 ;; Group:       CO
10999 ;; Latency:     4
11000 ;; Issue Rate:  1
11001 ;; F1 is blocked for last three cycles. 
11002
11003 (define_insn_reservation "fpscr_load" 4
11004   (and (eq_attr "pipe_model" "sh4")
11005        (eq_attr "type" "gp_fpscr"))
11006   "d_lock,nothing,F1*3")
11007
11008 ;; LDS.L to FPSCR
11009 ;; Group:       CO
11010 ;; Latency:     1 / 4
11011 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
11012 ;; Issue Rate:  1
11013 ;; F1 is blocked for last three cycles.
11014
11015 (define_insn_reservation "fpscr_load_mem" 4
11016   (and (eq_attr "pipe_model" "sh4")
11017        (eq_attr "type"  "mem_fpscr"))
11018   "d_lock,nothing,(F1+memory),F1*2")
11019
11020 \f
11021 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11022 ;; Group:       CO
11023 ;; Latency:     4 / 4
11024 ;; Issue Rate:  1
11025
11026 (define_insn_reservation "multi" 4
11027   (and (eq_attr "pipe_model" "sh4")
11028        (eq_attr "type" "smpy,dmpy"))
11029   "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11030
11031 ;; Fixed STS from MACL / MACH
11032 ;; Group:       CO
11033 ;; Latency:     3
11034 ;; Issue Rate:  1
11035
11036 (define_insn_reservation "sh4_mac_gp" 3
11037   (and (eq_attr "pipe_model" "sh4")
11038        (eq_attr "type" "mac_gp"))
11039   "d_lock")
11040
11041
11042 ;; Single precision floating point computation FCMP/EQ,
11043 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11044 ;; Group:       FE
11045 ;; Latency:     3/4
11046 ;; Issue Rate:  1
11047
11048 (define_insn_reservation "fp_arith"  3
11049   (and (eq_attr "pipe_model" "sh4")
11050        (eq_attr "type" "fp"))
11051   "issue,F01,F2")
11052
11053 (define_insn_reservation "fp_arith_ftrc"  3
11054   (and (eq_attr "pipe_model" "sh4")
11055        (eq_attr "type" "ftrc_s"))
11056   "issue,F01,F2")
11057
11058 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11059
11060 ;; Single Precision FDIV/SQRT
11061 ;; Group:       FE
11062 ;; Latency:     12/13 (FDIV); 11/12 (FSQRT)
11063 ;; Issue Rate:  1
11064 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11065
11066 (define_insn_reservation "fp_div" 12
11067   (and (eq_attr "pipe_model" "sh4")
11068        (eq_attr "type" "fdiv"))
11069   "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11070
11071 ;; Double Precision floating point computation
11072 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11073 ;; Group:       FE
11074 ;; Latency:     (3,4)/5
11075 ;; Issue Rate:  1
11076
11077 (define_insn_reservation "dp_float" 4
11078   (and (eq_attr "pipe_model" "sh4")
11079        (eq_attr "type" "dfp_conv"))
11080   "issue,F01,F1+F2,F2")
11081
11082 ;; Double-precision floating-point (FADD,FMUL,FSUB) 
11083 ;; Group:       FE
11084 ;; Latency:     (7,8)/9
11085 ;; Issue Rate:  1
11086
11087 (define_insn_reservation "fp_double_arith" 8
11088   (and (eq_attr "pipe_model" "sh4")
11089        (eq_attr "type" "dfp_arith"))
11090   "issue,F01,F1+F2,fpu*4,F2")
11091
11092 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT) 
11093 ;; Group:       CO
11094 ;; Latency:     3/5
11095 ;; Issue Rate:  2
11096
11097 (define_insn_reservation "fp_double_cmp" 3 
11098   (and (eq_attr "pipe_model" "sh4")
11099        (eq_attr "type" "dfp_cmp"))
11100   "d_lock,(d_lock+F01),F1+F2,F2")
11101
11102 ;; Double precision FDIV/SQRT
11103 ;; Group:       FE
11104 ;; Latency:     (24,25)/26
11105 ;; Issue Rate:  1
11106
11107 (define_insn_reservation "dp_div" 25
11108   (and (eq_attr "pipe_model" "sh4")
11109        (eq_attr "type" "dfdiv"))
11110   "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11111
11112
11113 ;; Use the branch-not-taken case to model arith3 insns.  For the branch taken
11114 ;; case, we'd get a d_lock instead of issue at the end.
11115 (define_insn_reservation "arith3" 3
11116   (and (eq_attr "pipe_model" "sh4")
11117        (eq_attr "type" "arith3"))
11118   "issue,d_lock+pcr_addrcalc,issue")
11119
11120 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11121 (define_insn_reservation "arith3b" 2
11122   (and (eq_attr "pipe_model" "sh4")
11123        (eq_attr "type" "arith3"))
11124   "issue,d_lock+pcr_addrcalc")