OSDN Git Service

faef8b55a8307954c5b317c2473cf0164100e0c8
[pf3gnuchains/gcc-fork.git] / gcc / config / sh / sh.md
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 ;;  Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
146
147   ;; These are used with unspec_volatile.
148   (UNSPECV_BLOCKAGE     0)
149   (UNSPECV_ALIGN        1)
150   (UNSPECV_CONST2       2)
151   (UNSPECV_CONST4       4)
152   (UNSPECV_CONST8       6)
153   (UNSPECV_WINDOW_END   10)
154   (UNSPECV_CONST_END    11)
155 ])
156
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
160
161 ;; Target CPU.
162
163 (define_attr "cpu"
164  "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
165   (const (symbol_ref "sh_cpu_attr")))
166
167 (define_attr "endian" "big,little"
168  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169                       (const_string "little") (const_string "big"))))
170
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174                          (const_string "yes") (const_string "no"))))
175
176 (define_attr "fmovd" "yes,no"
177   (const (if_then_else (symbol_ref "TARGET_FMOVD")
178                        (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181   (const
182    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184          (const_string "sh1"))))
185
186 ;; cbranch      conditional branch instructions
187 ;; jump         unconditional jumps
188 ;; arith        ordinary arithmetic
189 ;; arith3       a compound insn that behaves similarly to a sequence of
190 ;;              three insns of type arith
191 ;; arith3b      like above, but might end with a redirected branch
192 ;; load         from memory
193 ;; load_si      Likewise, SImode variant for general register.
194 ;; fload        Likewise, but load to fp register.
195 ;; store        to memory
196 ;; move         general purpose register to register
197 ;; mt_group     other sh4 mt instructions
198 ;; fmove        register to register, floating point
199 ;; smpy         word precision integer multiply
200 ;; dmpy         longword or doublelongword precision integer multiply
201 ;; return       rts
202 ;; pload        load of pr reg, which can't be put into delay slot of rts
203 ;; prset        copy register to pr reg, ditto
204 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
205 ;; prget        copy pr to register, ditto
206 ;; pcload       pc relative load of constant value
207 ;; pcfload      Likewise, but load to fp register.
208 ;; pcload_si    Likewise, SImode variant for general register.
209 ;; rte          return from exception
210 ;; sfunc        special function call with known used registers
211 ;; call         function call
212 ;; fp           floating point
213 ;; fdiv         floating point divide (or square root)
214 ;; gp_fpul      move from general purpose register to fpul
215 ;; fpul_gp      move from fpul to general purpose register
216 ;; mac_gp       move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s       fix_truncsfsi2_i4
219 ;; dfdiv        double precision floating point divide (or square root)
220 ;; cwb          ic_invalidate_line_i
221 ;; tls_load     load TLS related address
222 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
223 ;; cbranch_media SHmedia conditional branch instructions
224 ;; cmp_media    SHmedia compare instructions
225 ;; dfdiv_media  SHmedia double precision divide and square root
226 ;; dfmul_media  SHmedia double precision multiply instruction
227 ;; dfparith_media SHmedia double precision floating point arithmetic
228 ;; dfpconv_media SHmedia double precision floating point conversions
229 ;; dmpy_media   SHmedia longword multiply
230 ;; fcmp_media   SHmedia floating point compare instructions
231 ;; fdiv_media   SHmedia single precision divide and square root
232 ;; fload_media  SHmedia floating point register load instructions
233 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
234 ;; fparith_media SHmedia single precision floating point arithmetic
235 ;; fpconv_media SHmedia single precision floating point conversions
236 ;; fstore_media SHmedia floating point register store instructions
237 ;; gettr_media  SHmedia gettr instruction
238 ;; invalidate_line_media SHmedia invalidate_line sequence
239 ;; jump_media   SHmedia unconditional branch instructions
240 ;; load_media   SHmedia general register load instructions
241 ;; pt_media     SHmedia pt instruction (expanded by assembler)
242 ;; ptabs_media  SHmedia ptabs instruction
243 ;; store_media  SHmedia general register store instructions
244 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
245 ;; mac_media    SHmedia mac-style fixed point operations
246 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
247 ;; atrans       SHmedia approximate transcendental functions
248 ;; ustore_media SHmedia unaligned stores
249 ;; nil          no-op move, will be deleted.
250
251 (define_attr "type"
252  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
253   (const_string "other"))
254
255 ;; We define a new attribute namely "insn_class".We use
256 ;; this for the DFA based pipeline description.
257 ;;
258 ;; mt_group      SH4 "mt" group instructions.
259 ;;
260 ;; ex_group      SH4 "ex" group instructions.
261 ;;
262 ;; ls_group      SH4 "ls" group instructions.
263 ;;
264
265 (define_attr "insn_class"
266   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270          (eq_attr "type" "cbranch,jump") (const_string "br_group")
271          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272            (const_string "fe_group")
273          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
274         (const_string "none")))
275 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276 ;; so these do not belong in an insn group, although they are modeled
277 ;; with their own define_insn_reservations.
278
279 ;; Indicate what precision must be selected in fpscr for this insn, if any.
280
281 (define_attr "fp_mode" "single,double,none" (const_string "none"))
282
283 ;; Indicate if the fpu mode is set by this instruction
284 ;; "unknown" must have the value as "none" in fp_mode, and means
285 ;; that the instruction/abi has left the processor in an unknown
286 ;; state.
287 ;; "none" means that nothing has changed and no mode is set.
288 ;; This attribute is only used for the Renesas ABI.
289 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
290
291 ; If a conditional branch destination is within -252..258 bytes away
292 ; from the instruction it can be 2 bytes long.  Something in the
293 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
294 ; branches are initially assumed to be 16 bytes long.
295 ; In machine_dependent_reorg, we split all branches that are longer than
296 ; 2 bytes.
297
298 ;; The maximum range used for SImode constant pool entries is 1018.  A final
299 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
300 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
301 ;; instruction around the pool table, 2 bytes of alignment before the table,
302 ;; and 30 bytes of alignment after the table.  That gives a maximum total
303 ;; pool size of 1058 bytes.
304 ;; Worst case code/pool content size ratio is 1:2 (using asms).
305 ;; Thus, in the worst case, there is one instruction in front of a maximum
306 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
307 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
308 ;; If we have a forward branch, the initial table will be put after the
309 ;; unconditional branch.
310 ;;
311 ;; ??? We could do much better by keeping track of the actual pcloads within
312 ;; the branch range and in the pcload range in front of the branch range.
313
314 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
315 ;; inside an le.
316 (define_attr "short_cbranch_p" "no,yes"
317   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
318          (const_string "no")
319          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
320          (const_string "yes")
321          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
322          (const_string "no")
323          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
324          (const_string "yes")
325          ] (const_string "no")))
326
327 (define_attr "med_branch_p" "no,yes"
328   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
329               (const_int 1988))
330          (const_string "yes")
331          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
332          (const_string "no")
333          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
334               (const_int 8186))
335          (const_string "yes")
336          ] (const_string "no")))
337
338 (define_attr "med_cbranch_p" "no,yes"
339   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
340               (const_int 1986))
341          (const_string "yes")
342          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
343          (const_string "no")
344          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
345                (const_int 8184))
346          (const_string "yes")
347          ] (const_string "no")))
348
349 (define_attr "braf_branch_p" "no,yes"
350   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
351          (const_string "no")
352          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
353               (const_int 20660))
354          (const_string "yes")
355          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
356          (const_string "no")
357          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
358               (const_int 65530))
359          (const_string "yes")
360          ] (const_string "no")))
361
362 (define_attr "braf_cbranch_p" "no,yes"
363   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
364          (const_string "no")
365          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
366               (const_int 20658))
367          (const_string "yes")
368          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
369          (const_string "no")
370          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
371               (const_int 65528))
372          (const_string "yes")
373          ] (const_string "no")))
374
375 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
376 ; For wider ranges, we need a combination of a code and a data part.
377 ; If we can get a scratch register for a long range jump, the code
378 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
379 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
380 ; long; otherwise, it must be 6 bytes long.
381
382 ; All other instructions are two bytes long by default.
383
384 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
385 ;; but getattrtab doesn't understand this.
386 (define_attr "length" ""
387   (cond [(eq_attr "type" "cbranch")
388          (cond [(eq_attr "short_cbranch_p" "yes")
389                 (const_int 2)
390                 (eq_attr "med_cbranch_p" "yes")
391                 (const_int 6)
392                 (eq_attr "braf_cbranch_p" "yes")
393                 (const_int 12)
394 ;; ??? using pc is not computed transitively.
395                 (ne (match_dup 0) (match_dup 0))
396                 (const_int 14)
397                 (ne (symbol_ref ("flag_pic")) (const_int 0))
398                 (const_int 24)
399                 ] (const_int 16))
400          (eq_attr "type" "jump")
401          (cond [(eq_attr "med_branch_p" "yes")
402                 (const_int 2)
403                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
404                          (symbol_ref "INSN"))
405                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
406                          (symbol_ref "code_for_indirect_jump_scratch")))
407                 (if_then_else (eq_attr "braf_branch_p" "yes")
408                               (const_int 6)
409                               (const_int 10))
410                 (eq_attr "braf_branch_p" "yes")
411                 (const_int 10)
412 ;; ??? using pc is not computed transitively.
413                 (ne (match_dup 0) (match_dup 0))
414                 (const_int 12)
415                 (ne (symbol_ref ("flag_pic")) (const_int 0))
416                 (const_int 22)
417                 ] (const_int 14))
418          (eq_attr "type" "pt_media")
419          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
420                        (const_int 20) (const_int 12))
421          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
422                          (const_int 4)
423                          (const_int 2))))
424
425 ;; (define_function_unit {name} {num-units} {n-users} {test}
426 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
427
428 ;; Load and store instructions save a cycle if they are aligned on a
429 ;; four byte boundary.  Using a function unit for stores encourages
430 ;; gcc to separate load and store instructions by one instruction,
431 ;; which makes it more likely that the linker will be able to word
432 ;; align them when relaxing.
433
434 ;; Loads have a latency of two.
435 ;; However, call insns can have a delay slot, so that we want one more
436 ;; insn to be scheduled between the load of the function address and the call.
437 ;; This is equivalent to a latency of three.
438 ;; We cannot use a conflict list for this, because we need to distinguish
439 ;; between the actual call address and the function arguments.
440 ;; ADJUST_COST can only properly handle reductions of the cost, so we
441 ;; use a latency of three here.
442 ;; We only do this for SImode loads of general registers, to make the work
443 ;; for ADJUST_COST easier.
444 (define_function_unit "memory" 1 0
445   (and (eq_attr "pipe_model" "sh1")
446        (eq_attr "type" "load_si,pcload_si"))
447   3 2)
448 (define_function_unit "memory" 1 0
449   (and (eq_attr "pipe_model" "sh1")
450        (eq_attr "type" "load,pcload,pload,store,pstore"))
451   2 2)
452
453 (define_function_unit "int"    1 0
454   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
455
456 (define_function_unit "int"    1 0
457   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
458
459 (define_function_unit "int"    1 0
460   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
461
462 ;; ??? These are approximations.
463 (define_function_unit "mpy"    1 0
464   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
465 (define_function_unit "mpy"    1 0
466   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
467
468 (define_function_unit "fp"     1 0
469   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
470 (define_function_unit "fp"     1 0
471   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
472
473
474 ;; SH-5 SHmedia scheduling
475 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
476 ;; single-issue machine.  It has four pipelines, the branch unit (br),
477 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
478 ;; the floating point unit (fpu).
479 ;; Here model the instructions with a latency greater than one cycle.
480
481 ;; Every instruction on SH-5 occupies the issue resource for at least one
482 ;; cycle.
483 (define_function_unit "sh5issue" 1 0
484   (and (eq_attr "pipe_model" "sh5media")
485        (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)
486
487 ;; Specify the various types of instruction which have latency > 1
488 (define_function_unit "sh5issue" 1 0
489   (and (eq_attr "pipe_model" "sh5media")
490        (eq_attr "type" "mcmp_media")) 2 1)
491
492 (define_function_unit "sh5issue" 1 0
493   (and (eq_attr "pipe_model" "sh5media")
494        (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
495 ;; but see sh_adjust_cost for mac_media exception.
496
497 (define_function_unit "sh5issue" 1 0
498   (and (eq_attr "pipe_model" "sh5media")
499        (eq_attr "type" "fload_media,fmove_media")) 4 1)
500
501 (define_function_unit "sh5issue" 1 0
502   (and (eq_attr "pipe_model" "sh5media")
503        (eq_attr "type" "d2mpy_media")) 4 2)
504
505 (define_function_unit "sh5issue" 1 0
506   (and (eq_attr "pipe_model" "sh5media")
507        (eq_attr "type" "pt_media,ptabs_media")) 5 1)
508
509 (define_function_unit "sh5issue" 1 0
510   (and (eq_attr "pipe_model" "sh5media")
511        (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
512
513 (define_function_unit "sh5issue" 1 0
514   (and (eq_attr "pipe_model" "sh5media")
515        (eq_attr "type" "invalidate_line_media")) 7 7)
516
517 (define_function_unit "sh5issue" 1 0
518   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
519
520 (define_function_unit "sh5issue" 1 0
521   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
522
523 ;; Floating-point divide and square-root occupy an additional resource,
524 ;; which is not internally pipelined.  However, other instructions
525 ;; can continue to issue.
526 (define_function_unit "sh5fds" 1 0
527   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media"))  19 19)
528
529 (define_function_unit "sh5fds" 1 0
530   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
531
532 ; Definitions for filling branch delay slots.
533
534 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
535
536 ;; ??? This should be (nil) instead of (const_int 0)
537 (define_attr "hit_stack" "yes,no"
538         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
539                    (const_int 0))
540                (const_string "no")]
541               (const_string "yes")))
542
543 (define_attr "interrupt_function" "no,yes"
544   (const (symbol_ref "current_function_interrupt")))
545
546 (define_attr "in_delay_slot" "yes,no"
547   (cond [(eq_attr "type" "cbranch") (const_string "no")
548          (eq_attr "type" "pcload,pcload_si") (const_string "no")
549          (eq_attr "needs_delay_slot" "yes") (const_string "no")
550          (eq_attr "length" "2") (const_string "yes")
551          ] (const_string "no")))
552
553 (define_attr "cond_delay_slot" "yes,no"
554   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
555          ] (const_string "no")))
556
557 (define_attr "is_sfunc" ""
558   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
559
560 (define_attr "is_mac_media" ""
561   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
562
563 (define_attr "branch_zero" "yes,no"
564   (cond [(eq_attr "type" "!cbranch") (const_string "no")
565          (ne (symbol_ref "(next_active_insn (insn)\
566                            == (prev_active_insn\
567                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
568                           && get_attr_length (next_active_insn (insn)) == 2")
569              (const_int 0))
570          (const_string "yes")]
571         (const_string "no")))
572
573 ;; SH4 Double-precision computation with double-precision result -
574 ;; the two halves are ready at different times.
575 (define_attr "dfp_comp" "yes,no"
576   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
577         (const_string "no")))
578
579 ;; Insns for which the latency of a preceding fp insn is decreased by one.
580 (define_attr "late_fp_use" "yes,no" (const_string "no"))
581 ;; And feeding insns for which this relevant.
582 (define_attr "any_fp_comp" "yes,no"
583   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
584          (const_string "yes")]
585         (const_string "no")))
586
587 (define_attr "any_int_load" "yes,no"
588   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
589          (const_string "yes")]
590         (const_string "no")))
591
592 (define_delay
593   (eq_attr "needs_delay_slot" "yes")
594   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
595
596 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
597 ;; and thus we can't put a pop instruction in its delay slot.
598 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
599 ;; instruction can go in the delay slot.
600
601 ;; Since a normal return (rts) implicitly uses the PR register,
602 ;; we can't allow PR register loads in an rts delay slot.
603
604 (define_delay
605   (eq_attr "type" "return")
606   [(and (eq_attr "in_delay_slot" "yes")
607         (ior (and (eq_attr "interrupt_function" "no")
608                   (eq_attr "type" "!pload,prset"))
609              (and (eq_attr "interrupt_function" "yes")
610                   (ior
611                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
612                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
613
614 ;; Since a call implicitly uses the PR register, we can't allow
615 ;; a PR register store in a jsr delay slot.
616
617 (define_delay
618   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
619   [(and (eq_attr "in_delay_slot" "yes")
620         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
621
622 ;; Say that we have annulled true branches, since this gives smaller and
623 ;; faster code when branches are predicted as not taken.
624
625 (define_delay
626   (and (eq_attr "type" "cbranch")
627        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
628   ;; SH2e has a hardware bug that pretty much prohibits the use of
629   ;; annuled delay slots.
630   [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
631                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
632 \f
633 ;; -------------------------------------------------------------------------
634 ;; SImode signed integer comparisons
635 ;; -------------------------------------------------------------------------
636
637 (define_insn ""
638   [(set (reg:SI T_REG)
639         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
640                        (match_operand:SI 1 "arith_operand" "K08,r"))
641                (const_int 0)))]
642   "TARGET_SH1"
643   "tst  %1,%0"
644   [(set_attr "type" "mt_group")])
645
646 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
647 ;; That would still allow reload to create cmpi instructions, but would
648 ;; perhaps allow forcing the constant into a register when that is better.
649 ;; Probably should use r0 for mem/imm compares, but force constant into a
650 ;; register for pseudo/imm compares.
651
652 (define_insn "cmpeqsi_t"
653   [(set (reg:SI T_REG)
654         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
655                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
656   "TARGET_SH1"
657   "@
658         tst     %0,%0
659         cmp/eq  %1,%0
660         cmp/eq  %1,%0"
661    [(set_attr "type" "mt_group")])
662
663 (define_insn "cmpgtsi_t"
664   [(set (reg:SI T_REG)
665         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
666                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
667   "TARGET_SH1"
668   "@
669         cmp/gt  %1,%0
670         cmp/pl  %0"
671    [(set_attr "type" "mt_group")])
672
673 (define_insn "cmpgesi_t"
674   [(set (reg:SI T_REG)
675         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
676                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
677   "TARGET_SH1"
678   "@
679         cmp/ge  %1,%0
680         cmp/pz  %0"
681    [(set_attr "type" "mt_group")])
682
683 ;; -------------------------------------------------------------------------
684 ;; SImode unsigned integer comparisons
685 ;; -------------------------------------------------------------------------
686
687 (define_insn "cmpgeusi_t"
688   [(set (reg:SI T_REG)
689         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
690                 (match_operand:SI 1 "arith_reg_operand" "r")))]
691   "TARGET_SH1"
692   "cmp/hs       %1,%0"
693    [(set_attr "type" "mt_group")])
694
695 (define_insn "cmpgtusi_t"
696   [(set (reg:SI T_REG)
697         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
698                 (match_operand:SI 1 "arith_reg_operand" "r")))]
699   "TARGET_SH1"
700   "cmp/hi       %1,%0"
701    [(set_attr "type" "mt_group")])
702
703 ;; We save the compare operands in the cmpxx patterns and use them when
704 ;; we generate the branch.
705
706 (define_expand "cmpsi"
707   [(set (reg:SI T_REG)
708         (compare (match_operand:SI 0 "arith_operand" "")
709                  (match_operand:SI 1 "arith_operand" "")))]
710   "TARGET_SH1"
711   "
712 {
713   sh_compare_op0 = operands[0];
714   sh_compare_op1 = operands[1];
715   DONE;
716 }")
717 \f
718 ;; -------------------------------------------------------------------------
719 ;; DImode signed integer comparisons
720 ;; -------------------------------------------------------------------------
721
722 ;; ??? Could get better scheduling by splitting the initial test from the
723 ;; rest of the insn after reload.  However, the gain would hardly justify
724 ;; the sh.md size increase necessary to do that.
725
726 (define_insn ""
727   [(set (reg:SI T_REG)
728         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
729                        (match_operand:DI 1 "arith_operand" "r"))
730                (const_int 0)))]
731   "TARGET_SH1"
732   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
733                                  insn, operands);"
734   [(set_attr "length" "6")
735    (set_attr "type" "arith3b")])
736
737 (define_insn "cmpeqdi_t"
738   [(set (reg:SI T_REG)
739         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
740                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
741   "TARGET_SH1"
742   "@
743         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
744         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
745   [(set_attr "length" "6")
746    (set_attr "type" "arith3b")])
747
748 (define_split
749   [(set (reg:SI T_REG)
750         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
751                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
752 ;; If we applied this split when not optimizing, it would only be
753 ;; applied during the machine-dependent reorg, when no new basic blocks
754 ;; may be created.
755   "TARGET_SH1 && reload_completed && optimize"
756   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
757    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
758                            (label_ref (match_dup 6))
759                            (pc)))
760    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
761    (match_dup 6)]
762   "
763 {
764   operands[2]
765     = gen_rtx_REG (SImode,
766                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
767   operands[3]
768     = (operands[1] == const0_rtx
769        ? const0_rtx
770        : gen_rtx_REG (SImode,
771                       true_regnum (operands[1])
772                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
773   operands[4] = gen_lowpart (SImode, operands[0]);
774   operands[5] = gen_lowpart (SImode, operands[1]);
775   operands[6] = gen_label_rtx ();
776 }")
777
778 (define_insn "cmpgtdi_t"
779   [(set (reg:SI T_REG)
780         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
781                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
782   "TARGET_SH2"
783   "@
784         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
785         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
786   [(set_attr "length" "8")
787    (set_attr "type" "arith3")])
788
789 (define_insn "cmpgedi_t"
790   [(set (reg:SI T_REG)
791         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
792                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
793   "TARGET_SH2"
794   "@
795         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
796         cmp/pz\\t%S0"
797   [(set_attr "length" "8,2")
798    (set_attr "type" "arith3,mt_group")])
799 \f
800 ;; -------------------------------------------------------------------------
801 ;; DImode unsigned integer comparisons
802 ;; -------------------------------------------------------------------------
803
804 (define_insn "cmpgeudi_t"
805   [(set (reg:SI T_REG)
806         (geu: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/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
810   [(set_attr "length" "8")
811    (set_attr "type" "arith3")])
812
813 (define_insn "cmpgtudi_t"
814   [(set (reg:SI T_REG)
815         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
816                 (match_operand:DI 1 "arith_reg_operand" "r")))]
817   "TARGET_SH2"
818   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
819   [(set_attr "length" "8")
820    (set_attr "type" "arith3")])
821
822 (define_insn "cmpeqdi_media"
823   [(set (match_operand:DI 0 "register_operand" "=r")
824         (eq:DI (match_operand:DI 1 "register_operand" "%r")
825                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
826   "TARGET_SHMEDIA"
827   "cmpeq        %1, %N2, %0"
828   [(set_attr "type" "cmp_media")])
829
830 (define_insn "cmpgtdi_media"
831   [(set (match_operand:DI 0 "register_operand" "=r")
832         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
833                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
834   "TARGET_SHMEDIA"
835   "cmpgt        %N1, %N2, %0"
836   [(set_attr "type" "cmp_media")])
837
838 (define_insn "cmpgtudi_media"
839   [(set (match_operand:DI 0 "register_operand" "=r")
840         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
841                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
842   "TARGET_SHMEDIA"
843   "cmpgtu       %N1, %N2, %0"
844   [(set_attr "type" "cmp_media")])
845
846 ;; We save the compare operands in the cmpxx patterns and use them when
847 ;; we generate the branch.
848
849 (define_expand "cmpdi"
850   [(set (reg:SI T_REG)
851         (compare (match_operand:DI 0 "arith_operand" "")
852                  (match_operand:DI 1 "arith_operand" "")))]
853   "TARGET_SH2 || TARGET_SHMEDIA"
854   "
855 {
856   sh_compare_op0 = operands[0];
857   sh_compare_op1 = operands[1];
858   DONE;
859 }")
860 ;; -------------------------------------------------------------------------
861 ;; Conditional move instructions
862 ;; -------------------------------------------------------------------------
863
864 ;; The insn names may seem reversed, but note that cmveq performs the move
865 ;; if op1 == 0, and cmvne does it if op1 != 0.
866
867 (define_insn "movdicc_false"
868   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
869         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
870                              (const_int 0))
871          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
872          (match_operand:DI 3 "arith_reg_operand" "0")))]
873   "TARGET_SHMEDIA"
874   "cmveq        %1, %N2, %0"
875   [(set_attr "type" "arith_media")])
876
877 (define_insn "movdicc_true"
878   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
879         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
880                              (const_int 0))
881          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
882          (match_operand:DI 3 "arith_reg_operand" "0")))]
883   "TARGET_SHMEDIA"
884   "cmvne        %1, %N2, %0"
885   [(set_attr "type" "arith_media")])
886
887 (define_expand "movdicc"
888   [(set (match_operand:DI 0 "register_operand" "")
889         (if_then_else:DI (match_operand 1 "comparison_operator" "")
890                          (match_operand:DI 2 "register_operand" "")
891                          (match_operand:DI 3 "register_operand" "")))]
892   "TARGET_SHMEDIA"
893   "
894 {
895   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
896       && GET_MODE (sh_compare_op0) == DImode
897       && sh_compare_op1 == const0_rtx)
898     operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
899                            sh_compare_op0, sh_compare_op1);
900   else
901     {
902       rtx tmp;
903
904       if (no_new_pseudos)
905         FAIL;
906
907       tmp = gen_reg_rtx (DImode);
908
909       switch (GET_CODE (operands[1]))
910         {
911         case EQ:
912           emit_insn (gen_seq (tmp));
913           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
914           break;
915
916         case NE:
917           emit_insn (gen_seq (tmp));
918           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
919           break;
920
921         case GT:
922           emit_insn (gen_sgt (tmp));
923           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
924           break;
925
926         case LT:
927           emit_insn (gen_slt (tmp));
928           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
929           break;
930
931         case GE:
932           emit_insn (gen_slt (tmp));
933           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
934           break;
935
936         case LE:
937           emit_insn (gen_sgt (tmp));
938           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
939           break;
940
941         case GTU:
942           emit_insn (gen_sgtu (tmp));
943           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
944           break;
945
946         case LTU:
947           emit_insn (gen_sltu (tmp));
948           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
949           break;
950
951         case GEU:
952           emit_insn (gen_sltu (tmp));
953           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
954           break;
955
956         case LEU:
957           emit_insn (gen_sgtu (tmp));
958           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
959           break;
960
961         case UNORDERED:
962           emit_insn (gen_sunordered (tmp));
963           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
964           break;
965
966         case ORDERED:
967           emit_insn (gen_sunordered (tmp));
968           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
969           break;
970
971         case UNEQ:
972         case UNGE:
973         case UNGT:
974         case UNLE:
975         case UNLT:
976         case LTGT:
977           FAIL;
978
979         default:
980           abort ();
981         }
982     }
983 }")
984 \f
985 ;; -------------------------------------------------------------------------
986 ;; Addition instructions
987 ;; -------------------------------------------------------------------------
988
989 (define_expand "adddi3"
990   [(set (match_operand:DI 0 "arith_reg_operand" "")
991         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
992                  (match_operand:DI 2 "arith_operand" "")))]
993   ""
994   "
995 {
996   if (TARGET_SH1)
997     {
998       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
999         FAIL;
1000       operands[2] = force_reg (DImode, operands[2]);
1001       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1002       DONE;
1003     }
1004 }")
1005
1006 (define_insn "*adddi3_media"
1007   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1008         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1009                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1010   "TARGET_SHMEDIA"
1011   "@
1012         add     %1, %2, %0
1013         addi    %1, %2, %0"
1014   [(set_attr "type" "arith_media")])
1015
1016 (define_insn "adddi3z_media"
1017   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1018         (zero_extend:DI
1019          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1020                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1021   "TARGET_SHMEDIA"
1022   "addz.l       %1, %N2, %0"
1023   [(set_attr "type" "arith_media")])
1024
1025 (define_insn "adddi3_compact"
1026   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1027         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1028                  (match_operand:DI 2 "arith_reg_operand" "r")))
1029    (clobber (reg:SI T_REG))]
1030   "TARGET_SH1"
1031   "#"
1032   [(set_attr "length" "6")])
1033
1034 (define_split
1035   [(set (match_operand:DI 0 "arith_reg_operand" "")
1036         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1037                  (match_operand:DI 2 "arith_reg_operand" "")))
1038    (clobber (reg:SI T_REG))]
1039   "TARGET_SH1 && reload_completed"
1040   [(const_int 0)]
1041   "
1042 {
1043   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1044   high0 = gen_rtx_REG (SImode,
1045                        true_regnum (operands[0])
1046                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1047   high2 = gen_rtx_REG (SImode,
1048                        true_regnum (operands[2])
1049                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1050   emit_insn (gen_clrt ());
1051   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1052   emit_insn (gen_addc1 (high0, high0, high2));
1053   DONE;
1054 }")
1055
1056 (define_insn "addc"
1057   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1058         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1059                           (match_operand:SI 2 "arith_reg_operand" "r"))
1060                  (reg:SI T_REG)))
1061    (set (reg:SI T_REG)
1062         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1063   "TARGET_SH1"
1064   "addc %2,%0"
1065   [(set_attr "type" "arith")])
1066
1067 (define_insn "addc1"
1068   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1069         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1070                           (match_operand:SI 2 "arith_reg_operand" "r"))
1071                  (reg:SI T_REG)))
1072    (clobber (reg:SI T_REG))]
1073   "TARGET_SH1"
1074   "addc %2,%0"
1075   [(set_attr "type" "arith")])
1076
1077 (define_expand "addsi3"
1078   [(set (match_operand:SI 0 "arith_reg_operand" "")
1079         (plus:SI (match_operand:SI 1 "arith_operand" "")
1080                  (match_operand:SI 2 "arith_operand" "")))]
1081   ""
1082   "
1083 {
1084   if (TARGET_SHMEDIA)
1085     operands[1] = force_reg (SImode, operands[1]);
1086 }")
1087
1088 (define_insn "addsi3_media"
1089   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1090         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1091                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1092   "TARGET_SHMEDIA"
1093   "@
1094         add.l   %1, %2, %0
1095         addi.l  %1, %2, %0"
1096   [(set_attr "type" "arith_media")])
1097
1098 (define_insn "*addsi3_compact"
1099   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1100         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1101                  (match_operand:SI 2 "arith_operand" "rI08")))]
1102   "TARGET_SH1"
1103   "add  %2,%0"
1104   [(set_attr "type" "arith")])
1105
1106 ;; -------------------------------------------------------------------------
1107 ;; Subtraction instructions
1108 ;; -------------------------------------------------------------------------
1109
1110 (define_expand "subdi3"
1111   [(set (match_operand:DI 0 "arith_reg_operand" "")
1112         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1113                   (match_operand:DI 2 "arith_reg_operand" "")))]
1114   ""
1115   "
1116 {
1117   if (TARGET_SH1)
1118     {
1119       operands[1] = force_reg (DImode, operands[1]);
1120       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1121       DONE;
1122     }
1123 }")
1124
1125 (define_insn "*subdi3_media"
1126   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1127         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1128                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1129   "TARGET_SHMEDIA"
1130   "sub  %N1, %2, %0"
1131   [(set_attr "type" "arith_media")])
1132
1133 (define_insn "subdi3_compact"
1134   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1135         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1136                  (match_operand:DI 2 "arith_reg_operand" "r")))
1137    (clobber (reg:SI T_REG))]
1138   "TARGET_SH1"
1139   "#"
1140   [(set_attr "length" "6")])
1141
1142 (define_split
1143   [(set (match_operand:DI 0 "arith_reg_operand" "")
1144         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1145                   (match_operand:DI 2 "arith_reg_operand" "")))
1146    (clobber (reg:SI T_REG))]
1147   "TARGET_SH1 && reload_completed"
1148   [(const_int 0)]
1149   "
1150 {
1151   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1152   high0 = gen_rtx_REG (SImode,
1153                        true_regnum (operands[0])
1154                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1155   high2 = gen_rtx_REG (SImode,
1156                        true_regnum (operands[2])
1157                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1158   emit_insn (gen_clrt ());
1159   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1160   emit_insn (gen_subc1 (high0, high0, high2));
1161   DONE;
1162 }")
1163
1164 (define_insn "subc"
1165   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1166         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1167                             (match_operand:SI 2 "arith_reg_operand" "r"))
1168                   (reg:SI T_REG)))
1169    (set (reg:SI T_REG)
1170         (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1171   "TARGET_SH1"
1172   "subc %2,%0"
1173   [(set_attr "type" "arith")])
1174
1175 (define_insn "subc1"
1176   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1177         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1178                             (match_operand:SI 2 "arith_reg_operand" "r"))
1179                   (reg:SI T_REG)))
1180    (clobber (reg:SI T_REG))]
1181   "TARGET_SH1"
1182   "subc %2,%0"
1183   [(set_attr "type" "arith")])
1184
1185 (define_insn "*subsi3_internal"
1186   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1187         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1188                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1189   "TARGET_SH1"
1190   "sub  %2,%0"
1191   [(set_attr "type" "arith")])
1192
1193 (define_insn "*subsi3_media"
1194   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1195         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1196                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1197   "TARGET_SHMEDIA"
1198   "sub.l        %N1, %2, %0"
1199   [(set_attr "type" "arith_media")])
1200
1201 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1202 ;; will sometimes save one instruction.  Otherwise we might get
1203 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1204 ;; are the same.
1205
1206 (define_expand "subsi3"
1207   [(set (match_operand:SI 0 "arith_reg_operand" "")
1208         (minus:SI (match_operand:SI 1 "arith_operand" "")
1209                   (match_operand:SI 2 "arith_reg_operand" "")))]
1210   ""
1211   "
1212 {
1213   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1214     {
1215       emit_insn (gen_negsi2 (operands[0], operands[2]));
1216       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1217       DONE;
1218     }
1219   if (TARGET_SHMEDIA)
1220     {
1221       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1222         FAIL;
1223       if (operands[1] != const0_rtx)
1224         operands[1] = force_reg (SImode, operands[1]);
1225     }
1226 }")
1227 \f
1228 ;; -------------------------------------------------------------------------
1229 ;; Division instructions
1230 ;; -------------------------------------------------------------------------
1231
1232 ;; We take advantage of the library routines which don't clobber as many
1233 ;; registers as a normal function call would.
1234
1235 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1236 ;; also has an effect on the register that holds the address of the sfunc.
1237 ;; To make this work, we have an extra dummy insn that shows the use
1238 ;; of this register for reorg.
1239
1240 (define_insn "use_sfunc_addr"
1241   [(set (reg:SI PR_REG)
1242         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1243   "TARGET_SH1"
1244   ""
1245   [(set_attr "length" "0")])
1246
1247 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1248 ;; hard register 0.  If we used hard register 0, then the next instruction
1249 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1250 ;; gets allocated to a stack slot that needs its address reloaded, then
1251 ;; there is nothing to prevent reload from using r0 to reload the address.
1252 ;; This reload would clobber the value in r0 we are trying to store.
1253 ;; If we let reload allocate r0, then this problem can never happen.
1254
1255 (define_insn "udivsi3_i1"
1256   [(set (match_operand:SI 0 "register_operand" "=z")
1257         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1258    (clobber (reg:SI T_REG))
1259    (clobber (reg:SI PR_REG))
1260    (clobber (reg:SI R4_REG))
1261    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1262   "TARGET_SH1 && ! TARGET_SH4"
1263   "jsr  @%1%#"
1264   [(set_attr "type" "sfunc")
1265    (set_attr "needs_delay_slot" "yes")])
1266
1267 ; Since shmedia-nofpu code could be linked against shcompact code, and
1268 ; the udivsi3 libcall has the same name, we must consider all registers
1269 ; clobbered that are in the union of the registers clobbered by the
1270 ; shmedia and the shcompact implementation.  Note, if the shcompact
1271 ; implementation actually used shcompact code, we'd need to clobber
1272 ; also r23 and fr23.
1273 (define_insn "udivsi3_i1_media"
1274   [(set (match_operand:SI 0 "register_operand" "=z")
1275         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1276    (clobber (reg:SI T_MEDIA_REG))
1277    (clobber (reg:SI PR_MEDIA_REG))
1278    (clobber (reg:SI R20_REG))
1279    (clobber (reg:SI R21_REG))
1280    (clobber (reg:SI R22_REG))
1281    (clobber (reg:DI TR0_REG))
1282    (clobber (reg:DI TR1_REG))
1283    (clobber (reg:DI TR2_REG))
1284    (use (match_operand:DI 1 "target_operand" "b"))]
1285   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1286   "blink        %1, r18"
1287   [(set_attr "type" "sfunc")
1288    (set_attr "needs_delay_slot" "yes")])
1289
1290 (define_expand "udivsi3_i4_media"
1291   [(set (match_dup 3)
1292         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1293    (set (match_dup 4)
1294         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1295    (set (match_dup 5) (float:DF (match_dup 3)))
1296    (set (match_dup 6) (float:DF (match_dup 4)))
1297    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1298    (set (match_dup 8) (fix:DI (match_dup 7)))
1299    (set (match_operand:SI 0 "register_operand" "")
1300         (truncate:SI (match_dup 8)))]
1301   "TARGET_SHMEDIA_FPU"
1302   "
1303 {
1304   operands[3] = gen_reg_rtx (DImode);
1305   operands[4] = gen_reg_rtx (DImode);
1306   operands[5] = gen_reg_rtx (DFmode);
1307   operands[6] = gen_reg_rtx (DFmode);
1308   operands[7] = gen_reg_rtx (DFmode);
1309   operands[8] = gen_reg_rtx (DImode);
1310 }")
1311
1312 (define_insn "udivsi3_i4"
1313   [(set (match_operand:SI 0 "register_operand" "=y")
1314         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1315    (clobber (reg:SI T_REG))
1316    (clobber (reg:SI PR_REG))
1317    (clobber (reg:DF DR0_REG))
1318    (clobber (reg:DF DR2_REG))
1319    (clobber (reg:DF DR4_REG))
1320    (clobber (reg:SI R0_REG))
1321    (clobber (reg:SI R1_REG))
1322    (clobber (reg:SI R4_REG))
1323    (clobber (reg:SI R5_REG))
1324    (use (reg:PSI FPSCR_REG))
1325    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1326   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1327   "jsr  @%1%#"
1328   [(set_attr "type" "sfunc")
1329    (set_attr "fp_mode" "double")
1330    (set_attr "needs_delay_slot" "yes")])
1331
1332 (define_insn "udivsi3_i4_single"
1333   [(set (match_operand:SI 0 "register_operand" "=y")
1334         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1335    (clobber (reg:SI T_REG))
1336    (clobber (reg:SI PR_REG))
1337    (clobber (reg:DF DR0_REG))
1338    (clobber (reg:DF DR2_REG))
1339    (clobber (reg:DF DR4_REG))
1340    (clobber (reg:SI R0_REG))
1341    (clobber (reg:SI R1_REG))
1342    (clobber (reg:SI R4_REG))
1343    (clobber (reg:SI R5_REG))
1344    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1345   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1346   "jsr  @%1%#"
1347   [(set_attr "type" "sfunc")
1348    (set_attr "needs_delay_slot" "yes")])
1349
1350 (define_expand "udivsi3"
1351   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1352    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1353    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1354    (parallel [(set (match_operand:SI 0 "register_operand" "")
1355                    (udiv:SI (reg:SI R4_REG)
1356                             (reg:SI R5_REG)))
1357               (clobber (reg:SI T_REG))
1358               (clobber (reg:SI PR_REG))
1359               (clobber (reg:SI R4_REG))
1360               (use (match_dup 3))])]
1361   ""
1362   "
1363 {
1364   rtx first, last;
1365
1366   operands[3] = gen_reg_rtx (Pmode);
1367   /* Emit the move of the address to a pseudo outside of the libcall.  */
1368   if (TARGET_HARD_SH4 && TARGET_SH2E)
1369     {
1370       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1371       if (TARGET_FPU_SINGLE)
1372         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1373       else
1374         last = gen_udivsi3_i4 (operands[0], operands[3]);
1375     }
1376   else if (TARGET_SHMEDIA_FPU)
1377     {
1378       operands[1] = force_reg (SImode, operands[1]);
1379       operands[2] = force_reg (SImode, operands[2]);
1380       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1381       DONE;
1382     }
1383   else if (TARGET_SH5)
1384     {
1385       emit_move_insn (operands[3],
1386                       function_symbol (TARGET_FPU_ANY
1387                                        ? \"__udivsi3_i4\"
1388                                        : \"__udivsi3\"));
1389
1390       if (TARGET_SHMEDIA)
1391         last = gen_udivsi3_i1_media (operands[0],
1392                                      Pmode == DImode
1393                                      ? operands[3]
1394                                      : gen_rtx_SUBREG (DImode, operands[3],
1395                                                        0));
1396       else if (TARGET_FPU_ANY)
1397         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1398       else
1399         last = gen_udivsi3_i1 (operands[0], operands[3]);
1400     }
1401   else
1402     {
1403       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1404       last = gen_udivsi3_i1 (operands[0], operands[3]);
1405     }
1406   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1407   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1408   last = emit_insn (last);
1409   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1410      invariant code motion can move it.  */
1411   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1412   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1413   DONE;
1414 }")
1415
1416 (define_insn "divsi3_i1"
1417   [(set (match_operand:SI 0 "register_operand" "=z")
1418         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1419    (clobber (reg:SI T_REG))
1420    (clobber (reg:SI PR_REG))
1421    (clobber (reg:SI R1_REG))
1422    (clobber (reg:SI R2_REG))
1423    (clobber (reg:SI R3_REG))
1424    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1425   "TARGET_SH1 && ! TARGET_SH4"
1426   "jsr  @%1%#"
1427   [(set_attr "type" "sfunc")
1428    (set_attr "needs_delay_slot" "yes")])
1429
1430 ; Since shmedia-nofpu code could be linked against shcompact code, and
1431 ; the sdivsi3 libcall has the same name, we must consider all registers
1432 ; clobbered that are in the union of the registers clobbered by the
1433 ; shmedia and the shcompact implementation.  Note, if the shcompact
1434 ; implementation actually used shcompact code, we'd need to clobber
1435 ; also r22, r23 and fr23.
1436 (define_insn "divsi3_i1_media"
1437   [(set (match_operand:SI 0 "register_operand" "=z")
1438         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1439    (clobber (reg:SI T_MEDIA_REG))
1440    (clobber (reg:SI PR_MEDIA_REG))
1441    (clobber (reg:SI R1_REG))
1442    (clobber (reg:SI R2_REG))
1443    (clobber (reg:SI R3_REG))
1444    (clobber (reg:SI R20_REG))
1445    (clobber (reg:SI R21_REG))
1446    (clobber (reg:DI TR0_REG))
1447    (clobber (reg:DI TR1_REG))
1448    (clobber (reg:DI TR2_REG))
1449    (use (match_operand:DI 1 "target_operand" "b"))]
1450   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1451   "blink        %1, r18"
1452   [(set_attr "type" "sfunc")])
1453
1454 (define_expand "divsi3_i4_media"
1455   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1456    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1457    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1458    (set (match_operand:SI 0 "register_operand" "=r")
1459         (fix:SI (match_dup 5)))]
1460   "TARGET_SHMEDIA_FPU"
1461   "
1462 {
1463   operands[3] = gen_reg_rtx (DFmode);
1464   operands[4] = gen_reg_rtx (DFmode);
1465   operands[5] = gen_reg_rtx (DFmode);
1466 }")
1467
1468 (define_insn "divsi3_i4"
1469   [(set (match_operand:SI 0 "register_operand" "=y")
1470         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1471    (clobber (reg:SI PR_REG))
1472    (clobber (reg:DF DR0_REG))
1473    (clobber (reg:DF DR2_REG))
1474    (use (reg:PSI FPSCR_REG))
1475    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1476   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1477   "jsr  @%1%#"
1478   [(set_attr "type" "sfunc")
1479    (set_attr "fp_mode" "double")
1480    (set_attr "needs_delay_slot" "yes")])
1481
1482 (define_insn "divsi3_i4_single"
1483   [(set (match_operand:SI 0 "register_operand" "=y")
1484         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1485    (clobber (reg:SI PR_REG))
1486    (clobber (reg:DF DR0_REG))
1487    (clobber (reg:DF DR2_REG))
1488    (clobber (reg:SI R2_REG))
1489    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1490   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1491   "jsr  @%1%#"
1492   [(set_attr "type" "sfunc")
1493    (set_attr "needs_delay_slot" "yes")])
1494
1495 (define_expand "divsi3"
1496   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1497    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1498    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1499    (parallel [(set (match_operand:SI 0 "register_operand" "")
1500                    (div:SI (reg:SI R4_REG)
1501                            (reg:SI R5_REG)))
1502               (clobber (reg:SI T_REG))
1503               (clobber (reg:SI PR_REG))
1504               (clobber (reg:SI R1_REG))
1505               (clobber (reg:SI R2_REG))
1506               (clobber (reg:SI R3_REG))
1507               (use (match_dup 3))])]
1508   ""
1509   "
1510 {
1511   rtx first, last;
1512
1513   operands[3] = gen_reg_rtx (Pmode);
1514   /* Emit the move of the address to a pseudo outside of the libcall.  */
1515   if (TARGET_HARD_SH4 && TARGET_SH2E)
1516     {
1517       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1518       if (TARGET_FPU_SINGLE)
1519         last = gen_divsi3_i4_single (operands[0], operands[3]);
1520       else
1521         last = gen_divsi3_i4 (operands[0], operands[3]);
1522     }
1523   else if (TARGET_SHMEDIA_FPU)
1524     {
1525       operands[1] = force_reg (SImode, operands[1]);
1526       operands[2] = force_reg (SImode, operands[2]);
1527       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1528       DONE;
1529     }
1530   else if (TARGET_SH5)
1531     {
1532       emit_move_insn (operands[3],
1533                       function_symbol (TARGET_FPU_ANY
1534                                        ? \"__sdivsi3_i4\"
1535                                        : \"__sdivsi3\"));
1536
1537       if (TARGET_SHMEDIA)
1538         last = gen_divsi3_i1_media (operands[0],
1539                                     Pmode == DImode
1540                                     ? operands[3]
1541                                     : gen_rtx_SUBREG (DImode, operands[3],
1542                                                       0));
1543       else if (TARGET_FPU_ANY)
1544         last = gen_divsi3_i4_single (operands[0], operands[3]);
1545       else
1546         last = gen_divsi3_i1 (operands[0], operands[3]);
1547     }
1548   else
1549     {
1550       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1551       last = gen_divsi3_i1 (operands[0], operands[3]);
1552     }
1553   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1554   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1555   last = emit_insn (last);
1556   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1557      invariant code motion can move it.  */
1558   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1559   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1560   DONE;
1561 }")
1562 \f
1563 ;; -------------------------------------------------------------------------
1564 ;; Multiplication instructions
1565 ;; -------------------------------------------------------------------------
1566
1567 (define_insn "umulhisi3_i"
1568   [(set (reg:SI MACL_REG)
1569         (mult:SI (zero_extend:SI
1570                   (match_operand:HI 0 "arith_reg_operand" "r"))
1571                  (zero_extend:SI
1572                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1573   "TARGET_SH1"
1574   "mulu.w       %1,%0"
1575   [(set_attr "type" "smpy")])
1576
1577 (define_insn "mulhisi3_i"
1578   [(set (reg:SI MACL_REG)
1579         (mult:SI (sign_extend:SI
1580                   (match_operand:HI 0 "arith_reg_operand" "r"))
1581                  (sign_extend:SI
1582                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1583   "TARGET_SH1"
1584   "muls.w       %1,%0"
1585   [(set_attr "type" "smpy")])
1586
1587 (define_expand "mulhisi3"
1588   [(set (reg:SI MACL_REG)
1589         (mult:SI (sign_extend:SI
1590                   (match_operand:HI 1 "arith_reg_operand" ""))
1591                  (sign_extend:SI
1592                   (match_operand:HI 2 "arith_reg_operand" ""))))
1593    (set (match_operand:SI 0 "arith_reg_operand" "")
1594         (reg:SI MACL_REG))]
1595   "TARGET_SH1"
1596   "
1597 {
1598   rtx first, last;
1599
1600   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1601   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1602   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1603      invariant code motion can move it.  */
1604   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1605   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1606   /* expand_binop can't find a suitable code in umul_widen_optab to
1607      make a REG_EQUAL note from, so make one here.
1608      See also smulsi3_highpart.
1609      ??? Alternatively, we could put this at the calling site of expand_binop,
1610      i.e. expand_expr.  */
1611   REG_NOTES (last)
1612     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1613                          REG_NOTES (last));
1614   DONE;
1615 }")
1616
1617 (define_expand "umulhisi3"
1618   [(set (reg:SI MACL_REG)
1619         (mult:SI (zero_extend:SI
1620                   (match_operand:HI 1 "arith_reg_operand" ""))
1621                  (zero_extend:SI
1622                   (match_operand:HI 2 "arith_reg_operand" ""))))
1623    (set (match_operand:SI 0 "arith_reg_operand" "")
1624         (reg:SI MACL_REG))]
1625   "TARGET_SH1"
1626   "
1627 {
1628   rtx first, last;
1629
1630   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1631   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1632   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1633      invariant code motion can move it.  */
1634   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1635   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1636   /* expand_binop can't find a suitable code in umul_widen_optab to
1637      make a REG_EQUAL note from, so make one here.
1638      See also smulsi3_highpart.
1639      ??? Alternatively, we could put this at the calling site of expand_binop,
1640      i.e. expand_expr.  */
1641   REG_NOTES (last)
1642     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1643                          REG_NOTES (last));
1644   DONE;
1645 }")
1646
1647 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1648 ;; a call to a routine which clobbers known registers.
1649
1650 (define_insn ""
1651   [(set (match_operand:SI 1 "register_operand" "=z")
1652         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1653    (clobber (reg:SI MACL_REG))
1654    (clobber (reg:SI T_REG))
1655    (clobber (reg:SI PR_REG))
1656    (clobber (reg:SI R3_REG))
1657    (clobber (reg:SI R2_REG))
1658    (clobber (reg:SI R1_REG))
1659    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1660   "TARGET_SH1"
1661   "jsr  @%0%#"
1662   [(set_attr "type" "sfunc")
1663    (set_attr "needs_delay_slot" "yes")])
1664
1665 (define_expand "mulsi3_call"
1666   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1667    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1668    (parallel[(set (match_operand:SI 0 "register_operand" "")
1669                   (mult:SI (reg:SI R4_REG)
1670                            (reg:SI R5_REG)))
1671              (clobber (reg:SI MACL_REG))
1672              (clobber (reg:SI T_REG))
1673              (clobber (reg:SI PR_REG))
1674              (clobber (reg:SI R3_REG))
1675              (clobber (reg:SI R2_REG))
1676              (clobber (reg:SI R1_REG))
1677              (use (match_operand:SI 3 "register_operand" ""))])]
1678   "TARGET_SH1"
1679   "")
1680
1681 (define_insn "mul_l"
1682   [(set (reg:SI MACL_REG)
1683         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1684                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1685   "TARGET_SH2"
1686   "mul.l        %1,%0"
1687   [(set_attr "type" "dmpy")])
1688
1689 (define_expand "mulsi3"
1690   [(set (reg:SI MACL_REG)
1691         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1692                   (match_operand:SI 2 "arith_reg_operand" "")))
1693    (set (match_operand:SI 0 "arith_reg_operand" "")
1694         (reg:SI MACL_REG))]
1695   "TARGET_SH1"
1696   "
1697 {
1698   rtx first, last;
1699
1700   if (!TARGET_SH2)
1701     {
1702       /* The address must be set outside the libcall,
1703          since it goes into a pseudo.  */
1704       rtx sym = function_symbol (\"__mulsi3\");
1705       rtx addr = force_reg (SImode, sym);
1706       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1707                                    operands[2], addr);
1708       first = insns;
1709       last = emit_insn (insns);
1710     }
1711   else
1712     {
1713       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1714
1715       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1716       /* consec_sets_giv can only recognize the first insn that sets a
1717          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1718          note.  */
1719       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1720     }
1721   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1722      invariant code motion can move it.  */
1723   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1724   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1725   DONE;
1726 }")
1727
1728 (define_insn "mulsidi3_i"
1729   [(set (reg:SI MACH_REG)
1730         (truncate:SI
1731          (lshiftrt:DI
1732           (mult:DI
1733            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1734            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1735           (const_int 32))))
1736    (set (reg:SI MACL_REG)
1737         (mult:SI (match_dup 0)
1738                  (match_dup 1)))]
1739   "TARGET_SH2"
1740   "dmuls.l      %1,%0"
1741   [(set_attr "type" "dmpy")])
1742
1743 (define_expand "mulsidi3"
1744   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1745         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1746                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1747   "TARGET_SH2 || TARGET_SHMEDIA"
1748   "
1749 {
1750   if (TARGET_SH2)
1751     {
1752        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1753                                         operands[2]));
1754        DONE;
1755     }
1756 }")
1757
1758 (define_insn "mulsidi3_media"
1759   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1760         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1761                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1762   "TARGET_SHMEDIA"
1763   "muls.l       %1, %2, %0"
1764   [(set_attr "type" "dmpy_media")])
1765
1766 (define_insn "mulsidi3_compact"
1767   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1768         (mult:DI
1769          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1770          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1771    (clobber (reg:SI MACH_REG))
1772    (clobber (reg:SI MACL_REG))]
1773   "TARGET_SH2"
1774   "#")
1775
1776 (define_split
1777   [(set (match_operand:DI 0 "arith_reg_operand" "")
1778         (mult:DI
1779          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1780          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1781    (clobber (reg:SI MACH_REG))
1782    (clobber (reg:SI MACL_REG))]
1783   "TARGET_SH2"
1784   [(const_int 0)]
1785   "
1786 {
1787   rtx low_dst = gen_lowpart (SImode, operands[0]);
1788   rtx high_dst = gen_highpart (SImode, operands[0]);
1789
1790   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1791
1792   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1793   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1794   /* We need something to tag the possible REG_EQUAL notes on to.  */
1795   emit_move_insn (operands[0], operands[0]);
1796   DONE;
1797 }")
1798
1799 (define_insn "umulsidi3_i"
1800   [(set (reg:SI MACH_REG)
1801         (truncate:SI
1802          (lshiftrt:DI
1803           (mult:DI
1804            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1805            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1806           (const_int 32))))
1807    (set (reg:SI MACL_REG)
1808         (mult:SI (match_dup 0)
1809                  (match_dup 1)))]
1810   "TARGET_SH2"
1811   "dmulu.l      %1,%0"
1812   [(set_attr "type" "dmpy")])
1813
1814 (define_expand "umulsidi3"
1815   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1816         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1817                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1818   "TARGET_SH2 || TARGET_SHMEDIA"
1819   "
1820 {
1821   if (TARGET_SH2)
1822     {
1823        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1824                                          operands[2]));
1825        DONE;
1826     }
1827 }")
1828
1829 (define_insn "umulsidi3_media"
1830   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1831         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1832                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1833   "TARGET_SHMEDIA"
1834   "mulu.l       %1, %2, %0"
1835   [(set_attr "type" "dmpy_media")])
1836
1837 (define_insn "umulsidi3_compact"
1838   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1839         (mult:DI
1840          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1841          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1842    (clobber (reg:SI MACH_REG))
1843    (clobber (reg:SI MACL_REG))]
1844   "TARGET_SH2"
1845   "#")
1846
1847 (define_split
1848   [(set (match_operand:DI 0 "arith_reg_operand" "")
1849         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1850                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1851    (clobber (reg:SI MACH_REG))
1852    (clobber (reg:SI MACL_REG))]
1853   "TARGET_SH2"
1854   [(const_int 0)]
1855   "
1856 {
1857   rtx low_dst = gen_lowpart (SImode, operands[0]);
1858   rtx high_dst = gen_highpart (SImode, operands[0]);
1859
1860   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1861
1862   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1863   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1864   /* We need something to tag the possible REG_EQUAL notes on to.  */
1865   emit_move_insn (operands[0], operands[0]);
1866   DONE;
1867 }")
1868
1869 (define_insn "smulsi3_highpart_i"
1870   [(set (reg:SI MACH_REG)
1871         (truncate:SI
1872          (lshiftrt:DI
1873           (mult:DI
1874            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1875            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1876           (const_int 32))))
1877    (clobber (reg:SI MACL_REG))]
1878   "TARGET_SH2"
1879   "dmuls.l      %1,%0"
1880   [(set_attr "type" "dmpy")])
1881
1882 (define_expand "smulsi3_highpart"
1883   [(parallel
1884     [(set (reg:SI MACH_REG)
1885           (truncate:SI
1886            (lshiftrt:DI
1887             (mult:DI
1888              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1889              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1890             (const_int 32))))
1891     (clobber (reg:SI MACL_REG))])
1892    (set (match_operand:SI 0 "arith_reg_operand" "")
1893         (reg:SI MACH_REG))]
1894   "TARGET_SH2"
1895   "
1896 {
1897   rtx first, last;
1898
1899   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1900   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1901   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1902      invariant code motion can move it.  */
1903   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1904   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1905   /* expand_binop can't find a suitable code in mul_highpart_optab to
1906      make a REG_EQUAL note from, so make one here.
1907      See also {,u}mulhisi.
1908      ??? Alternatively, we could put this at the calling site of expand_binop,
1909      i.e. expand_mult_highpart.  */
1910   REG_NOTES (last)
1911     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1912                          REG_NOTES (last));
1913   DONE;
1914 }")
1915
1916 (define_insn "umulsi3_highpart_i"
1917   [(set (reg:SI MACH_REG)
1918         (truncate:SI
1919          (lshiftrt:DI
1920           (mult:DI
1921            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1922            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1923           (const_int 32))))
1924    (clobber (reg:SI MACL_REG))]
1925   "TARGET_SH2"
1926   "dmulu.l      %1,%0"
1927   [(set_attr "type" "dmpy")])
1928
1929 (define_expand "umulsi3_highpart"
1930   [(parallel
1931     [(set (reg:SI MACH_REG)
1932           (truncate:SI
1933            (lshiftrt:DI
1934             (mult:DI
1935              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1936              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1937             (const_int 32))))
1938     (clobber (reg:SI MACL_REG))])
1939    (set (match_operand:SI 0 "arith_reg_operand" "")
1940         (reg:SI MACH_REG))]
1941   "TARGET_SH2"
1942   "
1943 {
1944   rtx first, last;
1945
1946   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1947   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1948   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1949      invariant code motion can move it.  */
1950   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1951   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1952   DONE;
1953 }")
1954 \f
1955 ;; -------------------------------------------------------------------------
1956 ;; Logical operations
1957 ;; -------------------------------------------------------------------------
1958
1959 (define_insn "*andsi3_compact"
1960   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1961         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1962                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1963   "TARGET_SH1"
1964   "and  %2,%0"
1965   [(set_attr "type" "arith")])
1966
1967 ;; If the constant is 255, then emit an extu.b instruction instead of an
1968 ;; and, since that will give better code.
1969
1970 (define_expand "andsi3"
1971   [(set (match_operand:SI 0 "arith_reg_operand" "")
1972         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1973                 (match_operand:SI 2 "logical_operand" "")))]
1974   "TARGET_SH1"
1975   "
1976 {
1977   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1978     {
1979       emit_insn (gen_zero_extendqisi2 (operands[0],
1980                                        gen_lowpart (QImode, operands[1])));
1981       DONE;
1982     }
1983 }")
1984
1985 (define_insn_and_split "anddi3"
1986   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1987         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1988                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1989   "TARGET_SHMEDIA"
1990   "@
1991         and     %1, %2, %0
1992         andi    %1, %2, %0
1993         #"
1994   "reload_completed
1995    && ! logical_operand (operands[2], DImode)"
1996   [(const_int 0)]
1997   "
1998 {
1999   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2000     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2001   else
2002     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2003   DONE;
2004 }"
2005   [(set_attr "type" "arith_media")])
2006
2007 (define_insn "andcdi3"
2008   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2009         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2010                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2011   "TARGET_SHMEDIA"
2012   "andc %1,%2,%0"
2013   [(set_attr "type" "arith_media")])
2014
2015 (define_insn "iorsi3"
2016   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2017         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2018                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2019   "TARGET_SH1"
2020   "or   %2,%0"
2021   [(set_attr "type" "arith")])
2022
2023 (define_insn "iordi3"
2024   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2025         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2026                 (match_operand:DI 2 "logical_operand" "r,I10")))]
2027   "TARGET_SHMEDIA"
2028   "@
2029         or      %1, %2, %0
2030         ori     %1, %2, %0"
2031   [(set_attr "type" "arith_media")])
2032
2033 (define_insn "xorsi3"
2034   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2035         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2036                 (match_operand:SI 2 "logical_operand" "K08,r")))]
2037   "TARGET_SH1"
2038   "xor  %2,%0"
2039   [(set_attr "type" "arith")])
2040
2041 (define_insn "xordi3"
2042   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2043         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2044                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2045   "TARGET_SHMEDIA"
2046   "@
2047         xor     %1, %2, %0
2048         xori    %1, %2, %0"
2049   [(set_attr "type" "arith_media")])
2050
2051 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2052 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2053 (define_split
2054   [(set (match_operand:DI 0 "arith_reg_operand" "")
2055         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2056                           [(match_operand 1 "any_register_operand" "")
2057                            (match_operand 2 "any_register_operand" "")])))]
2058   "TARGET_SHMEDIA"
2059   [(set (match_dup 5) (match_dup 4))
2060    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2061 "
2062 {
2063   enum machine_mode inmode = GET_MODE (operands[1]);
2064   int offset = 0;
2065
2066   if (GET_CODE (operands[0]) == SUBREG)
2067     {
2068       offset = SUBREG_BYTE (operands[0]);
2069       operands[0] = SUBREG_REG (operands[0]);
2070     }
2071   if (GET_CODE (operands[0]) != REG)
2072     abort ();
2073   if (! TARGET_LITTLE_ENDIAN)
2074     offset += 8 - GET_MODE_SIZE (inmode);
2075   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2076 }")
2077 \f
2078 ;; -------------------------------------------------------------------------
2079 ;; Shifts and rotates
2080 ;; -------------------------------------------------------------------------
2081
2082 (define_expand "rotldi3"
2083   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2084         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2085                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2086   "TARGET_SHMEDIA"
2087   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2088
2089 (define_insn "rotldi3_mextr"
2090   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2091         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2092                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2093   "TARGET_SHMEDIA"
2094   "*
2095 {
2096   static char templ[16];
2097
2098   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2099            8 - (int) (INTVAL (operands[2]) >> 3));
2100   return templ;
2101 }"
2102   [(set_attr "type" "arith_media")])
2103
2104 (define_expand "rotrdi3"
2105   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2106         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2107                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2108   "TARGET_SHMEDIA"
2109   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2110
2111 (define_insn "rotrdi3_mextr"
2112   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2113         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2114                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2115   "TARGET_SHMEDIA"
2116   "*
2117 {
2118   static char templ[16];
2119
2120   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2121   return templ;
2122 }"
2123   [(set_attr "type" "arith_media")])
2124
2125 (define_insn "rotlsi3_1"
2126   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2127         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2128                    (const_int 1)))
2129    (set (reg:SI T_REG)
2130         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2131   "TARGET_SH1"
2132   "rotl %0"
2133   [(set_attr "type" "arith")])
2134
2135 (define_insn "rotlsi3_31"
2136   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2137         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2138                    (const_int 31)))
2139    (clobber (reg:SI T_REG))]
2140   "TARGET_SH1"
2141   "rotr %0"
2142   [(set_attr "type" "arith")])
2143
2144 (define_insn "rotlsi3_16"
2145   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2146         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2147                    (const_int 16)))]
2148   "TARGET_SH1"
2149   "swap.w       %1,%0"
2150   [(set_attr "type" "arith")])
2151
2152 (define_expand "rotlsi3"
2153   [(set (match_operand:SI 0 "arith_reg_operand" "")
2154         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2155                    (match_operand:SI 2 "immediate_operand" "")))]
2156   "TARGET_SH1"
2157   "
2158 {
2159   static const char rot_tab[] = {
2160     000, 000, 000, 000, 000, 000, 010, 001,
2161     001, 001, 011, 013, 003, 003, 003, 003,
2162     003, 003, 003, 003, 003, 013, 012, 002,
2163     002, 002, 010, 000, 000, 000, 000, 000,
2164   };
2165
2166   int count, choice;
2167
2168   if (GET_CODE (operands[2]) != CONST_INT)
2169     FAIL;
2170   count = INTVAL (operands[2]);
2171   choice = rot_tab[count];
2172   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2173     FAIL;
2174   choice &= 7;
2175   switch (choice)
2176     {
2177     case 0:
2178       emit_move_insn (operands[0], operands[1]);
2179       count -= (count & 16) * 2;
2180       break;
2181     case 3:
2182      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2183      count -= 16;
2184      break;
2185     case 1:
2186     case 2:
2187       {
2188         rtx parts[2];
2189         parts[0] = gen_reg_rtx (SImode);
2190         parts[1] = gen_reg_rtx (SImode);
2191         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2192         parts[choice-1] = operands[1];
2193         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2194         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2195         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2196         count = (count & ~16) - 8;
2197       }
2198     }
2199
2200   for (; count > 0; count--)
2201     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2202   for (; count < 0; count++)
2203     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2204
2205   DONE;
2206 }")
2207
2208 (define_insn "*rotlhi3_8"
2209   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2210         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2211                    (const_int 8)))]
2212   "TARGET_SH1"
2213   "swap.b       %1,%0"
2214   [(set_attr "type" "arith")])
2215
2216 (define_expand "rotlhi3"
2217   [(set (match_operand:HI 0 "arith_reg_operand" "")
2218         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2219                    (match_operand:HI 2 "immediate_operand" "")))]
2220   "TARGET_SH1"
2221   "
2222 {
2223   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2224     FAIL;
2225 }")
2226
2227 ;;
2228 ;; shift left
2229
2230 ;; This pattern is used by init_expmed for computing the costs of shift
2231 ;; insns.
2232
2233 (define_insn_and_split "ashlsi3_std"
2234   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2235         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2236                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2237    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2238   "TARGET_SH3
2239    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2240        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2241   "@
2242    shld %2,%0
2243    add  %0,%0
2244    shll%O2      %0
2245    #"
2246   "TARGET_SH3
2247    && reload_completed
2248    && GET_CODE (operands[2]) == CONST_INT
2249    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2250   [(set (match_dup 3) (match_dup 2))
2251    (parallel
2252     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2253      (clobber (match_dup 4))])]
2254   "operands[4] = gen_rtx_SCRATCH (SImode);"
2255   [(set_attr "length" "*,*,*,4")
2256    (set_attr "type" "dyn_shift,arith,arith,arith")])
2257
2258 (define_insn "ashlhi3_k"
2259   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2260         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2261                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2262   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2263   "@
2264         add     %0,%0
2265         shll%O2 %0"
2266   [(set_attr "type" "arith")])
2267
2268 (define_insn "ashlsi3_n"
2269   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2270         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2271                    (match_operand:SI 2 "const_int_operand" "n")))
2272    (clobber (reg:SI T_REG))]
2273   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2274   "#"
2275   [(set (attr "length")
2276         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2277                (const_string "2")
2278                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2279                (const_string "4")
2280                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2281                (const_string "6")]
2282               (const_string "8")))
2283    (set_attr "type" "arith")])
2284
2285 (define_split
2286   [(set (match_operand:SI 0 "arith_reg_operand" "")
2287         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2288                    (match_operand:SI 2 "const_int_operand" "")))
2289    (clobber (reg:SI T_REG))]
2290   "TARGET_SH1 && reload_completed"
2291   [(use (reg:SI R0_REG))]
2292   "
2293 {
2294   gen_shifty_op (ASHIFT, operands);
2295   DONE;
2296 }")
2297
2298 (define_insn "ashlsi3_media"
2299   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2300         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2301                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2302   "TARGET_SHMEDIA"
2303   "@
2304         shlld.l %1, %2, %0
2305         shlli.l %1, %2, %0"
2306   [(set_attr "type" "arith_media")])
2307
2308 (define_expand "ashlsi3"
2309   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2310                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2311                               (match_operand:SI 2 "nonmemory_operand" "")))
2312               (clobber (reg:SI T_REG))])]
2313   ""
2314   "
2315 {
2316   if (TARGET_SHMEDIA)
2317     {
2318       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2319       DONE;
2320     }
2321   if (GET_CODE (operands[2]) == CONST_INT
2322       && sh_dynamicalize_shift_p (operands[2]))
2323     operands[2] = force_reg (SImode, operands[2]);
2324   if (TARGET_SH3)
2325     {
2326       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2327       DONE;
2328     }
2329   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2330     FAIL;
2331 }")
2332
2333 (define_insn "ashlhi3"
2334   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2335         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2336                    (match_operand:HI 2 "const_int_operand" "n")))
2337    (clobber (reg:SI T_REG))]
2338   "TARGET_SH1"
2339   "#"
2340   [(set (attr "length")
2341         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2342                (const_string "2")
2343                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2344                (const_string "4")]
2345               (const_string "6")))
2346    (set_attr "type" "arith")])
2347
2348 (define_split
2349   [(set (match_operand:HI 0 "arith_reg_operand" "")
2350         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2351                    (match_operand:HI 2 "const_int_operand" "")))
2352    (clobber (reg:SI T_REG))]
2353   "TARGET_SH1 && reload_completed"
2354   [(use (reg:SI R0_REG))]
2355   "
2356 {
2357   gen_shifty_hi_op (ASHIFT, operands);
2358   DONE;
2359 }")
2360
2361 ;
2362 ; arithmetic shift right
2363 ;
2364
2365 (define_insn "ashrsi3_k"
2366   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2367         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2368                      (match_operand:SI 2 "const_int_operand" "M")))
2369    (clobber (reg:SI T_REG))]
2370   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2371   "shar %0"
2372   [(set_attr "type" "arith")])
2373
2374 ;; We can't do HImode right shifts correctly unless we start out with an
2375 ;; explicit zero / sign extension; doing that would result in worse overall
2376 ;; code, so just let the machine independent code widen the mode.
2377 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2378
2379
2380 ;; ??? This should be a define expand.
2381
2382 (define_insn "ashrsi2_16"
2383   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2384         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2385                      (const_int 16)))]
2386   "TARGET_SH1"
2387   "#"
2388   [(set_attr "length" "4")])
2389
2390 (define_split
2391   [(set (match_operand:SI 0 "arith_reg_operand" "")
2392         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2393                      (const_int 16)))]
2394   "TARGET_SH1"
2395   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2396    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2397   "operands[2] = gen_lowpart (HImode, operands[0]);")
2398
2399 ;; ??? This should be a define expand.
2400
2401 (define_insn "ashrsi2_31"
2402   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2403         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2404                      (const_int 31)))
2405    (clobber (reg:SI T_REG))]
2406   "TARGET_SH1"
2407   "#"
2408   [(set_attr "length" "4")])
2409
2410 (define_split
2411   [(set (match_operand:SI 0 "arith_reg_operand" "")
2412         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2413                      (const_int 31)))
2414    (clobber (reg:SI T_REG))]
2415   "TARGET_SH1"
2416   [(const_int 0)]
2417   "
2418 {
2419   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2420   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2421   DONE;
2422 }")
2423
2424 (define_insn "ashlsi_c"
2425   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2426         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2427    (set (reg:SI T_REG)
2428         (lt:SI (match_dup 1) (const_int 0)))]
2429   "TARGET_SH1"
2430   "shll %0"
2431   [(set_attr "type" "arith")])
2432
2433 (define_insn "ashrsi3_d"
2434   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2435         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2436                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2437   "TARGET_SH3"
2438   "shad %2,%0"
2439   [(set_attr "type" "dyn_shift")])
2440
2441 (define_insn "ashrsi3_n"
2442   [(set (reg:SI R4_REG)
2443         (ashiftrt:SI (reg:SI R4_REG)
2444                      (match_operand:SI 0 "const_int_operand" "i")))
2445    (clobber (reg:SI T_REG))
2446    (clobber (reg:SI PR_REG))
2447    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2448   "TARGET_SH1"
2449   "jsr  @%1%#"
2450   [(set_attr "type" "sfunc")
2451    (set_attr "needs_delay_slot" "yes")])
2452
2453 (define_insn "ashrsi3_media"
2454   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2455         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2456                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2457   "TARGET_SHMEDIA"
2458   "@
2459         shard.l %1, %2, %0
2460         shari.l %1, %2, %0"
2461   [(set_attr "type" "arith_media")])
2462
2463 (define_expand "ashrsi3"
2464   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2465                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2466                                 (match_operand:SI 2 "nonmemory_operand" "")))
2467               (clobber (reg:SI T_REG))])]
2468   ""
2469   "
2470 {
2471   if (TARGET_SHMEDIA)
2472     {
2473       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2474       DONE;
2475     }
2476   if (expand_ashiftrt (operands))
2477     DONE;
2478   else
2479     FAIL;
2480 }")
2481
2482 ;; logical shift right
2483
2484 (define_insn "lshrsi3_d"
2485   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2486         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2487                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2488   "TARGET_SH3"
2489   "shld %2,%0"
2490   [(set_attr "type" "dyn_shift")])
2491
2492 ;;  Only the single bit shift clobbers the T bit.
2493
2494 (define_insn "lshrsi3_m"
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" "M")))
2498    (clobber (reg:SI T_REG))]
2499   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2500   "shlr %0"
2501   [(set_attr "type" "arith")])
2502
2503 (define_insn "lshrsi3_k"
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" "P27")))]
2507   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2508    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2509   "shlr%O2      %0"
2510   [(set_attr "type" "arith")])
2511
2512 (define_insn "lshrsi3_n"
2513   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2514         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2515                      (match_operand:SI 2 "const_int_operand" "n")))
2516    (clobber (reg:SI T_REG))]
2517   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2518   "#"
2519   [(set (attr "length")
2520         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2521                (const_string "2")
2522                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2523                (const_string "4")
2524                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2525                (const_string "6")]
2526               (const_string "8")))
2527    (set_attr "type" "arith")])
2528
2529 (define_split
2530   [(set (match_operand:SI 0 "arith_reg_operand" "")
2531         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2532                      (match_operand:SI 2 "const_int_operand" "")))
2533    (clobber (reg:SI T_REG))]
2534   "TARGET_SH1 && reload_completed"
2535   [(use (reg:SI R0_REG))]
2536   "
2537 {
2538   gen_shifty_op (LSHIFTRT, operands);
2539   DONE;
2540 }")
2541
2542 (define_insn "lshrsi3_media"
2543   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2544         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2545                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2546   "TARGET_SHMEDIA"
2547   "@
2548         shlrd.l %1, %2, %0
2549         shlri.l %1, %2, %0"
2550   [(set_attr "type" "arith_media")])
2551
2552 (define_expand "lshrsi3"
2553   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2554                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2555                                 (match_operand:SI 2 "nonmemory_operand" "")))
2556               (clobber (reg:SI T_REG))])]
2557   ""
2558   "
2559 {
2560   if (TARGET_SHMEDIA)
2561     {
2562       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2563       DONE;
2564     }
2565   if (GET_CODE (operands[2]) == CONST_INT
2566       && sh_dynamicalize_shift_p (operands[2]))
2567     operands[2] = force_reg (SImode, operands[2]);
2568   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2569     {
2570       rtx count = copy_to_mode_reg (SImode, operands[2]);
2571       emit_insn (gen_negsi2 (count, count));
2572       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2573       DONE;
2574     }
2575   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2576     FAIL;
2577 }")
2578
2579 ;; ??? This should be a define expand.
2580
2581 (define_insn "ashldi3_k"
2582   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2583         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2584                    (const_int 1)))
2585    (clobber (reg:SI T_REG))]
2586   "TARGET_SH1"
2587   "shll %R0\;rotcl      %S0"
2588   [(set_attr "length" "4")
2589    (set_attr "type" "arith")])
2590
2591 (define_insn "ashldi3_media"
2592   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2593         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2594                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2595   "TARGET_SHMEDIA"
2596   "@
2597         shlld   %1, %2, %0
2598         shlli   %1, %2, %0"
2599   [(set_attr "type" "arith_media")])
2600
2601 (define_expand "ashldi3"
2602   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2603                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2604                               (match_operand:DI 2 "immediate_operand" "")))
2605               (clobber (reg:SI T_REG))])]
2606   ""
2607   "
2608 {
2609   if (TARGET_SHMEDIA)
2610     {
2611       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2612       DONE;
2613     }
2614   if (GET_CODE (operands[2]) != CONST_INT
2615       || INTVAL (operands[2]) != 1)
2616     FAIL;
2617 }")
2618
2619 ;; ??? This should be a define expand.
2620
2621 (define_insn "lshrdi3_k"
2622   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2623         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2624                      (const_int 1)))
2625    (clobber (reg:SI T_REG))]
2626   "TARGET_SH1"
2627   "shlr %S0\;rotcr      %R0"
2628   [(set_attr "length" "4")
2629    (set_attr "type" "arith")])
2630
2631 (define_insn "lshrdi3_media"
2632   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2633         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2634                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2635   "TARGET_SHMEDIA"
2636   "@
2637         shlrd   %1, %2, %0
2638         shlri   %1, %2, %0"
2639   [(set_attr "type" "arith_media")])
2640
2641 (define_expand "lshrdi3"
2642   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2643                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2644                                (match_operand:DI 2 "immediate_operand" "")))
2645              (clobber (reg:SI T_REG))])]
2646   ""
2647   "
2648 {
2649   if (TARGET_SHMEDIA)
2650     {
2651       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2652       DONE;
2653     }
2654   if (GET_CODE (operands[2]) != CONST_INT
2655       || INTVAL (operands[2]) != 1)
2656     FAIL;
2657 }")
2658
2659 ;; ??? This should be a define expand.
2660
2661 (define_insn "ashrdi3_k"
2662   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2663         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2664                      (const_int 1)))
2665    (clobber (reg:SI T_REG))]
2666   "TARGET_SH1"
2667   "shar %S0\;rotcr      %R0"
2668   [(set_attr "length" "4")
2669    (set_attr "type" "arith")])
2670
2671 (define_insn "ashrdi3_media"
2672   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2673         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2674                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2675   "TARGET_SHMEDIA"
2676   "@
2677         shard   %1, %2, %0
2678         shari   %1, %2, %0"
2679   [(set_attr "type" "arith_media")])
2680
2681 (define_expand "ashrdi3"
2682   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2683                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2684                                 (match_operand:DI 2 "immediate_operand" "")))
2685               (clobber (reg:SI T_REG))])]
2686   ""
2687   "
2688 {
2689   if (TARGET_SHMEDIA)
2690     {
2691       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2692       DONE;
2693     }
2694   if (GET_CODE (operands[2]) != CONST_INT
2695       || INTVAL (operands[2]) != 1)
2696     FAIL;
2697 }")
2698
2699 ;; combined left/right shift
2700
2701 (define_split
2702   [(set (match_operand:SI 0 "register_operand" "")
2703         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2704                            (match_operand:SI 2 "const_int_operand" ""))
2705                 (match_operand:SI 3 "const_int_operand" "")))]
2706   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2707   [(use (reg:SI R0_REG))]
2708   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2709    DONE;")
2710
2711 (define_split
2712   [(set (match_operand:SI 0 "register_operand" "")
2713         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2714                            (match_operand:SI 2 "const_int_operand" ""))
2715                 (match_operand:SI 3 "const_int_operand" "")))
2716    (clobber (reg:SI T_REG))]
2717   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2718   [(use (reg:SI R0_REG))]
2719   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2720    DONE;")
2721
2722 (define_insn ""
2723   [(set (match_operand:SI 0 "register_operand" "=r")
2724         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2725                            (match_operand:SI 2 "const_int_operand" "n"))
2726                 (match_operand:SI 3 "const_int_operand" "n")))
2727    (clobber (reg:SI T_REG))]
2728   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2729  "#"
2730   [(set (attr "length")
2731         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2732                (const_string "4")
2733                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2734                (const_string "6")
2735                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2736                (const_string "8")
2737                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2738                (const_string "10")
2739                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2740                (const_string "12")
2741                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2742                (const_string "14")
2743                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2744                (const_string "16")]
2745               (const_string "18")))
2746    (set_attr "type" "arith")])
2747
2748 (define_insn ""
2749   [(set (match_operand:SI 0 "register_operand" "=z")
2750         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2751                            (match_operand:SI 2 "const_int_operand" "n"))
2752                 (match_operand:SI 3 "const_int_operand" "n")))
2753    (clobber (reg:SI T_REG))]
2754   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2755  "#"
2756   [(set (attr "length")
2757         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2758                (const_string "4")
2759                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2760                (const_string "6")
2761                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2762                (const_string "8")]
2763               (const_string "10")))
2764    (set_attr "type" "arith")])
2765
2766 ;; shift left / and combination with a scratch register: The combine pass
2767 ;; does not accept the individual instructions, even though they are
2768 ;; cheap.  But it needs a precise description so that it is usable after
2769 ;; reload.
2770 (define_insn "and_shl_scratch"
2771   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2772         (lshiftrt:SI
2773          (ashift:SI
2774           (and:SI
2775            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2776                         (match_operand:SI 2 "const_int_operand" "N,n"))
2777            (match_operand:SI 3 "" "0,r"))
2778           (match_operand:SI 4 "const_int_operand" "n,n"))
2779          (match_operand:SI 5 "const_int_operand" "n,n")))
2780    (clobber (reg:SI T_REG))]
2781   "TARGET_SH1"
2782   "#"
2783   [(set (attr "length")
2784         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2785                (const_string "4")
2786                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2787                (const_string "6")
2788                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2789                (const_string "8")
2790                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2791                (const_string "10")]
2792               (const_string "12")))
2793    (set_attr "type" "arith")])
2794
2795 (define_split
2796   [(set (match_operand:SI 0 "register_operand" "")
2797         (lshiftrt:SI
2798          (ashift:SI
2799           (and:SI
2800            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2801                         (match_operand:SI 2 "const_int_operand" ""))
2802            (match_operand:SI 3 "register_operand" ""))
2803           (match_operand:SI 4 "const_int_operand" ""))
2804          (match_operand:SI 5 "const_int_operand" "")))
2805    (clobber (reg:SI T_REG))]
2806   "TARGET_SH1"
2807   [(use (reg:SI R0_REG))]
2808   "
2809 {
2810   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2811
2812   if (INTVAL (operands[2]))
2813     {
2814       gen_shifty_op (LSHIFTRT, operands);
2815     }
2816   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2817   operands[2] = operands[4];
2818   gen_shifty_op (ASHIFT, operands);
2819   if (INTVAL (operands[5]))
2820     {
2821       operands[2] = operands[5];
2822       gen_shifty_op (LSHIFTRT, operands);
2823     }
2824   DONE;
2825 }")
2826
2827 ;; signed left/right shift combination.
2828 (define_split
2829   [(set (match_operand:SI 0 "register_operand" "")
2830         (sign_extract:SI
2831          (ashift:SI (match_operand:SI 1 "register_operand" "")
2832                     (match_operand:SI 2 "const_int_operand" ""))
2833          (match_operand:SI 3 "const_int_operand" "")
2834          (const_int 0)))
2835    (clobber (reg:SI T_REG))]
2836   "TARGET_SH1"
2837   [(use (reg:SI R0_REG))]
2838   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2839    DONE;")
2840
2841 (define_insn "shl_sext_ext"
2842   [(set (match_operand:SI 0 "register_operand" "=r")
2843         (sign_extract:SI
2844          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2845                     (match_operand:SI 2 "const_int_operand" "n"))
2846          (match_operand:SI 3 "const_int_operand" "n")
2847          (const_int 0)))
2848    (clobber (reg:SI T_REG))]
2849   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2850   "#"
2851   [(set (attr "length")
2852         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2853                (const_string "2")
2854                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2855                (const_string "4")
2856                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2857                (const_string "6")
2858                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2859                (const_string "8")
2860                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2861                (const_string "10")
2862                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2863                (const_string "12")
2864                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2865                (const_string "14")
2866                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2867                (const_string "16")]
2868               (const_string "18")))
2869     (set_attr "type" "arith")])
2870
2871 (define_insn "shl_sext_sub"
2872   [(set (match_operand:SI 0 "register_operand" "=z")
2873         (sign_extract:SI
2874          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2875                     (match_operand:SI 2 "const_int_operand" "n"))
2876          (match_operand:SI 3 "const_int_operand" "n")
2877          (const_int 0)))
2878    (clobber (reg:SI T_REG))]
2879   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2880   "#"
2881   [(set (attr "length")
2882         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2883                (const_string "6")
2884                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2885                (const_string "8")
2886                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2887                (const_string "10")
2888                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2889                (const_string "12")]
2890               (const_string "14")))
2891     (set_attr "type" "arith")])
2892
2893 ;; These patterns are found in expansions of DImode shifts by 16, and
2894 ;; allow the xtrct instruction to be generated from C source.
2895
2896 (define_insn "xtrct_left"
2897   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2898         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2899                            (const_int 16))
2900                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2901                              (const_int 16))))]
2902   "TARGET_SH1"
2903   "xtrct        %1,%0"
2904   [(set_attr "type" "arith")])
2905
2906 (define_insn "xtrct_right"
2907   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2908         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2909                              (const_int 16))
2910                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2911                            (const_int 16))))]
2912   "TARGET_SH1"
2913   "xtrct        %2,%0"
2914   [(set_attr "type" "arith")])
2915
2916 ;; -------------------------------------------------------------------------
2917 ;; Unary arithmetic
2918 ;; -------------------------------------------------------------------------
2919
2920 (define_insn "negc"
2921   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2922         (neg:SI (plus:SI (reg:SI T_REG)
2923                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2924    (set (reg:SI T_REG)
2925         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2926                (const_int 0)))]
2927   "TARGET_SH1"
2928   "negc %1,%0"
2929   [(set_attr "type" "arith")])
2930
2931 (define_insn "*negdi_media"
2932   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2933         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2934   "TARGET_SHMEDIA"
2935   "sub  r63, %1, %0"
2936   [(set_attr "type" "arith_media")])
2937
2938 (define_expand "negdi2"
2939   [(set (match_operand:DI 0 "arith_reg_operand" "")
2940         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2941   ""
2942   "
2943 {
2944   if (TARGET_SH1)
2945     {
2946       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2947       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2948
2949       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2950       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2951
2952       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2953       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2954
2955       emit_insn (gen_clrt ());
2956       emit_insn (gen_negc (low_dst, low_src));
2957       emit_insn (gen_negc (high_dst, high_src));
2958       DONE;
2959     }
2960 }")
2961
2962 (define_insn "negsi2"
2963   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2964         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2965   "TARGET_SH1"
2966   "neg  %1,%0"
2967   [(set_attr "type" "arith")])
2968
2969 (define_insn "one_cmplsi2"
2970   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2971         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2972   "TARGET_SH1"
2973   "not  %1,%0"
2974   [(set_attr "type" "arith")])
2975
2976 (define_expand "one_cmpldi2"
2977   [(set (match_operand:DI 0 "arith_reg_operand" "")
2978         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2979                 (const_int -1)))]
2980   "TARGET_SHMEDIA" "")
2981 \f
2982 ;; -------------------------------------------------------------------------
2983 ;; Zero extension instructions
2984 ;; -------------------------------------------------------------------------
2985
2986 (define_insn "zero_extendsidi2"
2987   [(set (match_operand:DI 0 "register_operand" "=r")
2988         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2989   "TARGET_SHMEDIA"
2990   "addz.l       %1, r63, %0"
2991   [(set_attr "type" "arith_media")])
2992
2993 (define_insn "zero_extendhidi2"
2994   [(set (match_operand:DI 0 "register_operand" "=r,r")
2995         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2996   "TARGET_SHMEDIA"
2997   "@
2998         #
2999         ld%M1.uw        %m1, %0"
3000   [(set_attr "type" "*,load_media")])
3001
3002 (define_split
3003   [(set (match_operand:DI 0 "register_operand" "")
3004         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3005   "TARGET_SHMEDIA && reload_completed"
3006   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3007    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3008   "
3009 {
3010   if (GET_CODE (operands[1]) == TRUNCATE)
3011     operands[1] = XEXP (operands[1], 0);
3012 }")
3013
3014 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3015 ;; reload the entire truncate expression.
3016 (define_insn_and_split "*loaddi_trunc"
3017   [(set (match_operand 0 "int_gpr_dest" "=r")
3018         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3019   "TARGET_SHMEDIA && reload_completed"
3020   "#"
3021   "TARGET_SHMEDIA && reload_completed"
3022   [(set (match_dup 0) (match_dup 1))]
3023   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3024
3025 (define_insn "zero_extendqidi2"
3026   [(set (match_operand:DI 0 "register_operand" "=r,r")
3027         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3028   "TARGET_SHMEDIA"
3029   "@
3030         andi    %1, 255, %0
3031         ld%M1.ub        %m1, %0"
3032   [(set_attr "type" "arith_media,load_media")])
3033
3034 (define_expand "zero_extendhisi2"
3035   [(set (match_operand:SI 0 "arith_reg_operand" "")
3036         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3037   ""
3038   "
3039 {
3040   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3041     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3042 }")
3043
3044 (define_insn "*zero_extendhisi2_compact"
3045   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3046         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3047   "TARGET_SH1"
3048   "extu.w       %1,%0"
3049   [(set_attr "type" "arith")])
3050
3051 (define_insn "*zero_extendhisi2_media"
3052   [(set (match_operand:SI 0 "register_operand" "=r,r")
3053         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3054   "TARGET_SHMEDIA"
3055   "@
3056         #
3057         ld%M1.uw        %m1, %0"
3058   [(set_attr "type" "arith_media,load_media")])
3059
3060 (define_split
3061   [(set (match_operand:SI 0 "register_operand" "")
3062         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3063   "TARGET_SHMEDIA && reload_completed"
3064   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3065    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3066   "
3067 {
3068   if (GET_CODE (operands[1]) == TRUNCATE)
3069     operands[1] = XEXP (operands[1], 0);
3070 }")
3071
3072 (define_expand "zero_extendqisi2"
3073   [(set (match_operand:SI 0 "arith_reg_operand" "")
3074         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3075   ""
3076   "
3077 {
3078   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3079     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3080 }")
3081
3082 (define_insn "*zero_extendqisi2_compact"
3083   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3084         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3085   "TARGET_SH1"
3086   "extu.b       %1,%0"
3087   [(set_attr "type" "arith")])
3088
3089 (define_insn "*zero_extendqisi2_media"
3090   [(set (match_operand:SI 0 "register_operand" "=r,r")
3091         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3092   "TARGET_SHMEDIA"
3093   "@
3094         andi    %1, 255, %0
3095         ld%M1.ub        %m1, %0"
3096   [(set_attr "type" "arith_media,load_media")])
3097
3098 (define_insn "zero_extendqihi2"
3099   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3100         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3101   "TARGET_SH1"
3102   "extu.b       %1,%0"
3103   [(set_attr "type" "arith")])
3104
3105 ;; -------------------------------------------------------------------------
3106 ;; Sign extension instructions
3107 ;; -------------------------------------------------------------------------
3108
3109 ;; ??? This should be a define expand.
3110 ;; ??? Or perhaps it should be dropped?
3111
3112 ;; convert_move generates good code for SH[1-4].
3113 (define_insn "extendsidi2"
3114   [(set (match_operand:DI 0 "register_operand" "=r,r")
3115         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3116   "TARGET_SHMEDIA"
3117   "@
3118         add.l   %1, r63, %0
3119         ld%M1.l %m1, %0"
3120   [(set_attr "type" "arith_media,load_media")])
3121
3122 (define_insn "extendhidi2"
3123   [(set (match_operand:DI 0 "register_operand" "=r,r")
3124         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3125   "TARGET_SHMEDIA"
3126   "@
3127         #
3128         ld%M1.w %m1, %0"
3129   [(set_attr "type" "*,load_media")])
3130
3131 (define_split
3132   [(set (match_operand:DI 0 "register_operand" "")
3133         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3134   "TARGET_SHMEDIA && reload_completed"
3135   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3136    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3137   "
3138 {
3139   if (GET_CODE (operands[1]) == TRUNCATE)
3140     operands[1] = XEXP (operands[1], 0);
3141 }")
3142
3143 (define_insn "extendqidi2"
3144   [(set (match_operand:DI 0 "register_operand" "=r,r")
3145         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3146   "TARGET_SHMEDIA"
3147   "@
3148         #
3149         ld%M1.b %m1, %0"
3150   [(set_attr "type" "*,load_media")])
3151
3152 (define_split
3153   [(set (match_operand:DI 0 "register_operand" "")
3154         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3155   "TARGET_SHMEDIA && reload_completed"
3156   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3157    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3158   "
3159 {
3160   if (GET_CODE (operands[1]) == TRUNCATE)
3161     operands[1] = XEXP (operands[1], 0);
3162 }")
3163
3164 (define_expand "extendhisi2"
3165   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3166        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3167   ""
3168   "")
3169
3170 (define_insn "*extendhisi2_compact"
3171   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3172         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3173   "TARGET_SH1"
3174   "@
3175         exts.w  %1,%0
3176         mov.w   %1,%0"
3177   [(set_attr "type" "arith,load")])
3178
3179 (define_insn "*extendhisi2_media"
3180   [(set (match_operand:SI 0 "register_operand" "=r,r")
3181         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3182   "TARGET_SHMEDIA"
3183   "@
3184         #
3185         ld%M1.w %m1, %0"
3186   [(set_attr "type" "arith_media,load_media")])
3187
3188 (define_split
3189   [(set (match_operand:SI 0 "register_operand" "")
3190         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3191   "TARGET_SHMEDIA && reload_completed"
3192   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3193    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3194   "
3195 {
3196   if (GET_CODE (operands[1]) == TRUNCATE)
3197     operands[1] = XEXP (operands[1], 0);
3198 }")
3199
3200 (define_expand "extendqisi2"
3201   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3202         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3203   ""
3204   "")
3205
3206 (define_insn "*extendqisi2_compact"
3207   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3208         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3209   "TARGET_SH1"
3210   "@
3211         exts.b  %1,%0
3212         mov.b   %1,%0"
3213   [(set_attr "type" "arith,load")])
3214
3215 (define_insn "*extendqisi2_media"
3216   [(set (match_operand:SI 0 "register_operand" "=r,r")
3217         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3218   "TARGET_SHMEDIA"
3219   "@
3220         #
3221         ld%M1.b %m1, %0"
3222   [(set_attr "type" "arith_media,load_media")])
3223
3224 (define_split
3225   [(set (match_operand:SI 0 "register_operand" "")
3226         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3227   "TARGET_SHMEDIA && reload_completed"
3228   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3229    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3230    "
3231 {
3232   if (GET_CODE (operands[1]) == TRUNCATE)
3233     operands[1] = XEXP (operands[1], 0);
3234 }")
3235
3236 (define_insn "extendqihi2"
3237   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3238         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3239   "TARGET_SH1"
3240   "@
3241         exts.b  %1,%0
3242         mov.b   %1,%0"
3243   [(set_attr "type" "arith,load")])
3244
3245 /* It would seem useful to combine the truncXi patterns into the movXi
3246    patterns, but unary operators are ignored when matching constraints,
3247    so we need separate patterns.  */
3248 (define_insn "truncdisi2"
3249   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3250         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3251   "TARGET_SHMEDIA"
3252   "@
3253         add.l   %1, r63, %0
3254         st%M0.l %m0, %1
3255         fst%M0.s        %m0, %T1
3256         fmov.ls %1, %0
3257         fmov.sl %T1, %0
3258         fmov.s  %T1, %0"
3259   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3260
3261
3262 (define_insn "truncdihi2"
3263   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3264         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3265   "TARGET_SHMEDIA"
3266   "@
3267         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3268         st%M0.w %m0, %1"
3269   [(set_attr "type"   "arith_media,store_media")
3270    (set_attr "length" "8,4")])
3271
3272 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3273 ; Because we use zero extension, we can't provide signed QImode compares
3274 ; using a simple compare or conditional banch insn.
3275 (define_insn "truncdiqi2"
3276   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3277         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3278   "TARGET_SHMEDIA"
3279   "@
3280         and     %1, 255, %0
3281         st%M0.b %m0, %1"
3282   [(set_attr "type"   "arith_media,store")])
3283
3284 ;; -------------------------------------------------------------------------
3285 ;; Move instructions
3286 ;; -------------------------------------------------------------------------
3287
3288 ;; define push and pop so it is easy for sh.c
3289 ;; We can't use push and pop on SHcompact because the stack must always
3290 ;; be 8-byte aligned.
3291
3292 (define_expand "push"
3293   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3294         (match_operand:SI 0 "register_operand" "r,l,x"))]
3295   "TARGET_SH1 && ! TARGET_SH5"
3296   "")
3297
3298 (define_expand "pop"
3299   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3300         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3301   "TARGET_SH1 && ! TARGET_SH5"
3302   "")
3303
3304 (define_expand "push_e"
3305   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3306                    (match_operand:SF 0 "" ""))
3307               (use (reg:PSI FPSCR_REG))
3308               (clobber (scratch:SI))])]
3309   "TARGET_SH1 && ! TARGET_SH5"
3310   "")
3311
3312 (define_insn "push_fpul"
3313   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3314   "TARGET_SH2E && ! TARGET_SH5"
3315   "sts.l        fpul,@-r15"
3316   [(set_attr "type" "store")
3317    (set_attr "late_fp_use" "yes")
3318    (set_attr "hit_stack" "yes")])
3319
3320 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3321 ;; so use that.
3322 (define_expand "push_4"
3323   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3324                    (match_operand:DF 0 "" ""))
3325               (use (reg:PSI FPSCR_REG))
3326               (clobber (scratch:SI))])]
3327   "TARGET_SH1 && ! TARGET_SH5"
3328   "")
3329
3330 (define_expand "pop_e"
3331   [(parallel [(set (match_operand:SF 0 "" "")
3332               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3333               (use (reg:PSI FPSCR_REG))
3334               (clobber (scratch:SI))])]
3335   "TARGET_SH1 && ! TARGET_SH5"
3336   "")
3337
3338 (define_insn "pop_fpul"
3339   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3340   "TARGET_SH2E && ! TARGET_SH5"
3341   "lds.l        @r15+,fpul"
3342   [(set_attr "type" "load")
3343    (set_attr "hit_stack" "yes")])
3344
3345 (define_expand "pop_4"
3346   [(parallel [(set (match_operand:DF 0 "" "")
3347                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3348               (use (reg:PSI FPSCR_REG))
3349               (clobber (scratch:SI))])]
3350   "TARGET_SH1 && ! TARGET_SH5"
3351   "")
3352
3353 (define_expand "push_fpscr"
3354   [(const_int 0)]
3355   "TARGET_SH2E"
3356   "
3357 {
3358   rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
3359                                                  gen_rtx (PRE_DEC, Pmode,
3360                                                           stack_pointer_rtx)),
3361                                         get_fpscr_rtx ()));
3362   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3363   DONE;
3364 }")
3365
3366 (define_expand "pop_fpscr"
3367   [(const_int 0)]
3368   "TARGET_SH2E"
3369   "
3370 {
3371   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3372                                         gen_rtx (MEM, PSImode,
3373                                                  gen_rtx (POST_INC, Pmode,
3374                                                           stack_pointer_rtx))));
3375   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
3376   DONE;
3377 }")
3378
3379 ;; These two patterns can happen as the result of optimization, when
3380 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3381 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3382
3383 (define_insn "clrt"
3384   [(set (reg:SI T_REG) (const_int 0))]
3385   "TARGET_SH1"
3386   "clrt")
3387
3388 (define_insn "sett"
3389   [(set (reg:SI T_REG) (const_int 1))]
3390   "TARGET_SH1"
3391   "sett")
3392
3393 ;; t/r must come after r/r, lest reload will try to reload stuff like
3394 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3395 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3396 (define_insn "movsi_i"
3397   [(set (match_operand:SI 0 "general_movdst_operand"
3398             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3399         (match_operand:SI 1 "general_movsrc_operand"
3400          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3401   "TARGET_SH1
3402    && ! TARGET_SH2E
3403    && (register_operand (operands[0], SImode)
3404        || register_operand (operands[1], SImode))"
3405   "@
3406         mov.l   %1,%0
3407         mov     %1,%0
3408         cmp/pl  %1
3409         mov.l   %1,%0
3410         sts     %1,%0
3411         sts     %1,%0
3412         movt    %0
3413         mov.l   %1,%0
3414         sts.l   %1,%0
3415         sts.l   %1,%0
3416         lds     %1,%0
3417         lds     %1,%0
3418         lds.l   %1,%0
3419         lds.l   %1,%0
3420         fake    %1,%0"
3421   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3422    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3423
3424 ;; t/r must come after r/r, lest reload will try to reload stuff like
3425 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3426 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3427 ;; will require a reload.
3428 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3429 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3430 (define_insn "movsi_ie"
3431   [(set (match_operand:SI 0 "general_movdst_operand"
3432             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3433         (match_operand:SI 1 "general_movsrc_operand"
3434          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3435   "TARGET_SH2E
3436    && (register_operand (operands[0], SImode)
3437        || register_operand (operands[1], SImode))"
3438   "@
3439         mov.l   %1,%0
3440         mov     %1,%0
3441         cmp/pl  %1
3442         mov.l   %1,%0
3443         sts     %1,%0
3444         sts     %1,%0
3445         movt    %0
3446         mov.l   %1,%0
3447         sts.l   %1,%0
3448         sts.l   %1,%0
3449         lds     %1,%0
3450         lds     %1,%0
3451         lds.l   %1,%0
3452         lds.l   %1,%0
3453         lds.l   %1,%0
3454         sts.l   %1,%0
3455         fake    %1,%0
3456         lds     %1,%0
3457         sts     %1,%0
3458         fsts    fpul,%0
3459         flds    %1,fpul
3460         fmov    %1,%0
3461         ! move optimized away"
3462   [(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")
3463    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3464    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3465
3466 (define_insn "movsi_i_lowpart"
3467   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3468         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3469    "TARGET_SH1
3470     && (register_operand (operands[0], SImode)
3471         || register_operand (operands[1], SImode))"
3472   "@
3473         mov.l   %1,%0
3474         mov     %1,%0
3475         mov.l   %1,%0
3476         sts     %1,%0
3477         sts     %1,%0
3478         movt    %0
3479         mov.l   %1,%0
3480         fake    %1,%0"
3481   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3482
3483 (define_insn_and_split "load_ra"
3484   [(set (match_operand:SI 0 "general_movdst_operand" "")
3485         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3486   "TARGET_SH1"
3487   "#"
3488   "&& ! rtx_equal_function_value_matters"
3489   [(set (match_dup 0) (match_dup 1))]
3490   "
3491 {
3492   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3493     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3494 }")
3495
3496 (define_insn "*movsi_media"
3497   [(set (match_operand:SI 0 "general_movdst_operand"
3498                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3499         (match_operand:SI 1 "general_movsrc_operand"
3500          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3501   "TARGET_SHMEDIA_FPU
3502    && (register_operand (operands[0], SImode)
3503        || sh_register_operand (operands[1], SImode))"
3504   "@
3505         add.l   %1, r63, %0
3506         movi    %1, %0
3507         #
3508         ld%M1.l %m1, %0
3509         st%M0.l %m0, %N1
3510         fld%M1.s        %m1, %0
3511         fst%M0.s        %m0, %1
3512         fmov.ls %N1, %0
3513         fmov.sl %1, %0
3514         fmov.s  %1, %0
3515         ptabs   %1, %0
3516         gettr   %1, %0
3517         pt      %1, %0"
3518   [(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")
3519    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3520
3521 (define_insn "*movsi_media_nofpu"
3522   [(set (match_operand:SI 0 "general_movdst_operand"
3523                 "=r,r,r,r,m,*b,r,b")
3524         (match_operand:SI 1 "general_movsrc_operand"
3525          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3526   "TARGET_SHMEDIA
3527    && (register_operand (operands[0], SImode)
3528        || sh_register_operand (operands[1], SImode))"
3529   "@
3530         add.l   %1, r63, %0
3531         movi    %1, %0
3532         #
3533         ld%M1.l %m1, %0
3534         st%M0.l %m0, %N1
3535         ptabs   %1, %0
3536         gettr   %1, %0
3537         pt      %1, %0"
3538   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3539    (set_attr "length" "4,4,8,4,4,4,4,12")])
3540
3541 (define_split
3542   [(set (match_operand:SI 0 "arith_reg_operand" "")
3543         (match_operand:SI 1 "immediate_operand" ""))]
3544   "TARGET_SHMEDIA && reload_completed
3545    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3546   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3547   "
3548 {
3549   operands[2] = shallow_copy_rtx (operands[1]);
3550   PUT_MODE (operands[2], DImode);
3551 }")
3552
3553 (define_split
3554   [(set (match_operand:SI 0 "register_operand" "")
3555         (match_operand:SI 1 "immediate_operand" ""))]
3556   "TARGET_SHMEDIA && reload_completed
3557    && ((GET_CODE (operands[1]) == CONST_INT
3558         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3559        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3560   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3561
3562 (define_expand "movsi"
3563   [(set (match_operand:SI 0 "general_movdst_operand" "")
3564         (match_operand:SI 1 "general_movsrc_operand" ""))]
3565   ""
3566   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3567
3568 (define_expand "ic_invalidate_line"
3569   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3570                                 (match_dup 1)] UNSPEC_ICACHE)
3571               (clobber (scratch:SI))])]
3572   "TARGET_HARD_SH4 || TARGET_SH5"
3573   "
3574 {
3575   if (TARGET_SHMEDIA)
3576     {
3577       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3578       DONE;
3579     }
3580   else if (TARGET_SHCOMPACT)
3581     {
3582       operands[1] = function_symbol (\"__ic_invalidate\");
3583       operands[1] = force_reg (Pmode, operands[1]);
3584       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3585       DONE;
3586     }
3587   operands[0] = force_reg (Pmode, operands[0]);
3588   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3589                                                                Pmode)));
3590 }")
3591
3592 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3593 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3594 ;; the requirement *1*00 for associative address writes.  The alignment of
3595 ;; %0 implies that its least significant bit is cleared,
3596 ;; thus we clear the V bit of a matching entry if there is one.
3597 (define_insn "ic_invalidate_line_i"
3598   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3599                      (match_operand:SI 1 "register_operand" "r")]
3600                      UNSPEC_ICACHE)
3601    (clobber (match_scratch:SI 2 "=&r"))]
3602   "TARGET_HARD_SH4"
3603   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3604   [(set_attr "length" "8")
3605    (set_attr "type" "cwb")])
3606
3607 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3608 ;; an add in the code that calculates the address.
3609 (define_insn "ic_invalidate_line_media"
3610   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3611                     UNSPEC_ICACHE)]
3612   "TARGET_SHMEDIA"
3613   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3614   [(set_attr "length" "16")
3615    (set_attr "type" "invalidate_line_media")])
3616
3617 (define_insn "ic_invalidate_line_compact"
3618   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3619                      (match_operand:SI 1 "register_operand" "r")]
3620                     UNSPEC_ICACHE)
3621    (clobber (reg:SI PR_REG))]
3622   "TARGET_SHCOMPACT"
3623   "jsr @%1%#"
3624   [(set_attr "type" "sfunc")
3625    (set_attr "needs_delay_slot" "yes")])
3626
3627 (define_expand "initialize_trampoline"
3628   [(match_operand:SI 0 "" "")
3629    (match_operand:SI 1 "" "")
3630    (match_operand:SI 2 "" "")]
3631   "TARGET_SHCOMPACT"
3632   "
3633 {
3634   rtx sfun, tramp;
3635
3636   tramp = force_reg (Pmode, operands[0]);
3637   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3638   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3639   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3640
3641   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3642   DONE;
3643 }")
3644
3645 (define_insn "initialize_trampoline_compact"
3646   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3647                      (match_operand:SI 1 "register_operand" "r")
3648                      (reg:SI R2_REG) (reg:SI R3_REG)]
3649                     UNSPEC_INIT_TRAMP)
3650
3651    (clobber (reg:SI PR_REG))]
3652   "TARGET_SHCOMPACT"
3653   "jsr @%1%#"
3654   [(set_attr "type" "sfunc")
3655    (set_attr "needs_delay_slot" "yes")])
3656
3657 (define_insn "movqi_i"
3658   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3659         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3660   "TARGET_SH1
3661    && (arith_reg_operand (operands[0], QImode)
3662        || arith_reg_operand (operands[1], QImode))"
3663   "@
3664         mov     %1,%0
3665         mov.b   %1,%0
3666         mov.b   %1,%0
3667         movt    %0
3668         sts     %1,%0
3669         lds     %1,%0"
3670  [(set_attr "type" "move,load,store,move,move,move")])
3671
3672 (define_insn "*movqi_media"
3673   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3674         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3675   "TARGET_SHMEDIA
3676    && (arith_reg_operand (operands[0], QImode)
3677        || arith_reg_or_0_operand (operands[1], QImode))"
3678   "@
3679         add.l   %1, r63, %0
3680         movi    %1, %0
3681         ld%M1.ub        %m1, %0
3682         st%M0.b %m0, %N1"
3683   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3684
3685 (define_expand "movqi"
3686   [(set (match_operand:QI 0 "general_operand" "")
3687         (match_operand:QI 1 "general_operand"  ""))]
3688   ""
3689   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3690
3691 (define_expand "reload_inqi"
3692   [(set (match_operand:SI 2 "" "=&r")
3693         (match_operand:QI 1 "inqhi_operand" ""))
3694    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3695         (truncate:QI (match_dup 3)))]
3696   "TARGET_SHMEDIA"
3697   "
3698 {
3699   rtx inner = XEXP (operands[1], 0);
3700   int regno = REGNO (inner);
3701
3702   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3703   operands[1] = gen_rtx_REG (SImode, regno);
3704   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3705 }")
3706
3707 /* When storing r0, we have to avoid reg+reg addressing.  */
3708 (define_insn "movhi_i"
3709   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3710         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3711   "TARGET_SH1
3712    && (arith_reg_operand (operands[0], HImode)
3713        || arith_reg_operand (operands[1], HImode))
3714    && (GET_CODE (operands[0]) != MEM
3715        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3716        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3717        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3718   "@
3719         mov.w   %1,%0
3720         mov     %1,%0
3721         mov.w   %1,%0
3722         movt    %0
3723         mov.w   %1,%0
3724         sts     %1,%0
3725         lds     %1,%0
3726         fake    %1,%0"
3727   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3728
3729 (define_insn "*movhi_media"
3730   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3731         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3732   "TARGET_SHMEDIA
3733    && (arith_reg_operand (operands[0], HImode)
3734        || arith_reg_or_0_operand (operands[1], HImode))"
3735   "@
3736         add.l   %1, r63, %0
3737         movi    %1, %0
3738         #
3739         ld%M1.w %m1, %0
3740         st%M0.w %m0, %N1"
3741   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3742
3743 (define_split
3744   [(set (match_operand:HI 0 "register_operand" "")
3745         (match_operand:HI 1 "immediate_operand" ""))]
3746   "TARGET_SHMEDIA && reload_completed
3747    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3748   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3749
3750 (define_expand "movhi"
3751   [(set (match_operand:HI 0 "general_movdst_operand" "")
3752         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3753   ""
3754   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3755
3756 (define_expand "reload_inhi"
3757   [(set (match_operand:SI 2 "" "=&r")
3758         (match_operand:HI 1 "inqhi_operand" ""))
3759    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3760         (truncate:HI (match_dup 3)))]
3761   "TARGET_SHMEDIA"
3762   "
3763 {
3764   rtx inner = XEXP (operands[1], 0);
3765   int regno = REGNO (inner);
3766
3767   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3768   operands[1] = gen_rtx_REG (SImode, regno);
3769   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3770 }")
3771
3772 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3773 ;; compiled with -m2 -ml -O3 -funroll-loops
3774 (define_insn "*movdi_i"
3775   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3776         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3777   "TARGET_SH1
3778    && (arith_reg_operand (operands[0], DImode)
3779        || arith_reg_operand (operands[1], DImode))"
3780   "* return output_movedouble (insn, operands, DImode);"
3781   [(set_attr "length" "4")
3782    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3783
3784 ;; If the output is a register and the input is memory or a register, we have
3785 ;; to be careful and see which word needs to be loaded first.
3786
3787 (define_split
3788   [(set (match_operand:DI 0 "general_movdst_operand" "")
3789         (match_operand:DI 1 "general_movsrc_operand" ""))]
3790   "TARGET_SH1 && reload_completed"
3791   [(set (match_dup 2) (match_dup 3))
3792    (set (match_dup 4) (match_dup 5))]
3793   "
3794 {
3795   int regno;
3796
3797   if ((GET_CODE (operands[0]) == MEM
3798        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3799       || (GET_CODE (operands[1]) == MEM
3800           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3801     FAIL;
3802
3803   if (GET_CODE (operands[0]) == REG)
3804     regno = REGNO (operands[0]);
3805   else if (GET_CODE (operands[0]) == SUBREG)
3806     regno = subreg_regno (operands[0]);
3807   else if (GET_CODE (operands[0]) == MEM)
3808     regno = -1;
3809   else
3810     abort ();
3811
3812   if (regno == -1
3813       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3814     {
3815       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3816       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3817       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3818       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3819     }
3820   else
3821     {
3822       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3823       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3824       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3825       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3826     }
3827
3828   if (operands[2] == 0 || operands[3] == 0
3829       || operands[4] == 0 || operands[5] == 0)
3830     FAIL;
3831 }")
3832
3833 (define_insn "*movdi_media"
3834   [(set (match_operand:DI 0 "general_movdst_operand"
3835                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3836         (match_operand:DI 1 "general_movsrc_operand"
3837          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3838   "TARGET_SHMEDIA_FPU
3839    && (register_operand (operands[0], DImode)
3840        || sh_register_operand (operands[1], DImode))"
3841   "@
3842         add     %1, r63, %0
3843         movi    %1, %0
3844         #
3845         ld%M1.q %m1, %0
3846         st%M0.q %m0, %N1
3847         fld%M1.d        %m1, %0
3848         fst%M0.d        %m0, %1
3849         fmov.qd %N1, %0
3850         fmov.dq %1, %0
3851         fmov.d  %1, %0
3852         ptabs   %1, %0
3853         gettr   %1, %0
3854         pt      %1, %0"
3855   [(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")
3856    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3857
3858 (define_insn "*movdi_media_nofpu"
3859   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3860         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3861   "TARGET_SHMEDIA
3862    && (register_operand (operands[0], DImode)
3863        || sh_register_operand (operands[1], DImode))"
3864   "@
3865         add     %1, r63, %0
3866         movi    %1, %0
3867         #
3868         ld%M1.q %m1, %0
3869         st%M0.q %m0, %N1
3870         ptabs   %1, %0
3871         gettr   %1, %0
3872         pt      %1, %0"
3873   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3874    (set_attr "length" "4,4,16,4,4,4,4,*")])
3875
3876 (define_split
3877   [(set (match_operand:DI 0 "arith_reg_operand" "")
3878         (match_operand:DI 1 "immediate_operand" ""))]
3879   "TARGET_SHMEDIA && reload_completed
3880    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3881   [(set (match_dup 0) (match_dup 1))]
3882   "
3883 {
3884   rtx insn;
3885
3886   if (TARGET_SHMEDIA64)
3887     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3888   else
3889     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3890
3891   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3892                                         REG_NOTES (insn));
3893
3894   DONE;
3895 }")
3896
3897 (define_expand "movdi_const"
3898   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3899         (const:DI (sign_extend:DI
3900                    (truncate:HI
3901                     (ashiftrt:DI
3902                      (match_operand:DI 1 "immediate_operand" "s")
3903                      (const_int 48))))))
3904    (set (match_dup 0)
3905         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3906                 (zero_extend:DI
3907                  (truncate:HI
3908                   (const:DI
3909                    (sign_extend:DI
3910                     (truncate:HI
3911                      (ashiftrt:SI
3912                       (match_dup 1)
3913                       (const_int 32)))))))))
3914    (set (match_dup 0)
3915         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3916                 (zero_extend:DI
3917                  (truncate:HI
3918                   (const:DI
3919                    (sign_extend:DI
3920                     (truncate:HI
3921                      (ashiftrt:SI
3922                       (match_dup 1)
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_SHMEDIA64 && reload_completed
3933    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3934   "
3935 {
3936   sh_mark_label (operands[1], 4);
3937 }")
3938
3939 (define_expand "movdi_const_32bit"
3940   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3941         (const:DI (sign_extend:DI
3942                    (truncate:HI
3943                     (ashiftrt:DI
3944                      (match_operand:DI 1 "immediate_operand" "s")
3945                      (const_int 16))))))
3946    (set (match_dup 0)
3947         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3948                 (zero_extend:DI
3949                  (truncate:HI
3950                   (const:DI
3951                    (sign_extend:DI
3952                     (truncate:HI
3953                      (match_dup 1))))))))]
3954   "TARGET_SHMEDIA32 && reload_completed
3955    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3956   "
3957 {
3958   sh_mark_label (operands[1], 2);
3959 }")
3960
3961 (define_expand "movdi_const_16bit"
3962   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3963         (const:DI (sign_extend:DI
3964                    (truncate:HI
3965                     (match_operand:DI 1 "immediate_operand" "s")))))]
3966   "TARGET_SHMEDIA && flag_pic && reload_completed
3967    && GET_CODE (operands[1]) == SYMBOL_REF"
3968   "")
3969
3970 (define_split
3971   [(set (match_operand:DI 0 "arith_reg_operand" "")
3972         (match_operand:DI 1 "immediate_operand" ""))]
3973   "TARGET_SHMEDIA && reload_completed
3974    && GET_CODE (operands[1]) == CONST_INT
3975    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3976   [(set (match_dup 0) (match_dup 2))
3977    (match_dup 1)]
3978   "
3979 {
3980   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3981   unsigned HOST_WIDE_INT low = val;
3982   unsigned HOST_WIDE_INT high = val;
3983   unsigned HOST_WIDE_INT sign;
3984   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3985
3986   /* Sign-extend the 16 least-significant bits.  */
3987   low &= 0xffff;
3988   low ^= 0x8000;
3989   low -= 0x8000;
3990
3991   /* Arithmetic shift right the word by 16 bits.  */
3992   high >>= 16;
3993   sign = 1;
3994   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3995   high ^= sign;
3996   high -= sign;
3997   do
3998     {
3999       /* If we can't generate the constant with a two-insn movi / shori
4000          sequence, try some other strategies.  */
4001       if (! CONST_OK_FOR_I16 (high))
4002         {
4003           /* Try constant load / left shift.  We know VAL != 0.  */
4004           val2 = val ^ (val-1);
4005           if (val2 > 0x1ffff)
4006             {
4007               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4008
4009               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4010                   || (! CONST_OK_FOR_I16 (high >> 16)
4011                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4012                 {
4013                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4014                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4015                                                    GEN_INT (trailing_zeroes));
4016                   break;
4017                 }
4018             }
4019           /* Try constant load / right shift.  */
4020           val2 = (val >> 15) + 1;
4021           if (val2 == (val2 & -val2))
4022             {
4023               int shift = 49 - exact_log2 (val2);
4024
4025               val2 = trunc_int_for_mode (val << shift, DImode);
4026               if (CONST_OK_FOR_I16 (val2))
4027                 {
4028                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4029                                                    GEN_INT (shift));
4030                   break;
4031                 }
4032             }
4033           /* Try mperm.w .  */
4034           val2 = val & 0xffff;
4035           if ((val >> 16 & 0xffff) == val2
4036               && (val >> 32 & 0xffff) == val2
4037               && (val >> 48 & 0xffff) == val2)
4038             {
4039               val2 = (HOST_WIDE_INT) val >> 48;
4040               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4041               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4042               break;
4043             }
4044           /* Try movi / mshflo.l  */
4045           val2 = (HOST_WIDE_INT) val >> 32;
4046           if (val2 == trunc_int_for_mode (val, SImode))
4047             {
4048               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4049                                              operands[0]);
4050               break;
4051             }
4052           /* Try movi / mshflo.l w/ r63.  */
4053           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4054           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4055             {
4056               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4057                                              GEN_INT (0));
4058               break;
4059             }
4060         }
4061       val2 = high;
4062       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4063     }
4064   while (0);
4065   operands[2] = GEN_INT (val2);
4066 }")
4067
4068 (define_split
4069   [(set (match_operand:DI 0 "arith_reg_operand" "")
4070         (match_operand:DI 1 "immediate_operand" ""))]
4071   "TARGET_SHMEDIA && reload_completed
4072    && GET_CODE (operands[1]) == CONST_DOUBLE"
4073   [(set (match_dup 0) (match_dup 2))
4074   (set (match_dup 0)
4075        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4076                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4077   "
4078 {
4079   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4080   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4081   unsigned HOST_WIDE_INT val = low;
4082   unsigned HOST_WIDE_INT sign;
4083
4084   /* Sign-extend the 16 least-significant bits.  */
4085   val &= 0xffff;
4086   val ^= 0x8000;
4087   val -= 0x8000;
4088   operands[1] = GEN_INT (val);
4089
4090   /* Arithmetic shift right the double-word by 16 bits.  */
4091   low >>= 16;
4092   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4093   high >>= 16;
4094   sign = 1;
4095   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4096   high ^= sign;
4097   high -= sign;
4098
4099   /* This will only be true if high is a sign-extension of low, i.e.,
4100      it must be either 0 or (unsigned)-1, and be zero iff the
4101      most-significant bit of low is set.  */
4102   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4103     operands[2] = GEN_INT (low);
4104   else
4105     operands[2] = immed_double_const (low, high, DImode);
4106 }")
4107
4108 (define_insn "shori_media"
4109   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4110         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4111                            (const_int 16))
4112                 (zero_extend:DI
4113                  (truncate:HI
4114                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4115   "TARGET_SHMEDIA"
4116   "@
4117         shori   %u2, %0
4118         #"
4119   [(set_attr "type" "arith_media,*")])
4120
4121 (define_expand "movdi"
4122   [(set (match_operand:DI 0 "general_movdst_operand" "")
4123         (match_operand:DI 1 "general_movsrc_operand" ""))]
4124   ""
4125   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4126
4127 (define_insn "movdf_media"
4128   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4129         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4130   "TARGET_SHMEDIA_FPU
4131    && (register_operand (operands[0], DFmode)
4132        || sh_register_operand (operands[1], DFmode))"
4133   "@
4134         fmov.d  %1, %0
4135         fmov.qd %N1, %0
4136         fmov.dq %1, %0
4137         add     %1, r63, %0
4138         #
4139         fld%M1.d        %m1, %0
4140         fst%M0.d        %m0, %1
4141         ld%M1.q %m1, %0
4142         st%M0.q %m0, %N1"
4143   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4144
4145 (define_insn "movdf_media_nofpu"
4146   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4147         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4148   "TARGET_SHMEDIA
4149    && (register_operand (operands[0], DFmode)
4150        || sh_register_operand (operands[1], DFmode))"
4151   "@
4152         add     %1, r63, %0
4153         #
4154         ld%M1.q %m1, %0
4155         st%M0.q %m0, %N1"
4156   [(set_attr "type" "arith_media,*,load_media,store_media")])
4157
4158 (define_split
4159   [(set (match_operand:DF 0 "arith_reg_operand" "")
4160         (match_operand:DF 1 "immediate_operand" ""))]
4161   "TARGET_SHMEDIA && reload_completed"
4162   [(set (match_dup 3) (match_dup 2))]
4163   "
4164 {
4165   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4166   long values[2];
4167   REAL_VALUE_TYPE value;
4168
4169   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4170   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4171
4172   if (HOST_BITS_PER_WIDE_INT >= 64)
4173     operands[2] = immed_double_const ((unsigned long) values[endian]
4174                                       | ((HOST_WIDE_INT) values[1 - endian]
4175                                          << 32), 0, DImode);
4176   else if (HOST_BITS_PER_WIDE_INT == 32)
4177     operands[2] = immed_double_const (values[endian], values[1 - endian],
4178                                       DImode);
4179   else
4180     abort ();
4181
4182   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4183 }")
4184
4185 ;; ??? This should be a define expand.
4186
4187 (define_insn "movdf_k"
4188   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4189         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4190   "TARGET_SH1
4191    && (! TARGET_SH4 || reload_completed
4192        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4193        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4194        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4195    && (arith_reg_operand (operands[0], DFmode)
4196        || arith_reg_operand (operands[1], DFmode))"
4197   "* return output_movedouble (insn, operands, DFmode);"
4198   [(set_attr "length" "4")
4199    (set_attr "type" "move,pcload,load,store")])
4200
4201 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4202 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4203 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4204 ;; the d/m/c/X alternative, which is split later into single-precision
4205 ;; instructions.  And when not optimizing, no splits are done before fixing
4206 ;; up pcloads, so we need usable length information for that.
4207 (define_insn "movdf_i4"
4208   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4209         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4210    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4211    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4212   "TARGET_SH4
4213    && (arith_reg_operand (operands[0], DFmode)
4214        || arith_reg_operand (operands[1], DFmode))"
4215   "@
4216         fmov    %1,%0
4217         #
4218         #
4219         fmov.d  %1,%0
4220         fmov.d  %1,%0
4221         #
4222         #
4223         #
4224         #
4225         #"
4226   [(set_attr_alternative "length"
4227      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4228       (const_int 4)
4229       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4230       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4231       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4232       (const_int 4)
4233       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4234       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4235       ;; increment or decrement r15 explicitly.
4236       (if_then_else
4237        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4238        (const_int 10) (const_int 8))
4239       (if_then_else
4240        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4241        (const_int 10) (const_int 8))])
4242    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4243    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4244    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4245                                            (const_string "double")
4246                                            (const_string "none")))])
4247
4248 ;; Moving DFmode between fp/general registers through memory
4249 ;; (the top of the stack) is faster than moving through fpul even for
4250 ;; little endian.  Because the type of an instruction is important for its
4251 ;; scheduling,  it is beneficial to split these operations, rather than
4252 ;; emitting them in one single chunk, even if this will expose a stack
4253 ;; use that will prevent scheduling of other stack accesses beyond this
4254 ;; instruction.
4255 (define_split
4256   [(set (match_operand:DF 0 "register_operand" "")
4257         (match_operand:DF 1 "register_operand" ""))
4258    (use (match_operand:PSI 2 "fpscr_operand" ""))
4259    (clobber (match_scratch:SI 3 "=X"))]
4260   "TARGET_SH4 && reload_completed
4261    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4262   [(const_int 0)]
4263   "
4264 {
4265   rtx insn, tos;
4266
4267   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4268     {
4269       emit_move_insn (stack_pointer_rtx,
4270                       plus_constant (stack_pointer_rtx, -8));
4271       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4272     }
4273   else
4274     tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4275   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4276   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4277     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4278   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4279     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4280   else
4281     tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4282   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4283   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4284     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4285   else
4286     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4287   DONE;
4288 }")
4289
4290 ;; local-alloc sometimes allocates scratch registers even when not required,
4291 ;; so we must be prepared to handle these.
4292
4293 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4294 (define_split
4295   [(set (match_operand:DF 0 "general_movdst_operand" "")
4296         (match_operand:DF 1 "general_movsrc_operand"  ""))
4297    (use (match_operand:PSI 2 "fpscr_operand" ""))
4298    (clobber (match_scratch:SI 3 ""))]
4299   "TARGET_SH4
4300    && reload_completed
4301    && true_regnum (operands[0]) < 16
4302    && true_regnum (operands[1]) < 16"
4303   [(set (match_dup 0) (match_dup 1))]
4304   "
4305 {
4306   /* If this was a reg <-> mem operation with base + index reg addressing,
4307      we have to handle this in a special way.  */
4308   rtx mem = operands[0];
4309   int store_p = 1;
4310   if (! memory_operand (mem, DFmode))
4311     {
4312       mem = operands[1];
4313       store_p = 0;
4314     }
4315   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4316     mem = SUBREG_REG (mem);
4317   if (GET_CODE (mem) == MEM)
4318     {
4319       rtx addr = XEXP (mem, 0);
4320       if (GET_CODE (addr) == PLUS
4321           && GET_CODE (XEXP (addr, 0)) == REG
4322           && GET_CODE (XEXP (addr, 1)) == REG)
4323         {
4324           int offset;
4325           rtx reg0 = gen_rtx (REG, Pmode, 0);
4326           rtx regop = operands[store_p], word0 ,word1;
4327
4328           if (GET_CODE (regop) == SUBREG)
4329             alter_subreg (&regop);
4330           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4331             offset = 2;
4332           else
4333             offset = 4;
4334           mem = copy_rtx (mem);
4335           PUT_MODE (mem, SImode);
4336           word0 = gen_rtx (SUBREG, SImode, regop, 0);
4337           alter_subreg (&word0);
4338           word1 = gen_rtx (SUBREG, SImode, regop, 4);
4339           alter_subreg (&word1);
4340           if (store_p || ! refers_to_regno_p (REGNO (word0),
4341                                               REGNO (word0) + 1, addr, 0))
4342             {
4343               emit_insn (store_p
4344                          ? gen_movsi_ie (mem, word0)
4345                          : gen_movsi_ie (word0, mem));
4346               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4347               mem = copy_rtx (mem);
4348               emit_insn (store_p
4349                          ? gen_movsi_ie (mem, word1)
4350                          : gen_movsi_ie (word1, mem));
4351               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4352             }
4353           else
4354             {
4355               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4356               emit_insn (gen_movsi_ie (word1, mem));
4357               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4358               mem = copy_rtx (mem);
4359               emit_insn (gen_movsi_ie (word0, mem));
4360             }
4361           DONE;
4362         }
4363     }
4364 }")
4365
4366 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4367 (define_split
4368   [(set (match_operand:DF 0 "register_operand" "")
4369         (match_operand:DF 1 "memory_operand"  ""))
4370    (use (match_operand:PSI 2 "fpscr_operand" ""))
4371    (clobber (reg:SI R0_REG))]
4372   "TARGET_SH4 && reload_completed"
4373   [(parallel [(set (match_dup 0) (match_dup 1))
4374               (use (match_dup 2))
4375               (clobber (scratch:SI))])]
4376   "")
4377
4378 (define_expand "reload_indf"
4379   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4380                    (match_operand:DF 1 "immediate_operand" "FQ"))
4381               (use (reg:PSI FPSCR_REG))
4382               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4383   "TARGET_SH1"
4384   "")
4385
4386 (define_expand "reload_outdf"
4387   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4388                    (match_operand:DF 1 "register_operand" "af,r"))
4389               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4390   "TARGET_SH1"
4391   "")
4392
4393 ;; Simplify no-op moves.
4394 (define_split
4395   [(set (match_operand:SF 0 "register_operand" "")
4396         (match_operand:SF 1 "register_operand" ""))
4397    (use (match_operand:PSI 2 "fpscr_operand" ""))
4398    (clobber (match_scratch:SI 3 "X"))]
4399   "TARGET_SH2E && reload_completed
4400    && true_regnum (operands[0]) == true_regnum (operands[1])"
4401   [(set (match_dup 0) (match_dup 0))]
4402   "")
4403
4404 ;; fmovd substitute post-reload splits
4405 (define_split
4406   [(set (match_operand:DF 0 "register_operand" "")
4407         (match_operand:DF 1 "register_operand" ""))
4408    (use (match_operand:PSI 2 "fpscr_operand" ""))
4409    (clobber (match_scratch:SI 3 "X"))]
4410   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4411    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4412    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4413   [(const_int 0)]
4414   "
4415 {
4416   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4417   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4418                            gen_rtx (REG, SFmode, src), operands[2]));
4419   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4420                            gen_rtx (REG, SFmode, src + 1), operands[2]));
4421   DONE;
4422 }")
4423
4424 (define_split
4425   [(set (match_operand:DF 0 "register_operand" "")
4426         (mem:DF (match_operand:SI 1 "register_operand" "")))
4427    (use (match_operand:PSI 2 "fpscr_operand" ""))
4428    (clobber (match_scratch:SI 3 ""))]
4429   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4430    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4431    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4432   [(const_int 0)]
4433   "
4434 {
4435   int regno = true_regnum (operands[0]);
4436   rtx insn;
4437   rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4438
4439   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4440                                            regno + !! TARGET_LITTLE_ENDIAN),
4441                                   mem2, operands[2]));
4442   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4443   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4444                                            regno + ! TARGET_LITTLE_ENDIAN),
4445                                   gen_rtx (MEM, SFmode, operands[1]),
4446                                   operands[2]));
4447   DONE;
4448 }")
4449
4450 (define_split
4451   [(set (match_operand:DF 0 "register_operand" "")
4452         (match_operand:DF 1 "memory_operand" ""))
4453    (use (match_operand:PSI 2 "fpscr_operand" ""))
4454    (clobber (match_scratch:SI 3 ""))]
4455   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4456    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4457   [(const_int 0)]
4458   "
4459 {
4460   int regno = true_regnum (operands[0]);
4461   rtx addr, insn, adjust = NULL_RTX;
4462   rtx mem2 = copy_rtx (operands[1]);
4463   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4464   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4465
4466   PUT_MODE (mem2, SFmode);
4467   operands[1] = copy_rtx (mem2);
4468   addr = XEXP (mem2, 0);
4469   if (GET_CODE (addr) != POST_INC)
4470     {
4471       /* If we have to modify the stack pointer, the value that we have
4472          read with post-increment might be modified by an interrupt,
4473          so write it back.  */
4474       if (REGNO (addr) == STACK_POINTER_REGNUM)
4475         adjust = gen_push_e (reg0);
4476       else
4477         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4478       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4479     }
4480   addr = XEXP (addr, 0);
4481   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4482   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4483   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4484   if (adjust)
4485     emit_insn (adjust);
4486   else
4487     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4488   DONE;
4489 }")
4490
4491 (define_split
4492   [(set (match_operand:DF 0 "memory_operand" "")
4493         (match_operand:DF 1 "register_operand" ""))
4494    (use (match_operand:PSI 2 "fpscr_operand" ""))
4495    (clobber (match_scratch:SI 3 ""))]
4496   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4497    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4498   [(const_int 0)]
4499   "
4500 {
4501   int regno = true_regnum (operands[1]);
4502   rtx insn, addr, adjust = NULL_RTX;
4503
4504   operands[0] = copy_rtx (operands[0]);
4505   PUT_MODE (operands[0], SFmode);
4506   insn = emit_insn (gen_movsf_ie (operands[0],
4507                                   gen_rtx (REG, SFmode,
4508                                            regno + ! TARGET_LITTLE_ENDIAN),
4509                                   operands[2]));
4510   operands[0] = copy_rtx (operands[0]);
4511   addr = XEXP (operands[0], 0);
4512   if (GET_CODE (addr) != PRE_DEC)
4513     {
4514       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4515       emit_insn_before (adjust, insn);
4516       XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4517     }
4518   addr = XEXP (addr, 0);
4519   if (! adjust)
4520     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4521   insn = emit_insn (gen_movsf_ie (operands[0],
4522                                   gen_rtx (REG, SFmode,
4523                                            regno + !! TARGET_LITTLE_ENDIAN),
4524                                   operands[2]));
4525   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4526   DONE;
4527 }")
4528
4529 ;; If the output is a register and the input is memory or a register, we have
4530 ;; to be careful and see which word needs to be loaded first.
4531
4532 (define_split
4533   [(set (match_operand:DF 0 "general_movdst_operand" "")
4534         (match_operand:DF 1 "general_movsrc_operand" ""))]
4535   "TARGET_SH1 && reload_completed"
4536   [(set (match_dup 2) (match_dup 3))
4537    (set (match_dup 4) (match_dup 5))]
4538   "
4539 {
4540   int regno;
4541
4542   if ((GET_CODE (operands[0]) == MEM
4543        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4544       || (GET_CODE (operands[1]) == MEM
4545           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4546     FAIL;
4547
4548   if (GET_CODE (operands[0]) == REG)
4549     regno = REGNO (operands[0]);
4550   else if (GET_CODE (operands[0]) == SUBREG)
4551     regno = subreg_regno (operands[0]);
4552   else if (GET_CODE (operands[0]) == MEM)
4553     regno = -1;
4554   else
4555     abort ();
4556
4557   if (regno == -1
4558       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4559     {
4560       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4561       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4562       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4563       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4564     }
4565   else
4566     {
4567       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4568       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4569       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4570       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4571     }
4572
4573   if (operands[2] == 0 || operands[3] == 0
4574       || operands[4] == 0 || operands[5] == 0)
4575     FAIL;
4576 }")
4577
4578 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4579 ;; used only once, let combine add in the index again.
4580
4581 (define_split
4582   [(set (match_operand:SI 0 "register_operand" "")
4583         (match_operand:SI 1 "" ""))
4584    (clobber (match_operand 2 "register_operand" ""))]
4585   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4586   [(use (reg:SI R0_REG))]
4587   "
4588 {
4589   rtx addr, reg, const_int;
4590
4591   if (GET_CODE (operands[1]) != MEM)
4592     FAIL;
4593   addr = XEXP (operands[1], 0);
4594   if (GET_CODE (addr) != PLUS)
4595     FAIL;
4596   reg = XEXP (addr, 0);
4597   const_int = XEXP (addr, 1);
4598   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4599          && GET_CODE (const_int) == CONST_INT))
4600     FAIL;
4601   emit_move_insn (operands[2], const_int);
4602   emit_move_insn (operands[0],
4603                   change_address (operands[1], VOIDmode,
4604                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4605   DONE;
4606 }")
4607
4608 (define_split
4609   [(set (match_operand:SI 1 "" "")
4610         (match_operand:SI 0 "register_operand" ""))
4611    (clobber (match_operand 2 "register_operand" ""))]
4612   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4613   [(use (reg:SI R0_REG))]
4614   "
4615 {
4616   rtx addr, reg, const_int;
4617
4618   if (GET_CODE (operands[1]) != MEM)
4619     FAIL;
4620   addr = XEXP (operands[1], 0);
4621   if (GET_CODE (addr) != PLUS)
4622     FAIL;
4623   reg = XEXP (addr, 0);
4624   const_int = XEXP (addr, 1);
4625   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4626          && GET_CODE (const_int) == CONST_INT))
4627     FAIL;
4628   emit_move_insn (operands[2], const_int);
4629   emit_move_insn (change_address (operands[1], VOIDmode,
4630                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4631                   operands[0]);
4632   DONE;
4633 }")
4634
4635 (define_expand "movdf"
4636   [(set (match_operand:DF 0 "general_movdst_operand" "")
4637         (match_operand:DF 1 "general_movsrc_operand" ""))]
4638   ""
4639   "
4640 {
4641   if (prepare_move_operands (operands, DFmode)) DONE;
4642   if (TARGET_SHMEDIA)
4643     {
4644       if (TARGET_SHMEDIA_FPU)
4645         emit_insn (gen_movdf_media (operands[0], operands[1]));
4646       else
4647         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4648       DONE;
4649     }
4650   if (TARGET_SH4)
4651     {
4652       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4653       DONE;
4654     }
4655 }")
4656
4657 ;;This is incompatible with the way gcc uses subregs.
4658 ;;(define_insn "movv2sf_i"
4659 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4660 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4661 ;;  "TARGET_SHMEDIA_FPU
4662 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4663 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4664 ;;  "@
4665 ;;      #
4666 ;;      fld%M1.p        %m1, %0
4667 ;;      fst%M0.p        %m0, %1"
4668 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4669
4670 (define_insn_and_split "movv2sf_i"
4671   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4672         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4673   "TARGET_SHMEDIA_FPU"
4674   "#"
4675   "TARGET_SHMEDIA_FPU && reload_completed"
4676   [(set (match_dup 0) (match_dup 1))]
4677   "
4678 {
4679   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4680   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4681 }")
4682
4683 (define_expand "movv2sf"
4684   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4685         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4686   "TARGET_SHMEDIA_FPU"
4687   "
4688 {
4689   if (prepare_move_operands (operands, V2SFmode))
4690     DONE;
4691 }")
4692
4693 (define_expand "addv2sf3"
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 (PLUS, operands[0], operands[1], operands[2]);
4701   DONE;
4702 }")
4703
4704 (define_expand "subv2sf3"
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 (MINUS, operands[0], operands[1], operands[2]);
4712   DONE;
4713 }")
4714
4715 (define_expand "mulv2sf3"
4716   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4717    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4718    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4719   "TARGET_SHMEDIA_FPU"
4720   "
4721 {
4722   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4723   DONE;
4724 }")
4725
4726 (define_expand "divv2sf3"
4727   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4728    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4729    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4730   "TARGET_SHMEDIA_FPU"
4731   "
4732 {
4733   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4734   DONE;
4735 }")
4736
4737 (define_insn_and_split "*movv4sf_i"
4738   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4739         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4740   "TARGET_SHMEDIA_FPU"
4741   "#"
4742   "&& reload_completed"
4743   [(const_int 0)]
4744   "
4745 {
4746   int i;
4747
4748   for (i = 0; i < 4/2; i++)
4749     {
4750       rtx x, y;
4751
4752       if (GET_CODE (operands[0]) == MEM)
4753         x = gen_rtx_MEM (V2SFmode,
4754                          plus_constant (XEXP (operands[0], 0),
4755                                         i * GET_MODE_SIZE (V2SFmode)));
4756       else
4757         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4758
4759       if (GET_CODE (operands[1]) == MEM)
4760         y = gen_rtx_MEM (V2SFmode,
4761                          plus_constant (XEXP (operands[1], 0),
4762                                         i * GET_MODE_SIZE (V2SFmode)));
4763       else
4764         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4765
4766       emit_insn (gen_movv2sf_i (x, y));
4767     }
4768
4769   DONE;
4770 }"
4771   [(set_attr "length" "8")])
4772
4773 (define_expand "movv4sf"
4774   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4775         (match_operand:V4SF 1 "general_operand" ""))]
4776   "TARGET_SHMEDIA_FPU"
4777   "
4778 {
4779   if (prepare_move_operands (operands, V4SFmode))
4780     DONE;
4781 }")
4782
4783 (define_insn_and_split "*movv16sf_i"
4784   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4785         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4786   "TARGET_SHMEDIA_FPU"
4787   "#"
4788   "&& reload_completed"
4789   [(const_int 0)]
4790   "
4791 {
4792   int i;
4793
4794   for (i = 0; i < 16/2; i++)
4795     {
4796       rtx x,y;
4797
4798       if (GET_CODE (operands[0]) == MEM)
4799         x = gen_rtx_MEM (V2SFmode,
4800                          plus_constant (XEXP (operands[0], 0),
4801                                         i * GET_MODE_SIZE (V2SFmode)));
4802       else
4803         {
4804           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4805           alter_subreg (&x);
4806         }
4807
4808       if (GET_CODE (operands[1]) == MEM)
4809         y = gen_rtx_MEM (V2SFmode,
4810                          plus_constant (XEXP (operands[1], 0),
4811                                         i * GET_MODE_SIZE (V2SFmode)));
4812       else
4813         {
4814           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4815           alter_subreg (&y);
4816         }
4817
4818       emit_insn (gen_movv2sf_i (x, y));
4819     }
4820
4821   DONE;
4822 }"
4823   [(set_attr "length" "32")])
4824
4825 (define_expand "movv16sf"
4826   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4827         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4828   "TARGET_SHMEDIA_FPU"
4829   "
4830 {
4831   if (prepare_move_operands (operands, V16SFmode))
4832     DONE;
4833 }")
4834
4835 (define_insn "movsf_media"
4836   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4837         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4838   "TARGET_SHMEDIA_FPU
4839    && (register_operand (operands[0], SFmode)
4840        || sh_register_operand (operands[1], SFmode))"
4841   "@
4842         fmov.s  %1, %0
4843         fmov.ls %N1, %0
4844         fmov.sl %1, %0
4845         add.l   %1, r63, %0
4846         #
4847         fld%M1.s        %m1, %0
4848         fst%M0.s        %m0, %1
4849         ld%M1.l %m1, %0
4850         st%M0.l %m0, %N1"
4851   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4852
4853 (define_insn "movsf_media_nofpu"
4854   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4855         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4856   "TARGET_SHMEDIA
4857    && (register_operand (operands[0], SFmode)
4858        || sh_register_operand (operands[1], SFmode))"
4859   "@
4860         add.l   %1, r63, %0
4861         #
4862         ld%M1.l %m1, %0
4863         st%M0.l %m0, %N1"
4864   [(set_attr "type" "arith_media,*,load_media,store_media")])
4865
4866 (define_split
4867   [(set (match_operand:SF 0 "arith_reg_operand" "")
4868         (match_operand:SF 1 "immediate_operand" ""))]
4869   "TARGET_SHMEDIA && reload_completed
4870    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4871   [(set (match_dup 3) (match_dup 2))]
4872   "
4873 {
4874   long values;
4875   REAL_VALUE_TYPE value;
4876
4877   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4878   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4879   operands[2] = GEN_INT (values);
4880
4881   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4882 }")
4883
4884 (define_insn "movsf_i"
4885   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4886         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4887   "TARGET_SH1
4888    && (! TARGET_SH2E
4889        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4890        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4891        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4892    && (arith_reg_operand (operands[0], SFmode)
4893        || arith_reg_operand (operands[1], SFmode))"
4894   "@
4895         mov     %1,%0
4896         mov     #0,%0
4897         mov.l   %1,%0
4898         mov.l   %1,%0
4899         mov.l   %1,%0
4900         lds     %1,%0
4901         sts     %1,%0"
4902   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4903
4904 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4905 ;; update_flow_info would not know where to put REG_EQUAL notes
4906 ;; when the destination changes mode.
4907 (define_insn "movsf_ie"
4908   [(set (match_operand:SF 0 "general_movdst_operand"
4909          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4910         (match_operand:SF 1 "general_movsrc_operand"
4911           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4912    (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"))
4913    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4914
4915   "TARGET_SH2E
4916    && (arith_reg_operand (operands[0], SFmode)
4917        || arith_reg_operand (operands[1], SFmode)
4918        || arith_reg_operand (operands[3], SImode)
4919        || (fpul_operand (operands[0], SFmode)
4920            && memory_operand (operands[1], SFmode)
4921            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4922        || (fpul_operand (operands[1], SFmode)
4923            && memory_operand (operands[0], SFmode)
4924            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4925   "@
4926         fmov    %1,%0
4927         mov     %1,%0
4928         fldi0   %0
4929         fldi1   %0
4930         #
4931         fmov.s  %1,%0
4932         fmov.s  %1,%0
4933         mov.l   %1,%0
4934         mov.l   %1,%0
4935         mov.l   %1,%0
4936         fsts    fpul,%0
4937         flds    %1,fpul
4938         lds.l   %1,%0
4939         #
4940         sts     %1,%0
4941         lds     %1,%0
4942         sts.l   %1,%0
4943         lds.l   %1,%0
4944         ! move optimized away"
4945   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4946    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4947    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4948    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4949                                            (const_string "single")
4950                                            (const_string "none")))])
4951
4952 (define_split
4953   [(set (match_operand:SF 0 "register_operand" "")
4954         (match_operand:SF 1 "register_operand" ""))
4955    (use (match_operand:PSI 2 "fpscr_operand" ""))
4956    (clobber (reg:SI FPUL_REG))]
4957   "TARGET_SH1"
4958   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4959               (use (match_dup 2))
4960               (clobber (scratch:SI))])
4961    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4962               (use (match_dup 2))
4963               (clobber (scratch:SI))])]
4964   "")
4965
4966 (define_expand "movsf"
4967   [(set (match_operand:SF 0 "general_movdst_operand" "")
4968         (match_operand:SF 1 "general_movsrc_operand" ""))]
4969   ""
4970   "
4971 {
4972   if (prepare_move_operands (operands, SFmode))
4973     DONE;
4974   if (TARGET_SHMEDIA)
4975     {
4976       if (TARGET_SHMEDIA_FPU)
4977         emit_insn (gen_movsf_media (operands[0], operands[1]));
4978       else
4979         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4980       DONE;
4981     }
4982   if (TARGET_SH2E)
4983     {
4984       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4985       DONE;
4986     }
4987 }")
4988
4989 (define_insn "mov_nop"
4990   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4991   "TARGET_SH2E"
4992   ""
4993   [(set_attr "length" "0")
4994    (set_attr "type" "nil")])
4995
4996 (define_expand "reload_insf"
4997   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4998                    (match_operand:SF 1 "immediate_operand" "FQ"))
4999               (use (reg:PSI FPSCR_REG))
5000               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5001   "TARGET_SH1"
5002   "")
5003
5004 (define_expand "reload_insi"
5005   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5006                    (match_operand:SF 1 "immediate_operand" "FQ"))
5007               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5008   "TARGET_SH1"
5009   "")
5010
5011 (define_insn "*movsi_y"
5012   [(set (match_operand:SI 0 "register_operand" "=y,y")
5013         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5014    (clobber (match_scratch:SI 2 "=&z,r"))]
5015   "TARGET_SH2E
5016    && (reload_in_progress || reload_completed)"
5017   "#"
5018   [(set_attr "length" "4")
5019    (set_attr "type" "pcload,move")])
5020
5021 (define_split
5022   [(set (match_operand:SI 0 "register_operand" "")
5023         (match_operand:SI 1 "immediate_operand" ""))
5024    (clobber (match_operand:SI 2 "register_operand" ""))]
5025   "TARGET_SH1"
5026   [(set (match_dup 2) (match_dup 1))
5027    (set (match_dup 0) (match_dup 2))]
5028   "")
5029
5030 (define_split
5031   [(set (match_operand:SI 0 "register_operand" "")
5032         (match_operand:SI 1 "memory_operand" ""))
5033    (clobber (reg:SI R0_REG))]
5034   "TARGET_SH1"
5035   [(set (match_dup 0) (match_dup 1))]
5036   "")
5037 \f
5038 ;; ------------------------------------------------------------------------
5039 ;; Define the real conditional branch instructions.
5040 ;; ------------------------------------------------------------------------
5041
5042 (define_insn "branch_true"
5043   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5044                            (label_ref (match_operand 0 "" ""))
5045                            (pc)))]
5046   "TARGET_SH1"
5047   "* return output_branch (1, insn, operands);"
5048   [(set_attr "type" "cbranch")])
5049
5050 (define_insn "branch_false"
5051   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5052                            (label_ref (match_operand 0 "" ""))
5053                            (pc)))]
5054   "TARGET_SH1"
5055   "* return output_branch (0, insn, operands);"
5056   [(set_attr "type" "cbranch")])
5057
5058 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5059 ;; which destination is too far away.
5060 ;; The const_int_operand is distinct for each branch target; it avoids
5061 ;; unwanted matches with redundant_insn.
5062 (define_insn "block_branch_redirect"
5063   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5064   "TARGET_SH1"
5065   ""
5066   [(set_attr "length" "0")])
5067
5068 ;; This one has the additional purpose to record a possible scratch register
5069 ;; for the following branch.
5070 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5071 ;; because the insn then might be deemed dead and deleted.  And we can't
5072 ;; make the use in the jump insn explicit because that would disable
5073 ;; delay slot scheduling from the target.
5074 (define_insn "indirect_jump_scratch"
5075   [(set (match_operand:SI 0 "register_operand" "=r")
5076         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5077    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5078   "TARGET_SH1"
5079   ""
5080   [(set_attr "length" "0")])
5081
5082 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5083 ;; being pulled into the delay slot of a condbranch that has been made to
5084 ;; jump around the unconditional jump because it was out of range.
5085 (define_insn "stuff_delay_slot"
5086   [(set (pc)
5087         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5088    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5089   "TARGET_SH1"
5090   ""
5091   [(set_attr "length" "0")
5092    (set_attr "cond_delay_slot" "yes")])
5093 \f
5094 ;; Conditional branch insns
5095
5096 (define_expand "beq_media"
5097   [(set (pc)
5098         (if_then_else (eq (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_insn "*beq_media_i"
5106   [(set (pc)
5107         (if_then_else (match_operator 3 "equality_comparison_operator"
5108                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5109                          (match_operand:DI 2 "arith_operand" "r,I06")])
5110                       (match_operand:DI 0 "target_operand" "b,b")
5111                       (pc)))]
5112   "TARGET_SHMEDIA"
5113   "@
5114         b%o3%'  %1, %2, %0
5115         b%o3i%' %1, %2, %0"
5116   [(set_attr "type" "cbranch_media")])
5117
5118 (define_expand "bne_media"
5119   [(set (pc)
5120         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5121                           (match_operand:DI 2 "arith_operand" "r,I06"))
5122                       (label_ref:DI (match_operand 0 "" ""))
5123                       (pc)))]
5124   "TARGET_SHMEDIA"
5125   "")
5126
5127 (define_expand "bgt_media"
5128   [(set (pc)
5129         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5130                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5131                       (label_ref:DI (match_operand 0 "" ""))
5132                       (pc)))]
5133   "TARGET_SHMEDIA"
5134   "")
5135
5136 (define_expand "bge_media"
5137   [(set (pc)
5138         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5139                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5140                       (label_ref:DI (match_operand 0 "" ""))
5141                       (pc)))]
5142   "TARGET_SHMEDIA"
5143   "")
5144
5145 (define_expand "bgtu_media"
5146   [(set (pc)
5147         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5148                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5149                       (label_ref:DI (match_operand 0 "" ""))
5150                       (pc)))]
5151   "TARGET_SHMEDIA"
5152   "")
5153
5154 (define_expand "bgeu_media"
5155   [(set (pc)
5156         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5157                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5158                       (label_ref:DI (match_operand 0 "" ""))
5159                       (pc)))]
5160   "TARGET_SHMEDIA"
5161   "")
5162
5163 (define_insn "*bgt_media_i"
5164   [(set (pc)
5165         (if_then_else (match_operator 3 "greater_comparison_operator"
5166                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5167                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5168                       (match_operand:DI 0 "target_operand" "b")
5169                       (pc)))]
5170   "TARGET_SHMEDIA"
5171   "b%o3%'       %N1, %N2, %0"
5172   [(set_attr "type" "cbranch_media")])
5173
5174 ;; These are only needed to make invert_jump() happy.
5175 (define_insn "*blt_media_i"
5176   [(set (pc)
5177         (if_then_else (match_operator 3 "less_comparison_operator"
5178                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5179                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5180                       (match_operand:DI 0 "target_operand" "b")
5181                       (pc)))]
5182   "TARGET_SHMEDIA"
5183   "b%o3%'       %N2, %N1, %0"
5184   [(set_attr "type" "cbranch_media")])
5185
5186 (define_expand "beq"
5187   [(set (pc)
5188         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5189                       (label_ref (match_operand 0 "" ""))
5190                       (pc)))]
5191   ""
5192   "
5193 {
5194   if (TARGET_SHMEDIA)
5195     {
5196       if (GET_MODE (sh_compare_op0) != DImode)
5197         {
5198           rtx tmp = gen_reg_rtx (DImode);
5199
5200           emit_insn (gen_seq (tmp));
5201           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5202           DONE;
5203         }
5204
5205       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5206       emit_jump_insn (gen_beq_media (operands[0],
5207                                      sh_compare_op0, sh_compare_op1));
5208       DONE;
5209     }
5210
5211   from_compare (operands, EQ);
5212 }")
5213
5214 (define_expand "bne"
5215   [(set (pc)
5216         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5217                       (label_ref (match_operand 0 "" ""))
5218                       (pc)))]
5219   ""
5220   "
5221 {
5222   if (TARGET_SHMEDIA)
5223     {
5224       if (GET_MODE (sh_compare_op0) != DImode)
5225         {
5226           rtx tmp = gen_reg_rtx (DImode);
5227
5228           emit_insn (gen_seq (tmp));
5229           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5230           DONE;
5231         }
5232
5233       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5234       emit_jump_insn (gen_bne_media (operands[0],
5235                                      sh_compare_op0, sh_compare_op1));
5236       DONE;
5237     }
5238
5239   from_compare (operands, EQ);
5240 }")
5241
5242 (define_expand "bgt"
5243   [(set (pc)
5244         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5245                       (label_ref (match_operand 0 "" ""))
5246                       (pc)))]
5247   ""
5248   "
5249 {
5250   if (TARGET_SHMEDIA)
5251     {
5252       if (GET_MODE (sh_compare_op0) != DImode)
5253         {
5254           rtx tmp = gen_reg_rtx (DImode);
5255
5256           emit_insn (gen_sgt (tmp));
5257           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5258           DONE;
5259         }
5260
5261       if (sh_compare_op0 != const0_rtx)
5262         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5263       if (sh_compare_op1 != const0_rtx)
5264         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5265       emit_jump_insn (gen_bgt_media (operands[0],
5266                                      sh_compare_op0, sh_compare_op1));
5267       DONE;
5268     }
5269
5270   from_compare (operands, GT);
5271 }")
5272
5273 (define_expand "blt"
5274   [(set (pc)
5275         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5276                       (label_ref (match_operand 0 "" ""))
5277                       (pc)))]
5278   ""
5279   "
5280 {
5281   if (TARGET_SHMEDIA)
5282     {
5283       if (GET_MODE (sh_compare_op0) != DImode)
5284         {
5285           rtx tmp = gen_reg_rtx (DImode);
5286
5287           emit_insn (gen_slt (tmp));
5288           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5289           DONE;
5290         }
5291
5292       if (sh_compare_op0 != const0_rtx)
5293         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5294       if (sh_compare_op1 != const0_rtx)
5295         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5296       emit_jump_insn (gen_bgt_media (operands[0],
5297                                      sh_compare_op1, sh_compare_op0));
5298       DONE;
5299     }
5300
5301   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5302     {
5303       rtx tmp = sh_compare_op0;
5304       sh_compare_op0 = sh_compare_op1;
5305       sh_compare_op1 = tmp;
5306       emit_insn (gen_bgt (operands[0]));
5307       DONE;
5308     }
5309   from_compare (operands, GE);
5310 }")
5311
5312 (define_expand "ble"
5313   [(set (pc)
5314         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5315                       (label_ref (match_operand 0 "" ""))
5316                       (pc)))]
5317   ""
5318   "
5319 {
5320   if (TARGET_SHMEDIA)
5321     {
5322       if (GET_MODE (sh_compare_op0) != DImode)
5323         {
5324           rtx tmp = gen_reg_rtx (DImode);
5325
5326           emit_insn (gen_sle (tmp));
5327           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5328           DONE;
5329         }
5330
5331       if (sh_compare_op0 != const0_rtx)
5332         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5333       if (sh_compare_op1 != const0_rtx)
5334         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5335       emit_jump_insn (gen_bge_media (operands[0],
5336                                      sh_compare_op1, sh_compare_op0));
5337       DONE;
5338     }
5339
5340   if (TARGET_SH2E
5341       && TARGET_IEEE
5342       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5343     {
5344       rtx tmp = sh_compare_op0;
5345       sh_compare_op0 = sh_compare_op1;
5346       sh_compare_op1 = tmp;
5347       emit_insn (gen_bge (operands[0]));
5348       DONE;
5349     }
5350   from_compare (operands, GT);
5351 }")
5352
5353 (define_expand "bge"
5354   [(set (pc)
5355         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5356                       (label_ref (match_operand 0 "" ""))
5357                       (pc)))]
5358   ""
5359   "
5360 {
5361   if (TARGET_SHMEDIA)
5362     {
5363       if (GET_MODE (sh_compare_op0) != DImode)
5364         {
5365           rtx tmp = gen_reg_rtx (DImode);
5366
5367           emit_insn (gen_sge (tmp));
5368           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5369           DONE;
5370         }
5371
5372       if (sh_compare_op0 != const0_rtx)
5373         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5374       if (sh_compare_op1 != const0_rtx)
5375         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5376       emit_jump_insn (gen_bge_media (operands[0],
5377                                      sh_compare_op0, sh_compare_op1));
5378       DONE;
5379     }
5380
5381   if (TARGET_SH2E
5382       && ! TARGET_IEEE
5383       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5384     {
5385       rtx tmp = sh_compare_op0;
5386       sh_compare_op0 = sh_compare_op1;
5387       sh_compare_op1 = tmp;
5388       emit_insn (gen_ble (operands[0]));
5389       DONE;
5390     }
5391   from_compare (operands, GE);
5392 }")
5393
5394 (define_expand "bgtu"
5395   [(set (pc)
5396         (if_then_else (ne (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_op0, sh_compare_op1));
5410       DONE;
5411     }
5412
5413   from_compare (operands, GTU);
5414 }")
5415
5416 (define_expand "bltu"
5417   [(set (pc)
5418         (if_then_else (eq (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_bgtu_media (operands[0],
5431                                       sh_compare_op1, sh_compare_op0));
5432       DONE;
5433     }
5434
5435   from_compare (operands, GEU);
5436 }")
5437
5438 (define_expand "bgeu"
5439   [(set (pc)
5440         (if_then_else (ne (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_op0, sh_compare_op1));
5454       DONE;
5455     }
5456
5457   from_compare (operands, GEU);
5458 }")
5459
5460 (define_expand "bleu"
5461   [(set (pc)
5462         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5463                       (label_ref (match_operand 0 "" ""))
5464                       (pc)))]
5465   ""
5466   "
5467 {
5468   if (TARGET_SHMEDIA)
5469     {
5470       if (sh_compare_op0 != const0_rtx)
5471         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5472       if (sh_compare_op1 != const0_rtx)
5473         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5474       emit_jump_insn (gen_bgeu_media (operands[0],
5475                                       sh_compare_op1, sh_compare_op0));
5476       DONE;
5477     }
5478
5479   from_compare (operands, GTU);
5480 }")
5481
5482 (define_expand "bunordered"
5483   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5484    (set (pc)
5485         (if_then_else (ne (match_dup 1) (const_int 0))
5486                       (label_ref:DI (match_operand 0 "" ""))
5487                       (pc)))]
5488   "TARGET_SHMEDIA"
5489   "
5490 {
5491   operands[1] = gen_reg_rtx (DImode);
5492   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5493   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5494 }")
5495 \f
5496 ;; ------------------------------------------------------------------------
5497 ;; Jump and linkage insns
5498 ;; ------------------------------------------------------------------------
5499
5500 (define_insn "jump_compact"
5501   [(set (pc)
5502         (label_ref (match_operand 0 "" "")))]
5503   "TARGET_SH1"
5504   "*
5505 {
5506   /* The length is 16 if the delay slot is unfilled.  */
5507   if (get_attr_length(insn) > 4)
5508     return output_far_jump(insn, operands[0]);
5509   else
5510     return   \"bra      %l0%#\";
5511 }"
5512   [(set_attr "type" "jump")
5513    (set_attr "needs_delay_slot" "yes")])
5514
5515 ;; ??? It would be much saner to explicitly use the scratch register
5516 ;; in the jump insn, and have indirect_jump_scratch only set it,
5517 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5518 ;; from the target then, as it uses simplejump_p.
5519 ;;(define_insn "jump_compact_far"
5520 ;;  [(set (pc)
5521 ;;      (label_ref (match_operand 0 "" "")))
5522 ;;   (use (match_operand 1 "register_operand" "r")]
5523 ;;  "TARGET_SH1"
5524 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5525 ;;  [(set_attr "type" "jump")
5526 ;;   (set_attr "needs_delay_slot" "yes")])
5527
5528 (define_insn "jump_media"
5529   [(set (pc)
5530         (match_operand:DI 0 "target_operand" "b"))]
5531   "TARGET_SHMEDIA"
5532   "blink        %0, r63"
5533   [(set_attr "type" "jump_media")])
5534
5535 (define_expand "jump"
5536   [(set (pc)
5537         (label_ref (match_operand 0 "" "")))]
5538   ""
5539   "
5540 {
5541   if (TARGET_SH1)
5542     emit_jump_insn (gen_jump_compact (operands[0]));
5543   else if (TARGET_SHMEDIA)
5544     {
5545       if (reload_in_progress || reload_completed)
5546         FAIL;
5547       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5548                                                          operands[0])));
5549     }
5550   DONE;
5551 }")
5552
5553 (define_insn "force_mode_for_call"
5554   [(use (reg:PSI FPSCR_REG))]
5555   "TARGET_SHCOMPACT"
5556   ""
5557   [(set_attr "length" "0")
5558    (set (attr "fp_mode")
5559         (if_then_else (eq_attr "fpu_single" "yes")
5560                       (const_string "single") (const_string "double")))])
5561
5562 (define_insn "calli"
5563   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5564          (match_operand 1 "" ""))
5565    (use (reg:PSI FPSCR_REG))
5566    (clobber (reg:SI PR_REG))]
5567   "TARGET_SH1"
5568   "jsr  @%0%#"
5569   [(set_attr "type" "call")
5570    (set (attr "fp_mode")
5571         (if_then_else (eq_attr "fpu_single" "yes")
5572                       (const_string "single") (const_string "double")))
5573    (set_attr "needs_delay_slot" "yes")
5574    (set_attr "fp_set" "unknown")])
5575
5576 ;; This is a pc-rel call, using bsrf, for use with PIC.
5577
5578 (define_insn "calli_pcrel"
5579   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5580          (match_operand 1 "" ""))
5581    (use (reg:PSI FPSCR_REG))
5582    (use (reg:SI PIC_REG))
5583    (use (match_operand 2 "" ""))
5584    (clobber (reg:SI PR_REG))]
5585   "TARGET_SH2"
5586   "bsrf %0\\n%O2:%#"
5587   [(set_attr "type" "call")
5588    (set (attr "fp_mode")
5589         (if_then_else (eq_attr "fpu_single" "yes")
5590                       (const_string "single") (const_string "double")))
5591    (set_attr "needs_delay_slot" "yes")
5592    (set_attr "fp_set" "unknown")])
5593
5594 (define_insn_and_split "call_pcrel"
5595   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5596          (match_operand 1 "" ""))
5597    (use (reg:PSI FPSCR_REG))
5598    (use (reg:SI PIC_REG))
5599    (clobber (reg:SI PR_REG))
5600    (clobber (match_scratch:SI 2 "=r"))]
5601   "TARGET_SH2"
5602   "#"
5603   "reload_completed"
5604   [(const_int 0)]
5605   "
5606 {
5607   rtx lab = PATTERN (gen_call_site ());
5608
5609   if (SYMBOL_REF_LOCAL_P (operands[0]))
5610     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5611   else
5612     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5613   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5614   DONE;
5615 }"
5616   [(set_attr "type" "call")
5617    (set (attr "fp_mode")
5618         (if_then_else (eq_attr "fpu_single" "yes")
5619                       (const_string "single") (const_string "double")))
5620    (set_attr "needs_delay_slot" "yes")
5621    (set_attr "fp_set" "unknown")])
5622
5623 (define_insn "call_compact"
5624   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5625          (match_operand 1 "" ""))
5626    (match_operand 2 "immediate_operand" "n")
5627    (use (reg:SI R0_REG))
5628    (use (reg:SI R1_REG))
5629    (use (reg:PSI FPSCR_REG))
5630    (clobber (reg:SI PR_REG))]
5631   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5632   "jsr  @%0%#"
5633   [(set_attr "type" "call")
5634    (set (attr "fp_mode")
5635         (if_then_else (eq_attr "fpu_single" "yes")
5636                       (const_string "single") (const_string "double")))
5637    (set_attr "needs_delay_slot" "yes")])
5638
5639 (define_insn "call_compact_rettramp"
5640   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5641          (match_operand 1 "" ""))
5642    (match_operand 2 "immediate_operand" "n")
5643    (use (reg:SI R0_REG))
5644    (use (reg:SI R1_REG))
5645    (use (reg:PSI FPSCR_REG))
5646    (clobber (reg:SI R10_REG))
5647    (clobber (reg:SI PR_REG))]
5648   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5649   "jsr  @%0%#"
5650   [(set_attr "type" "call")
5651    (set (attr "fp_mode")
5652         (if_then_else (eq_attr "fpu_single" "yes")
5653                       (const_string "single") (const_string "double")))
5654    (set_attr "needs_delay_slot" "yes")])
5655
5656 (define_insn "call_media"
5657   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5658          (match_operand 1 "" ""))
5659    (clobber (reg:DI PR_MEDIA_REG))]
5660   "TARGET_SHMEDIA"
5661   "blink        %0, r18"
5662   [(set_attr "type" "jump_media")])
5663
5664 (define_insn "call_valuei"
5665   [(set (match_operand 0 "" "=rf")
5666         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5667               (match_operand 2 "" "")))
5668    (use (reg:PSI FPSCR_REG))
5669    (clobber (reg:SI PR_REG))]
5670   "TARGET_SH1"
5671   "jsr  @%1%#"
5672   [(set_attr "type" "call")
5673    (set (attr "fp_mode")
5674         (if_then_else (eq_attr "fpu_single" "yes")
5675                       (const_string "single") (const_string "double")))
5676    (set_attr "needs_delay_slot" "yes")
5677    (set_attr "fp_set" "unknown")])
5678
5679 (define_insn "call_valuei_pcrel"
5680   [(set (match_operand 0 "" "=rf")
5681         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5682               (match_operand 2 "" "")))
5683    (use (reg:PSI FPSCR_REG))
5684    (use (reg:SI PIC_REG))
5685    (use (match_operand 3 "" ""))
5686    (clobber (reg:SI PR_REG))]
5687   "TARGET_SH2"
5688   "bsrf %1\\n%O3:%#"
5689   [(set_attr "type" "call")
5690    (set (attr "fp_mode")
5691         (if_then_else (eq_attr "fpu_single" "yes")
5692                       (const_string "single") (const_string "double")))
5693    (set_attr "needs_delay_slot" "yes")
5694    (set_attr "fp_set" "unknown")])
5695
5696 (define_insn_and_split "call_value_pcrel"
5697   [(set (match_operand 0 "" "=rf")
5698         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5699               (match_operand 2 "" "")))
5700    (use (reg:PSI FPSCR_REG))
5701    (use (reg:SI PIC_REG))
5702    (clobber (reg:SI PR_REG))
5703    (clobber (match_scratch:SI 3 "=r"))]
5704   "TARGET_SH2"
5705   "#"
5706   "reload_completed"
5707   [(const_int 0)]
5708   "
5709 {
5710   rtx lab = PATTERN (gen_call_site ());
5711
5712   if (SYMBOL_REF_LOCAL_P (operands[1]))
5713     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5714   else
5715     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5716   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5717                                          operands[2], lab));
5718   DONE;
5719 }"
5720   [(set_attr "type" "call")
5721    (set (attr "fp_mode")
5722         (if_then_else (eq_attr "fpu_single" "yes")
5723                       (const_string "single") (const_string "double")))
5724    (set_attr "needs_delay_slot" "yes")
5725    (set_attr "fp_set" "unknown")])
5726
5727 (define_insn "call_value_compact"
5728   [(set (match_operand 0 "" "=rf")
5729         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5730               (match_operand 2 "" "")))
5731    (match_operand 3 "immediate_operand" "n")
5732    (use (reg:SI R0_REG))
5733    (use (reg:SI R1_REG))
5734    (use (reg:PSI FPSCR_REG))
5735    (clobber (reg:SI PR_REG))]
5736   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5737   "jsr  @%1%#"
5738   [(set_attr "type" "call")
5739    (set (attr "fp_mode")
5740         (if_then_else (eq_attr "fpu_single" "yes")
5741                       (const_string "single") (const_string "double")))
5742    (set_attr "needs_delay_slot" "yes")])
5743
5744 (define_insn "call_value_compact_rettramp"
5745   [(set (match_operand 0 "" "=rf")
5746         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5747               (match_operand 2 "" "")))
5748    (match_operand 3 "immediate_operand" "n")
5749    (use (reg:SI R0_REG))
5750    (use (reg:SI R1_REG))
5751    (use (reg:PSI FPSCR_REG))
5752    (clobber (reg:SI R10_REG))
5753    (clobber (reg:SI PR_REG))]
5754   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5755   "jsr  @%1%#"
5756   [(set_attr "type" "call")
5757    (set (attr "fp_mode")
5758         (if_then_else (eq_attr "fpu_single" "yes")
5759                       (const_string "single") (const_string "double")))
5760    (set_attr "needs_delay_slot" "yes")])
5761
5762 (define_insn "call_value_media"
5763   [(set (match_operand 0 "" "=rf")
5764         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5765               (match_operand 2 "" "")))
5766    (clobber (reg:DI PR_MEDIA_REG))]
5767   "TARGET_SHMEDIA"
5768   "blink        %1, r18"
5769   [(set_attr "type" "jump_media")])
5770
5771 (define_expand "call"
5772   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5773                             (match_operand 1 "" ""))
5774               (match_operand 2 "" "")
5775               (use (reg:PSI FPSCR_REG))
5776               (clobber (reg:SI PR_REG))])]
5777   ""
5778   "
5779 {
5780   if (TARGET_SHMEDIA)
5781     {
5782       operands[0] = XEXP (operands[0], 0);
5783       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5784         {
5785           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5786             {
5787               rtx reg = gen_reg_rtx (Pmode);
5788
5789               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5790               operands[0] = reg;
5791             }
5792           else
5793             {
5794               operands[0] = gen_sym2PIC (operands[0]);
5795               PUT_MODE (operands[0], Pmode);
5796             }
5797         }
5798       if (GET_MODE (operands[0]) == SImode)
5799         {
5800           if (GET_CODE (operands[0]) == REG)
5801             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5802           else if (GET_CODE (operands[0]) == SUBREG)
5803             {
5804               operands[0] = SUBREG_REG (operands[0]);
5805               if (GET_MODE (operands[0]) != DImode)
5806                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5807             }
5808           else
5809             {
5810               operands[0] = shallow_copy_rtx (operands[0]);
5811               PUT_MODE (operands[0], DImode);
5812             }
5813         }
5814       if (! target_reg_operand (operands[0], DImode))
5815         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5816       emit_call_insn (gen_call_media (operands[0], operands[1]));
5817       DONE;
5818     }
5819   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5820     {
5821       rtx cookie_rtx = operands[2];
5822       long cookie = INTVAL (cookie_rtx);
5823       rtx func = XEXP (operands[0], 0);
5824       rtx r0, r1;
5825
5826       if (flag_pic)
5827         {
5828           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5829             {
5830               rtx reg = gen_reg_rtx (Pmode);
5831
5832               emit_insn (gen_symGOTPLT2reg (reg, func));
5833               func = reg;
5834             }
5835           else
5836             func = legitimize_pic_address (func, Pmode, 0);
5837         }
5838
5839       r0 = gen_rtx_REG (SImode, R0_REG);
5840       r1 = gen_rtx_REG (SImode, R1_REG);
5841
5842       /* Since such a call function may use all call-clobbered
5843          registers, we force a mode switch earlier, so that we don't
5844          run out of registers when adjusting fpscr for the call.  */
5845       emit_insn (gen_force_mode_for_call ());
5846
5847       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5848       if (flag_pic)
5849         {
5850           rtx reg = gen_reg_rtx (Pmode);
5851
5852           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5853           operands[0] = reg;
5854         }
5855       operands[0] = force_reg (SImode, operands[0]);
5856
5857       emit_move_insn (r0, func);
5858       emit_move_insn (r1, cookie_rtx);
5859
5860       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5861         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5862                                                    operands[2]));
5863       else
5864         emit_call_insn (gen_call_compact (operands[0], operands[1],
5865                                           operands[2]));
5866
5867       DONE;
5868     }
5869   else if (TARGET_SHCOMPACT && flag_pic
5870            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5871            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5872     {
5873       rtx reg = gen_reg_rtx (Pmode);
5874
5875       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5876       XEXP (operands[0], 0) = reg;
5877     }
5878   if (flag_pic && TARGET_SH2
5879       && GET_CODE (operands[0]) == MEM
5880       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5881     {
5882       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5883       DONE;
5884     }
5885   else
5886   {
5887     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5888     operands[1] = operands[2];
5889   }
5890
5891   emit_call_insn (gen_calli (operands[0], operands[1]));
5892   DONE;
5893 }")
5894
5895 (define_insn "call_pop_compact"
5896   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5897          (match_operand 1 "" ""))
5898    (match_operand 2 "immediate_operand" "n")
5899    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5900                                  (match_operand 3 "immediate_operand" "n")))
5901    (use (reg:SI R0_REG))
5902    (use (reg:SI R1_REG))
5903    (use (reg:PSI FPSCR_REG))
5904    (clobber (reg:SI PR_REG))]
5905   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5906   "jsr  @%0%#"
5907   [(set_attr "type" "call")
5908    (set (attr "fp_mode")
5909         (if_then_else (eq_attr "fpu_single" "yes")
5910                       (const_string "single") (const_string "double")))
5911    (set_attr "needs_delay_slot" "yes")])
5912
5913 (define_insn "call_pop_compact_rettramp"
5914   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5915          (match_operand 1 "" ""))
5916    (match_operand 2 "immediate_operand" "n")
5917    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5918                                  (match_operand 3 "immediate_operand" "n")))
5919    (use (reg:SI R0_REG))
5920    (use (reg:SI R1_REG))
5921    (use (reg:PSI FPSCR_REG))
5922    (clobber (reg:SI R10_REG))
5923    (clobber (reg:SI PR_REG))]
5924   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5925   "jsr  @%0%#"
5926   [(set_attr "type" "call")
5927    (set (attr "fp_mode")
5928         (if_then_else (eq_attr "fpu_single" "yes")
5929                       (const_string "single") (const_string "double")))
5930    (set_attr "needs_delay_slot" "yes")])
5931
5932 (define_expand "call_pop"
5933   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5934                     (match_operand 1 "" ""))
5935              (match_operand 2 "" "")
5936              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5937                                            (match_operand 3 "" "")))])]
5938   "TARGET_SHCOMPACT"
5939   "
5940 {
5941   if (operands[2] && INTVAL (operands[2]))
5942     {
5943       rtx cookie_rtx = operands[2];
5944       long cookie = INTVAL (cookie_rtx);
5945       rtx func = XEXP (operands[0], 0);
5946       rtx r0, r1;
5947
5948       if (flag_pic)
5949         {
5950           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5951             {
5952               rtx reg = gen_reg_rtx (Pmode);
5953
5954               emit_insn (gen_symGOTPLT2reg (reg, func));
5955               func = reg;
5956             }
5957           else
5958             func = legitimize_pic_address (func, Pmode, 0);
5959         }
5960
5961       r0 = gen_rtx_REG (SImode, R0_REG);
5962       r1 = gen_rtx_REG (SImode, R1_REG);
5963
5964       /* Since such a call function may use all call-clobbered
5965          registers, we force a mode switch earlier, so that we don't
5966          run out of registers when adjusting fpscr for the call.  */
5967       emit_insn (gen_force_mode_for_call ());
5968
5969       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5970       if (flag_pic)
5971         {
5972           rtx reg = gen_reg_rtx (Pmode);
5973
5974           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5975           operands[0] = reg;
5976         }
5977       operands[0] = force_reg (SImode, operands[0]);
5978
5979       emit_move_insn (r0, func);
5980       emit_move_insn (r1, cookie_rtx);
5981
5982       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5983         emit_call_insn (gen_call_pop_compact_rettramp
5984                         (operands[0], operands[1], operands[2], operands[3]));
5985       else
5986         emit_call_insn (gen_call_pop_compact
5987                         (operands[0], operands[1], operands[2], operands[3]));
5988
5989       DONE;
5990     }
5991
5992   abort ();
5993 }")
5994
5995 (define_expand "call_value"
5996   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5997                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5998                                  (match_operand 2 "" "")))
5999               (match_operand 3 "" "")
6000               (use (reg:PSI FPSCR_REG))
6001               (clobber (reg:SI PR_REG))])]
6002   ""
6003   "
6004 {
6005   if (TARGET_SHMEDIA)
6006     {
6007       operands[1] = XEXP (operands[1], 0);
6008       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6009         {
6010           if (! SYMBOL_REF_LOCAL_P (operands[1]))
6011             {
6012               rtx reg = gen_reg_rtx (Pmode);
6013
6014               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6015               operands[1] = reg;
6016             }
6017           else
6018             {
6019               operands[1] = gen_sym2PIC (operands[1]);
6020               PUT_MODE (operands[1], Pmode);
6021             }
6022         }
6023       if (GET_MODE (operands[1]) == SImode)
6024         {
6025           if (GET_CODE (operands[1]) == REG)
6026             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6027           else if (GET_CODE (operands[1]) == SUBREG)
6028             {
6029               operands[1] = SUBREG_REG (operands[1]);
6030               if (GET_MODE (operands[1]) != DImode)
6031                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6032             }
6033           else
6034             {
6035               operands[1] = shallow_copy_rtx (operands[1]);
6036               PUT_MODE (operands[1], DImode);
6037             }
6038         }
6039       if (! target_reg_operand (operands[1], DImode))
6040         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6041       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6042                                             operands[2]));
6043       DONE;
6044     }
6045   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6046     {
6047       rtx cookie_rtx = operands[3];
6048       long cookie = INTVAL (cookie_rtx);
6049       rtx func = XEXP (operands[1], 0);
6050       rtx r0, r1;
6051
6052       if (flag_pic)
6053         {
6054           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6055             {
6056               rtx reg = gen_reg_rtx (Pmode);
6057
6058               emit_insn (gen_symGOTPLT2reg (reg, func));
6059               func = reg;
6060             }
6061           else
6062             func = legitimize_pic_address (func, Pmode, 0);
6063         }
6064
6065       r0 = gen_rtx_REG (SImode, R0_REG);
6066       r1 = gen_rtx_REG (SImode, R1_REG);
6067
6068       /* Since such a call function may use all call-clobbered
6069          registers, we force a mode switch earlier, so that we don't
6070          run out of registers when adjusting fpscr for the call.  */
6071       emit_insn (gen_force_mode_for_call ());
6072
6073       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6074       if (flag_pic)
6075         {
6076           rtx reg = gen_reg_rtx (Pmode);
6077
6078           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6079           operands[1] = reg;
6080         }
6081       operands[1] = force_reg (SImode, operands[1]);
6082
6083       emit_move_insn (r0, func);
6084       emit_move_insn (r1, cookie_rtx);
6085
6086       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6087         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6088                                                          operands[1],
6089                                                          operands[2],
6090                                                          operands[3]));
6091       else
6092         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6093                                                 operands[2], operands[3]));
6094
6095       DONE;
6096     }
6097   else if (TARGET_SHCOMPACT && flag_pic
6098            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6099            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6100     {
6101       rtx reg = gen_reg_rtx (Pmode);
6102
6103       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6104       XEXP (operands[1], 0) = reg;
6105     }
6106   if (flag_pic && TARGET_SH2
6107       && GET_CODE (operands[1]) == MEM
6108       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6109     {
6110       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6111                                             operands[2]));
6112       DONE;
6113     }
6114   else
6115     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6116
6117   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6118   DONE;
6119 }")
6120
6121 (define_insn "sibcalli"
6122   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6123          (match_operand 1 "" ""))
6124    (use (reg:PSI FPSCR_REG))
6125    (return)]
6126   "TARGET_SH1"
6127   "jmp  @%0%#"
6128   [(set_attr "needs_delay_slot" "yes")
6129    (set (attr "fp_mode")
6130         (if_then_else (eq_attr "fpu_single" "yes")
6131                       (const_string "single") (const_string "double")))
6132    (set_attr "type" "jump_ind")])
6133
6134 (define_insn "sibcalli_pcrel"
6135   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6136          (match_operand 1 "" ""))
6137    (use (match_operand 2 "" ""))
6138    (use (reg:PSI FPSCR_REG))
6139    (return)]
6140   "TARGET_SH2"
6141   "braf %0\\n%O2:%#"
6142   [(set_attr "needs_delay_slot" "yes")
6143    (set (attr "fp_mode")
6144         (if_then_else (eq_attr "fpu_single" "yes")
6145                       (const_string "single") (const_string "double")))
6146    (set_attr "type" "jump_ind")])
6147
6148 (define_insn_and_split "sibcall_pcrel"
6149   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6150          (match_operand 1 "" ""))
6151    (use (reg:PSI FPSCR_REG))
6152    (clobber (match_scratch:SI 2 "=k"))
6153    (return)]
6154   "TARGET_SH2"
6155   "#"
6156   "reload_completed"
6157   [(const_int 0)]
6158   "
6159 {
6160   rtx lab = PATTERN (gen_call_site ());
6161   rtx call_insn;
6162
6163   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6164   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6165                                                   lab));
6166   SIBLING_CALL_P (call_insn) = 1;
6167   DONE;
6168 }"
6169   [(set_attr "needs_delay_slot" "yes")
6170    (set (attr "fp_mode")
6171         (if_then_else (eq_attr "fpu_single" "yes")
6172                       (const_string "single") (const_string "double")))
6173    (set_attr "type" "jump_ind")])
6174
6175 (define_insn "sibcall_compact"
6176   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6177          (match_operand 1 "" ""))
6178    (return)
6179    (use (match_operand:SI 2 "register_operand" "z,x"))
6180    (use (reg:SI R1_REG))
6181    (use (reg:PSI FPSCR_REG))
6182    ;; We want to make sure the `x' above will only match MACH_REG
6183    ;; because sibcall_epilogue may clobber MACL_REG.
6184    (clobber (reg:SI MACL_REG))]
6185   "TARGET_SHCOMPACT"
6186   "@
6187         jmp     @%0%#
6188         jmp     @%0\\n  sts     %2, r0"
6189   [(set_attr "needs_delay_slot" "yes,no")
6190    (set_attr "length" "2,4")
6191    (set (attr "fp_mode") (const_string "single"))
6192    (set_attr "type" "jump_ind")])
6193
6194 (define_insn "sibcall_media"
6195   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6196          (match_operand 1 "" ""))
6197    (use (reg:SI PR_MEDIA_REG))
6198    (return)]
6199   "TARGET_SHMEDIA"
6200   "blink        %0, r63"
6201   [(set_attr "type" "jump_media")])
6202
6203 (define_expand "sibcall"
6204   [(parallel
6205     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6206            (match_operand 1 "" ""))
6207      (match_operand 2 "" "")
6208      (use (reg:PSI FPSCR_REG))
6209      (return)])]
6210   ""
6211   "
6212 {
6213   if (TARGET_SHMEDIA)
6214     {
6215       operands[0] = XEXP (operands[0], 0);
6216       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6217         {
6218           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6219             {
6220               rtx reg = gen_reg_rtx (Pmode);
6221
6222               /* We must not use GOTPLT for sibcalls, because PIC_REG
6223                  must be restored before the PLT code gets to run.  */
6224               emit_insn (gen_symGOT2reg (reg, operands[0]));
6225               operands[0] = reg;
6226             }
6227           else
6228             {
6229               operands[0] = gen_sym2PIC (operands[0]);
6230               PUT_MODE (operands[0], Pmode);
6231             }
6232         }
6233       if (GET_MODE (operands[0]) == SImode)
6234         {
6235           if (GET_CODE (operands[0]) == REG)
6236             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6237           else if (GET_CODE (operands[0]) == SUBREG)
6238             {
6239               operands[0] = SUBREG_REG (operands[0]);
6240               if (GET_MODE (operands[0]) != DImode)
6241                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6242             }
6243           else
6244             {
6245               operands[0] = shallow_copy_rtx (operands[0]);
6246               PUT_MODE (operands[0], DImode);
6247             }
6248         }
6249       if (! target_reg_operand (operands[0], DImode))
6250         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6251       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6252       DONE;
6253     }
6254   else if (TARGET_SHCOMPACT && operands[2]
6255            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6256     {
6257       rtx cookie_rtx = operands[2];
6258       long cookie = INTVAL (cookie_rtx);
6259       rtx func = XEXP (operands[0], 0);
6260       rtx mach, r1;
6261
6262       if (flag_pic)
6263         {
6264           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6265             {
6266               rtx reg = gen_reg_rtx (Pmode);
6267
6268               emit_insn (gen_symGOT2reg (reg, func));
6269               func = reg;
6270             }
6271           else
6272             func = legitimize_pic_address (func, Pmode, 0);
6273         }
6274
6275       /* FIXME: if we could tell whether all argument registers are
6276          already taken, we could decide whether to force the use of
6277          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6278          simple way to tell.  We could use the CALL_COOKIE, but we
6279          can't currently tell a register used for regular argument
6280          passing from one that is unused.  If we leave it up to reload
6281          to decide which register to use, it seems to always choose
6282          R0_REG, which leaves no available registers in SIBCALL_REGS
6283          to hold the address of the trampoline.  */
6284       mach = gen_rtx_REG (SImode, MACH_REG);
6285       r1 = gen_rtx_REG (SImode, R1_REG);
6286
6287       /* Since such a call function may use all call-clobbered
6288          registers, we force a mode switch earlier, so that we don't
6289          run out of registers when adjusting fpscr for the call.  */
6290       emit_insn (gen_force_mode_for_call ());
6291
6292       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6293       if (flag_pic)
6294         {
6295           rtx reg = gen_reg_rtx (Pmode);
6296
6297           emit_insn (gen_symGOT2reg (reg, operands[0]));
6298           operands[0] = reg;
6299         }
6300       operands[0] = force_reg (SImode, operands[0]);
6301
6302       /* We don't need a return trampoline, since the callee will
6303          return directly to the upper caller.  */
6304       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6305         {
6306           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6307           cookie_rtx = GEN_INT (cookie);
6308         }
6309
6310       emit_move_insn (mach, func);
6311       emit_move_insn (r1, cookie_rtx);
6312
6313       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6314       DONE;
6315     }
6316   else if (TARGET_SHCOMPACT && flag_pic
6317            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6318            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6319     {
6320       rtx reg = gen_reg_rtx (Pmode);
6321
6322       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6323       XEXP (operands[0], 0) = reg;
6324     }
6325   if (flag_pic && TARGET_SH2
6326       && GET_CODE (operands[0]) == MEM
6327       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6328       /* The PLT needs the PIC register, but the epilogue would have
6329          to restore it, so we can only use PC-relative PIC calls for
6330          static functions.  */
6331       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6332     {
6333       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6334       DONE;
6335     }
6336   else
6337     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6338
6339   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6340   DONE;
6341 }")
6342
6343 (define_expand "sibcall_value"
6344   [(set (match_operand 0 "" "")
6345         (call (match_operand 1 "" "")
6346               (match_operand 2 "" "")))
6347    (match_operand 3 "" "")]
6348   ""
6349   "
6350 {
6351   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6352   DONE;
6353 }")
6354
6355 (define_insn "call_value_pop_compact"
6356   [(set (match_operand 0 "" "=rf")
6357         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6358               (match_operand 2 "" "")))
6359    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6360                                  (match_operand 4 "immediate_operand" "n")))
6361    (match_operand 3 "immediate_operand" "n")
6362    (use (reg:SI R0_REG))
6363    (use (reg:SI R1_REG))
6364    (use (reg:PSI FPSCR_REG))
6365    (clobber (reg:SI PR_REG))]
6366   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6367   "jsr  @%1%#"
6368   [(set_attr "type" "call")
6369    (set (attr "fp_mode")
6370         (if_then_else (eq_attr "fpu_single" "yes")
6371                       (const_string "single") (const_string "double")))
6372    (set_attr "needs_delay_slot" "yes")])
6373
6374 (define_insn "call_value_pop_compact_rettramp"
6375   [(set (match_operand 0 "" "=rf")
6376         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6377               (match_operand 2 "" "")))
6378    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6379                                  (match_operand 4 "immediate_operand" "n")))
6380    (match_operand 3 "immediate_operand" "n")
6381    (use (reg:SI R0_REG))
6382    (use (reg:SI R1_REG))
6383    (use (reg:PSI FPSCR_REG))
6384    (clobber (reg:SI R10_REG))
6385    (clobber (reg:SI PR_REG))]
6386   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6387   "jsr  @%1%#"
6388   [(set_attr "type" "call")
6389    (set (attr "fp_mode")
6390         (if_then_else (eq_attr "fpu_single" "yes")
6391                       (const_string "single") (const_string "double")))
6392    (set_attr "needs_delay_slot" "yes")])
6393
6394 (define_expand "call_value_pop"
6395   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6396                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6397                                  (match_operand 2 "" "")))
6398               (match_operand 3 "" "")
6399               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6400                                             (match_operand 4 "" "")))])]
6401   "TARGET_SHCOMPACT"
6402   "
6403 {
6404   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6405     {
6406       rtx cookie_rtx = operands[3];
6407       long cookie = INTVAL (cookie_rtx);
6408       rtx func = XEXP (operands[1], 0);
6409       rtx r0, r1;
6410
6411       if (flag_pic)
6412         {
6413           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6414             {
6415               rtx reg = gen_reg_rtx (Pmode);
6416
6417               emit_insn (gen_symGOTPLT2reg (reg, func));
6418               func = reg;
6419             }
6420           else
6421             func = legitimize_pic_address (func, Pmode, 0);
6422         }
6423
6424       r0 = gen_rtx_REG (SImode, R0_REG);
6425       r1 = gen_rtx_REG (SImode, R1_REG);
6426
6427       /* Since such a call function may use all call-clobbered
6428          registers, we force a mode switch earlier, so that we don't
6429          run out of registers when adjusting fpscr for the call.  */
6430       emit_insn (gen_force_mode_for_call ());
6431
6432       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6433       if (flag_pic)
6434         {
6435           rtx reg = gen_reg_rtx (Pmode);
6436
6437           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6438           operands[1] = reg;
6439         }
6440       operands[1] = force_reg (SImode, operands[1]);
6441
6442       emit_move_insn (r0, func);
6443       emit_move_insn (r1, cookie_rtx);
6444
6445       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6446         emit_call_insn (gen_call_value_pop_compact_rettramp
6447                         (operands[0], operands[1], operands[2],
6448                          operands[3], operands[4]));
6449       else
6450         emit_call_insn (gen_call_value_pop_compact
6451                         (operands[0], operands[1], operands[2],
6452                          operands[3], operands[4]));
6453
6454       DONE;
6455     }
6456
6457   abort ();
6458 }")
6459
6460 (define_expand "sibcall_epilogue"
6461   [(return)]
6462   ""
6463   "
6464 {
6465   sh_expand_epilogue ();
6466   if (TARGET_SHCOMPACT)
6467     {
6468       rtx insn, set;
6469
6470       /* If epilogue clobbers r0, preserve it in macl.  */
6471       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6472         if ((set = single_set (insn))
6473             && GET_CODE (SET_DEST (set)) == REG
6474             && REGNO (SET_DEST (set)) == R0_REG)
6475           {
6476             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6477             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6478             rtx i;
6479
6480             /* We can't tell at this point whether the sibcall is a
6481                sibcall_compact and, if it is, whether it uses r0 or
6482                mach as operand 2, so let the instructions that
6483                preserve r0 be optimized away if r0 turns out to be
6484                dead.  */
6485             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6486             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6487                                                REG_NOTES (i));
6488             i = emit_move_insn (r0, tmp);
6489             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6490                                                REG_NOTES (i));
6491             break;
6492           }
6493     }
6494   DONE;
6495 }")
6496
6497 (define_insn "indirect_jump_compact"
6498   [(set (pc)
6499         (match_operand:SI 0 "arith_reg_operand" "r"))]
6500   "TARGET_SH1"
6501   "jmp  @%0%#"
6502   [(set_attr "needs_delay_slot" "yes")
6503    (set_attr "type" "jump_ind")])
6504
6505 (define_expand "indirect_jump"
6506   [(set (pc)
6507         (match_operand 0 "register_operand" ""))]
6508   ""
6509   "
6510 {
6511   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6512     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6513 }")
6514
6515 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6516 ;; which can be present in structured code from indirect jumps which can not
6517 ;; be present in structured code.  This allows -fprofile-arcs to work.
6518
6519 ;; For SH1 processors.
6520 (define_insn "casesi_jump_1"
6521   [(set (pc)
6522         (match_operand:SI 0 "register_operand" "r"))
6523    (use (label_ref (match_operand 1 "" "")))]
6524   "TARGET_SH1"
6525   "jmp  @%0%#"
6526   [(set_attr "needs_delay_slot" "yes")
6527    (set_attr "type" "jump_ind")])
6528
6529 ;; For all later processors.
6530 (define_insn "casesi_jump_2"
6531   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6532                       (label_ref (match_operand 1 "" ""))))
6533    (use (label_ref (match_operand 2 "" "")))]
6534   "TARGET_SH2
6535    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6536   "braf %0%#"
6537   [(set_attr "needs_delay_slot" "yes")
6538    (set_attr "type" "jump_ind")])
6539
6540 (define_insn "casesi_jump_media"
6541   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6542    (use (label_ref (match_operand 1 "" "")))]
6543   "TARGET_SHMEDIA"
6544   "blink        %0, r63"
6545   [(set_attr "type" "jump_media")])
6546
6547 ;; Call subroutine returning any type.
6548 ;; ??? This probably doesn't work.
6549
6550 (define_expand "untyped_call"
6551   [(parallel [(call (match_operand 0 "" "")
6552                     (const_int 0))
6553               (match_operand 1 "" "")
6554               (match_operand 2 "" "")])]
6555   "TARGET_SH2E || TARGET_SHMEDIA"
6556   "
6557 {
6558   int i;
6559
6560   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6561
6562   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6563     {
6564       rtx set = XVECEXP (operands[2], 0, i);
6565       emit_move_insn (SET_DEST (set), SET_SRC (set));
6566     }
6567
6568   /* The optimizer does not know that the call sets the function value
6569      registers we stored in the result block.  We avoid problems by
6570      claiming that all hard registers are used and clobbered at this
6571      point.  */
6572   emit_insn (gen_blockage ());
6573
6574   DONE;
6575 }")
6576 \f
6577 ;; ------------------------------------------------------------------------
6578 ;; Misc insns
6579 ;; ------------------------------------------------------------------------
6580
6581 (define_insn "dect"
6582   [(set (reg:SI T_REG)
6583         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6584    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6585   "TARGET_SH2"
6586   "dt   %0"
6587   [(set_attr "type" "arith")])
6588
6589 (define_insn "nop"
6590   [(const_int 0)]
6591   ""
6592   "nop")
6593
6594 ;; Load address of a label. This is only generated by the casesi expand,
6595 ;; and by machine_dependent_reorg (fixing up fp moves).
6596 ;; This must use unspec, because this only works for labels that are
6597 ;; within range,
6598
6599 (define_insn "mova"
6600   [(set (reg:SI R0_REG)
6601         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6602   "TARGET_SH1"
6603   "mova %O0,r0"
6604   [(set_attr "in_delay_slot" "no")
6605    (set_attr "type" "arith")])
6606
6607 ;; machine_dependent_reorg will make this a `mova'.
6608 (define_insn "mova_const"
6609   [(set (reg:SI R0_REG)
6610         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6611   "TARGET_SH1"
6612   "#"
6613   [(set_attr "in_delay_slot" "no")
6614    (set_attr "type" "arith")])
6615
6616 (define_expand "GOTaddr2picreg"
6617   [(set (reg:SI R0_REG)
6618         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6619                    UNSPEC_MOVA))
6620    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6621    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6622   "" "
6623 {
6624   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6625   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6626
6627   if (TARGET_SH5)
6628     operands[1] = gen_datalabel_ref (operands[1]);
6629
6630   if (TARGET_SHMEDIA)
6631     {
6632       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6633       rtx dipic = operands[0];
6634       rtx lab = PATTERN (gen_call_site ());
6635       rtx insn, equiv;
6636
6637       equiv = operands[1];
6638       operands[1] = gen_rtx_MINUS (DImode,
6639                                    operands[1],
6640                                    gen_rtx_CONST
6641                                    (DImode,
6642                                     gen_rtx_MINUS (DImode,
6643                                                    gen_rtx_CONST (DImode,
6644                                                                   lab),
6645                                                    pc_rtx)));
6646       operands[1] = gen_sym2PIC (operands[1]);
6647       PUT_MODE (operands[1], DImode);
6648
6649       if (GET_MODE (dipic) != DImode)
6650         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6651
6652       if (TARGET_SHMEDIA64)
6653         emit_insn (gen_movdi_const (dipic, operands[1]));
6654       else
6655         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6656
6657       emit_insn (gen_ptrel (tr, dipic, lab));
6658
6659       if (GET_MODE (operands[0]) != GET_MODE (tr))
6660         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6661
6662       insn = emit_move_insn (operands[0], tr);
6663
6664       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6665                                             REG_NOTES (insn));
6666
6667       DONE;
6668     }
6669 }
6670 ")
6671
6672 (define_insn "*ptb"
6673   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6674         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6675                              UNSPEC_DATALABEL)))]
6676   "TARGET_SHMEDIA && flag_pic
6677    && EXTRA_CONSTRAINT_Csy (operands[1])"
6678   "ptb/u        datalabel %1, %0"
6679   [(set_attr "type" "pt_media")
6680    (set_attr "length" "*")])
6681
6682 (define_insn "ptrel"
6683   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6684         (plus:DI (match_operand:DI 1 "register_operand" "r")
6685               (pc)))
6686    (match_operand:DI 2 "" "")]
6687   "TARGET_SHMEDIA"
6688   "%O2: ptrel/u %1, %0"
6689   [(set_attr "type" "ptabs_media")])
6690
6691 (define_expand "builtin_setjmp_receiver"
6692   [(match_operand 0 "" "")]
6693   "flag_pic"
6694   "
6695 {
6696   emit_insn (gen_GOTaddr2picreg ());
6697   DONE;
6698 }")
6699
6700 (define_expand "call_site"
6701   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6702   "TARGET_SH1"
6703   "
6704 {
6705   static HOST_WIDE_INT i = 0;
6706   operands[0] = GEN_INT (i);
6707   i++;
6708 }")
6709
6710 (define_expand "sym_label2reg"
6711   [(set (match_operand:SI 0 "" "")
6712         (const:SI (minus:SI
6713                    (const:SI
6714                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6715                    (const:SI
6716                     (plus:SI
6717                      (match_operand:SI 2 "" "")
6718                      (const_int 2))))))]
6719   "TARGET_SH1" "")
6720
6721 (define_expand "symGOT_load"
6722   [(set (match_dup 2) (match_operand 1 "" ""))
6723    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6724    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6725   ""
6726   "
6727 {
6728   rtx insn;
6729
6730   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6731   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6732
6733   if (TARGET_SHMEDIA)
6734     {
6735       rtx reg = operands[2];
6736
6737       if (GET_MODE (reg) != DImode)
6738         reg = gen_rtx_SUBREG (DImode, reg, 0);
6739
6740       if (flag_pic > 1)
6741         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6742       else
6743         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6744     }
6745   else
6746     emit_move_insn (operands[2], operands[1]);
6747
6748   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6749                                              operands[2],
6750                                              gen_rtx_REG (Pmode, PIC_REG)));
6751
6752   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6753
6754   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6755                                                                   0), 0, 0),
6756                                         REG_NOTES (insn));
6757
6758   DONE;
6759 }")
6760
6761 (define_expand "sym2GOT"
6762   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6763   ""
6764   "")
6765
6766 (define_expand "symGOT2reg"
6767   [(match_operand 0 "" "") (match_operand 1 "" "")]
6768   ""
6769   "
6770 {
6771   rtx gotsym, insn;
6772
6773   gotsym = gen_sym2GOT (operands[1]);
6774   PUT_MODE (gotsym, Pmode);
6775   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6776
6777   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6778
6779   DONE;
6780 }")
6781
6782 (define_expand "sym2GOTPLT"
6783   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6784   ""
6785   "")
6786
6787 (define_expand "symGOTPLT2reg"
6788   [(match_operand 0 "" "") (match_operand 1 "" "")]
6789   ""
6790   "
6791 {
6792   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6793   DONE;
6794 }")
6795
6796 (define_expand "sym2GOTOFF"
6797   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6798   ""
6799   "")
6800
6801 (define_expand "symGOTOFF2reg"
6802   [(match_operand 0 "" "") (match_operand 1 "" "")]
6803   ""
6804   "
6805 {
6806   rtx gotoffsym, insn;
6807   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6808
6809   gotoffsym = gen_sym2GOTOFF (operands[1]);
6810   PUT_MODE (gotoffsym, Pmode);
6811   emit_move_insn (t, gotoffsym);
6812   insn = emit_move_insn (operands[0],
6813                          gen_rtx_PLUS (Pmode, t,
6814                                        gen_rtx_REG (Pmode, PIC_REG)));
6815
6816   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6817                                         REG_NOTES (insn));
6818
6819   DONE;
6820 }")
6821
6822 (define_expand "symPLT_label2reg"
6823   [(set (match_operand:SI 0 "" "")
6824         (const:SI (minus:SI
6825                    (const:SI
6826                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6827                    (const:SI
6828                     (minus:SI
6829                      (const:SI (plus:SI
6830                                 (match_operand:SI 2 "" "")
6831                                 (const_int 2)))
6832                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6833    ;; Even though the PIC register is not really used by the call
6834    ;; sequence in which this is expanded, the PLT code assumes the PIC
6835    ;; register is set, so we must not skip its initialization.  Since
6836    ;; we only use this expand as part of calling sequences, and never
6837    ;; to take the address of a function, this is the best point to
6838    ;; insert the (use).  Using the PLT to take the address of a
6839    ;; function would be wrong, not only because the PLT entry could
6840    ;; then be called from a function that doesn't initialize the PIC
6841    ;; register to the proper GOT, but also because pointers to the
6842    ;; same function might not compare equal, should they be set by
6843    ;; different shared libraries.
6844    (use (reg:SI PIC_REG))]
6845   "TARGET_SH1"
6846   "")
6847
6848 (define_expand "sym2PIC"
6849   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6850   ""
6851   "")
6852
6853 ;; TLS code generation.
6854 ;; ??? this should be a define_insn_and_split
6855 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6856 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6857 ;; for details.
6858
6859 (define_insn "tls_global_dynamic"
6860   [(set (match_operand:SI 0 "register_operand" "=&z")
6861         (unspec:SI [(match_operand:SI 1 "" "")]
6862                     UNSPEC_TLSGD))
6863    (use (reg:PSI FPSCR_REG))
6864    (use (reg:SI PIC_REG))
6865    (clobber (reg:SI PR_REG))
6866    (clobber (scratch:SI))]
6867   "TARGET_SH1"
6868   "*
6869 {
6870   return \"\\
6871 mov.l\\t1f,r4\\n\\
6872 \\tmova\\t2f,r0\\n\\
6873 \\tmov.l\\t2f,r1\\n\\
6874 \\tadd\\tr0,r1\\n\\
6875 \\tjsr\\t@r1\\n\\
6876 \\tadd\\tr12,r4\\n\\
6877 \\tbra\\t3f\\n\\
6878 \\tnop\\n\\
6879 \\t.align\\t2\\n\\
6880 1:\\t.long\\t%a1@TLSGD\\n\\
6881 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6882 3:\";
6883 }"
6884   [(set_attr "type" "tls_load")
6885    (set_attr "length" "26")])
6886
6887 (define_insn "tls_local_dynamic"
6888   [(set (match_operand:SI 0 "register_operand" "=&z")
6889         (unspec:SI [(match_operand:SI 1 "" "")]
6890                     UNSPEC_TLSLDM))
6891    (use (reg:PSI FPSCR_REG))
6892    (use (reg:SI PIC_REG))
6893    (clobber (reg:SI PR_REG))
6894    (clobber (scratch:SI))]
6895   "TARGET_SH1"
6896   "*
6897 {
6898   return \"\\
6899 mov.l\\t1f,r4\\n\\
6900 \\tmova\\t2f,r0\\n\\
6901 \\tmov.l\\t2f,r1\\n\\
6902 \\tadd\\tr0,r1\\n\\
6903 \\tjsr\\t@r1\\n\\
6904 \\tadd\\tr12,r4\\n\\
6905 \\tbra\\t3f\\n\\
6906 \\tnop\\n\\
6907 \\t.align\\t2\\n\\
6908 1:\\t.long\\t%a1@TLSLDM\\n\\
6909 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6910 3:\";
6911 }"
6912   [(set_attr "type" "tls_load")
6913    (set_attr "length" "26")])
6914
6915 (define_expand "sym2DTPOFF"
6916   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6917   ""
6918   "")
6919
6920 (define_expand "symDTPOFF2reg"
6921   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6922   ""
6923   "
6924 {
6925   rtx dtpoffsym, insn;
6926   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6927
6928   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6929   PUT_MODE (dtpoffsym, Pmode);
6930   emit_move_insn (t, dtpoffsym);
6931   insn = emit_move_insn (operands[0],
6932                          gen_rtx_PLUS (Pmode, t, operands[2]));
6933   DONE;
6934 }")
6935
6936 (define_expand "sym2GOTTPOFF"
6937   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6938   ""
6939   "")
6940
6941 (define_insn "tls_initial_exec"
6942   [(set (match_operand:SI 0 "register_operand" "=&r")
6943         (unspec:SI [(match_operand:SI 1 "" "")]
6944                     UNSPEC_TLSIE))
6945    (use (reg:SI GBR_REG))
6946    (use (reg:SI PIC_REG))
6947    (clobber (reg:SI R0_REG))]
6948   ""
6949   "*
6950 {
6951   return \"\\
6952 mov.l\\t1f,r0\\n\\
6953 \\tstc\\tgbr,%0\\n\\
6954 \\tmov.l\\t@(r0,r12),r0\\n\\
6955 \\tbra\\t2f\\n\\
6956 \\tadd\\tr0,%0\\n\\
6957 \\t.align\\t2\\n\\
6958 1:\\t.long\\t%a1\\n\\
6959 2:\";
6960 }"
6961   [(set_attr "type" "tls_load")
6962    (set_attr "length" "16")])
6963
6964 (define_expand "sym2TPOFF"
6965   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6966   ""
6967   "")
6968
6969 (define_expand "symTPOFF2reg"
6970   [(match_operand 0 "" "") (match_operand 1 "" "")]
6971   ""
6972   "
6973 {
6974   rtx tpoffsym, insn;
6975
6976   tpoffsym = gen_sym2TPOFF (operands[1]);
6977   PUT_MODE (tpoffsym, Pmode);
6978   insn = emit_move_insn (operands[0], tpoffsym);
6979   DONE;
6980 }")
6981
6982 (define_insn "load_gbr"
6983   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6984    (use (reg:SI GBR_REG))]
6985   ""
6986   "stc  gbr,%0"
6987   [(set_attr "type" "tls_load")])
6988
6989 ;; case instruction for switch statements.
6990
6991 ;; Operand 0 is index
6992 ;; operand 1 is the minimum bound
6993 ;; operand 2 is the maximum bound - minimum bound + 1
6994 ;; operand 3 is CODE_LABEL for the table;
6995 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6996
6997 (define_expand "casesi"
6998   [(match_operand:SI 0 "arith_reg_operand" "")
6999    (match_operand:SI 1 "arith_reg_operand" "")
7000    (match_operand:SI 2 "arith_reg_operand" "")
7001    (match_operand 3 "" "") (match_operand 4 "" "")]
7002   ""
7003   "
7004 {
7005   rtx reg = gen_reg_rtx (SImode);
7006   rtx reg2 = gen_reg_rtx (SImode);
7007   if (TARGET_SHMEDIA)
7008     {
7009       rtx reg = gen_reg_rtx (DImode);
7010       rtx reg2 = gen_reg_rtx (DImode);
7011       rtx reg3 = gen_reg_rtx (DImode);
7012       rtx reg4 = gen_reg_rtx (DImode);
7013       rtx reg5 = gen_reg_rtx (DImode);
7014
7015       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7016       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7017       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7018
7019       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7020       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7021       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7022       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7023       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7024                                                (DImode, operands[3])));
7025       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7026       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7027       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7028       emit_barrier ();
7029       DONE;
7030     }
7031   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7032   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7033   /* If optimizing, casesi_worker depends on the mode of the instruction
7034      before label it 'uses' - operands[3].  */
7035   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7036                            reg));
7037   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7038   if (TARGET_SH2)
7039     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7040   else
7041     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7042   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7043      operands[3], but to lab.  We will fix this up in
7044      machine_dependent_reorg.  */
7045   emit_barrier ();
7046   DONE;
7047 }")
7048
7049 (define_expand "casesi_0"
7050   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7051    (set (match_dup 4) (minus:SI (match_dup 4)
7052                                 (match_operand:SI 1 "arith_operand" "")))
7053    (set (reg:SI T_REG)
7054         (gtu:SI (match_dup 4)
7055                 (match_operand:SI 2 "arith_reg_operand" "")))
7056    (set (pc)
7057         (if_then_else (ne (reg:SI T_REG)
7058                           (const_int 0))
7059                       (label_ref (match_operand 3 "" ""))
7060                       (pc)))]
7061   "TARGET_SH1"
7062   "")
7063
7064 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7065 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7066 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7067
7068 (define_insn "casesi_worker_0"
7069   [(set (match_operand:SI 0 "register_operand" "=r,r")
7070         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7071                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7072    (clobber (match_scratch:SI 3 "=X,1"))
7073    (clobber (match_scratch:SI 4 "=&z,z"))]
7074   "TARGET_SH1"
7075   "#")
7076
7077 (define_split
7078   [(set (match_operand:SI 0 "register_operand" "")
7079         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7080                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7081    (clobber (match_scratch:SI 3 ""))
7082    (clobber (match_scratch:SI 4 ""))]
7083   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7084   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7085    (parallel [(set (match_dup 0)
7086               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7087                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7088               (clobber (match_dup 3))])
7089    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7090   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7091
7092 (define_split
7093   [(set (match_operand:SI 0 "register_operand" "")
7094         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7095                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7096    (clobber (match_scratch:SI 3 ""))
7097    (clobber (match_scratch:SI 4 ""))]
7098   "TARGET_SH2 && reload_completed"
7099   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7100    (parallel [(set (match_dup 0)
7101               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7102                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7103               (clobber (match_dup 3))])]
7104   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7105
7106 (define_insn "*casesi_worker"
7107   [(set (match_operand:SI 0 "register_operand" "=r,r")
7108         (unspec:SI [(reg:SI R0_REG)
7109                     (match_operand:SI 1 "register_operand" "0,r")
7110                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7111    (clobber (match_scratch:SI 3 "=X,1"))]
7112   "TARGET_SH1"
7113   "*
7114 {
7115   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7116
7117   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7118     abort ();
7119
7120   switch (GET_MODE (diff_vec))
7121     {
7122     case SImode:
7123       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7124     case HImode:
7125       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7126     case QImode:
7127       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7128         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7129       return \"mov.b    @(r0,%1),%0\";
7130     default:
7131       abort ();
7132     }
7133 }"
7134   [(set_attr "length" "4")])
7135
7136 (define_insn "casesi_shift_media"
7137   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7138         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7139                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7140                     UNSPEC_CASESI)))]
7141   "TARGET_SHMEDIA"
7142   "*
7143 {
7144   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7145
7146   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7147     abort ();
7148
7149   switch (GET_MODE (diff_vec))
7150     {
7151     case SImode:
7152       return \"shlli    %1, 2, %0\";
7153     case HImode:
7154       return \"shlli    %1, 1, %0\";
7155     case QImode:
7156       if (rtx_equal_p (operands[0], operands[1]))
7157         return \"\";
7158       return \"add      %1, r63, %0\";
7159     default:
7160       abort ();
7161     }
7162 }"
7163   [(set_attr "type" "arith_media")])
7164
7165 (define_insn "casesi_load_media"
7166   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7167         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7168                          (match_operand 2 "arith_reg_operand" "r")
7169                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7170   "TARGET_SHMEDIA"
7171   "*
7172 {
7173   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7174
7175   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7176     abort ();
7177
7178   switch (GET_MODE (diff_vec))
7179     {
7180     case SImode:
7181       return \"ldx.l    %1, %2, %0\";
7182     case HImode:
7183 #if 0
7184       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7185         return \"ldx.uw %1, %2, %0\";
7186 #endif
7187       return \"ldx.w    %1, %2, %0\";
7188     case QImode:
7189       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7190         return \"ldx.ub %1, %2, %0\";
7191       return \"ldx.b    %1, %2, %0\";
7192     default:
7193       abort ();
7194     }
7195 }"
7196   [(set_attr "type" "load_media")])
7197
7198 (define_expand "return"
7199   [(return)]
7200   "reload_completed && ! sh_need_epilogue ()"
7201   "
7202 {
7203   if (TARGET_SHMEDIA)
7204     {
7205       emit_jump_insn (gen_return_media ());
7206       DONE;
7207     }
7208
7209   if (TARGET_SHCOMPACT
7210       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7211     {
7212       emit_jump_insn (gen_shcompact_return_tramp ());
7213       DONE;
7214     }
7215 }")
7216
7217 (define_insn "*return_i"
7218   [(return)]
7219   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7220                     && (current_function_args_info.call_cookie
7221                         & CALL_COOKIE_RET_TRAMP (1)))
7222    && reload_completed"
7223   "%@   %#"
7224   [(set_attr "type" "return")
7225    (set_attr "needs_delay_slot" "yes")])
7226
7227 (define_expand "shcompact_return_tramp"
7228   [(return)]
7229   "TARGET_SHCOMPACT
7230    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7231   "
7232 {
7233   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7234   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7235
7236   if (flag_pic)
7237     emit_insn (gen_symGOTPLT2reg (reg, sym));
7238   else
7239     emit_move_insn (reg, sym);
7240
7241   emit_jump_insn (gen_shcompact_return_tramp_i ());
7242   DONE;
7243 }")
7244
7245 (define_insn "shcompact_return_tramp_i"
7246   [(parallel [(return) (use (reg:SI R0_REG))])]
7247   "TARGET_SHCOMPACT
7248    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7249   "jmp  @r0%#"
7250   [(set_attr "type" "jump_ind")
7251    (set_attr "needs_delay_slot" "yes")])
7252
7253 (define_insn "return_media_i"
7254   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7255   "TARGET_SHMEDIA && reload_completed"
7256   "blink        %0, r63"
7257   [(set_attr "type" "jump_media")])
7258
7259 (define_insn "return_media_rte"
7260   [(return)]
7261   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7262   "rte"
7263   [(set_attr "type" "jump_media")])
7264
7265 (define_expand "return_media"
7266   [(return)]
7267   "TARGET_SHMEDIA && reload_completed"
7268   "
7269 {
7270   int tr_regno = sh_media_register_for_return ();
7271   rtx tr;
7272
7273   if (current_function_interrupt)
7274     {
7275       emit_jump_insn (gen_return_media_rte ());
7276       DONE;
7277     }
7278   if (tr_regno < 0)
7279     {
7280       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7281
7282       if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7283         abort ();
7284       tr_regno = TR0_REG;
7285       tr = gen_rtx_REG (DImode, tr_regno);
7286       emit_move_insn (tr, r18);
7287     }
7288   else
7289     tr = gen_rtx_REG (DImode, tr_regno);
7290
7291   emit_jump_insn (gen_return_media_i (tr));
7292   DONE;
7293 }")
7294
7295 (define_insn "shcompact_preserve_incoming_args"
7296   [(set (match_operand:SI 0 "register_operand" "+r")
7297         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7298   "TARGET_SHCOMPACT"
7299   ""
7300   [(set_attr "length" "0")])
7301
7302 (define_insn "shcompact_incoming_args"
7303   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7304    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7305    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7306    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7307    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7308    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7309    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7310    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7311    (set (mem:BLK (reg:SI MACL_REG))
7312         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7313    (use (reg:SI R0_REG))
7314    (clobber (reg:SI R0_REG))
7315    (clobber (reg:SI MACL_REG))
7316    (clobber (reg:SI MACH_REG))
7317    (clobber (reg:SI PR_REG))]
7318   "TARGET_SHCOMPACT"
7319   "jsr  @r0%#"
7320   [(set_attr "needs_delay_slot" "yes")])
7321
7322 (define_insn "shmedia_save_restore_regs_compact"
7323   [(set (reg:SI SP_REG)
7324         (plus:SI (reg:SI SP_REG)
7325                  (match_operand:SI 0 "immediate_operand" "i")))
7326    (use (reg:SI R0_REG))
7327    (clobber (reg:SI PR_REG))]
7328   "TARGET_SHCOMPACT
7329    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7330        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7331   "jsr @r0%#"
7332   [(set_attr "needs_delay_slot" "yes")])
7333
7334 (define_expand "prologue"
7335   [(const_int 0)]
7336   ""
7337   "sh_expand_prologue (); DONE;")
7338
7339 (define_expand "epilogue"
7340   [(return)]
7341   ""
7342   "
7343 {
7344   sh_expand_epilogue ();
7345   emit_jump_insn (gen_return ());
7346   DONE;
7347 }")
7348
7349 (define_expand "eh_return"
7350   [(use (match_operand 0 "register_operand" ""))]
7351   ""
7352 {
7353   rtx tmp, ra = operands[0];
7354
7355   if (TARGET_SHMEDIA64)
7356     emit_insn (gen_eh_set_ra_di (ra));
7357   else
7358     emit_insn (gen_eh_set_ra_si (ra));
7359
7360   DONE;
7361 })
7362
7363 ;; Clobber the return address on the stack.  We can't expand this
7364 ;; until we know where it will be put in the stack frame.
7365
7366 (define_insn "eh_set_ra_si"
7367   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7368    (clobber (match_scratch:SI 1 "=&r"))]
7369   "! TARGET_SHMEDIA64"
7370   "#")
7371
7372 (define_insn "eh_set_ra_di"
7373   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7374    (clobber (match_scratch:DI 1 "=&r"))]
7375   "TARGET_SHMEDIA64"
7376   "#")
7377
7378 (define_split
7379   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7380    (clobber (match_scratch 1 ""))]
7381   "reload_completed"
7382   [(const_int 0)]
7383   "
7384 {
7385   sh_set_return_address (operands[0], operands[1]);
7386   DONE;
7387 }")
7388
7389 (define_insn "blockage"
7390   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7391   ""
7392   ""
7393   [(set_attr "length" "0")])
7394 \f
7395 ;; ------------------------------------------------------------------------
7396 ;; Scc instructions
7397 ;; ------------------------------------------------------------------------
7398
7399 (define_insn "movt"
7400   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7401         (eq:SI (reg:SI T_REG) (const_int 1)))]
7402   "TARGET_SH1"
7403   "movt %0"
7404   [(set_attr "type" "arith")])
7405
7406 (define_expand "seq"
7407   [(set (match_operand:SI 0 "arith_reg_operand" "")
7408         (match_dup 1))]
7409   ""
7410   "
7411 {
7412   if (TARGET_SHMEDIA)
7413     {
7414       if (GET_MODE (operands[0]) != DImode)
7415         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7416       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7417       if (sh_compare_op1 != const0_rtx)
7418         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7419                                     ? GET_MODE (sh_compare_op0)
7420                                     : GET_MODE (sh_compare_op1),
7421                                     sh_compare_op1);
7422
7423       switch (GET_MODE (sh_compare_op0))
7424         {
7425         case DImode:
7426           emit_insn (gen_cmpeqdi_media (operands[0],
7427                                         sh_compare_op0, sh_compare_op1));
7428           break;
7429
7430         case SFmode:
7431           if (! TARGET_SHMEDIA_FPU)
7432             FAIL;
7433           emit_insn (gen_cmpeqsf_media (operands[0],
7434                                         sh_compare_op0, sh_compare_op1));
7435           break;
7436
7437         case DFmode:
7438           if (! TARGET_SHMEDIA_FPU)
7439             FAIL;
7440           emit_insn (gen_cmpeqdf_media (operands[0],
7441                                         sh_compare_op0, sh_compare_op1));
7442           break;
7443
7444         default:
7445           FAIL;
7446         }
7447       DONE;
7448     }
7449   operands[1] = prepare_scc_operands (EQ);
7450 }")
7451
7452 (define_expand "slt"
7453   [(set (match_operand:SI 0 "arith_reg_operand" "")
7454         (match_dup 1))]
7455   ""
7456   "
7457 {
7458   if (TARGET_SHMEDIA)
7459     {
7460       if (GET_MODE (operands[0]) != DImode)
7461         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7462       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7463       if (sh_compare_op1 != const0_rtx)
7464         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7465                                     ? GET_MODE (sh_compare_op0)
7466                                     : GET_MODE (sh_compare_op1),
7467                                     sh_compare_op1);
7468
7469       switch (GET_MODE (sh_compare_op0))
7470         {
7471         case DImode:
7472           emit_insn (gen_cmpgtdi_media (operands[0],
7473                                         sh_compare_op1, sh_compare_op0));
7474           break;
7475
7476         case SFmode:
7477           if (! TARGET_SHMEDIA_FPU)
7478             FAIL;
7479           emit_insn (gen_cmpgtsf_media (operands[0],
7480                                         sh_compare_op1, sh_compare_op0));
7481           break;
7482
7483         case DFmode:
7484           if (! TARGET_SHMEDIA_FPU)
7485             FAIL;
7486           emit_insn (gen_cmpgtdf_media (operands[0],
7487                                         sh_compare_op1, sh_compare_op0));
7488           break;
7489
7490         default:
7491           FAIL;
7492         }
7493       DONE;
7494     }
7495   operands[1] = prepare_scc_operands (LT);
7496 }")
7497
7498 (define_expand "sle"
7499   [(match_operand:SI 0 "arith_reg_operand" "")]
7500   ""
7501   "
7502 {
7503   rtx tmp = sh_compare_op0;
7504
7505   if (TARGET_SHMEDIA)
7506     {
7507       if (GET_MODE (operands[0]) != DImode)
7508         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7509       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7510       if (sh_compare_op1 != const0_rtx)
7511         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7512                                     ? GET_MODE (sh_compare_op0)
7513                                     : GET_MODE (sh_compare_op1),
7514                                     sh_compare_op1);
7515
7516       switch (GET_MODE (sh_compare_op0))
7517         {
7518         case DImode:
7519           {
7520             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7521
7522             emit_insn (gen_cmpgtdi_media (tmp,
7523                                           sh_compare_op0, sh_compare_op1));
7524             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7525             break;
7526           }
7527
7528         case SFmode:
7529           if (! TARGET_SHMEDIA_FPU)
7530             FAIL;
7531           emit_insn (gen_cmpgesf_media (operands[0],
7532                                         sh_compare_op1, sh_compare_op0));
7533           break;
7534
7535         case DFmode:
7536           if (! TARGET_SHMEDIA_FPU)
7537             FAIL;
7538           emit_insn (gen_cmpgedf_media (operands[0],
7539                                         sh_compare_op1, sh_compare_op0));
7540           break;
7541
7542         default:
7543           FAIL;
7544         }
7545       DONE;
7546     }
7547
7548   sh_compare_op0 = sh_compare_op1;
7549   sh_compare_op1 = tmp;
7550   emit_insn (gen_sge (operands[0]));
7551   DONE;
7552 }")
7553
7554 (define_expand "sgt"
7555   [(set (match_operand:SI 0 "arith_reg_operand" "")
7556         (match_dup 1))]
7557   ""
7558   "
7559 {
7560   if (TARGET_SHMEDIA)
7561     {
7562       if (GET_MODE (operands[0]) != DImode)
7563         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7564       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7565       if (sh_compare_op1 != const0_rtx)
7566         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7567                                     ? GET_MODE (sh_compare_op0)
7568                                     : GET_MODE (sh_compare_op1),
7569                                     sh_compare_op1);
7570
7571       switch (GET_MODE (sh_compare_op0))
7572         {
7573         case DImode:
7574           emit_insn (gen_cmpgtdi_media (operands[0],
7575                                         sh_compare_op0, sh_compare_op1));
7576           break;
7577
7578         case SFmode:
7579           if (! TARGET_SHMEDIA_FPU)
7580             FAIL;
7581           emit_insn (gen_cmpgtsf_media (operands[0],
7582                                         sh_compare_op0, sh_compare_op1));
7583           break;
7584
7585         case DFmode:
7586           if (! TARGET_SHMEDIA_FPU)
7587             FAIL;
7588           emit_insn (gen_cmpgtdf_media (operands[0],
7589                                         sh_compare_op0, sh_compare_op1));
7590           break;
7591
7592         default:
7593           FAIL;
7594         }
7595       DONE;
7596     }
7597   operands[1] = prepare_scc_operands (GT);
7598 }")
7599
7600 (define_expand "sge"
7601   [(set (match_operand:SI 0 "arith_reg_operand" "")
7602         (match_dup 1))]
7603   ""
7604   "
7605 {
7606   if (TARGET_SHMEDIA)
7607     {
7608       if (GET_MODE (operands[0]) != DImode)
7609         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7610       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7611       if (sh_compare_op1 != const0_rtx)
7612         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7613                                     ? GET_MODE (sh_compare_op0)
7614                                     : GET_MODE (sh_compare_op1),
7615                                     sh_compare_op1);
7616
7617       switch (GET_MODE (sh_compare_op0))
7618         {
7619         case DImode:
7620           {
7621             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7622
7623             emit_insn (gen_cmpgtdi_media (tmp,
7624                                           sh_compare_op1, sh_compare_op0));
7625             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7626             break;
7627           }
7628
7629         case SFmode:
7630           if (! TARGET_SHMEDIA_FPU)
7631             FAIL;
7632           emit_insn (gen_cmpgesf_media (operands[0],
7633                                         sh_compare_op0, sh_compare_op1));
7634           break;
7635
7636         case DFmode:
7637           if (! TARGET_SHMEDIA_FPU)
7638             FAIL;
7639           emit_insn (gen_cmpgedf_media (operands[0],
7640                                         sh_compare_op0, sh_compare_op1));
7641           break;
7642
7643         default:
7644           FAIL;
7645         }
7646       DONE;
7647     }
7648
7649   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7650     {
7651       if (TARGET_IEEE)
7652         {
7653           rtx lab = gen_label_rtx ();
7654           prepare_scc_operands (EQ);
7655           emit_jump_insn (gen_branch_true (lab));
7656           prepare_scc_operands (GT);
7657           emit_label (lab);
7658           emit_insn (gen_movt (operands[0]));
7659         }
7660       else
7661         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7662       DONE;
7663     }
7664   operands[1] = prepare_scc_operands (GE);
7665 }")
7666
7667 (define_expand "sgtu"
7668   [(set (match_operand:SI 0 "arith_reg_operand" "")
7669         (match_dup 1))]
7670   ""
7671   "
7672 {
7673   if (TARGET_SHMEDIA)
7674     {
7675       if (GET_MODE (operands[0]) != DImode)
7676         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7677       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7678       if (sh_compare_op1 != const0_rtx)
7679         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7680                                     ? GET_MODE (sh_compare_op0)
7681                                     : GET_MODE (sh_compare_op1),
7682                                     sh_compare_op1);
7683
7684       emit_insn (gen_cmpgtudi_media (operands[0],
7685                                      sh_compare_op0, sh_compare_op1));
7686       DONE;
7687     }
7688   operands[1] = prepare_scc_operands (GTU);
7689 }")
7690
7691 (define_expand "sltu"
7692   [(set (match_operand:SI 0 "arith_reg_operand" "")
7693         (match_dup 1))]
7694   ""
7695   "
7696 {
7697   if (TARGET_SHMEDIA)
7698     {
7699       if (GET_MODE (operands[0]) != DImode)
7700         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7701       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7702       if (sh_compare_op1 != const0_rtx)
7703         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7704                                     ? GET_MODE (sh_compare_op0)
7705                                     : GET_MODE (sh_compare_op1),
7706                                     sh_compare_op1);
7707
7708       emit_insn (gen_cmpgtudi_media (operands[0],
7709                                      sh_compare_op1, sh_compare_op0));
7710       DONE;
7711     }
7712   operands[1] = prepare_scc_operands (LTU);
7713 }")
7714
7715 (define_expand "sleu"
7716   [(set (match_operand:SI 0 "arith_reg_operand" "")
7717         (match_dup 1))]
7718   ""
7719   "
7720 {
7721   if (TARGET_SHMEDIA)
7722     {
7723       rtx tmp;
7724
7725       if (GET_MODE (operands[0]) != DImode)
7726         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7727       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7728       if (sh_compare_op1 != const0_rtx)
7729         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7730                                     ? GET_MODE (sh_compare_op0)
7731                                     : GET_MODE (sh_compare_op1),
7732                                     sh_compare_op1);
7733
7734       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7735
7736       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7737       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7738
7739       DONE;
7740     }
7741   operands[1] = prepare_scc_operands (LEU);
7742 }")
7743
7744 (define_expand "sgeu"
7745   [(set (match_operand:SI 0 "arith_reg_operand" "")
7746         (match_dup 1))]
7747   ""
7748   "
7749 {
7750   if (TARGET_SHMEDIA)
7751     {
7752       rtx tmp;
7753
7754       if (GET_MODE (operands[0]) != DImode)
7755         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7756       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7757       if (sh_compare_op1 != const0_rtx)
7758         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7759                                     ? GET_MODE (sh_compare_op0)
7760                                     : GET_MODE (sh_compare_op1),
7761                                     sh_compare_op1);
7762
7763       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7764
7765       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7766       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7767
7768       DONE;
7769     }
7770
7771   operands[1] = prepare_scc_operands (GEU);
7772 }")
7773
7774 ;; sne moves the complement of the T reg to DEST like this:
7775 ;;      cmp/eq ...
7776 ;;      mov    #-1,temp
7777 ;;      negc   temp,dest
7778 ;;   This is better than xoring compare result with 1 because it does
7779 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7780 ;;   loop.
7781
7782 (define_expand "sne"
7783   [(set (match_dup 2) (const_int -1))
7784    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7785                    (neg:SI (plus:SI (match_dup 1)
7786                                     (match_dup 2))))
7787               (set (reg:SI T_REG)
7788                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7789                           (const_int 0)))])]
7790   ""
7791   "
7792 {
7793   if (TARGET_SHMEDIA)
7794     {
7795       rtx tmp;
7796
7797       if (GET_MODE (operands[0]) != DImode)
7798         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7799
7800       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7801         FAIL;
7802
7803       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7804       if (sh_compare_op1 != const0_rtx)
7805         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7806                                     ? GET_MODE (sh_compare_op0)
7807                                     : GET_MODE (sh_compare_op1),
7808                                     sh_compare_op1);
7809
7810       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7811
7812       emit_insn (gen_seq (tmp));
7813       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7814
7815       DONE;
7816     }
7817
7818    operands[1] = prepare_scc_operands (EQ);
7819    operands[2] = gen_reg_rtx (SImode);
7820 }")
7821
7822 (define_expand "sunordered"
7823   [(set (match_operand:DI 0 "arith_reg_operand" "")
7824         (unordered:DI (match_dup 1) (match_dup 2)))]
7825   "TARGET_SHMEDIA_FPU"
7826   "
7827 {
7828   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7829   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7830 }")
7831
7832 ;; Use the same trick for FP sle / sge
7833 (define_expand "movnegt"
7834   [(set (match_dup 2) (const_int -1))
7835    (parallel [(set (match_operand 0 "" "")
7836                    (neg:SI (plus:SI (match_dup 1)
7837                                     (match_dup 2))))
7838               (set (reg:SI T_REG)
7839                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7840                           (const_int 0)))])]
7841   "TARGET_SH1"
7842   "operands[2] = gen_reg_rtx (SImode);")
7843
7844 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7845 ;; This prevents a regression that occurred when we switched from xor to
7846 ;; mov/neg for sne.
7847
7848 (define_split
7849   [(set (match_operand:SI 0 "arith_reg_operand" "")
7850         (plus:SI (reg:SI T_REG)
7851                  (const_int -1)))]
7852   "TARGET_SH1"
7853   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7854    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7855   "")
7856
7857 ;; -------------------------------------------------------------------------
7858 ;; Instructions to cope with inline literal tables
7859 ;; -------------------------------------------------------------------------
7860
7861 ; 2 byte integer in line
7862
7863 (define_insn "consttable_2"
7864  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7865                     (match_operand 1 "" "")]
7866                    UNSPECV_CONST2)]
7867  ""
7868  "*
7869 {
7870   if (operands[1] != const0_rtx)
7871     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7872   return \"\";
7873 }"
7874  [(set_attr "length" "2")
7875  (set_attr "in_delay_slot" "no")])
7876
7877 ; 4 byte integer in line
7878
7879 (define_insn "consttable_4"
7880  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7881                     (match_operand 1 "" "")]
7882                    UNSPECV_CONST4)]
7883  ""
7884  "*
7885 {
7886   if (operands[1] != const0_rtx)
7887     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7888   return \"\";
7889 }"
7890  [(set_attr "length" "4")
7891   (set_attr "in_delay_slot" "no")])
7892
7893 ; 8 byte integer in line
7894
7895 (define_insn "consttable_8"
7896  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7897                     (match_operand 1 "" "")]
7898                    UNSPECV_CONST8)]
7899  ""
7900  "*
7901 {
7902   if (operands[1] != const0_rtx)
7903     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7904   return \"\";
7905 }"
7906  [(set_attr "length" "8")
7907   (set_attr "in_delay_slot" "no")])
7908
7909 ; 4 byte floating point
7910
7911 (define_insn "consttable_sf"
7912  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7913                     (match_operand 1 "" "")]
7914                    UNSPECV_CONST4)]
7915  ""
7916  "*
7917 {
7918   if (operands[1] != const0_rtx)
7919     {
7920       REAL_VALUE_TYPE d;
7921       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7922       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7923     }
7924   return \"\";
7925 }"
7926  [(set_attr "length" "4")
7927   (set_attr "in_delay_slot" "no")])
7928
7929 ; 8 byte floating point
7930
7931 (define_insn "consttable_df"
7932  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7933                     (match_operand 1 "" "")]
7934                    UNSPECV_CONST8)]
7935  ""
7936  "*
7937 {
7938   if (operands[1] != const0_rtx)
7939     {
7940       REAL_VALUE_TYPE d;
7941       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7942       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7943     }
7944   return \"\";
7945 }"
7946  [(set_attr "length" "8")
7947   (set_attr "in_delay_slot" "no")])
7948
7949 ;; Alignment is needed for some constant tables; it may also be added for
7950 ;; Instructions at the start of loops, or after unconditional branches.
7951 ;; ??? We would get more accurate lengths if we did instruction
7952 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7953 ;; here is too conservative.
7954
7955 ; align to a two byte boundary
7956
7957 (define_expand "align_2"
7958  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7959  ""
7960  "")
7961
7962 ; align to a four byte boundary
7963 ;; align_4 and align_log are instructions for the starts of loops, or
7964 ;; after unconditional branches, which may take up extra room.
7965
7966 (define_expand "align_4"
7967  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7968  ""
7969  "")
7970
7971 ; align to a cache line boundary
7972
7973 (define_insn "align_log"
7974  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7975  ""
7976  ""
7977  [(set_attr "length" "0")
7978   (set_attr "in_delay_slot" "no")])
7979
7980 ; emitted at the end of the literal table, used to emit the
7981 ; 32bit branch labels if needed.
7982
7983 (define_insn "consttable_end"
7984   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7985   ""
7986   "* return output_jump_label_table ();"
7987   [(set_attr "in_delay_slot" "no")])
7988
7989 ; emitted at the end of the window in the literal table.
7990
7991 (define_insn "consttable_window_end"
7992   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7993   ""
7994   ""
7995   [(set_attr "length" "0")
7996    (set_attr "in_delay_slot" "no")])
7997
7998 ;; -------------------------------------------------------------------------
7999 ;; Misc
8000 ;; -------------------------------------------------------------------------
8001
8002 ;; String/block move insn.
8003
8004 (define_expand "movstrsi"
8005   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8006                    (mem:BLK (match_operand:BLK 1 "" "")))
8007               (use (match_operand:SI 2 "nonmemory_operand" ""))
8008               (use (match_operand:SI 3 "immediate_operand" ""))
8009               (clobber (reg:SI PR_REG))
8010               (clobber (reg:SI R4_REG))
8011               (clobber (reg:SI R5_REG))
8012               (clobber (reg:SI R0_REG))])]
8013   "TARGET_SH1 && ! TARGET_SH5"
8014   "
8015 {
8016   if(expand_block_move (operands))
8017      DONE;
8018   else FAIL;
8019 }")
8020
8021 (define_insn "block_move_real"
8022   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8023                    (mem:BLK (reg:SI R5_REG)))
8024               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8025               (clobber (reg:SI PR_REG))
8026               (clobber (reg:SI R0_REG))])]
8027   "TARGET_SH1 && ! TARGET_HARD_SH4"
8028   "jsr  @%0%#"
8029   [(set_attr "type" "sfunc")
8030    (set_attr "needs_delay_slot" "yes")])
8031
8032 (define_insn "block_lump_real"
8033   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8034                    (mem:BLK (reg:SI R5_REG)))
8035               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8036               (use (reg:SI R6_REG))
8037               (clobber (reg:SI PR_REG))
8038               (clobber (reg:SI T_REG))
8039               (clobber (reg:SI R4_REG))
8040               (clobber (reg:SI R5_REG))
8041               (clobber (reg:SI R6_REG))
8042               (clobber (reg:SI R0_REG))])]
8043   "TARGET_SH1 && ! TARGET_HARD_SH4"
8044   "jsr  @%0%#"
8045   [(set_attr "type" "sfunc")
8046    (set_attr "needs_delay_slot" "yes")])
8047
8048 (define_insn "block_move_real_i4"
8049   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8050                    (mem:BLK (reg:SI R5_REG)))
8051               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8052               (clobber (reg:SI PR_REG))
8053               (clobber (reg:SI R0_REG))
8054               (clobber (reg:SI R1_REG))
8055               (clobber (reg:SI R2_REG))])]
8056   "TARGET_HARD_SH4"
8057   "jsr  @%0%#"
8058   [(set_attr "type" "sfunc")
8059    (set_attr "needs_delay_slot" "yes")])
8060
8061 (define_insn "block_lump_real_i4"
8062   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8063                    (mem:BLK (reg:SI R5_REG)))
8064               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8065               (use (reg:SI R6_REG))
8066               (clobber (reg:SI PR_REG))
8067               (clobber (reg:SI T_REG))
8068               (clobber (reg:SI R4_REG))
8069               (clobber (reg:SI R5_REG))
8070               (clobber (reg:SI R6_REG))
8071               (clobber (reg:SI R0_REG))
8072               (clobber (reg:SI R1_REG))
8073               (clobber (reg:SI R2_REG))
8074               (clobber (reg:SI R3_REG))])]
8075   "TARGET_HARD_SH4"
8076   "jsr  @%0%#"
8077   [(set_attr "type" "sfunc")
8078    (set_attr "needs_delay_slot" "yes")])
8079 \f
8080 ;; -------------------------------------------------------------------------
8081 ;; Floating point instructions.
8082 ;; -------------------------------------------------------------------------
8083
8084 ;; ??? All patterns should have a type attribute.
8085
8086 (define_expand "fpu_switch0"
8087   [(set (match_operand:SI 0 "" "") (match_dup 2))
8088    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8089   "TARGET_SH4"
8090   "
8091 {
8092   operands[1] = get_fpscr_rtx ();
8093   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8094   if (flag_pic)
8095     operands[2] = legitimize_pic_address (operands[2], SImode,
8096                                           no_new_pseudos ? operands[0] : 0);
8097 }")
8098
8099 (define_expand "fpu_switch1"
8100   [(set (match_operand:SI 0 "" "") (match_dup 2))
8101    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8102    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8103   "TARGET_SH4"
8104   "
8105 {
8106   operands[1] = get_fpscr_rtx ();
8107   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8108   if (flag_pic)
8109     operands[2] = legitimize_pic_address (operands[2], SImode,
8110                                           no_new_pseudos ? operands[0] : 0);
8111   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8112 }")
8113
8114 (define_expand "movpsi"
8115   [(set (match_operand:PSI 0 "register_operand" "")
8116         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8117   "TARGET_SH4"
8118   "")
8119
8120 ;; The c / m alternative is a fake to guide reload to load directly into
8121 ;; fpscr, since reload doesn't know how to use post-increment.
8122 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8123 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8124 ;; predicate after reload.
8125 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8126 ;; like a mac -> gpr move.
8127 (define_insn "fpu_switch"
8128   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8129         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8130   "TARGET_SH2E
8131    && (! reload_completed
8132        || true_regnum (operands[0]) != FPSCR_REG
8133        || GET_CODE (operands[1]) != MEM
8134        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8135   "@
8136         ! precision stays the same
8137         lds.l   %1,fpscr
8138         mov.l   %1,%0
8139         #
8140         lds     %1,fpscr
8141         mov     %1,%0
8142         mov.l   %1,%0
8143         sts     fpscr,%0
8144         sts.l   fpscr,%0"
8145   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8146    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8147
8148 (define_split
8149   [(set (reg:PSI FPSCR_REG)
8150         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8151   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8152   [(set (match_dup 0) (match_dup 0))]
8153   "
8154 {
8155   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8156                                         gen_rtx (MEM, PSImode,
8157                                                  gen_rtx (POST_INC, Pmode,
8158                                                           operands[0]))));
8159   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8160 }")
8161
8162 (define_split
8163   [(set (reg:PSI FPSCR_REG)
8164         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8165   "TARGET_SH4"
8166   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8167   "
8168 {
8169   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8170                                         gen_rtx (MEM, PSImode,
8171                                                  gen_rtx (POST_INC, Pmode,
8172                                                           operands[0]))));
8173   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8174 }")
8175
8176 ;; ??? This uses the fp unit, but has no type indicating that.
8177 ;; If we did that, this would either give a bogus latency or introduce
8178 ;; a bogus FIFO constraint.
8179 ;; Since this insn is currently only used for prologues/epilogues,
8180 ;; it is probably best to claim no function unit, which matches the
8181 ;; current setting.
8182 (define_insn "toggle_sz"
8183   [(set (reg:PSI FPSCR_REG)
8184         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8185   "TARGET_SH4"
8186   "fschg"
8187   [(set_attr "fp_set" "unknown")])
8188
8189 (define_expand "addsf3"
8190   [(set (match_operand:SF 0 "arith_reg_operand" "")
8191         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8192                  (match_operand:SF 2 "arith_reg_operand" "")))]
8193   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8194   "
8195 {
8196   if (TARGET_SH2E)
8197     {
8198       expand_sf_binop (&gen_addsf3_i, operands);
8199       DONE;
8200     }
8201 }")
8202
8203 (define_insn "*addsf3_media"
8204   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8205         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8206                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8207   "TARGET_SHMEDIA_FPU"
8208   "fadd.s       %1, %2, %0"
8209   [(set_attr "type" "fparith_media")])
8210
8211 (define_insn_and_split "unary_sf_op"
8212   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8213         (vec_select:V2SF
8214          (vec_concat:V2SF
8215           (vec_select:SF
8216            (match_dup 0)
8217            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8218           (match_operator:SF 2 "unary_float_operator"
8219             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8220                             (parallel [(match_operand 4
8221                                         "const_int_operand" "n")]))]))
8222          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8223   "TARGET_SHMEDIA_FPU"
8224   "#"
8225   "TARGET_SHMEDIA_FPU && reload_completed"
8226   [(set (match_dup 5) (match_dup 6))]
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[4]) ^ endian)));
8233
8234   operands[7] = gen_rtx_REG (SFmode,
8235                              (true_regnum (operands[0])
8236                               + (INTVAL (operands[3]) ^ endian)));
8237   operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8238 }"
8239   [(set_attr "type" "fparith_media")])
8240
8241 (define_insn_and_split "binary_sf_op"
8242   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8243         (vec_select:V2SF
8244          (vec_concat:V2SF
8245           (vec_select:SF
8246            (match_dup 0)
8247            (parallel [(match_operand 7 "const_int_operand" "n")]))
8248           (match_operator:SF 3 "binary_float_operator"
8249             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8250                             (parallel [(match_operand 5
8251                                         "const_int_operand" "n")]))
8252              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8253                             (parallel [(match_operand 6
8254                                         "const_int_operand" "n")]))]))
8255          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8256   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8257   "#"
8258   "&& reload_completed"
8259   [(set (match_dup 8) (match_dup 9))]
8260   "
8261 {
8262   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8263   rtx op1 = gen_rtx_REG (SFmode,
8264                          (true_regnum (operands[1])
8265                           + (INTVAL (operands[5]) ^ endian)));
8266   rtx op2 = gen_rtx_REG (SFmode,
8267                          (true_regnum (operands[2])
8268                           + (INTVAL (operands[6]) ^ endian)));
8269
8270   operands[8] = gen_rtx_REG (SFmode,
8271                              (true_regnum (operands[0])
8272                               + (INTVAL (operands[4]) ^ endian)));
8273   operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8274 }"
8275   [(set_attr "type" "fparith_media")])
8276
8277 (define_insn "addsf3_i"
8278   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8279         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8280                  (match_operand:SF 2 "arith_reg_operand" "f")))
8281    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8282   "TARGET_SH2E"
8283   "fadd %2,%0"
8284   [(set_attr "type" "fp")
8285    (set_attr "fp_mode" "single")])
8286
8287 (define_expand "subsf3"
8288   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8289         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8290                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8291   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8292   "
8293 {
8294   if (TARGET_SH2E)
8295     {
8296       expand_sf_binop (&gen_subsf3_i, operands);
8297       DONE;
8298     }
8299 }")
8300
8301 (define_insn "*subsf3_media"
8302   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8303         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8304                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8305   "TARGET_SHMEDIA_FPU"
8306   "fsub.s       %1, %2, %0"
8307   [(set_attr "type" "fparith_media")])
8308
8309 (define_insn "subsf3_i"
8310   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8311         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8312                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8313    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8314   "TARGET_SH2E"
8315   "fsub %2,%0"
8316   [(set_attr "type" "fp")
8317    (set_attr "fp_mode" "single")])
8318
8319 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8320 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8321 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8322 ;; SH3E, we use a separate insn for SH3E mulsf3.
8323
8324 (define_expand "mulsf3"
8325   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8326         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8327                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8328   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8329   "
8330 {
8331   if (TARGET_SH4)
8332     expand_sf_binop (&gen_mulsf3_i4, operands);
8333   else if (TARGET_SH2E)
8334     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8335   if (! TARGET_SHMEDIA)
8336     DONE;
8337 }")
8338
8339 (define_insn "*mulsf3_media"
8340   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8341         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8342                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8343   "TARGET_SHMEDIA_FPU"
8344   "fmul.s       %1, %2, %0"
8345   [(set_attr "type" "fparith_media")])
8346
8347 (define_insn "mulsf3_i4"
8348   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8349         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8350                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8351    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8352   "TARGET_SH2E"
8353   "fmul %2,%0"
8354   [(set_attr "type" "fp")
8355    (set_attr "fp_mode" "single")])
8356
8357 (define_insn "mulsf3_ie"
8358   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8359         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8360                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8361   "TARGET_SH2E && ! TARGET_SH4"
8362   "fmul %2,%0"
8363   [(set_attr "type" "fp")])
8364
8365 (define_insn "*mac_media"
8366   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8367         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8368                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8369                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8370   "TARGET_SHMEDIA_FPU"
8371   "fmac.s %1, %2, %0"
8372   [(set_attr "type" "fparith_media")])
8373
8374 (define_insn "*macsf3"
8375   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8376         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8377                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8378                  (match_operand:SF 3 "arith_reg_operand" "0")))
8379    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8380   "TARGET_SH2E && ! TARGET_SH4"
8381   "fmac fr0,%2,%0"
8382   [(set_attr "type" "fp")
8383    (set_attr "fp_mode" "single")])
8384
8385 (define_expand "divsf3"
8386   [(set (match_operand:SF 0 "arith_reg_operand" "")
8387         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8388                 (match_operand:SF 2 "arith_reg_operand" "")))]
8389   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8390   "
8391 {
8392   if (TARGET_SH2E)
8393     {
8394       expand_sf_binop (&gen_divsf3_i, operands);
8395       DONE;
8396     }
8397 }")
8398
8399 (define_insn "*divsf3_media"
8400   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8401         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8402                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8403   "TARGET_SHMEDIA_FPU"
8404   "fdiv.s       %1, %2, %0"
8405   [(set_attr "type" "fdiv_media")])
8406
8407 (define_insn "divsf3_i"
8408   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8409         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8410                  (match_operand:SF 2 "arith_reg_operand" "f")))
8411    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8412   "TARGET_SH2E"
8413   "fdiv %2,%0"
8414   [(set_attr "type" "fdiv")
8415    (set_attr "fp_mode" "single")])
8416
8417 (define_insn "floatdisf2"
8418   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8419         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8420   "TARGET_SHMEDIA_FPU"
8421   "float.qs %1, %0"
8422   [(set_attr "type" "fpconv_media")])
8423
8424 (define_expand "floatsisf2"
8425   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8426         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8427   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8428   "
8429 {
8430   if (TARGET_SH4)
8431     {
8432       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8433       DONE;
8434     }
8435 }")
8436
8437 (define_insn "*floatsisf2_media"
8438   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8439         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8440   "TARGET_SHMEDIA_FPU"
8441   "float.ls     %1, %0"
8442   [(set_attr "type" "fpconv_media")])
8443
8444 (define_insn "floatsisf2_i4"
8445   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8446         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8447    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8448   "TARGET_SH4"
8449   "float        %1,%0"
8450   [(set_attr "type" "fp")
8451    (set_attr "fp_mode" "single")])
8452
8453 (define_insn "*floatsisf2_ie"
8454   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8455         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8456   "TARGET_SH2E && ! TARGET_SH4"
8457   "float        %1,%0"
8458   [(set_attr "type" "fp")])
8459
8460 (define_insn "fix_truncsfdi2"
8461   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8462         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8463   "TARGET_SHMEDIA_FPU"
8464   "ftrc.sq %1, %0"
8465   [(set_attr "type" "fpconv_media")])
8466
8467 (define_expand "fix_truncsfsi2"
8468   [(set (match_operand:SI 0 "fpul_operand" "=y")
8469         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8470   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8471   "
8472 {
8473   if (TARGET_SH4)
8474     {
8475       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8476       DONE;
8477     }
8478 }")
8479
8480 (define_insn "*fix_truncsfsi2_media"
8481   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8482         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8483   "TARGET_SHMEDIA_FPU"
8484   "ftrc.sl      %1, %0"
8485   [(set_attr "type" "fpconv_media")])
8486
8487 (define_insn "fix_truncsfsi2_i4"
8488   [(set (match_operand:SI 0 "fpul_operand" "=y")
8489         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8490    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8491   "TARGET_SH4"
8492   "ftrc %1,%0"
8493   [(set_attr "type" "ftrc_s")
8494    (set_attr "fp_mode" "single")])
8495
8496 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8497 ;; fix_truncsfsi2_i4.
8498 ;; (define_insn "fix_truncsfsi2_i4_2"
8499 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8500 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8501 ;;   (use (reg:PSI FPSCR_REG))
8502 ;;   (clobber (reg:SI FPUL_REG))]
8503 ;;  "TARGET_SH4"
8504 ;;  "#"
8505 ;;  [(set_attr "length" "4")
8506 ;;   (set_attr "fp_mode" "single")])
8507
8508 ;;(define_split
8509 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8510 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8511 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8512 ;;   (clobber (reg:SI FPUL_REG))]
8513 ;;  "TARGET_SH4"
8514 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8515 ;;            (use (match_dup 2))])
8516 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8517
8518 (define_insn "*fixsfsi"
8519   [(set (match_operand:SI 0 "fpul_operand" "=y")
8520         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8521   "TARGET_SH2E && ! TARGET_SH4"
8522   "ftrc %1,%0"
8523   [(set_attr "type" "fp")])
8524
8525 (define_insn "cmpgtsf_t"
8526   [(set (reg:SI T_REG)
8527         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8528                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8529   "TARGET_SH2E && ! TARGET_SH4"
8530   "fcmp/gt      %1,%0"
8531   [(set_attr "type" "fp")
8532    (set_attr "fp_mode" "single")])
8533
8534 (define_insn "cmpeqsf_t"
8535   [(set (reg:SI T_REG)
8536         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8537                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8538   "TARGET_SH2E && ! TARGET_SH4"
8539   "fcmp/eq      %1,%0"
8540   [(set_attr "type" "fp")
8541    (set_attr "fp_mode" "single")])
8542
8543 (define_insn "ieee_ccmpeqsf_t"
8544   [(set (reg:SI T_REG)
8545         (ior:SI (reg:SI T_REG)
8546                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8547                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8548   "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8549   "* return output_ieee_ccmpeq (insn, operands);"
8550   [(set_attr "length" "4")])
8551
8552
8553 (define_insn "cmpgtsf_t_i4"
8554   [(set (reg:SI T_REG)
8555         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8556                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8557    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8558   "TARGET_SH4"
8559   "fcmp/gt      %1,%0"
8560   [(set_attr "type" "fp")
8561    (set_attr "fp_mode" "single")])
8562
8563 (define_insn "cmpeqsf_t_i4"
8564   [(set (reg:SI T_REG)
8565         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8566                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8567    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8568   "TARGET_SH4"
8569   "fcmp/eq      %1,%0"
8570   [(set_attr "type" "fp")
8571    (set_attr "fp_mode" "single")])
8572
8573 (define_insn "*ieee_ccmpeqsf_t_4"
8574   [(set (reg:SI T_REG)
8575         (ior:SI (reg:SI T_REG)
8576                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8577                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8578    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8579   "TARGET_IEEE && TARGET_SH4"
8580   "* return output_ieee_ccmpeq (insn, operands);"
8581   [(set_attr "length" "4")
8582    (set_attr "fp_mode" "single")])
8583
8584 (define_insn "cmpeqsf_media"
8585   [(set (match_operand:DI 0 "register_operand" "=r")
8586         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8587                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8588   "TARGET_SHMEDIA_FPU"
8589   "fcmpeq.s     %1, %2, %0"
8590   [(set_attr "type" "fcmp_media")])
8591
8592 (define_insn "cmpgtsf_media"
8593   [(set (match_operand:DI 0 "register_operand" "=r")
8594         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8595                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8596   "TARGET_SHMEDIA_FPU"
8597   "fcmpgt.s     %1, %2, %0"
8598   [(set_attr "type" "fcmp_media")])
8599
8600 (define_insn "cmpgesf_media"
8601   [(set (match_operand:DI 0 "register_operand" "=r")
8602         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8603                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8604   "TARGET_SHMEDIA_FPU"
8605   "fcmpge.s     %1, %2, %0"
8606   [(set_attr "type" "fcmp_media")])
8607
8608 (define_insn "cmpunsf_media"
8609   [(set (match_operand:DI 0 "register_operand" "=r")
8610         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8611                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8612   "TARGET_SHMEDIA_FPU"
8613   "fcmpun.s     %1, %2, %0"
8614   [(set_attr "type" "fcmp_media")])
8615
8616 (define_expand "cmpsf"
8617   [(set (reg:SI T_REG)
8618         (compare (match_operand:SF 0 "arith_operand" "")
8619                  (match_operand:SF 1 "arith_operand" "")))]
8620   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8621   "
8622 {
8623   sh_compare_op0 = operands[0];
8624   sh_compare_op1 = operands[1];
8625   DONE;
8626 }")
8627
8628 (define_expand "negsf2"
8629   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8630         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8631   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8632   "
8633 {
8634   if (TARGET_SH2E)
8635     {
8636       expand_sf_unop (&gen_negsf2_i, operands);
8637       DONE;
8638     }
8639 }")
8640
8641 (define_insn "*negsf2_media"
8642   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8643         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8644   "TARGET_SHMEDIA_FPU"
8645   "fneg.s       %1, %0"
8646   [(set_attr "type" "fmove_media")])
8647
8648 (define_insn "negsf2_i"
8649   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8650         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8651    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8652   "TARGET_SH2E"
8653   "fneg %0"
8654   [(set_attr "type" "fmove")
8655    (set_attr "fp_mode" "single")])
8656
8657 (define_expand "sqrtsf2"
8658   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8659         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8660   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8661   "
8662 {
8663   if (TARGET_SH3E)
8664     {
8665       expand_sf_unop (&gen_sqrtsf2_i, operands);
8666       DONE;
8667     }
8668 }")
8669
8670 (define_insn "*sqrtsf2_media"
8671   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8672         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8673   "TARGET_SHMEDIA_FPU"
8674   "fsqrt.s      %1, %0"
8675   [(set_attr "type" "fdiv_media")])
8676
8677 (define_insn "sqrtsf2_i"
8678   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8679         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8680    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8681   "TARGET_SH3E"
8682   "fsqrt        %0"
8683   [(set_attr "type" "fdiv")
8684    (set_attr "fp_mode" "single")])
8685
8686 (define_expand "abssf2"
8687   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8688         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8689   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8690   "
8691 {
8692   if (TARGET_SH2E)
8693     {
8694       expand_sf_unop (&gen_abssf2_i, operands);
8695       DONE;
8696     }
8697 }")
8698
8699 (define_insn "*abssf2_media"
8700   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8701         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8702   "TARGET_SHMEDIA_FPU"
8703   "fabs.s       %1, %0"
8704   [(set_attr "type" "fmove_media")])
8705
8706 (define_insn "abssf2_i"
8707   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8708         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8709    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8710   "TARGET_SH2E"
8711   "fabs %0"
8712   [(set_attr "type" "fmove")
8713    (set_attr "fp_mode" "single")])
8714
8715 (define_expand "adddf3"
8716   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8717         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8718                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8719   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8720   "
8721 {
8722   if (TARGET_SH4)
8723     {
8724       expand_df_binop (&gen_adddf3_i, operands);
8725       DONE;
8726     }
8727 }")
8728
8729 (define_insn "*adddf3_media"
8730   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8731         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8732                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8733   "TARGET_SHMEDIA_FPU"
8734   "fadd.d       %1, %2, %0"
8735   [(set_attr "type" "dfparith_media")])
8736
8737 (define_insn "adddf3_i"
8738   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8739         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8740                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8741    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8742   "TARGET_SH4"
8743   "fadd %2,%0"
8744   [(set_attr "type" "dfp_arith")
8745    (set_attr "fp_mode" "double")])
8746
8747 (define_expand "subdf3"
8748   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8749         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8750                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8751   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8752   "
8753 {
8754   if (TARGET_SH4)
8755     {
8756       expand_df_binop (&gen_subdf3_i, operands);
8757       DONE;
8758     }
8759 }")
8760
8761 (define_insn "*subdf3_media"
8762   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8763         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8764                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8765   "TARGET_SHMEDIA_FPU"
8766   "fsub.d       %1, %2, %0"
8767   [(set_attr "type" "dfparith_media")])
8768
8769 (define_insn "subdf3_i"
8770   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8771         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8772                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8773    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8774   "TARGET_SH4"
8775   "fsub %2,%0"
8776   [(set_attr "type" "dfp_arith")
8777    (set_attr "fp_mode" "double")])
8778
8779 (define_expand "muldf3"
8780   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8781         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8782                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8783   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8784   "
8785 {
8786   if (TARGET_SH4)
8787     {
8788       expand_df_binop (&gen_muldf3_i, operands);
8789       DONE;
8790     }
8791 }")
8792
8793 (define_insn "*muldf3_media"
8794   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8795         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8796                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8797   "TARGET_SHMEDIA_FPU"
8798   "fmul.d       %1, %2, %0"
8799   [(set_attr "type" "dfmul_media")])
8800
8801 (define_insn "muldf3_i"
8802   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8803         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8804                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8805    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8806   "TARGET_SH4"
8807   "fmul %2,%0"
8808   [(set_attr "type" "dfp_arith")
8809    (set_attr "fp_mode" "double")])
8810
8811 (define_expand "divdf3"
8812   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8813         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8814                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8815   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8816   "
8817 {
8818   if (TARGET_SH4)
8819     {
8820       expand_df_binop (&gen_divdf3_i, operands);
8821       DONE;
8822     }
8823 }")
8824
8825 (define_insn "*divdf3_media"
8826   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8827         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8828                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8829   "TARGET_SHMEDIA_FPU"
8830   "fdiv.d       %1, %2, %0"
8831   [(set_attr "type" "dfdiv_media")])
8832
8833 (define_insn "divdf3_i"
8834   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8835         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8836                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8837    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8838   "TARGET_SH4"
8839   "fdiv %2,%0"
8840   [(set_attr "type" "dfdiv")
8841    (set_attr "fp_mode" "double")])
8842
8843 (define_insn "floatdidf2"
8844   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8845         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8846   "TARGET_SHMEDIA_FPU"
8847   "float.qd     %1, %0"
8848   [(set_attr "type" "dfpconv_media")])
8849
8850 (define_expand "floatsidf2"
8851   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8852         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8853   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8854   "
8855 {
8856   if (TARGET_SH4)
8857     {
8858       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8859                                       get_fpscr_rtx ()));
8860       DONE;
8861     }
8862 }")
8863
8864 (define_insn "*floatsidf2_media"
8865   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8866         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8867   "TARGET_SHMEDIA_FPU"
8868   "float.ld     %1, %0"
8869   [(set_attr "type" "dfpconv_media")])
8870
8871 (define_insn "floatsidf2_i"
8872   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8873         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8874    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8875   "TARGET_SH4"
8876   "float        %1,%0"
8877   [(set_attr "type" "dfp_conv")
8878    (set_attr "fp_mode" "double")])
8879
8880 (define_insn "fix_truncdfdi2"
8881   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8882         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8883   "TARGET_SHMEDIA_FPU"
8884   "ftrc.dq      %1, %0"
8885   [(set_attr "type" "dfpconv_media")])
8886
8887 (define_expand "fix_truncdfsi2"
8888   [(set (match_operand:SI 0 "fpul_operand" "")
8889         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8890   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8891   "
8892 {
8893   if (TARGET_SH4)
8894     {
8895       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8896                                           get_fpscr_rtx ()));
8897       DONE;
8898     }
8899 }")
8900
8901 (define_insn "*fix_truncdfsi2_media"
8902   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8903         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8904   "TARGET_SHMEDIA_FPU"
8905   "ftrc.dl      %1, %0"
8906   [(set_attr "type" "dfpconv_media")])
8907
8908 (define_insn "fix_truncdfsi2_i"
8909   [(set (match_operand:SI 0 "fpul_operand" "=y")
8910         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8911    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8912   "TARGET_SH4"
8913   "ftrc %1,%0"
8914   [(set_attr "type" "dfp_conv")
8915    (set_attr "dfp_comp" "no")
8916    (set_attr "fp_mode" "double")])
8917
8918 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8919 ;; fix_truncdfsi2_i.
8920 ;; (define_insn "fix_truncdfsi2_i4"
8921 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8922 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8923 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8924 ;;    (clobber (reg:SI FPUL_REG))]
8925 ;;   "TARGET_SH4"
8926 ;;   "#"
8927 ;;   [(set_attr "length" "4")
8928 ;;    (set_attr "fp_mode" "double")])
8929 ;;
8930 ;; (define_split
8931 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8932 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8933 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8934 ;;    (clobber (reg:SI FPUL_REG))]
8935 ;;   "TARGET_SH4"
8936 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8937 ;;            (use (match_dup 2))])
8938 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
8939
8940 (define_insn "cmpgtdf_t"
8941   [(set (reg:SI T_REG)
8942         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8943                (match_operand:DF 1 "arith_reg_operand" "f")))
8944    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8945   "TARGET_SH4"
8946   "fcmp/gt      %1,%0"
8947   [(set_attr "type" "dfp_cmp")
8948    (set_attr "fp_mode" "double")])
8949
8950 (define_insn "cmpeqdf_t"
8951   [(set (reg:SI T_REG)
8952         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8953                (match_operand:DF 1 "arith_reg_operand" "f")))
8954    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8955   "TARGET_SH4"
8956   "fcmp/eq      %1,%0"
8957   [(set_attr "type" "dfp_cmp")
8958    (set_attr "fp_mode" "double")])
8959
8960 (define_insn "*ieee_ccmpeqdf_t"
8961   [(set (reg:SI T_REG)
8962         (ior:SI (reg:SI T_REG)
8963                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8964                        (match_operand:DF 1 "arith_reg_operand" "f"))))
8965    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8966   "TARGET_IEEE && TARGET_SH4"
8967   "* return output_ieee_ccmpeq (insn, operands);"
8968   [(set_attr "length" "4")
8969    (set_attr "fp_mode" "double")])
8970
8971 (define_insn "cmpeqdf_media"
8972   [(set (match_operand:DI 0 "register_operand" "=r")
8973         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8974                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8975   "TARGET_SHMEDIA_FPU"
8976   "fcmpeq.d     %1,%2,%0"
8977   [(set_attr "type" "fcmp_media")])
8978
8979 (define_insn "cmpgtdf_media"
8980   [(set (match_operand:DI 0 "register_operand" "=r")
8981         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8982                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8983   "TARGET_SHMEDIA_FPU"
8984   "fcmpgt.d     %1,%2,%0"
8985   [(set_attr "type" "fcmp_media")])
8986
8987 (define_insn "cmpgedf_media"
8988   [(set (match_operand:DI 0 "register_operand" "=r")
8989         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8990                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8991   "TARGET_SHMEDIA_FPU"
8992   "fcmpge.d     %1,%2,%0"
8993   [(set_attr "type" "fcmp_media")])
8994
8995 (define_insn "cmpundf_media"
8996   [(set (match_operand:DI 0 "register_operand" "=r")
8997         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8998                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8999   "TARGET_SHMEDIA_FPU"
9000   "fcmpun.d     %1,%2,%0"
9001   [(set_attr "type" "fcmp_media")])
9002
9003 (define_expand "cmpdf"
9004   [(set (reg:SI T_REG)
9005         (compare (match_operand:DF 0 "arith_operand" "")
9006                  (match_operand:DF 1 "arith_operand" "")))]
9007   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9008   "
9009 {
9010   sh_compare_op0 = operands[0];
9011   sh_compare_op1 = operands[1];
9012   DONE;
9013 }")
9014
9015 (define_expand "negdf2"
9016   [(set (match_operand:DF 0 "arith_reg_operand" "")
9017         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9018   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9019   "
9020 {
9021   if (TARGET_SH4)
9022     {
9023       expand_df_unop (&gen_negdf2_i, operands);
9024       DONE;
9025     }
9026 }")
9027
9028 (define_insn "*negdf2_media"
9029   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9030         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9031   "TARGET_SHMEDIA_FPU"
9032   "fneg.d       %1, %0"
9033   [(set_attr "type" "fmove_media")])
9034
9035 (define_insn "negdf2_i"
9036   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9037         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9038    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9039   "TARGET_SH4"
9040   "fneg %0"
9041   [(set_attr "type" "fmove")
9042    (set_attr "fp_mode" "double")])
9043
9044 (define_expand "sqrtdf2"
9045   [(set (match_operand:DF 0 "arith_reg_operand" "")
9046         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9047   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9048   "
9049 {
9050   if (TARGET_SH4)
9051     {
9052       expand_df_unop (&gen_sqrtdf2_i, operands);
9053       DONE;
9054     }
9055 }")
9056
9057 (define_insn "*sqrtdf2_media"
9058   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9059         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9060   "TARGET_SHMEDIA_FPU"
9061   "fsqrt.d      %1, %0"
9062   [(set_attr "type" "dfdiv_media")])
9063
9064 (define_insn "sqrtdf2_i"
9065   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9066         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9067    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9068   "TARGET_SH4"
9069   "fsqrt        %0"
9070   [(set_attr "type" "dfdiv")
9071    (set_attr "fp_mode" "double")])
9072
9073 (define_expand "absdf2"
9074   [(set (match_operand:DF 0 "arith_reg_operand" "")
9075         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9076   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9077   "
9078 {
9079   if (TARGET_SH4)
9080     {
9081       expand_df_unop (&gen_absdf2_i, operands);
9082       DONE;
9083     }
9084 }")
9085
9086 (define_insn "*absdf2_media"
9087   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9088         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9089   "TARGET_SHMEDIA_FPU"
9090   "fabs.d       %1, %0"
9091   [(set_attr "type" "fmove_media")])
9092
9093 (define_insn "absdf2_i"
9094   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9095         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9096    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9097   "TARGET_SH4"
9098   "fabs %0"
9099   [(set_attr "type" "fmove")
9100    (set_attr "fp_mode" "double")])
9101
9102 (define_expand "extendsfdf2"
9103   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9104         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9105   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9106   "
9107 {
9108   if (TARGET_SH4)
9109     {
9110       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9111                                         get_fpscr_rtx ()));
9112       DONE;
9113     }
9114 }")
9115
9116 (define_insn "*extendsfdf2_media"
9117   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9118         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9119   "TARGET_SHMEDIA_FPU"
9120   "fcnv.sd      %1, %0"
9121   [(set_attr "type" "dfpconv_media")])
9122
9123 (define_insn "extendsfdf2_i4"
9124   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9125         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9126    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9127   "TARGET_SH4"
9128   "fcnvsd  %1,%0"
9129   [(set_attr "type" "fp")
9130    (set_attr "fp_mode" "double")])
9131
9132 (define_expand "truncdfsf2"
9133   [(set (match_operand:SF 0 "fpul_operand" "")
9134         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9135   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9136   "
9137 {
9138   if (TARGET_SH4)
9139     {
9140       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9141                                        get_fpscr_rtx ()));
9142       DONE;
9143     }
9144 }")
9145
9146 (define_insn "*truncdfsf2_media"
9147   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9148         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9149   "TARGET_SHMEDIA_FPU"
9150   "fcnv.ds      %1, %0"
9151   [(set_attr "type" "dfpconv_media")])
9152
9153 (define_insn "truncdfsf2_i4"
9154   [(set (match_operand:SF 0 "fpul_operand" "=y")
9155         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9156    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9157   "TARGET_SH4"
9158   "fcnvds  %1,%0"
9159   [(set_attr "type" "fp")
9160    (set_attr "fp_mode" "double")])
9161 \f
9162 ;; Bit field extract patterns.  These give better code for packed bitfields,
9163 ;; because they allow auto-increment addresses to be generated.
9164
9165 (define_expand "insv"
9166   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9167                          (match_operand:SI 1 "immediate_operand" "")
9168                          (match_operand:SI 2 "immediate_operand" ""))
9169         (match_operand:SI 3 "general_operand" ""))]
9170   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9171   "
9172 {
9173   rtx addr_target, orig_address, shift_reg, qi_val;
9174   HOST_WIDE_INT bitsize, size, v;
9175   rtx x = operands[3];
9176
9177   /* ??? expmed doesn't care for non-register predicates.  */
9178   if (! memory_operand (operands[0], VOIDmode)
9179       || ! immediate_operand (operands[1], VOIDmode)
9180       || ! immediate_operand (operands[2], VOIDmode)
9181       || ! general_operand (x, VOIDmode))
9182     FAIL;
9183   /* If this isn't a 16 / 24 / 32 bit field, or if
9184      it doesn't start on a byte boundary, then fail.  */
9185   bitsize = INTVAL (operands[1]);
9186   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9187       || (INTVAL (operands[2]) % 8) != 0)
9188     FAIL;
9189
9190   size = bitsize / 8;
9191   orig_address = XEXP (operands[0], 0);
9192   shift_reg = gen_reg_rtx (SImode);
9193   if (GET_CODE (x) == CONST_INT)
9194     {
9195       v = INTVAL (x);
9196       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9197     }
9198   else
9199     {
9200       emit_insn (gen_movsi (shift_reg, operands[3]));
9201       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9202     }
9203   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9204
9205   operands[0] = replace_equiv_address (operands[0], addr_target);
9206   emit_insn (gen_movqi (operands[0], qi_val));
9207
9208   while (size -= 1)
9209     {
9210       if (GET_CODE (x) == CONST_INT)
9211         qi_val
9212           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9213       else
9214         {
9215           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9216           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9217         }
9218       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9219       emit_insn (gen_movqi (operands[0], qi_val));
9220     }
9221
9222   DONE;
9223 }")
9224 \f
9225 ;; -------------------------------------------------------------------------
9226 ;; Peepholes
9227 ;; -------------------------------------------------------------------------
9228
9229 ;; This matches cases where a stack pointer increment at the start of the
9230 ;; epilogue combines with a stack slot read loading the return value.
9231
9232 (define_peephole
9233   [(set (match_operand:SI 0 "arith_reg_operand" "")
9234         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9235    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9236   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9237   "mov.l        @%1+,%0")
9238
9239 ;; See the comment on the dt combiner pattern above.
9240
9241 (define_peephole
9242   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9243         (plus:SI (match_dup 0)
9244                  (const_int -1)))
9245    (set (reg:SI T_REG)
9246         (eq:SI (match_dup 0)
9247                (const_int 0)))]
9248   "TARGET_SH2"
9249   "dt   %0")
9250
9251 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9252 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9253 ;; reload when the constant is too large for a reg+offset address.
9254
9255 ;; ??? We would get much better code if this was done in reload.  This would
9256 ;; require modifying find_reloads_address to recognize that if the constant
9257 ;; is out-of-range for an immediate add, then we get better code by reloading
9258 ;; the constant into a register than by reloading the sum into a register,
9259 ;; since the former is one instruction shorter if the address does not need
9260 ;; to be offsettable.  Unfortunately this does not work, because there is
9261 ;; only one register, r0, that can be used as an index register.  This register
9262 ;; is also the function return value register.  So, if we try to force reload
9263 ;; to use double-reg addresses, then we end up with some instructions that
9264 ;; need to use r0 twice.  The only way to fix this is to change the calling
9265 ;; convention so that r0 is not used to return values.
9266
9267 (define_peephole
9268   [(set (match_operand:SI 0 "register_operand" "=r")
9269         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9270    (set (mem:SI (match_dup 0))
9271         (match_operand:SI 2 "general_movsrc_operand" ""))]
9272   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9273   "mov.l        %2,@(%0,%1)")
9274
9275 (define_peephole
9276   [(set (match_operand:SI 0 "register_operand" "=r")
9277         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9278    (set (match_operand:SI 2 "general_movdst_operand" "")
9279         (mem:SI (match_dup 0)))]
9280   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9281   "mov.l        @(%0,%1),%2")
9282
9283 (define_peephole
9284   [(set (match_operand:SI 0 "register_operand" "=r")
9285         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9286    (set (mem:HI (match_dup 0))
9287         (match_operand:HI 2 "general_movsrc_operand" ""))]
9288   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9289   "mov.w        %2,@(%0,%1)")
9290
9291 (define_peephole
9292   [(set (match_operand:SI 0 "register_operand" "=r")
9293         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9294    (set (match_operand:HI 2 "general_movdst_operand" "")
9295         (mem:HI (match_dup 0)))]
9296   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9297   "mov.w        @(%0,%1),%2")
9298
9299 (define_peephole
9300   [(set (match_operand:SI 0 "register_operand" "=r")
9301         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9302    (set (mem:QI (match_dup 0))
9303         (match_operand:QI 2 "general_movsrc_operand" ""))]
9304   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9305   "mov.b        %2,@(%0,%1)")
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 (match_operand:QI 2 "general_movdst_operand" "")
9311         (mem:QI (match_dup 0)))]
9312   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9313   "mov.b        @(%0,%1),%2")
9314
9315 (define_peephole
9316   [(set (match_operand:SI 0 "register_operand" "=r")
9317         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9318    (set (mem:SF (match_dup 0))
9319         (match_operand:SF 2 "general_movsrc_operand" ""))]
9320   "TARGET_SH1 && REGNO (operands[0]) == 0
9321    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9322        || (GET_CODE (operands[2]) == SUBREG
9323            && REGNO (SUBREG_REG (operands[2])) < 16))
9324    && reg_unused_after (operands[0], insn)"
9325   "mov.l        %2,@(%0,%1)")
9326
9327 (define_peephole
9328   [(set (match_operand:SI 0 "register_operand" "=r")
9329         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9330    (set (match_operand:SF 2 "general_movdst_operand" "")
9331
9332         (mem:SF (match_dup 0)))]
9333   "TARGET_SH1 && REGNO (operands[0]) == 0
9334    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9335        || (GET_CODE (operands[2]) == SUBREG
9336            && REGNO (SUBREG_REG (operands[2])) < 16))
9337    && reg_unused_after (operands[0], insn)"
9338   "mov.l        @(%0,%1),%2")
9339
9340 (define_peephole
9341   [(set (match_operand:SI 0 "register_operand" "=r")
9342         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9343    (set (mem:SF (match_dup 0))
9344         (match_operand:SF 2 "general_movsrc_operand" ""))]
9345   "TARGET_SH2E && REGNO (operands[0]) == 0
9346    && ((GET_CODE (operands[2]) == REG
9347         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9348        || (GET_CODE (operands[2]) == SUBREG
9349            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9350    && reg_unused_after (operands[0], insn)"
9351   "fmov{.s|}    %2,@(%0,%1)")
9352
9353 (define_peephole
9354   [(set (match_operand:SI 0 "register_operand" "=r")
9355         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9356    (set (match_operand:SF 2 "general_movdst_operand" "")
9357
9358         (mem:SF (match_dup 0)))]
9359   "TARGET_SH2E && REGNO (operands[0]) == 0
9360    && ((GET_CODE (operands[2]) == REG
9361         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9362        || (GET_CODE (operands[2]) == SUBREG
9363            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9364    && reg_unused_after (operands[0], insn)"
9365   "fmov{.s|}    @(%0,%1),%2")
9366
9367 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9368 (define_insn "sp_switch_1"
9369   [(const_int 1)]
9370   "TARGET_SH1"
9371   "*
9372 {
9373   rtx xoperands[1];
9374
9375   xoperands[0] = sp_switch;
9376   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9377   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9378   return \"mov r0,r15\";
9379 }"
9380   [(set_attr "length" "10")])
9381
9382 ;; Switch back to the original stack for interrupt functions with the
9383 ;; sp_switch attribute.  */
9384 (define_insn "sp_switch_2"
9385   [(const_int 2)]
9386   "TARGET_SH1"
9387   "mov.l @r15+,r15\;mov.l @r15+,r0"
9388   [(set_attr "length" "4")])
9389
9390 ;; Integer vector moves
9391
9392 (define_expand "movv8qi"
9393   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9394         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9395   "TARGET_SHMEDIA"
9396   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9397
9398 (define_insn "movv8qi_i"
9399   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9400         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9401   "TARGET_SHMEDIA
9402    && (register_operand (operands[0], V8QImode)
9403        || sh_register_operand (operands[1], V8QImode))"
9404   "@
9405         add     %1, r63, %0
9406         movi    %1, %0
9407         #
9408         ld%M1.q %m1, %0
9409         st%M0.q %m0, %N1"
9410   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9411    (set_attr "length" "4,4,16,4,4")])
9412
9413 (define_split
9414   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9415         (subreg:V8QI (const_int 0) 0))]
9416   "TARGET_SHMEDIA"
9417   [(set (match_dup 0)
9418         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9419                             (const_int 0) (const_int 0) (const_int 0)
9420                             (const_int 0) (const_int 0)]))])
9421
9422 (define_split
9423   [(set (match_operand 0 "arith_reg_dest" "")
9424         (match_operand 1 "sh_rep_vec" ""))]
9425   "TARGET_SHMEDIA && reload_completed
9426    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9427    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9428    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9429    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9430        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9431    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9432        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9433   [(set (match_dup 0) (match_dup 1))
9434    (match_dup 2)]
9435   "
9436 {
9437   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9438   rtx elt1 = XVECEXP (operands[1], 0, 1);
9439
9440   if (unit_size > 2)
9441     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9442   else
9443     {
9444       if (unit_size < 2)
9445         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9446       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9447     }
9448   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9449   operands[1] = XVECEXP (operands[1], 0, 0);
9450   if (unit_size < 2)
9451     {
9452       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9453         operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9454                                ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9455                                : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9456       else
9457         {
9458           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9459           operands[1]
9460             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9461         }
9462     }
9463 }")
9464
9465 (define_split
9466   [(set (match_operand 0 "arith_reg_dest" "")
9467         (match_operand 1 "sh_const_vec" ""))]
9468   "TARGET_SHMEDIA && reload_completed
9469    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9470    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9471    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9472   [(set (match_dup 0) (match_dup 1))]
9473   "
9474 {
9475   rtx v = operands[1];
9476   enum machine_mode new_mode
9477     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9478
9479   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9480   operands[1]
9481     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9482 }")
9483
9484 (define_expand "movv2hi"
9485   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9486         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9487   "TARGET_SHMEDIA"
9488   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9489
9490 (define_insn "movv2hi_i"
9491   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9492         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9493   "TARGET_SHMEDIA
9494    && (register_operand (operands[0], V2HImode)
9495        || sh_register_operand (operands[1], V2HImode))"
9496   "@
9497         addz.l  %1, r63, %0
9498         movi    %1, %0
9499         #
9500         ld%M1.l %m1, %0
9501         st%M0.l %m0, %N1"
9502   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9503    (set_attr "length" "4,4,16,4,4")])
9504
9505 (define_expand "movv4hi"
9506   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9507         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9508   "TARGET_SHMEDIA"
9509   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9510
9511 (define_insn "movv4hi_i"
9512   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9513         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9514   "TARGET_SHMEDIA
9515    && (register_operand (operands[0], V4HImode)
9516        || sh_register_operand (operands[1], V4HImode))"
9517   "@
9518         add     %1, r63, %0
9519         movi    %1, %0
9520         #
9521         ld%M1.q %m1, %0
9522         st%M0.q %m0, %N1"
9523   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9524    (set_attr "length" "4,4,16,4,4")])
9525
9526 (define_expand "movv2si"
9527   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9528         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9529   "TARGET_SHMEDIA"
9530   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9531
9532 (define_insn "movv2si_i"
9533   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9534         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9535   "TARGET_SHMEDIA
9536    && (register_operand (operands[0], V2SImode)
9537        || sh_register_operand (operands[1], V2SImode))"
9538   "@
9539         add     %1, r63, %0
9540         #
9541         #
9542         ld%M1.q %m1, %0
9543         st%M0.q %m0, %N1"
9544   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9545    (set_attr "length" "4,4,16,4,4")])
9546
9547 ;; Multimedia Intrinsics
9548
9549 (define_insn "absv2si2"
9550   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9551         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9552   "TARGET_SHMEDIA"
9553   "mabs.l       %1, %0"
9554   [(set_attr "type" "mcmp_media")])
9555
9556 (define_insn "absv4hi2"
9557   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9558         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9559   "TARGET_SHMEDIA"
9560   "mabs.w       %1, %0"
9561   [(set_attr "type" "mcmp_media")])
9562
9563 (define_insn "addv2si3"
9564   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9565         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9566                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9567   "TARGET_SHMEDIA"
9568   "madd.l       %1, %2, %0"
9569   [(set_attr "type" "arith_media")])
9570
9571 (define_insn "addv4hi3"
9572   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9573         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9574                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9575   "TARGET_SHMEDIA"
9576   "madd.w       %1, %2, %0"
9577   [(set_attr "type" "arith_media")])
9578
9579 (define_insn "ssaddv2si3"
9580   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9581         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9582                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9583   "TARGET_SHMEDIA"
9584   "madds.l      %1, %2, %0"
9585   [(set_attr "type" "mcmp_media")])
9586
9587 (define_insn "usaddv8qi3"
9588   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9589         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9590                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9591   "TARGET_SHMEDIA"
9592   "madds.ub     %1, %2, %0"
9593   [(set_attr "type" "mcmp_media")])
9594
9595 (define_insn "ssaddv4hi3"
9596   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9597         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9598                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9599   "TARGET_SHMEDIA"
9600   "madds.w      %1, %2, %0"
9601   [(set_attr "type" "mcmp_media")])
9602
9603 (define_insn "negcmpeqv8qi"
9604   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9605         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9606                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9607   "TARGET_SHMEDIA"
9608   "mcmpeq.b     %N1, %N2, %0"
9609   [(set_attr "type" "mcmp_media")])
9610
9611 (define_insn "negcmpeqv2si"
9612   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9613         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9614                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9615   "TARGET_SHMEDIA"
9616   "mcmpeq.l     %N1, %N2, %0"
9617   [(set_attr "type" "mcmp_media")])
9618
9619 (define_insn "negcmpeqv4hi"
9620   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9621         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9622                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9623   "TARGET_SHMEDIA"
9624   "mcmpeq.w     %N1, %N2, %0"
9625   [(set_attr "type" "mcmp_media")])
9626
9627 (define_insn "negcmpgtuv8qi"
9628   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9629         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9630                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9631   "TARGET_SHMEDIA"
9632   "mcmpgt.ub    %N1, %N2, %0"
9633   [(set_attr "type" "mcmp_media")])
9634
9635 (define_insn "negcmpgtv2si"
9636   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9637         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9638                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9639   "TARGET_SHMEDIA"
9640   "mcmpgt.l     %N1, %N2, %0"
9641   [(set_attr "type" "mcmp_media")])
9642
9643 (define_insn "negcmpgtv4hi"
9644   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9645         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9646                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9647   "TARGET_SHMEDIA"
9648   "mcmpgt.w     %N1, %N2, %0"
9649   [(set_attr "type" "mcmp_media")])
9650
9651 (define_insn "mcmv"
9652   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9653         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9654                         (match_operand:DI 2 "arith_reg_operand" "r"))
9655                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9656                         (not:DI (match_dup 2)))))]
9657   "TARGET_SHMEDIA"
9658   "mcmv %N1, %2, %0"
9659   [(set_attr "type" "arith_media")])
9660
9661 (define_insn "mcnvs_lw"
9662   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9663         (vec_concat:V4HI
9664          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9665          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9666   "TARGET_SHMEDIA"
9667   "mcnvs.lw     %N1, %N2, %0"
9668   [(set_attr "type" "mcmp_media")])
9669
9670 (define_insn "mcnvs_wb"
9671   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9672         (vec_concat:V8QI
9673          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9674          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9675   "TARGET_SHMEDIA"
9676   "mcnvs.wb     %N1, %N2, %0"
9677   [(set_attr "type" "mcmp_media")])
9678
9679 (define_insn "mcnvs_wub"
9680   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9681         (vec_concat:V8QI
9682          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9683          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9684   "TARGET_SHMEDIA"
9685   "mcnvs.wub    %N1, %N2, %0"
9686   [(set_attr "type" "mcmp_media")])
9687
9688 (define_insn "mextr_rl"
9689   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9690         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9691                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9692                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9693                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9694   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9695   "*
9696 {
9697   static char templ[16];
9698
9699   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9700            (int) INTVAL (operands[3]) >> 3);
9701   return templ;
9702 }"
9703   [(set_attr "type" "arith_media")])
9704
9705 (define_insn "*mextr_lr"
9706   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9707         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9708                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9709                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9710                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9711   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9712   "*
9713 {
9714   static char templ[16];
9715
9716   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9717            (int) INTVAL (operands[4]) >> 3);
9718   return templ;
9719 }"
9720   [(set_attr "type" "arith_media")])
9721
9722 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9723 ; vector then varies depending on endianness.
9724 (define_expand "mextr1"
9725   [(match_operand:DI 0 "arith_reg_dest" "")
9726    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9727    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9728   "TARGET_SHMEDIA"
9729   "
9730 {
9731   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9732                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9733   DONE;
9734 }")
9735
9736 (define_expand "mextr2"
9737   [(match_operand:DI 0 "arith_reg_dest" "")
9738    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9739    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9740   "TARGET_SHMEDIA"
9741   "
9742 {
9743   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9744                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9745   DONE;
9746 }")
9747
9748 (define_expand "mextr3"
9749   [(match_operand:DI 0 "arith_reg_dest" "")
9750    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9751    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9752   "TARGET_SHMEDIA"
9753   "
9754 {
9755   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9756                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9757   DONE;
9758 }")
9759
9760 (define_expand "mextr4"
9761   [(match_operand:DI 0 "arith_reg_dest" "")
9762    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9763    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9764   "TARGET_SHMEDIA"
9765   "
9766 {
9767   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9768                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9769   DONE;
9770 }")
9771
9772 (define_expand "mextr5"
9773   [(match_operand:DI 0 "arith_reg_dest" "")
9774    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9775    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9776   "TARGET_SHMEDIA"
9777   "
9778 {
9779   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9780                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9781   DONE;
9782 }")
9783
9784 (define_expand "mextr6"
9785   [(match_operand:DI 0 "arith_reg_dest" "")
9786    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9787    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9788   "TARGET_SHMEDIA"
9789   "
9790 {
9791   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9792                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9793   DONE;
9794 }")
9795
9796 (define_expand "mextr7"
9797   [(match_operand:DI 0 "arith_reg_dest" "")
9798    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9799    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9800   "TARGET_SHMEDIA"
9801   "
9802 {
9803   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9804                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9805   DONE;
9806 }")
9807
9808 (define_expand "mmacfx_wl"
9809   [(match_operand:V2SI 0 "arith_reg_dest" "")
9810    (match_operand:V2HI 1 "extend_reg_operand" "")
9811    (match_operand:V2HI 2 "extend_reg_operand" "")
9812    (match_operand:V2SI 3 "arith_reg_operand" "")]
9813   "TARGET_SHMEDIA"
9814   "
9815 {
9816   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9817                               operands[1], operands[2]));
9818   DONE;
9819 }")
9820
9821 (define_insn "mmacfx_wl_i"
9822   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9823         (ss_plus:V2SI
9824          (match_operand:V2SI 1 "arith_reg_operand" "0")
9825          (ss_truncate:V2SI
9826           (ashift:V2DI
9827            (sign_extend:V2DI
9828             (mult:V2SI
9829              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9830              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9831            (const_int 1)))))]
9832   "TARGET_SHMEDIA"
9833   "mmacfx.wl    %2, %3, %0"
9834   [(set_attr "type" "mac_media")])
9835
9836 (define_expand "mmacnfx_wl"
9837   [(match_operand:V2SI 0 "arith_reg_dest" "")
9838    (match_operand:V2HI 1 "extend_reg_operand" "")
9839    (match_operand:V2HI 2 "extend_reg_operand" "")
9840    (match_operand:V2SI 3 "arith_reg_operand" "")]
9841   "TARGET_SHMEDIA"
9842   "
9843 {
9844   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9845                                operands[1], operands[2]));
9846   DONE;
9847 }")
9848
9849 (define_insn "mmacnfx_wl_i"
9850   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9851         (ss_minus:V2SI
9852          (match_operand:V2SI 1 "arith_reg_operand" "0")
9853          (ss_truncate:V2SI
9854           (ashift:V2DI
9855            (sign_extend:V2DI
9856             (mult:V2SI
9857              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9858              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9859            (const_int 1)))))]
9860   "TARGET_SHMEDIA"
9861   "mmacnfx.wl   %2, %3, %0"
9862   [(set_attr "type" "mac_media")])
9863
9864 (define_insn "mulv2si3"
9865   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9866         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9867                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9868   "TARGET_SHMEDIA"
9869   "mmul.l       %1, %2, %0"
9870   [(set_attr "type" "d2mpy_media")])
9871
9872 (define_insn "mulv4hi3"
9873   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9874         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9875                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9876   "TARGET_SHMEDIA"
9877   "mmul.w       %1, %2, %0"
9878   [(set_attr "type" "dmpy_media")])
9879
9880 (define_insn "mmulfx_l"
9881   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9882         (ss_truncate:V2SI
9883          (ashiftrt:V2DI
9884           (mult:V2DI
9885            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9886            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9887           (const_int 31))))]
9888   "TARGET_SHMEDIA"
9889   "mmulfx.l     %1, %2, %0"
9890   [(set_attr "type" "d2mpy_media")])
9891
9892 (define_insn "mmulfx_w"
9893   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9894         (ss_truncate:V4HI
9895          (ashiftrt:V4SI
9896           (mult:V4SI
9897            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9898            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9899           (const_int 15))))]
9900   "TARGET_SHMEDIA"
9901   "mmulfx.w     %1, %2, %0"
9902   [(set_attr "type" "dmpy_media")])
9903
9904 (define_insn "mmulfxrp_w"
9905   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9906         (ss_truncate:V4HI
9907          (ashiftrt:V4SI
9908           (plus:V4SI
9909            (mult:V4SI
9910             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9911             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9912            (const_int 16384))
9913           (const_int 15))))]
9914   "TARGET_SHMEDIA"
9915   "mmulfxrp.w   %1, %2, %0"
9916   [(set_attr "type" "dmpy_media")])
9917
9918 (define_expand "mmulhi_wl"
9919   [(match_operand:V2SI 0 "arith_reg_dest" "")
9920    (match_operand:V4HI 1 "arith_reg_operand" "")
9921    (match_operand:V4HI 2 "arith_reg_operand" "")]
9922   "TARGET_SHMEDIA"
9923   "
9924 {
9925   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9926              (operands[0], operands[1], operands[2]));
9927   DONE;
9928 }")
9929
9930 (define_expand "mmullo_wl"
9931   [(match_operand:V2SI 0 "arith_reg_dest" "")
9932    (match_operand:V4HI 1 "arith_reg_operand" "")
9933    (match_operand:V4HI 2 "arith_reg_operand" "")]
9934   "TARGET_SHMEDIA"
9935   "
9936 {
9937   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9938              (operands[0], operands[1], operands[2]));
9939   DONE;
9940 }")
9941
9942 (define_insn "mmul23_wl"
9943   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9944         (vec_select:V2SI
9945          (mult:V4SI
9946           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9947           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9948          (parallel [(const_int 2) (const_int 3)])))]
9949   "TARGET_SHMEDIA"
9950   "* return (TARGET_LITTLE_ENDIAN
9951              ? \"mmulhi.wl      %1, %2, %0\"
9952              : \"mmullo.wl      %1, %2, %0\");"
9953   [(set_attr "type" "dmpy_media")])
9954
9955 (define_insn "mmul01_wl"
9956   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9957         (vec_select:V2SI
9958          (mult:V4SI
9959           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9960           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9961          (parallel [(const_int 0) (const_int 1)])))]
9962   "TARGET_SHMEDIA"
9963   "* return (TARGET_LITTLE_ENDIAN
9964              ? \"mmullo.wl      %1, %2, %0\"
9965              : \"mmulhi.wl      %1, %2, %0\");"
9966   [(set_attr "type" "dmpy_media")])
9967
9968 (define_expand "mmulsum_wq"
9969   [(match_operand:DI 0 "arith_reg_dest" "")
9970    (match_operand:V4HI 1 "arith_reg_operand" "")
9971    (match_operand:V4HI 2 "arith_reg_operand" "")
9972    (match_operand:DI 3 "arith_reg_operand" "")]
9973   "TARGET_SHMEDIA"
9974   "
9975 {
9976   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9977                                operands[1], operands[2]));
9978   DONE;
9979 }")
9980
9981 (define_insn "mmulsum_wq_i"
9982   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9983         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9984          (plus:DI
9985           (plus:DI
9986            (vec_select:DI
9987             (mult:V4DI
9988              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9989              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9990             (parallel [(const_int 0)]))
9991            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9992                                      (sign_extend:V4DI (match_dup 3)))
9993                           (parallel [(const_int 1)])))
9994           (plus:DI
9995            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9996                                      (sign_extend:V4DI (match_dup 3)))
9997                           (parallel [(const_int 2)]))
9998            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9999                                      (sign_extend:V4DI (match_dup 3)))
10000                           (parallel [(const_int 3)]))))))]
10001   "TARGET_SHMEDIA"
10002   "mmulsum.wq   %2, %3, %0"
10003   [(set_attr "type" "mac_media")])
10004
10005 (define_expand "mperm_w"
10006   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10007    (match_operand:V4HI 1 "arith_reg_operand" "r")
10008    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10009   "TARGET_SHMEDIA"
10010   "
10011 {
10012   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10013              (operands[0], operands[1], operands[2]));
10014   DONE;
10015 }")
10016
10017 ; This use of vec_select isn't exactly correct according to rtl.texi
10018 ; (because not constant), but it seems a straightforward extension.
10019 (define_insn "mperm_w_little"
10020   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10021         (vec_select:V4HI
10022          (match_operand:V4HI 1 "arith_reg_operand" "r")
10023          (parallel
10024           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10025                             (const_int 2) (const_int 0))
10026            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10027            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10028            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10029   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10030   "mperm.w      %1, %N2, %0"
10031   [(set_attr "type" "arith_media")])
10032
10033 (define_insn "mperm_w_big"
10034   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10035         (vec_select:V4HI
10036          (match_operand:V4HI 1 "arith_reg_operand" "r")
10037          (parallel
10038           [(zero_extract:QI (not:QI (match_operand:QI 2
10039                                      "extend_reg_or_0_operand" "rZ"))
10040                             (const_int 2) (const_int 0))
10041            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10042            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10043            (zero_extract:QI (not:QI (match_dup 2))
10044                             (const_int 2) (const_int 6))])))]
10045   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10046   "mperm.w      %1, %N2, %0"
10047   [(set_attr "type" "arith_media")])
10048
10049 (define_insn "mperm_w0"
10050   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10051         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10052                                           "trunc_hi_operand" "r"))))]
10053   "TARGET_SHMEDIA"
10054   "mperm.w      %1, r63, %0"
10055   [(set_attr "type" "arith_media")])
10056
10057 (define_expand "msad_ubq"
10058   [(match_operand:DI 0 "arith_reg_dest" "")
10059    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10060    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10061    (match_operand:DI 3 "arith_reg_operand" "")]
10062   "TARGET_SHMEDIA"
10063   "
10064 {
10065   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10066                              operands[1], operands[2]));
10067   DONE;
10068 }")
10069
10070 (define_insn "msad_ubq_i"
10071   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10072         (plus:DI
10073          (plus:DI
10074           (plus:DI
10075            (plus:DI
10076             (match_operand:DI 1 "arith_reg_operand" "0")
10077             (abs:DI (vec_select:DI
10078                      (minus:V8DI
10079                       (zero_extend:V8DI
10080                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10081                       (zero_extend:V8DI
10082                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10083                      (parallel [(const_int 0)]))))
10084            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10085                                               (zero_extend:V8DI (match_dup 3)))
10086                                   (parallel [(const_int 1)]))))
10087           (plus:DI
10088            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10089                                               (zero_extend:V8DI (match_dup 3)))
10090                                   (parallel [(const_int 2)])))
10091            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10092                                               (zero_extend:V8DI (match_dup 3)))
10093                                   (parallel [(const_int 3)])))))
10094          (plus:DI
10095           (plus:DI
10096            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10097                                               (zero_extend:V8DI (match_dup 3)))
10098                                   (parallel [(const_int 4)])))
10099            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10100                                               (zero_extend:V8DI (match_dup 3)))
10101                                   (parallel [(const_int 5)]))))
10102           (plus:DI
10103            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10104                                               (zero_extend:V8DI (match_dup 3)))
10105                                   (parallel [(const_int 6)])))
10106            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10107                                               (zero_extend:V8DI (match_dup 3)))
10108                                   (parallel [(const_int 7)])))))))]
10109   "TARGET_SHMEDIA"
10110   "msad.ubq     %N2, %N3, %0"
10111   [(set_attr "type" "mac_media")])
10112
10113 (define_insn "mshalds_l"
10114   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10115         (ss_truncate:V2SI
10116          (ashift:V2DI
10117           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10118           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10119                   (const_int 31)))))]
10120   "TARGET_SHMEDIA"
10121   "mshalds.l    %1, %2, %0"
10122   [(set_attr "type" "mcmp_media")])
10123
10124 (define_insn "mshalds_w"
10125   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10126         (ss_truncate:V4HI
10127          (ashift:V4SI
10128           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10129           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10130                   (const_int 15)))))]
10131   "TARGET_SHMEDIA"
10132   "mshalds.w    %1, %2, %0"
10133   [(set_attr "type" "mcmp_media")])
10134
10135 (define_insn "ashrv2si3"
10136   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10137         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10138                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10139   "TARGET_SHMEDIA"
10140   "mshard.l     %1, %2, %0"
10141   [(set_attr "type" "arith_media")])
10142
10143 (define_insn "ashrv4hi3"
10144   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10145         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10146                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10147   "TARGET_SHMEDIA"
10148   "mshard.w     %1, %2, %0"
10149   [(set_attr "type" "arith_media")])
10150
10151 (define_insn "mshards_q"
10152   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10153         (ss_truncate:HI
10154          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10155                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10156   "TARGET_SHMEDIA"
10157   "mshards.q    %1, %N2, %0"
10158   [(set_attr "type" "mcmp_media")])
10159
10160 (define_expand "mshfhi_b"
10161   [(match_operand:V8QI 0 "arith_reg_dest" "")
10162    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10163    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10164   "TARGET_SHMEDIA"
10165   "
10166 {
10167   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10168              (operands[0], operands[1], operands[2]));
10169   DONE;
10170 }")
10171
10172 (define_expand "mshflo_b"
10173   [(match_operand:V8QI 0 "arith_reg_dest" "")
10174    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10175    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10176   "TARGET_SHMEDIA"
10177   "
10178 {
10179   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10180              (operands[0], operands[1], operands[2]));
10181   DONE;
10182 }")
10183
10184 (define_insn "mshf4_b"
10185   [(set
10186     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10187     (vec_select:V8QI
10188      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10189                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10190      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10191                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10192   "TARGET_SHMEDIA"
10193   "* return (TARGET_LITTLE_ENDIAN
10194              ? \"mshfhi.b       %N1, %N2, %0\"
10195              : \"mshflo.b       %N1, %N2, %0\");"
10196   [(set_attr "type" "arith_media")])
10197
10198 (define_insn "mshf0_b"
10199   [(set
10200     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10201     (vec_select:V8QI
10202      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10203                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10204      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10205                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10206   "TARGET_SHMEDIA"
10207   "* return (TARGET_LITTLE_ENDIAN
10208              ? \"mshflo.b       %N1, %N2, %0\"
10209              : \"mshfhi.b       %N1, %N2, %0\");"
10210   [(set_attr "type" "arith_media")])
10211
10212 (define_expand "mshfhi_l"
10213   [(match_operand:V2SI 0 "arith_reg_dest" "")
10214    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10215    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10216   "TARGET_SHMEDIA"
10217   "
10218 {
10219   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10220              (operands[0], operands[1], operands[2]));
10221   DONE;
10222 }")
10223
10224 (define_expand "mshflo_l"
10225   [(match_operand:V2SI 0 "arith_reg_dest" "")
10226    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10227    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10228   "TARGET_SHMEDIA"
10229   "
10230 {
10231   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10232              (operands[0], operands[1], operands[2]));
10233   DONE;
10234 }")
10235
10236 (define_insn "mshf4_l"
10237   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10238         (vec_select:V2SI
10239          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10240                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10241          (parallel [(const_int 1) (const_int 3)])))]
10242   "TARGET_SHMEDIA"
10243   "* return (TARGET_LITTLE_ENDIAN
10244              ? \"mshfhi.l       %N1, %N2, %0\"
10245              : \"mshflo.l       %N1, %N2, %0\");"
10246   [(set_attr "type" "arith_media")])
10247
10248 (define_insn "mshf0_l"
10249   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10250         (vec_select:V2SI
10251          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10252                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10253          (parallel [(const_int 0) (const_int 2)])))]
10254   "TARGET_SHMEDIA"
10255   "* return (TARGET_LITTLE_ENDIAN
10256              ? \"mshflo.l       %N1, %N2, %0\"
10257              : \"mshfhi.l       %N1, %N2, %0\");"
10258   [(set_attr "type" "arith_media")])
10259
10260 (define_expand "mshfhi_w"
10261   [(match_operand:V4HI 0 "arith_reg_dest" "")
10262    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10263    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10264   "TARGET_SHMEDIA"
10265   "
10266 {
10267   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10268              (operands[0], operands[1], operands[2]));
10269   DONE;
10270 }")
10271
10272 (define_expand "mshflo_w"
10273   [(match_operand:V4HI 0 "arith_reg_dest" "")
10274    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10275    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10276   "TARGET_SHMEDIA"
10277   "
10278 {
10279   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10280              (operands[0], operands[1], operands[2]));
10281   DONE;
10282 }")
10283
10284 (define_insn "mshf4_w"
10285   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10286         (vec_select:V4HI
10287          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10288                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10289          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10290   "TARGET_SHMEDIA"
10291   "* return (TARGET_LITTLE_ENDIAN
10292              ? \"mshfhi.w       %N1, %N2, %0\"
10293              : \"mshflo.w       %N1, %N2, %0\");"
10294   [(set_attr "type" "arith_media")])
10295
10296 (define_insn "mshf0_w"
10297   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10298         (vec_select:V4HI
10299          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10300                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10301          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10302   "TARGET_SHMEDIA"
10303   "* return (TARGET_LITTLE_ENDIAN
10304              ? \"mshflo.w       %N1, %N2, %0\"
10305              : \"mshfhi.w       %N1, %N2, %0\");"
10306   [(set_attr "type" "arith_media")])
10307
10308 (define_insn "mshflo_w_x"
10309   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10310         (vec_select:V4HI
10311          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10312                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10313          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10314   "TARGET_SHMEDIA"
10315   "mshflo.w     %N1, %N2, %0"
10316   [(set_attr "type" "arith_media")])
10317
10318 /* These are useful to expand ANDs and as combiner patterns.  */
10319 (define_insn_and_split "mshfhi_l_di"
10320   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10321         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10322                              (const_int 32))
10323                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10324                         (const_int -4294967296))))]
10325   "TARGET_SHMEDIA"
10326   "@
10327         mshfhi.l        %N1, %N2, %0
10328         #"
10329   "TARGET_SHMEDIA && reload_completed
10330    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10331   [(set (match_dup 3) (match_dup 4))
10332    (set (match_dup 5) (match_dup 6))]
10333   "
10334 {
10335   operands[3] = gen_lowpart (SImode, operands[0]);
10336   operands[4] = gen_highpart (SImode, operands[1]);
10337   operands[5] = gen_highpart (SImode, operands[0]);
10338   operands[6] = gen_highpart (SImode, operands[2]);
10339 }"
10340   [(set_attr "type" "arith_media")])
10341
10342 (define_insn "*mshfhi_l_di_rev"
10343   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10344         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10345                         (const_int -4294967296))
10346                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10347                              (const_int 32))))]
10348   "TARGET_SHMEDIA"
10349   "mshfhi.l     %N2, %N1, %0"
10350   [(set_attr "type" "arith_media")])
10351
10352 (define_split
10353   [(set (match_operand:DI 0 "arith_reg_dest" "")
10354         (ior:DI (zero_extend:DI (match_operand:SI 1
10355                                               "extend_reg_or_0_operand" ""))
10356                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10357                         (const_int -4294967296))))
10358    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10359   "TARGET_SHMEDIA"
10360   [(const_int 0)]
10361   "
10362 {
10363   emit_insn (gen_ashldi3_media (operands[3],
10364                                 simplify_gen_subreg (DImode, operands[1],
10365                                                      SImode, 0),
10366                                 GEN_INT (32)));
10367   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10368   DONE;
10369 }")
10370
10371 (define_insn "mshflo_l_di"
10372   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10373         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10374                         (const_int 4294967295))
10375                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10376                            (const_int 32))))]
10377
10378   "TARGET_SHMEDIA"
10379   "mshflo.l     %N1, %N2, %0"
10380   [(set_attr "type" "arith_media")])
10381
10382 (define_insn "*mshflo_l_di_rev"
10383   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10384         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10385                            (const_int 32))
10386                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10387                         (const_int 4294967295))))]
10388
10389   "TARGET_SHMEDIA"
10390   "mshflo.l     %N2, %N1, %0"
10391   [(set_attr "type" "arith_media")])
10392
10393 ;; Combiner pattern for trampoline initialization.
10394 (define_insn_and_split "*double_shori"
10395   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10396         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10397                            (const_int 32))
10398                 (match_operand:DI 2 "const_int_operand" "n")))]
10399   "TARGET_SHMEDIA
10400    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10401   "#"
10402   "rtx_equal_p (operands[0], operands[1])"
10403   [(const_int 0)]
10404   "
10405 {
10406   HOST_WIDE_INT v = INTVAL (operands[2]);
10407
10408   emit_insn (gen_shori_media (operands[0], operands[0],
10409              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10410   emit_insn (gen_shori_media (operands[0], operands[0],
10411                               gen_int_mode (v, HImode)));
10412   DONE;
10413 }")
10414
10415
10416 (define_insn "*mshflo_l_di_x"
10417   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10418         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10419                                  "rZ"))
10420                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10421                            (const_int 32))))]
10422
10423   "TARGET_SHMEDIA"
10424   "mshflo.l     %N1, %N2, %0"
10425   [(set_attr "type" "arith_media")])
10426
10427 (define_insn_and_split "concat_v2sf"
10428   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10429 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10430         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10431                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10432
10433   "TARGET_SHMEDIA"
10434   "@
10435         mshflo.l        %N1, %N2, %0
10436         #
10437         #"
10438   "TARGET_SHMEDIA && reload_completed
10439    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10440   [(set (match_dup 3) (match_dup 1))
10441    (set (match_dup 4) (match_dup 2))]
10442   "
10443 {
10444   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10445   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10446 }"
10447   [(set_attr "type" "arith_media")])
10448
10449 (define_insn "*mshflo_l_di_x_rev"
10450   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10451         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10452                            (const_int 32))
10453                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10454
10455   "TARGET_SHMEDIA"
10456   "mshflo.l     %N2, %N1, %0"
10457   [(set_attr "type" "arith_media")])
10458
10459 (define_insn "ashlv2si3"
10460   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10461         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10462                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10463   "TARGET_SHMEDIA"
10464   "mshlld.l     %1, %2, %0"
10465   [(set_attr "type" "arith_media")])
10466
10467 (define_insn "ashlv4hi3"
10468   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10469         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10470                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10471   "TARGET_SHMEDIA"
10472   "mshlld.w     %1, %2, %0"
10473   [(set_attr "type" "arith_media")])
10474
10475 (define_insn "lshrv2si3"
10476   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10477         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10478                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10479   "TARGET_SHMEDIA"
10480   "mshlrd.l     %1, %2, %0"
10481   [(set_attr "type" "arith_media")])
10482
10483 (define_insn "lshrv4hi3"
10484   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10485         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10486                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10487   "TARGET_SHMEDIA"
10488   "mshlrd.w     %1, %2, %0"
10489   [(set_attr "type" "arith_media")])
10490
10491 (define_insn "subv2si3"
10492   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10493         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10494                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10495   "TARGET_SHMEDIA"
10496   "msub.l       %N1, %2, %0"
10497   [(set_attr "type" "arith_media")])
10498
10499 (define_insn "subv4hi3"
10500   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10501         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10502                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10503   "TARGET_SHMEDIA"
10504   "msub.w       %N1, %2, %0"
10505   [(set_attr "type" "arith_media")])
10506
10507 (define_insn "sssubv2si3"
10508   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10509         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10510                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10511   "TARGET_SHMEDIA"
10512   "msubs.l      %N1, %2, %0"
10513   [(set_attr "type" "mcmp_media")])
10514
10515 (define_insn "ussubv8qi3"
10516   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10517         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10518                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10519   "TARGET_SHMEDIA"
10520   "msubs.ub     %1, %2, %0"
10521   [(set_attr "type" "mcmp_media")])
10522
10523 (define_insn "sssubv4hi3"
10524   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10525         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10526                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10527   "TARGET_SHMEDIA"
10528   "msubs.w      %N1, %2, %0"
10529   [(set_attr "type" "mcmp_media")])
10530
10531 ;; Floating Point Intrinsics
10532
10533 (define_insn "fcosa_s"
10534   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10535         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10536                    UNSPEC_FCOSA))]
10537   "TARGET_SHMEDIA"
10538   "fcosa.s      %1, %0"
10539   [(set_attr "type" "atrans_media")])
10540
10541 (define_insn "fsina_s"
10542   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10543         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10544                    UNSPEC_FSINA))]
10545   "TARGET_SHMEDIA"
10546   "fsina.s      %1, %0"
10547   [(set_attr "type" "atrans_media")])
10548
10549 (define_insn "fipr"
10550   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10551         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10552                                                     "fp_arith_reg_operand" "f")
10553                                                    (match_operand:V4SF 2
10554                                                     "fp_arith_reg_operand" "f"))
10555                                          (parallel [(const_int 0)]))
10556                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10557                                          (parallel [(const_int 1)])))
10558                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10559                                          (parallel [(const_int 2)]))
10560                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10561                                          (parallel [(const_int 3)])))))]
10562   "TARGET_SHMEDIA"
10563   "fipr %1, %2, %0"
10564   [(set_attr "type" "fparith_media")])
10565
10566 (define_insn "fsrra_s"
10567   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10568         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10569                    UNSPEC_FSRRA))]
10570   "TARGET_SHMEDIA"
10571   "fsrra.s      %1, %0"
10572   [(set_attr "type" "atrans_media")])
10573
10574 (define_insn "ftrv"
10575   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10576         (plus:V4SF
10577          (plus:V4SF
10578           (mult:V4SF
10579            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10580                             (parallel [(const_int 0) (const_int 5)
10581                                        (const_int 10) (const_int 15)]))
10582            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10583           (mult:V4SF
10584            (vec_select:V4SF (match_dup 1)
10585                             (parallel [(const_int 4) (const_int 9)
10586                                        (const_int 14) (const_int 3)]))
10587            (vec_select:V4SF (match_dup 2)
10588                             (parallel [(const_int 1) (const_int 2)
10589                                       (const_int 3) (const_int 0)]))))
10590          (plus:V4SF
10591           (mult:V4SF
10592            (vec_select:V4SF (match_dup 1)
10593                             (parallel [(const_int 8) (const_int 13)
10594                                        (const_int 2) (const_int 7)]))
10595            (vec_select:V4SF (match_dup 2)
10596                             (parallel [(const_int 2) (const_int 3)
10597                                        (const_int 0) (const_int 1)])))
10598           (mult:V4SF
10599            (vec_select:V4SF (match_dup 1)
10600                             (parallel [(const_int 12) (const_int 1)
10601                                        (const_int 6) (const_int 11)]))
10602            (vec_select:V4SF (match_dup 2)
10603                             (parallel [(const_int 3) (const_int 0)
10604                                        (const_int 1) (const_int 2)]))))))]
10605   "TARGET_SHMEDIA"
10606   "ftrv %1, %2, %0"
10607   [(set_attr "type" "fparith_media")])
10608
10609 (define_insn "nsb"
10610   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10611         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10612                    UNSPEC_NSB))]
10613   "TARGET_SHMEDIA"
10614   "nsb  %1, %0"
10615   [(set_attr "type" "arith_media")])
10616
10617 (define_insn "nsbsi"
10618   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10619         (zero_extend:SI
10620          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10621                     UNSPEC_NSB)))]
10622   "TARGET_SHMEDIA"
10623   "nsb  %1, %0"
10624   [(set_attr "type" "arith_media")])
10625
10626 (define_insn "nsbdi"
10627   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10628         (zero_extend:DI
10629          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10630                     UNSPEC_NSB)))]
10631   "TARGET_SHMEDIA"
10632   "nsb  %1, %0"
10633   [(set_attr "type" "arith_media")])
10634
10635 (define_expand "ffsdi2"
10636   [(set (match_operand:DI 0 "arith_reg_dest" "")
10637         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10638   "TARGET_SHMEDIA"
10639   "
10640 {
10641   rtx scratch = gen_reg_rtx (DImode);
10642   rtx last;
10643
10644   emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10645   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10646   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10647   emit_insn (gen_nsbdi (scratch, scratch));
10648   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10649   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10650   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10651   REG_NOTES (last)
10652     = gen_rtx_EXPR_LIST (REG_EQUAL,
10653                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10654   DONE;
10655 }")
10656
10657 (define_expand "ffssi2"
10658   [(set (match_operand:SI 0 "arith_reg_dest" "")
10659         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10660   "TARGET_SHMEDIA"
10661   "
10662 {
10663   rtx scratch = gen_reg_rtx (SImode);
10664   rtx discratch = gen_reg_rtx (DImode);
10665   rtx last;
10666
10667   emit_insn (gen_adddi3 (discratch,
10668                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10669                          GEN_INT (-1)));
10670   emit_insn (gen_andcdi3 (discratch,
10671                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10672                           discratch));
10673   emit_insn (gen_nsbsi (scratch, discratch));
10674   last = emit_insn (gen_subsi3 (operands[0],
10675                                 force_reg (SImode, GEN_INT (63)), scratch));
10676   REG_NOTES (last)
10677     = gen_rtx_EXPR_LIST (REG_EQUAL,
10678                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10679   DONE;
10680 }")
10681
10682 (define_insn "byterev"
10683   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10684         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10685                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10686                                     (const_int 4) (const_int 3) (const_int 2)
10687                                     (const_int 1) (const_int 0)])))]
10688   "TARGET_SHMEDIA"
10689   "byterev      %1, %0"
10690   [(set_attr "type" "arith_media")])
10691
10692 (define_insn "prefetch"
10693   [(prefetch (match_operand:QI 0 "address_operand" "p")
10694              (match_operand:SI 1 "const_int_operand" "n")
10695              (match_operand:SI 2 "const_int_operand" "n"))]
10696   "TARGET_SHMEDIA"
10697   "*
10698 {
10699   operands[0] = gen_rtx_MEM (QImode, operands[0]);
10700   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
10701   return \"\";
10702 }"
10703   [(set_attr "type" "other")])
10704
10705 ;; The following description  models the
10706 ;; SH4 pipeline using the DFA based scheduler.
10707 ;; The DFA based description is better way to model
10708 ;; a superscalar pipeline as compared to function unit
10709 ;; reservation model.
10710 ;; 1. The function unit based model is oriented to describe at most one
10711 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple
10712 ;;    pipeline units by same insn. This can be done using DFA based description.
10713 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10714 ;; 3. Writing all unit reservations for an instruction class is more natural description
10715 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the
10716 ;;    old function unit based model.
10717 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10718
10719
10720 ;; Two automata are defined to reduce number of states
10721 ;; which a single large automaton will have.(Factoring)
10722
10723 (define_automaton "inst_pipeline,fpu_pipe")
10724
10725 ;; This unit is basically the decode unit of the processor.
10726 ;; Since SH4 is a dual issue machine,it is as if there are two
10727 ;; units so that any insn can be processed by either one
10728 ;; of the decoding unit.
10729
10730 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10731
10732
10733 ;; The fixed point arithmetic calculator(?? EX Unit).
10734
10735 (define_cpu_unit  "int" "inst_pipeline")
10736
10737 ;; f1_1 and f1_2 are floating point units.Actually there is
10738 ;; a f1 unit which can overlap with other f1 unit but
10739 ;; not another F1 unit.It is as though there were two
10740 ;; f1 units.
10741
10742 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10743
10744 ;; The floating point units (except FS - F2 always precedes it.)
10745
10746 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10747
10748 ;; This is basically the MA unit of SH4
10749 ;; used in LOAD/STORE pipeline.
10750
10751 (define_cpu_unit "memory" "inst_pipeline")
10752
10753 ;; However, there are LS group insns that don't use it, even ones that
10754 ;; complete in 0 cycles.  So we use an extra unit for the issue of LS insns.
10755 (define_cpu_unit "load_store" "inst_pipeline")
10756
10757 ;; The address calculator used for branch instructions.
10758 ;; This will be reserved after "issue" of branch instructions
10759 ;; and this is to make sure that no two branch instructions
10760 ;; can be issued in parallel.
10761
10762 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10763
10764 ;; ----------------------------------------------------
10765 ;; This reservation is to simplify the dual issue description.
10766
10767 (define_reservation  "issue"  "pipe_01|pipe_02")
10768
10769 ;; This is to express the locking of D stage.
10770 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10771
10772 (define_reservation  "d_lock" "pipe_01+pipe_02")
10773
10774 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10775 (define_reservation "F01" "F0+F1")
10776
10777 ;; This is to simplify description where F1,F2,FS
10778 ;; are used simultaneously.
10779
10780 (define_reservation "fpu" "F1+F2")
10781
10782 ;; This is to highlight the fact that f1
10783 ;; cannot overlap with F1.
10784
10785 (exclusion_set  "f1_1,f1_2" "F1")
10786
10787 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10788
10789 ;; Although reg moves have a latency of zero
10790 ;; we need to highlight that they use D stage
10791 ;; for one cycle.
10792
10793 ;; Group:       MT
10794
10795 (define_insn_reservation "reg_mov" 0
10796   (and (eq_attr "pipe_model" "sh4")
10797        (eq_attr "type" "move"))
10798   "issue")
10799
10800 ;; Group:       LS
10801
10802 (define_insn_reservation "freg_mov" 0
10803   (and (eq_attr "pipe_model" "sh4")
10804        (eq_attr "type" "fmove"))
10805   "issue+load_store")
10806
10807 ;; We don't model all pipeline stages; we model the issue ('D') stage
10808 ;; inasmuch as we allow only two instructions to issue simultaneously,
10809 ;; and CO instructions prevent any simultaneous issue of another instruction.
10810 ;; (This uses pipe_01 and pipe_02).
10811 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10812 ;; Double issue of EX / BR insns is prevented by using the int unit /
10813 ;; pcr_addrcalc unit in the EX stage.
10814 ;; Double issue of BR / LS instructions is prevented by using the
10815 ;; pcr_addrcalc / load_store unit in the issue cycle.
10816 ;; Double issue of FE instructions is prevented by using F0 in the first
10817 ;; pipeline stage after the first D stage.
10818 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10819 ;; (except in the cases outlined above), nor to describe the FS stage after
10820 ;; the F2 stage.
10821
10822 ;; Other MT  group instructions(1 step operations)
10823 ;; Group:       MT
10824 ;; Latency:     1
10825 ;; Issue Rate:  1
10826
10827 (define_insn_reservation "mt" 1
10828   (and (eq_attr "pipe_model" "sh4")
10829        (eq_attr "type" "mt_group"))
10830   "issue")
10831
10832 ;; Fixed Point Arithmetic Instructions(1 step operations)
10833 ;; Group:       EX
10834 ;; Latency:     1
10835 ;; Issue Rate:  1
10836
10837 (define_insn_reservation "sh4_simple_arith" 1
10838   (and (eq_attr "pipe_model" "sh4")
10839        (eq_attr "insn_class" "ex_group"))
10840   "issue,int")
10841
10842 ;; Load and store instructions have no alignment peculiarities for the SH4,
10843 ;; but they use the load-store unit, which they share with the fmove type
10844 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10845 ;; Loads have a latency of two.
10846 ;; However, call insns can only paired with a preceding insn, and have
10847 ;; a delay slot, so that we want two more insns to be scheduled between the
10848 ;; load of the function address and the call.  This is equivalent to a
10849 ;; latency of three.
10850 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10851 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10852 ;; We only do this for SImode loads of general registers, to make the work
10853 ;; for ADJUST_COST easier.
10854
10855 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10856 ;; Group:       LS
10857 ;; Latency:     2
10858 ;; Issue Rate:  1
10859
10860 (define_insn_reservation "sh4_load" 2
10861   (and (eq_attr "pipe_model" "sh4")
10862        (eq_attr "type" "load,pcload"))
10863   "issue+load_store,nothing,memory")
10864
10865 ;; calls / sfuncs need an extra instruction for their delay slot.
10866 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10867 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10868 ;; count of a dynamic shift.
10869 (define_insn_reservation "sh4_load_si" 3
10870   (and (eq_attr "pipe_model" "sh4")
10871        (eq_attr "type" "load_si,pcload_si"))
10872   "issue+load_store,nothing,memory")
10873
10874 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10875
10876 ;; The load latency is upped to three higher if the dependent insn does
10877 ;; double precision computation.  We want the 'default' latency to reflect
10878 ;; that increased latency because otherwise the insn priorities won't
10879 ;; allow proper scheduling.
10880 (define_insn_reservation "sh4_fload" 3
10881   (and (eq_attr "pipe_model" "sh4")
10882        (eq_attr "type" "fload,pcfload"))
10883   "issue+load_store,nothing,memory")
10884
10885 ;; (define_bypass 2 "sh4_fload" "!")
10886
10887 (define_insn_reservation "sh4_store" 1
10888   (and (eq_attr "pipe_model" "sh4")
10889        (eq_attr "type" "store"))
10890   "issue+load_store,nothing,memory")
10891
10892 ;; Load Store instructions.
10893 ;; Group:       LS
10894 ;; Latency:     1
10895 ;; Issue Rate:  1
10896
10897 (define_insn_reservation "sh4_gp_fpul" 1
10898   (and (eq_attr "pipe_model" "sh4")
10899        (eq_attr "type" "gp_fpul"))
10900   "issue+load_store")
10901
10902 ;; Load Store instructions.
10903 ;; Group:       LS
10904 ;; Latency:     3
10905 ;; Issue Rate:  1
10906
10907 (define_insn_reservation "sh4_fpul_gp" 3
10908   (and (eq_attr "pipe_model" "sh4")
10909        (eq_attr "type" "fpul_gp"))
10910   "issue+load_store")
10911
10912 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10913 ;; Group:       BR
10914 ;; Latency when taken:  2 (or 1)
10915 ;; Issue Rate:  1
10916 ;; The latency is 1 when displacement is 0.
10917 ;; We can't really do much with the latency, even if we could express it,
10918 ;; but the pairing restrictions are useful to take into account.
10919 ;; ??? If the branch is likely, we might want to fill the delay slot;
10920 ;; if the branch is likely, but not very likely, should we pretend to use
10921 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10922
10923 (define_insn_reservation "sh4_branch"  1
10924   (and (eq_attr "pipe_model" "sh4")
10925        (eq_attr "type" "cbranch,jump"))
10926   "issue+pcr_addrcalc")
10927
10928 ;; Branch Far (JMP,RTS,BRAF)
10929 ;; Group:       CO
10930 ;; Latency:     3
10931 ;; Issue Rate:  2
10932 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10933 ;; can't be distinguished from bra for the "jump" pattern.
10934
10935 (define_insn_reservation "sh4_return" 3
10936   (and (eq_attr "pipe_model" "sh4")
10937        (eq_attr "type" "return,jump_ind"))
10938          "d_lock*2")
10939
10940 ;; RTE
10941 ;; Group:       CO
10942 ;; Latency:     5
10943 ;; Issue Rate:  5
10944 ;; this instruction can be executed in any of the pipelines
10945 ;; and blocks the pipeline for next 4 stages.
10946
10947 (define_insn_reservation "sh4_return_from_exp" 5
10948   (and (eq_attr "pipe_model" "sh4")
10949        (eq_attr "type" "rte"))
10950   "d_lock*5")
10951
10952 ;; OCBP, OCBWB
10953 ;; Group:       CO
10954 ;; Latency:     1-5
10955 ;; Issue Rate:  1
10956
10957 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10958 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10959 (define_insn_reservation "ocbwb"  6
10960   (and (eq_attr "pipe_model" "sh4")
10961        (eq_attr "type" "cwb"))
10962   "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10963
10964 ;; LDS to PR,JSR
10965 ;; Group:       CO
10966 ;; Latency:     3
10967 ;; Issue Rate:  2
10968 ;; The SX stage is blocked for last 2 cycles.
10969 ;; OTOH, the only time that has an effect for insns generated by the compiler
10970 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10971 ;; or when we are doing a function call - and we don't do inter-function
10972 ;; scheduling.  For the function call case, it's really best that we end with
10973 ;; something that models an rts.
10974
10975 (define_insn_reservation "sh4_lds_to_pr" 3
10976   (and (eq_attr "pipe_model" "sh4")
10977        (eq_attr "type" "prset") )
10978   "d_lock*2")
10979
10980 ;; calls introduce a longisch delay that is likely to flush the pipelines
10981 ;; of the caller's instructions.  Ordinary functions tend to end with a
10982 ;; load to restore a register (in the delay slot of rts), while sfuncs
10983 ;; tend to end with an EX or MT insn.  But that is not actually relevant,
10984 ;; since there are no instructions that contend for memory access early.
10985 ;; We could, of course, provide exact scheduling information for specific
10986 ;; sfuncs, if that should prove useful.
10987
10988 (define_insn_reservation "sh4_call" 16
10989   (and (eq_attr "pipe_model" "sh4")
10990        (eq_attr "type" "call,sfunc"))
10991   "d_lock*16")
10992
10993 ;; LDS.L to PR
10994 ;; Group:       CO
10995 ;; Latency:     3
10996 ;; Issue Rate:  2
10997 ;; The SX unit is blocked for last 2 cycles.
10998
10999 (define_insn_reservation "ldsmem_to_pr"  3
11000   (and (eq_attr "pipe_model" "sh4")
11001        (eq_attr "type" "pload"))
11002   "d_lock*2")
11003
11004 ;; STS from PR
11005 ;; Group:       CO
11006 ;; Latency:     2
11007 ;; Issue Rate:  2
11008 ;; The SX unit in second and third cycles.
11009
11010 (define_insn_reservation "sts_from_pr" 2
11011   (and (eq_attr "pipe_model" "sh4")
11012        (eq_attr "type" "prget"))
11013   "d_lock*2")
11014
11015 ;; STS.L from PR
11016 ;; Group:       CO
11017 ;; Latency:     2
11018 ;; Issue Rate:  2
11019
11020 (define_insn_reservation "sh4_prstore_mem" 2
11021   (and (eq_attr "pipe_model" "sh4")
11022        (eq_attr "type" "pstore"))
11023   "d_lock*2,nothing,memory")
11024
11025 ;; LDS to FPSCR
11026 ;; Group:       CO
11027 ;; Latency:     4
11028 ;; Issue Rate:  1
11029 ;; F1 is blocked for last three cycles.
11030
11031 (define_insn_reservation "fpscr_load" 4
11032   (and (eq_attr "pipe_model" "sh4")
11033        (eq_attr "type" "gp_fpscr"))
11034   "d_lock,nothing,F1*3")
11035
11036 ;; LDS.L to FPSCR
11037 ;; Group:       CO
11038 ;; Latency:     1 / 4
11039 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
11040 ;; Issue Rate:  1
11041 ;; F1 is blocked for last three cycles.
11042
11043 (define_insn_reservation "fpscr_load_mem" 4
11044   (and (eq_attr "pipe_model" "sh4")
11045        (eq_attr "type"  "mem_fpscr"))
11046   "d_lock,nothing,(F1+memory),F1*2")
11047
11048 \f
11049 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11050 ;; Group:       CO
11051 ;; Latency:     4 / 4
11052 ;; Issue Rate:  1
11053
11054 (define_insn_reservation "multi" 4
11055   (and (eq_attr "pipe_model" "sh4")
11056        (eq_attr "type" "smpy,dmpy"))
11057   "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11058
11059 ;; Fixed STS from MACL / MACH
11060 ;; Group:       CO
11061 ;; Latency:     3
11062 ;; Issue Rate:  1
11063
11064 (define_insn_reservation "sh4_mac_gp" 3
11065   (and (eq_attr "pipe_model" "sh4")
11066        (eq_attr "type" "mac_gp"))
11067   "d_lock")
11068
11069
11070 ;; Single precision floating point computation FCMP/EQ,
11071 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11072 ;; Group:       FE
11073 ;; Latency:     3/4
11074 ;; Issue Rate:  1
11075
11076 (define_insn_reservation "fp_arith"  3
11077   (and (eq_attr "pipe_model" "sh4")
11078        (eq_attr "type" "fp"))
11079   "issue,F01,F2")
11080
11081 (define_insn_reservation "fp_arith_ftrc"  3
11082   (and (eq_attr "pipe_model" "sh4")
11083        (eq_attr "type" "ftrc_s"))
11084   "issue,F01,F2")
11085
11086 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11087
11088 ;; Single Precision FDIV/SQRT
11089 ;; Group:       FE
11090 ;; Latency:     12/13 (FDIV); 11/12 (FSQRT)
11091 ;; Issue Rate:  1
11092 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11093
11094 (define_insn_reservation "fp_div" 12
11095   (and (eq_attr "pipe_model" "sh4")
11096        (eq_attr "type" "fdiv"))
11097   "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11098
11099 ;; Double Precision floating point computation
11100 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11101 ;; Group:       FE
11102 ;; Latency:     (3,4)/5
11103 ;; Issue Rate:  1
11104
11105 (define_insn_reservation "dp_float" 4
11106   (and (eq_attr "pipe_model" "sh4")
11107        (eq_attr "type" "dfp_conv"))
11108   "issue,F01,F1+F2,F2")
11109
11110 ;; Double-precision floating-point (FADD,FMUL,FSUB)
11111 ;; Group:       FE
11112 ;; Latency:     (7,8)/9
11113 ;; Issue Rate:  1
11114
11115 (define_insn_reservation "fp_double_arith" 8
11116   (and (eq_attr "pipe_model" "sh4")
11117        (eq_attr "type" "dfp_arith"))
11118   "issue,F01,F1+F2,fpu*4,F2")
11119
11120 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
11121 ;; Group:       CO
11122 ;; Latency:     3/5
11123 ;; Issue Rate:  2
11124
11125 (define_insn_reservation "fp_double_cmp" 3
11126   (and (eq_attr "pipe_model" "sh4")
11127        (eq_attr "type" "dfp_cmp"))
11128   "d_lock,(d_lock+F01),F1+F2,F2")
11129
11130 ;; Double precision FDIV/SQRT
11131 ;; Group:       FE
11132 ;; Latency:     (24,25)/26
11133 ;; Issue Rate:  1
11134
11135 (define_insn_reservation "dp_div" 25
11136   (and (eq_attr "pipe_model" "sh4")
11137        (eq_attr "type" "dfdiv"))
11138   "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11139
11140
11141 ;; Use the branch-not-taken case to model arith3 insns.  For the branch taken
11142 ;; case, we'd get a d_lock instead of issue at the end.
11143 (define_insn_reservation "arith3" 3
11144   (and (eq_attr "pipe_model" "sh4")
11145        (eq_attr "type" "arith3"))
11146   "issue,d_lock+pcr_addrcalc,issue")
11147
11148 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11149 (define_insn_reservation "arith3b" 2
11150   (and (eq_attr "pipe_model" "sh4")
11151        (eq_attr "type" "arith3"))
11152   "issue,d_lock+pcr_addrcalc")