OSDN Git Service

* sh.h (REG_CLASS_FROM_LETTER): Change to:
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Hitachi / 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
146   ;; These are used with unspec_volatile.
147   (UNSPECV_BLOCKAGE     0)
148   (UNSPECV_ALIGN        1)
149   (UNSPECV_CONST2       2)
150   (UNSPECV_CONST4       4)
151   (UNSPECV_CONST8       6)
152   (UNSPECV_WINDOW_END   10)
153   (UNSPECV_CONST_END    11)
154 ])  
155
156 ;; -------------------------------------------------------------------------
157 ;; Attributes
158 ;; -------------------------------------------------------------------------
159
160 ;; Target CPU.
161
162 (define_attr "cpu"
163  "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
164   (const (symbol_ref "sh_cpu_attr")))
165
166 (define_attr "endian" "big,little"
167  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
168                       (const_string "little") (const_string "big"))))
169
170 ;; Indicate if the default fpu mode is single precision.
171 (define_attr "fpu_single" "yes,no"
172   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
173                          (const_string "yes") (const_string "no"))))
174
175 (define_attr "fmovd" "yes,no"
176   (const (if_then_else (symbol_ref "TARGET_FMOVD")
177                        (const_string "yes") (const_string "no"))))
178 ;; pipeline model
179 (define_attr "pipe_model" "sh1,sh4,sh5media"
180   (const
181    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
182           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
183          (const_string "sh1"))))
184
185 ;; cbranch      conditional branch instructions
186 ;; jump         unconditional jumps
187 ;; arith        ordinary arithmetic
188 ;; arith3       a compound insn that behaves similarly to a sequence of
189 ;;              three insns of type arith
190 ;; arith3b      like above, but might end with a redirected branch
191 ;; load         from memory
192 ;; load_si      Likewise, SImode variant for general register.
193 ;; fload        Likewise, but load to fp register.
194 ;; store        to memory
195 ;; move         general purpose register to register
196 ;; mt_group     other sh4 mt instructions
197 ;; fmove        register to register, floating point
198 ;; smpy         word precision integer multiply
199 ;; dmpy         longword or doublelongword precision integer multiply
200 ;; return       rts
201 ;; pload        load of pr reg, which can't be put into delay slot of rts
202 ;; prset        copy register to pr reg, ditto
203 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
204 ;; prget        copy pr to register, ditto
205 ;; pcload       pc relative load of constant value
206 ;; pcfload      Likewise, but load to fp register.
207 ;; pcload_si    Likewise, SImode variant for general register.
208 ;; rte          return from exception
209 ;; sfunc        special function call with known used registers
210 ;; call         function call
211 ;; fp           floating point
212 ;; fdiv         floating point divide (or square root)
213 ;; gp_fpul      move from general purpose register to fpul
214 ;; fpul_gp      move from fpul to general purpose register
215 ;; mac_gp       move from mac[lh] to general purpose register
216 ;; dfp_arith, dfp_cmp,dfp_conv
217 ;; ftrc_s       fix_truncsfsi2_i4
218 ;; dfdiv        double precision floating point divide (or square root)
219 ;; cwb          ic_invalidate_line_i
220 ;; tls_load     load TLS related address 
221 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
222 ;; cbranch_media SHmedia conditional branch instructions
223 ;; cmp_media    SHmedia compare instructions
224 ;; dfdiv_media  SHmedia double precision divide and square root
225 ;; dfmul_media  SHmedia double precision multiply instruction
226 ;; dfparith_media SHmedia double precision floating point arithmetic
227 ;; dfpconv_media SHmedia double precision floating point conversions
228 ;; dmpy_media   SHmedia longword multiply
229 ;; fcmp_media   SHmedia floating point compare instructions
230 ;; fdiv_media   SHmedia single precision divide and square root
231 ;; fload_media  SHmedia floating point register load instructions
232 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
233 ;; fparith_media SHmedia single precision floating point arithmetic
234 ;; fpconv_media SHmedia single precision floating point conversions
235 ;; fstore_media SHmedia floating point register store instructions
236 ;; gettr_media  SHmedia gettr instruction
237 ;; invalidate_line_media SHmedia invalidate_line sequence
238 ;; jump_media   SHmedia unconditional branch instructions
239 ;; load_media   SHmedia general register load instructions
240 ;; pt_media     SHmedia pt instruction (expanded by assembler)
241 ;; ptabs_media  SHmedia ptabs instruction
242 ;; store_media  SHmedia general register store instructions
243 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
244 ;; mac_media    SHmedia mac-style fixed point operations
245 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
246 ;; atrans       SHmedia approximate transcendental functions
247 ;; ustore_media SHmedia unaligned stores
248 ;; nil          no-op move, will be deleted.
249
250 (define_attr "type"
251  "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"
252   (const_string "other"))
253
254 ;; We define a new attribute namely "insn_class".We use
255 ;; this for the DFA based pipeline description.
256 ;;
257 ;; mt_group      SH4 "mt" group instructions.
258 ;;
259 ;; ex_group      SH4 "ex" group instructions.
260 ;;
261 ;; ls_group      SH4 "ls" group instructions.
262 ;;
263
264 (define_attr "insn_class"
265   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
266   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
267          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
268          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
269          (eq_attr "type" "cbranch,jump") (const_string "br_group")
270          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
271            (const_string "fe_group")
272          (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")]
273         (const_string "none")))
274 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
275 ;; so these do not belong in an insn group, although they are modeled
276 ;; with their own define_insn_reservations.
277
278 ;; Indicate what precision must be selected in fpscr for this insn, if any.
279
280 (define_attr "fp_mode" "single,double,none" (const_string "none"))
281
282 ; If a conditional branch destination is within -252..258 bytes away
283 ; from the instruction it can be 2 bytes long.  Something in the
284 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
285 ; branches are initially assumed to be 16 bytes long.
286 ; In machine_dependent_reorg, we split all branches that are longer than
287 ; 2 bytes.
288
289 ;; The maximum range used for SImode constant pool entries is 1018.  A final
290 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
291 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
292 ;; instruction around the pool table, 2 bytes of alignment before the table,
293 ;; and 30 bytes of alignment after the table.  That gives a maximum total
294 ;; pool size of 1058 bytes.
295 ;; Worst case code/pool content size ratio is 1:2 (using asms).
296 ;; Thus, in the worst case, there is one instruction in front of a maximum
297 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
298 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
299 ;; If we have a forward branch, the initial table will be put after the
300 ;; unconditional branch.
301 ;;
302 ;; ??? We could do much better by keeping track of the actual pcloads within
303 ;; the branch range and in the pcload range in front of the branch range.
304
305 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
306 ;; inside an le.
307 (define_attr "short_cbranch_p" "no,yes"
308   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
309          (const_string "no")
310          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
311          (const_string "yes")
312          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
313          (const_string "no")
314          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
315          (const_string "yes")
316          ] (const_string "no")))
317
318 (define_attr "med_branch_p" "no,yes"
319   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
320               (const_int 1988))
321          (const_string "yes")
322          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
323          (const_string "no")
324          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
325               (const_int 8186))
326          (const_string "yes")
327          ] (const_string "no")))
328
329 (define_attr "med_cbranch_p" "no,yes"
330   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
331               (const_int 1986))
332          (const_string "yes")
333          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
334          (const_string "no")
335          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
336                (const_int 8184))
337          (const_string "yes")
338          ] (const_string "no")))
339
340 (define_attr "braf_branch_p" "no,yes"
341   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
342          (const_string "no")
343          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
344               (const_int 20660))
345          (const_string "yes")
346          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
347          (const_string "no")
348          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
349               (const_int 65530))
350          (const_string "yes")
351          ] (const_string "no")))
352
353 (define_attr "braf_cbranch_p" "no,yes"
354   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
355          (const_string "no")
356          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
357               (const_int 20658))
358          (const_string "yes")
359          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
360          (const_string "no")
361          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
362               (const_int 65528))
363          (const_string "yes")
364          ] (const_string "no")))
365
366 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
367 ; For wider ranges, we need a combination of a code and a data part.
368 ; If we can get a scratch register for a long range jump, the code
369 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
370 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
371 ; long; otherwise, it must be 6 bytes long.
372
373 ; All other instructions are two bytes long by default.
374
375 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
376 ;; but getattrtab doesn't understand this.
377 (define_attr "length" ""
378   (cond [(eq_attr "type" "cbranch")
379          (cond [(eq_attr "short_cbranch_p" "yes")
380                 (const_int 2)
381                 (eq_attr "med_cbranch_p" "yes")
382                 (const_int 6)
383                 (eq_attr "braf_cbranch_p" "yes")
384                 (const_int 12)
385 ;; ??? using pc is not computed transitively.
386                 (ne (match_dup 0) (match_dup 0))
387                 (const_int 14)
388                 (ne (symbol_ref ("flag_pic")) (const_int 0))
389                 (const_int 24)
390                 ] (const_int 16))
391          (eq_attr "type" "jump")
392          (cond [(eq_attr "med_branch_p" "yes")
393                 (const_int 2)
394                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
395                          (symbol_ref "INSN"))
396                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
397                          (symbol_ref "code_for_indirect_jump_scratch")))
398                 (if_then_else (eq_attr "braf_branch_p" "yes")
399                               (const_int 6)
400                               (const_int 10))
401                 (eq_attr "braf_branch_p" "yes")
402                 (const_int 10)
403 ;; ??? using pc is not computed transitively.
404                 (ne (match_dup 0) (match_dup 0))
405                 (const_int 12)
406                 (ne (symbol_ref ("flag_pic")) (const_int 0))
407                 (const_int 22)
408                 ] (const_int 14))
409          (eq_attr "type" "pt_media")
410          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
411                        (const_int 20) (const_int 12))
412          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
413                          (const_int 4)
414                          (const_int 2))))
415
416 ;; (define_function_unit {name} {num-units} {n-users} {test}
417 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
418
419 ;; Load and store instructions save a cycle if they are aligned on a
420 ;; four byte boundary.  Using a function unit for stores encourages
421 ;; gcc to separate load and store instructions by one instruction,
422 ;; which makes it more likely that the linker will be able to word
423 ;; align them when relaxing.
424
425 ;; Loads have a latency of two.
426 ;; However, call insns can have a delay slot, so that we want one more
427 ;; insn to be scheduled between the load of the function address and the call.
428 ;; This is equivalent to a latency of three.
429 ;; We cannot use a conflict list for this, because we need to distinguish
430 ;; between the actual call address and the function arguments.
431 ;; ADJUST_COST can only properly handle reductions of the cost, so we
432 ;; use a latency of three here.
433 ;; We only do this for SImode loads of general registers, to make the work
434 ;; for ADJUST_COST easier.
435 (define_function_unit "memory" 1 0
436   (and (eq_attr "pipe_model" "sh1")
437        (eq_attr "type" "load_si,pcload_si"))
438   3 2)
439 (define_function_unit "memory" 1 0
440   (and (eq_attr "pipe_model" "sh1")
441        (eq_attr "type" "load,pcload,pload,store,pstore"))
442   2 2)
443
444 (define_function_unit "int"    1 0
445   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
446
447 (define_function_unit "int"    1 0
448   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
449
450 (define_function_unit "int"    1 0
451   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
452
453 ;; ??? These are approximations.
454 (define_function_unit "mpy"    1 0
455   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
456 (define_function_unit "mpy"    1 0
457   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
458
459 (define_function_unit "fp"     1 0
460   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
461 (define_function_unit "fp"     1 0
462   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
463
464
465 ;; SH-5 SHmedia scheduling
466 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
467 ;; single-issue machine.  It has four pipelines, the branch unit (br),
468 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
469 ;; the floating point unit (fpu).
470 ;; Here model the instructions with a latency greater than one cycle.
471
472 ;; Every instruction on SH-5 occupies the issue resource for at least one
473 ;; cycle.
474 (define_function_unit "sh5issue" 1 0
475   (and (eq_attr "pipe_model" "sh5media")
476        (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)
477
478 ;; Specify the various types of instruction which have latency > 1
479 (define_function_unit "sh5issue" 1 0
480   (and (eq_attr "pipe_model" "sh5media")
481        (eq_attr "type" "mcmp_media")) 2 1)
482
483 (define_function_unit "sh5issue" 1 0
484   (and (eq_attr "pipe_model" "sh5media")
485        (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
486 ;; but see sh_adjust_cost for mac_media exception.
487
488 (define_function_unit "sh5issue" 1 0
489   (and (eq_attr "pipe_model" "sh5media")
490        (eq_attr "type" "fload_media,fmove_media")) 4 1)
491
492 (define_function_unit "sh5issue" 1 0
493   (and (eq_attr "pipe_model" "sh5media")
494        (eq_attr "type" "d2mpy_media")) 4 2)
495
496 (define_function_unit "sh5issue" 1 0
497   (and (eq_attr "pipe_model" "sh5media")
498        (eq_attr "type" "pt_media,ptabs_media")) 5 1)
499
500 (define_function_unit "sh5issue" 1 0
501   (and (eq_attr "pipe_model" "sh5media")
502        (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
503
504 (define_function_unit "sh5issue" 1 0
505   (and (eq_attr "pipe_model" "sh5media")
506        (eq_attr "type" "invalidate_line_media")) 7 7)
507
508 (define_function_unit "sh5issue" 1 0
509   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
510
511 (define_function_unit "sh5issue" 1 0
512   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
513
514 ;; Floating-point divide and square-root occupy an additional resource,
515 ;; which is not internally pipelined.  However, other instructions
516 ;; can continue to issue.
517 (define_function_unit "sh5fds" 1 0
518   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media"))  19 19)
519
520 (define_function_unit "sh5fds" 1 0
521   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
522
523 ; Definitions for filling branch delay slots.
524
525 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
526
527 ;; ??? This should be (nil) instead of (const_int 0)
528 (define_attr "hit_stack" "yes,no"
529         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
530                    (const_int 0))
531                (const_string "no")]
532               (const_string "yes")))
533
534 (define_attr "interrupt_function" "no,yes"
535   (const (symbol_ref "current_function_interrupt")))
536
537 (define_attr "in_delay_slot" "yes,no"
538   (cond [(eq_attr "type" "cbranch") (const_string "no")
539          (eq_attr "type" "pcload,pcload_si") (const_string "no")
540          (eq_attr "needs_delay_slot" "yes") (const_string "no")
541          (eq_attr "length" "2") (const_string "yes")
542          ] (const_string "no")))
543
544 (define_attr "cond_delay_slot" "yes,no"
545   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
546          ] (const_string "no")))
547
548 (define_attr "is_sfunc" ""
549   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
550
551 (define_attr "is_mac_media" ""
552   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
553
554 (define_attr "branch_zero" "yes,no"
555   (cond [(eq_attr "type" "!cbranch") (const_string "no")
556          (ne (symbol_ref "(next_active_insn (insn)\
557                            == (prev_active_insn\
558                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
559                           && get_attr_length (next_active_insn (insn)) == 2")
560              (const_int 0))
561          (const_string "yes")]
562         (const_string "no")))
563
564 ;; SH4 Double-precision computation with double-precision result -
565 ;; the two halves are ready at different times.
566 (define_attr "dfp_comp" "yes,no"
567   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
568         (const_string "no")))
569
570 ;; Insns for which the latency of a preceding fp insn is decreased by one.
571 (define_attr "late_fp_use" "yes,no" (const_string "no"))
572 ;; And feeding insns for which this relevant.
573 (define_attr "any_fp_comp" "yes,no"
574   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
575          (const_string "yes")]
576         (const_string "no")))
577
578 (define_attr "any_int_load" "yes,no"
579   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
580          (const_string "yes")]
581         (const_string "no")))
582
583 (define_delay
584   (eq_attr "needs_delay_slot" "yes")
585   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
586
587 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
588 ;; and thus we can't put a pop instruction in its delay slot.
589 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
590 ;; instruction can go in the delay slot.
591
592 ;; Since a normal return (rts) implicitly uses the PR register,
593 ;; we can't allow PR register loads in an rts delay slot.
594
595 (define_delay
596   (eq_attr "type" "return")
597   [(and (eq_attr "in_delay_slot" "yes")
598         (ior (and (eq_attr "interrupt_function" "no")
599                   (eq_attr "type" "!pload,prset"))
600              (and (eq_attr "interrupt_function" "yes")
601                   (ior
602                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
603                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
604
605 ;; Since a call implicitly uses the PR register, we can't allow
606 ;; a PR register store in a jsr delay slot.
607
608 (define_delay
609   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
610   [(and (eq_attr "in_delay_slot" "yes")
611         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
612
613 ;; Say that we have annulled true branches, since this gives smaller and
614 ;; faster code when branches are predicted as not taken.
615
616 (define_delay
617   (and (eq_attr "type" "cbranch")
618        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
619   ;; SH2e has a hardware bug that pretty much prohibits the use of
620   ;; annuled delay slots.
621   [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
622                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
623 \f
624 ;; -------------------------------------------------------------------------
625 ;; SImode signed integer comparisons
626 ;; -------------------------------------------------------------------------
627
628 (define_insn ""
629   [(set (reg:SI T_REG)
630         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
631                        (match_operand:SI 1 "arith_operand" "K08,r"))
632                (const_int 0)))]
633   "TARGET_SH1"
634   "tst  %1,%0"
635   [(set_attr "type" "mt_group")])
636
637 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
638 ;; That would still allow reload to create cmpi instructions, but would
639 ;; perhaps allow forcing the constant into a register when that is better.
640 ;; Probably should use r0 for mem/imm compares, but force constant into a
641 ;; register for pseudo/imm compares.
642
643 (define_insn "cmpeqsi_t"
644   [(set (reg:SI T_REG)
645         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
646                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
647   "TARGET_SH1"
648   "@
649         tst     %0,%0
650         cmp/eq  %1,%0
651         cmp/eq  %1,%0"
652    [(set_attr "type" "mt_group")])
653
654 (define_insn "cmpgtsi_t"
655   [(set (reg:SI T_REG)
656         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
657                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
658   "TARGET_SH1"
659   "@
660         cmp/gt  %1,%0
661         cmp/pl  %0"
662    [(set_attr "type" "mt_group")])
663
664 (define_insn "cmpgesi_t"
665   [(set (reg:SI T_REG)
666         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
667                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
668   "TARGET_SH1"
669   "@
670         cmp/ge  %1,%0
671         cmp/pz  %0"
672    [(set_attr "type" "mt_group")])
673
674 ;; -------------------------------------------------------------------------
675 ;; SImode unsigned integer comparisons
676 ;; -------------------------------------------------------------------------
677
678 (define_insn "cmpgeusi_t"
679   [(set (reg:SI T_REG)
680         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
681                 (match_operand:SI 1 "arith_reg_operand" "r")))]
682   "TARGET_SH1"
683   "cmp/hs       %1,%0"
684    [(set_attr "type" "mt_group")])
685
686 (define_insn "cmpgtusi_t"
687   [(set (reg:SI T_REG)
688         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
689                 (match_operand:SI 1 "arith_reg_operand" "r")))]
690   "TARGET_SH1"
691   "cmp/hi       %1,%0"
692    [(set_attr "type" "mt_group")])
693
694 ;; We save the compare operands in the cmpxx patterns and use them when
695 ;; we generate the branch.
696
697 (define_expand "cmpsi"
698   [(set (reg:SI T_REG)
699         (compare (match_operand:SI 0 "arith_operand" "")
700                  (match_operand:SI 1 "arith_operand" "")))]
701   "TARGET_SH1"
702   "
703 {
704   sh_compare_op0 = operands[0];
705   sh_compare_op1 = operands[1];
706   DONE;
707 }")
708 \f
709 ;; -------------------------------------------------------------------------
710 ;; DImode signed integer comparisons
711 ;; -------------------------------------------------------------------------
712
713 ;; ??? Could get better scheduling by splitting the initial test from the
714 ;; rest of the insn after reload.  However, the gain would hardly justify
715 ;; the sh.md size increase necessary to do that.
716
717 (define_insn ""
718   [(set (reg:SI T_REG)
719         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
720                        (match_operand:DI 1 "arith_operand" "r"))
721                (const_int 0)))]
722   "TARGET_SH1"
723   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
724                                  insn, operands);"
725   [(set_attr "length" "6")
726    (set_attr "type" "arith3b")])
727
728 (define_insn "cmpeqdi_t"
729   [(set (reg:SI T_REG)
730         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
731                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
732   "TARGET_SH1"
733   "@
734         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
735         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
736   [(set_attr "length" "6")
737    (set_attr "type" "arith3b")])
738
739 (define_split
740   [(set (reg:SI T_REG)
741         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
742                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
743 ;; If we applied this split when not optimizing, it would only be
744 ;; applied during the machine-dependent reorg, when no new basic blocks
745 ;; may be created.
746   "TARGET_SH1 && reload_completed && optimize"
747   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
748    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
749                            (label_ref (match_dup 6))
750                            (pc)))
751    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
752    (match_dup 6)]
753   "
754 {
755   operands[2]
756     = gen_rtx_REG (SImode,
757                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
758   operands[3]
759     = (operands[1] == const0_rtx
760        ? const0_rtx
761        : gen_rtx_REG (SImode,
762                       true_regnum (operands[1])
763                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
764   operands[4] = gen_lowpart (SImode, operands[0]);
765   operands[5] = gen_lowpart (SImode, operands[1]);
766   operands[6] = gen_label_rtx ();
767 }")
768
769 (define_insn "cmpgtdi_t"
770   [(set (reg:SI T_REG)
771         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
772                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
773   "TARGET_SH2"
774   "@
775         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
776         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
777   [(set_attr "length" "8")
778    (set_attr "type" "arith3")])
779
780 (define_insn "cmpgedi_t"
781   [(set (reg:SI T_REG)
782         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
783                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
784   "TARGET_SH2"
785   "@
786         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
787         cmp/pz\\t%S0"
788   [(set_attr "length" "8,2")
789    (set_attr "type" "arith3,mt_group")])
790 \f
791 ;; -------------------------------------------------------------------------
792 ;; DImode unsigned integer comparisons
793 ;; -------------------------------------------------------------------------
794
795 (define_insn "cmpgeudi_t"
796   [(set (reg:SI T_REG)
797         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
798                 (match_operand:DI 1 "arith_reg_operand" "r")))]
799   "TARGET_SH2"
800   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
801   [(set_attr "length" "8")
802    (set_attr "type" "arith3")])
803
804 (define_insn "cmpgtudi_t"
805   [(set (reg:SI T_REG)
806         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
807                 (match_operand:DI 1 "arith_reg_operand" "r")))]
808   "TARGET_SH2"
809   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
810   [(set_attr "length" "8")
811    (set_attr "type" "arith3")])
812
813 (define_insn "cmpeqdi_media"
814   [(set (match_operand:DI 0 "register_operand" "=r")
815         (eq:DI (match_operand:DI 1 "register_operand" "%r")
816                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
817   "TARGET_SHMEDIA"
818   "cmpeq        %1, %N2, %0"
819   [(set_attr "type" "cmp_media")])
820
821 (define_insn "cmpgtdi_media"
822   [(set (match_operand:DI 0 "register_operand" "=r")
823         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
824                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
825   "TARGET_SHMEDIA"
826   "cmpgt        %N1, %N2, %0"
827   [(set_attr "type" "cmp_media")])
828
829 (define_insn "cmpgtudi_media"
830   [(set (match_operand:DI 0 "register_operand" "=r")
831         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
832                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
833   "TARGET_SHMEDIA"
834   "cmpgtu       %N1, %N2, %0"
835   [(set_attr "type" "cmp_media")])
836
837 ;; We save the compare operands in the cmpxx patterns and use them when
838 ;; we generate the branch.
839
840 (define_expand "cmpdi"
841   [(set (reg:SI T_REG)
842         (compare (match_operand:DI 0 "arith_operand" "")
843                  (match_operand:DI 1 "arith_operand" "")))]
844   "TARGET_SH2 || TARGET_SHMEDIA"
845   "
846 {
847   sh_compare_op0 = operands[0];
848   sh_compare_op1 = operands[1];
849   DONE;
850 }")
851 ;; -------------------------------------------------------------------------
852 ;; Conditional move instructions
853 ;; -------------------------------------------------------------------------
854
855 ;; The insn names may seem reversed, but note that cmveq performs the move
856 ;; if op1 == 0, and cmvne does it if op1 != 0.
857
858 (define_insn "movdicc_false"
859   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
860         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
861                              (const_int 0))
862          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
863          (match_operand:DI 3 "arith_reg_operand" "0")))]
864   "TARGET_SHMEDIA"
865   "cmveq        %1, %N2, %0"
866   [(set_attr "type" "arith_media")])
867
868 (define_insn "movdicc_true"
869   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
870         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
871                              (const_int 0))
872          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
873          (match_operand:DI 3 "arith_reg_operand" "0")))]
874   "TARGET_SHMEDIA"
875   "cmvne        %1, %N2, %0"
876   [(set_attr "type" "arith_media")])
877
878 (define_expand "movdicc"
879   [(set (match_operand:DI 0 "register_operand" "")
880         (if_then_else:DI (match_operand 1 "comparison_operator" "")
881                          (match_operand:DI 2 "register_operand" "")
882                          (match_operand:DI 3 "register_operand" "")))]
883   "TARGET_SHMEDIA"
884   "
885 {
886   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
887       && GET_MODE (sh_compare_op0) == DImode
888       && sh_compare_op1 == const0_rtx)
889     operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
890                            sh_compare_op0, sh_compare_op1);
891   else
892     {
893       rtx tmp;
894
895       if (no_new_pseudos)
896         FAIL;
897
898       tmp = gen_reg_rtx (DImode);
899
900       switch (GET_CODE (operands[1]))
901         {
902         case EQ:
903           emit_insn (gen_seq (tmp));
904           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
905           break;
906
907         case NE:
908           emit_insn (gen_seq (tmp));
909           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
910           break;
911
912         case GT:
913           emit_insn (gen_sgt (tmp));
914           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
915           break;
916
917         case LT:
918           emit_insn (gen_slt (tmp));
919           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
920           break;
921
922         case GE:
923           emit_insn (gen_slt (tmp));
924           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
925           break;
926
927         case LE:
928           emit_insn (gen_sgt (tmp));
929           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
930           break;
931
932         case GTU:
933           emit_insn (gen_sgtu (tmp));
934           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
935           break;
936
937         case LTU:
938           emit_insn (gen_sltu (tmp));
939           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
940           break;
941
942         case GEU:
943           emit_insn (gen_sltu (tmp));
944           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
945           break;
946
947         case LEU:
948           emit_insn (gen_sgtu (tmp));
949           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
950           break;
951
952         case UNORDERED:
953           emit_insn (gen_sunordered (tmp));
954           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
955           break;
956
957         case ORDERED:
958           emit_insn (gen_sunordered (tmp));
959           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
960           break;
961
962         case UNEQ:
963         case UNGE:
964         case UNGT:
965         case UNLE:
966         case UNLT:
967         case LTGT:
968           FAIL;
969
970         default:
971           abort ();
972         }
973     }
974 }")
975 \f
976 ;; -------------------------------------------------------------------------
977 ;; Addition instructions
978 ;; -------------------------------------------------------------------------
979
980 (define_expand "adddi3"
981   [(set (match_operand:DI 0 "arith_reg_operand" "")
982         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
983                  (match_operand:DI 2 "arith_operand" "")))]
984   ""
985   "
986 {
987   if (TARGET_SH1)
988     {
989       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
990         FAIL;
991       operands[2] = force_reg (DImode, operands[2]);
992       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
993       DONE;
994     }
995 }")
996
997 (define_insn "*adddi3_media"
998   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
999         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1000                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1001   "TARGET_SHMEDIA"
1002   "@
1003         add     %1, %2, %0
1004         addi    %1, %2, %0"
1005   [(set_attr "type" "arith_media")])
1006
1007 (define_insn "adddi3z_media"
1008   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1009         (zero_extend:DI
1010          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1011                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1012   "TARGET_SHMEDIA"
1013   "addz.l       %1, %N2, %0"
1014   [(set_attr "type" "arith_media")])
1015
1016 (define_insn "adddi3_compact"
1017   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1018         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1019                  (match_operand:DI 2 "arith_reg_operand" "r")))
1020    (clobber (reg:SI T_REG))]
1021   "TARGET_SH1"
1022   "#"
1023   [(set_attr "length" "6")])
1024
1025 (define_split
1026   [(set (match_operand:DI 0 "arith_reg_operand" "")
1027         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1028                  (match_operand:DI 2 "arith_reg_operand" "")))
1029    (clobber (reg:SI T_REG))]
1030   "TARGET_SH1 && reload_completed"
1031   [(const_int 0)]
1032   "
1033 {
1034   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1035   high0 = gen_rtx_REG (SImode,
1036                        true_regnum (operands[0])
1037                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1038   high2 = gen_rtx_REG (SImode,
1039                        true_regnum (operands[2])
1040                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1041   emit_insn (gen_clrt ());
1042   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1043   emit_insn (gen_addc1 (high0, high0, high2));
1044   DONE;
1045 }")
1046
1047 (define_insn "addc"
1048   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1049         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1050                           (match_operand:SI 2 "arith_reg_operand" "r"))
1051                  (reg:SI T_REG)))
1052    (set (reg:SI T_REG)
1053         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1054   "TARGET_SH1"
1055   "addc %2,%0"
1056   [(set_attr "type" "arith")])
1057
1058 (define_insn "addc1"
1059   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1060         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1061                           (match_operand:SI 2 "arith_reg_operand" "r"))
1062                  (reg:SI T_REG)))
1063    (clobber (reg:SI T_REG))]
1064   "TARGET_SH1"
1065   "addc %2,%0"
1066   [(set_attr "type" "arith")])
1067
1068 (define_expand "addsi3"
1069   [(set (match_operand:SI 0 "arith_reg_operand" "")
1070         (plus:SI (match_operand:SI 1 "arith_operand" "")
1071                  (match_operand:SI 2 "arith_operand" "")))]
1072   ""
1073   "
1074 {
1075   if (TARGET_SHMEDIA)
1076     operands[1] = force_reg (SImode, operands[1]);
1077 }")
1078
1079 (define_insn "addsi3_media"
1080   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1081         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1082                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1083   "TARGET_SHMEDIA"
1084   "@
1085         add.l   %1, %2, %0
1086         addi.l  %1, %2, %0"
1087   [(set_attr "type" "arith_media")])
1088
1089 (define_insn "*addsi3_compact"
1090   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1091         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1092                  (match_operand:SI 2 "arith_operand" "rI08")))]
1093   "TARGET_SH1"
1094   "add  %2,%0"
1095   [(set_attr "type" "arith")])
1096
1097 ;; -------------------------------------------------------------------------
1098 ;; Subtraction instructions
1099 ;; -------------------------------------------------------------------------
1100
1101 (define_expand "subdi3"
1102   [(set (match_operand:DI 0 "arith_reg_operand" "")
1103         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1104                   (match_operand:DI 2 "arith_reg_operand" "")))]
1105   ""
1106   "
1107 {
1108   if (TARGET_SH1)
1109     {
1110       operands[1] = force_reg (DImode, operands[1]);
1111       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1112       DONE;
1113     }
1114 }")
1115
1116 (define_insn "*subdi3_media"
1117   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1118         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1119                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1120   "TARGET_SHMEDIA"
1121   "sub  %N1, %2, %0"
1122   [(set_attr "type" "arith_media")])
1123
1124 (define_insn "subdi3_compact"
1125   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1126         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1127                  (match_operand:DI 2 "arith_reg_operand" "r")))
1128    (clobber (reg:SI T_REG))]
1129   "TARGET_SH1"
1130   "#"
1131   [(set_attr "length" "6")])
1132
1133 (define_split
1134   [(set (match_operand:DI 0 "arith_reg_operand" "")
1135         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1136                   (match_operand:DI 2 "arith_reg_operand" "")))
1137    (clobber (reg:SI T_REG))]
1138   "TARGET_SH1 && reload_completed"
1139   [(const_int 0)]
1140   "
1141 {
1142   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1143   high0 = gen_rtx_REG (SImode,
1144                        true_regnum (operands[0])
1145                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1146   high2 = gen_rtx_REG (SImode,
1147                        true_regnum (operands[2])
1148                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1149   emit_insn (gen_clrt ());
1150   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1151   emit_insn (gen_subc1 (high0, high0, high2));
1152   DONE;
1153 }")
1154
1155 (define_insn "subc"
1156   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1157         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1158                             (match_operand:SI 2 "arith_reg_operand" "r"))
1159                   (reg:SI T_REG)))
1160    (set (reg:SI T_REG)
1161         (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1162   "TARGET_SH1"
1163   "subc %2,%0"
1164   [(set_attr "type" "arith")])
1165
1166 (define_insn "subc1"
1167   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1168         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1169                             (match_operand:SI 2 "arith_reg_operand" "r"))
1170                   (reg:SI T_REG)))
1171    (clobber (reg:SI T_REG))]
1172   "TARGET_SH1"
1173   "subc %2,%0"
1174   [(set_attr "type" "arith")])
1175
1176 (define_insn "*subsi3_internal"
1177   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1178         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1179                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1180   "TARGET_SH1"
1181   "sub  %2,%0"
1182   [(set_attr "type" "arith")])
1183
1184 (define_insn "*subsi3_media"
1185   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1186         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1187                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1188   "TARGET_SHMEDIA"
1189   "sub.l        %N1, %2, %0"
1190   [(set_attr "type" "arith_media")])
1191
1192 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1193 ;; will sometimes save one instruction.  Otherwise we might get
1194 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1195 ;; are the same.
1196
1197 (define_expand "subsi3"
1198   [(set (match_operand:SI 0 "arith_reg_operand" "")
1199         (minus:SI (match_operand:SI 1 "arith_operand" "")
1200                   (match_operand:SI 2 "arith_reg_operand" "")))]
1201   ""
1202   "
1203 {
1204   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1205     {
1206       emit_insn (gen_negsi2 (operands[0], operands[2]));
1207       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1208       DONE;
1209     }
1210   if (TARGET_SHMEDIA)
1211     {
1212       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1213         FAIL;
1214       if (operands[1] != const0_rtx)
1215         operands[1] = force_reg (SImode, operands[1]);
1216     }
1217 }")
1218 \f
1219 ;; -------------------------------------------------------------------------
1220 ;; Division instructions
1221 ;; -------------------------------------------------------------------------
1222
1223 ;; We take advantage of the library routines which don't clobber as many
1224 ;; registers as a normal function call would.
1225
1226 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1227 ;; also has an effect on the register that holds the address of the sfunc.
1228 ;; To make this work, we have an extra dummy insn that shows the use
1229 ;; of this register for reorg.
1230
1231 (define_insn "use_sfunc_addr"
1232   [(set (reg:SI PR_REG)
1233         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1234   "TARGET_SH1"
1235   ""
1236   [(set_attr "length" "0")])
1237
1238 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1239 ;; hard register 0.  If we used hard register 0, then the next instruction
1240 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1241 ;; gets allocated to a stack slot that needs its address reloaded, then
1242 ;; there is nothing to prevent reload from using r0 to reload the address.
1243 ;; This reload would clobber the value in r0 we are trying to store.
1244 ;; If we let reload allocate r0, then this problem can never happen.
1245
1246 (define_insn "udivsi3_i1"
1247   [(set (match_operand:SI 0 "register_operand" "=z")
1248         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1249    (clobber (reg:SI T_REG))
1250    (clobber (reg:SI PR_REG))
1251    (clobber (reg:SI R4_REG))
1252    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1253   "TARGET_SH1 && ! TARGET_SH4"
1254   "jsr  @%1%#"
1255   [(set_attr "type" "sfunc")
1256    (set_attr "needs_delay_slot" "yes")])
1257
1258 ; Since shmedia-nofpu code could be linked against shcompact code, and
1259 ; the udivsi3 libcall has the same name, we must consider all registers
1260 ; clobbered that are in the union of the registers clobbered by the
1261 ; shmedia and the shcompact implementation.  Note, if the shcompact
1262 ; implementation actually used shcompact code, we'd need to clobber
1263 ; also r23 and fr23.
1264 (define_insn "udivsi3_i1_media"
1265   [(set (match_operand:SI 0 "register_operand" "=z")
1266         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1267    (clobber (reg:SI T_MEDIA_REG))
1268    (clobber (reg:SI PR_MEDIA_REG))
1269    (clobber (reg:SI R20_REG))
1270    (clobber (reg:SI R21_REG))
1271    (clobber (reg:SI R22_REG))
1272    (clobber (reg:DI TR0_REG))
1273    (clobber (reg:DI TR1_REG))
1274    (clobber (reg:DI TR2_REG))
1275    (use (match_operand:DI 1 "target_operand" "b"))]
1276   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1277   "blink        %1, r18"
1278   [(set_attr "type" "sfunc")
1279    (set_attr "needs_delay_slot" "yes")])
1280
1281 (define_expand "udivsi3_i4_media"
1282   [(set (match_dup 3)
1283         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1284    (set (match_dup 4)
1285         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1286    (set (match_dup 5) (float:DF (match_dup 3)))
1287    (set (match_dup 6) (float:DF (match_dup 4)))
1288    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1289    (set (match_dup 8) (fix:DI (match_dup 7)))
1290    (set (match_operand:SI 0 "register_operand" "")
1291         (truncate:SI (match_dup 8)))]
1292   "TARGET_SHMEDIA_FPU"
1293   "
1294 {
1295   operands[3] = gen_reg_rtx (DImode);
1296   operands[4] = gen_reg_rtx (DImode);
1297   operands[5] = gen_reg_rtx (DFmode);
1298   operands[6] = gen_reg_rtx (DFmode);
1299   operands[7] = gen_reg_rtx (DFmode);
1300   operands[8] = gen_reg_rtx (DImode);
1301 }")
1302
1303 (define_insn "udivsi3_i4"
1304   [(set (match_operand:SI 0 "register_operand" "=y")
1305         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1306    (clobber (reg:SI T_REG))
1307    (clobber (reg:SI PR_REG))
1308    (clobber (reg:DF DR0_REG))
1309    (clobber (reg:DF DR2_REG))
1310    (clobber (reg:DF DR4_REG))
1311    (clobber (reg:SI R0_REG))
1312    (clobber (reg:SI R1_REG))
1313    (clobber (reg:SI R4_REG))
1314    (clobber (reg:SI R5_REG))
1315    (use (reg:PSI FPSCR_REG))
1316    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1317   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1318   "jsr  @%1%#"
1319   [(set_attr "type" "sfunc")
1320    (set_attr "fp_mode" "double")
1321    (set_attr "needs_delay_slot" "yes")])
1322
1323 (define_insn "udivsi3_i4_single"
1324   [(set (match_operand:SI 0 "register_operand" "=y")
1325         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1326    (clobber (reg:SI T_REG))
1327    (clobber (reg:SI PR_REG))
1328    (clobber (reg:DF DR0_REG))
1329    (clobber (reg:DF DR2_REG))
1330    (clobber (reg:DF DR4_REG))
1331    (clobber (reg:SI R0_REG))
1332    (clobber (reg:SI R1_REG))
1333    (clobber (reg:SI R4_REG))
1334    (clobber (reg:SI R5_REG))
1335    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1336   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1337   "jsr  @%1%#"
1338   [(set_attr "type" "sfunc")
1339    (set_attr "needs_delay_slot" "yes")])
1340
1341 (define_expand "udivsi3"
1342   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1343    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1344    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1345    (parallel [(set (match_operand:SI 0 "register_operand" "")
1346                    (udiv:SI (reg:SI R4_REG)
1347                             (reg:SI R5_REG)))
1348               (clobber (reg:SI T_REG))
1349               (clobber (reg:SI PR_REG))
1350               (clobber (reg:SI R4_REG))
1351               (use (match_dup 3))])]
1352   ""
1353   "
1354 {
1355   rtx first, last;
1356
1357   operands[3] = gen_reg_rtx (Pmode);
1358   /* Emit the move of the address to a pseudo outside of the libcall.  */
1359   if (TARGET_HARD_SH4 && TARGET_SH2E)
1360     {
1361       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1362       if (TARGET_FPU_SINGLE)
1363         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1364       else
1365         last = gen_udivsi3_i4 (operands[0], operands[3]);
1366     }
1367   else if (TARGET_SHMEDIA_FPU)
1368     {
1369       operands[1] = force_reg (SImode, operands[1]);
1370       operands[2] = force_reg (SImode, operands[2]);
1371       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1372       DONE;
1373     }
1374   else if (TARGET_SH5)
1375     {
1376       emit_move_insn (operands[3],
1377                       function_symbol (TARGET_FPU_ANY
1378                                        ? \"__udivsi3_i4\"
1379                                        : \"__udivsi3\"));
1380
1381       if (TARGET_SHMEDIA)
1382         last = gen_udivsi3_i1_media (operands[0],
1383                                      Pmode == DImode
1384                                      ? operands[3]
1385                                      : gen_rtx_SUBREG (DImode, operands[3],
1386                                                        0));
1387       else if (TARGET_FPU_ANY)
1388         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1389       else
1390         last = gen_udivsi3_i1 (operands[0], operands[3]);
1391     }
1392   else
1393     {
1394       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1395       last = gen_udivsi3_i1 (operands[0], operands[3]);
1396     }
1397   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1398   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1399   last = emit_insn (last);
1400   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1401      invariant code motion can move it.  */
1402   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1403   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1404   DONE;
1405 }")
1406
1407 (define_insn "divsi3_i1"
1408   [(set (match_operand:SI 0 "register_operand" "=z")
1409         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1410    (clobber (reg:SI T_REG))
1411    (clobber (reg:SI PR_REG))
1412    (clobber (reg:SI R1_REG))
1413    (clobber (reg:SI R2_REG))
1414    (clobber (reg:SI R3_REG))
1415    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1416   "TARGET_SH1 && ! TARGET_SH4"
1417   "jsr  @%1%#"
1418   [(set_attr "type" "sfunc")
1419    (set_attr "needs_delay_slot" "yes")])
1420
1421 ; Since shmedia-nofpu code could be linked against shcompact code, and
1422 ; the sdivsi3 libcall has the same name, we must consider all registers
1423 ; clobbered that are in the union of the registers clobbered by the
1424 ; shmedia and the shcompact implementation.  Note, if the shcompact
1425 ; implementation actually used shcompact code, we'd need to clobber
1426 ; also r22, r23 and fr23.
1427 (define_insn "divsi3_i1_media"
1428   [(set (match_operand:SI 0 "register_operand" "=z")
1429         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1430    (clobber (reg:SI T_MEDIA_REG))
1431    (clobber (reg:SI PR_MEDIA_REG))
1432    (clobber (reg:SI R1_REG))
1433    (clobber (reg:SI R2_REG))
1434    (clobber (reg:SI R3_REG))
1435    (clobber (reg:SI R20_REG))
1436    (clobber (reg:SI R21_REG))
1437    (clobber (reg:DI TR0_REG))
1438    (clobber (reg:DI TR1_REG))
1439    (clobber (reg:DI TR2_REG))
1440    (use (match_operand:DI 1 "target_operand" "b"))]
1441   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1442   "blink        %1, r18"
1443   [(set_attr "type" "sfunc")])
1444
1445 (define_expand "divsi3_i4_media"
1446   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1447    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1448    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1449    (set (match_operand:SI 0 "register_operand" "=r")
1450         (fix:SI (match_dup 5)))]
1451   "TARGET_SHMEDIA_FPU"
1452   "
1453 {
1454   operands[3] = gen_reg_rtx (DFmode);
1455   operands[4] = gen_reg_rtx (DFmode);
1456   operands[5] = gen_reg_rtx (DFmode);
1457 }")
1458
1459 (define_insn "divsi3_i4"
1460   [(set (match_operand:SI 0 "register_operand" "=y")
1461         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1462    (clobber (reg:SI PR_REG))
1463    (clobber (reg:DF DR0_REG))
1464    (clobber (reg:DF DR2_REG))
1465    (use (reg:PSI FPSCR_REG))
1466    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1467   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1468   "jsr  @%1%#"
1469   [(set_attr "type" "sfunc")
1470    (set_attr "fp_mode" "double")
1471    (set_attr "needs_delay_slot" "yes")])
1472
1473 (define_insn "divsi3_i4_single"
1474   [(set (match_operand:SI 0 "register_operand" "=y")
1475         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1476    (clobber (reg:SI PR_REG))
1477    (clobber (reg:DF DR0_REG))
1478    (clobber (reg:DF DR2_REG))
1479    (clobber (reg:SI R2_REG))
1480    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1481   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1482   "jsr  @%1%#"
1483   [(set_attr "type" "sfunc")
1484    (set_attr "needs_delay_slot" "yes")])
1485
1486 (define_expand "divsi3"
1487   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1488    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1489    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1490    (parallel [(set (match_operand:SI 0 "register_operand" "")
1491                    (div:SI (reg:SI R4_REG)
1492                            (reg:SI R5_REG)))
1493               (clobber (reg:SI T_REG))
1494               (clobber (reg:SI PR_REG))
1495               (clobber (reg:SI R1_REG))
1496               (clobber (reg:SI R2_REG))
1497               (clobber (reg:SI R3_REG))
1498               (use (match_dup 3))])]
1499   ""
1500   "
1501 {
1502   rtx first, last;
1503
1504   operands[3] = gen_reg_rtx (Pmode);
1505   /* Emit the move of the address to a pseudo outside of the libcall.  */
1506   if (TARGET_HARD_SH4 && TARGET_SH2E)
1507     {
1508       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1509       if (TARGET_FPU_SINGLE)
1510         last = gen_divsi3_i4_single (operands[0], operands[3]);
1511       else
1512         last = gen_divsi3_i4 (operands[0], operands[3]);
1513     }
1514   else if (TARGET_SHMEDIA_FPU)
1515     {
1516       operands[1] = force_reg (SImode, operands[1]);
1517       operands[2] = force_reg (SImode, operands[2]);
1518       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1519       DONE;
1520     }
1521   else if (TARGET_SH5)
1522     {
1523       emit_move_insn (operands[3],
1524                       function_symbol (TARGET_FPU_ANY
1525                                        ? \"__sdivsi3_i4\"
1526                                        : \"__sdivsi3\"));
1527
1528       if (TARGET_SHMEDIA)
1529         last = gen_divsi3_i1_media (operands[0],
1530                                     Pmode == DImode
1531                                     ? operands[3]
1532                                     : gen_rtx_SUBREG (DImode, operands[3],
1533                                                       0));
1534       else if (TARGET_FPU_ANY)
1535         last = gen_divsi3_i4_single (operands[0], operands[3]);
1536       else
1537         last = gen_divsi3_i1 (operands[0], operands[3]);
1538     }
1539   else
1540     {
1541       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1542       last = gen_divsi3_i1 (operands[0], operands[3]);
1543     }
1544   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1545   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1546   last = emit_insn (last);
1547   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1548      invariant code motion can move it.  */
1549   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1550   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1551   DONE;
1552 }")
1553 \f
1554 ;; -------------------------------------------------------------------------
1555 ;; Multiplication instructions
1556 ;; -------------------------------------------------------------------------
1557
1558 (define_insn "umulhisi3_i"
1559   [(set (reg:SI MACL_REG)
1560         (mult:SI (zero_extend:SI
1561                   (match_operand:HI 0 "arith_reg_operand" "r"))
1562                  (zero_extend:SI
1563                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1564   "TARGET_SH1"
1565   "mulu.w       %1,%0"
1566   [(set_attr "type" "smpy")])
1567
1568 (define_insn "mulhisi3_i"
1569   [(set (reg:SI MACL_REG)
1570         (mult:SI (sign_extend:SI
1571                   (match_operand:HI 0 "arith_reg_operand" "r"))
1572                  (sign_extend:SI
1573                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1574   "TARGET_SH1"
1575   "muls.w       %1,%0"
1576   [(set_attr "type" "smpy")])
1577
1578 (define_expand "mulhisi3"
1579   [(set (reg:SI MACL_REG)
1580         (mult:SI (sign_extend:SI
1581                   (match_operand:HI 1 "arith_reg_operand" ""))
1582                  (sign_extend:SI
1583                   (match_operand:HI 2 "arith_reg_operand" ""))))
1584    (set (match_operand:SI 0 "arith_reg_operand" "")
1585         (reg:SI MACL_REG))]
1586   "TARGET_SH1"
1587   "
1588 {
1589   rtx first, last;
1590
1591   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1592   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1593   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1594      invariant code motion can move it.  */
1595   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1596   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1597   /* expand_binop can't find a suitable code in umul_widen_optab to
1598      make a REG_EQUAL note from, so make one here.
1599      See also smulsi3_highpart.
1600      ??? Alternatively, we could put this at the calling site of expand_binop,
1601      i.e. expand_expr.  */
1602   REG_NOTES (last)
1603     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1604                          REG_NOTES (last));
1605   DONE;
1606 }")
1607
1608 (define_expand "umulhisi3"
1609   [(set (reg:SI MACL_REG)
1610         (mult:SI (zero_extend:SI
1611                   (match_operand:HI 1 "arith_reg_operand" ""))
1612                  (zero_extend:SI
1613                   (match_operand:HI 2 "arith_reg_operand" ""))))
1614    (set (match_operand:SI 0 "arith_reg_operand" "")
1615         (reg:SI MACL_REG))]
1616   "TARGET_SH1"
1617   "
1618 {
1619   rtx first, last;
1620
1621   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1622   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1623   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1624      invariant code motion can move it.  */
1625   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1626   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1627   /* expand_binop can't find a suitable code in umul_widen_optab to
1628      make a REG_EQUAL note from, so make one here.
1629      See also smulsi3_highpart.
1630      ??? Alternatively, we could put this at the calling site of expand_binop,
1631      i.e. expand_expr.  */
1632   REG_NOTES (last)
1633     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1634                          REG_NOTES (last));
1635   DONE;
1636 }")
1637
1638 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1639 ;; a call to a routine which clobbers known registers.
1640
1641 (define_insn ""
1642   [(set (match_operand:SI 1 "register_operand" "=z")
1643         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1644    (clobber (reg:SI MACL_REG))
1645    (clobber (reg:SI T_REG))
1646    (clobber (reg:SI PR_REG))
1647    (clobber (reg:SI R3_REG))
1648    (clobber (reg:SI R2_REG))
1649    (clobber (reg:SI R1_REG))
1650    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1651   "TARGET_SH1"
1652   "jsr  @%0%#"
1653   [(set_attr "type" "sfunc")
1654    (set_attr "needs_delay_slot" "yes")])
1655
1656 (define_expand "mulsi3_call"
1657   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1658    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1659    (parallel[(set (match_operand:SI 0 "register_operand" "")
1660                   (mult:SI (reg:SI R4_REG)
1661                            (reg:SI R5_REG)))
1662              (clobber (reg:SI MACL_REG))
1663              (clobber (reg:SI T_REG))
1664              (clobber (reg:SI PR_REG))
1665              (clobber (reg:SI R3_REG))
1666              (clobber (reg:SI R2_REG))
1667              (clobber (reg:SI R1_REG))
1668              (use (match_operand:SI 3 "register_operand" ""))])]
1669   "TARGET_SH1"
1670   "")
1671
1672 (define_insn "mul_l"
1673   [(set (reg:SI MACL_REG)
1674         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1675                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1676   "TARGET_SH2"
1677   "mul.l        %1,%0"
1678   [(set_attr "type" "dmpy")])
1679
1680 (define_expand "mulsi3"
1681   [(set (reg:SI MACL_REG)
1682         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1683                   (match_operand:SI 2 "arith_reg_operand" "")))
1684    (set (match_operand:SI 0 "arith_reg_operand" "")
1685         (reg:SI MACL_REG))]
1686   "TARGET_SH1"
1687   "
1688 {
1689   rtx first, last;
1690
1691   if (!TARGET_SH2)
1692     {
1693       /* The address must be set outside the libcall,
1694          since it goes into a pseudo.  */
1695       rtx sym = function_symbol (\"__mulsi3\");
1696       rtx addr = force_reg (SImode, sym);
1697       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1698                                    operands[2], addr);
1699       first = insns;
1700       last = emit_insn (insns);
1701     }
1702   else
1703     {
1704       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1705
1706       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1707       /* consec_sets_giv can only recognize the first insn that sets a
1708          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1709          note.  */
1710       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1711     }
1712   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1713      invariant code motion can move it.  */
1714   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1715   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1716   DONE;
1717 }")
1718
1719 (define_insn "mulsidi3_i"
1720   [(set (reg:SI MACH_REG)
1721         (truncate:SI
1722          (lshiftrt:DI
1723           (mult:DI
1724            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1725            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1726           (const_int 32))))
1727    (set (reg:SI MACL_REG)
1728         (mult:SI (match_dup 0)
1729                  (match_dup 1)))]
1730   "TARGET_SH2"
1731   "dmuls.l      %1,%0"
1732   [(set_attr "type" "dmpy")])
1733
1734 (define_expand "mulsidi3"
1735   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1736         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1737                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1738   "TARGET_SH2 || TARGET_SHMEDIA"
1739   "
1740 {
1741   if (TARGET_SH2)
1742     {
1743        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1744                                         operands[2]));
1745        DONE;
1746     }
1747 }")
1748
1749 (define_insn "mulsidi3_media"
1750   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1751         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1752                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1753   "TARGET_SHMEDIA"
1754   "muls.l       %1, %2, %0"
1755   [(set_attr "type" "dmpy_media")])
1756
1757 (define_insn "mulsidi3_compact"
1758   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1759         (mult:DI
1760          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1761          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1762    (clobber (reg:SI MACH_REG))
1763    (clobber (reg:SI MACL_REG))]
1764   "TARGET_SH2"
1765   "#")
1766
1767 (define_split
1768   [(set (match_operand:DI 0 "arith_reg_operand" "")
1769         (mult:DI
1770          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1771          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1772    (clobber (reg:SI MACH_REG))
1773    (clobber (reg:SI MACL_REG))]
1774   "TARGET_SH2"
1775   [(const_int 0)]
1776   "
1777 {
1778   rtx low_dst = gen_lowpart (SImode, operands[0]);
1779   rtx high_dst = gen_highpart (SImode, operands[0]);
1780
1781   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1782
1783   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1784   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1785   /* We need something to tag the possible REG_EQUAL notes on to.  */
1786   emit_move_insn (operands[0], operands[0]);
1787   DONE;
1788 }")
1789
1790 (define_insn "umulsidi3_i"
1791   [(set (reg:SI MACH_REG)
1792         (truncate:SI
1793          (lshiftrt:DI
1794           (mult:DI
1795            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1796            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1797           (const_int 32))))
1798    (set (reg:SI MACL_REG)
1799         (mult:SI (match_dup 0)
1800                  (match_dup 1)))]
1801   "TARGET_SH2"
1802   "dmulu.l      %1,%0"
1803   [(set_attr "type" "dmpy")])
1804
1805 (define_expand "umulsidi3"
1806   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1807         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1808                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1809   "TARGET_SH2 || TARGET_SHMEDIA"
1810   "
1811 {
1812   if (TARGET_SH2)
1813     {
1814        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1815                                          operands[2]));
1816        DONE;
1817     }
1818 }")
1819
1820 (define_insn "umulsidi3_media"
1821   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1822         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1823                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1824   "TARGET_SHMEDIA"
1825   "mulu.l       %1, %2, %0"
1826   [(set_attr "type" "dmpy_media")])
1827
1828 (define_insn "umulsidi3_compact"
1829   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1830         (mult:DI
1831          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1832          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1833    (clobber (reg:SI MACH_REG))
1834    (clobber (reg:SI MACL_REG))]
1835   "TARGET_SH2"
1836   "#")
1837
1838 (define_split
1839   [(set (match_operand:DI 0 "arith_reg_operand" "")
1840         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1841                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1842    (clobber (reg:SI MACH_REG))
1843    (clobber (reg:SI MACL_REG))]
1844   "TARGET_SH2"
1845   [(const_int 0)]
1846   "
1847 {
1848   rtx low_dst = gen_lowpart (SImode, operands[0]);
1849   rtx high_dst = gen_highpart (SImode, operands[0]);
1850
1851   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1852
1853   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1854   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1855   /* We need something to tag the possible REG_EQUAL notes on to.  */
1856   emit_move_insn (operands[0], operands[0]);
1857   DONE;
1858 }")
1859
1860 (define_insn "smulsi3_highpart_i"
1861   [(set (reg:SI MACH_REG)
1862         (truncate:SI
1863          (lshiftrt:DI
1864           (mult:DI
1865            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1866            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1867           (const_int 32))))
1868    (clobber (reg:SI MACL_REG))]
1869   "TARGET_SH2"
1870   "dmuls.l      %1,%0"
1871   [(set_attr "type" "dmpy")])
1872
1873 (define_expand "smulsi3_highpart"
1874   [(parallel
1875     [(set (reg:SI MACH_REG)
1876           (truncate:SI
1877            (lshiftrt:DI
1878             (mult:DI
1879              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1880              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1881             (const_int 32))))
1882     (clobber (reg:SI MACL_REG))])
1883    (set (match_operand:SI 0 "arith_reg_operand" "")
1884         (reg:SI MACH_REG))]
1885   "TARGET_SH2"
1886   "
1887 {
1888   rtx first, last;
1889
1890   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1891   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1892   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1893      invariant code motion can move it.  */
1894   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1895   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1896   /* expand_binop can't find a suitable code in mul_highpart_optab to
1897      make a REG_EQUAL note from, so make one here.
1898      See also {,u}mulhisi.
1899      ??? Alternatively, we could put this at the calling site of expand_binop,
1900      i.e. expand_mult_highpart.  */
1901   REG_NOTES (last)
1902     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1903                          REG_NOTES (last));
1904   DONE;
1905 }")
1906
1907 (define_insn "umulsi3_highpart_i"
1908   [(set (reg:SI MACH_REG)
1909         (truncate:SI
1910          (lshiftrt:DI
1911           (mult:DI
1912            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1913            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1914           (const_int 32))))
1915    (clobber (reg:SI MACL_REG))]
1916   "TARGET_SH2"
1917   "dmulu.l      %1,%0"
1918   [(set_attr "type" "dmpy")])
1919
1920 (define_expand "umulsi3_highpart"
1921   [(parallel
1922     [(set (reg:SI MACH_REG)
1923           (truncate:SI
1924            (lshiftrt:DI
1925             (mult:DI
1926              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1927              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1928             (const_int 32))))
1929     (clobber (reg:SI MACL_REG))])
1930    (set (match_operand:SI 0 "arith_reg_operand" "")
1931         (reg:SI MACH_REG))]
1932   "TARGET_SH2"
1933   "
1934 {
1935   rtx first, last;
1936
1937   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1938   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1939   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1940      invariant code motion can move it.  */
1941   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1942   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1943   DONE;
1944 }")
1945 \f
1946 ;; -------------------------------------------------------------------------
1947 ;; Logical operations
1948 ;; -------------------------------------------------------------------------
1949
1950 (define_insn "*andsi3_compact"
1951   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1952         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1953                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1954   "TARGET_SH1"
1955   "and  %2,%0"
1956   [(set_attr "type" "arith")])
1957
1958 ;; If the constant is 255, then emit an extu.b instruction instead of an
1959 ;; and, since that will give better code.
1960
1961 (define_expand "andsi3"
1962   [(set (match_operand:SI 0 "arith_reg_operand" "")
1963         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1964                 (match_operand:SI 2 "logical_operand" "")))]
1965   "TARGET_SH1"
1966   "
1967 {
1968   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1969     {
1970       emit_insn (gen_zero_extendqisi2 (operands[0],
1971                                        gen_lowpart (QImode, operands[1])));
1972       DONE;
1973     }
1974 }")
1975
1976 (define_insn_and_split "anddi3"
1977   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1978         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1979                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1980   "TARGET_SHMEDIA"
1981   "@
1982         and     %1, %2, %0
1983         andi    %1, %2, %0
1984         #"
1985   "reload_completed
1986    && ! logical_operand (operands[2], DImode)"
1987   [(const_int 0)]
1988   "
1989 {
1990   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1991     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1992   else
1993     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1994   DONE;
1995 }"
1996   [(set_attr "type" "arith_media")])
1997
1998 (define_insn "andcdi3"
1999   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2000         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2001                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2002   "TARGET_SHMEDIA"
2003   "andc %1,%2,%0"
2004   [(set_attr "type" "arith_media")])
2005
2006 (define_insn "iorsi3"
2007   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2008         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2009                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2010   "TARGET_SH1"
2011   "or   %2,%0"
2012   [(set_attr "type" "arith")])
2013
2014 (define_insn "iordi3"
2015   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2016         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2017                 (match_operand:DI 2 "logical_operand" "r,I10")))]
2018   "TARGET_SHMEDIA"
2019   "@
2020         or      %1, %2, %0
2021         ori     %1, %2, %0"
2022   [(set_attr "type" "arith_media")])
2023
2024 (define_insn "xorsi3"
2025   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2026         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2027                 (match_operand:SI 2 "logical_operand" "K08,r")))]
2028   "TARGET_SH1"
2029   "xor  %2,%0"
2030   [(set_attr "type" "arith")])
2031
2032 (define_insn "xordi3"
2033   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2034         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2035                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2036   "TARGET_SHMEDIA"
2037   "@
2038         xor     %1, %2, %0
2039         xori    %1, %2, %0"
2040   [(set_attr "type" "arith_media")])
2041
2042 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2043 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2044 (define_split
2045   [(set (match_operand:DI 0 "arith_reg_operand" "")
2046         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2047                           [(match_operand 1 "any_register_operand" "")
2048                            (match_operand 2 "any_register_operand" "")])))]
2049   "TARGET_SHMEDIA"
2050   [(set (match_dup 5) (match_dup 4))
2051    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2052 "
2053 {
2054   enum machine_mode inmode = GET_MODE (operands[1]);
2055   int regno, offset = 0;
2056
2057   if (GET_CODE (operands[0]) == SUBREG)
2058     {
2059       offset = SUBREG_BYTE (operands[0]);
2060       operands[0] = SUBREG_REG (operands[0]);
2061     }
2062   if (GET_CODE (operands[0]) != REG)
2063     abort ();
2064   if (! TARGET_LITTLE_ENDIAN)
2065     offset += 8 - GET_MODE_SIZE (inmode);
2066   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2067 }")
2068 \f
2069 ;; -------------------------------------------------------------------------
2070 ;; Shifts and rotates
2071 ;; -------------------------------------------------------------------------
2072
2073 (define_expand "rotldi3"
2074   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2075         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2076                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2077   "TARGET_SHMEDIA"
2078   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2079
2080 (define_insn "rotldi3_mextr"
2081   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2082         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2083                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2084   "TARGET_SHMEDIA"
2085   "*
2086 {
2087   static char templ[16];
2088
2089   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2090            8 - (int) (INTVAL (operands[2]) >> 3));
2091   return templ;
2092 }"
2093   [(set_attr "type" "arith_media")])
2094
2095 (define_expand "rotrdi3"
2096   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2097         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2098                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2099   "TARGET_SHMEDIA"
2100   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2101
2102 (define_insn "rotrdi3_mextr"
2103   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2104         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2105                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2106   "TARGET_SHMEDIA"
2107   "*
2108 {
2109   static char templ[16];
2110
2111   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2112   return templ;
2113 }"
2114   [(set_attr "type" "arith_media")])
2115
2116 (define_insn "rotlsi3_1"
2117   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2118         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2119                    (const_int 1)))
2120    (set (reg:SI T_REG)
2121         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2122   "TARGET_SH1"
2123   "rotl %0"
2124   [(set_attr "type" "arith")])
2125
2126 (define_insn "rotlsi3_31"
2127   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2128         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2129                    (const_int 31)))
2130    (clobber (reg:SI T_REG))]
2131   "TARGET_SH1"
2132   "rotr %0"
2133   [(set_attr "type" "arith")])
2134
2135 (define_insn "rotlsi3_16"
2136   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2137         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2138                    (const_int 16)))]
2139   "TARGET_SH1"
2140   "swap.w       %1,%0"
2141   [(set_attr "type" "arith")])
2142
2143 (define_expand "rotlsi3"
2144   [(set (match_operand:SI 0 "arith_reg_operand" "")
2145         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2146                    (match_operand:SI 2 "immediate_operand" "")))]
2147   "TARGET_SH1"
2148   "
2149 {
2150   static const char rot_tab[] = {
2151     000, 000, 000, 000, 000, 000, 010, 001,
2152     001, 001, 011, 013, 003, 003, 003, 003,
2153     003, 003, 003, 003, 003, 013, 012, 002,
2154     002, 002, 010, 000, 000, 000, 000, 000,
2155   };
2156
2157   int count, choice;
2158
2159   if (GET_CODE (operands[2]) != CONST_INT)
2160     FAIL;
2161   count = INTVAL (operands[2]);
2162   choice = rot_tab[count];
2163   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2164     FAIL;
2165   choice &= 7;
2166   switch (choice)
2167     {
2168     case 0:
2169       emit_move_insn (operands[0], operands[1]);
2170       count -= (count & 16) * 2;
2171       break;
2172     case 3:
2173      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2174      count -= 16;
2175      break;
2176     case 1:
2177     case 2:
2178       {
2179         rtx parts[2];
2180         parts[0] = gen_reg_rtx (SImode);
2181         parts[1] = gen_reg_rtx (SImode);
2182         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2183         parts[choice-1] = operands[1];
2184         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2185         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2186         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2187         count = (count & ~16) - 8;
2188       }
2189     }
2190
2191   for (; count > 0; count--)
2192     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2193   for (; count < 0; count++)
2194     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2195
2196   DONE;
2197 }")
2198
2199 (define_insn "*rotlhi3_8"
2200   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2201         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2202                    (const_int 8)))]
2203   "TARGET_SH1"
2204   "swap.b       %1,%0"
2205   [(set_attr "type" "arith")])
2206
2207 (define_expand "rotlhi3"
2208   [(set (match_operand:HI 0 "arith_reg_operand" "")
2209         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2210                    (match_operand:HI 2 "immediate_operand" "")))]
2211   "TARGET_SH1"
2212   "
2213 {
2214   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2215     FAIL;
2216 }")
2217
2218 ;;
2219 ;; shift left
2220
2221 ;; This pattern is used by init_expmed for computing the costs of shift
2222 ;; insns.
2223
2224 (define_insn_and_split "ashlsi3_std"
2225   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2226         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2227                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2228    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2229   "TARGET_SH3
2230    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2231        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2232   "@
2233    shld %2,%0
2234    add  %0,%0
2235    shll%O2      %0
2236    #"
2237   "TARGET_SH3
2238    && reload_completed
2239    && GET_CODE (operands[2]) == CONST_INT
2240    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2241   [(set (match_dup 3) (match_dup 2))
2242    (parallel
2243     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2244      (clobber (match_dup 4))])]
2245   "operands[4] = gen_rtx_SCRATCH (SImode);"
2246   [(set_attr "length" "*,*,*,4")
2247    (set_attr "type" "dyn_shift,arith,arith,arith")])
2248
2249 (define_insn "ashlhi3_k"
2250   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2251         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2252                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2253   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2254   "@
2255         add     %0,%0
2256         shll%O2 %0"
2257   [(set_attr "type" "arith")])
2258
2259 (define_insn "ashlsi3_n"
2260   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2261         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2262                    (match_operand:SI 2 "const_int_operand" "n")))
2263    (clobber (reg:SI T_REG))]
2264   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2265   "#"
2266   [(set (attr "length")
2267         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2268                (const_string "2")
2269                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2270                (const_string "4")
2271                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2272                (const_string "6")]
2273               (const_string "8")))
2274    (set_attr "type" "arith")])
2275
2276 (define_split
2277   [(set (match_operand:SI 0 "arith_reg_operand" "")
2278         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2279                    (match_operand:SI 2 "const_int_operand" "")))
2280    (clobber (reg:SI T_REG))]
2281   "TARGET_SH1 && reload_completed"
2282   [(use (reg:SI R0_REG))]
2283   "
2284 {
2285   gen_shifty_op (ASHIFT, operands);
2286   DONE;
2287 }")
2288
2289 (define_insn "ashlsi3_media"
2290   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2291         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2292                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2293   "TARGET_SHMEDIA"
2294   "@
2295         shlld.l %1, %2, %0
2296         shlli.l %1, %2, %0"
2297   [(set_attr "type" "arith_media")])
2298
2299 (define_expand "ashlsi3"
2300   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2301                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2302                               (match_operand:SI 2 "nonmemory_operand" "")))
2303               (clobber (reg:SI T_REG))])]
2304   ""
2305   "
2306 {
2307   if (TARGET_SHMEDIA)
2308     {
2309       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2310       DONE;
2311     }
2312   if (GET_CODE (operands[2]) == CONST_INT
2313       && sh_dynamicalize_shift_p (operands[2]))
2314     operands[2] = force_reg (SImode, operands[2]);
2315   if (TARGET_SH3)
2316     {
2317       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2318       DONE;
2319     }
2320   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2321     FAIL;
2322 }")
2323
2324 (define_insn "ashlhi3"
2325   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2326         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2327                    (match_operand:HI 2 "const_int_operand" "n")))
2328    (clobber (reg:SI T_REG))]
2329   "TARGET_SH1"
2330   "#"
2331   [(set (attr "length")
2332         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2333                (const_string "2")
2334                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2335                (const_string "4")]
2336               (const_string "6")))
2337    (set_attr "type" "arith")])
2338
2339 (define_split
2340   [(set (match_operand:HI 0 "arith_reg_operand" "")
2341         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2342                    (match_operand:HI 2 "const_int_operand" "")))
2343    (clobber (reg:SI T_REG))]
2344   "TARGET_SH1 && reload_completed"
2345   [(use (reg:SI R0_REG))]
2346   "
2347 {
2348   gen_shifty_hi_op (ASHIFT, operands);
2349   DONE;
2350 }")
2351
2352 ;
2353 ; arithmetic shift right
2354 ;
2355
2356 (define_insn "ashrsi3_k"
2357   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2358         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2359                      (match_operand:SI 2 "const_int_operand" "M")))
2360    (clobber (reg:SI T_REG))]
2361   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2362   "shar %0"
2363   [(set_attr "type" "arith")])
2364
2365 ;; We can't do HImode right shifts correctly unless we start out with an
2366 ;; explicit zero / sign extension; doing that would result in worse overall
2367 ;; code, so just let the machine independent code widen the mode.
2368 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2369
2370
2371 ;; ??? This should be a define expand.
2372
2373 (define_insn "ashrsi2_16"
2374   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2375         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2376                      (const_int 16)))]
2377   "TARGET_SH1"
2378   "#"
2379   [(set_attr "length" "4")])
2380
2381 (define_split
2382   [(set (match_operand:SI 0 "arith_reg_operand" "")
2383         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2384                      (const_int 16)))]
2385   "TARGET_SH1"
2386   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2387    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2388   "operands[2] = gen_lowpart (HImode, operands[0]);")
2389
2390 ;; ??? This should be a define expand.
2391
2392 (define_insn "ashrsi2_31"
2393   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2394         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2395                      (const_int 31)))
2396    (clobber (reg:SI T_REG))]
2397   "TARGET_SH1"
2398   "#"
2399   [(set_attr "length" "4")])
2400
2401 (define_split
2402   [(set (match_operand:SI 0 "arith_reg_operand" "")
2403         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2404                      (const_int 31)))
2405    (clobber (reg:SI T_REG))]
2406   "TARGET_SH1"
2407   [(const_int 0)]
2408   "
2409 {
2410   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2411   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2412   DONE;
2413 }")
2414
2415 (define_insn "ashlsi_c"
2416   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2417         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2418    (set (reg:SI T_REG)
2419         (lt:SI (match_dup 1) (const_int 0)))]
2420   "TARGET_SH1"
2421   "shll %0"
2422   [(set_attr "type" "arith")])
2423
2424 (define_insn "ashrsi3_d"
2425   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2426         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2427                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2428   "TARGET_SH3"
2429   "shad %2,%0"
2430   [(set_attr "type" "dyn_shift")])
2431
2432 (define_insn "ashrsi3_n"
2433   [(set (reg:SI R4_REG)
2434         (ashiftrt:SI (reg:SI R4_REG)
2435                      (match_operand:SI 0 "const_int_operand" "i")))
2436    (clobber (reg:SI T_REG))
2437    (clobber (reg:SI PR_REG))
2438    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2439   "TARGET_SH1"
2440   "jsr  @%1%#"
2441   [(set_attr "type" "sfunc")
2442    (set_attr "needs_delay_slot" "yes")])
2443
2444 (define_insn "ashrsi3_media"
2445   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2446         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2447                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2448   "TARGET_SHMEDIA"
2449   "@
2450         shard.l %1, %2, %0
2451         shari.l %1, %2, %0"
2452   [(set_attr "type" "arith_media")])
2453
2454 (define_expand "ashrsi3"
2455   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2456                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2457                                 (match_operand:SI 2 "nonmemory_operand" "")))
2458               (clobber (reg:SI T_REG))])]
2459   ""
2460   "
2461 {
2462   if (TARGET_SHMEDIA)
2463     {
2464       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2465       DONE;
2466     }
2467   if (expand_ashiftrt (operands))
2468     DONE;
2469   else
2470     FAIL;
2471 }")
2472
2473 ;; logical shift right
2474
2475 (define_insn "lshrsi3_d"
2476   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2477         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2478                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2479   "TARGET_SH3"
2480   "shld %2,%0"
2481   [(set_attr "type" "dyn_shift")])
2482
2483 ;;  Only the single bit shift clobbers the T bit.
2484
2485 (define_insn "lshrsi3_m"
2486   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2487         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2488                      (match_operand:SI 2 "const_int_operand" "M")))
2489    (clobber (reg:SI T_REG))]
2490   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2491   "shlr %0"
2492   [(set_attr "type" "arith")])
2493
2494 (define_insn "lshrsi3_k"
2495   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2496         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2497                      (match_operand:SI 2 "const_int_operand" "P27")))]
2498   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2499    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2500   "shlr%O2      %0"
2501   [(set_attr "type" "arith")])
2502
2503 (define_insn "lshrsi3_n"
2504   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2505         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2506                      (match_operand:SI 2 "const_int_operand" "n")))
2507    (clobber (reg:SI T_REG))]
2508   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2509   "#"
2510   [(set (attr "length")
2511         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2512                (const_string "2")
2513                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2514                (const_string "4")
2515                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2516                (const_string "6")]
2517               (const_string "8")))
2518    (set_attr "type" "arith")])
2519
2520 (define_split
2521   [(set (match_operand:SI 0 "arith_reg_operand" "")
2522         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2523                      (match_operand:SI 2 "const_int_operand" "")))
2524    (clobber (reg:SI T_REG))]
2525   "TARGET_SH1 && reload_completed"
2526   [(use (reg:SI R0_REG))]
2527   "
2528 {
2529   gen_shifty_op (LSHIFTRT, operands);
2530   DONE;
2531 }")
2532
2533 (define_insn "lshrsi3_media"
2534   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2535         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2536                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2537   "TARGET_SHMEDIA"
2538   "@
2539         shlrd.l %1, %2, %0
2540         shlri.l %1, %2, %0"
2541   [(set_attr "type" "arith_media")])
2542
2543 (define_expand "lshrsi3"
2544   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2545                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2546                                 (match_operand:SI 2 "nonmemory_operand" "")))
2547               (clobber (reg:SI T_REG))])]
2548   ""
2549   "
2550 {
2551   if (TARGET_SHMEDIA)
2552     {
2553       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2554       DONE;
2555     }
2556   if (GET_CODE (operands[2]) == CONST_INT
2557       && sh_dynamicalize_shift_p (operands[2]))
2558     operands[2] = force_reg (SImode, operands[2]);
2559   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2560     {
2561       rtx count = copy_to_mode_reg (SImode, operands[2]);
2562       emit_insn (gen_negsi2 (count, count));
2563       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2564       DONE;
2565     }
2566   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2567     FAIL;
2568 }")
2569
2570 ;; ??? This should be a define expand.
2571
2572 (define_insn "ashldi3_k"
2573   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2574         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2575                    (const_int 1)))
2576    (clobber (reg:SI T_REG))]
2577   "TARGET_SH1"
2578   "shll %R0\;rotcl      %S0"
2579   [(set_attr "length" "4")
2580    (set_attr "type" "arith")])
2581
2582 (define_insn "ashldi3_media"
2583   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2584         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2585                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2586   "TARGET_SHMEDIA"
2587   "@
2588         shlld   %1, %2, %0
2589         shlli   %1, %2, %0"
2590   [(set_attr "type" "arith_media")])
2591
2592 (define_expand "ashldi3"
2593   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2594                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2595                               (match_operand:DI 2 "immediate_operand" "")))
2596               (clobber (reg:SI T_REG))])]
2597   ""
2598   "
2599 {
2600   if (TARGET_SHMEDIA)
2601     {
2602       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2603       DONE;
2604     }
2605   if (GET_CODE (operands[2]) != CONST_INT
2606       || INTVAL (operands[2]) != 1)
2607     FAIL;
2608 }")
2609
2610 ;; ??? This should be a define expand.
2611
2612 (define_insn "lshrdi3_k"
2613   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2614         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2615                      (const_int 1)))
2616    (clobber (reg:SI T_REG))]
2617   "TARGET_SH1"
2618   "shlr %S0\;rotcr      %R0"
2619   [(set_attr "length" "4")
2620    (set_attr "type" "arith")])
2621
2622 (define_insn "lshrdi3_media"
2623   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2624         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2625                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2626   "TARGET_SHMEDIA"
2627   "@
2628         shlrd   %1, %2, %0
2629         shlri   %1, %2, %0"
2630   [(set_attr "type" "arith_media")])
2631
2632 (define_expand "lshrdi3"
2633   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2634                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2635                                (match_operand:DI 2 "immediate_operand" "")))
2636              (clobber (reg:SI T_REG))])]
2637   ""
2638   "
2639 {
2640   if (TARGET_SHMEDIA)
2641     {
2642       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2643       DONE;
2644     }
2645   if (GET_CODE (operands[2]) != CONST_INT
2646       || INTVAL (operands[2]) != 1)
2647     FAIL;
2648 }")
2649
2650 ;; ??? This should be a define expand.
2651
2652 (define_insn "ashrdi3_k"
2653   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2654         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2655                      (const_int 1)))
2656    (clobber (reg:SI T_REG))]
2657   "TARGET_SH1"
2658   "shar %S0\;rotcr      %R0"
2659   [(set_attr "length" "4")
2660    (set_attr "type" "arith")])
2661
2662 (define_insn "ashrdi3_media"
2663   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2664         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2665                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2666   "TARGET_SHMEDIA"
2667   "@
2668         shard   %1, %2, %0
2669         shari   %1, %2, %0"
2670   [(set_attr "type" "arith_media")])
2671
2672 (define_expand "ashrdi3"
2673   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2674                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2675                                 (match_operand:DI 2 "immediate_operand" "")))
2676               (clobber (reg:SI T_REG))])]
2677   ""
2678   "
2679 {
2680   if (TARGET_SHMEDIA)
2681     {
2682       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2683       DONE;
2684     }
2685   if (GET_CODE (operands[2]) != CONST_INT
2686       || INTVAL (operands[2]) != 1)
2687     FAIL;
2688 }")
2689
2690 ;; combined left/right shift
2691
2692 (define_split
2693   [(set (match_operand:SI 0 "register_operand" "")
2694         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2695                            (match_operand:SI 2 "const_int_operand" ""))
2696                 (match_operand:SI 3 "const_int_operand" "")))]
2697   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2698   [(use (reg:SI R0_REG))]
2699   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2700    DONE;")
2701
2702 (define_split
2703   [(set (match_operand:SI 0 "register_operand" "")
2704         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2705                            (match_operand:SI 2 "const_int_operand" ""))
2706                 (match_operand:SI 3 "const_int_operand" "")))
2707    (clobber (reg:SI T_REG))]
2708   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2709   [(use (reg:SI R0_REG))]
2710   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2711    DONE;")
2712
2713 (define_insn ""
2714   [(set (match_operand:SI 0 "register_operand" "=r")
2715         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2716                            (match_operand:SI 2 "const_int_operand" "n"))
2717                 (match_operand:SI 3 "const_int_operand" "n")))
2718    (clobber (reg:SI T_REG))]
2719   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2720  "#"
2721   [(set (attr "length")
2722         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2723                (const_string "4")
2724                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2725                (const_string "6")
2726                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2727                (const_string "8")
2728                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2729                (const_string "10")
2730                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2731                (const_string "12")
2732                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2733                (const_string "14")
2734                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2735                (const_string "16")]
2736               (const_string "18")))
2737    (set_attr "type" "arith")])
2738
2739 (define_insn ""
2740   [(set (match_operand:SI 0 "register_operand" "=z")
2741         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2742                            (match_operand:SI 2 "const_int_operand" "n"))
2743                 (match_operand:SI 3 "const_int_operand" "n")))
2744    (clobber (reg:SI T_REG))]
2745   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2746  "#"
2747   [(set (attr "length")
2748         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2749                (const_string "4")
2750                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2751                (const_string "6")
2752                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2753                (const_string "8")]
2754               (const_string "10")))
2755    (set_attr "type" "arith")])
2756
2757 ;; shift left / and combination with a scratch register: The combine pass
2758 ;; does not accept the individual instructions, even though they are
2759 ;; cheap.  But it needs a precise description so that it is usable after
2760 ;; reload.
2761 (define_insn "and_shl_scratch"
2762   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2763         (lshiftrt:SI
2764          (ashift:SI
2765           (and:SI
2766            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2767                         (match_operand:SI 2 "const_int_operand" "N,n"))
2768            (match_operand:SI 3 "" "0,r"))
2769           (match_operand:SI 4 "const_int_operand" "n,n"))
2770          (match_operand:SI 5 "const_int_operand" "n,n")))
2771    (clobber (reg:SI T_REG))]
2772   "TARGET_SH1"
2773   "#"
2774   [(set (attr "length")
2775         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2776                (const_string "4")
2777                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2778                (const_string "6")
2779                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2780                (const_string "8")
2781                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2782                (const_string "10")]
2783               (const_string "12")))
2784    (set_attr "type" "arith")])
2785
2786 (define_split
2787   [(set (match_operand:SI 0 "register_operand" "")
2788         (lshiftrt:SI
2789          (ashift:SI
2790           (and:SI
2791            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2792                         (match_operand:SI 2 "const_int_operand" ""))
2793            (match_operand:SI 3 "register_operand" ""))
2794           (match_operand:SI 4 "const_int_operand" ""))
2795          (match_operand:SI 5 "const_int_operand" "")))
2796    (clobber (reg:SI T_REG))]
2797   "TARGET_SH1"
2798   [(use (reg:SI R0_REG))]
2799   "
2800 {
2801   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2802
2803   if (INTVAL (operands[2]))
2804     {
2805       gen_shifty_op (LSHIFTRT, operands);
2806     }
2807   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2808   operands[2] = operands[4];
2809   gen_shifty_op (ASHIFT, operands);
2810   if (INTVAL (operands[5]))
2811     {
2812       operands[2] = operands[5];
2813       gen_shifty_op (LSHIFTRT, operands);
2814     }
2815   DONE;
2816 }")
2817
2818 ;; signed left/right shift combination.
2819 (define_split
2820   [(set (match_operand:SI 0 "register_operand" "")
2821         (sign_extract:SI
2822          (ashift:SI (match_operand:SI 1 "register_operand" "")
2823                     (match_operand:SI 2 "const_int_operand" ""))
2824          (match_operand:SI 3 "const_int_operand" "")
2825          (const_int 0)))
2826    (clobber (reg:SI T_REG))]
2827   "TARGET_SH1"
2828   [(use (reg:SI R0_REG))]
2829   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2830    DONE;")
2831
2832 (define_insn "shl_sext_ext"
2833   [(set (match_operand:SI 0 "register_operand" "=r")
2834         (sign_extract:SI
2835          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2836                     (match_operand:SI 2 "const_int_operand" "n"))
2837          (match_operand:SI 3 "const_int_operand" "n")
2838          (const_int 0)))
2839    (clobber (reg:SI T_REG))]
2840   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2841   "#"
2842   [(set (attr "length")
2843         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2844                (const_string "2")
2845                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2846                (const_string "4")
2847                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2848                (const_string "6")
2849                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2850                (const_string "8")
2851                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2852                (const_string "10")
2853                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2854                (const_string "12")
2855                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2856                (const_string "14")
2857                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2858                (const_string "16")]
2859               (const_string "18")))
2860     (set_attr "type" "arith")])
2861
2862 (define_insn "shl_sext_sub"
2863   [(set (match_operand:SI 0 "register_operand" "=z")
2864         (sign_extract:SI
2865          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2866                     (match_operand:SI 2 "const_int_operand" "n"))
2867          (match_operand:SI 3 "const_int_operand" "n")
2868          (const_int 0)))
2869    (clobber (reg:SI T_REG))]
2870   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2871   "#"
2872   [(set (attr "length")
2873         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2874                (const_string "6")
2875                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2876                (const_string "8")
2877                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2878                (const_string "10")
2879                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2880                (const_string "12")]
2881               (const_string "14")))
2882     (set_attr "type" "arith")])
2883
2884 ;; These patterns are found in expansions of DImode shifts by 16, and
2885 ;; allow the xtrct instruction to be generated from C source.
2886
2887 (define_insn "xtrct_left"
2888   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2889         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2890                            (const_int 16))
2891                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2892                              (const_int 16))))]
2893   "TARGET_SH1"
2894   "xtrct        %1,%0"
2895   [(set_attr "type" "arith")])
2896
2897 (define_insn "xtrct_right"
2898   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2899         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2900                              (const_int 16))
2901                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2902                            (const_int 16))))]
2903   "TARGET_SH1"
2904   "xtrct        %2,%0"
2905   [(set_attr "type" "arith")])
2906
2907 ;; -------------------------------------------------------------------------
2908 ;; Unary arithmetic
2909 ;; -------------------------------------------------------------------------
2910
2911 (define_insn "negc"
2912   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913         (neg:SI (plus:SI (reg:SI T_REG)
2914                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2915    (set (reg:SI T_REG)
2916         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2917                (const_int 0)))]
2918   "TARGET_SH1"
2919   "negc %1,%0"
2920   [(set_attr "type" "arith")])
2921
2922 (define_insn "*negdi_media"
2923   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2924         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2925   "TARGET_SHMEDIA"
2926   "sub  r63, %1, %0"
2927   [(set_attr "type" "arith_media")])
2928
2929 (define_expand "negdi2"
2930   [(set (match_operand:DI 0 "arith_reg_operand" "")
2931         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2932   ""
2933   "
2934 {
2935   if (TARGET_SH1)
2936     {
2937       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2938       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2939
2940       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2941       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2942
2943       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2944       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2945
2946       emit_insn (gen_clrt ());
2947       emit_insn (gen_negc (low_dst, low_src));
2948       emit_insn (gen_negc (high_dst, high_src));
2949       DONE;
2950     }
2951 }")
2952
2953 (define_insn "negsi2"
2954   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2955         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2956   "TARGET_SH1"
2957   "neg  %1,%0"
2958   [(set_attr "type" "arith")])
2959
2960 (define_insn "one_cmplsi2"
2961   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2962         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2963   "TARGET_SH1"
2964   "not  %1,%0"
2965   [(set_attr "type" "arith")])
2966
2967 (define_expand "one_cmpldi2"
2968   [(set (match_operand:DI 0 "arith_reg_operand" "")
2969         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2970                 (const_int -1)))]
2971   "TARGET_SHMEDIA" "")
2972 \f
2973 ;; -------------------------------------------------------------------------
2974 ;; Zero extension instructions
2975 ;; -------------------------------------------------------------------------
2976
2977 (define_insn "zero_extendsidi2"
2978   [(set (match_operand:DI 0 "register_operand" "=r")
2979         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2980   "TARGET_SHMEDIA"
2981   "addz.l       %1, r63, %0"
2982   [(set_attr "type" "arith_media")])
2983
2984 (define_insn "zero_extendhidi2"
2985   [(set (match_operand:DI 0 "register_operand" "=r,r")
2986         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2987   "TARGET_SHMEDIA"
2988   "@
2989         #
2990         ld%M1.uw        %m1, %0"
2991   [(set_attr "type" "*,load_media")])
2992
2993 (define_split
2994   [(set (match_operand:DI 0 "register_operand" "")
2995         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2996   "TARGET_SHMEDIA && reload_completed"
2997   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2998    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2999   "
3000 {
3001   if (GET_CODE (operands[1]) == TRUNCATE)
3002     operands[1] = XEXP (operands[1], 0);
3003 }")
3004
3005 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
3006 ;; reload the entrire truncate expression.
3007 (define_insn_and_split "*loaddi_trunc"
3008   [(set (match_operand 0 "int_gpr_dest" "=r")
3009         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3010   "TARGET_SHMEDIA && reload_completed"
3011   "#"
3012   "TARGET_SHMEDIA && reload_completed"
3013   [(set (match_dup 0) (match_dup 1))]
3014   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3015
3016 (define_insn "zero_extendqidi2"
3017   [(set (match_operand:DI 0 "register_operand" "=r,r")
3018         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3019   "TARGET_SHMEDIA"
3020   "@
3021         andi    %1, 255, %0
3022         ld%M1.ub        %m1, %0"
3023   [(set_attr "type" "arith_media,load_media")])
3024
3025 (define_expand "zero_extendhisi2"
3026   [(set (match_operand:SI 0 "arith_reg_operand" "")
3027         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3028   ""
3029   "
3030 {
3031   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3032     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3033 }")
3034
3035 (define_insn "*zero_extendhisi2_compact"
3036   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3037         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3038   "TARGET_SH1"
3039   "extu.w       %1,%0"
3040   [(set_attr "type" "arith")])
3041
3042 (define_insn "*zero_extendhisi2_media"
3043   [(set (match_operand:SI 0 "register_operand" "=r,r")
3044         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3045   "TARGET_SHMEDIA"
3046   "@
3047         #
3048         ld%M1.uw        %m1, %0"
3049   [(set_attr "type" "arith_media,load_media")])
3050
3051 (define_split
3052   [(set (match_operand:SI 0 "register_operand" "")
3053         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3054   "TARGET_SHMEDIA && reload_completed"
3055   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3056    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3057   "
3058 {
3059   if (GET_CODE (operands[1]) == TRUNCATE)
3060     operands[1] = XEXP (operands[1], 0);
3061 }")
3062
3063 (define_expand "zero_extendqisi2"
3064   [(set (match_operand:SI 0 "arith_reg_operand" "")
3065         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3066   ""
3067   "
3068 {
3069   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3070     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3071 }")
3072
3073 (define_insn "*zero_extendqisi2_compact"
3074   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3075         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3076   "TARGET_SH1"
3077   "extu.b       %1,%0"
3078   [(set_attr "type" "arith")])
3079
3080 (define_insn "*zero_extendqisi2_media"
3081   [(set (match_operand:SI 0 "register_operand" "=r,r")
3082         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3083   "TARGET_SHMEDIA"
3084   "@
3085         andi    %1, 255, %0
3086         ld%M1.ub        %m1, %0"
3087   [(set_attr "type" "arith_media,load_media")])
3088
3089 (define_insn "zero_extendqihi2"
3090   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3091         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3092   "TARGET_SH1"
3093   "extu.b       %1,%0"
3094   [(set_attr "type" "arith")])
3095
3096 ;; -------------------------------------------------------------------------
3097 ;; Sign extension instructions
3098 ;; -------------------------------------------------------------------------
3099
3100 ;; ??? This should be a define expand.
3101 ;; ??? Or perhaps it should be dropped?
3102
3103 ;; convert_move generates good code for SH[1-4].
3104 (define_insn "extendsidi2"
3105   [(set (match_operand:DI 0 "register_operand" "=r,r")
3106         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3107   "TARGET_SHMEDIA"
3108   "@
3109         add.l   %1, r63, %0
3110         ld%M1.l %m1, %0"
3111   [(set_attr "type" "arith_media,load_media")])
3112
3113 (define_insn "extendhidi2"
3114   [(set (match_operand:DI 0 "register_operand" "=r,r")
3115         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3116   "TARGET_SHMEDIA"
3117   "@
3118         #
3119         ld%M1.w %m1, %0"
3120   [(set_attr "type" "*,load_media")])
3121
3122 (define_split
3123   [(set (match_operand:DI 0 "register_operand" "")
3124         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3125   "TARGET_SHMEDIA && reload_completed"
3126   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3127    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3128   "
3129 {
3130   if (GET_CODE (operands[1]) == TRUNCATE)
3131     operands[1] = XEXP (operands[1], 0);
3132 }")
3133
3134 (define_insn "extendqidi2"
3135   [(set (match_operand:DI 0 "register_operand" "=r,r")
3136         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3137   "TARGET_SHMEDIA"
3138   "@
3139         #
3140         ld%M1.b %m1, %0"
3141   [(set_attr "type" "*,load_media")])
3142
3143 (define_split
3144   [(set (match_operand:DI 0 "register_operand" "")
3145         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3146   "TARGET_SHMEDIA && reload_completed"
3147   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3148    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3149   "
3150 {
3151   if (GET_CODE (operands[1]) == TRUNCATE)
3152     operands[1] = XEXP (operands[1], 0);
3153 }")
3154
3155 (define_expand "extendhisi2"
3156   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3157        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3158   ""
3159   "")
3160
3161 (define_insn "*extendhisi2_compact"
3162   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3163         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3164   "TARGET_SH1"
3165   "@
3166         exts.w  %1,%0
3167         mov.w   %1,%0"
3168   [(set_attr "type" "arith,load")])
3169
3170 (define_insn "*extendhisi2_media"
3171   [(set (match_operand:SI 0 "register_operand" "=r,r")
3172         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3173   "TARGET_SHMEDIA"
3174   "@
3175         #
3176         ld%M1.w %m1, %0"
3177   [(set_attr "type" "arith_media,load_media")])
3178
3179 (define_split
3180   [(set (match_operand:SI 0 "register_operand" "")
3181         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3182   "TARGET_SHMEDIA && reload_completed"
3183   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3184    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3185   "
3186 {
3187   if (GET_CODE (operands[1]) == TRUNCATE)
3188     operands[1] = XEXP (operands[1], 0);
3189 }")
3190
3191 (define_expand "extendqisi2"
3192   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3193         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3194   ""
3195   "")
3196
3197 (define_insn "*extendqisi2_compact"
3198   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3199         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3200   "TARGET_SH1"
3201   "@
3202         exts.b  %1,%0
3203         mov.b   %1,%0"
3204   [(set_attr "type" "arith,load")])
3205
3206 (define_insn "*extendqisi2_media"
3207   [(set (match_operand:SI 0 "register_operand" "=r,r")
3208         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3209   "TARGET_SHMEDIA"
3210   "@
3211         #
3212         ld%M1.b %m1, %0"
3213   [(set_attr "type" "arith_media,load_media")])
3214
3215 (define_split
3216   [(set (match_operand:SI 0 "register_operand" "")
3217         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3218   "TARGET_SHMEDIA && reload_completed"
3219   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3220    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3221    "
3222 {
3223   if (GET_CODE (operands[1]) == TRUNCATE)
3224     operands[1] = XEXP (operands[1], 0);
3225 }")
3226
3227 (define_insn "extendqihi2"
3228   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3229         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3230   "TARGET_SH1"
3231   "@
3232         exts.b  %1,%0
3233         mov.b   %1,%0"
3234   [(set_attr "type" "arith,load")])
3235
3236 /* It would seem useful to combine the truncXi patterns into the movXi
3237    patterns, but unary operators are ignored when matching constraints,
3238    so we need separate patterns.  */
3239 (define_insn "truncdisi2"
3240   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3241         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3242   "TARGET_SHMEDIA"
3243   "@
3244         add.l   %1, r63, %0
3245         st%M0.l %m0, %1
3246         fst%M0.s        %m0, %T1
3247         fmov.ls %1, %0
3248         fmov.sl %T1, %0
3249         fmov.s  %T1, %0"
3250   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3251
3252
3253 (define_insn "truncdihi2"
3254   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3255         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3256   "TARGET_SHMEDIA"
3257   "@
3258         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3259         st%M0.w %m0, %1"
3260   [(set_attr "type"   "arith_media,store_media")
3261    (set_attr "length" "8,4")])
3262
3263 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3264 ; Because we use zero extension, we can't provide signed QImode compares
3265 ; using a simple compare or conditional banch insn.
3266 (define_insn "truncdiqi2"
3267   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3268         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3269   "TARGET_SHMEDIA"
3270   "@
3271         and     %1, 255, %0
3272         st%M0.b %m0, %1"
3273   [(set_attr "type"   "arith_media,store")])
3274
3275 ;; -------------------------------------------------------------------------
3276 ;; Move instructions
3277 ;; -------------------------------------------------------------------------
3278
3279 ;; define push and pop so it is easy for sh.c
3280 ;; We can't use push and pop on SHcompact because the stack must always
3281 ;; be 8-byte aligned.
3282
3283 (define_expand "push"
3284   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3285         (match_operand:SI 0 "register_operand" "r,l,x"))]
3286   "TARGET_SH1 && ! TARGET_SH5"
3287   "")
3288
3289 (define_expand "pop"
3290   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3291         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3292   "TARGET_SH1 && ! TARGET_SH5"
3293   "")
3294
3295 (define_expand "push_e"
3296   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3297                    (match_operand:SF 0 "" ""))
3298               (use (reg:PSI FPSCR_REG))
3299               (clobber (scratch:SI))])]
3300   "TARGET_SH1 && ! TARGET_SH5"
3301   "")
3302
3303 (define_insn "push_fpul"
3304   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3305   "TARGET_SH2E && ! TARGET_SH5"
3306   "sts.l        fpul,@-r15"
3307   [(set_attr "type" "store")
3308    (set_attr "late_fp_use" "yes")
3309    (set_attr "hit_stack" "yes")])
3310
3311 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3312 ;; so use that.
3313 (define_expand "push_4"
3314   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3315                    (match_operand:DF 0 "" ""))
3316               (use (reg:PSI FPSCR_REG))
3317               (clobber (scratch:SI))])]
3318   "TARGET_SH1 && ! TARGET_SH5"
3319   "")
3320
3321 (define_expand "pop_e"
3322   [(parallel [(set (match_operand:SF 0 "" "")
3323               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3324               (use (reg:PSI FPSCR_REG))
3325               (clobber (scratch:SI))])]
3326   "TARGET_SH1 && ! TARGET_SH5"
3327   "")
3328
3329 (define_insn "pop_fpul"
3330   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3331   "TARGET_SH2E && ! TARGET_SH5"
3332   "lds.l        @r15+,fpul"
3333   [(set_attr "type" "load")
3334    (set_attr "hit_stack" "yes")])
3335
3336 (define_expand "pop_4"
3337   [(parallel [(set (match_operand:DF 0 "" "")
3338                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3339               (use (reg:PSI FPSCR_REG))
3340               (clobber (scratch:SI))])]
3341   "TARGET_SH1 && ! TARGET_SH5"
3342   "")
3343
3344 (define_expand "push_fpscr"
3345   [(const_int 0)]
3346   "TARGET_SH3E"
3347   "
3348 {
3349   rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3350                                                  gen_rtx (PRE_DEC, Pmode,
3351                                                           stack_pointer_rtx)),
3352                                         get_fpscr_rtx ()));
3353   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3354   DONE;
3355 }")
3356
3357 (define_expand "pop_fpscr"
3358   [(const_int 0)]
3359   "TARGET_SH3E"
3360   "
3361 {
3362   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3363                                         gen_rtx (MEM, PSImode,
3364                                                  gen_rtx (POST_INC, Pmode,
3365                                                           stack_pointer_rtx))));
3366   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3367   DONE;
3368 }")
3369
3370 ;; These two patterns can happen as the result of optimization, when
3371 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3372 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3373
3374 (define_insn "clrt"
3375   [(set (reg:SI T_REG) (const_int 0))]
3376   "TARGET_SH1"
3377   "clrt")
3378
3379 (define_insn "sett"
3380   [(set (reg:SI T_REG) (const_int 1))]
3381   "TARGET_SH1"
3382   "sett")
3383
3384 ;; t/r must come after r/r, lest reload will try to reload stuff like
3385 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3386 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3387 (define_insn "movsi_i"
3388   [(set (match_operand:SI 0 "general_movdst_operand"
3389             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3390         (match_operand:SI 1 "general_movsrc_operand"
3391          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3392   "TARGET_SH1
3393    && ! TARGET_SH2E
3394    && (register_operand (operands[0], SImode)
3395        || register_operand (operands[1], SImode))"
3396   "@
3397         mov.l   %1,%0
3398         mov     %1,%0
3399         cmp/pl  %1
3400         mov.l   %1,%0
3401         sts     %1,%0
3402         sts     %1,%0
3403         movt    %0
3404         mov.l   %1,%0
3405         sts.l   %1,%0
3406         sts.l   %1,%0
3407         lds     %1,%0
3408         lds     %1,%0
3409         lds.l   %1,%0
3410         lds.l   %1,%0
3411         fake    %1,%0"
3412   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3413    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3414
3415 ;; t/r must come after r/r, lest reload will try to reload stuff like
3416 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3417 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3418 ;; will require a reload.
3419 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3420 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3421 (define_insn "movsi_ie"
3422   [(set (match_operand:SI 0 "general_movdst_operand"
3423             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3424         (match_operand:SI 1 "general_movsrc_operand"
3425          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3426   "TARGET_SH2E
3427    && (register_operand (operands[0], SImode)
3428        || register_operand (operands[1], SImode))"
3429   "@
3430         mov.l   %1,%0
3431         mov     %1,%0
3432         cmp/pl  %1
3433         mov.l   %1,%0
3434         sts     %1,%0
3435         sts     %1,%0
3436         movt    %0
3437         mov.l   %1,%0
3438         sts.l   %1,%0
3439         sts.l   %1,%0
3440         lds     %1,%0
3441         lds     %1,%0
3442         lds.l   %1,%0
3443         lds.l   %1,%0
3444         lds.l   %1,%0
3445         sts.l   %1,%0
3446         fake    %1,%0
3447         lds     %1,%0
3448         sts     %1,%0
3449         fsts    fpul,%0
3450         flds    %1,fpul
3451         fmov    %1,%0
3452         ! move optimized away"
3453   [(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")
3454    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3455    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3456
3457 (define_insn "movsi_i_lowpart"
3458   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3459         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3460    "TARGET_SH1
3461     && (register_operand (operands[0], SImode)
3462         || register_operand (operands[1], SImode))"
3463   "@
3464         mov.l   %1,%0
3465         mov     %1,%0
3466         mov.l   %1,%0
3467         sts     %1,%0
3468         sts     %1,%0
3469         movt    %0
3470         mov.l   %1,%0
3471         fake    %1,%0"
3472   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3473
3474 (define_insn "*movsi_media"
3475   [(set (match_operand:SI 0 "general_movdst_operand"
3476                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3477         (match_operand:SI 1 "general_movsrc_operand"
3478          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3479   "TARGET_SHMEDIA_FPU
3480    && (register_operand (operands[0], SImode)
3481        || sh_register_operand (operands[1], SImode))"
3482   "@
3483         add.l   %1, r63, %0
3484         movi    %1, %0
3485         #
3486         ld%M1.l %m1, %0
3487         st%M0.l %m0, %N1
3488         fld%M1.s        %m1, %0
3489         fst%M0.s        %m0, %1
3490         fmov.ls %N1, %0
3491         fmov.sl %1, %0
3492         fmov.s  %1, %0
3493         ptabs   %1, %0
3494         gettr   %1, %0
3495         pt      %1, %0"
3496   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3497    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3498
3499 (define_insn "*movsi_media_nofpu"
3500   [(set (match_operand:SI 0 "general_movdst_operand"
3501                 "=r,r,r,r,m,*b,r,b")
3502         (match_operand:SI 1 "general_movsrc_operand"
3503          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3504   "TARGET_SHMEDIA
3505    && (register_operand (operands[0], SImode)
3506        || sh_register_operand (operands[1], SImode))"
3507   "@
3508         add.l   %1, r63, %0
3509         movi    %1, %0
3510         #
3511         ld%M1.l %m1, %0
3512         st%M0.l %m0, %N1
3513         ptabs   %1, %0
3514         gettr   %1, %0
3515         pt      %1, %0"
3516   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3517    (set_attr "length" "4,4,8,4,4,4,4,12")])
3518
3519 (define_split
3520   [(set (match_operand:SI 0 "arith_reg_operand" "")
3521         (match_operand:SI 1 "immediate_operand" ""))]
3522   "TARGET_SHMEDIA && reload_completed
3523    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3524   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3525   "
3526 {
3527   operands[2] = shallow_copy_rtx (operands[1]);
3528   PUT_MODE (operands[2], DImode);
3529 }")
3530
3531 (define_split
3532   [(set (match_operand:SI 0 "register_operand" "")
3533         (match_operand:SI 1 "immediate_operand" ""))]
3534   "TARGET_SHMEDIA && reload_completed
3535    && ((GET_CODE (operands[1]) == CONST_INT
3536         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3537        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3538   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3539
3540 (define_expand "movsi"
3541   [(set (match_operand:SI 0 "general_movdst_operand" "")
3542         (match_operand:SI 1 "general_movsrc_operand" ""))]
3543   ""
3544   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3545
3546 (define_expand "ic_invalidate_line"
3547   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3548                                 (match_dup 1)] UNSPEC_ICACHE)
3549               (clobber (scratch:SI))])]
3550   "TARGET_HARD_SH4 || TARGET_SH5"
3551   "
3552 {
3553   if (TARGET_SHMEDIA)
3554     {
3555       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3556       DONE;
3557     }
3558   else if (TARGET_SHCOMPACT)
3559     {
3560       operands[1] = function_symbol (\"__ic_invalidate\");
3561       operands[1] = force_reg (Pmode, operands[1]);
3562       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3563       DONE;
3564     }
3565   operands[0] = force_reg (Pmode, operands[0]);
3566   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3567                                                                Pmode)));
3568 }")
3569
3570 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3571 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3572 ;; the requirement *1*00 for associative address writes.  The alignment of
3573 ;; %0 implies that its least significant bit is cleared,
3574 ;; thus we clear the V bit of a matching entry if there is one.
3575 (define_insn "ic_invalidate_line_i"
3576   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3577                      (match_operand:SI 1 "register_operand" "r")]
3578                      UNSPEC_ICACHE)
3579    (clobber (match_scratch:SI 2 "=&r"))]
3580   "TARGET_HARD_SH4"
3581   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3582   [(set_attr "length" "8")
3583    (set_attr "type" "cwb")])
3584
3585 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3586 ;; an add in the code that calculates the address.
3587 (define_insn "ic_invalidate_line_media"
3588   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3589                     UNSPEC_ICACHE)]
3590   "TARGET_SHMEDIA"
3591   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3592   [(set_attr "length" "16")
3593    (set_attr "type" "invalidate_line_media")])
3594
3595 (define_insn "ic_invalidate_line_compact"
3596   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3597                      (match_operand:SI 1 "register_operand" "r")]
3598                     UNSPEC_ICACHE)
3599    (clobber (reg:SI PR_REG))]
3600   "TARGET_SHCOMPACT"
3601   "jsr @%1%#"
3602   [(set_attr "type" "sfunc")
3603    (set_attr "needs_delay_slot" "yes")])
3604
3605 (define_expand "initialize_trampoline"
3606   [(match_operand:SI 0 "" "")
3607    (match_operand:SI 1 "" "")
3608    (match_operand:SI 2 "" "")]
3609   "TARGET_SHCOMPACT"
3610   "
3611 {
3612   rtx sfun, tramp;
3613
3614   tramp = force_reg (Pmode, operands[0]);
3615   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3616   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3617   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3618
3619   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3620   DONE;
3621 }")
3622
3623 (define_insn "initialize_trampoline_compact"
3624   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3625                      (match_operand:SI 1 "register_operand" "r")
3626                      (reg:SI R2_REG) (reg:SI R3_REG)]
3627                     UNSPEC_INIT_TRAMP)
3628
3629    (clobber (reg:SI PR_REG))]
3630   "TARGET_SHCOMPACT"
3631   "jsr @%1%#"
3632   [(set_attr "type" "sfunc")
3633    (set_attr "needs_delay_slot" "yes")])
3634
3635 (define_insn "movqi_i"
3636   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3637         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3638   "TARGET_SH1
3639    && (arith_reg_operand (operands[0], QImode)
3640        || arith_reg_operand (operands[1], QImode))"
3641   "@
3642         mov     %1,%0
3643         mov.b   %1,%0
3644         mov.b   %1,%0
3645         movt    %0
3646         sts     %1,%0
3647         lds     %1,%0"
3648  [(set_attr "type" "move,load,store,move,move,move")])
3649
3650 (define_insn "*movqi_media"
3651   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3652         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3653   "TARGET_SHMEDIA
3654    && (arith_reg_operand (operands[0], QImode)
3655        || arith_reg_or_0_operand (operands[1], QImode))"
3656   "@
3657         add.l   %1, r63, %0
3658         movi    %1, %0
3659         ld%M1.ub        %m1, %0
3660         st%M0.b %m0, %N1"
3661   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3662
3663 (define_expand "movqi"
3664   [(set (match_operand:QI 0 "general_operand" "")
3665         (match_operand:QI 1 "general_operand"  ""))]
3666   ""
3667   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3668
3669 (define_expand "reload_inqi"
3670   [(set (match_operand:SI 2 "" "=&r")
3671         (match_operand:QI 1 "inqhi_operand" ""))
3672    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3673         (truncate:QI (match_dup 3)))]
3674   "TARGET_SHMEDIA"
3675   "
3676 {
3677   rtx inner = XEXP (operands[1], 0);
3678   int regno = REGNO (inner);
3679
3680   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3681   operands[1] = gen_rtx_REG (SImode, regno);
3682   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3683 }")
3684
3685 /* When storing r0, we have to avoid reg+reg addressing.  */
3686 (define_insn "movhi_i"
3687   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3688         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3689   "TARGET_SH1
3690    && (arith_reg_operand (operands[0], HImode)
3691        || arith_reg_operand (operands[1], HImode))
3692    && (GET_CODE (operands[0]) != MEM
3693        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3694        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3695        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3696   "@
3697         mov.w   %1,%0
3698         mov     %1,%0
3699         mov.w   %1,%0
3700         movt    %0
3701         mov.w   %1,%0
3702         sts     %1,%0
3703         lds     %1,%0
3704         fake    %1,%0"
3705   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3706
3707 (define_insn "*movhi_media"
3708   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3709         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3710   "TARGET_SHMEDIA
3711    && (arith_reg_operand (operands[0], HImode)
3712        || arith_reg_or_0_operand (operands[1], HImode))"
3713   "@
3714         add.l   %1, r63, %0
3715         movi    %1, %0
3716         #
3717         ld%M1.w %m1, %0
3718         st%M0.w %m0, %N1"
3719   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3720
3721 (define_split
3722   [(set (match_operand:HI 0 "register_operand" "")
3723         (match_operand:HI 1 "immediate_operand" ""))]
3724   "TARGET_SHMEDIA && reload_completed
3725    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3726   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3727
3728 (define_expand "movhi"
3729   [(set (match_operand:HI 0 "general_movdst_operand" "")
3730         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3731   ""
3732   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3733
3734 (define_expand "reload_inhi"
3735   [(set (match_operand:SI 2 "" "=&r")
3736         (match_operand:HI 1 "inqhi_operand" ""))
3737    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3738         (truncate:HI (match_dup 3)))]
3739   "TARGET_SHMEDIA"
3740   "
3741 {
3742   rtx inner = XEXP (operands[1], 0);
3743   int regno = REGNO (inner);
3744
3745   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3746   operands[1] = gen_rtx_REG (SImode, regno);
3747   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3748 }")
3749
3750 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3751 ;; compiled with -m2 -ml -O3 -funroll-loops
3752 (define_insn "*movdi_i"
3753   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3754         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3755   "TARGET_SH1
3756    && (arith_reg_operand (operands[0], DImode)
3757        || arith_reg_operand (operands[1], DImode))"
3758   "* return output_movedouble (insn, operands, DImode);"
3759   [(set_attr "length" "4")
3760    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3761
3762 ;; If the output is a register and the input is memory or a register, we have
3763 ;; to be careful and see which word needs to be loaded first.
3764
3765 (define_split
3766   [(set (match_operand:DI 0 "general_movdst_operand" "")
3767         (match_operand:DI 1 "general_movsrc_operand" ""))]
3768   "TARGET_SH1 && reload_completed"
3769   [(set (match_dup 2) (match_dup 3))
3770    (set (match_dup 4) (match_dup 5))]
3771   "
3772 {
3773   int regno;
3774
3775   if ((GET_CODE (operands[0]) == MEM
3776        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3777       || (GET_CODE (operands[1]) == MEM
3778           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3779     FAIL;
3780
3781   if (GET_CODE (operands[0]) == REG)
3782     regno = REGNO (operands[0]);
3783   else if (GET_CODE (operands[0]) == SUBREG)
3784     regno = subreg_regno (operands[0]);
3785   else if (GET_CODE (operands[0]) == MEM)
3786     regno = -1;
3787   else
3788     abort ();
3789
3790   if (regno == -1
3791       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3792     {
3793       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3794       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3795       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3796       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3797     }
3798   else
3799     {
3800       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3801       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3802       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3803       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3804     }
3805
3806   if (operands[2] == 0 || operands[3] == 0
3807       || operands[4] == 0 || operands[5] == 0)
3808     FAIL;
3809 }")
3810
3811 (define_insn "*movdi_media"
3812   [(set (match_operand:DI 0 "general_movdst_operand"
3813                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3814         (match_operand:DI 1 "general_movsrc_operand"
3815          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3816   "TARGET_SHMEDIA_FPU
3817    && (register_operand (operands[0], DImode)
3818        || sh_register_operand (operands[1], DImode))"
3819   "@
3820         add     %1, r63, %0
3821         movi    %1, %0
3822         #
3823         ld%M1.q %m1, %0
3824         st%M0.q %m0, %N1
3825         fld%M1.d        %m1, %0
3826         fst%M0.d        %m0, %1
3827         fmov.qd %N1, %0
3828         fmov.dq %1, %0
3829         fmov.d  %1, %0
3830         ptabs   %1, %0
3831         gettr   %1, %0
3832         pt      %1, %0"
3833   [(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")
3834    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3835
3836 (define_insn "*movdi_media_nofpu"
3837   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3838         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3839   "TARGET_SHMEDIA
3840    && (register_operand (operands[0], DImode)
3841        || sh_register_operand (operands[1], DImode))"
3842   "@
3843         add     %1, r63, %0
3844         movi    %1, %0
3845         #
3846         ld%M1.q %m1, %0
3847         st%M0.q %m0, %N1
3848         ptabs   %1, %0
3849         gettr   %1, %0
3850         pt      %1, %0"
3851   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3852    (set_attr "length" "4,4,16,4,4,4,4,*")])
3853
3854 (define_split
3855   [(set (match_operand:DI 0 "arith_reg_operand" "")
3856         (match_operand:DI 1 "immediate_operand" ""))]
3857   "TARGET_SHMEDIA && reload_completed
3858    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3859   [(set (match_dup 0) (match_dup 1))]
3860   "
3861 {
3862   rtx insn;
3863
3864   if (TARGET_SHMEDIA64)
3865     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3866   else
3867     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3868
3869   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3870                                         REG_NOTES (insn));
3871
3872   DONE;
3873 }")
3874
3875 (define_expand "movdi_const"
3876   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3877         (const:DI (sign_extend:DI
3878                    (truncate:HI
3879                     (ashiftrt:DI
3880                      (match_operand:DI 1 "immediate_operand" "s")
3881                      (const_int 48))))))
3882    (set (match_dup 0)
3883         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3884                 (zero_extend:DI
3885                  (truncate:HI
3886                   (const:DI
3887                    (sign_extend:DI
3888                     (truncate:HI
3889                      (ashiftrt:SI
3890                       (match_dup 1)
3891                       (const_int 32)))))))))
3892    (set (match_dup 0)
3893         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3894                 (zero_extend:DI
3895                  (truncate:HI
3896                   (const:DI
3897                    (sign_extend:DI
3898                     (truncate:HI
3899                      (ashiftrt:SI
3900                       (match_dup 1)
3901                       (const_int 16)))))))))
3902    (set (match_dup 0)
3903         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3904                 (zero_extend:DI
3905                  (truncate:HI
3906                   (const:DI
3907                    (sign_extend:DI
3908                     (truncate:HI
3909                      (match_dup 1))))))))]
3910   "TARGET_SHMEDIA64 && reload_completed
3911    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3912   "
3913 {
3914   sh_mark_label (operands[1], 4);
3915 }")
3916
3917 (define_expand "movdi_const_32bit"
3918   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3919         (const:DI (sign_extend:DI
3920                    (truncate:HI
3921                     (ashiftrt:DI
3922                      (match_operand:DI 1 "immediate_operand" "s")
3923                      (const_int 16))))))
3924    (set (match_dup 0)
3925         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3926                 (zero_extend:DI
3927                  (truncate:HI
3928                   (const:DI
3929                    (sign_extend:DI
3930                     (truncate:HI
3931                      (match_dup 1))))))))]
3932   "TARGET_SHMEDIA32 && reload_completed
3933    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3934   "
3935 {
3936   sh_mark_label (operands[1], 2);
3937 }")
3938
3939 (define_expand "movdi_const_16bit"
3940   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3941         (const:DI (sign_extend:DI
3942                    (truncate:HI
3943                     (match_operand:DI 1 "immediate_operand" "s")))))]
3944   "TARGET_SHMEDIA && flag_pic && reload_completed
3945    && GET_CODE (operands[1]) == SYMBOL_REF"
3946   "")
3947
3948 (define_split
3949   [(set (match_operand:DI 0 "arith_reg_operand" "")
3950         (match_operand:DI 1 "immediate_operand" ""))]
3951   "TARGET_SHMEDIA && reload_completed
3952    && GET_CODE (operands[1]) == CONST_INT
3953    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3954   [(set (match_dup 0) (match_dup 2))
3955    (match_dup 1)]
3956   "
3957 {
3958   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3959   unsigned HOST_WIDE_INT low = val;
3960   unsigned HOST_WIDE_INT high = val;
3961   unsigned HOST_WIDE_INT sign;
3962   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3963
3964   /* Sign-extend the 16 least-significant bits.  */
3965   low &= 0xffff;
3966   low ^= 0x8000;
3967   low -= 0x8000;
3968
3969   /* Arithmetic shift right the word by 16 bits.  */
3970   high >>= 16;
3971   sign = 1;
3972   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3973   high ^= sign;
3974   high -= sign;
3975   do
3976     {
3977       /* If we can't generate the constant with a two-insn movi / shori
3978          sequence, try some other strategies.  */
3979       if (! CONST_OK_FOR_I16 (high))
3980         {
3981           /* Try constant load / left shift.  We know VAL != 0.  */
3982           val2 = val ^ (val-1);
3983           if (val2 > 0x1ffff)
3984             {
3985               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3986
3987               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
3988                   || (! CONST_OK_FOR_I16 (high >> 16)
3989                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
3990                 {
3991                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3992                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
3993                                                    GEN_INT (trailing_zeroes));
3994                   break;
3995                 }
3996             }
3997           /* Try constant load / right shift.  */
3998           val2 = (val >> 15) + 1;
3999           if (val2 == (val2 & -val2))
4000             {
4001               int shift = 49 - exact_log2 (val2);
4002
4003               val2 = trunc_int_for_mode (val << shift, DImode);
4004               if (CONST_OK_FOR_I16 (val2))
4005                 {
4006                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4007                                                    GEN_INT (shift));
4008                   break;
4009                 }
4010             }
4011           /* Try mperm.w .  */
4012           val2 = val & 0xffff;
4013           if ((val >> 16 & 0xffff) == val2
4014               && (val >> 32 & 0xffff) == val2
4015               && (val >> 48 & 0xffff) == val2)
4016             {
4017               val2 = (HOST_WIDE_INT) val >> 48;
4018               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4019               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4020               break;
4021             }
4022           /* Try movi / mshflo.l  */
4023           val2 = (HOST_WIDE_INT) val >> 32;
4024           if (val2 == trunc_int_for_mode (val, SImode))
4025             {
4026               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4027                                              operands[0]);
4028               break;
4029             }
4030           /* Try movi / mshflo.l w/ r63.  */
4031           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4032           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4033             {
4034               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4035                                              GEN_INT (0));
4036               break;
4037             }
4038         }
4039       val2 = high;
4040       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4041     }
4042   while (0);
4043   operands[2] = GEN_INT (val2);
4044 }")
4045
4046 (define_split
4047   [(set (match_operand:DI 0 "arith_reg_operand" "")
4048         (match_operand:DI 1 "immediate_operand" ""))]
4049   "TARGET_SHMEDIA && reload_completed
4050    && GET_CODE (operands[1]) == CONST_DOUBLE"
4051   [(set (match_dup 0) (match_dup 2))
4052   (set (match_dup 0)
4053        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4054                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4055   "
4056 {
4057   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4058   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4059   unsigned HOST_WIDE_INT val = low;
4060   unsigned HOST_WIDE_INT sign;
4061
4062   /* Sign-extend the 16 least-significant bits.  */
4063   val &= 0xffff;
4064   val ^= 0x8000;
4065   val -= 0x8000;
4066   operands[1] = GEN_INT (val);
4067
4068   /* Arithmetic shift right the double-word by 16 bits.  */
4069   low >>= 16;
4070   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4071   high >>= 16;
4072   sign = 1;
4073   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4074   high ^= sign;
4075   high -= sign;
4076
4077   /* This will only be true if high is a sign-extension of low, i.e.,
4078      it must be either 0 or (unsigned)-1, and be zero iff the
4079      most-significant bit of low is set.  */
4080   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4081     operands[2] = GEN_INT (low);
4082   else
4083     operands[2] = immed_double_const (low, high, DImode);
4084 }")
4085
4086 (define_insn "shori_media"
4087   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4088         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4089                            (const_int 16))
4090                 (zero_extend:DI
4091                  (truncate:HI
4092                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4093   "TARGET_SHMEDIA"
4094   "@
4095         shori   %u2, %0
4096         #"
4097   [(set_attr "type" "arith_media,*")])
4098
4099 (define_expand "movdi"
4100   [(set (match_operand:DI 0 "general_movdst_operand" "")
4101         (match_operand:DI 1 "general_movsrc_operand" ""))]
4102   ""
4103   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4104
4105 (define_insn "movdf_media"
4106   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4107         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4108   "TARGET_SHMEDIA_FPU
4109    && (register_operand (operands[0], DFmode)
4110        || sh_register_operand (operands[1], DFmode))"
4111   "@
4112         fmov.d  %1, %0
4113         fmov.qd %N1, %0
4114         fmov.dq %1, %0
4115         add     %1, r63, %0
4116         #
4117         fld%M1.d        %m1, %0
4118         fst%M0.d        %m0, %1
4119         ld%M1.q %m1, %0
4120         st%M0.q %m0, %N1"
4121   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4122
4123 (define_insn "movdf_media_nofpu"
4124   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4125         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4126   "TARGET_SHMEDIA
4127    && (register_operand (operands[0], DFmode)
4128        || sh_register_operand (operands[1], DFmode))"
4129   "@
4130         add     %1, r63, %0
4131         #
4132         ld%M1.q %m1, %0
4133         st%M0.q %m0, %N1"
4134   [(set_attr "type" "arith_media,*,load_media,store_media")])
4135
4136 (define_split
4137   [(set (match_operand:DF 0 "arith_reg_operand" "")
4138         (match_operand:DF 1 "immediate_operand" ""))]
4139   "TARGET_SHMEDIA && reload_completed"
4140   [(set (match_dup 3) (match_dup 2))]
4141   "
4142 {
4143   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4144   long values[2];
4145   REAL_VALUE_TYPE value;
4146
4147   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4148   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4149
4150   if (HOST_BITS_PER_WIDE_INT >= 64)
4151     operands[2] = immed_double_const ((unsigned long) values[endian]
4152                                       | ((HOST_WIDE_INT) values[1 - endian]
4153                                          << 32), 0, DImode);
4154   else if (HOST_BITS_PER_WIDE_INT == 32)
4155     operands[2] = immed_double_const (values[endian], values[1 - endian],
4156                                       DImode);
4157   else
4158     abort ();
4159
4160   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4161 }")
4162
4163 ;; ??? This should be a define expand.
4164
4165 (define_insn "movdf_k"
4166   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4167         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4168   "TARGET_SH1
4169    && (! TARGET_SH4 || reload_completed
4170        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4171        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4172        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4173    && (arith_reg_operand (operands[0], DFmode)
4174        || arith_reg_operand (operands[1], DFmode))"
4175   "* return output_movedouble (insn, operands, DFmode);"
4176   [(set_attr "length" "4")
4177    (set_attr "type" "move,pcload,load,store")])
4178
4179 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4180 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4181 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4182 ;; the d/m/c/X alternative, which is split later into single-precision
4183 ;; instructions.  And when not optimizing, no splits are done before fixing
4184 ;; up pcloads, so we need usable length information for that.
4185 (define_insn "movdf_i4"
4186   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4187         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4188    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4189    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4190   "TARGET_SH4
4191    && (arith_reg_operand (operands[0], DFmode)
4192        || arith_reg_operand (operands[1], DFmode))"
4193   "@
4194         fmov    %1,%0
4195         #
4196         #
4197         fmov.d  %1,%0
4198         fmov.d  %1,%0
4199         #
4200         #
4201         #
4202         #
4203         #"
4204   [(set_attr_alternative "length"
4205      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4206       (const_int 4)
4207       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4208       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4209       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4210       (const_int 4)
4211       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4212       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4213       ;; increment or decrement r15 explicitly.
4214       (if_then_else
4215        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4216        (const_int 10) (const_int 8))
4217       (if_then_else
4218        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4219        (const_int 10) (const_int 8))])
4220    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4221    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4222    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4223                                            (const_string "double")
4224                                            (const_string "none")))])
4225
4226 ;; Moving DFmode between fp/general registers through memory
4227 ;; (the top of the stack) is faster than moving through fpul even for
4228 ;; little endian.  Because the type of an instruction is important for its
4229 ;; scheduling,  it is beneficial to split these operations, rather than
4230 ;; emitting them in one single chunk, even if this will expose a stack
4231 ;; use that will prevent scheduling of other stack accesses beyond this
4232 ;; instruction.
4233 (define_split
4234   [(set (match_operand:DF 0 "register_operand" "")
4235         (match_operand:DF 1 "register_operand" ""))
4236    (use (match_operand:PSI 2 "fpscr_operand" ""))
4237    (clobber (match_scratch:SI 3 "=X"))]
4238   "TARGET_SH4 && reload_completed
4239    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4240   [(const_int 0)]
4241   "
4242 {
4243   rtx insn, tos;
4244
4245   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4246     {
4247       emit_move_insn (stack_pointer_rtx,
4248                       plus_constant (stack_pointer_rtx, -8));
4249       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4250     }
4251   else
4252     tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4253   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4254   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4255     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4256   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4257     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4258   else
4259     tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4260   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4261   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4262     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4263   else
4264     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4265   DONE;
4266 }")
4267
4268 ;; local-alloc sometimes allocates scratch registers even when not required,
4269 ;; so we must be prepared to handle these.
4270
4271 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4272 (define_split
4273   [(set (match_operand:DF 0 "general_movdst_operand" "")
4274         (match_operand:DF 1 "general_movsrc_operand"  ""))
4275    (use (match_operand:PSI 2 "fpscr_operand" ""))
4276    (clobber (match_scratch:SI 3 ""))]
4277   "TARGET_SH4
4278    && reload_completed
4279    && true_regnum (operands[0]) < 16
4280    && true_regnum (operands[1]) < 16"
4281   [(set (match_dup 0) (match_dup 1))]
4282   "
4283 {
4284   /* If this was a reg <-> mem operation with base + index reg addressing,
4285      we have to handle this in a special way.  */
4286   rtx mem = operands[0];
4287   int store_p = 1;
4288   if (! memory_operand (mem, DFmode))
4289     {
4290       mem = operands[1];
4291       store_p = 0;
4292     }
4293   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4294     mem = SUBREG_REG (mem);
4295   if (GET_CODE (mem) == MEM)
4296     {
4297       rtx addr = XEXP (mem, 0);
4298       if (GET_CODE (addr) == PLUS
4299           && GET_CODE (XEXP (addr, 0)) == REG
4300           && GET_CODE (XEXP (addr, 1)) == REG)
4301         {
4302           int offset;
4303           rtx reg0 = gen_rtx (REG, Pmode, 0);
4304           rtx regop = operands[store_p], word0 ,word1;
4305
4306           if (GET_CODE (regop) == SUBREG)
4307             alter_subreg (&regop);
4308           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4309             offset = 2;
4310           else
4311             offset = 4;
4312           mem = copy_rtx (mem);
4313           PUT_MODE (mem, SImode);
4314           word0 = gen_rtx (SUBREG, SImode, regop, 0);
4315           alter_subreg (&word0);
4316           word1 = gen_rtx (SUBREG, SImode, regop, 4);
4317           alter_subreg (&word1);
4318           if (store_p || ! refers_to_regno_p (REGNO (word0),
4319                                               REGNO (word0) + 1, addr, 0))
4320             {
4321               emit_insn (store_p
4322                          ? gen_movsi_ie (mem, word0)
4323                          : gen_movsi_ie (word0, mem));
4324               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4325               mem = copy_rtx (mem);
4326               emit_insn (store_p
4327                          ? gen_movsi_ie (mem, word1)
4328                          : gen_movsi_ie (word1, mem));
4329               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4330             }
4331           else
4332             {
4333               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4334               emit_insn (gen_movsi_ie (word1, mem));
4335               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4336               mem = copy_rtx (mem);
4337               emit_insn (gen_movsi_ie (word0, mem));
4338             }
4339           DONE;
4340         }
4341     }
4342 }")
4343
4344 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4345 (define_split
4346   [(set (match_operand:DF 0 "register_operand" "")
4347         (match_operand:DF 1 "memory_operand"  ""))
4348    (use (match_operand:PSI 2 "fpscr_operand" ""))
4349    (clobber (reg:SI R0_REG))]
4350   "TARGET_SH4 && reload_completed"
4351   [(parallel [(set (match_dup 0) (match_dup 1))
4352               (use (match_dup 2))
4353               (clobber (scratch:SI))])]
4354   "")
4355
4356 (define_expand "reload_indf"
4357   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4358                    (match_operand:DF 1 "immediate_operand" "FQ"))
4359               (use (reg:PSI FPSCR_REG))
4360               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4361   "TARGET_SH1"
4362   "")
4363
4364 (define_expand "reload_outdf"
4365   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4366                    (match_operand:DF 1 "register_operand" "af,r"))
4367               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4368   "TARGET_SH1"
4369   "")
4370
4371 ;; Simplify no-op moves.
4372 (define_split
4373   [(set (match_operand:SF 0 "register_operand" "")
4374         (match_operand:SF 1 "register_operand" ""))
4375    (use (match_operand:PSI 2 "fpscr_operand" ""))
4376    (clobber (match_scratch:SI 3 "X"))]
4377   "TARGET_SH2E && reload_completed
4378    && true_regnum (operands[0]) == true_regnum (operands[1])"
4379   [(set (match_dup 0) (match_dup 0))]
4380   "")
4381
4382 ;; fmovd substitute post-reload splits
4383 (define_split
4384   [(set (match_operand:DF 0 "register_operand" "")
4385         (match_operand:DF 1 "register_operand" ""))
4386    (use (match_operand:PSI 2 "fpscr_operand" ""))
4387    (clobber (match_scratch:SI 3 "X"))]
4388   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4389    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4390    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4391   [(const_int 0)]
4392   "
4393 {
4394   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4395   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4396                            gen_rtx (REG, SFmode, src), operands[2]));
4397   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4398                            gen_rtx (REG, SFmode, src + 1), operands[2]));
4399   DONE;
4400 }")
4401
4402 (define_split
4403   [(set (match_operand:DF 0 "register_operand" "")
4404         (mem:DF (match_operand:SI 1 "register_operand" "")))
4405    (use (match_operand:PSI 2 "fpscr_operand" ""))
4406    (clobber (match_scratch:SI 3 ""))]
4407   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4408    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4409    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4410   [(const_int 0)]
4411   "
4412 {
4413   int regno = true_regnum (operands[0]);
4414   rtx insn;
4415   rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4416
4417   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4418                                            regno + !! TARGET_LITTLE_ENDIAN),
4419                                   mem2, operands[2]));
4420   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4421   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4422                                            regno + ! TARGET_LITTLE_ENDIAN),
4423                                   gen_rtx (MEM, SFmode, operands[1]),
4424                                   operands[2]));
4425   DONE;
4426 }")
4427
4428 (define_split
4429   [(set (match_operand:DF 0 "register_operand" "")
4430         (match_operand:DF 1 "memory_operand" ""))
4431    (use (match_operand:PSI 2 "fpscr_operand" ""))
4432    (clobber (match_scratch:SI 3 ""))]
4433   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4434    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4435   [(const_int 0)]
4436   "
4437 {
4438   int regno = true_regnum (operands[0]);
4439   rtx addr, insn, adjust = NULL_RTX;
4440   rtx mem2 = copy_rtx (operands[1]);
4441   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4442   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4443
4444   PUT_MODE (mem2, SFmode);
4445   operands[1] = copy_rtx (mem2);
4446   addr = XEXP (mem2, 0);
4447   if (GET_CODE (addr) != POST_INC)
4448     {
4449       /* If we have to modify the stack pointer, the value that we have
4450          read with post-increment might be modified by an interrupt,
4451          so write it back.  */
4452       if (REGNO (addr) == STACK_POINTER_REGNUM)
4453         adjust = gen_push_e (reg0);
4454       else
4455         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4456       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4457     }
4458   addr = XEXP (addr, 0);
4459   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4460   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4461   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4462   if (adjust)
4463     emit_insn (adjust);
4464   else
4465     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4466   DONE;
4467 }")
4468
4469 (define_split
4470   [(set (match_operand:DF 0 "memory_operand" "")
4471         (match_operand:DF 1 "register_operand" ""))
4472    (use (match_operand:PSI 2 "fpscr_operand" ""))
4473    (clobber (match_scratch:SI 3 ""))]
4474   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4475    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4476   [(const_int 0)]
4477   "
4478 {
4479   int regno = true_regnum (operands[1]);
4480   rtx insn, addr, adjust = NULL_RTX;
4481
4482   operands[0] = copy_rtx (operands[0]);
4483   PUT_MODE (operands[0], SFmode);
4484   insn = emit_insn (gen_movsf_ie (operands[0],
4485                                   gen_rtx (REG, SFmode,
4486                                            regno + ! TARGET_LITTLE_ENDIAN),
4487                                   operands[2]));
4488   operands[0] = copy_rtx (operands[0]);
4489   addr = XEXP (operands[0], 0);
4490   if (GET_CODE (addr) != PRE_DEC)
4491     {
4492       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4493       emit_insn_before (adjust, insn);
4494       XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4495     }
4496   addr = XEXP (addr, 0);
4497   if (! adjust)
4498     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4499   insn = emit_insn (gen_movsf_ie (operands[0],
4500                                   gen_rtx (REG, SFmode,
4501                                            regno + !! TARGET_LITTLE_ENDIAN),
4502                                   operands[2]));
4503   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4504   DONE;
4505 }")
4506
4507 ;; If the output is a register and the input is memory or a register, we have
4508 ;; to be careful and see which word needs to be loaded first.
4509
4510 (define_split
4511   [(set (match_operand:DF 0 "general_movdst_operand" "")
4512         (match_operand:DF 1 "general_movsrc_operand" ""))]
4513   "TARGET_SH1 && reload_completed"
4514   [(set (match_dup 2) (match_dup 3))
4515    (set (match_dup 4) (match_dup 5))]
4516   "
4517 {
4518   int regno;
4519
4520   if ((GET_CODE (operands[0]) == MEM
4521        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4522       || (GET_CODE (operands[1]) == MEM
4523           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4524     FAIL;
4525
4526   if (GET_CODE (operands[0]) == REG)
4527     regno = REGNO (operands[0]);
4528   else if (GET_CODE (operands[0]) == SUBREG)
4529     regno = subreg_regno (operands[0]);
4530   else if (GET_CODE (operands[0]) == MEM)
4531     regno = -1;
4532   else
4533     abort ();
4534
4535   if (regno == -1
4536       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4537     {
4538       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4539       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4540       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4541       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4542     }
4543   else
4544     {
4545       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4546       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4547       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4548       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4549     }
4550
4551   if (operands[2] == 0 || operands[3] == 0
4552       || operands[4] == 0 || operands[5] == 0)
4553     FAIL;
4554 }")
4555
4556 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4557 ;; used only once, let combine add in the index again.
4558
4559 (define_split
4560   [(set (match_operand:SI 0 "register_operand" "")
4561         (match_operand:SI 1 "" ""))
4562    (clobber (match_operand 2 "register_operand" ""))]
4563   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4564   [(use (reg:SI R0_REG))]
4565   "
4566 {
4567   rtx addr, reg, const_int;
4568
4569   if (GET_CODE (operands[1]) != MEM)
4570     FAIL;
4571   addr = XEXP (operands[1], 0);
4572   if (GET_CODE (addr) != PLUS)
4573     FAIL;
4574   reg = XEXP (addr, 0);
4575   const_int = XEXP (addr, 1);
4576   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4577          && GET_CODE (const_int) == CONST_INT))
4578     FAIL;
4579   emit_move_insn (operands[2], const_int);
4580   emit_move_insn (operands[0],
4581                   change_address (operands[1], VOIDmode,
4582                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4583   DONE;
4584 }")
4585
4586 (define_split
4587   [(set (match_operand:SI 1 "" "")
4588         (match_operand:SI 0 "register_operand" ""))
4589    (clobber (match_operand 2 "register_operand" ""))]
4590   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4591   [(use (reg:SI R0_REG))]
4592   "
4593 {
4594   rtx addr, reg, const_int;
4595
4596   if (GET_CODE (operands[1]) != MEM)
4597     FAIL;
4598   addr = XEXP (operands[1], 0);
4599   if (GET_CODE (addr) != PLUS)
4600     FAIL;
4601   reg = XEXP (addr, 0);
4602   const_int = XEXP (addr, 1);
4603   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4604          && GET_CODE (const_int) == CONST_INT))
4605     FAIL;
4606   emit_move_insn (operands[2], const_int);
4607   emit_move_insn (change_address (operands[1], VOIDmode,
4608                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4609                   operands[0]);
4610   DONE;
4611 }")
4612
4613 (define_expand "movdf"
4614   [(set (match_operand:DF 0 "general_movdst_operand" "")
4615         (match_operand:DF 1 "general_movsrc_operand" ""))]
4616   ""
4617   "
4618 {
4619   if (prepare_move_operands (operands, DFmode)) DONE;
4620   if (TARGET_SHMEDIA)
4621     {
4622       if (TARGET_SHMEDIA_FPU)
4623         emit_insn (gen_movdf_media (operands[0], operands[1]));
4624       else
4625         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4626       DONE;
4627     }
4628   if (TARGET_SH4)
4629     {
4630       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4631       DONE;
4632     }
4633 }")
4634
4635 ;;This is incompatible with the way gcc uses subregs.
4636 ;;(define_insn "movv2sf_i"
4637 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4638 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4639 ;;  "TARGET_SHMEDIA_FPU
4640 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4641 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4642 ;;  "@
4643 ;;      #
4644 ;;      fld%M1.p        %m1, %0
4645 ;;      fst%M0.p        %m0, %1"
4646 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4647
4648 (define_insn_and_split "movv2sf_i"
4649   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4650         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4651   "TARGET_SHMEDIA_FPU"
4652   "#"
4653   "TARGET_SHMEDIA_FPU && reload_completed"
4654   [(set (match_dup 0) (match_dup 1))]
4655   "
4656 {
4657   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4658   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4659 }")
4660
4661 (define_expand "movv2sf"
4662   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4663         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4664   "TARGET_SHMEDIA_FPU"
4665   "
4666 {
4667   if (prepare_move_operands (operands, V2SFmode))
4668     DONE;
4669 }")
4670
4671 (define_expand "addv2sf3"
4672   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4673    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4674    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4675   "TARGET_SHMEDIA_FPU"
4676   "
4677 {
4678   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4679   DONE;
4680 }")
4681
4682 (define_expand "subv2sf3"
4683   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4684    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4685    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4686   "TARGET_SHMEDIA_FPU"
4687   "
4688 {
4689   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4690   DONE;
4691 }")
4692
4693 (define_expand "mulv2sf3"
4694   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4695    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4696    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4697   "TARGET_SHMEDIA_FPU"
4698   "
4699 {
4700   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4701   DONE;
4702 }")
4703
4704 (define_expand "divv2sf3"
4705   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4706    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4707    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4708   "TARGET_SHMEDIA_FPU"
4709   "
4710 {
4711   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4712   DONE;
4713 }")
4714
4715 (define_insn_and_split "*movv4sf_i"
4716   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4717         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4718   "TARGET_SHMEDIA_FPU"
4719   "#"
4720   "&& reload_completed"
4721   [(const_int 0)]
4722   "
4723 {
4724   int i;
4725
4726   for (i = 0; i < 4/2; i++)
4727     {
4728       rtx x, y;
4729
4730       if (GET_CODE (operands[0]) == MEM)
4731         x = gen_rtx_MEM (V2SFmode,
4732                          plus_constant (XEXP (operands[0], 0),
4733                                         i * GET_MODE_SIZE (V2SFmode)));
4734       else
4735         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4736
4737       if (GET_CODE (operands[1]) == MEM)
4738         y = gen_rtx_MEM (V2SFmode,
4739                          plus_constant (XEXP (operands[1], 0),
4740                                         i * GET_MODE_SIZE (V2SFmode)));
4741       else
4742         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4743
4744       emit_insn (gen_movv2sf_i (x, y));
4745     }
4746
4747   DONE;
4748 }"
4749   [(set_attr "length" "8")])
4750
4751 (define_expand "movv4sf"
4752   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4753         (match_operand:V4SF 1 "general_operand" ""))]
4754   "TARGET_SHMEDIA_FPU"
4755   "
4756 {
4757   if (prepare_move_operands (operands, V4SFmode))
4758     DONE;
4759 }")
4760
4761 (define_insn_and_split "*movv16sf_i"
4762   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4763         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4764   "TARGET_SHMEDIA_FPU"
4765   "#"
4766   "&& reload_completed"
4767   [(const_int 0)]
4768   "
4769 {
4770   int i;
4771
4772   for (i = 0; i < 16/2; i++)
4773     {
4774       rtx x,y;
4775
4776       if (GET_CODE (operands[0]) == MEM)
4777         x = gen_rtx_MEM (V2SFmode,
4778                          plus_constant (XEXP (operands[0], 0),
4779                                         i * GET_MODE_SIZE (V2SFmode)));
4780       else
4781         {
4782           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4783           alter_subreg (&x);
4784         }
4785
4786       if (GET_CODE (operands[1]) == MEM)
4787         y = gen_rtx_MEM (V2SFmode,
4788                          plus_constant (XEXP (operands[1], 0),
4789                                         i * GET_MODE_SIZE (V2SFmode)));
4790       else
4791         {
4792           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4793           alter_subreg (&y);
4794         }
4795
4796       emit_insn (gen_movv2sf_i (x, y));
4797     }
4798
4799   DONE;
4800 }"
4801   [(set_attr "length" "32")])
4802
4803 (define_expand "movv16sf"
4804   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4805         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4806   "TARGET_SHMEDIA_FPU"
4807   "
4808 {
4809   if (prepare_move_operands (operands, V16SFmode))
4810     DONE;
4811 }")
4812
4813 (define_insn "movsf_media"
4814   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4815         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4816   "TARGET_SHMEDIA_FPU
4817    && (register_operand (operands[0], SFmode)
4818        || sh_register_operand (operands[1], SFmode))"
4819   "@
4820         fmov.s  %1, %0
4821         fmov.ls %N1, %0
4822         fmov.sl %1, %0
4823         add.l   %1, r63, %0
4824         #
4825         fld%M1.s        %m1, %0
4826         fst%M0.s        %m0, %1
4827         ld%M1.l %m1, %0
4828         st%M0.l %m0, %N1"
4829   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4830
4831 (define_insn "movsf_media_nofpu"
4832   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4833         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4834   "TARGET_SHMEDIA
4835    && (register_operand (operands[0], SFmode)
4836        || sh_register_operand (operands[1], SFmode))"
4837   "@
4838         add.l   %1, r63, %0
4839         #
4840         ld%M1.l %m1, %0
4841         st%M0.l %m0, %N1"
4842   [(set_attr "type" "arith_media,*,load_media,store_media")])
4843
4844 (define_split
4845   [(set (match_operand:SF 0 "arith_reg_operand" "")
4846         (match_operand:SF 1 "immediate_operand" ""))]
4847   "TARGET_SHMEDIA && reload_completed
4848    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4849   [(set (match_dup 3) (match_dup 2))]
4850   "
4851 {
4852   long values;
4853   REAL_VALUE_TYPE value;
4854
4855   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4856   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4857   operands[2] = GEN_INT (values);
4858
4859   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4860 }")
4861
4862 (define_insn "movsf_i"
4863   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4864         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4865   "TARGET_SH1
4866    && (! TARGET_SH2E
4867        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4868        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4869        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4870    && (arith_reg_operand (operands[0], SFmode)
4871        || arith_reg_operand (operands[1], SFmode))"
4872   "@
4873         mov     %1,%0
4874         mov     #0,%0
4875         mov.l   %1,%0
4876         mov.l   %1,%0
4877         mov.l   %1,%0
4878         lds     %1,%0
4879         sts     %1,%0"
4880   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4881
4882 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4883 ;; update_flow_info would not know where to put REG_EQUAL notes
4884 ;; when the destination changes mode.
4885 (define_insn "movsf_ie"
4886   [(set (match_operand:SF 0 "general_movdst_operand"
4887          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4888         (match_operand:SF 1 "general_movsrc_operand"
4889           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4890    (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"))
4891    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4892
4893   "TARGET_SH2E
4894    && (arith_reg_operand (operands[0], SFmode)
4895        || arith_reg_operand (operands[1], SFmode)
4896        || arith_reg_operand (operands[3], SImode)
4897        || (fpul_operand (operands[0], SFmode)
4898            && memory_operand (operands[1], SFmode)
4899            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4900        || (fpul_operand (operands[1], SFmode)
4901            && memory_operand (operands[0], SFmode)
4902            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4903   "@
4904         fmov    %1,%0
4905         mov     %1,%0
4906         fldi0   %0
4907         fldi1   %0
4908         #
4909         fmov.s  %1,%0
4910         fmov.s  %1,%0
4911         mov.l   %1,%0
4912         mov.l   %1,%0
4913         mov.l   %1,%0
4914         fsts    fpul,%0
4915         flds    %1,fpul
4916         lds.l   %1,%0
4917         #
4918         sts     %1,%0
4919         lds     %1,%0
4920         sts.l   %1,%0
4921         lds.l   %1,%0
4922         ! move optimized away"
4923   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4924    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4925    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4926    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4927                                            (const_string "single")
4928                                            (const_string "none")))])
4929
4930 (define_split
4931   [(set (match_operand:SF 0 "register_operand" "")
4932         (match_operand:SF 1 "register_operand" ""))
4933    (use (match_operand:PSI 2 "fpscr_operand" ""))
4934    (clobber (reg:SI FPUL_REG))]
4935   "TARGET_SH1"
4936   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4937               (use (match_dup 2))
4938               (clobber (scratch:SI))])
4939    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4940               (use (match_dup 2))
4941               (clobber (scratch:SI))])]
4942   "")
4943
4944 (define_expand "movsf"
4945   [(set (match_operand:SF 0 "general_movdst_operand" "")
4946         (match_operand:SF 1 "general_movsrc_operand" ""))]
4947   ""
4948   "
4949 {
4950   if (prepare_move_operands (operands, SFmode))
4951     DONE;
4952   if (TARGET_SHMEDIA)
4953     {
4954       if (TARGET_SHMEDIA_FPU)
4955         emit_insn (gen_movsf_media (operands[0], operands[1]));
4956       else
4957         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4958       DONE;
4959     }
4960   if (TARGET_SH2E)
4961     {
4962       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4963       DONE;
4964     }
4965 }")
4966
4967 (define_insn "mov_nop"
4968   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4969   "TARGET_SH2E"
4970   ""
4971   [(set_attr "length" "0")
4972    (set_attr "type" "nil")])
4973
4974 (define_expand "reload_insf"
4975   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4976                    (match_operand:SF 1 "immediate_operand" "FQ"))
4977               (use (reg:PSI FPSCR_REG))
4978               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4979   "TARGET_SH1"
4980   "")
4981
4982 (define_expand "reload_insi"
4983   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4984                    (match_operand:SF 1 "immediate_operand" "FQ"))
4985               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4986   "TARGET_SH1"
4987   "")
4988
4989 (define_insn "*movsi_y"
4990   [(set (match_operand:SI 0 "register_operand" "=y,y")
4991         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
4992    (clobber (match_scratch:SI 2 "=&z,r"))]
4993   "TARGET_SH2E
4994    && (reload_in_progress || reload_completed)"
4995   "#"
4996   [(set_attr "length" "4")
4997    (set_attr "type" "pcload,move")])
4998
4999 (define_split
5000   [(set (match_operand:SI 0 "register_operand" "")
5001         (match_operand:SI 1 "immediate_operand" ""))
5002    (clobber (match_operand:SI 2 "register_operand" ""))]
5003   "TARGET_SH1"
5004   [(set (match_dup 2) (match_dup 1))
5005    (set (match_dup 0) (match_dup 2))]
5006   "")
5007
5008 (define_split
5009   [(set (match_operand:SI 0 "register_operand" "")
5010         (match_operand:SI 1 "memory_operand" ""))
5011    (clobber (reg:SI R0_REG))]
5012   "TARGET_SH1"
5013   [(set (match_dup 0) (match_dup 1))]
5014   "")
5015 \f
5016 ;; ------------------------------------------------------------------------
5017 ;; Define the real conditional branch instructions.
5018 ;; ------------------------------------------------------------------------
5019
5020 (define_insn "branch_true"
5021   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5022                            (label_ref (match_operand 0 "" ""))
5023                            (pc)))]
5024   "TARGET_SH1"
5025   "* return output_branch (1, insn, operands);"
5026   [(set_attr "type" "cbranch")])
5027
5028 (define_insn "branch_false"
5029   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5030                            (label_ref (match_operand 0 "" ""))
5031                            (pc)))]
5032   "TARGET_SH1"
5033   "* return output_branch (0, insn, operands);"
5034   [(set_attr "type" "cbranch")])
5035
5036 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5037 ;; which destination is too far away.
5038 ;; The const_int_operand is distinct for each branch target; it avoids
5039 ;; unwanted matches with redundant_insn.
5040 (define_insn "block_branch_redirect"
5041   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5042   "TARGET_SH1"
5043   ""
5044   [(set_attr "length" "0")])
5045
5046 ;; This one has the additional purpose to record a possible scratch register
5047 ;; for the following branch.
5048 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5049 ;; because the insn then might be deemed dead and deleted.  And we can't
5050 ;; make the use in the jump insn explicit because that would disable
5051 ;; delay slot scheduling from the target.
5052 (define_insn "indirect_jump_scratch"
5053   [(set (match_operand:SI 0 "register_operand" "=r")
5054         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR)) 
5055    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5056   "TARGET_SH1"
5057   ""
5058   [(set_attr "length" "0")])
5059
5060 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5061 ;; being pulled into the delay slot of a condbranch that has been made to
5062 ;; jump around the unconditional jump because it was out of range.
5063 (define_insn "stuff_delay_slot"
5064   [(set (pc)
5065         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5066    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5067   "TARGET_SH1"
5068   ""
5069   [(set_attr "length" "0")
5070    (set_attr "cond_delay_slot" "yes")])
5071 \f
5072 ;; Conditional branch insns
5073
5074 (define_expand "beq_media"
5075   [(set (pc)
5076         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5077                           (match_operand:DI 2 "arith_operand" "r,I06"))
5078                       (label_ref:DI (match_operand 0 "" ""))
5079                       (pc)))]
5080   "TARGET_SHMEDIA"
5081   "")
5082
5083 (define_insn "*beq_media_i"
5084   [(set (pc)
5085         (if_then_else (match_operator 3 "equality_comparison_operator"
5086                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5087                          (match_operand:DI 2 "arith_operand" "r,I06")])
5088                       (match_operand:DI 0 "target_operand" "b,b")
5089                       (pc)))]
5090   "TARGET_SHMEDIA"
5091   "@
5092         b%o3%'  %1, %2, %0
5093         b%o3i%' %1, %2, %0"
5094   [(set_attr "type" "cbranch_media")])
5095
5096 (define_expand "bne_media"
5097   [(set (pc)
5098         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5099                           (match_operand:DI 2 "arith_operand" "r,I06"))
5100                       (label_ref:DI (match_operand 0 "" ""))
5101                       (pc)))]
5102   "TARGET_SHMEDIA"
5103   "")
5104
5105 (define_expand "bgt_media"
5106   [(set (pc)
5107         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5108                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5109                       (label_ref:DI (match_operand 0 "" ""))
5110                       (pc)))]
5111   "TARGET_SHMEDIA"
5112   "")
5113
5114 (define_expand "bge_media"
5115   [(set (pc)
5116         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5117                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5118                       (label_ref:DI (match_operand 0 "" ""))
5119                       (pc)))]
5120   "TARGET_SHMEDIA"
5121   "")
5122
5123 (define_expand "bgtu_media"
5124   [(set (pc)
5125         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5126                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5127                       (label_ref:DI (match_operand 0 "" ""))
5128                       (pc)))]
5129   "TARGET_SHMEDIA"
5130   "")
5131
5132 (define_expand "bgeu_media"
5133   [(set (pc)
5134         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5135                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5136                       (label_ref:DI (match_operand 0 "" ""))
5137                       (pc)))]
5138   "TARGET_SHMEDIA"
5139   "")
5140
5141 (define_insn "*bgt_media_i"
5142   [(set (pc)
5143         (if_then_else (match_operator 3 "greater_comparison_operator"
5144                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5145                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5146                       (match_operand:DI 0 "target_operand" "b")
5147                       (pc)))]
5148   "TARGET_SHMEDIA"
5149   "b%o3%'       %N1, %N2, %0"
5150   [(set_attr "type" "cbranch_media")])
5151
5152 ;; These are only needed to make invert_jump() happy.
5153 (define_insn "*blt_media_i"
5154   [(set (pc)
5155         (if_then_else (match_operator 3 "less_comparison_operator"
5156                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5157                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5158                       (match_operand:DI 0 "target_operand" "b")
5159                       (pc)))]
5160   "TARGET_SHMEDIA"
5161   "b%o3%'       %N2, %N1, %0"
5162   [(set_attr "type" "cbranch_media")])
5163
5164 (define_expand "beq"
5165   [(set (pc)
5166         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5167                       (label_ref (match_operand 0 "" ""))
5168                       (pc)))]
5169   ""
5170   "
5171 {
5172   if (TARGET_SHMEDIA)
5173     {
5174       if (GET_MODE (sh_compare_op0) != DImode)
5175         {
5176           rtx tmp = gen_reg_rtx (DImode);
5177
5178           emit_insn (gen_seq (tmp));
5179           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5180           DONE;
5181         }
5182
5183       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5184       emit_jump_insn (gen_beq_media (operands[0],
5185                                      sh_compare_op0, sh_compare_op1));
5186       DONE;
5187     }
5188
5189   from_compare (operands, EQ);
5190 }")
5191
5192 (define_expand "bne"
5193   [(set (pc)
5194         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5195                       (label_ref (match_operand 0 "" ""))
5196                       (pc)))]
5197   ""
5198   "
5199 {
5200   if (TARGET_SHMEDIA)
5201     {
5202       if (GET_MODE (sh_compare_op0) != DImode)
5203         {
5204           rtx tmp = gen_reg_rtx (DImode);
5205
5206           emit_insn (gen_seq (tmp));
5207           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5208           DONE;
5209         }
5210
5211       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5212       emit_jump_insn (gen_bne_media (operands[0],
5213                                      sh_compare_op0, sh_compare_op1));
5214       DONE;
5215     }
5216
5217   from_compare (operands, EQ);
5218 }")
5219
5220 (define_expand "bgt"
5221   [(set (pc)
5222         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5223                       (label_ref (match_operand 0 "" ""))
5224                       (pc)))]
5225   ""
5226   "
5227 {
5228   if (TARGET_SHMEDIA)
5229     {
5230       if (GET_MODE (sh_compare_op0) != DImode)
5231         {
5232           rtx tmp = gen_reg_rtx (DImode);
5233
5234           emit_insn (gen_sgt (tmp));
5235           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5236           DONE;
5237         }
5238
5239       if (sh_compare_op0 != const0_rtx)
5240         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5241       if (sh_compare_op1 != const0_rtx)
5242         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5243       emit_jump_insn (gen_bgt_media (operands[0],
5244                                      sh_compare_op0, sh_compare_op1));
5245       DONE;
5246     }
5247
5248   from_compare (operands, GT);
5249 }")
5250
5251 (define_expand "blt"
5252   [(set (pc)
5253         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5254                       (label_ref (match_operand 0 "" ""))
5255                       (pc)))]
5256   ""
5257   "
5258 {
5259   if (TARGET_SHMEDIA)
5260     {
5261       if (GET_MODE (sh_compare_op0) != DImode)
5262         {
5263           rtx tmp = gen_reg_rtx (DImode);
5264
5265           emit_insn (gen_slt (tmp));
5266           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5267           DONE;
5268         }
5269
5270       if (sh_compare_op0 != const0_rtx)
5271         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5272       if (sh_compare_op1 != const0_rtx)
5273         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5274       emit_jump_insn (gen_bgt_media (operands[0],
5275                                      sh_compare_op1, sh_compare_op0));
5276       DONE;
5277     }
5278
5279   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5280     {
5281       rtx tmp = sh_compare_op0;
5282       sh_compare_op0 = sh_compare_op1;
5283       sh_compare_op1 = tmp;
5284       emit_insn (gen_bgt (operands[0]));
5285       DONE;
5286     }
5287   from_compare (operands, GE);
5288 }")
5289
5290 (define_expand "ble"
5291   [(set (pc)
5292         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5293                       (label_ref (match_operand 0 "" ""))
5294                       (pc)))]
5295   ""
5296   "
5297 {
5298   if (TARGET_SHMEDIA)
5299     {
5300       if (GET_MODE (sh_compare_op0) != DImode)
5301         {
5302           rtx tmp = gen_reg_rtx (DImode);
5303
5304           emit_insn (gen_sle (tmp));
5305           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5306           DONE;
5307         }
5308
5309       if (sh_compare_op0 != const0_rtx)
5310         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5311       if (sh_compare_op1 != const0_rtx)
5312         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5313       emit_jump_insn (gen_bge_media (operands[0],
5314                                      sh_compare_op1, sh_compare_op0));
5315       DONE;
5316     }
5317
5318   if (TARGET_SH2E
5319       && TARGET_IEEE
5320       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5321     {
5322       rtx tmp = sh_compare_op0;
5323       sh_compare_op0 = sh_compare_op1;
5324       sh_compare_op1 = tmp;
5325       emit_insn (gen_bge (operands[0]));
5326       DONE;
5327     }
5328   from_compare (operands, GT);
5329 }")
5330
5331 (define_expand "bge"
5332   [(set (pc)
5333         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5334                       (label_ref (match_operand 0 "" ""))
5335                       (pc)))]
5336   ""
5337   "
5338 {
5339   if (TARGET_SHMEDIA)
5340     {
5341       if (GET_MODE (sh_compare_op0) != DImode)
5342         {
5343           rtx tmp = gen_reg_rtx (DImode);
5344
5345           emit_insn (gen_sge (tmp));
5346           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5347           DONE;
5348         }
5349
5350       if (sh_compare_op0 != const0_rtx)
5351         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5352       if (sh_compare_op1 != const0_rtx)
5353         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5354       emit_jump_insn (gen_bge_media (operands[0],
5355                                      sh_compare_op0, sh_compare_op1));
5356       DONE;
5357     }
5358
5359   if (TARGET_SH2E
5360       && ! TARGET_IEEE
5361       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5362     {
5363       rtx tmp = sh_compare_op0;
5364       sh_compare_op0 = sh_compare_op1;
5365       sh_compare_op1 = tmp;
5366       emit_insn (gen_ble (operands[0]));
5367       DONE;
5368     }
5369   from_compare (operands, GE);
5370 }")
5371
5372 (define_expand "bgtu"
5373   [(set (pc)
5374         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5375                       (label_ref (match_operand 0 "" ""))
5376                       (pc)))]
5377   ""
5378   "
5379 {
5380   if (TARGET_SHMEDIA)
5381     {
5382       if (sh_compare_op0 != const0_rtx)
5383         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5384       if (sh_compare_op1 != const0_rtx)
5385         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5386       emit_jump_insn (gen_bgtu_media (operands[0],
5387                                       sh_compare_op0, sh_compare_op1));
5388       DONE;
5389     }
5390
5391   from_compare (operands, GTU);
5392 }")
5393
5394 (define_expand "bltu"
5395   [(set (pc)
5396         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5397                       (label_ref (match_operand 0 "" ""))
5398                       (pc)))]
5399   ""
5400   "
5401 {
5402   if (TARGET_SHMEDIA)
5403     {
5404       if (sh_compare_op0 != const0_rtx)
5405         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5406       if (sh_compare_op1 != const0_rtx)
5407         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5408       emit_jump_insn (gen_bgtu_media (operands[0],
5409                                       sh_compare_op1, sh_compare_op0));
5410       DONE;
5411     }
5412
5413   from_compare (operands, GEU);
5414 }")
5415
5416 (define_expand "bgeu"
5417   [(set (pc)
5418         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5419                       (label_ref (match_operand 0 "" ""))
5420                       (pc)))]
5421   ""
5422   "
5423 {
5424   if (TARGET_SHMEDIA)
5425     {
5426       if (sh_compare_op0 != const0_rtx)
5427         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5428       if (sh_compare_op1 != const0_rtx)
5429         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5430       emit_jump_insn (gen_bgeu_media (operands[0],
5431                                       sh_compare_op0, sh_compare_op1));
5432       DONE;
5433     }
5434
5435   from_compare (operands, GEU);
5436 }")
5437
5438 (define_expand "bleu"
5439   [(set (pc)
5440         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5441                       (label_ref (match_operand 0 "" ""))
5442                       (pc)))]
5443   ""
5444   "
5445 {
5446   if (TARGET_SHMEDIA)
5447     {
5448       if (sh_compare_op0 != const0_rtx)
5449         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5450       if (sh_compare_op1 != const0_rtx)
5451         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5452       emit_jump_insn (gen_bgeu_media (operands[0],
5453                                       sh_compare_op1, sh_compare_op0));
5454       DONE;
5455     }
5456
5457   from_compare (operands, GTU);
5458 }")
5459
5460 (define_expand "bunordered"
5461   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5462    (set (pc)
5463         (if_then_else (ne (match_dup 1) (const_int 0))
5464                       (label_ref:DI (match_operand 0 "" ""))
5465                       (pc)))]
5466   "TARGET_SHMEDIA"
5467   "
5468 {
5469   operands[1] = gen_reg_rtx (DImode);
5470   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5471   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5472 }")
5473 \f
5474 ;; ------------------------------------------------------------------------
5475 ;; Jump and linkage insns
5476 ;; ------------------------------------------------------------------------
5477
5478 (define_insn "jump_compact"
5479   [(set (pc)
5480         (label_ref (match_operand 0 "" "")))]
5481   "TARGET_SH1"
5482   "*
5483 {
5484   /* The length is 16 if the delay slot is unfilled.  */
5485   if (get_attr_length(insn) > 4)
5486     return output_far_jump(insn, operands[0]);
5487   else
5488     return   \"bra      %l0%#\";
5489 }"
5490   [(set_attr "type" "jump")
5491    (set_attr "needs_delay_slot" "yes")])
5492
5493 ;; ??? It would be much saner to explicitly use the scratch register
5494 ;; in the jump insn, and have indirect_jump_scratch only set it,
5495 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5496 ;; from the target then, as it uses simplejump_p.
5497 ;;(define_insn "jump_compact_far"
5498 ;;  [(set (pc)
5499 ;;      (label_ref (match_operand 0 "" "")))
5500 ;;   (use (match_operand 1 "register_operand" "r")]
5501 ;;  "TARGET_SH1"
5502 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5503 ;;  [(set_attr "type" "jump")
5504 ;;   (set_attr "needs_delay_slot" "yes")])
5505
5506 (define_insn "jump_media"
5507   [(set (pc)
5508         (match_operand:DI 0 "target_operand" "b"))]
5509   "TARGET_SHMEDIA"
5510   "blink        %0, r63"
5511   [(set_attr "type" "jump_media")])
5512
5513 (define_expand "jump"
5514   [(set (pc)
5515         (label_ref (match_operand 0 "" "")))]
5516   ""
5517   "
5518 {
5519   if (TARGET_SH1)
5520     emit_jump_insn (gen_jump_compact (operands[0]));
5521   else if (TARGET_SHMEDIA)
5522     {
5523       if (reload_in_progress || reload_completed)
5524         FAIL;
5525       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5526                                                          operands[0])));
5527     }
5528   DONE;
5529 }")
5530
5531 (define_insn "force_mode_for_call"
5532   [(use (reg:PSI FPSCR_REG))]
5533   "TARGET_SHCOMPACT"
5534   ""
5535   [(set_attr "length" "0")
5536    (set (attr "fp_mode")
5537         (if_then_else (eq_attr "fpu_single" "yes")
5538                       (const_string "single") (const_string "double")))])
5539
5540 (define_insn "calli"
5541   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5542          (match_operand 1 "" ""))
5543    (use (reg:PSI FPSCR_REG))
5544    (clobber (reg:SI PR_REG))]
5545   "TARGET_SH1"
5546   "jsr  @%0%#"
5547   [(set_attr "type" "call")
5548    (set (attr "fp_mode")
5549         (if_then_else (eq_attr "fpu_single" "yes")
5550                       (const_string "single") (const_string "double")))
5551    (set_attr "needs_delay_slot" "yes")])
5552
5553 ;; This is a pc-rel call, using bsrf, for use with PIC.
5554
5555 (define_insn "calli_pcrel"
5556   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5557          (match_operand 1 "" ""))
5558    (use (reg:PSI FPSCR_REG))
5559    (use (reg:SI PIC_REG))
5560    (use (match_operand 2 "" ""))
5561    (clobber (reg:SI PR_REG))]
5562   "TARGET_SH2"
5563   "bsrf %0\\n%O2:%#"
5564   [(set_attr "type" "call")
5565    (set (attr "fp_mode")
5566         (if_then_else (eq_attr "fpu_single" "yes")
5567                       (const_string "single") (const_string "double")))
5568    (set_attr "needs_delay_slot" "yes")])
5569
5570 (define_insn_and_split "call_pcrel"
5571   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5572          (match_operand 1 "" ""))
5573    (use (reg:PSI FPSCR_REG))
5574    (use (reg:SI PIC_REG))
5575    (clobber (reg:SI PR_REG))
5576    (clobber (match_scratch:SI 2 "=r"))]
5577   "TARGET_SH2"
5578   "#"
5579   "reload_completed"
5580   [(const_int 0)]
5581   "
5582 {
5583   rtx lab = PATTERN (gen_call_site ());
5584
5585   if (SYMBOL_REF_LOCAL_P (operands[0]))
5586     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5587   else
5588     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5589   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5590   DONE;
5591 }"
5592   [(set_attr "type" "call")
5593    (set (attr "fp_mode")
5594         (if_then_else (eq_attr "fpu_single" "yes")
5595                       (const_string "single") (const_string "double")))
5596    (set_attr "needs_delay_slot" "yes")])
5597
5598 (define_insn "call_compact"
5599   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5600          (match_operand 1 "" ""))
5601    (match_operand 2 "immediate_operand" "n")
5602    (use (reg:SI R0_REG))
5603    (use (reg:SI R1_REG))
5604    (use (reg:PSI FPSCR_REG))
5605    (clobber (reg:SI PR_REG))]
5606   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5607   "jsr  @%0%#"
5608   [(set_attr "type" "call")
5609    (set (attr "fp_mode")
5610         (if_then_else (eq_attr "fpu_single" "yes")
5611                       (const_string "single") (const_string "double")))
5612    (set_attr "needs_delay_slot" "yes")])
5613
5614 (define_insn "call_compact_rettramp"
5615   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5616          (match_operand 1 "" ""))
5617    (match_operand 2 "immediate_operand" "n")
5618    (use (reg:SI R0_REG))
5619    (use (reg:SI R1_REG))
5620    (use (reg:PSI FPSCR_REG))
5621    (clobber (reg:SI R10_REG))
5622    (clobber (reg:SI PR_REG))]
5623   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5624   "jsr  @%0%#"
5625   [(set_attr "type" "call")
5626    (set (attr "fp_mode")
5627         (if_then_else (eq_attr "fpu_single" "yes")
5628                       (const_string "single") (const_string "double")))
5629    (set_attr "needs_delay_slot" "yes")])
5630
5631 (define_insn "call_media"
5632   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5633          (match_operand 1 "" ""))
5634    (clobber (reg:DI PR_MEDIA_REG))]
5635   "TARGET_SHMEDIA"
5636   "blink        %0, r18"
5637   [(set_attr "type" "jump_media")])
5638
5639 (define_insn "call_valuei"
5640   [(set (match_operand 0 "" "=rf")
5641         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5642               (match_operand 2 "" "")))
5643    (use (reg:PSI FPSCR_REG))
5644    (clobber (reg:SI PR_REG))]
5645   "TARGET_SH1"
5646   "jsr  @%1%#"
5647   [(set_attr "type" "call")
5648    (set (attr "fp_mode")
5649         (if_then_else (eq_attr "fpu_single" "yes")
5650                       (const_string "single") (const_string "double")))
5651    (set_attr "needs_delay_slot" "yes")])
5652
5653 (define_insn "call_valuei_pcrel"
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    (use (reg:SI PIC_REG))
5659    (use (match_operand 3 "" ""))
5660    (clobber (reg:SI PR_REG))]
5661   "TARGET_SH2"
5662   "bsrf %1\\n%O3:%#"
5663   [(set_attr "type" "call")
5664    (set (attr "fp_mode")
5665         (if_then_else (eq_attr "fpu_single" "yes")
5666                       (const_string "single") (const_string "double")))
5667    (set_attr "needs_delay_slot" "yes")])
5668
5669 (define_insn_and_split "call_value_pcrel"
5670   [(set (match_operand 0 "" "=rf")
5671         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5672               (match_operand 2 "" "")))
5673    (use (reg:PSI FPSCR_REG))
5674    (use (reg:SI PIC_REG))
5675    (clobber (reg:SI PR_REG))
5676    (clobber (match_scratch:SI 3 "=r"))]
5677   "TARGET_SH2"
5678   "#"
5679   "reload_completed"
5680   [(const_int 0)]
5681   "
5682 {
5683   rtx lab = PATTERN (gen_call_site ());
5684
5685   if (SYMBOL_REF_LOCAL_P (operands[1]))
5686     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5687   else
5688     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5689   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5690                                          operands[2], lab));
5691   DONE;
5692 }"
5693   [(set_attr "type" "call")
5694    (set (attr "fp_mode")
5695         (if_then_else (eq_attr "fpu_single" "yes")
5696                       (const_string "single") (const_string "double")))
5697    (set_attr "needs_delay_slot" "yes")])
5698
5699 (define_insn "call_value_compact"
5700   [(set (match_operand 0 "" "=rf")
5701         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5702               (match_operand 2 "" "")))
5703    (match_operand 3 "immediate_operand" "n")
5704    (use (reg:SI R0_REG))
5705    (use (reg:SI R1_REG))
5706    (use (reg:PSI FPSCR_REG))
5707    (clobber (reg:SI PR_REG))]
5708   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5709   "jsr  @%1%#"
5710   [(set_attr "type" "call")
5711    (set (attr "fp_mode")
5712         (if_then_else (eq_attr "fpu_single" "yes")
5713                       (const_string "single") (const_string "double")))
5714    (set_attr "needs_delay_slot" "yes")])
5715
5716 (define_insn "call_value_compact_rettramp"
5717   [(set (match_operand 0 "" "=rf")
5718         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5719               (match_operand 2 "" "")))
5720    (match_operand 3 "immediate_operand" "n")
5721    (use (reg:SI R0_REG))
5722    (use (reg:SI R1_REG))
5723    (use (reg:PSI FPSCR_REG))
5724    (clobber (reg:SI R10_REG))
5725    (clobber (reg:SI PR_REG))]
5726   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5727   "jsr  @%1%#"
5728   [(set_attr "type" "call")
5729    (set (attr "fp_mode")
5730         (if_then_else (eq_attr "fpu_single" "yes")
5731                       (const_string "single") (const_string "double")))
5732    (set_attr "needs_delay_slot" "yes")])
5733
5734 (define_insn "call_value_media"
5735   [(set (match_operand 0 "" "=rf")
5736         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5737               (match_operand 2 "" "")))
5738    (clobber (reg:DI PR_MEDIA_REG))]
5739   "TARGET_SHMEDIA"
5740   "blink        %1, r18"
5741   [(set_attr "type" "jump_media")])
5742
5743 (define_expand "call"
5744   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5745                             (match_operand 1 "" ""))
5746               (match_operand 2 "" "")
5747               (use (reg:PSI FPSCR_REG))
5748               (clobber (reg:SI PR_REG))])]
5749   ""
5750   "
5751 {
5752   if (TARGET_SHMEDIA)
5753     {
5754       operands[0] = XEXP (operands[0], 0);
5755       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5756         {
5757           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5758             {
5759               rtx reg = gen_reg_rtx (Pmode);
5760
5761               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5762               operands[0] = reg;
5763             }
5764           else
5765             {
5766               operands[0] = gen_sym2PIC (operands[0]);
5767               PUT_MODE (operands[0], Pmode);
5768             }
5769         }
5770       if (GET_MODE (operands[0]) == SImode)
5771         {
5772           if (GET_CODE (operands[0]) == REG)
5773             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5774           else if (GET_CODE (operands[0]) == SUBREG)
5775             {
5776               operands[0] = SUBREG_REG (operands[0]);
5777               if (GET_MODE (operands[0]) != DImode)
5778                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5779             }
5780           else
5781             {
5782               operands[0] = shallow_copy_rtx (operands[0]);
5783               PUT_MODE (operands[0], DImode);
5784             }
5785         }
5786       if (! target_reg_operand (operands[0], DImode))
5787         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5788       emit_call_insn (gen_call_media (operands[0], operands[1]));
5789       DONE;
5790     }
5791   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5792     {
5793       rtx cookie_rtx = operands[2];
5794       long cookie = INTVAL (cookie_rtx);
5795       rtx func = XEXP (operands[0], 0);
5796       rtx r0, r1;
5797
5798       if (flag_pic)
5799         {
5800           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5801             {
5802               rtx reg = gen_reg_rtx (Pmode);
5803
5804               emit_insn (gen_symGOTPLT2reg (reg, func));
5805               func = reg;
5806             }
5807           else
5808             func = legitimize_pic_address (func, Pmode, 0);
5809         }
5810
5811       r0 = gen_rtx_REG (SImode, R0_REG);
5812       r1 = gen_rtx_REG (SImode, R1_REG);
5813
5814       /* Since such a call function may use all call-clobbered
5815          registers, we force a mode switch earlier, so that we don't
5816          run out of registers when adjusting fpscr for the call.  */
5817       emit_insn (gen_force_mode_for_call ());
5818
5819       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5820       if (flag_pic)
5821         {
5822           rtx reg = gen_reg_rtx (Pmode);
5823
5824           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5825           operands[0] = reg;
5826         }
5827       operands[0] = force_reg (SImode, operands[0]);
5828
5829       emit_move_insn (r0, func);
5830       emit_move_insn (r1, cookie_rtx);
5831
5832       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5833         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5834                                                    operands[2]));
5835       else
5836         emit_call_insn (gen_call_compact (operands[0], operands[1],
5837                                           operands[2]));
5838
5839       DONE;
5840     }
5841   else if (TARGET_SHCOMPACT && flag_pic
5842            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5843            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5844     {
5845       rtx reg = gen_reg_rtx (Pmode);
5846
5847       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5848       XEXP (operands[0], 0) = reg;
5849     }
5850   if (flag_pic && TARGET_SH2
5851       && GET_CODE (operands[0]) == MEM
5852       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5853     {
5854       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5855       DONE;
5856     }
5857   else
5858     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5859
5860   emit_call_insn (gen_calli (operands[0], operands[1]));
5861   DONE;
5862 }")
5863
5864 (define_insn "call_pop_compact"
5865   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5866          (match_operand 1 "" ""))
5867    (match_operand 2 "immediate_operand" "n")
5868    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5869                                  (match_operand 3 "immediate_operand" "n")))
5870    (use (reg:SI R0_REG))
5871    (use (reg:SI R1_REG))
5872    (use (reg:PSI FPSCR_REG))
5873    (clobber (reg:SI PR_REG))]
5874   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5875   "jsr  @%0%#"
5876   [(set_attr "type" "call")
5877    (set (attr "fp_mode")
5878         (if_then_else (eq_attr "fpu_single" "yes")
5879                       (const_string "single") (const_string "double")))
5880    (set_attr "needs_delay_slot" "yes")])
5881
5882 (define_insn "call_pop_compact_rettramp"
5883   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5884          (match_operand 1 "" ""))
5885    (match_operand 2 "immediate_operand" "n")
5886    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5887                                  (match_operand 3 "immediate_operand" "n")))
5888    (use (reg:SI R0_REG))
5889    (use (reg:SI R1_REG))
5890    (use (reg:PSI FPSCR_REG))
5891    (clobber (reg:SI R10_REG))
5892    (clobber (reg:SI PR_REG))]
5893   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5894   "jsr  @%0%#"
5895   [(set_attr "type" "call")
5896    (set (attr "fp_mode")
5897         (if_then_else (eq_attr "fpu_single" "yes")
5898                       (const_string "single") (const_string "double")))
5899    (set_attr "needs_delay_slot" "yes")])
5900
5901 (define_expand "call_pop"
5902   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5903                     (match_operand 1 "" ""))
5904              (match_operand 2 "" "")
5905              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5906                                            (match_operand 3 "" "")))])]
5907   "TARGET_SHCOMPACT"
5908   "
5909 {
5910   if (operands[2] && INTVAL (operands[2]))
5911     {
5912       rtx cookie_rtx = operands[2];
5913       long cookie = INTVAL (cookie_rtx);
5914       rtx func = XEXP (operands[0], 0);
5915       rtx r0, r1;
5916
5917       if (flag_pic)
5918         {
5919           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5920             {
5921               rtx reg = gen_reg_rtx (Pmode);
5922
5923               emit_insn (gen_symGOTPLT2reg (reg, func));
5924               func = reg;
5925             }
5926           else
5927             func = legitimize_pic_address (func, Pmode, 0);
5928         }
5929
5930       r0 = gen_rtx_REG (SImode, R0_REG);
5931       r1 = gen_rtx_REG (SImode, R1_REG);
5932
5933       /* Since such a call function may use all call-clobbered
5934          registers, we force a mode switch earlier, so that we don't
5935          run out of registers when adjusting fpscr for the call.  */
5936       emit_insn (gen_force_mode_for_call ());
5937
5938       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5939       if (flag_pic)
5940         {
5941           rtx reg = gen_reg_rtx (Pmode);
5942
5943           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5944           operands[0] = reg;
5945         }
5946       operands[0] = force_reg (SImode, operands[0]);
5947
5948       emit_move_insn (r0, func);
5949       emit_move_insn (r1, cookie_rtx);
5950
5951       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5952         emit_call_insn (gen_call_pop_compact_rettramp
5953                         (operands[0], operands[1], operands[2], operands[3]));
5954       else
5955         emit_call_insn (gen_call_pop_compact
5956                         (operands[0], operands[1], operands[2], operands[3]));
5957
5958       DONE;
5959     }
5960
5961   abort ();
5962 }")
5963
5964 (define_expand "call_value"
5965   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5966                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5967                                  (match_operand 2 "" "")))
5968               (match_operand 3 "" "")
5969               (use (reg:PSI FPSCR_REG))
5970               (clobber (reg:SI PR_REG))])]
5971   ""
5972   "
5973 {
5974   if (TARGET_SHMEDIA)
5975     {
5976       operands[1] = XEXP (operands[1], 0);
5977       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5978         {
5979           if (! SYMBOL_REF_LOCAL_P (operands[1]))
5980             {
5981               rtx reg = gen_reg_rtx (Pmode);
5982
5983               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5984               operands[1] = reg;
5985             }
5986           else
5987             {
5988               operands[1] = gen_sym2PIC (operands[1]);
5989               PUT_MODE (operands[1], Pmode);
5990             }
5991         }
5992       if (GET_MODE (operands[1]) == SImode)
5993         {
5994           if (GET_CODE (operands[1]) == REG)
5995             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5996           else if (GET_CODE (operands[1]) == SUBREG)
5997             {
5998               operands[1] = SUBREG_REG (operands[1]);
5999               if (GET_MODE (operands[1]) != DImode)
6000                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6001             }
6002           else
6003             {
6004               operands[1] = shallow_copy_rtx (operands[1]);
6005               PUT_MODE (operands[1], DImode);
6006             }
6007         }
6008       if (! target_reg_operand (operands[1], DImode))
6009         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6010       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6011                                             operands[2]));
6012       DONE;
6013     }
6014   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6015     {
6016       rtx cookie_rtx = operands[3];
6017       long cookie = INTVAL (cookie_rtx);
6018       rtx func = XEXP (operands[1], 0);
6019       rtx r0, r1;
6020
6021       if (flag_pic)
6022         {
6023           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6024             {
6025               rtx reg = gen_reg_rtx (Pmode);
6026
6027               emit_insn (gen_symGOTPLT2reg (reg, func));
6028               func = reg;
6029             }
6030           else
6031             func = legitimize_pic_address (func, Pmode, 0);
6032         }
6033
6034       r0 = gen_rtx_REG (SImode, R0_REG);
6035       r1 = gen_rtx_REG (SImode, R1_REG);
6036
6037       /* Since such a call function may use all call-clobbered
6038          registers, we force a mode switch earlier, so that we don't
6039          run out of registers when adjusting fpscr for the call.  */
6040       emit_insn (gen_force_mode_for_call ());
6041
6042       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6043       if (flag_pic)
6044         {
6045           rtx reg = gen_reg_rtx (Pmode);
6046
6047           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6048           operands[1] = reg;
6049         }
6050       operands[1] = force_reg (SImode, operands[1]);
6051
6052       emit_move_insn (r0, func);
6053       emit_move_insn (r1, cookie_rtx);
6054
6055       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6056         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6057                                                          operands[1],
6058                                                          operands[2],
6059                                                          operands[3]));
6060       else
6061         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6062                                                 operands[2], operands[3]));
6063
6064       DONE;
6065     }
6066   else if (TARGET_SHCOMPACT && flag_pic
6067            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6068            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6069     {
6070       rtx reg = gen_reg_rtx (Pmode);
6071
6072       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6073       XEXP (operands[1], 0) = reg;
6074     }
6075   if (flag_pic && TARGET_SH2
6076       && GET_CODE (operands[1]) == MEM
6077       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6078     {
6079       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6080                                             operands[2]));
6081       DONE;
6082     }
6083   else
6084     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6085
6086   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6087   DONE;
6088 }")
6089
6090 (define_insn "sibcalli"
6091   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6092          (match_operand 1 "" ""))
6093    (use (reg:PSI FPSCR_REG))
6094    (return)]
6095   "TARGET_SH1"
6096   "jmp  @%0%#"
6097   [(set_attr "needs_delay_slot" "yes")
6098    (set (attr "fp_mode")
6099         (if_then_else (eq_attr "fpu_single" "yes")
6100                       (const_string "single") (const_string "double")))
6101    (set_attr "type" "jump_ind")])
6102
6103 (define_insn "sibcalli_pcrel"
6104   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6105          (match_operand 1 "" ""))
6106    (use (match_operand 2 "" ""))
6107    (use (reg:PSI FPSCR_REG))
6108    (return)]
6109   "TARGET_SH2"
6110   "braf %0\\n%O2:%#"
6111   [(set_attr "needs_delay_slot" "yes")
6112    (set (attr "fp_mode")
6113         (if_then_else (eq_attr "fpu_single" "yes")
6114                       (const_string "single") (const_string "double")))
6115    (set_attr "type" "jump_ind")])
6116
6117 (define_insn_and_split "sibcall_pcrel"
6118   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6119          (match_operand 1 "" ""))
6120    (use (reg:PSI FPSCR_REG))
6121    (clobber (match_scratch:SI 2 "=k"))
6122    (return)]
6123   "TARGET_SH2"
6124   "#"
6125   "reload_completed"
6126   [(const_int 0)]
6127   "
6128 {
6129   rtx lab = PATTERN (gen_call_site ());
6130   rtx call_insn;
6131
6132   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6133   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6134                                                   lab));
6135   SIBLING_CALL_P (call_insn) = 1;
6136   DONE;
6137 }"
6138   [(set_attr "needs_delay_slot" "yes")
6139    (set (attr "fp_mode")
6140         (if_then_else (eq_attr "fpu_single" "yes")
6141                       (const_string "single") (const_string "double")))
6142    (set_attr "type" "jump_ind")])
6143
6144 (define_insn "sibcall_compact"
6145   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6146          (match_operand 1 "" ""))
6147    (return)
6148    (use (match_operand:SI 2 "register_operand" "z,x"))
6149    (use (reg:SI R1_REG))
6150    (use (reg:PSI FPSCR_REG))
6151    ;; We want to make sure the `x' above will only match MACH_REG
6152    ;; because sibcall_epilogue may clobber MACL_REG.
6153    (clobber (reg:SI MACL_REG))]
6154   "TARGET_SHCOMPACT"
6155   "@
6156         jmp     @%0%#
6157         jmp     @%0\\n  sts     %2, r0"
6158   [(set_attr "needs_delay_slot" "yes,no")
6159    (set_attr "length" "2,4")
6160    (set (attr "fp_mode") (const_string "single"))
6161    (set_attr "type" "jump_ind")])
6162
6163 (define_insn "sibcall_media"
6164   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6165          (match_operand 1 "" ""))
6166    (return)]
6167   "TARGET_SHMEDIA"
6168   "blink        %0, r63"
6169   [(set_attr "type" "jump_media")])
6170
6171 (define_expand "sibcall"
6172   [(parallel
6173     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6174            (match_operand 1 "" ""))
6175      (match_operand 2 "" "")
6176      (use (reg:PSI FPSCR_REG))
6177      (return)])]
6178   ""
6179   "
6180 {
6181   if (TARGET_SHMEDIA)
6182     {
6183       operands[0] = XEXP (operands[0], 0);
6184       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6185         {
6186           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6187             {
6188               rtx reg = gen_reg_rtx (Pmode);
6189
6190               /* We must not use GOTPLT for sibcalls, because PIC_REG
6191                  must be restored before the PLT code gets to run.  */
6192               emit_insn (gen_symGOT2reg (reg, operands[0]));
6193               operands[0] = reg;
6194             }
6195           else
6196             {
6197               operands[0] = gen_sym2PIC (operands[0]);
6198               PUT_MODE (operands[0], Pmode);
6199             }
6200         }
6201       if (GET_MODE (operands[0]) == SImode)
6202         {
6203           if (GET_CODE (operands[0]) == REG)
6204             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6205           else if (GET_CODE (operands[0]) == SUBREG)
6206             {
6207               operands[0] = SUBREG_REG (operands[0]);
6208               if (GET_MODE (operands[0]) != DImode)
6209                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6210             }
6211           else
6212             {
6213               operands[0] = shallow_copy_rtx (operands[0]);
6214               PUT_MODE (operands[0], DImode);
6215             }
6216         }
6217       if (! target_reg_operand (operands[0], DImode))
6218         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6219       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6220       DONE;
6221     }
6222   else if (TARGET_SHCOMPACT && operands[2]
6223            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6224     {
6225       rtx cookie_rtx = operands[2];
6226       long cookie = INTVAL (cookie_rtx);
6227       rtx func = XEXP (operands[0], 0);
6228       rtx mach, r1;
6229
6230       if (flag_pic)
6231         {
6232           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6233             {
6234               rtx reg = gen_reg_rtx (Pmode);
6235
6236               emit_insn (gen_symGOT2reg (reg, func));
6237               func = reg;
6238             }
6239           else
6240             func = legitimize_pic_address (func, Pmode, 0);
6241         }
6242
6243       /* FIXME: if we could tell whether all argument registers are
6244          already taken, we could decide whether to force the use of
6245          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6246          simple way to tell.  We could use the CALL_COOKIE, but we
6247          can't currently tell a register used for regular argument
6248          passing from one that is unused.  If we leave it up to reload
6249          to decide which register to use, it seems to always choose
6250          R0_REG, which leaves no available registers in SIBCALL_REGS
6251          to hold the address of the trampoline.  */
6252       mach = gen_rtx_REG (SImode, MACH_REG);
6253       r1 = gen_rtx_REG (SImode, R1_REG);
6254
6255       /* Since such a call function may use all call-clobbered
6256          registers, we force a mode switch earlier, so that we don't
6257          run out of registers when adjusting fpscr for the call.  */
6258       emit_insn (gen_force_mode_for_call ());
6259
6260       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6261       if (flag_pic)
6262         {
6263           rtx reg = gen_reg_rtx (Pmode);
6264
6265           emit_insn (gen_symGOT2reg (reg, operands[0]));
6266           operands[0] = reg;
6267         }
6268       operands[0] = force_reg (SImode, operands[0]);
6269
6270       /* We don't need a return trampoline, since the callee will
6271          return directly to the upper caller.  */
6272       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6273         {
6274           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6275           cookie_rtx = GEN_INT (cookie);
6276         }
6277
6278       emit_move_insn (mach, func);
6279       emit_move_insn (r1, cookie_rtx);
6280
6281       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6282       DONE;
6283     }
6284   else if (TARGET_SHCOMPACT && flag_pic
6285            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6286            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6287     {
6288       rtx reg = gen_reg_rtx (Pmode);
6289
6290       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6291       XEXP (operands[0], 0) = reg;
6292     }
6293   if (flag_pic && TARGET_SH2
6294       && GET_CODE (operands[0]) == MEM
6295       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6296       /* The PLT needs the PIC register, but the epilogue would have
6297          to restore it, so we can only use PC-relative PIC calls for
6298          static functions.  */
6299       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6300     {
6301       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6302       DONE;
6303     }
6304   else
6305     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6306
6307   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6308   DONE;
6309 }")
6310
6311 (define_expand "sibcall_value"
6312   [(set (match_operand 0 "" "")
6313         (call (match_operand 1 "" "")
6314               (match_operand 2 "" "")))
6315    (match_operand 3 "" "")]
6316   ""
6317   "
6318 {
6319   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6320   DONE;
6321 }")
6322
6323 (define_insn "call_value_pop_compact"
6324   [(set (match_operand 0 "" "=rf")
6325         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6326               (match_operand 2 "" "")))
6327    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6328                                  (match_operand 4 "immediate_operand" "n")))
6329    (match_operand 3 "immediate_operand" "n")
6330    (use (reg:SI R0_REG))
6331    (use (reg:SI R1_REG))
6332    (use (reg:PSI FPSCR_REG))
6333    (clobber (reg:SI PR_REG))]
6334   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6335   "jsr  @%1%#"
6336   [(set_attr "type" "call")
6337    (set (attr "fp_mode")
6338         (if_then_else (eq_attr "fpu_single" "yes")
6339                       (const_string "single") (const_string "double")))
6340    (set_attr "needs_delay_slot" "yes")])
6341
6342 (define_insn "call_value_pop_compact_rettramp"
6343   [(set (match_operand 0 "" "=rf")
6344         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6345               (match_operand 2 "" "")))
6346    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6347                                  (match_operand 4 "immediate_operand" "n")))
6348    (match_operand 3 "immediate_operand" "n")
6349    (use (reg:SI R0_REG))
6350    (use (reg:SI R1_REG))
6351    (use (reg:PSI FPSCR_REG))
6352    (clobber (reg:SI R10_REG))
6353    (clobber (reg:SI PR_REG))]
6354   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6355   "jsr  @%1%#"
6356   [(set_attr "type" "call")
6357    (set (attr "fp_mode")
6358         (if_then_else (eq_attr "fpu_single" "yes")
6359                       (const_string "single") (const_string "double")))
6360    (set_attr "needs_delay_slot" "yes")])
6361
6362 (define_expand "call_value_pop"
6363   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6364                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6365                                  (match_operand 2 "" "")))
6366               (match_operand 3 "" "")
6367               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6368                                             (match_operand 4 "" "")))])]
6369   "TARGET_SHCOMPACT"
6370   "
6371 {
6372   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6373     {
6374       rtx cookie_rtx = operands[3];
6375       long cookie = INTVAL (cookie_rtx);
6376       rtx func = XEXP (operands[1], 0);
6377       rtx r0, r1;
6378
6379       if (flag_pic)
6380         {
6381           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6382             {
6383               rtx reg = gen_reg_rtx (Pmode);
6384
6385               emit_insn (gen_symGOTPLT2reg (reg, func));
6386               func = reg;
6387             }
6388           else
6389             func = legitimize_pic_address (func, Pmode, 0);
6390         }
6391
6392       r0 = gen_rtx_REG (SImode, R0_REG);
6393       r1 = gen_rtx_REG (SImode, R1_REG);
6394
6395       /* Since such a call function may use all call-clobbered
6396          registers, we force a mode switch earlier, so that we don't
6397          run out of registers when adjusting fpscr for the call.  */
6398       emit_insn (gen_force_mode_for_call ());
6399
6400       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6401       if (flag_pic)
6402         {
6403           rtx reg = gen_reg_rtx (Pmode);
6404
6405           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6406           operands[1] = reg;
6407         }
6408       operands[1] = force_reg (SImode, operands[1]);
6409
6410       emit_move_insn (r0, func);
6411       emit_move_insn (r1, cookie_rtx);
6412
6413       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6414         emit_call_insn (gen_call_value_pop_compact_rettramp
6415                         (operands[0], operands[1], operands[2],
6416                          operands[3], operands[4]));
6417       else
6418         emit_call_insn (gen_call_value_pop_compact
6419                         (operands[0], operands[1], operands[2],
6420                          operands[3], operands[4]));
6421
6422       DONE;
6423     }
6424
6425   abort ();
6426 }")
6427
6428 (define_expand "sibcall_epilogue"
6429   [(return)]
6430   ""
6431   "
6432 {
6433   sh_expand_epilogue ();
6434   if (TARGET_SHCOMPACT)
6435     {
6436       rtx insn, set;
6437
6438       /* If epilogue clobbers r0, preserve it in macl.  */
6439       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6440         if ((set = single_set (insn))
6441             && GET_CODE (SET_DEST (set)) == REG
6442             && REGNO (SET_DEST (set)) == R0_REG)
6443           {
6444             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6445             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6446             rtx i;
6447
6448             /* We can't tell at this point whether the sibcall is a
6449                sibcall_compact and, if it is, whether it uses r0 or
6450                mach as operand 2, so let the instructions that
6451                preserve r0 be optimized away if r0 turns out to be
6452                dead.  */
6453             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6454             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6455                                                REG_NOTES (i));
6456             i = emit_move_insn (r0, tmp);
6457             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6458                                                REG_NOTES (i));
6459             break;
6460           }
6461     }
6462   DONE;
6463 }")
6464
6465 (define_insn "indirect_jump_compact"
6466   [(set (pc)
6467         (match_operand:SI 0 "arith_reg_operand" "r"))]
6468   "TARGET_SH1"
6469   "jmp  @%0%#"
6470   [(set_attr "needs_delay_slot" "yes")
6471    (set_attr "type" "jump_ind")])
6472
6473 (define_expand "indirect_jump"
6474   [(set (pc)
6475         (match_operand 0 "register_operand" ""))]
6476   ""
6477   "
6478 {
6479   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6480     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6481 }")
6482
6483 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6484 ;; which can be present in structured code from indirect jumps which can not
6485 ;; be present in structured code.  This allows -fprofile-arcs to work.
6486
6487 ;; For SH1 processors.
6488 (define_insn "casesi_jump_1"
6489   [(set (pc)
6490         (match_operand:SI 0 "register_operand" "r"))
6491    (use (label_ref (match_operand 1 "" "")))]
6492   "TARGET_SH1"
6493   "jmp  @%0%#"
6494   [(set_attr "needs_delay_slot" "yes")
6495    (set_attr "type" "jump_ind")])
6496
6497 ;; For all later processors.
6498 (define_insn "casesi_jump_2"
6499   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6500                       (label_ref (match_operand 1 "" ""))))
6501    (use (label_ref (match_operand 2 "" "")))]
6502   "TARGET_SH2
6503    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6504   "braf %0%#"
6505   [(set_attr "needs_delay_slot" "yes")
6506    (set_attr "type" "jump_ind")])
6507
6508 (define_insn "casesi_jump_media"
6509   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6510    (use (label_ref (match_operand 1 "" "")))]
6511   "TARGET_SHMEDIA"
6512   "blink        %0, r63"
6513   [(set_attr "type" "jump_media")])
6514
6515 ;; Call subroutine returning any type.
6516 ;; ??? This probably doesn't work.
6517
6518 (define_expand "untyped_call"
6519   [(parallel [(call (match_operand 0 "" "")
6520                     (const_int 0))
6521               (match_operand 1 "" "")
6522               (match_operand 2 "" "")])]
6523   "TARGET_SH2E || TARGET_SHMEDIA"
6524   "
6525 {
6526   int i;
6527
6528   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6529
6530   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6531     {
6532       rtx set = XVECEXP (operands[2], 0, i);
6533       emit_move_insn (SET_DEST (set), SET_SRC (set));
6534     }
6535
6536   /* The optimizer does not know that the call sets the function value
6537      registers we stored in the result block.  We avoid problems by
6538      claiming that all hard registers are used and clobbered at this
6539      point.  */
6540   emit_insn (gen_blockage ());
6541
6542   DONE;
6543 }")
6544 \f
6545 ;; ------------------------------------------------------------------------
6546 ;; Misc insns
6547 ;; ------------------------------------------------------------------------
6548
6549 (define_insn "dect"
6550   [(set (reg:SI T_REG)
6551         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6552    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6553   "TARGET_SH2"
6554   "dt   %0"
6555   [(set_attr "type" "arith")])
6556
6557 (define_insn "nop"
6558   [(const_int 0)]
6559   ""
6560   "nop")
6561
6562 ;; Load address of a label. This is only generated by the casesi expand,
6563 ;; and by machine_dependent_reorg (fixing up fp moves).
6564 ;; This must use unspec, because this only works for labels that are
6565 ;; within range,
6566
6567 (define_insn "mova"
6568   [(set (reg:SI R0_REG)
6569         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6570   "TARGET_SH1"
6571   "mova %O0,r0"
6572   [(set_attr "in_delay_slot" "no")
6573    (set_attr "type" "arith")])
6574
6575 ;; machine_dependent_reorg will make this a `mova'.
6576 (define_insn "mova_const"
6577   [(set (reg:SI R0_REG)
6578         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6579   "TARGET_SH1"
6580   "#"
6581   [(set_attr "in_delay_slot" "no")
6582    (set_attr "type" "arith")])
6583
6584 (define_expand "GOTaddr2picreg"
6585   [(set (reg:SI R0_REG)
6586         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6587                    UNSPEC_MOVA))
6588    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6589    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6590   "" "
6591 {
6592   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6593   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6594
6595   if (TARGET_SH5)
6596     operands[1] = gen_datalabel_ref (operands[1]);
6597
6598   if (TARGET_SHMEDIA)
6599     {
6600       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6601       rtx dipic = operands[0];
6602       rtx lab = PATTERN (gen_call_site ());
6603       rtx insn, equiv;
6604
6605       equiv = operands[1];
6606       operands[1] = gen_rtx_MINUS (DImode,
6607                                    operands[1],
6608                                    gen_rtx_CONST
6609                                    (DImode,
6610                                     gen_rtx_MINUS (DImode,
6611                                                    gen_rtx_CONST (DImode,
6612                                                                   lab),
6613                                                    pc_rtx)));
6614       operands[1] = gen_sym2PIC (operands[1]);
6615       PUT_MODE (operands[1], DImode);
6616
6617       if (GET_MODE (dipic) != DImode)
6618         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6619
6620       if (TARGET_SHMEDIA64)
6621         emit_insn (gen_movdi_const (dipic, operands[1]));
6622       else
6623         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6624
6625       emit_insn (gen_ptrel (tr, dipic, lab));
6626
6627       if (GET_MODE (operands[0]) != GET_MODE (tr))
6628         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6629
6630       insn = emit_move_insn (operands[0], tr);
6631
6632       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6633                                             REG_NOTES (insn));
6634
6635       DONE;
6636     }
6637 }
6638 ")
6639
6640 ;; When generating PIC, we must match label_refs especially, because
6641 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6642 ;; them to do, because they can't be loaded directly into
6643 ;; non-branch-target registers.
6644 (define_insn "*pt"
6645   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6646         (match_operand:DI 1 "" "Csy"))]
6647   "TARGET_SHMEDIA && flag_pic
6648    && EXTRA_CONSTRAINT_Csy (operands[1])"
6649   "pt   %1, %0"
6650   [(set_attr "type" "pt_media")
6651    (set_attr "length" "*")])
6652
6653 (define_insn "*ptb"
6654   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6655         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6656                              UNSPEC_DATALABEL)))]
6657   "TARGET_SHMEDIA && flag_pic
6658    && EXTRA_CONSTRAINT_Csy (operands[1])"
6659   "ptb/u        datalabel %1, %0"
6660   [(set_attr "type" "pt_media")
6661    (set_attr "length" "*")])
6662
6663 (define_insn "ptrel"
6664   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6665         (plus:DI (match_operand:DI 1 "register_operand" "r")
6666               (pc)))
6667    (match_operand:DI 2 "" "")]
6668   "TARGET_SHMEDIA"
6669   "%O2: ptrel/u %1, %0"
6670   [(set_attr "type" "ptabs_media")])
6671
6672 (define_expand "builtin_setjmp_receiver"
6673   [(match_operand 0 "" "")]
6674   "flag_pic"
6675   "
6676 {
6677   emit_insn (gen_GOTaddr2picreg ());
6678   DONE;
6679 }")
6680
6681 (define_expand "call_site"
6682   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6683   "TARGET_SH1"
6684   "
6685 {
6686   static HOST_WIDE_INT i = 0;
6687   operands[0] = GEN_INT (i);
6688   i++;
6689 }")
6690
6691 (define_expand "sym_label2reg"
6692   [(set (match_operand:SI 0 "" "")
6693         (const:SI (minus:SI
6694                    (const:SI
6695                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6696                    (const:SI
6697                     (plus:SI
6698                      (match_operand:SI 2 "" "")
6699                      (const_int 2))))))]
6700   "TARGET_SH1" "")
6701
6702 (define_expand "symGOT_load"
6703   [(set (match_dup 2) (match_operand 1 "" ""))
6704    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6705    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6706   ""
6707   "
6708 {
6709   rtx insn;
6710
6711   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6712   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6713
6714   if (TARGET_SHMEDIA)
6715     {
6716       rtx reg = operands[2];
6717
6718       if (GET_MODE (reg) != DImode)
6719         reg = gen_rtx_SUBREG (DImode, reg, 0);
6720
6721       if (flag_pic > 1)
6722         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6723       else
6724         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6725     }
6726   else
6727     emit_move_insn (operands[2], operands[1]);
6728
6729   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6730                                              operands[2],
6731                                              gen_rtx_REG (Pmode, PIC_REG)));
6732
6733   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6734
6735   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6736                                                                   0), 0, 0),
6737                                         REG_NOTES (insn));
6738
6739   DONE;
6740 }")
6741
6742 (define_expand "sym2GOT"
6743   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6744   ""
6745   "")
6746
6747 (define_expand "symGOT2reg"
6748   [(match_operand 0 "" "") (match_operand 1 "" "")]
6749   ""
6750   "
6751 {
6752   rtx gotsym, insn;
6753
6754   gotsym = gen_sym2GOT (operands[1]);
6755   PUT_MODE (gotsym, Pmode);
6756   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6757
6758   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6759
6760   DONE;
6761 }")
6762
6763 (define_expand "sym2GOTPLT"
6764   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6765   ""
6766   "")
6767
6768 (define_expand "symGOTPLT2reg"
6769   [(match_operand 0 "" "") (match_operand 1 "" "")]
6770   ""
6771   "
6772 {
6773   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6774   DONE;
6775 }")
6776
6777 (define_expand "sym2GOTOFF"
6778   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6779   ""
6780   "")
6781
6782 (define_expand "symGOTOFF2reg"
6783   [(match_operand 0 "" "") (match_operand 1 "" "")]
6784   ""
6785   "
6786 {
6787   rtx gotoffsym, insn;
6788   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6789
6790   gotoffsym = gen_sym2GOTOFF (operands[1]);
6791   PUT_MODE (gotoffsym, Pmode);
6792   emit_move_insn (t, gotoffsym);
6793   insn = emit_move_insn (operands[0],
6794                          gen_rtx_PLUS (Pmode, t,
6795                                        gen_rtx_REG (Pmode, PIC_REG)));
6796
6797   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6798                                         REG_NOTES (insn));
6799
6800   DONE;
6801 }")
6802
6803 (define_expand "symPLT_label2reg"
6804   [(set (match_operand:SI 0 "" "")
6805         (const:SI (minus:SI
6806                    (const:SI
6807                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6808                    (const:SI
6809                     (minus:SI
6810                      (const:SI (plus:SI
6811                                 (match_operand:SI 2 "" "")
6812                                 (const_int 2)))
6813                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6814    ;; Even though the PIC register is not really used by the call
6815    ;; sequence in which this is expanded, the PLT code assumes the PIC
6816    ;; register is set, so we must not skip its initialization.  Since
6817    ;; we only use this expand as part of calling sequences, and never
6818    ;; to take the address of a function, this is the best point to
6819    ;; insert the (use).  Using the PLT to take the address of a
6820    ;; function would be wrong, not only because the PLT entry could
6821    ;; then be called from a function that doesn't initialize the PIC
6822    ;; register to the proper GOT, but also because pointers to the
6823    ;; same function might not compare equal, should they be set by
6824    ;; different shared libraries.
6825    (use (reg:SI PIC_REG))]
6826   "TARGET_SH1"
6827   "")
6828
6829 (define_expand "sym2PIC"
6830   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6831   ""
6832   "")
6833
6834 ;; TLS code generation.
6835 ;; ??? this should be a define_insn_and_split
6836 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6837 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6838 ;; for details.
6839
6840 (define_insn "tls_global_dynamic"
6841   [(set (match_operand:SI 0 "register_operand" "=&z")
6842         (unspec:SI [(match_operand:SI 1 "" "")]
6843                     UNSPEC_TLSGD))
6844    (use (reg:PSI FPSCR_REG))
6845    (use (reg:SI PIC_REG))
6846    (clobber (reg:SI PR_REG))
6847    (clobber (scratch:SI))]
6848   "TARGET_SH1"
6849   "*
6850 {
6851   return \"\\
6852 mov.l\\t1f,r4\\n\\
6853 \\tmova\\t2f,r0\\n\\
6854 \\tmov.l\\t2f,r1\\n\\
6855 \\tadd\\tr0,r1\\n\\
6856 \\tjsr\\t@r1\\n\\
6857 \\tadd\\tr12,r4\\n\\
6858 \\tbra\\t3f\\n\\
6859 \\tnop\\n\\
6860 \\t.align\\t2\\n\\
6861 1:\\t.long\\t%a1@TLSGD\\n\\
6862 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6863 3:\";
6864 }"
6865   [(set_attr "type" "tls_load")
6866    (set_attr "length" "26")])
6867
6868 (define_insn "tls_local_dynamic"
6869   [(set (match_operand:SI 0 "register_operand" "=&z")
6870         (unspec:SI [(match_operand:SI 1 "" "")]
6871                     UNSPEC_TLSLDM))
6872    (use (reg:PSI FPSCR_REG))
6873    (use (reg:SI PIC_REG))
6874    (clobber (reg:SI PR_REG))
6875    (clobber (scratch:SI))]
6876   "TARGET_SH1"
6877   "*
6878 {
6879   return \"\\
6880 mov.l\\t1f,r4\\n\\
6881 \\tmova\\t2f,r0\\n\\
6882 \\tmov.l\\t2f,r1\\n\\
6883 \\tadd\\tr0,r1\\n\\
6884 \\tjsr\\t@r1\\n\\
6885 \\tadd\\tr12,r4\\n\\
6886 \\tbra\\t3f\\n\\
6887 \\tnop\\n\\
6888 \\t.align\\t2\\n\\
6889 1:\\t.long\\t%a1@TLSLDM\\n\\
6890 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6891 3:\";
6892 }"
6893   [(set_attr "type" "tls_load")
6894    (set_attr "length" "26")])
6895
6896 (define_expand "sym2DTPOFF"
6897   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6898   ""
6899   "")
6900
6901 (define_expand "symDTPOFF2reg"
6902   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6903   ""
6904   "
6905 {
6906   rtx dtpoffsym, insn;
6907   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6908
6909   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6910   PUT_MODE (dtpoffsym, Pmode);
6911   emit_move_insn (t, dtpoffsym);
6912   insn = emit_move_insn (operands[0],
6913                          gen_rtx_PLUS (Pmode, t, operands[2]));
6914   DONE;
6915 }")
6916
6917 (define_expand "sym2GOTTPOFF"
6918   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6919   ""
6920   "")
6921
6922 (define_insn "tls_initial_exec"
6923   [(set (match_operand:SI 0 "register_operand" "=&r")
6924         (unspec:SI [(match_operand:SI 1 "" "")]
6925                     UNSPEC_TLSIE))
6926    (use (reg:SI GBR_REG))
6927    (use (reg:SI PIC_REG))
6928    (clobber (reg:SI R0_REG))]
6929   ""
6930   "*
6931 {
6932   return \"\\
6933 mov.l\\t1f,r0\\n\\
6934 \\tstc\\tgbr,%0\\n\\
6935 \\tmov.l\\t@(r0,r12),r0\\n\\
6936 \\tbra\\t2f\\n\\
6937 \\tadd\\tr0,%0\\n\\
6938 \\t.align\\t2\\n\\
6939 1:\\t.long\\t%a1\\n\\
6940 2:\";
6941 }"
6942   [(set_attr "type" "tls_load")
6943    (set_attr "length" "16")])
6944
6945 (define_expand "sym2TPOFF"
6946   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6947   ""
6948   "")
6949
6950 (define_expand "symTPOFF2reg"
6951   [(match_operand 0 "" "") (match_operand 1 "" "")]
6952   ""
6953   "
6954 {
6955   rtx tpoffsym, insn;
6956
6957   tpoffsym = gen_sym2TPOFF (operands[1]);
6958   PUT_MODE (tpoffsym, Pmode);
6959   insn = emit_move_insn (operands[0], tpoffsym);
6960   DONE;
6961 }")
6962
6963 (define_insn "load_gbr"
6964   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6965    (use (reg:SI GBR_REG))]
6966   ""
6967   "stc  gbr,%0"
6968   [(set_attr "type" "tls_load")])
6969
6970 ;; case instruction for switch statements.
6971
6972 ;; Operand 0 is index
6973 ;; operand 1 is the minimum bound
6974 ;; operand 2 is the maximum bound - minimum bound + 1
6975 ;; operand 3 is CODE_LABEL for the table;
6976 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6977
6978 (define_expand "casesi"
6979   [(match_operand:SI 0 "arith_reg_operand" "")
6980    (match_operand:SI 1 "arith_reg_operand" "")
6981    (match_operand:SI 2 "arith_reg_operand" "")
6982    (match_operand 3 "" "") (match_operand 4 "" "")]
6983   ""
6984   "
6985 {
6986   rtx reg = gen_reg_rtx (SImode);
6987   rtx reg2 = gen_reg_rtx (SImode);
6988   if (TARGET_SHMEDIA)
6989     {
6990       rtx reg = gen_reg_rtx (DImode);
6991       rtx reg2 = gen_reg_rtx (DImode);
6992       rtx reg3 = gen_reg_rtx (DImode);
6993       rtx reg4 = gen_reg_rtx (DImode);
6994       rtx reg5 = gen_reg_rtx (DImode);
6995
6996       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6997       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6998       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6999
7000       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7001       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7002       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7003       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7004       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7005                                                (DImode, operands[3])));
7006       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7007       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7008       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7009       emit_barrier ();
7010       DONE;
7011     }
7012   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7013   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7014   /* If optimizing, casesi_worker depends on the mode of the instruction
7015      before label it 'uses' - operands[3].  */
7016   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7017                            reg));
7018   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7019   if (TARGET_SH2)
7020     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7021   else
7022     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7023   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7024      operands[3], but to lab.  We will fix this up in
7025      machine_dependent_reorg.  */
7026   emit_barrier ();
7027   DONE;
7028 }")
7029
7030 (define_expand "casesi_0"
7031   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7032    (set (match_dup 4) (minus:SI (match_dup 4)
7033                                 (match_operand:SI 1 "arith_operand" "")))
7034    (set (reg:SI T_REG)
7035         (gtu:SI (match_dup 4)
7036                 (match_operand:SI 2 "arith_reg_operand" "")))
7037    (set (pc)
7038         (if_then_else (ne (reg:SI T_REG)
7039                           (const_int 0))
7040                       (label_ref (match_operand 3 "" ""))
7041                       (pc)))]
7042   "TARGET_SH1"
7043   "")
7044
7045 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7046 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7047 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7048
7049 (define_insn "casesi_worker_0"
7050   [(set (match_operand:SI 0 "register_operand" "=r,r")
7051         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7052                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7053    (clobber (match_scratch:SI 3 "=X,1"))
7054    (clobber (match_scratch:SI 4 "=&z,z"))]
7055   "TARGET_SH1"
7056   "#")
7057
7058 (define_split
7059   [(set (match_operand:SI 0 "register_operand" "")
7060         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7061                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7062    (clobber (match_scratch:SI 3 ""))
7063    (clobber (match_scratch:SI 4 ""))]
7064   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7065   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7066    (parallel [(set (match_dup 0)
7067               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7068                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7069               (clobber (match_dup 3))])
7070    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7071   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7072
7073 (define_split
7074   [(set (match_operand:SI 0 "register_operand" "")
7075         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7076                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7077    (clobber (match_scratch:SI 3 ""))
7078    (clobber (match_scratch:SI 4 ""))]
7079   "TARGET_SH2 && reload_completed"
7080   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7081    (parallel [(set (match_dup 0)
7082               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7083                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7084               (clobber (match_dup 3))])]
7085   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7086
7087 (define_insn "*casesi_worker"
7088   [(set (match_operand:SI 0 "register_operand" "=r,r")
7089         (unspec:SI [(reg:SI R0_REG)
7090                     (match_operand:SI 1 "register_operand" "0,r")
7091                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7092    (clobber (match_scratch:SI 3 "=X,1"))]
7093   "TARGET_SH1"
7094   "*
7095 {
7096   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7097
7098   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7099     abort ();
7100
7101   switch (GET_MODE (diff_vec))
7102     {
7103     case SImode:
7104       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7105     case HImode:
7106       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7107     case QImode:
7108       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7109         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7110       return \"mov.b    @(r0,%1),%0\";
7111     default:
7112       abort ();
7113     }
7114 }"
7115   [(set_attr "length" "4")])
7116
7117 (define_insn "casesi_shift_media"
7118   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7119         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7120                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7121                     UNSPEC_CASESI)))]
7122   "TARGET_SHMEDIA"
7123   "*
7124 {
7125   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7126
7127   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7128     abort ();
7129
7130   switch (GET_MODE (diff_vec))
7131     {
7132     case SImode:
7133       return \"shlli    %1, 2, %0\";
7134     case HImode:
7135       return \"shlli    %1, 1, %0\";
7136     case QImode:
7137       if (rtx_equal_p (operands[0], operands[1]))
7138         return \"\";
7139       return \"add      %1, r63, %0\";
7140     default:
7141       abort ();
7142     }
7143 }"
7144   [(set_attr "type" "arith_media")])
7145
7146 (define_insn "casesi_load_media"
7147   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7148         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7149                          (match_operand 2 "arith_reg_operand" "r")
7150                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7151   "TARGET_SHMEDIA"
7152   "*
7153 {
7154   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7155
7156   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7157     abort ();
7158
7159   switch (GET_MODE (diff_vec))
7160     {
7161     case SImode:
7162       return \"ldx.l    %1, %2, %0\";
7163     case HImode:
7164 #if 0
7165       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7166         return \"ldx.uw %1, %2, %0\";
7167 #endif
7168       return \"ldx.w    %1, %2, %0\";
7169     case QImode:
7170       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7171         return \"ldx.ub %1, %2, %0\";
7172       return \"ldx.b    %1, %2, %0\";
7173     default:
7174       abort ();
7175     }
7176 }"
7177   [(set_attr "type" "load_media")])
7178
7179 (define_expand "return"
7180   [(return)]
7181   "reload_completed && ! sh_need_epilogue ()"
7182   "
7183 {
7184   if (TARGET_SHMEDIA)
7185     {
7186       emit_jump_insn (gen_return_media ());
7187       DONE;
7188     }
7189
7190   if (TARGET_SHCOMPACT
7191       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7192     {
7193       emit_jump_insn (gen_shcompact_return_tramp ());
7194       DONE;
7195     }
7196 }")
7197
7198 (define_insn "*return_i"
7199   [(return)]
7200   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7201                     && (current_function_args_info.call_cookie
7202                         & CALL_COOKIE_RET_TRAMP (1)))
7203    && reload_completed"
7204   "%@   %#"
7205   [(set_attr "type" "return")
7206    (set_attr "needs_delay_slot" "yes")])
7207
7208 (define_expand "shcompact_return_tramp"
7209   [(return)]
7210   "TARGET_SHCOMPACT
7211    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7212   "
7213 {
7214   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7215   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7216
7217   if (flag_pic)
7218     emit_insn (gen_symGOTPLT2reg (reg, sym));
7219   else
7220     emit_move_insn (reg, sym);
7221
7222   emit_jump_insn (gen_shcompact_return_tramp_i ());
7223   DONE;
7224 }")
7225
7226 (define_insn "shcompact_return_tramp_i"
7227   [(parallel [(return) (use (reg:SI R0_REG))])]
7228   "TARGET_SHCOMPACT
7229    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7230   "jmp  @r0%#"
7231   [(set_attr "type" "jump_ind")
7232    (set_attr "needs_delay_slot" "yes")])
7233
7234 (define_insn "return_media_i"
7235   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7236   "TARGET_SHMEDIA && reload_completed"
7237   "blink        %0, r63"
7238   [(set_attr "type" "jump_media")])
7239
7240 (define_expand "return_media"
7241   [(return)]
7242   "TARGET_SHMEDIA && reload_completed"
7243   "
7244 {
7245   int tr_regno = sh_media_register_for_return ();
7246   rtx tr;
7247
7248   if (tr_regno < 0)
7249     {
7250       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7251
7252       tr_regno = TR0_REG;
7253       tr = gen_rtx_REG (DImode, tr_regno);
7254       emit_move_insn (tr, r18);
7255     }
7256   else
7257     tr = gen_rtx_REG (DImode, tr_regno);
7258
7259   emit_jump_insn (gen_return_media_i (tr));
7260   DONE;
7261 }")
7262
7263 (define_insn "shcompact_preserve_incoming_args"
7264   [(set (match_operand:SI 0 "register_operand" "+r")
7265         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7266   "TARGET_SHCOMPACT"
7267   ""
7268   [(set_attr "length" "0")])
7269
7270 (define_insn "shcompact_incoming_args"
7271   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7272    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7273    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7274    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7275    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7276    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7277    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7278    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7279    (set (mem:BLK (reg:SI MACL_REG))
7280         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7281    (use (reg:SI R0_REG))
7282    (clobber (reg:SI R0_REG))
7283    (clobber (reg:SI MACL_REG))
7284    (clobber (reg:SI MACH_REG))
7285    (clobber (reg:SI PR_REG))]
7286   "TARGET_SHCOMPACT"
7287   "jsr  @r0%#"
7288   [(set_attr "needs_delay_slot" "yes")])
7289
7290 (define_insn "shmedia_save_restore_regs_compact"
7291   [(set (reg:SI SP_REG)
7292         (plus:SI (reg:SI SP_REG)
7293                  (match_operand:SI 0 "immediate_operand" "i")))
7294    (use (reg:SI R0_REG))
7295    (clobber (reg:SI PR_REG))]
7296   "TARGET_SHCOMPACT
7297    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7298        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7299   "jsr @r0%#"
7300   [(set_attr "needs_delay_slot" "yes")])
7301
7302 (define_expand "prologue"
7303   [(const_int 0)]
7304   ""
7305   "sh_expand_prologue (); DONE;")
7306
7307 (define_expand "epilogue"
7308   [(return)]
7309   ""
7310   "
7311 {
7312   sh_expand_epilogue ();
7313   emit_jump_insn (gen_return ());
7314   DONE;
7315 }")
7316
7317 (define_expand "eh_return"
7318   [(use (match_operand 0 "register_operand" ""))]
7319   ""
7320 {
7321   rtx tmp, ra = operands[0];
7322
7323   if (TARGET_SHMEDIA64)
7324     emit_insn (gen_eh_set_ra_di (ra));
7325   else
7326     emit_insn (gen_eh_set_ra_si (ra));
7327
7328   DONE;
7329 })
7330
7331 ;; Clobber the return address on the stack.  We can't expand this
7332 ;; until we know where it will be put in the stack frame.
7333
7334 (define_insn "eh_set_ra_si"
7335   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7336    (clobber (match_scratch:SI 1 "=&r"))]
7337   "! TARGET_SHMEDIA64"
7338   "#")
7339
7340 (define_insn "eh_set_ra_di"
7341   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7342    (clobber (match_scratch:DI 1 "=&r"))]
7343   "TARGET_SHMEDIA64"
7344   "#")
7345
7346 (define_split
7347   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7348    (clobber (match_scratch 1 ""))]
7349   "reload_completed"
7350   [(const_int 0)]
7351   "
7352 {
7353   sh_set_return_address (operands[0], operands[1]);
7354   DONE;
7355 }")
7356
7357 (define_insn "blockage"
7358   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7359   ""
7360   ""
7361   [(set_attr "length" "0")])
7362 \f
7363 ;; ------------------------------------------------------------------------
7364 ;; Scc instructions
7365 ;; ------------------------------------------------------------------------
7366
7367 (define_insn "movt"
7368   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7369         (eq:SI (reg:SI T_REG) (const_int 1)))]
7370   "TARGET_SH1"
7371   "movt %0"
7372   [(set_attr "type" "arith")])
7373
7374 (define_expand "seq"
7375   [(set (match_operand:SI 0 "arith_reg_operand" "")
7376         (match_dup 1))]
7377   ""
7378   "
7379 {
7380   if (TARGET_SHMEDIA)
7381     {
7382       if (GET_MODE (operands[0]) != DImode)
7383         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7384       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7385       if (sh_compare_op1 != const0_rtx)
7386         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7387                                     ? GET_MODE (sh_compare_op0)
7388                                     : GET_MODE (sh_compare_op1),
7389                                     sh_compare_op1);
7390
7391       switch (GET_MODE (sh_compare_op0))
7392         {
7393         case DImode:
7394           emit_insn (gen_cmpeqdi_media (operands[0],
7395                                         sh_compare_op0, sh_compare_op1));
7396           break;
7397
7398         case SFmode:
7399           if (! TARGET_SHMEDIA_FPU)
7400             FAIL;
7401           emit_insn (gen_cmpeqsf_media (operands[0],
7402                                         sh_compare_op0, sh_compare_op1));
7403           break;
7404
7405         case DFmode:
7406           if (! TARGET_SHMEDIA_FPU)
7407             FAIL;
7408           emit_insn (gen_cmpeqdf_media (operands[0],
7409                                         sh_compare_op0, sh_compare_op1));
7410           break;
7411
7412         default:
7413           FAIL;
7414         }
7415       DONE;
7416     }
7417   operands[1] = prepare_scc_operands (EQ);
7418 }")
7419
7420 (define_expand "slt"
7421   [(set (match_operand:SI 0 "arith_reg_operand" "")
7422         (match_dup 1))]
7423   ""
7424   "
7425 {
7426   if (TARGET_SHMEDIA)
7427     {
7428       if (GET_MODE (operands[0]) != DImode)
7429         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7430       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7431       if (sh_compare_op1 != const0_rtx)
7432         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7433                                     ? GET_MODE (sh_compare_op0)
7434                                     : GET_MODE (sh_compare_op1),
7435                                     sh_compare_op1);
7436
7437       switch (GET_MODE (sh_compare_op0))
7438         {
7439         case DImode:
7440           emit_insn (gen_cmpgtdi_media (operands[0],
7441                                         sh_compare_op1, sh_compare_op0));
7442           break;
7443
7444         case SFmode:
7445           if (! TARGET_SHMEDIA_FPU)
7446             FAIL;
7447           emit_insn (gen_cmpgtsf_media (operands[0],
7448                                         sh_compare_op1, sh_compare_op0));
7449           break;
7450
7451         case DFmode:
7452           if (! TARGET_SHMEDIA_FPU)
7453             FAIL;
7454           emit_insn (gen_cmpgtdf_media (operands[0],
7455                                         sh_compare_op1, sh_compare_op0));
7456           break;
7457
7458         default:
7459           FAIL;
7460         }
7461       DONE;
7462     }
7463   operands[1] = prepare_scc_operands (LT);
7464 }")
7465
7466 (define_expand "sle"
7467   [(match_operand:SI 0 "arith_reg_operand" "")]
7468   ""
7469   "
7470 {
7471   rtx tmp = sh_compare_op0;
7472
7473   if (TARGET_SHMEDIA)
7474     {
7475       if (GET_MODE (operands[0]) != DImode)
7476         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7477       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7478       if (sh_compare_op1 != const0_rtx)
7479         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7480                                     ? GET_MODE (sh_compare_op0)
7481                                     : GET_MODE (sh_compare_op1),
7482                                     sh_compare_op1);
7483
7484       switch (GET_MODE (sh_compare_op0))
7485         {
7486         case DImode:
7487           {
7488             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7489
7490             emit_insn (gen_cmpgtdi_media (tmp,
7491                                           sh_compare_op0, sh_compare_op1));
7492             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7493             break;
7494           }
7495
7496         case SFmode:
7497           if (! TARGET_SHMEDIA_FPU)
7498             FAIL;
7499           emit_insn (gen_cmpgesf_media (operands[0],
7500                                         sh_compare_op1, sh_compare_op0));
7501           break;
7502
7503         case DFmode:
7504           if (! TARGET_SHMEDIA_FPU)
7505             FAIL;
7506           emit_insn (gen_cmpgedf_media (operands[0],
7507                                         sh_compare_op1, sh_compare_op0));
7508           break;
7509
7510         default:
7511           FAIL;
7512         }
7513       DONE;
7514     }
7515
7516   sh_compare_op0 = sh_compare_op1;
7517   sh_compare_op1 = tmp;
7518   emit_insn (gen_sge (operands[0]));
7519   DONE;
7520 }")
7521
7522 (define_expand "sgt"
7523   [(set (match_operand:SI 0 "arith_reg_operand" "")
7524         (match_dup 1))]
7525   ""
7526   "
7527 {
7528   if (TARGET_SHMEDIA)
7529     {
7530       if (GET_MODE (operands[0]) != DImode)
7531         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7532       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7533       if (sh_compare_op1 != const0_rtx)
7534         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7535                                     ? GET_MODE (sh_compare_op0)
7536                                     : GET_MODE (sh_compare_op1),
7537                                     sh_compare_op1);
7538
7539       switch (GET_MODE (sh_compare_op0))
7540         {
7541         case DImode:
7542           emit_insn (gen_cmpgtdi_media (operands[0],
7543                                         sh_compare_op0, sh_compare_op1));
7544           break;
7545
7546         case SFmode:
7547           if (! TARGET_SHMEDIA_FPU)
7548             FAIL;
7549           emit_insn (gen_cmpgtsf_media (operands[0],
7550                                         sh_compare_op0, sh_compare_op1));
7551           break;
7552
7553         case DFmode:
7554           if (! TARGET_SHMEDIA_FPU)
7555             FAIL;
7556           emit_insn (gen_cmpgtdf_media (operands[0],
7557                                         sh_compare_op0, sh_compare_op1));
7558           break;
7559
7560         default:
7561           FAIL;
7562         }
7563       DONE;
7564     }
7565   operands[1] = prepare_scc_operands (GT);
7566 }")
7567
7568 (define_expand "sge"
7569   [(set (match_operand:SI 0 "arith_reg_operand" "")
7570         (match_dup 1))]
7571   ""
7572   "
7573 {
7574   if (TARGET_SHMEDIA)
7575     {
7576       if (GET_MODE (operands[0]) != DImode)
7577         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7578       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7579       if (sh_compare_op1 != const0_rtx)
7580         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7581                                     ? GET_MODE (sh_compare_op0)
7582                                     : GET_MODE (sh_compare_op1),
7583                                     sh_compare_op1);
7584
7585       switch (GET_MODE (sh_compare_op0))
7586         {
7587         case DImode:
7588           {
7589             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7590
7591             emit_insn (gen_cmpgtdi_media (tmp,
7592                                           sh_compare_op1, sh_compare_op0));
7593             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7594             break;
7595           }
7596
7597         case SFmode:
7598           if (! TARGET_SHMEDIA_FPU)
7599             FAIL;
7600           emit_insn (gen_cmpgesf_media (operands[0],
7601                                         sh_compare_op0, sh_compare_op1));
7602           break;
7603
7604         case DFmode:
7605           if (! TARGET_SHMEDIA_FPU)
7606             FAIL;
7607           emit_insn (gen_cmpgedf_media (operands[0],
7608                                         sh_compare_op0, sh_compare_op1));
7609           break;
7610
7611         default:
7612           FAIL;
7613         }
7614       DONE;
7615     }
7616
7617   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7618     {
7619       if (TARGET_IEEE)
7620         {
7621           rtx lab = gen_label_rtx ();
7622           prepare_scc_operands (EQ);
7623           emit_jump_insn (gen_branch_true (lab));
7624           prepare_scc_operands (GT);
7625           emit_label (lab);
7626           emit_insn (gen_movt (operands[0]));
7627         }
7628       else
7629         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7630       DONE;
7631     }
7632   operands[1] = prepare_scc_operands (GE);
7633 }")
7634
7635 (define_expand "sgtu"
7636   [(set (match_operand:SI 0 "arith_reg_operand" "")
7637         (match_dup 1))]
7638   ""
7639   "
7640 {
7641   if (TARGET_SHMEDIA)
7642     {
7643       if (GET_MODE (operands[0]) != DImode)
7644         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7645       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7646       if (sh_compare_op1 != const0_rtx)
7647         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7648                                     ? GET_MODE (sh_compare_op0)
7649                                     : GET_MODE (sh_compare_op1),
7650                                     sh_compare_op1);
7651
7652       emit_insn (gen_cmpgtudi_media (operands[0],
7653                                      sh_compare_op0, sh_compare_op1));
7654       DONE;
7655     }
7656   operands[1] = prepare_scc_operands (GTU);
7657 }")
7658
7659 (define_expand "sltu"
7660   [(set (match_operand:SI 0 "arith_reg_operand" "")
7661         (match_dup 1))]
7662   ""
7663   "
7664 {
7665   if (TARGET_SHMEDIA)
7666     {
7667       if (GET_MODE (operands[0]) != DImode)
7668         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7669       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7670       if (sh_compare_op1 != const0_rtx)
7671         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7672                                     ? GET_MODE (sh_compare_op0)
7673                                     : GET_MODE (sh_compare_op1),
7674                                     sh_compare_op1);
7675
7676       emit_insn (gen_cmpgtudi_media (operands[0],
7677                                      sh_compare_op1, sh_compare_op0));
7678       DONE;
7679     }
7680   operands[1] = prepare_scc_operands (LTU);
7681 }")
7682
7683 (define_expand "sleu"
7684   [(set (match_operand:SI 0 "arith_reg_operand" "")
7685         (match_dup 1))]
7686   ""
7687   "
7688 {
7689   if (TARGET_SHMEDIA)
7690     {
7691       rtx tmp;
7692
7693       if (GET_MODE (operands[0]) != DImode)
7694         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7695       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7696       if (sh_compare_op1 != const0_rtx)
7697         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7698                                     ? GET_MODE (sh_compare_op0)
7699                                     : GET_MODE (sh_compare_op1),
7700                                     sh_compare_op1);
7701
7702       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7703
7704       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7705       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7706
7707       DONE;
7708     }
7709   operands[1] = prepare_scc_operands (LEU);
7710 }")
7711
7712 (define_expand "sgeu"
7713   [(set (match_operand:SI 0 "arith_reg_operand" "")
7714         (match_dup 1))]
7715   ""
7716   "
7717 {
7718   if (TARGET_SHMEDIA)
7719     {
7720       rtx tmp;
7721
7722       if (GET_MODE (operands[0]) != DImode)
7723         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7724       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7725       if (sh_compare_op1 != const0_rtx)
7726         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7727                                     ? GET_MODE (sh_compare_op0)
7728                                     : GET_MODE (sh_compare_op1),
7729                                     sh_compare_op1);
7730
7731       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7732
7733       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7734       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7735
7736       DONE;
7737     }
7738
7739   operands[1] = prepare_scc_operands (GEU);
7740 }")
7741
7742 ;; sne moves the complement of the T reg to DEST like this:
7743 ;;      cmp/eq ...
7744 ;;      mov    #-1,temp
7745 ;;      negc   temp,dest
7746 ;;   This is better than xoring compare result with 1 because it does
7747 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7748 ;;   loop.
7749
7750 (define_expand "sne"
7751   [(set (match_dup 2) (const_int -1))
7752    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7753                    (neg:SI (plus:SI (match_dup 1)
7754                                     (match_dup 2))))
7755               (set (reg:SI T_REG)
7756                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7757                           (const_int 0)))])]
7758   ""
7759   "
7760 {
7761   if (TARGET_SHMEDIA)
7762     {
7763       rtx tmp;
7764
7765       if (GET_MODE (operands[0]) != DImode)
7766         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7767
7768       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7769         FAIL;
7770
7771       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7772       if (sh_compare_op1 != const0_rtx)
7773         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7774                                     ? GET_MODE (sh_compare_op0)
7775                                     : GET_MODE (sh_compare_op1),
7776                                     sh_compare_op1);
7777
7778       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7779
7780       emit_insn (gen_seq (tmp));
7781       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7782
7783       DONE;
7784     }
7785
7786    operands[1] = prepare_scc_operands (EQ);
7787    operands[2] = gen_reg_rtx (SImode);
7788 }")
7789
7790 (define_expand "sunordered"
7791   [(set (match_operand:DI 0 "arith_reg_operand" "")
7792         (unordered:DI (match_dup 1) (match_dup 2)))]
7793   "TARGET_SHMEDIA_FPU"
7794   "
7795 {
7796   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7797   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7798 }")
7799
7800 ;; Use the same trick for FP sle / sge
7801 (define_expand "movnegt"
7802   [(set (match_dup 2) (const_int -1))
7803    (parallel [(set (match_operand 0 "" "")
7804                    (neg:SI (plus:SI (match_dup 1)
7805                                     (match_dup 2))))
7806               (set (reg:SI T_REG)
7807                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7808                           (const_int 0)))])]
7809   "TARGET_SH1"
7810   "operands[2] = gen_reg_rtx (SImode);")
7811
7812 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7813 ;; This prevents a regression that occurred when we switched from xor to
7814 ;; mov/neg for sne.
7815
7816 (define_split
7817   [(set (match_operand:SI 0 "arith_reg_operand" "")
7818         (plus:SI (reg:SI T_REG)
7819                  (const_int -1)))]
7820   "TARGET_SH1"
7821   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7822    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7823   "")
7824
7825 ;; -------------------------------------------------------------------------
7826 ;; Instructions to cope with inline literal tables
7827 ;; -------------------------------------------------------------------------
7828
7829 ; 2 byte integer in line
7830
7831 (define_insn "consttable_2"
7832  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7833                     (match_operand 1 "" "")]
7834                    UNSPECV_CONST2)]
7835  ""
7836  "*
7837 {
7838   if (operands[1] != const0_rtx)
7839     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7840   return \"\";
7841 }"
7842  [(set_attr "length" "2")
7843  (set_attr "in_delay_slot" "no")])
7844
7845 ; 4 byte integer in line
7846
7847 (define_insn "consttable_4"
7848  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7849                     (match_operand 1 "" "")]
7850                    UNSPECV_CONST4)]
7851  ""
7852  "*
7853 {
7854   if (operands[1] != const0_rtx)
7855     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7856   return \"\";
7857 }"
7858  [(set_attr "length" "4")
7859   (set_attr "in_delay_slot" "no")])
7860
7861 ; 8 byte integer in line
7862
7863 (define_insn "consttable_8"
7864  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7865                     (match_operand 1 "" "")]
7866                    UNSPECV_CONST8)]
7867  ""
7868  "*
7869 {
7870   if (operands[1] != const0_rtx)
7871     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7872   return \"\";
7873 }"
7874  [(set_attr "length" "8")
7875   (set_attr "in_delay_slot" "no")])
7876
7877 ; 4 byte floating point
7878
7879 (define_insn "consttable_sf"
7880  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7881                     (match_operand 1 "" "")]
7882                    UNSPECV_CONST4)]
7883  ""
7884  "*
7885 {
7886   if (operands[1] != const0_rtx)
7887     {
7888       REAL_VALUE_TYPE d;
7889       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7890       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7891     }
7892   return \"\";
7893 }"
7894  [(set_attr "length" "4")
7895   (set_attr "in_delay_slot" "no")])
7896
7897 ; 8 byte floating point
7898
7899 (define_insn "consttable_df"
7900  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7901                     (match_operand 1 "" "")]
7902                    UNSPECV_CONST8)]
7903  ""
7904  "*
7905 {
7906   if (operands[1] != const0_rtx)
7907     {
7908       REAL_VALUE_TYPE d;
7909       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7910       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7911     }
7912   return \"\";
7913 }"
7914  [(set_attr "length" "8")
7915   (set_attr "in_delay_slot" "no")])
7916
7917 ;; Alignment is needed for some constant tables; it may also be added for
7918 ;; Instructions at the start of loops, or after unconditional branches.
7919 ;; ??? We would get more accurate lengths if we did instruction
7920 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7921 ;; here is too conservative.
7922
7923 ; align to a two byte boundary
7924
7925 (define_expand "align_2"
7926  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7927  ""
7928  "")
7929
7930 ; align to a four byte boundary
7931 ;; align_4 and align_log are instructions for the starts of loops, or
7932 ;; after unconditional branches, which may take up extra room.
7933
7934 (define_expand "align_4"
7935  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7936  ""
7937  "")
7938
7939 ; align to a cache line boundary
7940
7941 (define_insn "align_log"
7942  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7943  ""
7944  ""
7945  [(set_attr "length" "0")
7946   (set_attr "in_delay_slot" "no")])
7947
7948 ; emitted at the end of the literal table, used to emit the
7949 ; 32bit branch labels if needed.
7950
7951 (define_insn "consttable_end"
7952   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7953   ""
7954   "* return output_jump_label_table ();"
7955   [(set_attr "in_delay_slot" "no")])
7956
7957 ; emitted at the end of the window in the literal table.
7958
7959 (define_insn "consttable_window_end"
7960   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7961   ""
7962   ""
7963   [(set_attr "length" "0")
7964    (set_attr "in_delay_slot" "no")])
7965
7966 ;; -------------------------------------------------------------------------
7967 ;; Misc
7968 ;; -------------------------------------------------------------------------
7969
7970 ;; String/block move insn.
7971
7972 (define_expand "movstrsi"
7973   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7974                    (mem:BLK (match_operand:BLK 1 "" "")))
7975               (use (match_operand:SI 2 "nonmemory_operand" ""))
7976               (use (match_operand:SI 3 "immediate_operand" ""))
7977               (clobber (reg:SI PR_REG))
7978               (clobber (reg:SI R4_REG))
7979               (clobber (reg:SI R5_REG))
7980               (clobber (reg:SI R0_REG))])]
7981   "TARGET_SH1 && ! TARGET_SH5"
7982   "
7983 {
7984   if(expand_block_move (operands))
7985      DONE;
7986   else FAIL;
7987 }")
7988
7989 (define_insn "block_move_real"
7990   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7991                    (mem:BLK (reg:SI R5_REG)))
7992               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7993               (clobber (reg:SI PR_REG))
7994               (clobber (reg:SI R0_REG))])]
7995   "TARGET_SH1 && ! TARGET_HARD_SH4"
7996   "jsr  @%0%#"
7997   [(set_attr "type" "sfunc")
7998    (set_attr "needs_delay_slot" "yes")])
7999
8000 (define_insn "block_lump_real"
8001   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8002                    (mem:BLK (reg:SI R5_REG)))
8003               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8004               (use (reg:SI R6_REG))
8005               (clobber (reg:SI PR_REG))
8006               (clobber (reg:SI T_REG))
8007               (clobber (reg:SI R4_REG))
8008               (clobber (reg:SI R5_REG))
8009               (clobber (reg:SI R6_REG))
8010               (clobber (reg:SI R0_REG))])]
8011   "TARGET_SH1 && ! TARGET_HARD_SH4"
8012   "jsr  @%0%#"
8013   [(set_attr "type" "sfunc")
8014    (set_attr "needs_delay_slot" "yes")])
8015
8016 (define_insn "block_move_real_i4"
8017   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8018                    (mem:BLK (reg:SI R5_REG)))
8019               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8020               (clobber (reg:SI PR_REG))
8021               (clobber (reg:SI R0_REG))
8022               (clobber (reg:SI R1_REG))
8023               (clobber (reg:SI R2_REG))])]
8024   "TARGET_HARD_SH4"
8025   "jsr  @%0%#"
8026   [(set_attr "type" "sfunc")
8027    (set_attr "needs_delay_slot" "yes")])
8028
8029 (define_insn "block_lump_real_i4"
8030   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8031                    (mem:BLK (reg:SI R5_REG)))
8032               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8033               (use (reg:SI R6_REG))
8034               (clobber (reg:SI PR_REG))
8035               (clobber (reg:SI T_REG))
8036               (clobber (reg:SI R4_REG))
8037               (clobber (reg:SI R5_REG))
8038               (clobber (reg:SI R6_REG))
8039               (clobber (reg:SI R0_REG))
8040               (clobber (reg:SI R1_REG))
8041               (clobber (reg:SI R2_REG))
8042               (clobber (reg:SI R3_REG))])]
8043   "TARGET_HARD_SH4"
8044   "jsr  @%0%#"
8045   [(set_attr "type" "sfunc")
8046    (set_attr "needs_delay_slot" "yes")])
8047 \f
8048 ;; -------------------------------------------------------------------------
8049 ;; Floating point instructions.
8050 ;; -------------------------------------------------------------------------
8051
8052 ;; ??? All patterns should have a type attribute.
8053
8054 (define_expand "fpu_switch0"
8055   [(set (match_operand:SI 0 "" "") (match_dup 2))
8056    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8057   "TARGET_SH4"
8058   "
8059 {
8060   operands[1] = get_fpscr_rtx ();
8061   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8062   if (flag_pic)
8063     operands[2] = legitimize_pic_address (operands[2], SImode,
8064                                           no_new_pseudos ? operands[0] : 0);
8065 }")
8066
8067 (define_expand "fpu_switch1"
8068   [(set (match_operand:SI 0 "" "") (match_dup 2))
8069    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8070    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8071   "TARGET_SH4"
8072   "
8073 {
8074   operands[1] = get_fpscr_rtx ();
8075   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8076   if (flag_pic)
8077     operands[2] = legitimize_pic_address (operands[2], SImode,
8078                                           no_new_pseudos ? operands[0] : 0);
8079   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8080 }")
8081
8082 (define_expand "movpsi"
8083   [(set (match_operand:PSI 0 "register_operand" "")
8084         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8085   "TARGET_SH4"
8086   "")
8087
8088 ;; The c / m alternative is a fake to guide reload to load directly into
8089 ;; fpscr, since reload doesn't know how to use post-increment.
8090 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8091 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8092 ;; predicate after reload.
8093 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8094 ;; like a mac -> gpr move.
8095 (define_insn "fpu_switch"
8096   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8097         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8098   "TARGET_SH3E
8099    && (! reload_completed
8100        || true_regnum (operands[0]) != FPSCR_REG
8101        || GET_CODE (operands[1]) != MEM
8102        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8103   "@
8104         ! precision stays the same
8105         lds.l   %1,fpscr
8106         mov.l   %1,%0
8107         #
8108         lds     %1,fpscr
8109         mov     %1,%0
8110         mov.l   %1,%0
8111         sts     fpscr,%0
8112         sts.l   fpscr,%0"
8113   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8114    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8115
8116 (define_split
8117   [(set (reg:PSI FPSCR_REG)
8118         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8119   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8120   [(set (match_dup 0) (match_dup 0))]
8121   "
8122 {
8123   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8124                                         gen_rtx (MEM, PSImode,
8125                                                  gen_rtx (POST_INC, Pmode,
8126                                                           operands[0]))));
8127   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8128 }")
8129
8130 (define_split
8131   [(set (reg:PSI FPSCR_REG)
8132         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8133   "TARGET_SH4"
8134   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8135   "
8136 {
8137   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8138                                         gen_rtx (MEM, PSImode,
8139                                                  gen_rtx (POST_INC, Pmode,
8140                                                           operands[0]))));
8141   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8142 }")
8143
8144 ;; ??? This uses the fp unit, but has no type indicating that.
8145 ;; If we did that, this would either give a bogus latency or introduce
8146 ;; a bogus FIFO constraint.
8147 ;; Since this insn is currently only used for prologues/epilogues,
8148 ;; it is probably best to claim no function unit, which matches the
8149 ;; current setting.
8150 (define_insn "toggle_sz"
8151   [(set (reg:PSI FPSCR_REG)
8152         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8153   "TARGET_SH4"
8154   "fschg")
8155
8156 (define_expand "addsf3"
8157   [(set (match_operand:SF 0 "arith_reg_operand" "")
8158         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8159                  (match_operand:SF 2 "arith_reg_operand" "")))]
8160   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8161   "
8162 {
8163   if (TARGET_SH2E)
8164     {
8165       expand_sf_binop (&gen_addsf3_i, operands);
8166       DONE;
8167     }
8168 }")
8169
8170 (define_insn "*addsf3_media"
8171   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8172         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8173                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8174   "TARGET_SHMEDIA_FPU"
8175   "fadd.s       %1, %2, %0"
8176   [(set_attr "type" "fparith_media")])
8177
8178 (define_insn_and_split "unary_sf_op"
8179   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8180         (vec_select:V2SF
8181          (vec_concat:V2SF
8182           (vec_select:SF
8183            (match_dup 0)
8184            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8185           (match_operator:SF 2 "unary_float_operator"
8186             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8187                             (parallel [(match_operand 4
8188                                         "const_int_operand" "n")]))]))
8189          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8190   "TARGET_SHMEDIA_FPU"
8191   "#"
8192   "TARGET_SHMEDIA_FPU && reload_completed"
8193   [(set (match_dup 5) (match_dup 6))]
8194   "
8195 {
8196   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8197   rtx op1 = gen_rtx_REG (SFmode,
8198                          (true_regnum (operands[1])
8199                           + (INTVAL (operands[4]) ^ endian)));
8200
8201   operands[7] = gen_rtx_REG (SFmode,
8202                              (true_regnum (operands[0])
8203                               + (INTVAL (operands[3]) ^ endian)));
8204   operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8205 }"
8206   [(set_attr "type" "fparith_media")])
8207
8208 (define_insn_and_split "binary_sf_op"
8209   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8210         (vec_select:V2SF
8211          (vec_concat:V2SF
8212           (vec_select:SF
8213            (match_dup 0)
8214            (parallel [(match_operand 7 "const_int_operand" "n")]))
8215           (match_operator:SF 3 "binary_float_operator"
8216             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8217                             (parallel [(match_operand 5
8218                                         "const_int_operand" "n")]))
8219              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8220                             (parallel [(match_operand 6
8221                                         "const_int_operand" "n")]))]))
8222          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8223   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8224   "#"
8225   "&& reload_completed"
8226   [(set (match_dup 8) (match_dup 9))]
8227   "
8228 {
8229   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8230   rtx op1 = gen_rtx_REG (SFmode,
8231                          (true_regnum (operands[1])
8232                           + (INTVAL (operands[5]) ^ endian)));
8233   rtx op2 = gen_rtx_REG (SFmode,
8234                          (true_regnum (operands[2])
8235                           + (INTVAL (operands[6]) ^ endian)));
8236
8237   operands[8] = gen_rtx_REG (SFmode,
8238                              (true_regnum (operands[0])
8239                               + (INTVAL (operands[4]) ^ endian)));
8240   operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8241 }"
8242   [(set_attr "type" "fparith_media")])
8243
8244 (define_insn "addsf3_i"
8245   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8246         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8247                  (match_operand:SF 2 "arith_reg_operand" "f")))
8248    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8249   "TARGET_SH2E"
8250   "fadd %2,%0"
8251   [(set_attr "type" "fp")
8252    (set_attr "fp_mode" "single")])
8253
8254 (define_expand "subsf3"
8255   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8256         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8257                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8258   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8259   "
8260 {
8261   if (TARGET_SH2E)
8262     {
8263       expand_sf_binop (&gen_subsf3_i, operands);
8264       DONE;
8265     }
8266 }")
8267
8268 (define_insn "*subsf3_media"
8269   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8270         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8271                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8272   "TARGET_SHMEDIA_FPU"
8273   "fsub.s       %1, %2, %0"
8274   [(set_attr "type" "fparith_media")])
8275
8276 (define_insn "subsf3_i"
8277   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8278         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8279                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8280    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8281   "TARGET_SH2E"
8282   "fsub %2,%0"
8283   [(set_attr "type" "fp")
8284    (set_attr "fp_mode" "single")])
8285
8286 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8287 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8288 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8289 ;; SH3E, we use a separate insn for SH3E mulsf3.
8290
8291 (define_expand "mulsf3"
8292   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8293         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8294                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8295   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8296   "
8297 {
8298   if (TARGET_SH4)
8299     expand_sf_binop (&gen_mulsf3_i4, operands);
8300   else if (TARGET_SH2E)
8301     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8302   if (! TARGET_SHMEDIA)
8303     DONE;
8304 }")
8305
8306 (define_insn "*mulsf3_media"
8307   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8308         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8309                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8310   "TARGET_SHMEDIA_FPU"
8311   "fmul.s       %1, %2, %0"
8312   [(set_attr "type" "fparith_media")])
8313
8314 (define_insn "mulsf3_i4"
8315   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8316         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8317                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8318    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8319   "TARGET_SH2E"
8320   "fmul %2,%0"
8321   [(set_attr "type" "fp")
8322    (set_attr "fp_mode" "single")])
8323
8324 (define_insn "mulsf3_ie"
8325   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8326         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8327                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8328   "TARGET_SH2E && ! TARGET_SH4"
8329   "fmul %2,%0"
8330   [(set_attr "type" "fp")])
8331
8332 (define_insn "*mac_media"
8333   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8334         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8335                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8336                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8337   "TARGET_SHMEDIA_FPU"
8338   "fmac.s %1, %2, %0"
8339   [(set_attr "type" "fparith_media")])
8340
8341 (define_insn "*macsf3"
8342   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8343         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8344                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8345                  (match_operand:SF 3 "arith_reg_operand" "0")))
8346    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8347   "TARGET_SH2E && ! TARGET_SH4"
8348   "fmac fr0,%2,%0"
8349   [(set_attr "type" "fp")
8350    (set_attr "fp_mode" "single")])
8351
8352 (define_expand "divsf3"
8353   [(set (match_operand:SF 0 "arith_reg_operand" "")
8354         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8355                 (match_operand:SF 2 "arith_reg_operand" "")))]
8356   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8357   "
8358 {
8359   if (TARGET_SH2E)
8360     {
8361       expand_sf_binop (&gen_divsf3_i, operands);
8362       DONE;
8363     }
8364 }")
8365
8366 (define_insn "*divsf3_media"
8367   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8368         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8369                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8370   "TARGET_SHMEDIA_FPU"
8371   "fdiv.s       %1, %2, %0"
8372   [(set_attr "type" "fdiv_media")])
8373
8374 (define_insn "divsf3_i"
8375   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8376         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8377                  (match_operand:SF 2 "arith_reg_operand" "f")))
8378    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8379   "TARGET_SH2E"
8380   "fdiv %2,%0"
8381   [(set_attr "type" "fdiv")
8382    (set_attr "fp_mode" "single")])
8383
8384 (define_insn "floatdisf2"
8385   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8386         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8387   "TARGET_SHMEDIA_FPU"
8388   "float.qs %1, %0"
8389   [(set_attr "type" "fpconv_media")])
8390
8391 (define_expand "floatsisf2"
8392   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8393         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8394   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8395   "
8396 {
8397   if (TARGET_SH4)
8398     {
8399       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8400       DONE;
8401     }
8402 }")
8403
8404 (define_insn "*floatsisf2_media"
8405   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8406         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8407   "TARGET_SHMEDIA_FPU"
8408   "float.ls     %1, %0"
8409   [(set_attr "type" "fpconv_media")])
8410
8411 (define_insn "floatsisf2_i4"
8412   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8413         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8414    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8415   "TARGET_SH4"
8416   "float        %1,%0"
8417   [(set_attr "type" "fp")
8418    (set_attr "fp_mode" "single")])
8419
8420 (define_insn "*floatsisf2_ie"
8421   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8422         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8423   "TARGET_SH2E && ! TARGET_SH4"
8424   "float        %1,%0"
8425   [(set_attr "type" "fp")])
8426
8427 (define_insn "fix_truncsfdi2"
8428   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8429         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8430   "TARGET_SHMEDIA_FPU"
8431   "ftrc.sq %1, %0"
8432   [(set_attr "type" "fpconv_media")])
8433
8434 (define_expand "fix_truncsfsi2"
8435   [(set (match_operand:SI 0 "fpul_operand" "=y")
8436         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8437   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8438   "
8439 {
8440   if (TARGET_SH4)
8441     {
8442       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8443       DONE;
8444     }
8445 }")
8446
8447 (define_insn "*fix_truncsfsi2_media"
8448   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8449         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8450   "TARGET_SHMEDIA_FPU"
8451   "ftrc.sl      %1, %0"
8452   [(set_attr "type" "fpconv_media")])
8453
8454 (define_insn "fix_truncsfsi2_i4"
8455   [(set (match_operand:SI 0 "fpul_operand" "=y")
8456         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8457    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8458   "TARGET_SH4"
8459   "ftrc %1,%0"
8460   [(set_attr "type" "ftrc_s")
8461    (set_attr "fp_mode" "single")])
8462
8463 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8464 ;; fix_truncsfsi2_i4.
8465 ;; (define_insn "fix_truncsfsi2_i4_2"
8466 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8467 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8468 ;;   (use (reg:PSI FPSCR_REG))
8469 ;;   (clobber (reg:SI FPUL_REG))]
8470 ;;  "TARGET_SH4"
8471 ;;  "#"
8472 ;;  [(set_attr "length" "4")
8473 ;;   (set_attr "fp_mode" "single")])
8474
8475 ;;(define_split
8476 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8477 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8478 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8479 ;;   (clobber (reg:SI FPUL_REG))]
8480 ;;  "TARGET_SH4"
8481 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8482 ;;            (use (match_dup 2))])
8483 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8484
8485 (define_insn "*fixsfsi"
8486   [(set (match_operand:SI 0 "fpul_operand" "=y")
8487         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8488   "TARGET_SH2E && ! TARGET_SH4"
8489   "ftrc %1,%0"
8490   [(set_attr "type" "fp")])
8491
8492 (define_insn "cmpgtsf_t"
8493   [(set (reg:SI T_REG)
8494         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8495                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8496   "TARGET_SH2E && ! TARGET_SH4"
8497   "fcmp/gt      %1,%0"
8498   [(set_attr "type" "fp")
8499    (set_attr "fp_mode" "single")])
8500
8501 (define_insn "cmpeqsf_t"
8502   [(set (reg:SI T_REG)
8503         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8504                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8505   "TARGET_SH2E && ! TARGET_SH4"
8506   "fcmp/eq      %1,%0"
8507   [(set_attr "type" "fp")
8508    (set_attr "fp_mode" "single")])
8509
8510 (define_insn "ieee_ccmpeqsf_t"
8511   [(set (reg:SI T_REG)
8512         (ior:SI (reg:SI T_REG)
8513                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8514                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8515   "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8516   "* return output_ieee_ccmpeq (insn, operands);"
8517   [(set_attr "length" "4")])
8518
8519
8520 (define_insn "cmpgtsf_t_i4"
8521   [(set (reg:SI T_REG)
8522         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8523                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8524    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8525   "TARGET_SH4"
8526   "fcmp/gt      %1,%0"
8527   [(set_attr "type" "fp")
8528    (set_attr "fp_mode" "single")])
8529
8530 (define_insn "cmpeqsf_t_i4"
8531   [(set (reg:SI T_REG)
8532         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8533                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8534    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8535   "TARGET_SH4"
8536   "fcmp/eq      %1,%0"
8537   [(set_attr "type" "fp")
8538    (set_attr "fp_mode" "single")])
8539
8540 (define_insn "*ieee_ccmpeqsf_t_4"
8541   [(set (reg:SI T_REG)
8542         (ior:SI (reg:SI T_REG)
8543                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8544                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8545    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8546   "TARGET_IEEE && TARGET_SH4"
8547   "* return output_ieee_ccmpeq (insn, operands);"
8548   [(set_attr "length" "4")
8549    (set_attr "fp_mode" "single")])
8550
8551 (define_insn "cmpeqsf_media"
8552   [(set (match_operand:DI 0 "register_operand" "=r")
8553         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8554                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8555   "TARGET_SHMEDIA_FPU"
8556   "fcmpeq.s     %1, %2, %0"
8557   [(set_attr "type" "fcmp_media")])
8558
8559 (define_insn "cmpgtsf_media"
8560   [(set (match_operand:DI 0 "register_operand" "=r")
8561         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8562                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8563   "TARGET_SHMEDIA_FPU"
8564   "fcmpgt.s     %1, %2, %0"
8565   [(set_attr "type" "fcmp_media")])
8566
8567 (define_insn "cmpgesf_media"
8568   [(set (match_operand:DI 0 "register_operand" "=r")
8569         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8570                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8571   "TARGET_SHMEDIA_FPU"
8572   "fcmpge.s     %1, %2, %0"
8573   [(set_attr "type" "fcmp_media")])
8574
8575 (define_insn "cmpunsf_media"
8576   [(set (match_operand:DI 0 "register_operand" "=r")
8577         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8578                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8579   "TARGET_SHMEDIA_FPU"
8580   "fcmpun.s     %1, %2, %0"
8581   [(set_attr "type" "fcmp_media")])
8582
8583 (define_expand "cmpsf"
8584   [(set (reg:SI T_REG)
8585         (compare (match_operand:SF 0 "arith_operand" "")
8586                  (match_operand:SF 1 "arith_operand" "")))]
8587   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8588   "
8589 {
8590   sh_compare_op0 = operands[0];
8591   sh_compare_op1 = operands[1];
8592   DONE;
8593 }")
8594
8595 (define_expand "negsf2"
8596   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8597         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8598   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8599   "
8600 {
8601   if (TARGET_SH2E)
8602     {
8603       expand_sf_unop (&gen_negsf2_i, operands);
8604       DONE;
8605     }
8606 }")
8607
8608 (define_insn "*negsf2_media"
8609   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8610         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8611   "TARGET_SHMEDIA_FPU"
8612   "fneg.s       %1, %0"
8613   [(set_attr "type" "fmove_media")])
8614
8615 (define_insn "negsf2_i"
8616   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8617         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8618    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8619   "TARGET_SH2E"
8620   "fneg %0"
8621   [(set_attr "type" "fmove")
8622    (set_attr "fp_mode" "single")])
8623
8624 (define_expand "sqrtsf2"
8625   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8626         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8627   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8628   "
8629 {
8630   if (TARGET_SH3E)
8631     {
8632       expand_sf_unop (&gen_sqrtsf2_i, operands);
8633       DONE;
8634     }
8635 }")
8636
8637 (define_insn "*sqrtsf2_media"
8638   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8639         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8640   "TARGET_SHMEDIA_FPU"
8641   "fsqrt.s      %1, %0"
8642   [(set_attr "type" "fdiv_media")])
8643
8644 (define_insn "sqrtsf2_i"
8645   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8646         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8647    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8648   "TARGET_SH3E"
8649   "fsqrt        %0"
8650   [(set_attr "type" "fdiv")
8651    (set_attr "fp_mode" "single")])
8652
8653 (define_expand "abssf2"
8654   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8655         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8656   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8657   "
8658 {
8659   if (TARGET_SH2E)
8660     {
8661       expand_sf_unop (&gen_abssf2_i, operands);
8662       DONE;
8663     }
8664 }")
8665
8666 (define_insn "*abssf2_media"
8667   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8668         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8669   "TARGET_SHMEDIA_FPU"
8670   "fabs.s       %1, %0"
8671   [(set_attr "type" "fmove_media")])
8672
8673 (define_insn "abssf2_i"
8674   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8675         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8676    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8677   "TARGET_SH2E"
8678   "fabs %0"
8679   [(set_attr "type" "fmove")
8680    (set_attr "fp_mode" "single")])
8681
8682 (define_expand "adddf3"
8683   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8684         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8685                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8686   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8687   "
8688 {
8689   if (TARGET_SH4)
8690     {
8691       expand_df_binop (&gen_adddf3_i, operands);
8692       DONE;
8693     }
8694 }")
8695
8696 (define_insn "*adddf3_media"
8697   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8698         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8699                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8700   "TARGET_SHMEDIA_FPU"
8701   "fadd.d       %1, %2, %0"
8702   [(set_attr "type" "dfparith_media")])
8703
8704 (define_insn "adddf3_i"
8705   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8706         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8707                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8708    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8709   "TARGET_SH4"
8710   "fadd %2,%0"
8711   [(set_attr "type" "dfp_arith")
8712    (set_attr "fp_mode" "double")])
8713
8714 (define_expand "subdf3"
8715   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8716         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8717                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8718   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8719   "
8720 {
8721   if (TARGET_SH4)
8722     {
8723       expand_df_binop (&gen_subdf3_i, operands);
8724       DONE;
8725     }
8726 }")
8727
8728 (define_insn "*subdf3_media"
8729   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8730         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8731                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8732   "TARGET_SHMEDIA_FPU"
8733   "fsub.d       %1, %2, %0"
8734   [(set_attr "type" "dfparith_media")])
8735
8736 (define_insn "subdf3_i"
8737   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8738         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8739                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8740    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8741   "TARGET_SH4"
8742   "fsub %2,%0"
8743   [(set_attr "type" "dfp_arith")
8744    (set_attr "fp_mode" "double")])
8745
8746 (define_expand "muldf3"
8747   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8748         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8749                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8750   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8751   "
8752 {
8753   if (TARGET_SH4)
8754     {
8755       expand_df_binop (&gen_muldf3_i, operands);
8756       DONE;
8757     }
8758 }")
8759
8760 (define_insn "*muldf3_media"
8761   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8762         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8763                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8764   "TARGET_SHMEDIA_FPU"
8765   "fmul.d       %1, %2, %0"
8766   [(set_attr "type" "dfmul_media")])
8767
8768 (define_insn "muldf3_i"
8769   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8770         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8771                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8772    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8773   "TARGET_SH4"
8774   "fmul %2,%0"
8775   [(set_attr "type" "dfp_arith")
8776    (set_attr "fp_mode" "double")])
8777
8778 (define_expand "divdf3"
8779   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8780         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8781                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8782   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8783   "
8784 {
8785   if (TARGET_SH4)
8786     {
8787       expand_df_binop (&gen_divdf3_i, operands);
8788       DONE;
8789     }
8790 }")
8791
8792 (define_insn "*divdf3_media"
8793   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8794         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8795                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8796   "TARGET_SHMEDIA_FPU"
8797   "fdiv.d       %1, %2, %0"
8798   [(set_attr "type" "dfdiv_media")])
8799
8800 (define_insn "divdf3_i"
8801   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8802         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8803                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8804    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8805   "TARGET_SH4"
8806   "fdiv %2,%0"
8807   [(set_attr "type" "dfdiv")
8808    (set_attr "fp_mode" "double")])
8809
8810 (define_insn "floatdidf2"
8811   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8812         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8813   "TARGET_SHMEDIA_FPU"
8814   "float.qd     %1, %0"
8815   [(set_attr "type" "dfpconv_media")])
8816
8817 (define_expand "floatsidf2"
8818   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8819         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8820   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8821   "
8822 {
8823   if (TARGET_SH4)
8824     {
8825       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8826                                       get_fpscr_rtx ()));
8827       DONE;
8828     }
8829 }")
8830
8831 (define_insn "*floatsidf2_media"
8832   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8833         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8834   "TARGET_SHMEDIA_FPU"
8835   "float.ld     %1, %0"
8836   [(set_attr "type" "dfpconv_media")])
8837
8838 (define_insn "floatsidf2_i"
8839   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8840         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8841    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8842   "TARGET_SH4"
8843   "float        %1,%0"
8844   [(set_attr "type" "dfp_conv")
8845    (set_attr "fp_mode" "double")])
8846
8847 (define_insn "fix_truncdfdi2"
8848   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8849         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8850   "TARGET_SHMEDIA_FPU"
8851   "ftrc.dq      %1, %0"
8852   [(set_attr "type" "dfpconv_media")])
8853
8854 (define_expand "fix_truncdfsi2"
8855   [(set (match_operand:SI 0 "fpul_operand" "")
8856         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8857   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8858   "
8859 {
8860   if (TARGET_SH4)
8861     {
8862       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8863                                           get_fpscr_rtx ()));
8864       DONE;
8865     }
8866 }")
8867
8868 (define_insn "*fix_truncdfsi2_media"
8869   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8870         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8871   "TARGET_SHMEDIA_FPU"
8872   "ftrc.dl      %1, %0"
8873   [(set_attr "type" "dfpconv_media")])
8874
8875 (define_insn "fix_truncdfsi2_i"
8876   [(set (match_operand:SI 0 "fpul_operand" "=y")
8877         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8878    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8879   "TARGET_SH4"
8880   "ftrc %1,%0"
8881   [(set_attr "type" "dfp_conv")
8882    (set_attr "dfp_comp" "no")
8883    (set_attr "fp_mode" "double")])
8884
8885 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8886 ;; fix_truncdfsi2_i.
8887 ;; (define_insn "fix_truncdfsi2_i4"
8888 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8889 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8890 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8891 ;;    (clobber (reg:SI FPUL_REG))]
8892 ;;   "TARGET_SH4"
8893 ;;   "#"
8894 ;;   [(set_attr "length" "4")
8895 ;;    (set_attr "fp_mode" "double")])
8896 ;;
8897 ;; (define_split
8898 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8899 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8900 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8901 ;;    (clobber (reg:SI FPUL_REG))]
8902 ;;   "TARGET_SH4"
8903 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8904 ;;            (use (match_dup 2))])
8905 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
8906
8907 (define_insn "cmpgtdf_t"
8908   [(set (reg:SI T_REG)
8909         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8910                (match_operand:DF 1 "arith_reg_operand" "f")))
8911    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8912   "TARGET_SH4"
8913   "fcmp/gt      %1,%0"
8914   [(set_attr "type" "dfp_cmp")
8915    (set_attr "fp_mode" "double")])
8916
8917 (define_insn "cmpeqdf_t"
8918   [(set (reg:SI T_REG)
8919         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8920                (match_operand:DF 1 "arith_reg_operand" "f")))
8921    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8922   "TARGET_SH4"
8923   "fcmp/eq      %1,%0"
8924   [(set_attr "type" "dfp_cmp")
8925    (set_attr "fp_mode" "double")])
8926
8927 (define_insn "*ieee_ccmpeqdf_t"
8928   [(set (reg:SI T_REG)
8929         (ior:SI (reg:SI T_REG)
8930                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8931                        (match_operand:DF 1 "arith_reg_operand" "f"))))
8932    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8933   "TARGET_IEEE && TARGET_SH4"
8934   "* return output_ieee_ccmpeq (insn, operands);"
8935   [(set_attr "length" "4")
8936    (set_attr "fp_mode" "double")])
8937
8938 (define_insn "cmpeqdf_media"
8939   [(set (match_operand:DI 0 "register_operand" "=r")
8940         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8941                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8942   "TARGET_SHMEDIA_FPU"
8943   "fcmpeq.d     %1,%2,%0"
8944   [(set_attr "type" "fcmp_media")])
8945
8946 (define_insn "cmpgtdf_media"
8947   [(set (match_operand:DI 0 "register_operand" "=r")
8948         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8949                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8950   "TARGET_SHMEDIA_FPU"
8951   "fcmpgt.d     %1,%2,%0"
8952   [(set_attr "type" "fcmp_media")])
8953
8954 (define_insn "cmpgedf_media"
8955   [(set (match_operand:DI 0 "register_operand" "=r")
8956         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8957                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8958   "TARGET_SHMEDIA_FPU"
8959   "fcmpge.d     %1,%2,%0"
8960   [(set_attr "type" "fcmp_media")])
8961
8962 (define_insn "cmpundf_media"
8963   [(set (match_operand:DI 0 "register_operand" "=r")
8964         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8965                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8966   "TARGET_SHMEDIA_FPU"
8967   "fcmpun.d     %1,%2,%0"
8968   [(set_attr "type" "fcmp_media")])
8969
8970 (define_expand "cmpdf"
8971   [(set (reg:SI T_REG)
8972         (compare (match_operand:DF 0 "arith_operand" "")
8973                  (match_operand:DF 1 "arith_operand" "")))]
8974   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8975   "
8976 {
8977   sh_compare_op0 = operands[0];
8978   sh_compare_op1 = operands[1];
8979   DONE;
8980 }")
8981
8982 (define_expand "negdf2"
8983   [(set (match_operand:DF 0 "arith_reg_operand" "")
8984         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8985   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8986   "
8987 {
8988   if (TARGET_SH4)
8989     {
8990       expand_df_unop (&gen_negdf2_i, operands);
8991       DONE;
8992     }
8993 }")
8994
8995 (define_insn "*negdf2_media"
8996   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8997         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8998   "TARGET_SHMEDIA_FPU"
8999   "fneg.d       %1, %0"
9000   [(set_attr "type" "fmove_media")])
9001
9002 (define_insn "negdf2_i"
9003   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9004         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9005    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9006   "TARGET_SH4"
9007   "fneg %0"
9008   [(set_attr "type" "fmove")
9009    (set_attr "fp_mode" "double")])
9010
9011 (define_expand "sqrtdf2"
9012   [(set (match_operand:DF 0 "arith_reg_operand" "")
9013         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9014   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9015   "
9016 {
9017   if (TARGET_SH4)
9018     {
9019       expand_df_unop (&gen_sqrtdf2_i, operands);
9020       DONE;
9021     }
9022 }")
9023
9024 (define_insn "*sqrtdf2_media"
9025   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9026         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9027   "TARGET_SHMEDIA_FPU"
9028   "fsqrt.d      %1, %0"
9029   [(set_attr "type" "dfdiv_media")])
9030
9031 (define_insn "sqrtdf2_i"
9032   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9033         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9034    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9035   "TARGET_SH4"
9036   "fsqrt        %0"
9037   [(set_attr "type" "dfdiv")
9038    (set_attr "fp_mode" "double")])
9039
9040 (define_expand "absdf2"
9041   [(set (match_operand:DF 0 "arith_reg_operand" "")
9042         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9043   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9044   "
9045 {
9046   if (TARGET_SH4)
9047     {
9048       expand_df_unop (&gen_absdf2_i, operands);
9049       DONE;
9050     }
9051 }")
9052
9053 (define_insn "*absdf2_media"
9054   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9055         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9056   "TARGET_SHMEDIA_FPU"
9057   "fabs.d       %1, %0"
9058   [(set_attr "type" "fmove_media")])
9059
9060 (define_insn "absdf2_i"
9061   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9062         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9063    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9064   "TARGET_SH4"
9065   "fabs %0"
9066   [(set_attr "type" "fmove")
9067    (set_attr "fp_mode" "double")])
9068
9069 (define_expand "extendsfdf2"
9070   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9071         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9072   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9073   "
9074 {
9075   if (TARGET_SH4)
9076     {
9077       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9078                                         get_fpscr_rtx ()));
9079       DONE;
9080     }
9081 }")
9082
9083 (define_insn "*extendsfdf2_media"
9084   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9085         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9086   "TARGET_SHMEDIA_FPU"
9087   "fcnv.sd      %1, %0"
9088   [(set_attr "type" "dfpconv_media")])
9089
9090 (define_insn "extendsfdf2_i4"
9091   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9092         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9093    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9094   "TARGET_SH4"
9095   "fcnvsd  %1,%0"
9096   [(set_attr "type" "fp")
9097    (set_attr "fp_mode" "double")])
9098
9099 (define_expand "truncdfsf2"
9100   [(set (match_operand:SF 0 "fpul_operand" "")
9101         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9102   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9103   "
9104 {
9105   if (TARGET_SH4)
9106     {
9107       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9108                                        get_fpscr_rtx ()));
9109       DONE;
9110     }
9111 }")
9112
9113 (define_insn "*truncdfsf2_media"
9114   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9115         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9116   "TARGET_SHMEDIA_FPU"
9117   "fcnv.ds      %1, %0"
9118   [(set_attr "type" "dfpconv_media")])
9119
9120 (define_insn "truncdfsf2_i4"
9121   [(set (match_operand:SF 0 "fpul_operand" "=y")
9122         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9123    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9124   "TARGET_SH4"
9125   "fcnvds  %1,%0"
9126   [(set_attr "type" "fp")
9127    (set_attr "fp_mode" "double")])
9128 \f
9129 ;; Bit field extract patterns.  These give better code for packed bitfields,
9130 ;; because they allow auto-increment addresses to be generated.
9131
9132 (define_expand "insv"
9133   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9134                          (match_operand:SI 1 "immediate_operand" "")
9135                          (match_operand:SI 2 "immediate_operand" ""))
9136         (match_operand:SI 3 "general_operand" ""))]
9137   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9138   "
9139 {
9140   rtx addr_target, orig_address, shift_reg, qi_val;
9141   HOST_WIDE_INT bitsize, size, v;
9142   rtx x = operands[3];
9143
9144   /* ??? expmed doesn't care for non-register predicates.  */
9145   if (! memory_operand (operands[0], VOIDmode)
9146       || ! immediate_operand (operands[1], VOIDmode)
9147       || ! immediate_operand (operands[2], VOIDmode)
9148       || ! general_operand (x, VOIDmode))
9149     FAIL;
9150   /* If this isn't a 16 / 24 / 32 bit field, or if
9151      it doesn't start on a byte boundary, then fail.  */
9152   bitsize = INTVAL (operands[1]);
9153   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9154       || (INTVAL (operands[2]) % 8) != 0)
9155     FAIL;
9156
9157   size = bitsize / 8;
9158   orig_address = XEXP (operands[0], 0);
9159   shift_reg = gen_reg_rtx (SImode);
9160   if (GET_CODE (x) == CONST_INT)
9161     {
9162       v = INTVAL (x);
9163       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9164     }
9165   else
9166     {
9167       emit_insn (gen_movsi (shift_reg, operands[3]));
9168       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9169     }
9170   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9171
9172   operands[0] = replace_equiv_address (operands[0], addr_target);
9173   emit_insn (gen_movqi (operands[0], qi_val));
9174
9175   while (size -= 1)
9176     {
9177       if (GET_CODE (x) == CONST_INT)
9178         qi_val
9179           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9180       else
9181         {
9182           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9183           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9184         }
9185       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9186       emit_insn (gen_movqi (operands[0], qi_val));
9187     }
9188
9189   DONE;
9190 }")
9191 \f
9192 ;; -------------------------------------------------------------------------
9193 ;; Peepholes
9194 ;; -------------------------------------------------------------------------
9195
9196 ;; This matches cases where a stack pointer increment at the start of the
9197 ;; epilogue combines with a stack slot read loading the return value.
9198
9199 (define_peephole
9200   [(set (match_operand:SI 0 "arith_reg_operand" "")
9201         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9202    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9203   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9204   "mov.l        @%1+,%0")
9205
9206 ;; See the comment on the dt combiner pattern above.
9207
9208 (define_peephole
9209   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9210         (plus:SI (match_dup 0)
9211                  (const_int -1)))
9212    (set (reg:SI T_REG)
9213         (eq:SI (match_dup 0)
9214                (const_int 0)))]
9215   "TARGET_SH2"
9216   "dt   %0")
9217
9218 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9219 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9220 ;; reload when the constant is too large for a reg+offset address.
9221
9222 ;; ??? We would get much better code if this was done in reload.  This would
9223 ;; require modifying find_reloads_address to recognize that if the constant
9224 ;; is out-of-range for an immediate add, then we get better code by reloading
9225 ;; the constant into a register than by reloading the sum into a register,
9226 ;; since the former is one instruction shorter if the address does not need
9227 ;; to be offsettable.  Unfortunately this does not work, because there is
9228 ;; only one register, r0, that can be used as an index register.  This register
9229 ;; is also the function return value register.  So, if we try to force reload
9230 ;; to use double-reg addresses, then we end up with some instructions that
9231 ;; need to use r0 twice.  The only way to fix this is to change the calling
9232 ;; convention so that r0 is not used to return values.
9233
9234 (define_peephole
9235   [(set (match_operand:SI 0 "register_operand" "=r")
9236         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9237    (set (mem:SI (match_dup 0))
9238         (match_operand:SI 2 "general_movsrc_operand" ""))]
9239   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9240   "mov.l        %2,@(%0,%1)")
9241
9242 (define_peephole
9243   [(set (match_operand:SI 0 "register_operand" "=r")
9244         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9245    (set (match_operand:SI 2 "general_movdst_operand" "")
9246         (mem:SI (match_dup 0)))]
9247   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9248   "mov.l        @(%0,%1),%2")
9249
9250 (define_peephole
9251   [(set (match_operand:SI 0 "register_operand" "=r")
9252         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9253    (set (mem:HI (match_dup 0))
9254         (match_operand:HI 2 "general_movsrc_operand" ""))]
9255   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9256   "mov.w        %2,@(%0,%1)")
9257
9258 (define_peephole
9259   [(set (match_operand:SI 0 "register_operand" "=r")
9260         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9261    (set (match_operand:HI 2 "general_movdst_operand" "")
9262         (mem:HI (match_dup 0)))]
9263   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9264   "mov.w        @(%0,%1),%2")
9265
9266 (define_peephole
9267   [(set (match_operand:SI 0 "register_operand" "=r")
9268         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9269    (set (mem:QI (match_dup 0))
9270         (match_operand:QI 2 "general_movsrc_operand" ""))]
9271   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9272   "mov.b        %2,@(%0,%1)")
9273
9274 (define_peephole
9275   [(set (match_operand:SI 0 "register_operand" "=r")
9276         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9277    (set (match_operand:QI 2 "general_movdst_operand" "")
9278         (mem:QI (match_dup 0)))]
9279   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9280   "mov.b        @(%0,%1),%2")
9281
9282 (define_peephole
9283   [(set (match_operand:SI 0 "register_operand" "=r")
9284         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9285    (set (mem:SF (match_dup 0))
9286         (match_operand:SF 2 "general_movsrc_operand" ""))]
9287   "TARGET_SH1 && REGNO (operands[0]) == 0
9288    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9289        || (GET_CODE (operands[2]) == SUBREG
9290            && REGNO (SUBREG_REG (operands[2])) < 16))
9291    && reg_unused_after (operands[0], insn)"
9292   "mov.l        %2,@(%0,%1)")
9293
9294 (define_peephole
9295   [(set (match_operand:SI 0 "register_operand" "=r")
9296         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9297    (set (match_operand:SF 2 "general_movdst_operand" "")
9298
9299         (mem:SF (match_dup 0)))]
9300   "TARGET_SH1 && REGNO (operands[0]) == 0
9301    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9302        || (GET_CODE (operands[2]) == SUBREG
9303            && REGNO (SUBREG_REG (operands[2])) < 16))
9304    && reg_unused_after (operands[0], insn)"
9305   "mov.l        @(%0,%1),%2")
9306
9307 (define_peephole
9308   [(set (match_operand:SI 0 "register_operand" "=r")
9309         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9310    (set (mem:SF (match_dup 0))
9311         (match_operand:SF 2 "general_movsrc_operand" ""))]
9312   "TARGET_SH2E && REGNO (operands[0]) == 0
9313    && ((GET_CODE (operands[2]) == REG
9314         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9315        || (GET_CODE (operands[2]) == SUBREG
9316            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9317    && reg_unused_after (operands[0], insn)"
9318   "fmov{.s|}    %2,@(%0,%1)")
9319
9320 (define_peephole
9321   [(set (match_operand:SI 0 "register_operand" "=r")
9322         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9323    (set (match_operand:SF 2 "general_movdst_operand" "")
9324
9325         (mem:SF (match_dup 0)))]
9326   "TARGET_SH2E && REGNO (operands[0]) == 0
9327    && ((GET_CODE (operands[2]) == REG
9328         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9329        || (GET_CODE (operands[2]) == SUBREG
9330            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9331    && reg_unused_after (operands[0], insn)"
9332   "fmov{.s|}    @(%0,%1),%2")
9333
9334 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9335 (define_insn "sp_switch_1"
9336   [(const_int 1)]
9337   "TARGET_SH1"
9338   "*
9339 {
9340   rtx xoperands[1];
9341
9342   xoperands[0] = sp_switch;
9343   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9344   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9345   return \"mov r0,r15\";
9346 }"
9347   [(set_attr "length" "10")])
9348
9349 ;; Switch back to the original stack for interrupt functions with the
9350 ;; sp_switch attribute.  */
9351 (define_insn "sp_switch_2"
9352   [(const_int 2)]
9353   "TARGET_SH1"
9354   "mov.l @r15+,r15\;mov.l @r15+,r0"
9355   [(set_attr "length" "4")])
9356
9357 ;; Integer vector moves
9358
9359 (define_expand "movv8qi"
9360   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9361         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9362   "TARGET_SHMEDIA"
9363   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9364
9365 (define_insn "movv8qi_i"
9366   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9367         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9368   "TARGET_SHMEDIA
9369    && (register_operand (operands[0], V8QImode)
9370        || sh_register_operand (operands[1], V8QImode))"
9371   "@
9372         add     %1, r63, %0
9373         movi    %1, %0
9374         #
9375         ld%M1.q %m1, %0
9376         st%M0.q %m0, %N1"
9377   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9378    (set_attr "length" "4,4,16,4,4")])
9379
9380 (define_split
9381   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9382         (subreg:V8QI (const_int 0) 0))]
9383   "TARGET_SHMEDIA"
9384   [(set (match_dup 0)
9385         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9386                             (const_int 0) (const_int 0) (const_int 0)
9387                             (const_int 0) (const_int 0)]))])
9388
9389 (define_split
9390   [(set (match_operand 0 "arith_reg_dest" "")
9391         (match_operand 1 "sh_rep_vec" ""))]
9392   "TARGET_SHMEDIA && reload_completed
9393    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9394    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9395    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9396    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9397        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9398    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9399        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9400   [(set (match_dup 0) (match_dup 1))
9401    (match_dup 2)]
9402   "
9403 {
9404   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9405   rtx elt1 = XVECEXP (operands[1], 0, 1);
9406
9407   if (unit_size > 2)
9408     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9409   else
9410     {
9411       if (unit_size < 2)
9412         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9413       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9414     }
9415   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9416   operands[1] = XVECEXP (operands[1], 0, 0);
9417   if (unit_size < 2)
9418     {
9419       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9420         operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9421                                ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9422                                : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9423       else
9424         {
9425           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9426           operands[1]
9427             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9428         }
9429     }
9430 }")
9431
9432 (define_split
9433   [(set (match_operand 0 "arith_reg_dest" "")
9434         (match_operand 1 "sh_const_vec" ""))]
9435   "TARGET_SHMEDIA && reload_completed
9436    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9437    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9438    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9439   [(set (match_dup 0) (match_dup 1))]
9440   "
9441 {
9442   rtx v = operands[1];
9443   enum machine_mode new_mode
9444     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9445
9446   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9447   operands[1]
9448     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9449 }")
9450
9451 (define_expand "movv2hi"
9452   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9453         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9454   "TARGET_SHMEDIA"
9455   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9456
9457 (define_insn "movv2hi_i"
9458   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9459         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9460   "TARGET_SHMEDIA
9461    && (register_operand (operands[0], V2HImode)
9462        || sh_register_operand (operands[1], V2HImode))"
9463   "@
9464         addz.l  %1, r63, %0
9465         movi    %1, %0
9466         #
9467         ld%M1.l %m1, %0
9468         st%M0.l %m0, %N1"
9469   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9470    (set_attr "length" "4,4,16,4,4")])
9471
9472 (define_expand "movv4hi"
9473   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9474         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9475   "TARGET_SHMEDIA"
9476   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9477
9478 (define_insn "movv4hi_i"
9479   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9480         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9481   "TARGET_SHMEDIA
9482    && (register_operand (operands[0], V4HImode)
9483        || sh_register_operand (operands[1], V4HImode))"
9484   "@
9485         add     %1, r63, %0
9486         movi    %1, %0
9487         #
9488         ld%M1.q %m1, %0
9489         st%M0.q %m0, %N1"
9490   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9491    (set_attr "length" "4,4,16,4,4")])
9492
9493 (define_expand "movv2si"
9494   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9495         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9496   "TARGET_SHMEDIA"
9497   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9498
9499 (define_insn "movv2si_i"
9500   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9501         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9502   "TARGET_SHMEDIA
9503    && (register_operand (operands[0], V2SImode)
9504        || sh_register_operand (operands[1], V2SImode))"
9505   "@
9506         add     %1, r63, %0
9507         #
9508         #
9509         ld%M1.q %m1, %0
9510         st%M0.q %m0, %N1"
9511   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9512    (set_attr "length" "4,4,16,4,4")])
9513
9514 ;; Multimedia Intrinsics
9515
9516 (define_insn "absv2si2"
9517   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9518         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9519   "TARGET_SHMEDIA"
9520   "mabs.l       %1, %0"
9521   [(set_attr "type" "mcmp_media")])
9522
9523 (define_insn "absv4hi2"
9524   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9525         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9526   "TARGET_SHMEDIA"
9527   "mabs.w       %1, %0"
9528   [(set_attr "type" "mcmp_media")])
9529
9530 (define_insn "addv2si3"
9531   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9532         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9533                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9534   "TARGET_SHMEDIA"
9535   "madd.l       %1, %2, %0"
9536   [(set_attr "type" "arith_media")])
9537
9538 (define_insn "addv4hi3"
9539   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9540         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9541                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9542   "TARGET_SHMEDIA"
9543   "madd.w       %1, %2, %0"
9544   [(set_attr "type" "arith_media")])
9545
9546 (define_insn "ssaddv2si3"
9547   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9548         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9549                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9550   "TARGET_SHMEDIA"
9551   "madds.l      %1, %2, %0"
9552   [(set_attr "type" "mcmp_media")])
9553
9554 (define_insn "usaddv8qi3"
9555   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9556         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9557                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9558   "TARGET_SHMEDIA"
9559   "madds.ub     %1, %2, %0"
9560   [(set_attr "type" "mcmp_media")])
9561
9562 (define_insn "ssaddv4hi3"
9563   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9564         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9565                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9566   "TARGET_SHMEDIA"
9567   "madds.w      %1, %2, %0"
9568   [(set_attr "type" "mcmp_media")])
9569
9570 (define_insn "negcmpeqv8qi"
9571   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9572         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9573                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9574   "TARGET_SHMEDIA"
9575   "mcmpeq.b     %N1, %N2, %0"
9576   [(set_attr "type" "mcmp_media")])
9577
9578 (define_insn "negcmpeqv2si"
9579   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9580         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9581                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9582   "TARGET_SHMEDIA"
9583   "mcmpeq.l     %N1, %N2, %0"
9584   [(set_attr "type" "mcmp_media")])
9585
9586 (define_insn "negcmpeqv4hi"
9587   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9588         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9589                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9590   "TARGET_SHMEDIA"
9591   "mcmpeq.w     %N1, %N2, %0"
9592   [(set_attr "type" "mcmp_media")])
9593
9594 (define_insn "negcmpgtuv8qi"
9595   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9596         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9597                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9598   "TARGET_SHMEDIA"
9599   "mcmpgt.ub    %N1, %N2, %0"
9600   [(set_attr "type" "mcmp_media")])
9601
9602 (define_insn "negcmpgtv2si"
9603   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9604         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9605                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9606   "TARGET_SHMEDIA"
9607   "mcmpgt.l     %N1, %N2, %0"
9608   [(set_attr "type" "mcmp_media")])
9609
9610 (define_insn "negcmpgtv4hi"
9611   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9612         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9613                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9614   "TARGET_SHMEDIA"
9615   "mcmpgt.w     %N1, %N2, %0"
9616   [(set_attr "type" "mcmp_media")])
9617
9618 (define_insn "mcmv"
9619   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9620         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9621                         (match_operand:DI 2 "arith_reg_operand" "r"))
9622                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9623                         (not:DI (match_dup 2)))))]
9624   "TARGET_SHMEDIA"
9625   "mcmv %N1, %2, %0"
9626   [(set_attr "type" "arith_media")])
9627
9628 (define_insn "mcnvs_lw"
9629   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9630         (vec_concat:V4HI
9631          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9632          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9633   "TARGET_SHMEDIA"
9634   "mcnvs.lw     %N1, %N2, %0"
9635   [(set_attr "type" "mcmp_media")])
9636
9637 (define_insn "mcnvs_wb"
9638   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9639         (vec_concat:V8QI
9640          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9641          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9642   "TARGET_SHMEDIA"
9643   "mcnvs.wb     %N1, %N2, %0"
9644   [(set_attr "type" "mcmp_media")])
9645
9646 (define_insn "mcnvs_wub"
9647   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9648         (vec_concat:V8QI
9649          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9650          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9651   "TARGET_SHMEDIA"
9652   "mcnvs.wub    %N1, %N2, %0"
9653   [(set_attr "type" "mcmp_media")])
9654
9655 (define_insn "mextr_rl"
9656   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9657         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9658                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9659                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9660                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9661   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9662   "*
9663 {
9664   static char templ[16];
9665
9666   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9667            (int) INTVAL (operands[3]) >> 3);
9668   return templ;
9669 }"
9670   [(set_attr "type" "arith_media")])
9671
9672 (define_insn "*mextr_lr"
9673   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9674         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9675                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9676                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9677                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9678   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9679   "*
9680 {
9681   static char templ[16];
9682
9683   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9684            (int) INTVAL (operands[4]) >> 3);
9685   return templ;
9686 }"
9687   [(set_attr "type" "arith_media")])
9688
9689 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9690 ; vector then varies depending on endianness.
9691 (define_expand "mextr1"
9692   [(match_operand:DI 0 "arith_reg_dest" "")
9693    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9694    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9695   "TARGET_SHMEDIA"
9696   "
9697 {
9698   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9699                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9700   DONE;
9701 }")
9702
9703 (define_expand "mextr2"
9704   [(match_operand:DI 0 "arith_reg_dest" "")
9705    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9706    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9707   "TARGET_SHMEDIA"
9708   "
9709 {
9710   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9711                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9712   DONE;
9713 }")
9714
9715 (define_expand "mextr3"
9716   [(match_operand:DI 0 "arith_reg_dest" "")
9717    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9718    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9719   "TARGET_SHMEDIA"
9720   "
9721 {
9722   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9723                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9724   DONE;
9725 }")
9726
9727 (define_expand "mextr4"
9728   [(match_operand:DI 0 "arith_reg_dest" "")
9729    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9730    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9731   "TARGET_SHMEDIA"
9732   "
9733 {
9734   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9735                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9736   DONE;
9737 }")
9738
9739 (define_expand "mextr5"
9740   [(match_operand:DI 0 "arith_reg_dest" "")
9741    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9742    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9743   "TARGET_SHMEDIA"
9744   "
9745 {
9746   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9747                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9748   DONE;
9749 }")
9750
9751 (define_expand "mextr6"
9752   [(match_operand:DI 0 "arith_reg_dest" "")
9753    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9754    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9755   "TARGET_SHMEDIA"
9756   "
9757 {
9758   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9759                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9760   DONE;
9761 }")
9762
9763 (define_expand "mextr7"
9764   [(match_operand:DI 0 "arith_reg_dest" "")
9765    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9766    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9767   "TARGET_SHMEDIA"
9768   "
9769 {
9770   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9771                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9772   DONE;
9773 }")
9774
9775 (define_expand "mmacfx_wl"
9776   [(match_operand:V2SI 0 "arith_reg_dest" "")
9777    (match_operand:V2HI 1 "extend_reg_operand" "")
9778    (match_operand:V2HI 2 "extend_reg_operand" "")
9779    (match_operand:V2SI 3 "arith_reg_operand" "")]
9780   "TARGET_SHMEDIA"
9781   "
9782 {
9783   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9784                               operands[1], operands[2]));
9785   DONE;
9786 }")
9787
9788 (define_insn "mmacfx_wl_i"
9789   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9790         (ss_plus:V2SI
9791          (match_operand:V2SI 1 "arith_reg_operand" "0")
9792          (ss_truncate:V2SI
9793           (ashift:V2DI
9794            (sign_extend:V2DI
9795             (mult:V2SI
9796              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9797              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9798            (const_int 1)))))]
9799   "TARGET_SHMEDIA"
9800   "mmacfx.wl    %2, %3, %0"
9801   [(set_attr "type" "mac_media")])
9802
9803 (define_expand "mmacnfx_wl"
9804   [(match_operand:V2SI 0 "arith_reg_dest" "")
9805    (match_operand:V2HI 1 "extend_reg_operand" "")
9806    (match_operand:V2HI 2 "extend_reg_operand" "")
9807    (match_operand:V2SI 3 "arith_reg_operand" "")]
9808   "TARGET_SHMEDIA"
9809   "
9810 {
9811   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9812                                operands[1], operands[2]));
9813   DONE;
9814 }")
9815
9816 (define_insn "mmacnfx_wl_i"
9817   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9818         (ss_minus:V2SI
9819          (match_operand:V2SI 1 "arith_reg_operand" "0")
9820          (ss_truncate:V2SI
9821           (ashift:V2DI
9822            (sign_extend:V2DI
9823             (mult:V2SI
9824              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9825              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9826            (const_int 1)))))]
9827   "TARGET_SHMEDIA"
9828   "mmacnfx.wl   %2, %3, %0"
9829   [(set_attr "type" "mac_media")])
9830
9831 (define_insn "mulv2si3"
9832   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9833         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9834                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9835   "TARGET_SHMEDIA"
9836   "mmul.l       %1, %2, %0"
9837   [(set_attr "type" "d2mpy_media")])
9838
9839 (define_insn "mulv4hi3"
9840   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9841         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9842                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9843   "TARGET_SHMEDIA"
9844   "mmul.w       %1, %2, %0"
9845   [(set_attr "type" "dmpy_media")])
9846
9847 (define_insn "mmulfx_l"
9848   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9849         (ss_truncate:V2SI
9850          (ashiftrt:V2DI
9851           (mult:V2DI
9852            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9853            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9854           (const_int 31))))]
9855   "TARGET_SHMEDIA"
9856   "mmulfx.l     %1, %2, %0"
9857   [(set_attr "type" "d2mpy_media")])
9858
9859 (define_insn "mmulfx_w"
9860   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9861         (ss_truncate:V4HI
9862          (ashiftrt:V4SI
9863           (mult:V4SI
9864            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9865            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9866           (const_int 15))))]
9867   "TARGET_SHMEDIA"
9868   "mmulfx.w     %1, %2, %0"
9869   [(set_attr "type" "dmpy_media")])
9870
9871 (define_insn "mmulfxrp_w"
9872   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9873         (ss_truncate:V4HI
9874          (ashiftrt:V4SI
9875           (plus:V4SI
9876            (mult:V4SI
9877             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9878             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9879            (const_int 16384))
9880           (const_int 15))))]
9881   "TARGET_SHMEDIA"
9882   "mmulfxrp.w   %1, %2, %0"
9883   [(set_attr "type" "dmpy_media")])
9884
9885 (define_expand "mmulhi_wl"
9886   [(match_operand:V2SI 0 "arith_reg_dest" "")
9887    (match_operand:V4HI 1 "arith_reg_operand" "")
9888    (match_operand:V4HI 2 "arith_reg_operand" "")]
9889   "TARGET_SHMEDIA"
9890   "
9891 {
9892   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9893              (operands[0], operands[1], operands[2]));
9894   DONE;
9895 }")
9896
9897 (define_expand "mmullo_wl"
9898   [(match_operand:V2SI 0 "arith_reg_dest" "")
9899    (match_operand:V4HI 1 "arith_reg_operand" "")
9900    (match_operand:V4HI 2 "arith_reg_operand" "")]
9901   "TARGET_SHMEDIA"
9902   "
9903 {
9904   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9905              (operands[0], operands[1], operands[2]));
9906   DONE;
9907 }")
9908
9909 (define_insn "mmul23_wl"
9910   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9911         (vec_select:V2SI
9912          (mult:V4SI
9913           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9914           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9915          (parallel [(const_int 2) (const_int 3)])))]
9916   "TARGET_SHMEDIA"
9917   "* return (TARGET_LITTLE_ENDIAN
9918              ? \"mmulhi.wl      %1, %2, %0\"
9919              : \"mmullo.wl      %1, %2, %0\");"
9920   [(set_attr "type" "dmpy_media")])
9921
9922 (define_insn "mmul01_wl"
9923   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9924         (vec_select:V2SI
9925          (mult:V4SI
9926           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9927           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9928          (parallel [(const_int 0) (const_int 1)])))]
9929   "TARGET_SHMEDIA"
9930   "* return (TARGET_LITTLE_ENDIAN
9931              ? \"mmullo.wl      %1, %2, %0\"
9932              : \"mmulhi.wl      %1, %2, %0\");"
9933   [(set_attr "type" "dmpy_media")])
9934
9935 (define_expand "mmulsum_wq"
9936   [(match_operand:DI 0 "arith_reg_dest" "")
9937    (match_operand:V4HI 1 "arith_reg_operand" "")
9938    (match_operand:V4HI 2 "arith_reg_operand" "")
9939    (match_operand:DI 3 "arith_reg_operand" "")]
9940   "TARGET_SHMEDIA"
9941   "
9942 {
9943   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9944                                operands[1], operands[2]));
9945   DONE;
9946 }")
9947
9948 (define_insn "mmulsum_wq_i"
9949   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9950         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9951          (plus:DI
9952           (plus:DI
9953            (vec_select:DI
9954             (mult:V4DI
9955              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9956              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9957             (parallel [(const_int 0)]))
9958            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9959                                      (sign_extend:V4DI (match_dup 3)))
9960                           (parallel [(const_int 1)])))
9961           (plus:DI
9962            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9963                                      (sign_extend:V4DI (match_dup 3)))
9964                           (parallel [(const_int 2)]))
9965            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9966                                      (sign_extend:V4DI (match_dup 3)))
9967                           (parallel [(const_int 3)]))))))]
9968   "TARGET_SHMEDIA"
9969   "mmulsum.wq   %2, %3, %0"
9970   [(set_attr "type" "mac_media")])
9971
9972 (define_expand "mperm_w"
9973   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9974    (match_operand:V4HI 1 "arith_reg_operand" "r")
9975    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
9976   "TARGET_SHMEDIA"
9977   "
9978 {
9979   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9980              (operands[0], operands[1], operands[2]));
9981   DONE;
9982 }")
9983
9984 ; This use of vec_select isn't exactly correct according to rtl.texi
9985 ; (because not constant), but it seems a straightforward extension.
9986 (define_insn "mperm_w_little"
9987   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9988         (vec_select:V4HI
9989          (match_operand:V4HI 1 "arith_reg_operand" "r")
9990          (parallel
9991           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
9992                             (const_int 2) (const_int 0))
9993            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9994            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9995            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9996   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9997   "mperm.w      %1, %N2, %0"
9998   [(set_attr "type" "arith_media")])
9999
10000 (define_insn "mperm_w_big"
10001   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10002         (vec_select:V4HI
10003          (match_operand:V4HI 1 "arith_reg_operand" "r")
10004          (parallel
10005           [(zero_extract:QI (not:QI (match_operand:QI 2
10006                                      "extend_reg_or_0_operand" "rZ"))
10007                             (const_int 2) (const_int 0))
10008            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10009            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10010            (zero_extract:QI (not:QI (match_dup 2))
10011                             (const_int 2) (const_int 6))])))]
10012   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10013   "mperm.w      %1, %N2, %0"
10014   [(set_attr "type" "arith_media")])
10015
10016 (define_insn "mperm_w0"
10017   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10018         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10019                                           "trunc_hi_operand" "r"))))]
10020   "TARGET_SHMEDIA"
10021   "mperm.w      %1, r63, %0"
10022   [(set_attr "type" "arith_media")])
10023
10024 (define_expand "msad_ubq"
10025   [(match_operand:DI 0 "arith_reg_dest" "")
10026    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10027    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10028    (match_operand:DI 3 "arith_reg_operand" "")]
10029   "TARGET_SHMEDIA"
10030   "
10031 {
10032   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10033                              operands[1], operands[2]));
10034   DONE;
10035 }")
10036
10037 (define_insn "msad_ubq_i"
10038   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10039         (plus:DI
10040          (plus:DI
10041           (plus:DI
10042            (plus:DI
10043             (match_operand:DI 1 "arith_reg_operand" "0")
10044             (abs:DI (vec_select:DI
10045                      (minus:V8DI
10046                       (zero_extend:V8DI
10047                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10048                       (zero_extend:V8DI
10049                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10050                      (parallel [(const_int 0)]))))
10051            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10052                                               (zero_extend:V8DI (match_dup 3)))
10053                                   (parallel [(const_int 1)]))))
10054           (plus:DI
10055            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10056                                               (zero_extend:V8DI (match_dup 3)))
10057                                   (parallel [(const_int 2)])))
10058            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10059                                               (zero_extend:V8DI (match_dup 3)))
10060                                   (parallel [(const_int 3)])))))
10061          (plus:DI
10062           (plus:DI
10063            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10064                                               (zero_extend:V8DI (match_dup 3)))
10065                                   (parallel [(const_int 4)])))
10066            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10067                                               (zero_extend:V8DI (match_dup 3)))
10068                                   (parallel [(const_int 5)]))))
10069           (plus:DI
10070            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10071                                               (zero_extend:V8DI (match_dup 3)))
10072                                   (parallel [(const_int 6)])))
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 7)])))))))]
10076   "TARGET_SHMEDIA"
10077   "msad.ubq     %N2, %N3, %0"
10078   [(set_attr "type" "mac_media")])
10079
10080 (define_insn "mshalds_l"
10081   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10082         (ss_truncate:V2SI
10083          (ashift:V2DI
10084           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10085           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10086                   (const_int 31)))))]
10087   "TARGET_SHMEDIA"
10088   "mshalds.l    %1, %2, %0"
10089   [(set_attr "type" "mcmp_media")])
10090
10091 (define_insn "mshalds_w"
10092   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10093         (ss_truncate:V4HI
10094          (ashift:V4SI
10095           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10096           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10097                   (const_int 15)))))]
10098   "TARGET_SHMEDIA"
10099   "mshalds.w    %1, %2, %0"
10100   [(set_attr "type" "mcmp_media")])
10101
10102 (define_insn "ashrv2si3"
10103   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10104         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10105                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10106   "TARGET_SHMEDIA"
10107   "mshard.l     %1, %2, %0"
10108   [(set_attr "type" "arith_media")])
10109
10110 (define_insn "ashrv4hi3"
10111   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10112         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10113                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10114   "TARGET_SHMEDIA"
10115   "mshard.w     %1, %2, %0"
10116   [(set_attr "type" "arith_media")])
10117
10118 (define_insn "mshards_q"
10119   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10120         (ss_truncate:HI
10121          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10122                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10123   "TARGET_SHMEDIA"
10124   "mshards.q    %1, %N2, %0"
10125   [(set_attr "type" "mcmp_media")])
10126
10127 (define_expand "mshfhi_b"
10128   [(match_operand:V8QI 0 "arith_reg_dest" "")
10129    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10130    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10131   "TARGET_SHMEDIA"
10132   "
10133 {
10134   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10135              (operands[0], operands[1], operands[2]));
10136   DONE;
10137 }")
10138
10139 (define_expand "mshflo_b"
10140   [(match_operand:V8QI 0 "arith_reg_dest" "")
10141    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10142    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10143   "TARGET_SHMEDIA"
10144   "
10145 {
10146   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10147              (operands[0], operands[1], operands[2]));
10148   DONE;
10149 }")
10150
10151 (define_insn "mshf4_b"
10152   [(set
10153     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10154     (vec_select:V8QI
10155      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10156                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10157      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10158                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10159   "TARGET_SHMEDIA"
10160   "* return (TARGET_LITTLE_ENDIAN
10161              ? \"mshfhi.b       %N1, %N2, %0\"
10162              : \"mshflo.b       %N1, %N2, %0\");"
10163   [(set_attr "type" "arith_media")])
10164
10165 (define_insn "mshf0_b"
10166   [(set
10167     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10168     (vec_select:V8QI
10169      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10170                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10171      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10172                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10173   "TARGET_SHMEDIA"
10174   "* return (TARGET_LITTLE_ENDIAN
10175              ? \"mshflo.b       %N1, %N2, %0\"
10176              : \"mshfhi.b       %N1, %N2, %0\");"
10177   [(set_attr "type" "arith_media")])
10178
10179 (define_expand "mshfhi_l"
10180   [(match_operand:V2SI 0 "arith_reg_dest" "")
10181    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10182    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10183   "TARGET_SHMEDIA"
10184   "
10185 {
10186   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10187              (operands[0], operands[1], operands[2]));
10188   DONE;
10189 }")
10190
10191 (define_expand "mshflo_l"
10192   [(match_operand:V2SI 0 "arith_reg_dest" "")
10193    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10194    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10195   "TARGET_SHMEDIA"
10196   "
10197 {
10198   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10199              (operands[0], operands[1], operands[2]));
10200   DONE;
10201 }")
10202
10203 (define_insn "mshf4_l"
10204   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10205         (vec_select:V2SI
10206          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10207                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10208          (parallel [(const_int 1) (const_int 3)])))]
10209   "TARGET_SHMEDIA"
10210   "* return (TARGET_LITTLE_ENDIAN
10211              ? \"mshfhi.l       %N1, %N2, %0\"
10212              : \"mshflo.l       %N1, %N2, %0\");"
10213   [(set_attr "type" "arith_media")])
10214
10215 (define_insn "mshf0_l"
10216   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10217         (vec_select:V2SI
10218          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10219                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10220          (parallel [(const_int 0) (const_int 2)])))]
10221   "TARGET_SHMEDIA"
10222   "* return (TARGET_LITTLE_ENDIAN
10223              ? \"mshflo.l       %N1, %N2, %0\"
10224              : \"mshfhi.l       %N1, %N2, %0\");"
10225   [(set_attr "type" "arith_media")])
10226
10227 (define_expand "mshfhi_w"
10228   [(match_operand:V4HI 0 "arith_reg_dest" "")
10229    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10230    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10231   "TARGET_SHMEDIA"
10232   "
10233 {
10234   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10235              (operands[0], operands[1], operands[2]));
10236   DONE;
10237 }")
10238
10239 (define_expand "mshflo_w"
10240   [(match_operand:V4HI 0 "arith_reg_dest" "")
10241    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10242    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10243   "TARGET_SHMEDIA"
10244   "
10245 {
10246   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10247              (operands[0], operands[1], operands[2]));
10248   DONE;
10249 }")
10250
10251 (define_insn "mshf4_w"
10252   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10253         (vec_select:V4HI
10254          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10255                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10256          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10257   "TARGET_SHMEDIA"
10258   "* return (TARGET_LITTLE_ENDIAN
10259              ? \"mshfhi.w       %N1, %N2, %0\"
10260              : \"mshflo.w       %N1, %N2, %0\");"
10261   [(set_attr "type" "arith_media")])
10262
10263 (define_insn "mshf0_w"
10264   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10265         (vec_select:V4HI
10266          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10267                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10268          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10269   "TARGET_SHMEDIA"
10270   "* return (TARGET_LITTLE_ENDIAN
10271              ? \"mshflo.w       %N1, %N2, %0\"
10272              : \"mshfhi.w       %N1, %N2, %0\");"
10273   [(set_attr "type" "arith_media")])
10274
10275 (define_insn "mshflo_w_x"
10276   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10277         (vec_select:V4HI
10278          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10279                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10280          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10281   "TARGET_SHMEDIA"
10282   "mshflo.w     %N1, %N2, %0"
10283   [(set_attr "type" "arith_media")])
10284
10285 /* These are useful to expand ANDs and as combiner patterns.  */
10286 (define_insn_and_split "mshfhi_l_di"
10287   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10288         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10289                              (const_int 32))
10290                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10291                         (const_int -4294967296))))]
10292   "TARGET_SHMEDIA"
10293   "@
10294         mshfhi.l        %N1, %N2, %0
10295         #"
10296   "TARGET_SHMEDIA && reload_completed
10297    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10298   [(set (match_dup 3) (match_dup 4))
10299    (set (match_dup 5) (match_dup 6))]
10300   "
10301 {
10302   operands[3] = gen_lowpart (SImode, operands[0]);
10303   operands[4] = gen_highpart (SImode, operands[1]);
10304   operands[5] = gen_highpart (SImode, operands[0]);
10305   operands[6] = gen_highpart (SImode, operands[2]);
10306 }"
10307   [(set_attr "type" "arith_media")])
10308
10309 (define_insn "*mshfhi_l_di_rev"
10310   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10311         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10312                         (const_int -4294967296))
10313                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10314                              (const_int 32))))]
10315   "TARGET_SHMEDIA"
10316   "mshfhi.l     %N2, %N1, %0"
10317   [(set_attr "type" "arith_media")])
10318
10319 (define_split
10320   [(set (match_operand:DI 0 "arith_reg_dest" "")
10321         (ior:DI (zero_extend:DI (match_operand:SI 1
10322                                               "extend_reg_or_0_operand" ""))
10323                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10324                         (const_int -4294967296))))
10325    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10326   "TARGET_SHMEDIA"
10327   [(const_int 0)]
10328   "
10329 {
10330   emit_insn (gen_ashldi3_media (operands[3],
10331                                 simplify_gen_subreg (DImode, operands[1],
10332                                                      SImode, 0),
10333                                 GEN_INT (32)));
10334   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10335   DONE;
10336 }")
10337
10338 (define_insn "mshflo_l_di"
10339   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10340         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10341                         (const_int 4294967295))
10342                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10343                            (const_int 32))))]
10344                                 
10345   "TARGET_SHMEDIA"
10346   "mshflo.l     %N1, %N2, %0"
10347   [(set_attr "type" "arith_media")])
10348
10349 (define_insn "*mshflo_l_di_rev"
10350   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10351         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10352                            (const_int 32))
10353                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10354                         (const_int 4294967295))))]
10355                                 
10356   "TARGET_SHMEDIA"
10357   "mshflo.l     %N2, %N1, %0"
10358   [(set_attr "type" "arith_media")])
10359
10360 ;; Combiner pattern for trampoline initialization.
10361 (define_insn_and_split "*double_shori"
10362   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10363         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10364                            (const_int 32))
10365                 (match_operand:DI 2 "const_int_operand" "n")))]
10366   "TARGET_SHMEDIA
10367    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10368   "#"
10369   "rtx_equal_p (operands[0], operands[1])"
10370   [(const_int 0)]
10371   "
10372 {
10373   HOST_WIDE_INT v = INTVAL (operands[2]);
10374
10375   emit_insn (gen_shori_media (operands[0], operands[0],
10376              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10377   emit_insn (gen_shori_media (operands[0], operands[0],
10378                               gen_int_mode (v, HImode)));
10379   DONE;
10380 }")
10381
10382
10383 (define_insn "*mshflo_l_di_x"
10384   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10385         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10386                                  "rZ"))
10387                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10388                            (const_int 32))))]
10389                                 
10390   "TARGET_SHMEDIA"
10391   "mshflo.l     %N1, %N2, %0"
10392   [(set_attr "type" "arith_media")])
10393
10394 (define_insn_and_split "concat_v2sf"
10395   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10396 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10397         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10398                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10399                                 
10400   "TARGET_SHMEDIA"
10401   "@
10402         mshflo.l        %N1, %N2, %0
10403         #
10404         #"
10405   "TARGET_SHMEDIA && reload_completed
10406    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10407   [(set (match_dup 3) (match_dup 1))
10408    (set (match_dup 4) (match_dup 2))]
10409   "
10410 {
10411   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10412   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10413 }"
10414   [(set_attr "type" "arith_media")])
10415
10416 (define_insn "*mshflo_l_di_x_rev"
10417   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10418         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10419                            (const_int 32))
10420                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10421                                 
10422   "TARGET_SHMEDIA"
10423   "mshflo.l     %N2, %N1, %0"
10424   [(set_attr "type" "arith_media")])
10425
10426 (define_insn "ashlv2si3"
10427   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10428         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10429                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10430   "TARGET_SHMEDIA"
10431   "mshlld.l     %1, %2, %0"
10432   [(set_attr "type" "arith_media")])
10433
10434 (define_insn "ashlv4hi3"
10435   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10436         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10437                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10438   "TARGET_SHMEDIA"
10439   "mshlld.w     %1, %2, %0"
10440   [(set_attr "type" "arith_media")])
10441
10442 (define_insn "lshrv2si3"
10443   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10444         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10445                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10446   "TARGET_SHMEDIA"
10447   "mshlrd.l     %1, %2, %0"
10448   [(set_attr "type" "arith_media")])
10449
10450 (define_insn "lshrv4hi3"
10451   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10452         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10453                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10454   "TARGET_SHMEDIA"
10455   "mshlrd.w     %1, %2, %0"
10456   [(set_attr "type" "arith_media")])
10457
10458 (define_insn "subv2si3"
10459   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10460         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10461                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10462   "TARGET_SHMEDIA"
10463   "msub.l       %N1, %2, %0"
10464   [(set_attr "type" "arith_media")])
10465
10466 (define_insn "subv4hi3"
10467   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10468         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10469                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10470   "TARGET_SHMEDIA"
10471   "msub.w       %N1, %2, %0"
10472   [(set_attr "type" "arith_media")])
10473
10474 (define_insn "sssubv2si3"
10475   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10476         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10477                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10478   "TARGET_SHMEDIA"
10479   "msubs.l      %N1, %2, %0"
10480   [(set_attr "type" "mcmp_media")])
10481
10482 (define_insn "ussubv8qi3"
10483   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10484         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10485                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10486   "TARGET_SHMEDIA"
10487   "msubs.ub     %1, %2, %0"
10488   [(set_attr "type" "mcmp_media")])
10489
10490 (define_insn "sssubv4hi3"
10491   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10492         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10493                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10494   "TARGET_SHMEDIA"
10495   "msubs.w      %N1, %2, %0"
10496   [(set_attr "type" "mcmp_media")])
10497
10498 ;; Floating Point Intrinsics
10499
10500 (define_insn "fcosa_s"
10501   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10502         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10503                    UNSPEC_FCOSA))]
10504   "TARGET_SHMEDIA"
10505   "fcosa.s      %1, %0"
10506   [(set_attr "type" "atrans_media")])
10507
10508 (define_insn "fsina_s"
10509   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10510         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10511                    UNSPEC_FSINA))]
10512   "TARGET_SHMEDIA"
10513   "fsina.s      %1, %0"
10514   [(set_attr "type" "atrans_media")])
10515
10516 (define_insn "fipr"
10517   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10518         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10519                                                     "fp_arith_reg_operand" "f")
10520                                                    (match_operand:V4SF 2
10521                                                     "fp_arith_reg_operand" "f"))
10522                                          (parallel [(const_int 0)]))
10523                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10524                                          (parallel [(const_int 1)])))
10525                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10526                                          (parallel [(const_int 2)]))
10527                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10528                                          (parallel [(const_int 3)])))))]
10529   "TARGET_SHMEDIA"
10530   "fipr %1, %2, %0"
10531   [(set_attr "type" "fparith_media")])
10532
10533 (define_insn "fsrra_s"
10534   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10535         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10536                    UNSPEC_FSRRA))]
10537   "TARGET_SHMEDIA"
10538   "fsrra.s      %1, %0"
10539   [(set_attr "type" "atrans_media")])
10540
10541 (define_insn "ftrv"
10542   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10543         (plus:V4SF
10544          (plus:V4SF
10545           (mult:V4SF
10546            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10547                             (parallel [(const_int 0) (const_int 5)
10548                                        (const_int 10) (const_int 15)]))
10549            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10550           (mult:V4SF
10551            (vec_select:V4SF (match_dup 1)
10552                             (parallel [(const_int 4) (const_int 9)
10553                                        (const_int 14) (const_int 3)]))
10554            (vec_select:V4SF (match_dup 2)
10555                             (parallel [(const_int 1) (const_int 2)
10556                                       (const_int 3) (const_int 0)]))))
10557          (plus:V4SF
10558           (mult:V4SF
10559            (vec_select:V4SF (match_dup 1)
10560                             (parallel [(const_int 8) (const_int 13)
10561                                        (const_int 2) (const_int 7)]))
10562            (vec_select:V4SF (match_dup 2)
10563                             (parallel [(const_int 2) (const_int 3)
10564                                        (const_int 0) (const_int 1)])))
10565           (mult:V4SF
10566            (vec_select:V4SF (match_dup 1)
10567                             (parallel [(const_int 12) (const_int 1)
10568                                        (const_int 6) (const_int 11)]))
10569            (vec_select:V4SF (match_dup 2)
10570                             (parallel [(const_int 3) (const_int 0)
10571                                        (const_int 1) (const_int 2)]))))))]
10572   "TARGET_SHMEDIA"
10573   "ftrv %1, %2, %0"
10574   [(set_attr "type" "fparith_media")])
10575
10576 (define_insn "nsb"
10577   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10578         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10579                    UNSPEC_NSB))]
10580   "TARGET_SHMEDIA"
10581   "nsb  %1, %0"
10582   [(set_attr "type" "arith_media")])
10583
10584 (define_insn "nsbsi"
10585   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10586         (zero_extend:SI
10587          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10588                     UNSPEC_NSB)))]
10589   "TARGET_SHMEDIA"
10590   "nsb  %1, %0"
10591   [(set_attr "type" "arith_media")])
10592
10593 (define_insn "nsbdi"
10594   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10595         (zero_extend:DI
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_expand "ffsdi2"
10603   [(set (match_operand:DI 0 "arith_reg_dest" "")
10604         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10605   "TARGET_SHMEDIA"
10606   "
10607 {
10608   rtx scratch = gen_reg_rtx (DImode);
10609   rtx last;
10610
10611   emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10612   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10613   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10614   emit_insn (gen_nsbdi (scratch, scratch));
10615   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10616   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10617   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10618   REG_NOTES (last)
10619     = gen_rtx_EXPR_LIST (REG_EQUAL,
10620                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10621   DONE;
10622 }")
10623
10624 (define_expand "ffssi2"
10625   [(set (match_operand:SI 0 "arith_reg_dest" "")
10626         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10627   "TARGET_SHMEDIA"
10628   "
10629 {
10630   rtx scratch = gen_reg_rtx (SImode);
10631   rtx discratch = gen_reg_rtx (DImode);
10632   rtx last;
10633
10634   emit_insn (gen_adddi3 (discratch,
10635                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10636                          GEN_INT (-1)));
10637   emit_insn (gen_andcdi3 (discratch,
10638                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10639                           discratch));
10640   emit_insn (gen_nsbsi (scratch, discratch));
10641   last = emit_insn (gen_subsi3 (operands[0],
10642                                 force_reg (SImode, GEN_INT (63)), scratch));
10643   REG_NOTES (last)
10644     = gen_rtx_EXPR_LIST (REG_EQUAL,
10645                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10646   DONE;
10647 }")
10648
10649 (define_insn "byterev"
10650   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10651         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10652                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10653                                     (const_int 4) (const_int 3) (const_int 2)
10654                                     (const_int 1) (const_int 0)])))]
10655   "TARGET_SHMEDIA"
10656   "byterev      %1, %0"
10657   [(set_attr "type" "arith_media")])
10658
10659 ;; The following description  models the
10660 ;; SH4 pipeline using the DFA based scheduler. 
10661 ;; The DFA based description is better way to model 
10662 ;; a superscalar pipeline as compared to function unit
10663 ;; reservation model.   
10664 ;; 1. The function unit based model is oriented to describe at most one 
10665 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple 
10666 ;;    pipeline units by same insn. This can be done using DFA based description.
10667 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10668 ;; 3. Writing all unit reservations for an instruction class is more natural description 
10669 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the 
10670 ;;    old function unit based model.
10671 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10672
10673
10674 ;; Two automata are defined to reduce number of states
10675 ;; which a single large automaton will have.(Factoring)
10676
10677 (define_automaton "inst_pipeline,fpu_pipe")
10678
10679 ;; This unit is basically the decode unit of the processor.
10680 ;; Since SH4 is a dual issue machine,it is as if there are two 
10681 ;; units so that any insn can be processed by either one
10682 ;; of the decoding unit.
10683
10684 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10685
10686
10687 ;; The fixed point arithmetic calculator(?? EX Unit).
10688
10689 (define_cpu_unit  "int" "inst_pipeline")
10690
10691 ;; f1_1 and f1_2 are floating point units.Actually there is
10692 ;; a f1 unit which can overlap with other f1 unit but
10693 ;; not another F1 unit.It is as though there were two
10694 ;; f1 units.
10695
10696 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10697
10698 ;; The floating point units (except FS - F2 always precedes it.)
10699
10700 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10701
10702 ;; This is basically the MA unit of SH4
10703 ;; used in LOAD/STORE pipeline.
10704
10705 (define_cpu_unit "memory" "inst_pipeline")
10706
10707 ;; However, there are LS group insns that don't use it, even ones that
10708 ;; complete in 0 cycles.  So we use an extra unit for the issue of LS insns.
10709 (define_cpu_unit "load_store" "inst_pipeline")
10710
10711 ;; The address calculator used for branch instructions.
10712 ;; This will be reserved after "issue" of branch instructions
10713 ;; and this is to make sure that no two branch instructions 
10714 ;; can be issued in parallel. 
10715
10716 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10717
10718 ;; ----------------------------------------------------
10719 ;; This reservation is to simplify the dual issue description.
10720
10721 (define_reservation  "issue"  "pipe_01|pipe_02")
10722
10723 ;; This is to express the locking of D stage.
10724 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10725
10726 (define_reservation  "d_lock" "pipe_01+pipe_02")
10727
10728 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10729 (define_reservation "F01" "F0+F1")
10730
10731 ;; This is to simplify description where F1,F2,FS
10732 ;; are used simultaneously.
10733
10734 (define_reservation "fpu" "F1+F2")
10735
10736 ;; This is to highlight the fact that f1 
10737 ;; cannot overlap with F1.
10738
10739 (exclusion_set  "f1_1,f1_2" "F1")
10740
10741 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10742
10743 ;; Although reg moves have a latency of zero 
10744 ;; we need to highlight that they use D stage
10745 ;; for one cycle.
10746
10747 ;; Group:       MT
10748
10749 (define_insn_reservation "reg_mov" 0
10750   (and (eq_attr "pipe_model" "sh4")
10751        (eq_attr "type" "move"))
10752   "issue")
10753
10754 ;; Group:       LS
10755
10756 (define_insn_reservation "freg_mov" 0
10757   (and (eq_attr "pipe_model" "sh4")
10758        (eq_attr "type" "fmove"))
10759   "issue+load_store")
10760
10761 ;; We don't model all pipeline stages; we model the issue ('D') stage
10762 ;; inasmuch as we allow only two instructions to issue simultaneously,
10763 ;; and CO instructions prevent any simultaneous issue of another instruction.
10764 ;; (This uses pipe_01 and pipe_02).
10765 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10766 ;; Double issue of EX / BR insns is prevented by using the int unit /
10767 ;; pcr_addrcalc unit in the EX stage.
10768 ;; Double issue of BR / LS instructions is prevented by using the
10769 ;; pcr_addrcalc / load_store unit in the issue cycle.
10770 ;; Double issue of FE instructions is prevented by using F0 in the first
10771 ;; pipeline stage after the first D stage.
10772 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10773 ;; (except in the cases outlined above), nor to describe the FS stage after
10774 ;; the F2 stage.
10775
10776 ;; Other MT  group instructions(1 step operations)
10777 ;; Group:       MT
10778 ;; Latency:     1
10779 ;; Issue Rate:  1
10780
10781 (define_insn_reservation "mt" 1
10782   (and (eq_attr "pipe_model" "sh4")
10783        (eq_attr "type" "mt_group"))
10784   "issue")
10785
10786 ;; Fixed Point Arithmetic Instructions(1 step operations)
10787 ;; Group:       EX
10788 ;; Latency:     1
10789 ;; Issue Rate:  1
10790
10791 (define_insn_reservation "sh4_simple_arith" 1 
10792   (and (eq_attr "pipe_model" "sh4")
10793        (eq_attr "insn_class" "ex_group"))
10794   "issue,int")
10795
10796 ;; Load and store instructions have no alignment peculiarities for the SH4,
10797 ;; but they use the load-store unit, which they share with the fmove type
10798 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10799 ;; Loads have a latency of two.
10800 ;; However, call insns can only paired with a preceding insn, and have
10801 ;; a delay slot, so that we want two more insns to be scheduled between the
10802 ;; load of the function address and the call.  This is equivalent to a
10803 ;; latency of three.
10804 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10805 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10806 ;; We only do this for SImode loads of general registers, to make the work
10807 ;; for ADJUST_COST easier.
10808
10809 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10810 ;; Group:       LS
10811 ;; Latency:     2
10812 ;; Issue Rate:  1
10813
10814 (define_insn_reservation "sh4_load" 2
10815   (and (eq_attr "pipe_model" "sh4")
10816        (eq_attr "type" "load,pcload"))
10817   "issue+load_store,nothing,memory")
10818
10819 ;; calls / sfuncs need an extra instruction for their delay slot.
10820 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10821 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10822 ;; count of a dynamic shift.
10823 (define_insn_reservation "sh4_load_si" 3
10824   (and (eq_attr "pipe_model" "sh4")
10825        (eq_attr "type" "load_si,pcload_si"))
10826   "issue+load_store,nothing,memory")
10827
10828 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10829
10830 ;; The load latency is upped to three higher if the dependent insn does
10831 ;; double precision computation.  We want the 'default' latency to reflect
10832 ;; that increased latency because otherwise the insn priorities won't
10833 ;; allow proper scheduling.
10834 (define_insn_reservation "sh4_fload" 3
10835   (and (eq_attr "pipe_model" "sh4")
10836        (eq_attr "type" "fload,pcfload"))
10837   "issue+load_store,nothing,memory")
10838
10839 ;; (define_bypass 2 "sh4_fload" "!")
10840
10841 (define_insn_reservation "sh4_store" 1
10842   (and (eq_attr "pipe_model" "sh4")
10843        (eq_attr "type" "store"))
10844   "issue+load_store,nothing,memory")
10845
10846 ;; Load Store instructions.
10847 ;; Group:       LS
10848 ;; Latency:     1
10849 ;; Issue Rate:  1
10850
10851 (define_insn_reservation "sh4_gp_fpul" 1
10852   (and (eq_attr "pipe_model" "sh4")
10853        (eq_attr "type" "gp_fpul"))
10854   "issue+load_store")
10855
10856 ;; Load Store instructions.
10857 ;; Group:       LS
10858 ;; Latency:     3
10859 ;; Issue Rate:  1
10860
10861 (define_insn_reservation "sh4_fpul_gp" 3
10862   (and (eq_attr "pipe_model" "sh4")
10863        (eq_attr "type" "fpul_gp"))
10864   "issue+load_store")
10865
10866 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10867 ;; Group:       BR
10868 ;; Latency when taken:  2 (or 1)
10869 ;; Issue Rate:  1
10870 ;; The latency is 1 when displacement is 0.
10871 ;; We can't really do much with the latency, even if we could express it,
10872 ;; but the pairing restrictions are useful to take into account.
10873 ;; ??? If the branch is likely, we might want to fill the delay slot;
10874 ;; if the branch is likely, but not very likely, should we pretend to use
10875 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10876
10877 (define_insn_reservation "sh4_branch"  1
10878   (and (eq_attr "pipe_model" "sh4")
10879        (eq_attr "type" "cbranch,jump"))
10880   "issue+pcr_addrcalc")
10881
10882 ;; Branch Far (JMP,RTS,BRAF)
10883 ;; Group:       CO
10884 ;; Latency:     3
10885 ;; Issue Rate:  2
10886 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10887 ;; can't be distinguished from bra for the "jump" pattern.
10888
10889 (define_insn_reservation "sh4_return" 3
10890   (and (eq_attr "pipe_model" "sh4")
10891        (eq_attr "type" "return,jump_ind"))
10892          "d_lock*2")
10893
10894 ;; RTE
10895 ;; Group:       CO
10896 ;; Latency:     5
10897 ;; Issue Rate:  5
10898 ;; this instruction can be executed in any of the pipelines 
10899 ;; and blocks the pipeline for next 4 stages.
10900
10901 (define_insn_reservation "sh4_return_from_exp" 5
10902   (and (eq_attr "pipe_model" "sh4")
10903        (eq_attr "type" "rte"))
10904   "d_lock*5")
10905
10906 ;; OCBP, OCBWB
10907 ;; Group:       CO
10908 ;; Latency:     1-5
10909 ;; Issue Rate:  1
10910
10911 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10912 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10913 (define_insn_reservation "ocbwb"  6
10914   (and (eq_attr "pipe_model" "sh4")
10915        (eq_attr "type" "cwb"))
10916   "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10917                 
10918 ;; LDS to PR,JSR
10919 ;; Group:       CO
10920 ;; Latency:     3
10921 ;; Issue Rate:  2
10922 ;; The SX stage is blocked for last 2 cycles.
10923 ;; OTOH, the only time that has an effect for insns generated by the compiler
10924 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10925 ;; or when we are doing a function call - and we don't do inter-function
10926 ;; scheduling.  For the function call case, it's really best that we end with
10927 ;; something that models an rts.
10928
10929 (define_insn_reservation "sh4_lds_to_pr" 3 
10930   (and (eq_attr "pipe_model" "sh4")
10931        (eq_attr "type" "prset") )
10932   "d_lock*2")
10933
10934 ;; calls introduce a longisch delay that is likely to flush the pipelines
10935 ;; of the caller's instructions.  Ordinary functions tend to end with a
10936 ;; load to restore a register (in the delay slot of rts), while sfuncs
10937 ;; tend to end with an EX or MT insn.  But that is not actually relevant,
10938 ;; since there are no instructions that contend for memory access early.
10939 ;; We could, of course, provide exact scheduling information for specific
10940 ;; sfuncs, if that should prove useful.
10941
10942 (define_insn_reservation "sh4_call" 16 
10943   (and (eq_attr "pipe_model" "sh4")
10944        (eq_attr "type" "call,sfunc"))
10945   "d_lock*16")
10946
10947 ;; LDS.L to PR 
10948 ;; Group:       CO
10949 ;; Latency:     3
10950 ;; Issue Rate:  2
10951 ;; The SX unit is blocked for last 2 cycles.
10952  
10953 (define_insn_reservation "ldsmem_to_pr"  3
10954   (and (eq_attr "pipe_model" "sh4")
10955        (eq_attr "type" "pload"))
10956   "d_lock*2")
10957
10958 ;; STS from PR
10959 ;; Group:       CO
10960 ;; Latency:     2
10961 ;; Issue Rate:  2
10962 ;; The SX unit in second and third cycles.
10963
10964 (define_insn_reservation "sts_from_pr" 2
10965   (and (eq_attr "pipe_model" "sh4")
10966        (eq_attr "type" "prget"))
10967   "d_lock*2")
10968
10969 ;; STS.L from PR
10970 ;; Group:       CO
10971 ;; Latency:     2
10972 ;; Issue Rate:  2
10973
10974 (define_insn_reservation "sh4_prstore_mem" 2 
10975   (and (eq_attr "pipe_model" "sh4")
10976        (eq_attr "type" "pstore"))
10977   "d_lock*2,nothing,memory")
10978
10979 ;; LDS to FPSCR
10980 ;; Group:       CO
10981 ;; Latency:     4
10982 ;; Issue Rate:  1
10983 ;; F1 is blocked for last three cycles. 
10984
10985 (define_insn_reservation "fpscr_load" 4
10986   (and (eq_attr "pipe_model" "sh4")
10987        (eq_attr "type" "gp_fpscr"))
10988   "d_lock,nothing,F1*3")
10989
10990 ;; LDS.L to FPSCR
10991 ;; Group:       CO
10992 ;; Latency:     1 / 4
10993 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10994 ;; Issue Rate:  1
10995 ;; F1 is blocked for last three cycles.
10996
10997 (define_insn_reservation "fpscr_load_mem" 4
10998   (and (eq_attr "pipe_model" "sh4")
10999        (eq_attr "type"  "mem_fpscr"))
11000   "d_lock,nothing,(F1+memory),F1*2")
11001
11002 \f
11003 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11004 ;; Group:       CO
11005 ;; Latency:     4 / 4
11006 ;; Issue Rate:  1
11007
11008 (define_insn_reservation "multi" 4
11009   (and (eq_attr "pipe_model" "sh4")
11010        (eq_attr "type" "smpy,dmpy"))
11011   "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11012
11013 ;; Fixed STS from MACL / MACH
11014 ;; Group:       CO
11015 ;; Latency:     3
11016 ;; Issue Rate:  1
11017
11018 (define_insn_reservation "sh4_mac_gp" 3
11019   (and (eq_attr "pipe_model" "sh4")
11020        (eq_attr "type" "mac_gp"))
11021   "d_lock")
11022
11023
11024 ;; Single precision floating point computation FCMP/EQ,
11025 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11026 ;; Group:       FE
11027 ;; Latency:     3/4
11028 ;; Issue Rate:  1
11029
11030 (define_insn_reservation "fp_arith"  3
11031   (and (eq_attr "pipe_model" "sh4")
11032        (eq_attr "type" "fp"))
11033   "issue,F01,F2")
11034
11035 (define_insn_reservation "fp_arith_ftrc"  3
11036   (and (eq_attr "pipe_model" "sh4")
11037        (eq_attr "type" "ftrc_s"))
11038   "issue,F01,F2")
11039
11040 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11041
11042 ;; Single Precision FDIV/SQRT
11043 ;; Group:       FE
11044 ;; Latency:     12/13 (FDIV); 11/12 (FSQRT)
11045 ;; Issue Rate:  1
11046 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11047
11048 (define_insn_reservation "fp_div" 12
11049   (and (eq_attr "pipe_model" "sh4")
11050        (eq_attr "type" "fdiv"))
11051   "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11052
11053 ;; Double Precision floating point computation
11054 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11055 ;; Group:       FE
11056 ;; Latency:     (3,4)/5
11057 ;; Issue Rate:  1
11058
11059 (define_insn_reservation "dp_float" 4
11060   (and (eq_attr "pipe_model" "sh4")
11061        (eq_attr "type" "dfp_conv"))
11062   "issue,F01,F1+F2,F2")
11063
11064 ;; Double-precision floating-point (FADD,FMUL,FSUB) 
11065 ;; Group:       FE
11066 ;; Latency:     (7,8)/9
11067 ;; Issue Rate:  1
11068
11069 (define_insn_reservation "fp_double_arith" 8
11070   (and (eq_attr "pipe_model" "sh4")
11071        (eq_attr "type" "dfp_arith"))
11072   "issue,F01,F1+F2,fpu*4,F2")
11073
11074 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT) 
11075 ;; Group:       CO
11076 ;; Latency:     3/5
11077 ;; Issue Rate:  2
11078
11079 (define_insn_reservation "fp_double_cmp" 3 
11080   (and (eq_attr "pipe_model" "sh4")
11081        (eq_attr "type" "dfp_cmp"))
11082   "d_lock,(d_lock+F01),F1+F2,F2")
11083
11084 ;; Double precision FDIV/SQRT
11085 ;; Group:       FE
11086 ;; Latency:     (24,25)/26
11087 ;; Issue Rate:  1
11088
11089 (define_insn_reservation "dp_div" 25
11090   (and (eq_attr "pipe_model" "sh4")
11091        (eq_attr "type" "dfdiv"))
11092   "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11093
11094
11095 ;; Use the branch-not-taken case to model arith3 insns.  For the branch taken
11096 ;; case, we'd get a d_lock instead of issue at the end.
11097 (define_insn_reservation "arith3" 3
11098   (and (eq_attr "pipe_model" "sh4")
11099        (eq_attr "type" "arith3"))
11100   "issue,d_lock+pcr_addrcalc,issue")
11101
11102 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11103 (define_insn_reservation "arith3b" 2
11104   (and (eq_attr "pipe_model" "sh4")
11105        (eq_attr "type" "arith3"))
11106   "issue,d_lock+pcr_addrcalc")