OSDN Git Service

* config.sh/lib1funcs.h (FMOVD_WORKS): Only define if
[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,
3 ;;  2003, 2004, 2005, 2006, 2007, 2008, 2009 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 3, 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 COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
26
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences.  Especially the sequences for arithmetic right shifts.
29
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
31
32 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
33 ;; way to generate them.
34
35 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
36 ;; for a str* inline function.
37
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
41
42 ;; Special constraints for SH machine description:
43 ;;
44 ;;    t -- T
45 ;;    x -- mac
46 ;;    l -- pr
47 ;;    z -- r0
48 ;;
49 ;; Special formats used for outputting SH instructions:
50 ;;
51 ;;   %.  --  print a .s if insn needs delay slot
52 ;;   %@  --  print rte/rts if is/isn't an interrupt function
53 ;;   %#  --  output a nop if there is nothing to put in the delay slot
54 ;;   %O  --  print a constant without the #
55 ;;   %R  --  print the lsw reg of a double
56 ;;   %S  --  print the msw reg of a double
57 ;;   %T  --  print next word of a double REG or MEM
58 ;;
59 ;; Special predicates:
60 ;;
61 ;;  arith_operand          -- operand is valid source for arithmetic op
62 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
63 ;;  general_movdst_operand -- operand is valid move destination
64 ;;  general_movsrc_operand -- operand is valid move source
65 ;;  logical_operand        -- operand is valid source for logical op
66
67 ;; -------------------------------------------------------------------------
68 ;; Constants
69 ;; -------------------------------------------------------------------------
70
71 (define_constants [
72   (AP_REG       145)
73   (PR_REG       146)
74   (T_REG        147)
75   (GBR_REG      144)
76   (MACH_REG     148)
77   (MACL_REG     149)
78   (FPUL_REG     150)
79   (RAP_REG      152)
80
81   (FPSCR_REG    151)
82
83   (PIC_REG      12)
84   (FP_REG       14)
85   (SP_REG       15)
86
87   (PR_MEDIA_REG 18)
88   (T_MEDIA_REG  19)
89
90   (R0_REG       0)
91   (R1_REG       1)
92   (R2_REG       2)
93   (R3_REG       3)
94   (R4_REG       4)
95   (R5_REG       5)
96   (R6_REG       6)
97   (R7_REG       7)
98   (R8_REG       8)
99   (R9_REG       9)
100   (R10_REG      10)
101   (R20_REG      20)
102   (R21_REG      21)
103   (R22_REG      22)
104   (R23_REG      23)
105
106   (DR0_REG      64)
107   (DR2_REG      66)
108   (DR4_REG      68)
109   (FR23_REG     87)
110
111   (TR0_REG      128)
112   (TR1_REG      129)
113   (TR2_REG      130)
114
115   (XD0_REG      136)
116
117   ;; These are used with unspec.
118   (UNSPEC_COMPACT_ARGS  0)
119   (UNSPEC_MOVA          1)
120   (UNSPEC_CASESI        2)
121   (UNSPEC_DATALABEL     3)
122   (UNSPEC_BBR           4)
123   (UNSPEC_SFUNC         5)
124   (UNSPEC_PIC           6)
125   (UNSPEC_GOT           7)
126   (UNSPEC_GOTOFF        8)
127   (UNSPEC_PLT           9)
128   (UNSPEC_CALLER        10)
129   (UNSPEC_GOTPLT        11)
130   (UNSPEC_ICACHE        12)
131   (UNSPEC_INIT_TRAMP    13)
132   (UNSPEC_FCOSA         14)
133   (UNSPEC_FSRRA         15)
134   (UNSPEC_FSINA         16)
135   (UNSPEC_NSB           17)
136   (UNSPEC_ALLOCO        18)
137   (UNSPEC_TLSGD         20)
138   (UNSPEC_TLSLDM        21)
139   (UNSPEC_TLSIE         22)
140   (UNSPEC_DTPOFF        23)
141   (UNSPEC_GOTTPOFF      24)
142   (UNSPEC_TPOFF         25)
143   (UNSPEC_RA            26)
144   (UNSPEC_DIV_INV_M0    30)
145   (UNSPEC_DIV_INV_M1    31)
146   (UNSPEC_DIV_INV_M2    32)
147   (UNSPEC_DIV_INV_M3    33)
148   (UNSPEC_DIV_INV20     34)
149   (UNSPEC_DIV_INV_TABLE 37)
150   (UNSPEC_ASHIFTRT      35)
151   (UNSPEC_THUNK         36)
152   (UNSPEC_SP_SET        40)
153   (UNSPEC_SP_TEST       41)
154   (UNSPEC_MOVUA         42)
155
156   ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
157   ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
158   (UNSPEC_EXTRACT_S16   43)
159   (UNSPEC_EXTRACT_U16   44)
160
161   ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
162   (UNSPEC_SYMOFF        45)
163
164   ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
165   (UNSPEC_PCREL_SYMOFF  46)
166
167   ;; These are used with unspec_volatile.
168   (UNSPECV_BLOCKAGE     0)
169   (UNSPECV_ALIGN        1)
170   (UNSPECV_CONST2       2)
171   (UNSPECV_CONST4       4)
172   (UNSPECV_CONST8       6)
173   (UNSPECV_WINDOW_END   10)
174   (UNSPECV_CONST_END    11)
175   (UNSPECV_EH_RETURN    12)
176 ])
177
178 ;; -------------------------------------------------------------------------
179 ;; Attributes
180 ;; -------------------------------------------------------------------------
181
182 ;; Target CPU.
183
184 (define_attr "cpu"
185  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
186   (const (symbol_ref "sh_cpu_attr")))
187
188 (define_attr "endian" "big,little"
189  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
190                       (const_string "little") (const_string "big"))))
191
192 ;; Indicate if the default fpu mode is single precision.
193 (define_attr "fpu_single" "yes,no"
194   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
195                          (const_string "yes") (const_string "no"))))
196
197 (define_attr "fmovd" "yes,no"
198   (const (if_then_else (symbol_ref "TARGET_FMOVD")
199                        (const_string "yes") (const_string "no"))))
200 ;; pipeline model
201 (define_attr "pipe_model" "sh1,sh4,sh5media"
202   (const
203    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
204           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
205          (const_string "sh1"))))
206
207 ;; cbranch      conditional branch instructions
208 ;; jump         unconditional jumps
209 ;; arith        ordinary arithmetic
210 ;; arith3       a compound insn that behaves similarly to a sequence of
211 ;;              three insns of type arith
212 ;; arith3b      like above, but might end with a redirected branch
213 ;; load         from memory
214 ;; load_si      Likewise, SImode variant for general register.
215 ;; fload        Likewise, but load to fp register.
216 ;; store        to memory
217 ;; fstore       floating point register to memory
218 ;; move         general purpose register to register
219 ;; movi8        8-bit immediate to general purpose register
220 ;; mt_group     other sh4 mt instructions
221 ;; fmove        register to register, floating point
222 ;; smpy         word precision integer multiply
223 ;; dmpy         longword or doublelongword precision integer multiply
224 ;; return       rts
225 ;; pload        load of pr reg, which can't be put into delay slot of rts
226 ;; prset        copy register to pr reg, ditto
227 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
228 ;; prget        copy pr to register, ditto
229 ;; pcload       pc relative load of constant value
230 ;; pcfload      Likewise, but load to fp register.
231 ;; pcload_si    Likewise, SImode variant for general register.
232 ;; rte          return from exception
233 ;; sfunc        special function call with known used registers
234 ;; call         function call
235 ;; fp           floating point
236 ;; fpscr_toggle toggle a bit in the fpscr
237 ;; fdiv         floating point divide (or square root)
238 ;; gp_fpul      move from general purpose register to fpul
239 ;; fpul_gp      move from fpul to general purpose register
240 ;; mac_gp       move from mac[lh] to general purpose register
241 ;; gp_mac       move from general purpose register to mac[lh]
242 ;; mac_mem      move from mac[lh] to memory
243 ;; mem_mac      move from memory to mac[lh]
244 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
245 ;; ftrc_s       fix_truncsfsi2_i4
246 ;; dfdiv        double precision floating point divide (or square root)
247 ;; cwb          ic_invalidate_line_i
248 ;; movua        SH4a unaligned load
249 ;; fsrra        square root reciprocal approximate
250 ;; fsca         sine and cosine approximate
251 ;; tls_load     load TLS related address
252 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
253 ;; cbranch_media SHmedia conditional branch instructions
254 ;; cmp_media    SHmedia compare instructions
255 ;; dfdiv_media  SHmedia double precision divide and square root
256 ;; dfmul_media  SHmedia double precision multiply instruction
257 ;; dfparith_media SHmedia double precision floating point arithmetic
258 ;; dfpconv_media SHmedia double precision floating point conversions
259 ;; dmpy_media   SHmedia longword multiply
260 ;; fcmp_media   SHmedia floating point compare instructions
261 ;; fdiv_media   SHmedia single precision divide and square root
262 ;; fload_media  SHmedia floating point register load instructions
263 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
264 ;; fparith_media SHmedia single precision floating point arithmetic
265 ;; fpconv_media SHmedia single precision floating point conversions
266 ;; fstore_media SHmedia floating point register store instructions
267 ;; gettr_media  SHmedia gettr instruction
268 ;; invalidate_line_media SHmedia invalidate_line sequence
269 ;; jump_media   SHmedia unconditional branch instructions
270 ;; load_media   SHmedia general register load instructions
271 ;; pt_media     SHmedia pt instruction (expanded by assembler)
272 ;; ptabs_media  SHmedia ptabs instruction
273 ;; store_media  SHmedia general register store instructions
274 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
275 ;; mac_media    SHmedia mac-style fixed point operations
276 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
277 ;; atrans_media SHmedia approximate transcendental functions
278 ;; ustore_media SHmedia unaligned stores
279 ;; nil          no-op move, will be deleted.
280
281 (define_attr "type"
282  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
283   (const_string "other"))
284
285 ;; We define a new attribute namely "insn_class".We use
286 ;; this for the DFA based pipeline description.
287 ;;
288 ;; mt_group      SH4 "mt" group instructions.
289 ;;
290 ;; ex_group      SH4 "ex" group instructions.
291 ;;
292 ;; ls_group      SH4 "ls" group instructions.
293 ;;
294
295 (define_attr "insn_class"
296   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
297   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
298          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
299          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
300          (eq_attr "type" "cbranch,jump") (const_string "br_group")
301          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
302            (const_string "fe_group")
303          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
304         (const_string "none")))
305 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
306 ;; so these do not belong in an insn group, although they are modeled
307 ;; with their own define_insn_reservations.
308
309 ;; Indicate what precision must be selected in fpscr for this insn, if any.
310
311 (define_attr "fp_mode" "single,double,none" (const_string "none"))
312
313 ;; Indicate if the fpu mode is set by this instruction
314 ;; "unknown" must have the value as "none" in fp_mode, and means
315 ;; that the instruction/abi has left the processor in an unknown
316 ;; state.
317 ;; "none" means that nothing has changed and no mode is set.
318 ;; This attribute is only used for the Renesas ABI.
319 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
320
321 ; If a conditional branch destination is within -252..258 bytes away
322 ; from the instruction it can be 2 bytes long.  Something in the
323 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
324 ; branches are initially assumed to be 16 bytes long.
325 ; In machine_dependent_reorg, we split all branches that are longer than
326 ; 2 bytes.
327
328 ;; The maximum range used for SImode constant pool entries is 1018.  A final
329 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
330 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
331 ;; instruction around the pool table, 2 bytes of alignment before the table,
332 ;; and 30 bytes of alignment after the table.  That gives a maximum total
333 ;; pool size of 1058 bytes.
334 ;; Worst case code/pool content size ratio is 1:2 (using asms).
335 ;; Thus, in the worst case, there is one instruction in front of a maximum
336 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
337 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
338 ;; If we have a forward branch, the initial table will be put after the
339 ;; unconditional branch.
340 ;;
341 ;; ??? We could do much better by keeping track of the actual pcloads within
342 ;; the branch range and in the pcload range in front of the branch range.
343
344 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
345 ;; inside an le.
346 (define_attr "short_cbranch_p" "no,yes"
347   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
348          (const_string "no")
349          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
350          (const_string "yes")
351          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
352          (const_string "no")
353          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
354          (const_string "yes")
355          ] (const_string "no")))
356
357 (define_attr "med_branch_p" "no,yes"
358   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
359               (const_int 1988))
360          (const_string "yes")
361          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
362          (const_string "no")
363          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
364               (const_int 8186))
365          (const_string "yes")
366          ] (const_string "no")))
367
368 (define_attr "med_cbranch_p" "no,yes"
369   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
370               (const_int 1986))
371          (const_string "yes")
372          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
373          (const_string "no")
374          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
375                (const_int 8184))
376          (const_string "yes")
377          ] (const_string "no")))
378
379 (define_attr "braf_branch_p" "no,yes"
380   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
381          (const_string "no")
382          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
383               (const_int 20660))
384          (const_string "yes")
385          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
386          (const_string "no")
387          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
388               (const_int 65530))
389          (const_string "yes")
390          ] (const_string "no")))
391
392 (define_attr "braf_cbranch_p" "no,yes"
393   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
394          (const_string "no")
395          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
396               (const_int 20658))
397          (const_string "yes")
398          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
399          (const_string "no")
400          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
401               (const_int 65528))
402          (const_string "yes")
403          ] (const_string "no")))
404
405 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
406 ; For wider ranges, we need a combination of a code and a data part.
407 ; If we can get a scratch register for a long range jump, the code
408 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
409 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
410 ; long; otherwise, it must be 6 bytes long.
411
412 ; All other instructions are two bytes long by default.
413
414 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
415 ;; but getattrtab doesn't understand this.
416 (define_attr "length" ""
417   (cond [(eq_attr "type" "cbranch")
418          (cond [(eq_attr "short_cbranch_p" "yes")
419                 (const_int 2)
420                 (eq_attr "med_cbranch_p" "yes")
421                 (const_int 6)
422                 (eq_attr "braf_cbranch_p" "yes")
423                 (const_int 12)
424 ;; ??? using pc is not computed transitively.
425                 (ne (match_dup 0) (match_dup 0))
426                 (const_int 14)
427                 (ne (symbol_ref ("flag_pic")) (const_int 0))
428                 (const_int 24)
429                 ] (const_int 16))
430          (eq_attr "type" "jump")
431          (cond [(eq_attr "med_branch_p" "yes")
432                 (const_int 2)
433                 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
434                          (const_int 0))
435                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
436                               (symbol_ref "INSN"))
437                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
438                               (symbol_ref "code_for_indirect_jump_scratch"))))
439                 (cond [(eq_attr "braf_branch_p" "yes")
440                        (const_int 6)
441                        (eq (symbol_ref "flag_pic") (const_int 0))
442                        (const_int 10)
443                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
444                        (const_int 10)] (const_int 18))
445                 (eq_attr "braf_branch_p" "yes")
446                 (const_int 10)
447 ;; ??? using pc is not computed transitively.
448                 (ne (match_dup 0) (match_dup 0))
449                 (const_int 12)
450                 (ne (symbol_ref ("flag_pic")) (const_int 0))
451                 (const_int 22)
452                 ] (const_int 14))
453          (eq_attr "type" "pt_media")
454          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
455                        (const_int 20) (const_int 12))
456          (and (eq_attr "type" "jump_media")
457               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
458          (const_int 8)
459          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
460                          (const_int 4)
461                          (const_int 2))))
462
463 ;; DFA descriptions for the pipelines
464
465 (include "sh1.md")
466 (include "shmedia.md")
467 (include "sh4.md")
468
469 (include "predicates.md")
470 (include "constraints.md")
471
472 ;; Definitions for filling delay slots
473
474 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
475
476 (define_attr "banked" "yes,no" 
477         (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
478                    (const_int 1))
479                (const_string "yes")]
480               (const_string "no")))
481
482 ;; ??? This should be (nil) instead of (const_int 0)
483 (define_attr "hit_stack" "yes,no"
484         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
485                    (const_int 0))
486                (const_string "no")]
487               (const_string "yes")))
488
489 (define_attr "interrupt_function" "no,yes"
490   (const (symbol_ref "current_function_interrupt")))
491
492 (define_attr "in_delay_slot" "yes,no"
493   (cond [(eq_attr "type" "cbranch") (const_string "no")
494          (eq_attr "type" "pcload,pcload_si") (const_string "no")
495          (eq_attr "needs_delay_slot" "yes") (const_string "no")
496          (eq_attr "length" "2") (const_string "yes")
497          ] (const_string "no")))
498
499 (define_attr "cond_delay_slot" "yes,no"
500   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
501          ] (const_string "no")))
502
503 (define_attr "is_sfunc" ""
504   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
505
506 (define_attr "is_mac_media" ""
507   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
508
509 (define_attr "branch_zero" "yes,no"
510   (cond [(eq_attr "type" "!cbranch") (const_string "no")
511          (ne (symbol_ref "(next_active_insn (insn)\
512                            == (prev_active_insn\
513                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
514                           && get_attr_length (next_active_insn (insn)) == 2")
515              (const_int 0))
516          (const_string "yes")]
517         (const_string "no")))
518
519 ;; SH4 Double-precision computation with double-precision result -
520 ;; the two halves are ready at different times.
521 (define_attr "dfp_comp" "yes,no"
522   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
523         (const_string "no")))
524
525 ;; Insns for which the latency of a preceding fp insn is decreased by one.
526 (define_attr "late_fp_use" "yes,no" (const_string "no"))
527 ;; And feeding insns for which this relevant.
528 (define_attr "any_fp_comp" "yes,no"
529   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
530          (const_string "yes")]
531         (const_string "no")))
532
533 (define_attr "any_int_load" "yes,no"
534   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
535          (const_string "yes")]
536         (const_string "no")))
537
538 (define_attr "highpart" "user, ignore, extend, depend, must_split"
539   (const_string "user"))
540
541 (define_delay
542   (eq_attr "needs_delay_slot" "yes")
543   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
544
545 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
546 ;; and thus we can't put a pop instruction in its delay slot.
547 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
548 ;; instruction can go in the delay slot.
549
550 ;; Since a normal return (rts) implicitly uses the PR register,
551 ;; we can't allow PR register loads in an rts delay slot.
552
553 (define_delay
554   (eq_attr "type" "return")
555   [(and (eq_attr "in_delay_slot" "yes")
556         (ior (and (eq_attr "interrupt_function" "no")
557                   (eq_attr "type" "!pload,prset"))
558              (and (eq_attr "interrupt_function" "yes")
559                   (ior
560                    (eq (symbol_ref "TARGET_SH3") (const_int 0))
561                    (eq_attr "hit_stack" "no")
562                    (eq_attr "banked" "no"))))) (nil) (nil)])
563
564 ;; Since a call implicitly uses the PR register, we can't allow
565 ;; a PR register store in a jsr delay slot.
566
567 (define_delay
568   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
569   [(and (eq_attr "in_delay_slot" "yes")
570         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
571
572 ;; Say that we have annulled true branches, since this gives smaller and
573 ;; faster code when branches are predicted as not taken.
574
575 ;; ??? The non-annulled condition should really be "in_delay_slot",
576 ;; but insns that can be filled in non-annulled get priority over insns
577 ;; that can only be filled in anulled.
578
579 (define_delay
580   (and (eq_attr "type" "cbranch")
581        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
582   ;; SH2e has a hardware bug that pretty much prohibits the use of
583   ;; annuled delay slots.
584   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
585                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
586 \f
587 ;; -------------------------------------------------------------------------
588 ;; SImode signed integer comparisons
589 ;; -------------------------------------------------------------------------
590
591 (define_insn ""
592   [(set (reg:SI T_REG)
593         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
594                        (match_operand:SI 1 "arith_operand" "K08,r"))
595                (const_int 0)))]
596   "TARGET_SH1"
597   "tst  %1,%0"
598   [(set_attr "type" "mt_group")])
599
600 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
601 ;; That would still allow reload to create cmpi instructions, but would
602 ;; perhaps allow forcing the constant into a register when that is better.
603 ;; Probably should use r0 for mem/imm compares, but force constant into a
604 ;; register for pseudo/imm compares.
605
606 (define_insn "cmpeqsi_t"
607   [(set (reg:SI T_REG)
608         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
609                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
610   "TARGET_SH1"
611   "@
612         tst     %0,%0
613         cmp/eq  %1,%0
614         cmp/eq  %1,%0"
615    [(set_attr "type" "mt_group")])
616
617 (define_insn "cmpgtsi_t"
618   [(set (reg:SI T_REG)
619         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
620                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
621   "TARGET_SH1"
622   "@
623         cmp/gt  %1,%0
624         cmp/pl  %0"
625    [(set_attr "type" "mt_group")])
626
627 (define_insn "cmpgesi_t"
628   [(set (reg:SI T_REG)
629         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
630                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
631   "TARGET_SH1"
632   "@
633         cmp/ge  %1,%0
634         cmp/pz  %0"
635    [(set_attr "type" "mt_group")])
636
637 ;; -------------------------------------------------------------------------
638 ;; SImode compare and branch
639 ;; -------------------------------------------------------------------------
640
641 (define_expand "cbranchsi4"
642   [(set (pc)
643         (if_then_else (match_operator 0 "comparison_operator"
644                         [(match_operand:SI 1 "arith_operand" "")
645                          (match_operand:SI 2 "arith_operand" "")])
646                       (label_ref (match_operand 3 "" ""))
647                       (pc)))
648    (clobber (reg:SI T_REG))]
649   ""
650   "if (TARGET_SHMEDIA)
651       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
652                                              operands[2], operands[3]));
653    else if (TARGET_CBRANCHDI4)
654      expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
655    else
656      sh_emit_compare_and_branch (operands, SImode);
657    DONE;")
658
659 ;; -------------------------------------------------------------------------
660 ;; SImode unsigned integer comparisons
661 ;; -------------------------------------------------------------------------
662
663 (define_insn_and_split "cmpgeusi_t"
664   [(set (reg:SI T_REG)
665         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
666                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
667   "TARGET_SH1"
668   "cmp/hs       %1,%0"
669   "&& operands[1] == CONST0_RTX (SImode)"
670   [(pc)]
671   "
672 {
673   emit_insn (gen_sett ());
674   DONE;
675 }"
676    [(set_attr "type" "mt_group")])
677
678 (define_insn "cmpgtusi_t"
679   [(set (reg:SI T_REG)
680         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
681                 (match_operand:SI 1 "arith_reg_operand" "r")))]
682   "TARGET_SH1"
683   "cmp/hi       %1,%0"
684    [(set_attr "type" "mt_group")])
685
686 \f
687 ;; -------------------------------------------------------------------------
688 ;; DImode compare and branch
689 ;; -------------------------------------------------------------------------
690
691
692 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
693 ;; Therefore, we aim to have a set of three branches that go straight to the
694 ;; destination, i.e. only one of them is taken at any one time.
695 ;; This mechanism should also be slightly better for the sh4-200.
696
697 (define_expand "cbranchdi4"
698   [(set (pc)
699         (if_then_else (match_operator 0 "comparison_operator"
700                         [(match_operand:DI 1 "arith_operand" "")
701                          (match_operand:DI 2 "arith_operand" "")])
702                       (label_ref (match_operand 3 "" ""))
703                       (pc)))
704    (clobber (match_dup 4))
705    (clobber (reg:SI T_REG))]
706   "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
707   "
708 {
709   enum rtx_code comparison;
710
711   if (TARGET_SHMEDIA)
712     {
713       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
714                                              operands[2], operands[3]));
715       DONE;
716     }
717
718   else if (!TARGET_CBRANCHDI4)
719     {
720       sh_emit_compare_and_branch (operands, DImode);
721       DONE;
722     }
723
724   else
725     {
726       if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
727         DONE;
728
729       comparison = prepare_cbranch_operands (operands, DImode,
730                                              LAST_AND_UNUSED_RTX_CODE);
731       if (comparison != GET_CODE (operands[0]))
732         operands[0]
733           = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
734        operands[4] = gen_rtx_SCRATCH (SImode);
735     }
736 }")
737
738 (define_insn_and_split "cbranchdi4_i"
739   [(set (pc)
740         (if_then_else (match_operator 0 "comparison_operator"
741                         [(match_operand:DI 1 "arith_operand" "r,r")
742                          (match_operand:DI 2 "arith_operand" "rN,I08")])
743                       (label_ref (match_operand 3 "" ""))
744                       (pc)))
745    (clobber (match_scratch:SI 4 "=X,&r"))
746    (clobber (reg:SI T_REG))]
747   "TARGET_CBRANCHDI4"
748   "#"
749   "&& reload_completed"
750   [(pc)]
751   "
752 {
753   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
754     FAIL;
755   DONE;
756 }")
757
758 ;; -------------------------------------------------------------------------
759 ;; DImode signed integer comparisons
760 ;; -------------------------------------------------------------------------
761
762 (define_insn ""
763   [(set (reg:SI T_REG)
764         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
765                        (match_operand:DI 1 "arith_operand" "r"))
766                (const_int 0)))]
767   "TARGET_SH1"
768   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
769                                  insn, operands);"
770   [(set_attr "length" "6")
771    (set_attr "type" "arith3b")])
772
773 (define_insn "cmpeqdi_t"
774   [(set (reg:SI T_REG)
775         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
776                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
777   "TARGET_SH1"
778   "@
779         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
780         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
781   [(set_attr "length" "6")
782    (set_attr "type" "arith3b")])
783
784 (define_split
785   [(set (reg:SI T_REG)
786         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
787                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
788 ;; If we applied this split when not optimizing, it would only be
789 ;; applied during the machine-dependent reorg, when no new basic blocks
790 ;; may be created.
791   "TARGET_SH1 && reload_completed && optimize"
792   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
793    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
794                            (label_ref (match_dup 6))
795                            (pc)))
796    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
797    (match_dup 6)]
798   "
799 {
800   operands[2]
801     = gen_rtx_REG (SImode,
802                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
803   operands[3]
804     = (operands[1] == const0_rtx
805        ? const0_rtx
806        : gen_rtx_REG (SImode,
807                       true_regnum (operands[1])
808                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
809   operands[4] = gen_lowpart (SImode, operands[0]);
810   operands[5] = gen_lowpart (SImode, operands[1]);
811   operands[6] = gen_label_rtx ();
812 }")
813
814 (define_insn "cmpgtdi_t"
815   [(set (reg:SI T_REG)
816         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
817                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
818   "TARGET_SH2"
819   "@
820         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
821         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
822   [(set_attr "length" "8")
823    (set_attr "type" "arith3")])
824
825 (define_insn "cmpgedi_t"
826   [(set (reg:SI T_REG)
827         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
828                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
829   "TARGET_SH2"
830   "@
831         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
832         cmp/pz\\t%S0"
833   [(set_attr "length" "8,2")
834    (set_attr "type" "arith3,mt_group")])
835 \f
836 ;; -------------------------------------------------------------------------
837 ;; DImode unsigned integer comparisons
838 ;; -------------------------------------------------------------------------
839
840 (define_insn "cmpgeudi_t"
841   [(set (reg:SI T_REG)
842         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
843                 (match_operand:DI 1 "arith_reg_operand" "r")))]
844   "TARGET_SH2"
845   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
846   [(set_attr "length" "8")
847    (set_attr "type" "arith3")])
848
849 (define_insn "cmpgtudi_t"
850   [(set (reg:SI T_REG)
851         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
852                 (match_operand:DI 1 "arith_reg_operand" "r")))]
853   "TARGET_SH2"
854   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
855   [(set_attr "length" "8")
856    (set_attr "type" "arith3")])
857
858 (define_insn "cmpeqsi_media"
859   [(set (match_operand:SI 0 "register_operand" "=r")
860         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
861                (match_operand:SI 2 "cmp_operand" "Nr")))]
862   "TARGET_SHMEDIA"
863   "cmpeq        %1, %N2, %0"
864   [(set_attr "type" "cmp_media")])
865
866 (define_insn "cmpeqdi_media"
867   [(set (match_operand:SI 0 "register_operand" "=r")
868         (eq:SI (match_operand:DI 1 "register_operand" "%r")
869                (match_operand:DI 2 "cmp_operand" "Nr")))]
870   "TARGET_SHMEDIA"
871   "cmpeq        %1, %N2, %0"
872   [(set_attr "type" "cmp_media")])
873
874 (define_insn "cmpgtsi_media"
875   [(set (match_operand:SI 0 "register_operand" "=r")
876         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
877                (match_operand:SI 2 "cmp_operand" "rN")))]
878   "TARGET_SHMEDIA"
879   "cmpgt        %N1, %N2, %0"
880   [(set_attr "type" "cmp_media")])
881
882 (define_insn "cmpgtdi_media"
883   [(set (match_operand:SI 0 "register_operand" "=r")
884         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
886   "TARGET_SHMEDIA"
887   "cmpgt        %N1, %N2, %0"
888   [(set_attr "type" "cmp_media")])
889
890 (define_insn "cmpgtusi_media"
891   [(set (match_operand:SI 0 "register_operand" "=r")
892         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
893                 (match_operand:SI 2 "cmp_operand" "rN")))]
894   "TARGET_SHMEDIA"
895   "cmpgtu       %N1, %N2, %0"
896   [(set_attr "type" "cmp_media")])
897
898 (define_insn "cmpgtudi_media"
899   [(set (match_operand:SI 0 "register_operand" "=r")
900         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
901                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
902   "TARGET_SHMEDIA"
903   "cmpgtu       %N1, %N2, %0"
904   [(set_attr "type" "cmp_media")])
905
906 ; These two patterns are for combine.
907 (define_insn "*cmpne0sisi_media"
908   [(set (match_operand:SI 0 "register_operand" "=r")
909         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
910   "TARGET_SHMEDIA"
911   "cmpgtu       %1,r63,%0"
912   [(set_attr "type" "cmp_media")])
913
914 ;; -------------------------------------------------------------------------
915 ;; Conditional move instructions
916 ;; -------------------------------------------------------------------------
917
918 ;; The insn names may seem reversed, but note that cmveq performs the move
919 ;; if op1 == 0, and cmvne does it if op1 != 0.
920
921 (define_insn "movdicc_false"
922   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
923         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
924                              (const_int 0))
925          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
926          (match_operand:DI 3 "arith_reg_operand" "0")))]
927   "TARGET_SHMEDIA"
928   "cmveq        %1, %N2, %0"
929   [(set_attr "type" "arith_media")])
930
931 (define_insn "movdicc_true"
932   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
933         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
934                              (const_int 0))
935          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
936          (match_operand:DI 3 "arith_reg_operand" "0")))]
937   "TARGET_SHMEDIA"
938   "cmvne        %1, %N2, %0"
939   [(set_attr "type" "arith_media")])
940
941 (define_peephole2
942   [(set (match_operand:DI 0 "arith_reg_dest" "")
943         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
944                            [(match_operand:DI 1 "arith_reg_operand" "")
945                             (const_int 0)])
946          (match_operand:DI 2 "arith_reg_dest" "")
947          (match_dup 0)))
948    (set (match_dup 2) (match_dup 0))]
949   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
950   [(set (match_dup 2)
951         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
952   "
953 {
954   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
955                                 VOIDmode, operands[1], CONST0_RTX (DImode));
956 }")
957
958 (define_peephole2
959   [(set (match_operand:DI 0 "general_movdst_operand" "")
960         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
961    (set (match_operand:DI 2 "arith_reg_dest" "")
962         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
963                            [(match_operand:DI 3 "arith_reg_operand" "")
964                             (const_int 0)])
965          (match_dup 0)
966          (match_dup 2)))]
967   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
968   [(set (match_dup 2)
969         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
970   "")
971
972 (define_expand "movdicc"
973   [(set (match_operand:DI 0 "register_operand" "")
974         (if_then_else:DI (match_operand 1 "comparison_operator" "")
975                          (match_operand:DI 2 "register_operand" "")
976                          (match_operand:DI 3 "register_operand" "")))]
977   "TARGET_SHMEDIA"
978   "
979 {
980   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
981       && GET_MODE (XEXP (operands[1], 0)) == DImode
982       && XEXP (operands[1], 1) == const0_rtx)
983     ;
984   else
985     {
986       if (!can_create_pseudo_p ())
987         FAIL;
988
989       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
990                                               GET_CODE (operands[1]),
991                                               XEXP (operands[1], 0),
992                                               XEXP (operands[1], 1));
993       if (!operands[1])
994         FAIL;
995     }
996 }")
997
998 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
999 ;; SImode to DImode.
1000 (define_insn "movsicc_false"
1001   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1002         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1003                           (const_int 0))
1004          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1005          (match_operand:SI 3 "arith_reg_operand" "0")))]
1006   "TARGET_SHMEDIA"
1007   "cmveq        %1, %N2, %0"
1008   [(set_attr "type" "arith_media")])
1009
1010 (define_insn "movsicc_true"
1011   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1012         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1013                           (const_int 0))
1014          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1015          (match_operand:SI 3 "arith_reg_operand" "0")))]
1016   "TARGET_SHMEDIA"
1017   "cmvne        %1, %N2, %0"
1018   [(set_attr "type" "arith_media")])
1019
1020 (define_peephole2
1021   [(set (match_operand:SI 0 "arith_reg_dest" "")
1022         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1023                            [(match_operand:SI 1 "arith_reg_operand" "")
1024                             (const_int 0)])
1025          (match_operand:SI 2 "arith_reg_dest" "")
1026          (match_dup 0)))
1027    (set (match_dup 2) (match_dup 0))]
1028   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1029   [(set (match_dup 2)
1030         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1031   "
1032 {
1033   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1034                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1035 }")
1036
1037 (define_peephole2
1038   [(set (match_operand:SI 0 "general_movdst_operand" "")
1039         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1040    (set (match_operand:SI 2 "arith_reg_dest" "")
1041         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1042                            [(match_operand:SI 3 "arith_reg_operand" "")
1043                             (const_int 0)])
1044          (match_dup 0)
1045          (match_dup 2)))]
1046   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1047    && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1048   [(set (match_dup 2)
1049         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1050   "
1051 {
1052   replace_rtx (operands[4], operands[0], operands[1]);
1053 }")
1054
1055 (define_peephole2
1056   [(set (match_operand 0 "any_register_operand" "")
1057         (match_operand 1 "any_register_operand" ""))
1058    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1059    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1060   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1061     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1062    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1063    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1064    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1065    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1066    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1067    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1068    && (REGNO_REG_CLASS (REGNO (operands[0]))
1069        == REGNO_REG_CLASS (REGNO (operands[2])))
1070    && (REGNO_REG_CLASS (REGNO (operands[1]))
1071        == REGNO_REG_CLASS (REGNO (operands[0])))"
1072   [(set (match_dup 0) (match_dup 3))
1073    (set (match_dup 4) (match_dup 5))]
1074   "
1075 {
1076   rtx set1, set2, insn2;
1077   rtx replacements[4];
1078
1079   /* We want to replace occurrences of operands[0] with operands[1] and
1080      operands[2] with operands[0] in operands[4]/operands[5].
1081      Doing just two replace_rtx calls naively would result in the second
1082      replacement undoing all that the first did if operands[1] and operands[2]
1083      are identical, so we must do this simultaneously.  */
1084   replacements[0] = operands[0];
1085   replacements[1] = operands[1];
1086   replacements[2] = operands[2];
1087   replacements[3] = operands[0];
1088   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1089       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1090       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1091     FAIL;
1092
1093   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1094   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1095   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1096   /* The operands array is aliased to recog_data.operand, which gets
1097      clobbered by extract_insn, so finish with it now.  */
1098   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1099   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1100   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1101      always uses emit_insn.  */
1102   /* Check that we don't violate matching constraints or earlyclobbers.  */
1103   extract_insn (emit_insn (set1));
1104   if (! constrain_operands (1))
1105     goto failure;
1106   insn2 = emit (set2);
1107   if (GET_CODE (insn2) == BARRIER)
1108     goto failure;
1109   extract_insn (insn2);
1110   if (! constrain_operands (1))
1111     {
1112       rtx tmp;
1113     failure:
1114       tmp = replacements[0];
1115       replacements[0] = replacements[1];
1116       replacements[1] = tmp;
1117       tmp = replacements[2];
1118       replacements[2] = replacements[3];
1119       replacements[3] = tmp;
1120       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1121       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1122       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1123       FAIL;
1124     }
1125   DONE;
1126 }")
1127
1128 ;; The register allocator is rather clumsy in handling multi-way conditional
1129 ;; moves, so allow the combiner to make them, and we split them up after
1130 ;; reload.  */
1131 (define_insn_and_split "*movsicc_umin"
1132   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1133         (umin:SI (if_then_else:SI
1134                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1135                        (const_int 0))
1136                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1137                    (match_operand:SI 3 "register_operand" "0"))
1138                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1139    (clobber (match_scratch:SI 5 "=&r"))]
1140   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1141   "#"
1142   "TARGET_SHMEDIA && reload_completed"
1143   [(pc)]
1144   "
1145 {
1146   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1147                                 operands[3]));
1148   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1149   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1150                                 operands[0]));
1151   DONE;
1152 }")
1153
1154 (define_insn "*movsicc_t_false"
1155   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1156         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1157                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1158                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1159   "TARGET_PRETEND_CMOVE
1160    && (arith_reg_operand (operands[1], SImode)
1161        || (immediate_operand (operands[1], SImode)
1162            && satisfies_constraint_I08 (operands[1])))"
1163   "bt 0f\;mov %1,%0\\n0:"
1164   [(set_attr "type" "mt_group,arith") ;; poor approximation
1165    (set_attr "length" "4")])
1166
1167 (define_insn "*movsicc_t_true"
1168   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1169         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1170                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1171                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1172   "TARGET_PRETEND_CMOVE
1173    && (arith_reg_operand (operands[1], SImode)
1174        || (immediate_operand (operands[1], SImode)
1175            && satisfies_constraint_I08 (operands[1])))"
1176   "bf 0f\;mov %1,%0\\n0:"
1177   [(set_attr "type" "mt_group,arith") ;; poor approximation
1178    (set_attr "length" "4")])
1179
1180 (define_expand "movsicc"
1181   [(set (match_operand:SI 0 "arith_reg_dest" "")
1182         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1183                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1184                          (match_operand:SI 3 "arith_reg_operand" "")))]
1185   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1186   "
1187 {
1188   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1189       && GET_MODE (XEXP (operands[1], 0)) == SImode
1190       && (TARGET_SHMEDIA
1191           || (REG_P (XEXP (operands[1], 0))
1192               && REGNO (XEXP (operands[1], 0)) == T_REG))
1193       && XEXP (operands[1], 1) == const0_rtx)
1194     ;
1195
1196   else if (TARGET_PRETEND_CMOVE)
1197     {
1198       enum rtx_code code = GET_CODE (operands[1]);
1199       enum rtx_code new_code = code;
1200       rtx op0 = XEXP (operands[1], 0);
1201       rtx op1 = XEXP (operands[1], 1);
1202
1203       if (! currently_expanding_to_rtl)
1204         FAIL;
1205       switch (code)
1206         {
1207         case LT: case LE: case LEU: case LTU:
1208           if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1209             break;
1210         case NE:
1211           new_code = reverse_condition (code);
1212           break;
1213         case EQ: case GT: case GE: case GEU: case GTU:
1214           break;
1215         default:
1216           FAIL;
1217         }
1218       sh_emit_scc_to_t (new_code, op0, op1);
1219       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1220                                     gen_rtx_REG (SImode, T_REG), const0_rtx);
1221     }
1222   else
1223     {
1224       if (!can_create_pseudo_p ())
1225         FAIL;
1226
1227       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1228                                               GET_CODE (operands[1]),
1229                                               XEXP (operands[1], 0),
1230                                               XEXP (operands[1], 1));
1231       if (!operands[1])
1232         FAIL;
1233     }
1234 }")
1235
1236 (define_expand "movqicc"
1237   [(set (match_operand:QI 0 "register_operand" "")
1238         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1239                          (match_operand:QI 2 "register_operand" "")
1240                          (match_operand:QI 3 "register_operand" "")))]
1241   "TARGET_SHMEDIA"
1242   "
1243 {
1244   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1245   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1246   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1247   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1248   DONE;
1249 }")
1250 \f
1251 ;; -------------------------------------------------------------------------
1252 ;; Addition instructions
1253 ;; -------------------------------------------------------------------------
1254
1255 (define_expand "adddi3"
1256   [(set (match_operand:DI 0 "arith_reg_operand" "")
1257         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1258                  (match_operand:DI 2 "arith_operand" "")))]
1259   ""
1260   "
1261 {
1262   if (TARGET_SH1)
1263     {
1264       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1265         FAIL;
1266       operands[2] = force_reg (DImode, operands[2]);
1267       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1268       DONE;
1269     }
1270 }")
1271
1272 (define_insn "*adddi3_media"
1273   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1274         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1275                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1276   "TARGET_SHMEDIA"
1277   "@
1278         add     %1, %2, %0
1279         addi    %1, %2, %0"
1280   [(set_attr "type" "arith_media")])
1281
1282 (define_insn "*adddisi3_media"
1283   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1284         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1285                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1286   "TARGET_SHMEDIA"
1287   "@
1288         add.l   %1, %2, %0
1289         addi.l  %1, %2, %0"
1290   [(set_attr "type" "arith_media")
1291    (set_attr "highpart" "ignore")])
1292
1293 (define_insn "adddi3z_media"
1294   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1295         (zero_extend:DI
1296          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1297                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1298   "TARGET_SHMEDIA"
1299   "addz.l       %1, %N2, %0"
1300   [(set_attr "type" "arith_media")
1301    (set_attr "highpart" "ignore")])
1302
1303 (define_insn "adddi3_compact"
1304   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1305         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1306                  (match_operand:DI 2 "arith_reg_operand" "r")))
1307    (clobber (reg:SI T_REG))]
1308   "TARGET_SH1"
1309   "#"
1310   [(set_attr "length" "6")])
1311
1312 (define_split
1313   [(set (match_operand:DI 0 "arith_reg_dest" "")
1314         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1315                  (match_operand:DI 2 "arith_reg_operand" "")))
1316    (clobber (reg:SI T_REG))]
1317   "TARGET_SH1 && reload_completed"
1318   [(const_int 0)]
1319   "
1320 {
1321   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1322   high0 = gen_rtx_REG (SImode,
1323                        true_regnum (operands[0])
1324                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1325   high2 = gen_rtx_REG (SImode,
1326                        true_regnum (operands[2])
1327                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1328   emit_insn (gen_clrt ());
1329   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1330   emit_insn (gen_addc1 (high0, high0, high2));
1331   DONE;
1332 }")
1333
1334 (define_insn "addc"
1335   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1336         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1337                           (match_operand:SI 2 "arith_reg_operand" "r"))
1338                  (reg:SI T_REG)))
1339    (set (reg:SI T_REG)
1340         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1341   "TARGET_SH1"
1342   "addc %2,%0"
1343   [(set_attr "type" "arith")])
1344
1345 (define_insn "addc1"
1346   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1347         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1348                           (match_operand:SI 2 "arith_reg_operand" "r"))
1349                  (reg:SI T_REG)))
1350    (clobber (reg:SI T_REG))]
1351   "TARGET_SH1"
1352   "addc %2,%0"
1353   [(set_attr "type" "arith")])
1354
1355 (define_expand "addsi3"
1356   [(set (match_operand:SI 0 "arith_reg_operand" "")
1357         (plus:SI (match_operand:SI 1 "arith_operand" "")
1358                  (match_operand:SI 2 "arith_operand" "")))]
1359   ""
1360   "
1361 {
1362   if (TARGET_SHMEDIA)
1363     operands[1] = force_reg (SImode, operands[1]);
1364 }")
1365
1366 (define_insn "addsi3_media"
1367   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1368         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1369                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1370   "TARGET_SHMEDIA"
1371   "@
1372         add.l   %1, %2, %0
1373         addi.l  %1, %2, %0"
1374   [(set_attr "type" "arith_media")
1375    (set_attr "highpart" "ignore")])
1376
1377 (define_insn "addsidi3_media"
1378   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1379         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1380                                   "%r,r")
1381                                  (match_operand:SI 2 "arith_operand"
1382                                   "r,I10"))))]
1383   "TARGET_SHMEDIA"
1384   "@
1385         add.l   %1, %2, %0
1386         addi.l  %1, %2, %0"
1387   [(set_attr "type" "arith_media")
1388    (set_attr "highpart" "ignore")])
1389
1390 (define_insn "*addsi3_compact"
1391   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1392         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1393                  (match_operand:SI 2 "arith_operand" "rI08")))]
1394   "TARGET_SH1"
1395   "add  %2,%0"
1396   [(set_attr "type" "arith")])
1397
1398 ;; -------------------------------------------------------------------------
1399 ;; Subtraction instructions
1400 ;; -------------------------------------------------------------------------
1401
1402 (define_expand "subdi3"
1403   [(set (match_operand:DI 0 "arith_reg_operand" "")
1404         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1405                   (match_operand:DI 2 "arith_reg_operand" "")))]
1406   ""
1407   "
1408 {
1409   if (TARGET_SH1)
1410     {
1411       operands[1] = force_reg (DImode, operands[1]);
1412       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1413       DONE;
1414     }
1415 }")
1416
1417 (define_insn "*subdi3_media"
1418   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1419         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1420                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1421   "TARGET_SHMEDIA"
1422   "sub  %N1, %2, %0"
1423   [(set_attr "type" "arith_media")])
1424   
1425 (define_insn "subdisi3_media"
1426   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1427         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1428                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1429   "TARGET_SHMEDIA"
1430   "sub.l        %N1, %2, %0"
1431   [(set_attr "type" "arith_media")
1432    (set_attr "highpart" "ignore")])
1433
1434 (define_insn "subdi3_compact"
1435   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1436         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1437                  (match_operand:DI 2 "arith_reg_operand" "r")))
1438    (clobber (reg:SI T_REG))]
1439   "TARGET_SH1"
1440   "#"
1441   [(set_attr "length" "6")])
1442
1443 (define_split
1444   [(set (match_operand:DI 0 "arith_reg_dest" "")
1445         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1446                   (match_operand:DI 2 "arith_reg_operand" "")))
1447    (clobber (reg:SI T_REG))]
1448   "TARGET_SH1 && reload_completed"
1449   [(const_int 0)]
1450   "
1451 {
1452   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1453   high0 = gen_rtx_REG (SImode,
1454                        true_regnum (operands[0])
1455                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1456   high2 = gen_rtx_REG (SImode,
1457                        true_regnum (operands[2])
1458                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1459   emit_insn (gen_clrt ());
1460   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1461   emit_insn (gen_subc1 (high0, high0, high2));
1462   DONE;
1463 }")
1464
1465 (define_insn "subc"
1466   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1467         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1468                             (match_operand:SI 2 "arith_reg_operand" "r"))
1469                   (reg:SI T_REG)))
1470    (set (reg:SI T_REG)
1471         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1472                           (reg:SI T_REG))
1473                 (match_dup 1)))]
1474   "TARGET_SH1"
1475   "subc %2,%0"
1476   [(set_attr "type" "arith")])
1477
1478 (define_insn "subc1"
1479   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1480         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1481                             (match_operand:SI 2 "arith_reg_operand" "r"))
1482                   (reg:SI T_REG)))
1483    (clobber (reg:SI T_REG))]
1484   "TARGET_SH1"
1485   "subc %2,%0"
1486   [(set_attr "type" "arith")])
1487
1488 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1489 ;; pattern for this case.  This helps multimedia applications that compute
1490 ;; the sum of absolute differences.
1491 (define_insn "mov_neg_si_t"
1492   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1493   "TARGET_SH1"
1494   "subc %0,%0"
1495   [(set_attr "type" "arith")])
1496
1497 (define_insn "*subsi3_internal"
1498   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1499         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1500                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1501   "TARGET_SH1"
1502   "sub  %2,%0"
1503   [(set_attr "type" "arith")])
1504
1505 (define_insn_and_split "*subsi3_media"
1506   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1507         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1508                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1509   "TARGET_SHMEDIA
1510    && (operands[1] != constm1_rtx
1511        || (GET_CODE (operands[2]) != TRUNCATE
1512            && GET_CODE (operands[2]) != SUBREG))"
1513   "sub.l        %N1, %2, %0"
1514   "operands[1] == constm1_rtx"
1515   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1516   ""
1517   [(set_attr "type" "arith_media")
1518    (set_attr "highpart" "ignore")])
1519
1520 (define_split
1521   [(set (match_operand:SI 0 "arith_reg_dest" "")
1522         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1523                                                        "general_extend_operand"
1524                                                        "") 0)) 0)))]
1525   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1526   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1527    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1528   "")
1529
1530 (define_split
1531   [(set (match_operand:SI 0 "arith_reg_dest" "")
1532         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1533                                                        "general_extend_operand"
1534                                                        "") 0)) 3)))]
1535   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1536   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1537    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1538   "")
1539 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1540 ;; will sometimes save one instruction.  Otherwise we might get
1541 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1542 ;; are the same.
1543
1544 (define_expand "subsi3"
1545   [(set (match_operand:SI 0 "arith_reg_operand" "")
1546         (minus:SI (match_operand:SI 1 "arith_operand" "")
1547                   (match_operand:SI 2 "arith_reg_operand" "")))]
1548   ""
1549   "
1550 {
1551   if (TARGET_SH1 && CONST_INT_P (operands[1]))
1552     {
1553       emit_insn (gen_negsi2 (operands[0], operands[2]));
1554       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1555       DONE;
1556     }
1557   if (TARGET_SHMEDIA)
1558     {
1559       if (!can_create_pseudo_p ()
1560           && ! arith_reg_or_0_operand (operands[1], SImode))
1561         FAIL;
1562       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1563         operands[1] = force_reg (SImode, operands[1]);
1564     }
1565 }")
1566 \f
1567 ;; -------------------------------------------------------------------------
1568 ;; Division instructions
1569 ;; -------------------------------------------------------------------------
1570
1571 ;; We take advantage of the library routines which don't clobber as many
1572 ;; registers as a normal function call would.
1573
1574 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1575 ;; also has an effect on the register that holds the address of the sfunc.
1576 ;; To make this work, we have an extra dummy insn that shows the use
1577 ;; of this register for reorg.
1578
1579 (define_insn "use_sfunc_addr"
1580   [(set (reg:SI PR_REG)
1581         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1582   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1583   ""
1584   [(set_attr "length" "0")])
1585
1586 (define_insn "udivsi3_sh2a"
1587   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1588         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1589                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1590   "TARGET_SH2A"
1591   "divu %2,%1"
1592   [(set_attr "type" "arith")
1593    (set_attr "in_delay_slot" "no")])
1594
1595 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1596 ;; hard register 0.  If we used hard register 0, then the next instruction
1597 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1598 ;; gets allocated to a stack slot that needs its address reloaded, then
1599 ;; there is nothing to prevent reload from using r0 to reload the address.
1600 ;; This reload would clobber the value in r0 we are trying to store.
1601 ;; If we let reload allocate r0, then this problem can never happen.
1602
1603 (define_insn "udivsi3_i1"
1604   [(set (match_operand:SI 0 "register_operand" "=z")
1605         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1606    (clobber (reg:SI T_REG))
1607    (clobber (reg:SI PR_REG))
1608    (clobber (reg:SI R4_REG))
1609    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1610   "TARGET_SH1 && ! TARGET_SH4"
1611   "jsr  @%1%#"
1612   [(set_attr "type" "sfunc")
1613    (set_attr "needs_delay_slot" "yes")])
1614
1615 ; Since shmedia-nofpu code could be linked against shcompact code, and
1616 ; the udivsi3 libcall has the same name, we must consider all registers
1617 ; clobbered that are in the union of the registers clobbered by the
1618 ; shmedia and the shcompact implementation.  Note, if the shcompact
1619 ; implementation actually used shcompact code, we'd need to clobber
1620 ; also r23 and fr23.
1621 (define_insn "udivsi3_i1_media"
1622   [(set (match_operand:SI 0 "register_operand" "=z")
1623         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1624    (clobber (reg:SI T_MEDIA_REG))
1625    (clobber (reg:SI PR_MEDIA_REG))
1626    (clobber (reg:SI R20_REG))
1627    (clobber (reg:SI R21_REG))
1628    (clobber (reg:SI R22_REG))
1629    (clobber (reg:DI TR0_REG))
1630    (clobber (reg:DI TR1_REG))
1631    (clobber (reg:DI TR2_REG))
1632    (use (match_operand 1 "target_reg_operand" "b"))]
1633   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1634   "blink        %1, r18"
1635   [(set_attr "type" "sfunc")
1636    (set_attr "needs_delay_slot" "yes")])
1637
1638 (define_expand "udivsi3_i4_media"
1639   [(set (match_dup 3)
1640         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1641    (set (match_dup 4)
1642         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1643    (set (match_dup 5) (float:DF (match_dup 3)))
1644    (set (match_dup 6) (float:DF (match_dup 4)))
1645    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1646    (set (match_dup 8) (fix:DI (match_dup 7)))
1647    (set (match_operand:SI 0 "register_operand" "")
1648         (truncate:SI (match_dup 8)))]
1649   "TARGET_SHMEDIA_FPU"
1650   "
1651 {
1652   operands[3] = gen_reg_rtx (DImode);
1653   operands[4] = gen_reg_rtx (DImode);
1654   operands[5] = gen_reg_rtx (DFmode);
1655   operands[6] = gen_reg_rtx (DFmode);
1656   operands[7] = gen_reg_rtx (DFmode);
1657   operands[8] = gen_reg_rtx (DImode);
1658 }")
1659
1660 (define_insn "udivsi3_i4"
1661   [(set (match_operand:SI 0 "register_operand" "=y")
1662         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1663    (clobber (reg:SI T_REG))
1664    (clobber (reg:SI PR_REG))
1665    (clobber (reg:DF DR0_REG))
1666    (clobber (reg:DF DR2_REG))
1667    (clobber (reg:DF DR4_REG))
1668    (clobber (reg:SI R0_REG))
1669    (clobber (reg:SI R1_REG))
1670    (clobber (reg:SI R4_REG))
1671    (clobber (reg:SI R5_REG))
1672    (use (reg:PSI FPSCR_REG))
1673    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1674   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1675   "jsr  @%1%#"
1676   [(set_attr "type" "sfunc")
1677    (set_attr "fp_mode" "double")
1678    (set_attr "needs_delay_slot" "yes")])
1679
1680 (define_insn "udivsi3_i4_single"
1681   [(set (match_operand:SI 0 "register_operand" "=y")
1682         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1683    (clobber (reg:SI T_REG))
1684    (clobber (reg:SI PR_REG))
1685    (clobber (reg:DF DR0_REG))
1686    (clobber (reg:DF DR2_REG))
1687    (clobber (reg:DF DR4_REG))
1688    (clobber (reg:SI R0_REG))
1689    (clobber (reg:SI R1_REG))
1690    (clobber (reg:SI R4_REG))
1691    (clobber (reg:SI R5_REG))
1692    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1693   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1694   "jsr  @%1%#"
1695   [(set_attr "type" "sfunc")
1696    (set_attr "needs_delay_slot" "yes")])
1697
1698 (define_insn "udivsi3_i4_int"
1699   [(set (match_operand:SI 0 "register_operand" "=z")
1700         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1701    (clobber (reg:SI T_REG))
1702    (clobber (reg:SI R1_REG))
1703    (clobber (reg:SI PR_REG))
1704    (clobber (reg:SI MACH_REG))
1705    (clobber (reg:SI MACL_REG))
1706    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1707   "TARGET_SH1"
1708   "jsr  @%1%#"
1709   [(set_attr "type" "sfunc")
1710    (set_attr "needs_delay_slot" "yes")])
1711
1712
1713 (define_expand "udivsi3"
1714   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1715    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1716    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1717    (parallel [(set (match_operand:SI 0 "register_operand" "")
1718                    (udiv:SI (reg:SI R4_REG)
1719                             (reg:SI R5_REG)))
1720               (clobber (reg:SI T_REG))
1721               (clobber (reg:SI PR_REG))
1722               (clobber (reg:SI R4_REG))
1723               (use (match_dup 3))])]
1724   ""
1725   "
1726 {
1727   rtx last;
1728
1729   operands[3] = gen_reg_rtx (Pmode);
1730   /* Emit the move of the address to a pseudo outside of the libcall.  */
1731   if (TARGET_DIVIDE_CALL_TABLE)
1732     {
1733       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1734          that causes problems when the divide code is supposed to come from a
1735          separate library.  Division by zero is undefined, so dividing 1 can be
1736          implemented by comparing with the divisor.  */
1737       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1738         {
1739           rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1740           emit_insn (gen_cstoresi4 (operands[0], test,
1741                                     operands[1], operands[2]));
1742           DONE;
1743         }
1744       else if (operands[2] == const0_rtx)
1745         {
1746           emit_move_insn (operands[0], operands[2]);
1747           DONE;
1748         }
1749       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1750       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1751     }
1752   else if (TARGET_DIVIDE_CALL_FP)
1753     {
1754       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1755       if (TARGET_FPU_SINGLE)
1756         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1757       else
1758         last = gen_udivsi3_i4 (operands[0], operands[3]);
1759     }
1760   else if (TARGET_SHMEDIA_FPU)
1761     {
1762       operands[1] = force_reg (SImode, operands[1]);
1763       operands[2] = force_reg (SImode, operands[2]);
1764       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1765       DONE;
1766     }
1767   else if (TARGET_SH2A)
1768     {
1769       operands[1] = force_reg (SImode, operands[1]);
1770       operands[2] = force_reg (SImode, operands[2]);
1771       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1772       DONE;
1773     }
1774   else if (TARGET_SH5)
1775     {
1776       function_symbol (operands[3],
1777                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1778                        SFUNC_STATIC);
1779
1780       if (TARGET_SHMEDIA)
1781         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1782       else if (TARGET_FPU_ANY)
1783         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1784       else
1785         last = gen_udivsi3_i1 (operands[0], operands[3]);
1786     }
1787   else
1788     {
1789       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1790       last = gen_udivsi3_i1 (operands[0], operands[3]);
1791     }
1792   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1793   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1794   emit_insn (last);
1795   DONE;
1796 }")
1797
1798 (define_insn "divsi3_sh2a"
1799   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1800         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1801                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1802   "TARGET_SH2A"
1803   "divs %2,%1"
1804   [(set_attr "type" "arith")
1805    (set_attr "in_delay_slot" "no")])
1806
1807 (define_insn "divsi3_i1"
1808   [(set (match_operand:SI 0 "register_operand" "=z")
1809         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1810    (clobber (reg:SI T_REG))
1811    (clobber (reg:SI PR_REG))
1812    (clobber (reg:SI R1_REG))
1813    (clobber (reg:SI R2_REG))
1814    (clobber (reg:SI R3_REG))
1815    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1816   "TARGET_SH1 && ! TARGET_SH4"
1817   "jsr  @%1%#"
1818   [(set_attr "type" "sfunc")
1819    (set_attr "needs_delay_slot" "yes")])
1820
1821 (define_insn "divsi3_i1_media"
1822   [(set (match_operand:SI 0 "register_operand" "=z")
1823         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1824    (clobber (reg:SI T_MEDIA_REG))
1825    (clobber (reg:SI PR_MEDIA_REG))
1826    (clobber (reg:SI R1_REG))
1827    (clobber (reg:SI R20_REG))
1828    (clobber (reg:SI R21_REG))
1829    (clobber (reg:SI TR0_REG))
1830    (use (match_operand 1 "target_reg_operand" "b"))]
1831   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1832   "blink        %1, r18"
1833   [(set_attr "type" "sfunc")])
1834
1835 (define_insn "divsi3_media_2"
1836   [(set (match_operand:SI 0 "register_operand" "=z")
1837         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1838    (clobber (reg:SI T_MEDIA_REG))
1839    (clobber (reg:SI PR_MEDIA_REG))
1840    (clobber (reg:SI R1_REG))
1841    (clobber (reg:SI R21_REG))
1842    (clobber (reg:SI TR0_REG))
1843    (use (reg:SI R20_REG))
1844    (use (match_operand 1 "target_reg_operand" "b"))]
1845   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1846   "blink        %1, r18"
1847   [(set_attr "type" "sfunc")])
1848
1849 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1850 ;; hard reg clobbers and data dependencies that we need when we want
1851 ;; to rematerialize the division into a call.
1852 (define_insn_and_split "divsi_inv_call"
1853   [(set (match_operand:SI 0 "register_operand" "=r")
1854         (div:SI (match_operand:SI 1 "register_operand" "r")
1855                 (match_operand:SI 2 "register_operand" "r")))
1856    (clobber (reg:SI R4_REG))
1857    (clobber (reg:SI R5_REG))
1858    (clobber (reg:SI T_MEDIA_REG))
1859    (clobber (reg:SI PR_MEDIA_REG))
1860    (clobber (reg:SI R1_REG))
1861    (clobber (reg:SI R21_REG))
1862    (clobber (reg:SI TR0_REG))
1863    (clobber (reg:SI R20_REG))
1864    (use (match_operand:SI 3 "register_operand" "r"))]
1865   "TARGET_SHMEDIA"
1866   "#"
1867   "&& (high_life_started || reload_completed)"
1868   [(set (match_dup 0) (match_dup 3))]
1869   ""
1870   [(set_attr "highpart" "must_split")])
1871
1872 ;; This is the combiner pattern for -mdiv=inv:call .
1873 (define_insn_and_split "*divsi_inv_call_combine"
1874   [(set (match_operand:SI 0 "register_operand" "=z")
1875         (div:SI (match_operand:SI 1 "register_operand" "r")
1876                 (match_operand:SI 2 "register_operand" "r")))
1877    (clobber (reg:SI R4_REG))
1878    (clobber (reg:SI R5_REG))
1879    (clobber (reg:SI T_MEDIA_REG))
1880    (clobber (reg:SI PR_MEDIA_REG))
1881    (clobber (reg:SI R1_REG))
1882    (clobber (reg:SI R21_REG))
1883    (clobber (reg:SI TR0_REG))
1884    (clobber (reg:SI R20_REG))
1885    (use (unspec:SI [(match_dup 1)
1886                     (match_operand:SI 3 "" "")
1887                     (unspec:SI [(match_operand:SI 4 "" "")
1888                                 (match_dup 3)
1889                                 (match_operand:DI 5 "" "")]
1890                      UNSPEC_DIV_INV_M2)
1891                     (match_operand:DI 6 "" "")
1892                     (const_int 0)
1893                     (const_int 0)]
1894          UNSPEC_DIV_INV_M3))]
1895   "TARGET_SHMEDIA"
1896   "#"
1897   "&& (high_life_started || reload_completed)"
1898   [(pc)]
1899   "
1900 {
1901   const char *name = sh_divsi3_libfunc;
1902   enum sh_function_kind kind = SFUNC_GOT;
1903   rtx sym;
1904
1905   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1906   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1907   while (TARGET_DIVIDE_INV_CALL2)
1908     {
1909       rtx x = operands[3];
1910
1911       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1912         break;
1913       x = XVECEXP (x, 0, 0);
1914       name = \"__sdivsi3_2\";
1915       kind = SFUNC_STATIC;
1916       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1917       break;
1918     }
1919   sym = function_symbol (NULL, name, kind);
1920   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1921   DONE;
1922 }"
1923   [(set_attr "highpart" "must_split")])
1924
1925 (define_expand "divsi3_i4_media"
1926   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1927    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1928    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1929    (set (match_operand:SI 0 "register_operand" "=r")
1930         (fix:SI (match_dup 5)))]
1931   "TARGET_SHMEDIA_FPU"
1932   "
1933 {
1934   operands[3] = gen_reg_rtx (DFmode);
1935   operands[4] = gen_reg_rtx (DFmode);
1936   operands[5] = gen_reg_rtx (DFmode);
1937 }")
1938
1939 (define_insn "divsi3_i4"
1940   [(set (match_operand:SI 0 "register_operand" "=y")
1941         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1942    (clobber (reg:SI PR_REG))
1943    (clobber (reg:DF DR0_REG))
1944    (clobber (reg:DF DR2_REG))
1945    (use (reg:PSI FPSCR_REG))
1946    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1947   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1948   "jsr  @%1%#"
1949   [(set_attr "type" "sfunc")
1950    (set_attr "fp_mode" "double")
1951    (set_attr "needs_delay_slot" "yes")])
1952
1953 (define_insn "divsi3_i4_single"
1954   [(set (match_operand:SI 0 "register_operand" "=y")
1955         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1956    (clobber (reg:SI PR_REG))
1957    (clobber (reg:DF DR0_REG))
1958    (clobber (reg:DF DR2_REG))
1959    (clobber (reg:SI R2_REG))
1960    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1961   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1962   "jsr  @%1%#"
1963   [(set_attr "type" "sfunc")
1964    (set_attr "needs_delay_slot" "yes")])
1965
1966 (define_insn "divsi3_i4_int"
1967   [(set (match_operand:SI 0 "register_operand" "=z")
1968         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1969    (clobber (reg:SI T_REG))
1970    (clobber (reg:SI PR_REG))
1971    (clobber (reg:SI R1_REG))
1972    (clobber (reg:SI MACH_REG))
1973    (clobber (reg:SI MACL_REG))
1974    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1975   "TARGET_SH1"
1976   "jsr  @%1%#"
1977   [(set_attr "type" "sfunc")
1978    (set_attr "needs_delay_slot" "yes")])
1979
1980 (define_expand "divsi3"
1981   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1982    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1983    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1984    (parallel [(set (match_operand:SI 0 "register_operand" "")
1985                    (div:SI (reg:SI R4_REG)
1986                            (reg:SI R5_REG)))
1987               (clobber (reg:SI T_REG))
1988               (clobber (reg:SI PR_REG))
1989               (clobber (reg:SI R1_REG))
1990               (clobber (reg:SI R2_REG))
1991               (clobber (reg:SI R3_REG))
1992               (use (match_dup 3))])]
1993   ""
1994   "
1995 {
1996   rtx last;
1997
1998   operands[3] = gen_reg_rtx (Pmode);
1999   /* Emit the move of the address to a pseudo outside of the libcall.  */
2000   if (TARGET_DIVIDE_CALL_TABLE)
2001     {
2002       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2003       last = gen_divsi3_i4_int (operands[0], operands[3]);
2004     }
2005   else if (TARGET_DIVIDE_CALL_FP)
2006     {
2007       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2008       if (TARGET_FPU_SINGLE)
2009         last = gen_divsi3_i4_single (operands[0], operands[3]);
2010       else
2011         last = gen_divsi3_i4 (operands[0], operands[3]);
2012     }
2013   else if (TARGET_SH2A)
2014     {
2015       operands[1] = force_reg (SImode, operands[1]);
2016       operands[2] = force_reg (SImode, operands[2]);
2017       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2018       DONE;
2019     }
2020   else if (TARGET_DIVIDE_INV)
2021     {
2022       rtx dividend = operands[1];
2023       rtx divisor = operands[2];
2024       rtx tab_base;
2025       rtx nsb_res = gen_reg_rtx (DImode);
2026       rtx norm64 = gen_reg_rtx (DImode);
2027       rtx tab_ix = gen_reg_rtx (DImode);
2028       rtx norm32 = gen_reg_rtx (SImode);
2029       rtx i92 = force_reg (DImode, GEN_INT (92));
2030       rtx scratch0a = gen_reg_rtx (DImode);
2031       rtx scratch0b = gen_reg_rtx (DImode);
2032       rtx inv0 = gen_reg_rtx (SImode);
2033       rtx scratch1a = gen_reg_rtx (DImode);
2034       rtx scratch1b = gen_reg_rtx (DImode);
2035       rtx shift = gen_reg_rtx (DImode);
2036       rtx i2p27, i43;
2037       rtx inv1 = gen_reg_rtx (SImode);
2038       rtx scratch2a = gen_reg_rtx (DImode);
2039       rtx scratch2b = gen_reg_rtx (SImode);
2040       rtx inv2 = gen_reg_rtx (SImode);
2041       rtx scratch3a = gen_reg_rtx (DImode);
2042       rtx scratch3b = gen_reg_rtx (DImode);
2043       rtx scratch3c = gen_reg_rtx (DImode);
2044       rtx scratch3d = gen_reg_rtx (SImode);
2045       rtx scratch3e = gen_reg_rtx (DImode);
2046       rtx result = gen_reg_rtx (SImode);
2047
2048       if (! arith_reg_or_0_operand (dividend, SImode))
2049         dividend = force_reg (SImode, dividend);
2050       if (! arith_reg_operand (divisor, SImode))
2051         divisor = force_reg (SImode, divisor);
2052       if (flag_pic && Pmode != DImode)
2053         {
2054           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2055           tab_base = gen_datalabel_ref (tab_base);
2056           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2057         }
2058       else
2059         {
2060           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2061           tab_base = gen_datalabel_ref (tab_base);
2062           tab_base = force_reg (DImode, tab_base);
2063         }
2064       if (TARGET_DIVIDE_INV20U)
2065         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2066       else
2067         i2p27 = GEN_INT (0);
2068       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2069         i43 = force_reg (DImode, GEN_INT (43));
2070       else
2071         i43 = GEN_INT (0);
2072       emit_insn (gen_nsbdi (nsb_res,
2073                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2074       emit_insn (gen_ashldi3_media (norm64,
2075                                     gen_rtx_SUBREG (DImode, divisor, 0),
2076                                     nsb_res));
2077       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2078       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2079       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2080                                    inv0, scratch0a, scratch0b,
2081                                    scratch1a, scratch1b));
2082       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2083       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2084                                    scratch2a));
2085       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2086                                    i2p27, i43,
2087                                    scratch3a, scratch3b, scratch3c,
2088                                    scratch2a, scratch2b, scratch3d, scratch3e));
2089       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2090         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2091       else if (TARGET_DIVIDE_INV_FP)
2092         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2093                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2094                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2095                                      gen_reg_rtx (DFmode)));
2096       else
2097         emit_move_insn (operands[0], result);
2098       DONE;
2099     }
2100   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2101     {
2102       operands[1] = force_reg (SImode, operands[1]);
2103       operands[2] = force_reg (SImode, operands[2]);
2104       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2105       DONE;
2106     }
2107   else if (TARGET_SH5)
2108     {
2109       if (TARGET_DIVIDE_CALL2)
2110         {
2111           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2112           tab_base = gen_datalabel_ref (tab_base);
2113           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2114         }
2115       if (TARGET_FPU_ANY && TARGET_SH1)
2116         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2117       else if (TARGET_DIVIDE_CALL2)
2118         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2119       else
2120         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2121
2122       if (TARGET_SHMEDIA)
2123         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2124                 (operands[0], operands[3]));
2125       else if (TARGET_FPU_ANY)
2126         last = gen_divsi3_i4_single (operands[0], operands[3]);
2127       else
2128         last = gen_divsi3_i1 (operands[0], operands[3]);
2129     }
2130   else
2131     {
2132       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2133       last = gen_divsi3_i1 (operands[0], operands[3]);
2134     }
2135   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2136   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2137   emit_insn (last);
2138   DONE;
2139 }")
2140
2141 ;; operands: scratch, tab_base, tab_ix
2142 ;; These are unspecs because we could generate an indexed addressing mode
2143 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2144 ;; confuse reload.  See PR27117.
2145
2146 (define_insn "divsi_inv_qitable"
2147   [(set (match_operand:DI 0 "register_operand" "=r")
2148         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2149                                     (match_operand:DI 2 "register_operand" "r")]
2150                          UNSPEC_DIV_INV_TABLE)))]
2151   "TARGET_SHMEDIA"
2152   "@
2153         ldx.ub  %1, %2, %0"
2154   [(set_attr "type" "load_media")
2155    (set_attr "highpart" "user")])
2156
2157 ;; operands: scratch, tab_base, tab_ix
2158 (define_insn "divsi_inv_hitable"
2159   [(set (match_operand:DI 0 "register_operand" "=r")
2160         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2161                                     (match_operand:DI 2 "register_operand" "r")]
2162                          UNSPEC_DIV_INV_TABLE)))]
2163   "TARGET_SHMEDIA"
2164   "@
2165         ldx.w   %1, %2, %0"
2166   [(set_attr "type" "load_media")
2167    (set_attr "highpart" "user")])
2168
2169 ;; operands: inv0, tab_base, tab_ix, norm32
2170 ;; scratch equiv in sdivsi3_2: r19, r21
2171 (define_expand "divsi_inv_m0"
2172   [(set (match_operand:SI 0 "register_operand" "=r")
2173         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2174                     (match_operand:DI 2 "register_operand" "r")
2175                     (match_operand:SI 3 "register_operand" "r")]
2176          UNSPEC_DIV_INV_M0))
2177    (clobber (match_operand:DI 4 "register_operand" "=r"))
2178    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2179   "TARGET_SHMEDIA"
2180   "
2181 {
2182 /*
2183 tab_base: r20
2184 tab_ix: r21
2185 norm32: r25
2186  ldx.ub r20, r21, r19 // u0.8
2187  shlli r21, 1, r21
2188  muls.l r25, r19, r19 // s2.38
2189  ldx.w r20, r21, r21  // s2.14
2190  shari r19, 24, r19   // truncate to s2.14
2191  sub r21, r19, r19    // some 11 bit inverse in s1.14
2192 */
2193
2194   rtx inv0 = operands[0];
2195   rtx tab_base = operands[1];
2196   rtx tab_ix = operands[2];
2197   rtx norm32 = operands[3];
2198   rtx scratch0 = operands[4];
2199   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2200   rtx scratch1 = operands[5];
2201
2202   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2203   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2204   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2205   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2206   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2207   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2208   DONE;
2209 }")
2210
2211 ;; operands: inv1, tab_base, tab_ix, norm32
2212 (define_insn_and_split "divsi_inv_m1"
2213   [(set (match_operand:SI 0 "register_operand" "=r")
2214         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2215                     (match_operand:DI 2 "register_operand" "r")
2216                     (match_operand:SI 3 "register_operand" "r")]
2217          UNSPEC_DIV_INV_M1))
2218    (clobber (match_operand:SI 4 "register_operand" "=r"))
2219    (clobber (match_operand:DI 5 "register_operand" "=r"))
2220    (clobber (match_operand:DI 6 "register_operand" "=r"))
2221    (clobber (match_operand:DI 7 "register_operand" "=r"))
2222    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2223   "TARGET_SHMEDIA"
2224   "#"
2225   "&& !can_create_pseudo_p ()"
2226   [(pc)]
2227   "
2228 {
2229 /* inv0: r19
2230  muls.l r19, r19, r18 // u0.28
2231  muls.l r25, r18, r18 // s2.58
2232  shlli r19, 45, r0    // multiply by two and convert to s2.58
2233  sub r0, r18, r18
2234  shari r18, 28, r18   // some 18 bit inverse in s1.30
2235 */
2236
2237   rtx inv1 = operands[0];
2238   rtx tab_base = operands[1];
2239   rtx tab_ix = operands[2];
2240   rtx norm32 = operands[3];
2241   rtx inv0 = operands[4];
2242   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2243   rtx scratch0a = operands[5];
2244   rtx scratch0b = operands[6];
2245   rtx scratch0 = operands[7];
2246   rtx scratch1 = operands[8];
2247   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2248
2249   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2250                                scratch0a, scratch0b));
2251   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2252   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2253   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2254   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2255   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2256   DONE;
2257 }")
2258
2259 ;; operands: inv2, norm32, inv1, i92
2260 (define_insn_and_split "divsi_inv_m2"
2261   [(set (match_operand:SI 0 "register_operand" "=r")
2262         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2263                     (match_operand:SI 2 "register_operand" "r")
2264                     (match_operand:DI 3 "register_operand" "r")]
2265          UNSPEC_DIV_INV_M2))
2266    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2267   "TARGET_SHMEDIA"
2268   "#"
2269   "&& !can_create_pseudo_p ()"
2270   [(pc)]
2271   "
2272 {
2273 /*
2274  muls.l r18, r25, r0  // s2.60
2275  shari r0, 16, r0     // s-16.44
2276   sub
2277  muls.l r0, r18, r19  // s-16.74
2278  shari r19, 30, r19   // s-16.44
2279 */
2280   rtx inv2 = operands[0];
2281   rtx norm32 = operands[1];
2282   rtx inv1 = operands[2];
2283   rtx i92 = operands[3];
2284   rtx scratch0 = operands[4];
2285   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2286
2287   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2288   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2289   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2290   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2291   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2292   DONE;
2293 }")
2294
2295 (define_insn_and_split "divsi_inv_m3"
2296   [(set (match_operand:SI 0 "register_operand" "=r")
2297         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2298                     (match_operand:SI 2 "register_operand" "r")
2299                     (match_operand:SI 3 "register_operand" "r")
2300                     (match_operand:DI 4 "register_operand" "r")
2301                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2302                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2303          UNSPEC_DIV_INV_M3))
2304    (clobber (match_operand:DI 7 "register_operand" "=r"))
2305    (clobber (match_operand:DI 8 "register_operand" "=r"))
2306    (clobber (match_operand:DI 9 "register_operand" "=r"))
2307    (clobber (match_operand:DI 10 "register_operand" "=r"))
2308    (clobber (match_operand:SI 11 "register_operand" "=r"))
2309    (clobber (match_operand:SI 12 "register_operand" "=r"))
2310    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2311   "TARGET_SHMEDIA"
2312   "#"
2313   "&& !can_create_pseudo_p ()"
2314   [(pc)]
2315   "
2316 {
2317 /*
2318   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2319   r0: scratch0  r19: scratch1 r21: scratch2
2320
2321   muls.l r18, r4, r25 // s32.30
2322  muls.l r19, r4, r19  // s15.30
2323  shari r25, 63, r21
2324   shari r19, 14, r19  // s18.-14
2325  sub r25, r19, r0
2326  shard r0, r1, r0
2327  sub r0, r21, r0
2328 */
2329
2330   rtx result = operands[0];
2331   rtx dividend = operands[1];
2332   rtx inv1 = operands[2];
2333   rtx inv2 = operands[3];
2334   rtx shift = operands[4];
2335   rtx scratch0 = operands[7];
2336   rtx scratch1 = operands[8];
2337   rtx scratch2 = operands[9];
2338
2339   if (satisfies_constraint_N (dividend))
2340     {
2341       emit_move_insn (result, dividend);
2342       DONE;
2343     }
2344
2345   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2346   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2347   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2348   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2349   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2350   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2351   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2352   DONE;
2353 }")
2354
2355 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2356 ;; inv1: tab_base, tab_ix, norm32
2357 ;; inv2: norm32, inv1, i92
2358 (define_insn_and_split "divsi_inv_m1_3"
2359   [(set (match_operand:SI 0 "register_operand" "=r")
2360         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2361                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2362                                 (match_operand:DI 3 "register_operand" "r")
2363                                 (match_operand:SI 4 "register_operand" "r")]
2364                      UNSPEC_DIV_INV_M1)
2365                     (unspec:SI [(match_dup 4)
2366                                 (unspec:SI [(match_dup 2)
2367                                             (match_dup 3)
2368                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2369                                 (match_operand:SI 5 "" "")]
2370                      UNSPEC_DIV_INV_M2)
2371                     (match_operand:DI 6 "register_operand" "r")
2372                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2373                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2374          UNSPEC_DIV_INV_M3))
2375    (clobber (match_operand:DI 9 "register_operand" "=r"))
2376    (clobber (match_operand:DI 10 "register_operand" "=r"))
2377    (clobber (match_operand:DI 11 "register_operand" "=r"))
2378    (clobber (match_operand:DI 12 "register_operand" "=r"))
2379    (clobber (match_operand:SI 13 "register_operand" "=r"))
2380    (clobber (match_operand:SI 14 "register_operand" "=r"))
2381    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2382   "TARGET_SHMEDIA
2383    && (TARGET_DIVIDE_INV_MINLAT
2384        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2385   "#"
2386   "&& !can_create_pseudo_p ()"
2387   [(pc)]
2388   "
2389 {
2390   rtx result = operands[0];
2391   rtx dividend = operands[1];
2392   rtx tab_base = operands[2];
2393   rtx tab_ix = operands[3];
2394   rtx norm32 = operands[4];
2395   /* rtx i92 = operands[5]; */
2396   rtx shift = operands[6];
2397   rtx i2p27 = operands[7];
2398   rtx i43 = operands[8];
2399   rtx scratch0 = operands[9];
2400   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2401   rtx scratch1 = operands[10];
2402   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2403   rtx scratch2 = operands[11];
2404   rtx scratch3 = operands[12];
2405   rtx scratch4 = operands[13];
2406   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2407   rtx scratch5 = operands[14];
2408   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2409   rtx scratch6 = operands[15];
2410
2411   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2412                                scratch0, scratch1));
2413   /* inv0 == scratch4 */
2414   if (! TARGET_DIVIDE_INV20U)
2415     {
2416       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2417       i2p27 = scratch0;
2418       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2419     }
2420   else
2421     {
2422       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2423       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2424     }
2425   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2426   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2427   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2428   /* inv1 == scratch4 */
2429
2430   if (TARGET_DIVIDE_INV_MINLAT)
2431     {
2432       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2433       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2434       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2435       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2436       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2437       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2438       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2439       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2440       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2441       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2442       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2443     }
2444   else
2445     {
2446       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2447       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2448       emit_insn (gen_nsbdi (scratch6,
2449                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2450       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2451       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2452       emit_insn (gen_divsi_inv20 (scratch2,
2453                                   norm32, scratch4, dividend,
2454                                   scratch6, scratch3, i43,
2455                                   /* scratch0 may be shared with i2p27.  */
2456                                   scratch0, scratch1, scratch5,
2457                                   label, label, i2p27));
2458     }
2459   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2460   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2461   DONE;
2462 }")
2463
2464 (define_insn "divsi_inv20"
2465   [(set (match_operand:DI 0 "register_operand" "=&r")
2466         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2467                     (match_operand:SI 2 "register_operand" "r")
2468                     (match_operand:SI 3 "register_operand" "r")
2469                     (match_operand:DI 4 "register_operand" "r")
2470                     (match_operand:DI 5 "register_operand" "r")
2471                     (match_operand:DI 6 "register_operand" "r")
2472                     (match_operand:DI 12 "register_operand" "r")
2473                     (match_operand 10 "target_operand" "b")
2474                     (match_operand 11 "immediate_operand" "i")]
2475          UNSPEC_DIV_INV20))
2476    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2477    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2478    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2479   "TARGET_SHMEDIA
2480    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2481   "*
2482 {
2483 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2484              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2485              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2486              %10 label (tr), %11 label (imm)
2487
2488  muls.l inv1, norm32, scratch0  // s2.60
2489   muls.l inv1, dividend, result // s32.30
2490   xor i2p27, result_sign, round_scratch
2491  bge/u dividend_nsb, i43, tr.. (label)
2492  shari scratch0, 16, scratch0   // s-16.44
2493  muls.l sratch0_si, inv1, scratch0 // s-16.74
2494   sub result, round_scratch, result
2495   shari dividend, 14, scratch1   // s19.-14
2496  shari scratch0, 30, scratch0   // s-16.44
2497  muls.l scratch0, scratch1, round_scratch // s15.30
2498 label:
2499  sub result, round_scratch, result */
2500
2501   int likely = TARGET_DIVIDE_INV20L;
2502
2503   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2504   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2505   output_asm_insn (likely
2506                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2507                    : \"bge/u\t%4, %6, %10\", operands);
2508   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2509   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2510   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2511   return (likely
2512           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2513           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2514 }")
2515
2516 (define_insn_and_split "divsi_inv_fp"
2517   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2518         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2519                 (match_operand:SI 2 "register_operand" "rf")))
2520    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2521    (clobber (match_operand:SI 4 "register_operand" "=r"))
2522    (clobber (match_operand:SI 5 "register_operand" "=r"))
2523    (clobber (match_operand:DF 6 "register_operand" "=r"))
2524    (clobber (match_operand:DF 7 "register_operand" "=r"))
2525    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2526   "TARGET_SHMEDIA_FPU"
2527   "#"
2528   "&& (high_life_started || reload_completed)"
2529   [(set (match_dup 0) (match_dup 3))]
2530   ""
2531   [(set_attr "highpart" "must_split")])
2532
2533 ;; If a matching group of divide-by-inverse instructions is in the same
2534 ;; basic block after gcse & loop optimizations, we want to transform them
2535 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2536 (define_insn_and_split "*divsi_inv_fp_combine"
2537   [(set (match_operand:SI 0 "register_operand" "=f")
2538         (div:SI (match_operand:SI 1 "register_operand" "f")
2539                 (match_operand:SI 2 "register_operand" "f")))
2540    (use (unspec:SI [(match_dup 1)
2541                     (match_operand:SI 3 "" "")
2542                     (unspec:SI [(match_operand:SI 4 "" "")
2543                                 (match_dup 3)
2544                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2545                     (match_operand:DI 6 "" "")
2546                     (const_int 0)
2547                     (const_int 0)] UNSPEC_DIV_INV_M3))
2548    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2549    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2550    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2551    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2552    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2553   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2554   "#"
2555   "&& 1"
2556   [(set (match_dup 9) (float:DF (match_dup 1)))
2557    (set (match_dup 10) (float:DF (match_dup 2)))
2558    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2559    (set (match_dup 8)
2560         (fix:SI (match_dup 11)))
2561    (set (match_dup 0) (match_dup 8))]
2562   "
2563 {
2564   if (! fp_arith_reg_operand (operands[1], SImode))
2565     {
2566       emit_move_insn (operands[7], operands[1]);
2567       operands[1] = operands[7];
2568     }
2569   if (! fp_arith_reg_operand (operands[2], SImode))
2570     {
2571       emit_move_insn (operands[8], operands[2]);
2572       operands[2] = operands[8];
2573     }
2574 }"
2575   [(set_attr "highpart" "must_split")])
2576 \f
2577 ;; -------------------------------------------------------------------------
2578 ;; Multiplication instructions
2579 ;; -------------------------------------------------------------------------
2580
2581 (define_insn "umulhisi3_i"
2582   [(set (reg:SI MACL_REG)
2583         (mult:SI (zero_extend:SI
2584                   (match_operand:HI 0 "arith_reg_operand" "r"))
2585                  (zero_extend:SI
2586                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2587   "TARGET_SH1"
2588   "mulu.w       %1,%0"
2589   [(set_attr "type" "smpy")])
2590
2591 (define_insn "mulhisi3_i"
2592   [(set (reg:SI MACL_REG)
2593         (mult:SI (sign_extend:SI
2594                   (match_operand:HI 0 "arith_reg_operand" "r"))
2595                  (sign_extend:SI
2596                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2597   "TARGET_SH1"
2598   "muls.w       %1,%0"
2599   [(set_attr "type" "smpy")])
2600
2601 (define_expand "mulhisi3"
2602   [(set (reg:SI MACL_REG)
2603         (mult:SI (sign_extend:SI
2604                   (match_operand:HI 1 "arith_reg_operand" ""))
2605                  (sign_extend:SI
2606                   (match_operand:HI 2 "arith_reg_operand" ""))))
2607    (set (match_operand:SI 0 "arith_reg_operand" "")
2608         (reg:SI MACL_REG))]
2609   "TARGET_SH1"
2610   "
2611 {
2612   rtx insn, macl;
2613
2614   macl = gen_rtx_REG (SImode, MACL_REG);
2615   start_sequence ();
2616   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2617   insn = get_insns ();  
2618   end_sequence ();
2619   /* expand_binop can't find a suitable code in umul_widen_optab to
2620      make a REG_EQUAL note from, so make one here.
2621      See also smulsi3_highpart.
2622      ??? Alternatively, we could put this at the calling site of expand_binop,
2623      i.e. expand_expr.  */
2624   /* Use emit_libcall_block for loop invariant code motion and to make
2625      a REG_EQUAL note.  */
2626   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2627
2628   DONE;
2629 }")
2630
2631 (define_expand "umulhisi3"
2632   [(set (reg:SI MACL_REG)
2633         (mult:SI (zero_extend:SI
2634                   (match_operand:HI 1 "arith_reg_operand" ""))
2635                  (zero_extend:SI
2636                   (match_operand:HI 2 "arith_reg_operand" ""))))
2637    (set (match_operand:SI 0 "arith_reg_operand" "")
2638         (reg:SI MACL_REG))]
2639   "TARGET_SH1"
2640   "
2641 {
2642   rtx insn, macl;
2643
2644   macl = gen_rtx_REG (SImode, MACL_REG);
2645   start_sequence ();
2646   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2647   insn = get_insns ();  
2648   end_sequence ();
2649   /* expand_binop can't find a suitable code in umul_widen_optab to
2650      make a REG_EQUAL note from, so make one here.
2651      See also smulsi3_highpart.
2652      ??? Alternatively, we could put this at the calling site of expand_binop,
2653      i.e. expand_expr.  */
2654   /* Use emit_libcall_block for loop invariant code motion and to make
2655      a REG_EQUAL note.  */
2656   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2657
2658   DONE;
2659 }")
2660
2661 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2662 ;; a call to a routine which clobbers known registers.
2663
2664 (define_insn ""
2665   [(set (match_operand:SI 1 "register_operand" "=z")
2666         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2667    (clobber (reg:SI MACL_REG))
2668    (clobber (reg:SI T_REG))
2669    (clobber (reg:SI PR_REG))
2670    (clobber (reg:SI R3_REG))
2671    (clobber (reg:SI R2_REG))
2672    (clobber (reg:SI R1_REG))
2673    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2674   "TARGET_SH1"
2675   "jsr  @%0%#"
2676   [(set_attr "type" "sfunc")
2677    (set_attr "needs_delay_slot" "yes")])
2678
2679 (define_expand "mulsi3_call"
2680   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2681    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2682    (parallel[(set (match_operand:SI 0 "register_operand" "")
2683                   (mult:SI (reg:SI R4_REG)
2684                            (reg:SI R5_REG)))
2685              (clobber (reg:SI MACL_REG))
2686              (clobber (reg:SI T_REG))
2687              (clobber (reg:SI PR_REG))
2688              (clobber (reg:SI R3_REG))
2689              (clobber (reg:SI R2_REG))
2690              (clobber (reg:SI R1_REG))
2691              (use (match_operand:SI 3 "register_operand" ""))])]
2692   "TARGET_SH1"
2693   "")
2694
2695 (define_insn "mul_r"
2696   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2697         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2698                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2699   "TARGET_SH2A"
2700   "mulr %2,%0"
2701   [(set_attr "type" "dmpy")])
2702
2703 (define_insn "mul_l"
2704   [(set (reg:SI MACL_REG)
2705         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2706                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2707   "TARGET_SH2"
2708   "mul.l        %1,%0"
2709   [(set_attr "type" "dmpy")])
2710
2711 (define_expand "mulsi3"
2712   [(set (reg:SI MACL_REG)
2713         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2714                   (match_operand:SI 2 "arith_reg_operand" "")))
2715    (set (match_operand:SI 0 "arith_reg_operand" "")
2716         (reg:SI MACL_REG))]
2717   "TARGET_SH1"
2718   "
2719 {
2720   if (!TARGET_SH2)
2721     {
2722       /* The address must be set outside the libcall,
2723          since it goes into a pseudo.  */
2724       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2725       rtx addr = force_reg (SImode, sym);
2726       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2727                                    operands[2], addr);
2728       emit_insn (insns);
2729     }
2730   else
2731     {
2732       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2733
2734       emit_insn (gen_mul_l (operands[1], operands[2]));
2735       /* consec_sets_giv can only recognize the first insn that sets a
2736          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2737          note.  */
2738       emit_insn (gen_movsi_i ((operands[0]), macl));
2739     }
2740   DONE;
2741 }")
2742
2743 (define_insn "mulsidi3_i"
2744   [(set (reg:SI MACH_REG)
2745         (truncate:SI
2746          (lshiftrt:DI
2747           (mult:DI
2748            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2749            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2750           (const_int 32))))
2751    (set (reg:SI MACL_REG)
2752         (mult:SI (match_dup 0)
2753                  (match_dup 1)))]
2754   "TARGET_SH2"
2755   "dmuls.l      %1,%0"
2756   [(set_attr "type" "dmpy")])
2757
2758 (define_expand "mulsidi3"
2759   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2760         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2761                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2762   "TARGET_SH2 || TARGET_SHMEDIA"
2763   "
2764 {
2765   if (TARGET_SH2)
2766     {
2767        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2768                                         operands[2]));
2769        DONE;
2770     }
2771 }")
2772
2773 (define_insn "mulsidi3_media"
2774   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2775         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2776                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2777   "TARGET_SHMEDIA"
2778   "muls.l       %1, %2, %0"
2779   [(set_attr "type" "dmpy_media")
2780    (set_attr "highpart" "ignore")])
2781
2782 (define_insn "mulsidi3_compact"
2783   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2784         (mult:DI
2785          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2786          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2787    (clobber (reg:SI MACH_REG))
2788    (clobber (reg:SI MACL_REG))]
2789   "TARGET_SH2"
2790   "#")
2791
2792 (define_split
2793   [(set (match_operand:DI 0 "arith_reg_dest" "")
2794         (mult:DI
2795          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2796          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2797    (clobber (reg:SI MACH_REG))
2798    (clobber (reg:SI MACL_REG))]
2799   "TARGET_SH2"
2800   [(const_int 0)]
2801   "
2802 {
2803   rtx low_dst = gen_lowpart (SImode, operands[0]);
2804   rtx high_dst = gen_highpart (SImode, operands[0]);
2805
2806   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2807
2808   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2809   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2810   /* We need something to tag the possible REG_EQUAL notes on to.  */
2811   emit_move_insn (operands[0], operands[0]);
2812   DONE;
2813 }")
2814
2815 (define_insn "umulsidi3_i"
2816   [(set (reg:SI MACH_REG)
2817         (truncate:SI
2818          (lshiftrt:DI
2819           (mult:DI
2820            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2821            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2822           (const_int 32))))
2823    (set (reg:SI MACL_REG)
2824         (mult:SI (match_dup 0)
2825                  (match_dup 1)))]
2826   "TARGET_SH2"
2827   "dmulu.l      %1,%0"
2828   [(set_attr "type" "dmpy")])
2829
2830 (define_expand "umulsidi3"
2831   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2832         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2833                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2834   "TARGET_SH2 || TARGET_SHMEDIA"
2835   "
2836 {
2837   if (TARGET_SH2)
2838     {
2839        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2840                                          operands[2]));
2841        DONE;
2842     }
2843 }")
2844
2845 (define_insn "umulsidi3_media"
2846   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2847         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2848                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2849   "TARGET_SHMEDIA"
2850   "mulu.l       %1, %2, %0"
2851   [(set_attr "type" "dmpy_media")
2852    (set_attr "highpart" "ignore")])
2853
2854 (define_insn "umulsidi3_compact"
2855   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2856         (mult:DI
2857          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2858          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2859    (clobber (reg:SI MACH_REG))
2860    (clobber (reg:SI MACL_REG))]
2861   "TARGET_SH2"
2862   "#")
2863
2864 (define_split
2865   [(set (match_operand:DI 0 "arith_reg_dest" "")
2866         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2867                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2868    (clobber (reg:SI MACH_REG))
2869    (clobber (reg:SI MACL_REG))]
2870   "TARGET_SH2"
2871   [(const_int 0)]
2872   "
2873 {
2874   rtx low_dst = gen_lowpart (SImode, operands[0]);
2875   rtx high_dst = gen_highpart (SImode, operands[0]);
2876
2877   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2878
2879   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2880   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2881   /* We need something to tag the possible REG_EQUAL notes on to.  */
2882   emit_move_insn (operands[0], operands[0]);
2883   DONE;
2884 }")
2885
2886 (define_insn "smulsi3_highpart_i"
2887   [(set (reg:SI MACH_REG)
2888         (truncate:SI
2889          (lshiftrt:DI
2890           (mult:DI
2891            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2892            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2893           (const_int 32))))
2894    (clobber (reg:SI MACL_REG))]
2895   "TARGET_SH2"
2896   "dmuls.l      %1,%0"
2897   [(set_attr "type" "dmpy")])
2898
2899 (define_expand "smulsi3_highpart"
2900   [(parallel
2901     [(set (reg:SI MACH_REG)
2902           (truncate:SI
2903            (lshiftrt:DI
2904             (mult:DI
2905              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2906              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2907             (const_int 32))))
2908     (clobber (reg:SI MACL_REG))])
2909    (set (match_operand:SI 0 "arith_reg_operand" "")
2910         (reg:SI MACH_REG))]
2911   "TARGET_SH2"
2912   "
2913 {
2914   rtx insn, mach;
2915
2916   mach = gen_rtx_REG (SImode, MACH_REG);
2917   start_sequence ();
2918   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2919   insn = get_insns ();  
2920   end_sequence ();
2921   /* expand_binop can't find a suitable code in mul_highpart_optab to
2922      make a REG_EQUAL note from, so make one here.
2923      See also {,u}mulhisi.
2924      ??? Alternatively, we could put this at the calling site of expand_binop,
2925      i.e. expand_mult_highpart.  */
2926   /* Use emit_libcall_block for loop invariant code motion and to make
2927      a REG_EQUAL note.  */
2928   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2929
2930   DONE;
2931 }")
2932
2933 (define_insn "umulsi3_highpart_i"
2934   [(set (reg:SI MACH_REG)
2935         (truncate:SI
2936          (lshiftrt:DI
2937           (mult:DI
2938            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2939            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2940           (const_int 32))))
2941    (clobber (reg:SI MACL_REG))]
2942   "TARGET_SH2"
2943   "dmulu.l      %1,%0"
2944   [(set_attr "type" "dmpy")])
2945
2946 (define_expand "umulsi3_highpart"
2947   [(parallel
2948     [(set (reg:SI MACH_REG)
2949           (truncate:SI
2950            (lshiftrt:DI
2951             (mult:DI
2952              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2953              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2954             (const_int 32))))
2955     (clobber (reg:SI MACL_REG))])
2956    (set (match_operand:SI 0 "arith_reg_operand" "")
2957         (reg:SI MACH_REG))]
2958   "TARGET_SH2"
2959   "
2960 {
2961   rtx insn, mach;
2962
2963   mach = gen_rtx_REG (SImode, MACH_REG);
2964   start_sequence ();
2965   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2966   insn = get_insns ();  
2967   end_sequence ();
2968   /* Use emit_libcall_block for loop invariant code motion and to make
2969      a REG_EQUAL note.  */
2970   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2971
2972   DONE;
2973 }")
2974
2975 (define_insn_and_split "muldi3"
2976   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2977         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2978                  (match_operand:DI 2 "arith_reg_operand" "r")))
2979    (clobber (match_scratch:DI 3 "=&r"))
2980    (clobber (match_scratch:DI 4 "=r"))]
2981   "TARGET_SHMEDIA"
2982   "#"
2983   "reload_completed"
2984   [(const_int 0)]
2985   "
2986 {
2987   rtx op3_v2si, op2_v2si;
2988
2989   op3_v2si = operands[3];
2990   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2991     {
2992       op3_v2si = XEXP (op3_v2si, 0);
2993       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2994     }
2995   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2996   op2_v2si = operands[2];
2997   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2998     {
2999       op2_v2si = XEXP (op2_v2si, 0);
3000       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3001     }
3002   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3003   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3004   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3005   emit_insn (gen_umulsidi3_media (operands[4],
3006                                  sh_gen_truncate (SImode, operands[1], 0),
3007                                  sh_gen_truncate (SImode, operands[2], 0)));
3008   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3009   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3010   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3011   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3012   DONE;
3013 }")
3014
3015 \f
3016 ;; -------------------------------------------------------------------------
3017 ;; Logical operations
3018 ;; -------------------------------------------------------------------------
3019
3020 (define_insn "*andsi3_compact"
3021   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3022         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3023                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3024   "TARGET_SH1"
3025   "and  %2,%0"
3026   [(set_attr "type" "arith")])
3027
3028 (define_insn "*andsi3_media"
3029   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3030         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3031                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3032   "TARGET_SHMEDIA"
3033   "@
3034         and     %1, %2, %0
3035         andi    %1, %2, %0"
3036   [(set_attr "type" "arith_media")])
3037
3038 (define_insn "*andsi3_bclr"
3039   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3040         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3041                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3042   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3043   "bclr\\t%W2,%0"
3044   [(set_attr "type" "arith")])
3045
3046 ;; If the constant is 255, then emit an extu.b instruction instead of an
3047 ;; and, since that will give better code.
3048
3049 (define_expand "andsi3"
3050   [(set (match_operand:SI 0 "arith_reg_operand" "")
3051         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3052                 (match_operand:SI 2 "logical_operand" "")))]
3053   ""
3054   "
3055 {
3056   if (TARGET_SH1
3057       && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3058     {
3059       emit_insn (gen_zero_extendqisi2 (operands[0],
3060                                        gen_lowpart (QImode, operands[1])));
3061       DONE;
3062     }
3063 }")
3064
3065 (define_insn_and_split "anddi3"
3066   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3067         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3068                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3069   "TARGET_SHMEDIA"
3070   "@
3071         and     %1, %2, %0
3072         andi    %1, %2, %0
3073         #"
3074   "reload_completed
3075    && ! logical_operand (operands[2], DImode)"
3076   [(const_int 0)]
3077   "
3078 {
3079   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3080     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3081   else
3082     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3083   DONE;
3084 }"
3085   [(set_attr "type" "arith_media")])
3086
3087 (define_insn "andcsi3"
3088   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3089         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3090                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3091   "TARGET_SHMEDIA"
3092   "andc %1,%2,%0"
3093   [(set_attr "type" "arith_media")])
3094
3095 (define_insn "andcdi3"
3096   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3097         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3098                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3099   "TARGET_SHMEDIA"
3100   "andc %1,%2,%0"
3101   [(set_attr "type" "arith_media")])
3102
3103 (define_expand "iorsi3"
3104   [(set (match_operand:SI 0 "arith_reg_operand" "")
3105         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3106                 (match_operand:SI 2 "logical_operand" "")))]
3107   ""
3108   "")
3109
3110 (define_insn "*iorsi3_compact"
3111   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3112         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3113                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3114   "TARGET_SH1
3115    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3116   "or   %2,%0"
3117   [(set_attr "type" "arith")])
3118
3119 (define_insn "*iorsi3_media"
3120   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3121         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3122                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3123   "TARGET_SHMEDIA"
3124   "@
3125         or      %1, %2, %0
3126         ori     %1, %2, %0"
3127   [(set_attr "type" "arith_media")])
3128
3129 (define_insn "*iorsi3_bset"
3130   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3131         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3132         (match_operand:SI 2 "const_int_operand" "Pso")))]
3133   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3134   "bset\\t%V2,%0"
3135   [(set_attr "type" "arith")])
3136
3137 (define_insn "iordi3"
3138   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3139         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3140                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3141   "TARGET_SHMEDIA"
3142   "@
3143         or      %1, %2, %0
3144         ori     %1, %2, %0"
3145   [(set_attr "type" "arith_media")])
3146
3147 (define_insn_and_split "*logical_sidi3"
3148   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3149         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3150                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3151                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3152   "TARGET_SHMEDIA"
3153   "#"
3154   "&& reload_completed"
3155   [(set (match_dup 0) (match_dup 3))]
3156   "
3157 {
3158   operands[3]
3159     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3160                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3161                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3162 }")
3163
3164 (define_insn_and_split "*logical_sidisi3"
3165   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3166         (truncate:SI (sign_extend:DI
3167                         (match_operator:SI 3 "logical_operator"
3168                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3169                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3170   "TARGET_SHMEDIA"
3171   "#"
3172   "&& 1"
3173   [(set (match_dup 0) (match_dup 3))])
3174
3175 (define_insn_and_split "*logical_sidi3_2"
3176   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3177         (sign_extend:DI (truncate:SI (sign_extend:DI
3178                         (match_operator:SI 3 "logical_operator"
3179                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3180                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3181   "TARGET_SHMEDIA"
3182   "#"
3183   "&& 1"
3184   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3185
3186 (define_expand "xorsi3"
3187   [(set (match_operand:SI 0 "arith_reg_operand" "")
3188         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3189                 (match_operand:SI 2 "xor_operand" "")))]
3190   ""
3191   "")
3192
3193 (define_insn "*xorsi3_compact"
3194   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3195         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3196                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3197   "TARGET_SH1"
3198   "xor  %2,%0"
3199   [(set_attr "type" "arith")])
3200
3201 (define_insn "*xorsi3_media"
3202   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3203         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3204                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3205   "TARGET_SHMEDIA"
3206   "@
3207         xor     %1, %2, %0
3208         xori    %1, %2, %0"
3209   [(set_attr "type" "arith_media")])
3210
3211 ;; Store the complements of the T bit in a register.
3212 (define_insn "xorsi3_movrt"
3213   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3214         (xor:SI (reg:SI T_REG)
3215                 (const_int 1)))]
3216   "TARGET_SH2A"
3217   "movrt\\t%0"
3218   [(set_attr "type" "arith")])
3219
3220 (define_insn "xordi3"
3221   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3222         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3223                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3224   "TARGET_SHMEDIA"
3225   "@
3226         xor     %1, %2, %0
3227         xori    %1, %2, %0"
3228   [(set_attr "type" "arith_media")])
3229
3230 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3231 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3232 (define_split
3233   [(set (match_operand:DI 0 "arith_reg_dest" "")
3234         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3235                           [(match_operand 1 "any_register_operand" "")
3236                            (match_operand 2 "any_register_operand" "")])))]
3237   "TARGET_SHMEDIA"
3238   [(set (match_dup 5) (match_dup 4))
3239    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3240 "
3241 {
3242   enum machine_mode inmode = GET_MODE (operands[1]);
3243   int offset = 0;
3244
3245   if (GET_CODE (operands[0]) == SUBREG)
3246     {
3247       offset = SUBREG_BYTE (operands[0]);
3248       operands[0] = SUBREG_REG (operands[0]);
3249     }
3250   gcc_assert (REG_P (operands[0]));
3251   if (! TARGET_LITTLE_ENDIAN)
3252     offset += 8 - GET_MODE_SIZE (inmode);
3253   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3254 }")
3255 \f
3256 ;; -------------------------------------------------------------------------
3257 ;; Shifts and rotates
3258 ;; -------------------------------------------------------------------------
3259
3260 (define_expand "rotldi3"
3261   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3262         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3263                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3264   "TARGET_SHMEDIA"
3265   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3266
3267 (define_insn "rotldi3_mextr"
3268   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3269         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3270                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3271   "TARGET_SHMEDIA"
3272   "*
3273 {
3274   static char templ[16];
3275
3276   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3277            8 - (int) (INTVAL (operands[2]) >> 3));
3278   return templ;
3279 }"
3280   [(set_attr "type" "arith_media")])
3281
3282 (define_expand "rotrdi3"
3283   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3284         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3285                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3286   "TARGET_SHMEDIA"
3287   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3288
3289 (define_insn "rotrdi3_mextr"
3290   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3291         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3292                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3293   "TARGET_SHMEDIA"
3294   "*
3295 {
3296   static char templ[16];
3297
3298   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3299   return templ;
3300 }"
3301   [(set_attr "type" "arith_media")])
3302
3303 (define_split
3304   [(set (match_operand:DI 0 "arith_reg_dest" "")
3305         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3306                                          "ua_address_operand" "")))
3307                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3308                            (const_int 8))))
3309    (clobber (match_operand:DI 3 "register_operand" ""))]
3310   "TARGET_SHMEDIA"
3311   [(match_dup 4) (match_dup 5)]
3312   "
3313 {
3314   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3315                  (operands[3], operands[1]));
3316   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3317                               GEN_INT (56), GEN_INT (8));
3318 }")
3319
3320 (define_insn "rotlsi3_1"
3321   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3322         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3323                    (const_int 1)))
3324    (set (reg:SI T_REG)
3325         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3326   "TARGET_SH1"
3327   "rotl %0"
3328   [(set_attr "type" "arith")])
3329
3330 (define_insn "rotlsi3_31"
3331   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3332         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3333                    (const_int 31)))
3334    (clobber (reg:SI T_REG))]
3335   "TARGET_SH1"
3336   "rotr %0"
3337   [(set_attr "type" "arith")])
3338
3339 (define_insn "rotlsi3_16"
3340   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3341         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3342                    (const_int 16)))]
3343   "TARGET_SH1"
3344   "swap.w       %1,%0"
3345   [(set_attr "type" "arith")])
3346
3347 (define_expand "rotlsi3"
3348   [(set (match_operand:SI 0 "arith_reg_dest" "")
3349         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3350                    (match_operand:SI 2 "immediate_operand" "")))]
3351   "TARGET_SH1"
3352   "
3353 {
3354   static const char rot_tab[] = {
3355     000, 000, 000, 000, 000, 000, 010, 001,
3356     001, 001, 011, 013, 003, 003, 003, 003,
3357     003, 003, 003, 003, 003, 013, 012, 002,
3358     002, 002, 010, 000, 000, 000, 000, 000,
3359   };
3360
3361   int count, choice;
3362
3363   if (!CONST_INT_P (operands[2]))
3364     FAIL;
3365   count = INTVAL (operands[2]);
3366   choice = rot_tab[count];
3367   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3368     FAIL;
3369   choice &= 7;
3370   switch (choice)
3371     {
3372     case 0:
3373       emit_move_insn (operands[0], operands[1]);
3374       count -= (count & 16) * 2;
3375       break;
3376     case 3:
3377      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3378      count -= 16;
3379      break;
3380     case 1:
3381     case 2:
3382       {
3383         rtx parts[2];
3384         parts[0] = gen_reg_rtx (SImode);
3385         parts[1] = gen_reg_rtx (SImode);
3386         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3387         emit_move_insn (parts[choice-1], operands[1]);
3388         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3389         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3390         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3391         count = (count & ~16) - 8;
3392       }
3393     }
3394
3395   for (; count > 0; count--)
3396     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3397   for (; count < 0; count++)
3398     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3399
3400   DONE;
3401 }")
3402
3403 (define_insn "*rotlhi3_8"
3404   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3405         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3406                    (const_int 8)))]
3407   "TARGET_SH1"
3408   "swap.b       %1,%0"
3409   [(set_attr "type" "arith")])
3410
3411 (define_expand "rotlhi3"
3412   [(set (match_operand:HI 0 "arith_reg_operand" "")
3413         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3414                    (match_operand:HI 2 "immediate_operand" "")))]
3415   "TARGET_SH1"
3416   "
3417 {
3418   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3419     FAIL;
3420 }")
3421
3422 ;;
3423 ;; shift left
3424
3425 (define_insn "ashlsi3_sh2a"
3426   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3427         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3428                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3429   "TARGET_SH2A"
3430   "shad %2,%0"
3431   [(set_attr "type" "arith")
3432    (set_attr "length" "4")])
3433
3434 ;; This pattern is used by init_expmed for computing the costs of shift
3435 ;; insns.
3436
3437 (define_insn_and_split "ashlsi3_std"
3438   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3439         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3440                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3441    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3442   "TARGET_SH3
3443    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3444   "@
3445    shld %2,%0
3446    add  %0,%0
3447    shll%O2      %0
3448    #"
3449   "TARGET_SH3
3450    && reload_completed
3451    && CONST_INT_P (operands[2])
3452    && ! satisfies_constraint_P27 (operands[2])"
3453   [(set (match_dup 3) (match_dup 2))
3454    (parallel
3455     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3456      (clobber (match_dup 4))])]
3457   "operands[4] = gen_rtx_SCRATCH (SImode);"
3458   [(set_attr "length" "*,*,*,4")
3459    (set_attr "type" "dyn_shift,arith,arith,arith")])
3460
3461 (define_insn "ashlhi3_k"
3462   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3463         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3464                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3465   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3466   "@
3467         add     %0,%0
3468         shll%O2 %0"
3469   [(set_attr "type" "arith")])
3470
3471 (define_insn "ashlsi3_n"
3472   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3473         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3474                    (match_operand:SI 2 "const_int_operand" "n")))
3475    (clobber (reg:SI T_REG))]
3476   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3477   "#"
3478   [(set (attr "length")
3479         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3480                (const_string "2")
3481                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3482                (const_string "4")
3483                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3484                (const_string "6")]
3485               (const_string "8")))
3486    (set_attr "type" "arith")])
3487
3488 (define_split
3489   [(set (match_operand:SI 0 "arith_reg_dest" "")
3490         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3491                    (match_operand:SI 2 "const_int_operand" "")))
3492    (clobber (reg:SI T_REG))]
3493   "TARGET_SH1 && reload_completed"
3494   [(use (reg:SI R0_REG))]
3495   "
3496 {
3497   gen_shifty_op (ASHIFT, operands);
3498   DONE;
3499 }")
3500
3501 (define_insn "ashlsi3_media"
3502   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3503         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3504                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3505   "TARGET_SHMEDIA"
3506   "@
3507         shlld.l %1, %2, %0
3508         shlli.l %1, %2, %0"
3509   [(set_attr "type" "arith_media")
3510    (set_attr "highpart" "ignore")])
3511
3512 (define_expand "ashlsi3"
3513   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3514                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3515                               (match_operand:SI 2 "nonmemory_operand" "")))
3516               (clobber (reg:SI T_REG))])]
3517   ""
3518   "
3519 {
3520   if (TARGET_SHMEDIA)
3521     {
3522       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3523       DONE;
3524     }
3525   if (CONST_INT_P (operands[2])
3526       && sh_dynamicalize_shift_p (operands[2]))
3527     operands[2] = force_reg (SImode, operands[2]);
3528   if (TARGET_SH3)
3529     {
3530       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3531       DONE;
3532     }
3533   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3534     FAIL;
3535 }")
3536
3537 (define_insn "*ashlhi3_n"
3538   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3539         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3540                    (match_operand:HI 2 "const_int_operand" "n")))
3541    (clobber (reg:SI T_REG))]
3542   "TARGET_SH1"
3543   "#"
3544   [(set (attr "length")
3545         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3546                (const_string "2")
3547                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3548                (const_string "4")]
3549               (const_string "6")))
3550    (set_attr "type" "arith")])
3551
3552 (define_expand "ashlhi3"
3553   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3554                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3555                               (match_operand:SI 2 "nonmemory_operand" "")))
3556               (clobber (reg:SI T_REG))])]
3557   "TARGET_SH1"
3558   "
3559 {
3560   if (!CONST_INT_P (operands[2]))
3561     FAIL;
3562   /* It may be possible to call gen_ashlhi3 directly with more generic
3563      operands.  Make sure operands[1] is a HImode register here.  */
3564   if (!arith_reg_operand (operands[1], HImode))
3565     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3566 }")
3567
3568 (define_split
3569   [(set (match_operand:HI 0 "arith_reg_dest" "")
3570         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3571                    (match_operand:HI 2 "const_int_operand" "")))
3572    (clobber (reg:SI T_REG))]
3573   "TARGET_SH1 && reload_completed"
3574   [(use (reg:SI R0_REG))]
3575   "
3576 {
3577   gen_shifty_hi_op (ASHIFT, operands);
3578   DONE;
3579 }")
3580
3581 ;
3582 ; arithmetic shift right
3583 ;
3584
3585 (define_insn "ashrsi3_sh2a"
3586   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3587         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3588                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3589   "TARGET_SH2A"
3590   "shad %2,%0"
3591   [(set_attr "type" "dyn_shift")
3592    (set_attr "length" "4")])
3593
3594 (define_insn "ashrsi3_k"
3595   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3596         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3597                      (match_operand:SI 2 "const_int_operand" "M")))
3598    (clobber (reg:SI T_REG))]
3599   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3600   "shar %0"
3601   [(set_attr "type" "arith")])
3602
3603 ;; We can't do HImode right shifts correctly unless we start out with an
3604 ;; explicit zero / sign extension; doing that would result in worse overall
3605 ;; code, so just let the machine independent code widen the mode.
3606 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3607
3608
3609 ;; ??? This should be a define expand.
3610
3611 (define_insn "ashrsi2_16"
3612   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3613         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3614                      (const_int 16)))]
3615   "TARGET_SH1"
3616   "#"
3617   [(set_attr "length" "4")])
3618
3619 (define_split
3620   [(set (match_operand:SI 0 "arith_reg_dest" "")
3621         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3622                      (const_int 16)))]
3623   "TARGET_SH1"
3624   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3625    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3626   "operands[2] = gen_lowpart (HImode, operands[0]);")
3627
3628 ;; ??? This should be a define expand.
3629
3630 (define_insn "ashrsi2_31"
3631   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3632         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3633                      (const_int 31)))
3634    (clobber (reg:SI T_REG))]
3635   "TARGET_SH1"
3636   "#"
3637   [(set_attr "length" "4")])
3638
3639 (define_split
3640   [(set (match_operand:SI 0 "arith_reg_dest" "")
3641         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3642                      (const_int 31)))
3643    (clobber (reg:SI T_REG))]
3644   "TARGET_SH1"
3645   [(const_int 0)]
3646   "
3647 {
3648   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3649   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3650   DONE;
3651 }")
3652
3653 (define_peephole2
3654   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3655    (set (reg:SI T_REG)
3656         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3657   "TARGET_SH1
3658    && peep2_reg_dead_p (2, operands[0])
3659    && peep2_reg_dead_p (2, operands[1])"
3660   [(const_int 0)]
3661   "
3662 {
3663   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3664   DONE;
3665 }")
3666
3667 (define_insn "ashlsi_c"
3668   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3669         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3670    (set (reg:SI T_REG)
3671         (lt:SI (match_dup 1) (const_int 0)))]
3672   "TARGET_SH1"
3673   "shll %0"
3674   [(set_attr "type" "arith")])
3675
3676 (define_insn "*ashlsi_c_void"
3677   [(set (reg:SI T_REG)
3678         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3679    (clobber (match_scratch:SI 1 "=0"))]
3680   "TARGET_SH1 && cse_not_expected"
3681   "shll %0"
3682   [(set_attr "type" "arith")])
3683
3684 (define_insn "ashrsi3_d"
3685   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3686         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3687                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3688   "TARGET_SH3"
3689   "shad %2,%0"
3690   [(set_attr "type" "dyn_shift")])
3691
3692 (define_insn "ashrsi3_n"
3693   [(set (reg:SI R4_REG)
3694         (ashiftrt:SI (reg:SI R4_REG)
3695                      (match_operand:SI 0 "const_int_operand" "i")))
3696    (clobber (reg:SI T_REG))
3697    (clobber (reg:SI PR_REG))
3698    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3699   "TARGET_SH1"
3700   "jsr  @%1%#"
3701   [(set_attr "type" "sfunc")
3702    (set_attr "needs_delay_slot" "yes")])
3703
3704 (define_insn "ashrsi3_media"
3705   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3706         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3707                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3708   "TARGET_SHMEDIA"
3709   "@
3710         shard.l %1, %2, %0
3711         shari.l %1, %2, %0"
3712   [(set_attr "type" "arith_media")
3713    (set_attr "highpart" "ignore")])
3714
3715 (define_expand "ashrsi3"
3716   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3717                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3718                                 (match_operand:SI 2 "nonmemory_operand" "")))
3719               (clobber (reg:SI T_REG))])]
3720   ""
3721   "
3722 {
3723   if (TARGET_SHMEDIA)
3724     {
3725       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3726       DONE;
3727     }
3728   if (expand_ashiftrt (operands))
3729     DONE;
3730   else
3731     FAIL;
3732 }")
3733
3734 ;; logical shift right
3735
3736 (define_insn "lshrsi3_sh2a"
3737   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3738         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3739                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3740   "TARGET_SH2A"
3741   "shld %2,%0"
3742   [(set_attr "type" "dyn_shift")
3743    (set_attr "length" "4")])
3744
3745 (define_insn "lshrsi3_d"
3746   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3747         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3748                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3749   "TARGET_SH3"
3750   "shld %2,%0"
3751   [(set_attr "type" "dyn_shift")])
3752
3753 ;;  Only the single bit shift clobbers the T bit.
3754
3755 (define_insn "lshrsi3_m"
3756   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3757         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3758                      (match_operand:SI 2 "const_int_operand" "M")))
3759    (clobber (reg:SI T_REG))]
3760   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3761   "shlr %0"
3762   [(set_attr "type" "arith")])
3763
3764 (define_insn "lshrsi3_k"
3765   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3766         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3767                      (match_operand:SI 2 "const_int_operand" "P27")))]
3768   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3769    && ! satisfies_constraint_M (operands[2])"
3770   "shlr%O2      %0"
3771   [(set_attr "type" "arith")])
3772
3773 (define_insn "lshrsi3_n"
3774   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3775         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3776                      (match_operand:SI 2 "const_int_operand" "n")))
3777    (clobber (reg:SI T_REG))]
3778   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3779   "#"
3780   [(set (attr "length")
3781         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3782                (const_string "2")
3783                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3784                (const_string "4")
3785                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3786                (const_string "6")]
3787               (const_string "8")))
3788    (set_attr "type" "arith")])
3789
3790 (define_split
3791   [(set (match_operand:SI 0 "arith_reg_dest" "")
3792         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3793                      (match_operand:SI 2 "const_int_operand" "")))
3794    (clobber (reg:SI T_REG))]
3795   "TARGET_SH1 && reload_completed"
3796   [(use (reg:SI R0_REG))]
3797   "
3798 {
3799   gen_shifty_op (LSHIFTRT, operands);
3800   DONE;
3801 }")
3802
3803 (define_insn "lshrsi3_media"
3804   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3805         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3806                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3807   "TARGET_SHMEDIA"
3808   "@
3809         shlrd.l %1, %2, %0
3810         shlri.l %1, %2, %0"
3811   [(set_attr "type" "arith_media")
3812    (set_attr "highpart" "ignore")])
3813
3814 (define_expand "lshrsi3"
3815   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3816                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3817                                 (match_operand:SI 2 "nonmemory_operand" "")))
3818               (clobber (reg:SI T_REG))])]
3819   ""
3820   "
3821 {
3822   if (TARGET_SHMEDIA)
3823     {
3824       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3825       DONE;
3826     }
3827   if (CONST_INT_P (operands[2])
3828       && sh_dynamicalize_shift_p (operands[2]))
3829     operands[2] = force_reg (SImode, operands[2]);
3830   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3831     {
3832       rtx count = copy_to_mode_reg (SImode, operands[2]);
3833       emit_insn (gen_negsi2 (count, count));
3834       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3835       DONE;
3836     }
3837   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3838     FAIL;
3839 }")
3840
3841 ;; ??? This should be a define expand.
3842
3843 (define_insn "ashldi3_k"
3844   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3845         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3846                    (const_int 1)))
3847    (clobber (reg:SI T_REG))]
3848   "TARGET_SH1"
3849   "shll %R0\;rotcl      %S0"
3850   [(set_attr "length" "4")
3851    (set_attr "type" "arith")])
3852
3853 ;; Expander for DImode shift left with SImode operations.
3854
3855 (define_expand "ashldi3_std"
3856   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3857         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3858                    (match_operand:DI 2 "const_int_operand" "n")))]
3859   "TARGET_SH1 && INTVAL (operands[2]) < 32"
3860   "
3861 {
3862   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3863   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3864   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3865   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3866   rtx dst = gen_reg_rtx (DImode);
3867   rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3868   rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3869   rtx tmp0, tmp1;
3870
3871   tmp0 = gen_reg_rtx (SImode);
3872   tmp1 = gen_reg_rtx (SImode);
3873   emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3874   emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));  
3875   emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));  
3876   emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3877   emit_move_insn (operands[0], dst);
3878   DONE;
3879 }")
3880
3881 (define_insn "ashldi3_media"
3882   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3883         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3884                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3885   "TARGET_SHMEDIA"
3886   "@
3887         shlld   %1, %2, %0
3888         shlli   %1, %2, %0"
3889   [(set_attr "type" "arith_media")])
3890
3891 (define_insn "*ashldisi3_media"
3892   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3893         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3894                    (match_operand:DI 2 "const_int_operand" "n")))]
3895   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3896   "shlli.l      %1, %2, %0"
3897   [(set_attr "type" "arith_media")
3898    (set_attr "highpart" "ignore")])
3899
3900 (define_expand "ashldi3"
3901   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3902                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3903                               (match_operand:DI 2 "immediate_operand" "")))
3904               (clobber (reg:SI T_REG))])]
3905   ""
3906   "
3907 {
3908   if (TARGET_SHMEDIA)
3909     {
3910       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3911       DONE;
3912     }
3913   if (CONST_INT_P (operands[2])
3914       && INTVAL (operands[2]) == 1)
3915     {
3916       emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3917       DONE;
3918     }
3919   else if (CONST_INT_P (operands[2])
3920       && INTVAL (operands[2]) < 32)
3921     {
3922       emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3923       DONE;
3924     }
3925   else
3926     FAIL;
3927 }")
3928
3929 ;; ??? This should be a define expand.
3930
3931 (define_insn "lshrdi3_k"
3932   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3933         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3934                      (const_int 1)))
3935    (clobber (reg:SI T_REG))]
3936   "TARGET_SH1"
3937   "shlr %S0\;rotcr      %R0"
3938   [(set_attr "length" "4")
3939    (set_attr "type" "arith")])
3940
3941 (define_insn "lshrdi3_media"
3942   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3943         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3944                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3945   "TARGET_SHMEDIA
3946    && (arith_reg_dest (operands[0], DImode)
3947        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3948   "@
3949         shlrd   %1, %2, %0
3950         shlri   %1, %2, %0"
3951   [(set_attr "type" "arith_media")])
3952
3953 (define_insn "*lshrdisi3_media"
3954   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3955         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3956                      (match_operand:DI 2 "const_int_operand" "n")))]
3957   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3958   "shlri.l      %1, %2, %0"
3959   [(set_attr "type" "arith_media")
3960    (set_attr "highpart" "ignore")])
3961
3962 (define_expand "lshrdi3"
3963   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3964                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3965                                (match_operand:DI 2 "immediate_operand" "")))
3966              (clobber (reg:SI T_REG))])]
3967   ""
3968   "
3969 {
3970   if (TARGET_SHMEDIA)
3971     {
3972       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3973       DONE;
3974     }
3975   if (!CONST_INT_P (operands[2])
3976       || INTVAL (operands[2]) != 1)
3977     FAIL;
3978 }")
3979
3980 ;; ??? This should be a define expand.
3981
3982 (define_insn "ashrdi3_k"
3983   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3984         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3985                      (const_int 1)))
3986    (clobber (reg:SI T_REG))]
3987   "TARGET_SH1"
3988   "shar %S0\;rotcr      %R0"
3989   [(set_attr "length" "4")
3990    (set_attr "type" "arith")])
3991
3992 (define_insn "ashrdi3_media"
3993   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3994         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3995                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3996   "TARGET_SHMEDIA
3997    && (arith_reg_dest (operands[0], DImode)
3998        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
3999   "@
4000         shard   %1, %2, %0
4001         shari   %1, %2, %0"
4002   [(set_attr "type" "arith_media")])
4003
4004 (define_insn "*ashrdisi3_media"
4005   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4006         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4007                      (match_operand:DI 2 "const_int_operand" "n")))]
4008   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4009   "shari.l      %1, %2, %0"
4010   [(set_attr "type" "arith_media")
4011    (set_attr "highpart" "ignore")])
4012
4013 (define_insn "ashrdisi3_media_high"
4014   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4015         (truncate:SI
4016            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4017                         (match_operand:DI 2 "const_int_operand" "n"))))]
4018   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4019   "shari        %1, %2, %0"
4020   [(set_attr "type" "arith_media")])
4021
4022 (define_insn "ashrdisi3_media_opaque"
4023   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4024         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4025                     (match_operand:DI 2 "const_int_operand" "n")]
4026          UNSPEC_ASHIFTRT))]
4027   "TARGET_SHMEDIA"
4028   "shari        %1, %2, %0"
4029   [(set_attr "type" "arith_media")])
4030
4031 (define_expand "ashrdi3"
4032   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4033                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4034                                 (match_operand:DI 2 "immediate_operand" "")))
4035               (clobber (reg:SI T_REG))])]
4036   ""
4037   "
4038 {
4039   if (TARGET_SHMEDIA)
4040     {
4041       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4042       DONE;
4043     }
4044   if (!CONST_INT_P (operands[2])
4045       || INTVAL (operands[2]) != 1)
4046     FAIL;
4047 }")
4048
4049 ;; combined left/right shift
4050
4051 (define_split
4052   [(set (match_operand:SI 0 "register_operand" "")
4053         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4054                            (match_operand:SI 2 "const_int_operand" ""))
4055                 (match_operand:SI 3 "const_int_operand" "")))]
4056   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4057   [(use (reg:SI R0_REG))]
4058   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4059    DONE;")
4060
4061 (define_split
4062   [(set (match_operand:SI 0 "register_operand" "")
4063         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4064                            (match_operand:SI 2 "const_int_operand" ""))
4065                 (match_operand:SI 3 "const_int_operand" "")))
4066    (clobber (reg:SI T_REG))]
4067   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4068   [(use (reg:SI R0_REG))]
4069   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4070    DONE;")
4071
4072 (define_insn ""
4073   [(set (match_operand:SI 0 "register_operand" "=r")
4074         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4075                            (match_operand:SI 2 "const_int_operand" "n"))
4076                 (match_operand:SI 3 "const_int_operand" "n")))
4077    (clobber (reg:SI T_REG))]
4078   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4079  "#"
4080   [(set (attr "length")
4081         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4082                (const_string "4")
4083                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4084                (const_string "6")
4085                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4086                (const_string "8")
4087                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4088                (const_string "10")
4089                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4090                (const_string "12")
4091                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4092                (const_string "14")
4093                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4094                (const_string "16")]
4095               (const_string "18")))
4096    (set_attr "type" "arith")])
4097
4098 (define_insn ""
4099   [(set (match_operand:SI 0 "register_operand" "=z")
4100         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4101                            (match_operand:SI 2 "const_int_operand" "n"))
4102                 (match_operand:SI 3 "const_int_operand" "n")))
4103    (clobber (reg:SI T_REG))]
4104   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4105  "#"
4106   [(set (attr "length")
4107         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4108                (const_string "4")
4109                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4110                (const_string "6")
4111                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4112                (const_string "8")]
4113               (const_string "10")))
4114    (set_attr "type" "arith")])
4115
4116 ;; shift left / and combination with a scratch register: The combine pass
4117 ;; does not accept the individual instructions, even though they are
4118 ;; cheap.  But it needs a precise description so that it is usable after
4119 ;; reload.
4120 (define_insn "and_shl_scratch"
4121   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4122         (lshiftrt:SI
4123          (ashift:SI
4124           (and:SI
4125            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4126                         (match_operand:SI 2 "const_int_operand" "N,n"))
4127            (match_operand:SI 3 "" "0,r"))
4128           (match_operand:SI 4 "const_int_operand" "n,n"))
4129          (match_operand:SI 5 "const_int_operand" "n,n")))
4130    (clobber (reg:SI T_REG))]
4131   "TARGET_SH1"
4132   "#"
4133   [(set (attr "length")
4134         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4135                (const_string "4")
4136                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4137                (const_string "6")
4138                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4139                (const_string "8")
4140                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4141                (const_string "10")]
4142               (const_string "12")))
4143    (set_attr "type" "arith")])
4144
4145 (define_split
4146   [(set (match_operand:SI 0 "register_operand" "")
4147         (lshiftrt:SI
4148          (ashift:SI
4149           (and:SI
4150            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4151                         (match_operand:SI 2 "const_int_operand" ""))
4152            (match_operand:SI 3 "register_operand" ""))
4153           (match_operand:SI 4 "const_int_operand" ""))
4154          (match_operand:SI 5 "const_int_operand" "")))
4155    (clobber (reg:SI T_REG))]
4156   "TARGET_SH1"
4157   [(use (reg:SI R0_REG))]
4158   "
4159 {
4160   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4161
4162   if (INTVAL (operands[2]))
4163     {
4164       gen_shifty_op (LSHIFTRT, operands);
4165     }
4166   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4167   operands[2] = operands[4];
4168   gen_shifty_op (ASHIFT, operands);
4169   if (INTVAL (operands[5]))
4170     {
4171       operands[2] = operands[5];
4172       gen_shifty_op (LSHIFTRT, operands);
4173     }
4174   DONE;
4175 }")
4176
4177 ;; signed left/right shift combination.
4178 (define_split
4179   [(set (match_operand:SI 0 "register_operand" "")
4180         (sign_extract:SI
4181          (ashift:SI (match_operand:SI 1 "register_operand" "")
4182                     (match_operand:SI 2 "const_int_operand" ""))
4183          (match_operand:SI 3 "const_int_operand" "")
4184          (const_int 0)))
4185    (clobber (reg:SI T_REG))]
4186   "TARGET_SH1"
4187   [(use (reg:SI R0_REG))]
4188   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4189    DONE;")
4190
4191 (define_insn "shl_sext_ext"
4192   [(set (match_operand:SI 0 "register_operand" "=r")
4193         (sign_extract:SI
4194          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4195                     (match_operand:SI 2 "const_int_operand" "n"))
4196          (match_operand:SI 3 "const_int_operand" "n")
4197          (const_int 0)))
4198    (clobber (reg:SI T_REG))]
4199   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4200   "#"
4201   [(set (attr "length")
4202         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4203                (const_string "2")
4204                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4205                (const_string "4")
4206                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4207                (const_string "6")
4208                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4209                (const_string "8")
4210                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4211                (const_string "10")
4212                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4213                (const_string "12")
4214                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4215                (const_string "14")
4216                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4217                (const_string "16")]
4218               (const_string "18")))
4219     (set_attr "type" "arith")])
4220
4221 (define_insn "shl_sext_sub"
4222   [(set (match_operand:SI 0 "register_operand" "=z")
4223         (sign_extract:SI
4224          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4225                     (match_operand:SI 2 "const_int_operand" "n"))
4226          (match_operand:SI 3 "const_int_operand" "n")
4227          (const_int 0)))
4228    (clobber (reg:SI T_REG))]
4229   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4230   "#"
4231   [(set (attr "length")
4232         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4233                (const_string "6")
4234                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4235                (const_string "8")
4236                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4237                (const_string "10")
4238                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4239                (const_string "12")]
4240               (const_string "14")))
4241     (set_attr "type" "arith")])
4242
4243 ;; These patterns are found in expansions of DImode shifts by 16, and
4244 ;; allow the xtrct instruction to be generated from C source.
4245
4246 (define_insn "xtrct_left"
4247   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4248         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4249                            (const_int 16))
4250                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4251                              (const_int 16))))]
4252   "TARGET_SH1"
4253   "xtrct        %1,%0"
4254   [(set_attr "type" "arith")])
4255
4256 (define_insn "xtrct_right"
4257   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4258         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4259                              (const_int 16))
4260                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4261                            (const_int 16))))]
4262   "TARGET_SH1"
4263   "xtrct        %2,%0"
4264   [(set_attr "type" "arith")])
4265
4266 ;; -------------------------------------------------------------------------
4267 ;; Unary arithmetic
4268 ;; -------------------------------------------------------------------------
4269
4270 (define_insn "negc"
4271   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4272         (neg:SI (plus:SI (reg:SI T_REG)
4273                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4274    (set (reg:SI T_REG)
4275         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4276                (const_int 0)))]
4277   "TARGET_SH1"
4278   "negc %1,%0"
4279   [(set_attr "type" "arith")])
4280
4281 (define_insn "*negdi_media"
4282   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4283         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4284   "TARGET_SHMEDIA"
4285   "sub  r63, %1, %0"
4286   [(set_attr "type" "arith_media")])
4287
4288 (define_expand "negdi2"
4289   [(set (match_operand:DI 0 "arith_reg_operand" "")
4290         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4291   ""
4292   "
4293 {
4294   if (TARGET_SH1)
4295     {
4296       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4297       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4298
4299       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4300       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4301
4302       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4303       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4304
4305       emit_insn (gen_clrt ());
4306       emit_insn (gen_negc (low_dst, low_src));
4307       emit_insn (gen_negc (high_dst, high_src));
4308       DONE;
4309     }
4310 }")
4311
4312 (define_insn "negsi2"
4313   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4314         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4315   "TARGET_SH1"
4316   "neg  %1,%0"
4317   [(set_attr "type" "arith")])
4318
4319 (define_insn "one_cmplsi2"
4320   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4321         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4322   "TARGET_SH1"
4323   "not  %1,%0"
4324   [(set_attr "type" "arith")])
4325
4326 (define_expand "one_cmpldi2"
4327   [(set (match_operand:DI 0 "arith_reg_dest" "")
4328         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4329                 (const_int -1)))]
4330   "TARGET_SHMEDIA" "")
4331
4332 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4333    This can be used as some kind of conditional execution, which is useful
4334    for abs.  */
4335 (define_split
4336   [(set (match_operand:SI 0 "arith_reg_dest" "")
4337         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4338                          (match_operand:SI 1 "arith_reg_operand" ""))
4339                  (reg:SI T_REG)))]
4340   "TARGET_HARD_SH4"
4341   [(const_int 0)]
4342   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4343    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4344    DONE;")
4345
4346 (define_insn "cneg"
4347   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4348         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4349                       (match_operand:SI 1 "arith_reg_operand" "0")
4350                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4351   "TARGET_HARD_SH4"
4352   "bf 0f\;neg %2,%0\\n0:"
4353   [(set_attr "type" "arith") ;; poor approximation
4354    (set_attr "length" "4")])
4355
4356 \f
4357 ;; -------------------------------------------------------------------------
4358 ;; Zero extension instructions
4359 ;; -------------------------------------------------------------------------
4360
4361 (define_insn "zero_extendsidi2"
4362   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4363         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4364   "TARGET_SHMEDIA"
4365   "addz.l       %1, r63, %0"
4366   [(set_attr "type" "arith_media")
4367    (set_attr "highpart" "extend")])
4368
4369 (define_insn "zero_extendhidi2"
4370   [(set (match_operand:DI 0 "register_operand" "=r,r")
4371         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4372   "TARGET_SHMEDIA"
4373   "@
4374         #
4375         ld%M1.uw        %m1, %0"
4376   [(set_attr "type" "*,load_media")
4377    (set (attr "highpart")
4378         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4379                (const_string "user")]
4380               (const_string "ignore")))])
4381
4382 (define_split
4383   [(set (match_operand:DI 0 "register_operand" "")
4384         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4385   "TARGET_SHMEDIA && reload_completed"
4386   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4387    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4388   "
4389 {
4390   if (GET_CODE (operands[1]) == TRUNCATE)
4391     operands[1] = XEXP (operands[1], 0);
4392 }")
4393
4394 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4395 ;; reload the entire truncate expression.
4396 (define_insn_and_split "*loaddi_trunc"
4397   [(set (match_operand 0 "any_register_operand" "=r")
4398         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4399   "TARGET_SHMEDIA && reload_completed"
4400   "#"
4401   "TARGET_SHMEDIA && reload_completed"
4402   [(set (match_dup 0) (match_dup 1))]
4403   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4404
4405 (define_insn "zero_extendqidi2"
4406   [(set (match_operand:DI 0 "register_operand" "=r,r")
4407         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4408   "TARGET_SHMEDIA"
4409   "@
4410         andi    %1, 255, %0
4411         ld%M1.ub        %m1, %0"
4412   [(set_attr "type" "arith_media,load_media")
4413    (set (attr "highpart")
4414         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4415                (const_string "user")]
4416               (const_string "ignore")))])
4417
4418 (define_expand "zero_extendhisi2"
4419   [(set (match_operand:SI 0 "arith_reg_operand" "")
4420         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4421   ""
4422   "
4423 {
4424   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4425     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4426 }")
4427
4428 (define_insn "*zero_extendhisi2_compact"
4429   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4430         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4431   "TARGET_SH1"
4432   "extu.w       %1,%0"
4433   [(set_attr "type" "arith")])
4434
4435 (define_insn "*zero_extendhisi2_media"
4436   [(set (match_operand:SI 0 "register_operand" "=r,r")
4437         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4438   "TARGET_SHMEDIA"
4439   "@
4440         #
4441         ld%M1.uw        %m1, %0"
4442   [(set_attr "type" "arith_media,load_media")
4443    (set (attr "highpart")
4444         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4445                (const_string "user")]
4446               (const_string "ignore")))])
4447
4448 (define_split
4449   [(set (match_operand:SI 0 "register_operand" "")
4450         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4451   "TARGET_SHMEDIA && reload_completed"
4452   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4453    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4454   "
4455 {
4456   rtx op1 = operands[1];
4457
4458   if (GET_CODE (op1) == TRUNCATE)
4459     op1 = XEXP (op1, 0);
4460   operands[2]
4461     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4462                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4463 }")
4464
4465 (define_expand "zero_extendqisi2"
4466   [(set (match_operand:SI 0 "arith_reg_operand" "")
4467         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4468   ""
4469   "
4470 {
4471   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4472     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4473 }")
4474
4475 (define_insn "*zero_extendqisi2_compact"
4476   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4477         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4478   "TARGET_SH1"
4479   "extu.b       %1,%0"
4480   [(set_attr "type" "arith")])
4481
4482 (define_insn "*zero_extendqisi2_media"
4483   [(set (match_operand:SI 0 "register_operand" "=r,r")
4484         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4485   "TARGET_SHMEDIA"
4486   "@
4487         andi    %1, 255, %0
4488         ld%M1.ub        %m1, %0"
4489   [(set_attr "type" "arith_media,load_media")
4490    (set (attr "highpart")
4491         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4492                (const_string "user")]
4493               (const_string "ignore")))])
4494
4495 (define_insn "zero_extendqihi2"
4496   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4497         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4498   "TARGET_SH1"
4499   "extu.b       %1,%0"
4500   [(set_attr "type" "arith")])
4501
4502 ;; -------------------------------------------------------------------------
4503 ;; Sign extension instructions
4504 ;; -------------------------------------------------------------------------
4505
4506 ;; ??? This should be a define expand.
4507 ;; ??? Or perhaps it should be dropped?
4508
4509 ;; convert_move generates good code for SH[1-4].
4510 (define_insn "extendsidi2"
4511   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4512         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4513   "TARGET_SHMEDIA"
4514   "@
4515         add.l   %1, r63, %0
4516         ld%M1.l %m1, %0
4517         fmov.sl %1, %0"
4518   [(set_attr "type" "arith_media,load_media,fpconv_media")
4519    (set (attr "highpart")
4520         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4521                (const_string "user")]
4522               (const_string "extend")))])
4523
4524 (define_insn "extendhidi2"
4525   [(set (match_operand:DI 0 "register_operand" "=r,r")
4526         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4527   "TARGET_SHMEDIA"
4528   "@
4529         #
4530         ld%M1.w %m1, %0"
4531   [(set_attr "type" "*,load_media")
4532    (set (attr "highpart")
4533         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4534                (const_string "user")]
4535               (const_string "ignore")))])
4536
4537 (define_split
4538   [(set (match_operand:DI 0 "register_operand" "")
4539         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4540   "TARGET_SHMEDIA && reload_completed"
4541   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4542    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4543   "
4544 {
4545   if (GET_CODE (operands[1]) == TRUNCATE)
4546     operands[1] = XEXP (operands[1], 0);
4547 }")
4548
4549 (define_insn "extendqidi2"
4550   [(set (match_operand:DI 0 "register_operand" "=r,r")
4551         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4552   "TARGET_SHMEDIA"
4553   "@
4554         #
4555         ld%M1.b %m1, %0"
4556   [(set_attr "type" "*,load_media")
4557    (set (attr "highpart")
4558         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4559                (const_string "user")]
4560               (const_string "ignore")))])
4561
4562 (define_split
4563   [(set (match_operand:DI 0 "register_operand" "")
4564         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4565   "TARGET_SHMEDIA && reload_completed"
4566   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4567    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4568   "
4569 {
4570   if (GET_CODE (operands[1]) == TRUNCATE)
4571     operands[1] = XEXP (operands[1], 0);
4572 }")
4573
4574 (define_expand "extendhisi2"
4575   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4576         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4577   ""
4578   "")
4579
4580 (define_insn "*extendhisi2_compact"
4581   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4582         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4583   "TARGET_SH1"
4584   "@
4585         exts.w  %1,%0
4586         mov.w   %1,%0"
4587   [(set_attr "type" "arith,load")])
4588
4589 (define_insn "*extendhisi2_media"
4590   [(set (match_operand:SI 0 "register_operand" "=r,r")
4591         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4592   "TARGET_SHMEDIA"
4593   "@
4594         #
4595         ld%M1.w %m1, %0"
4596   [(set_attr "type" "arith_media,load_media")
4597    (set (attr "highpart")
4598         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4599                (const_string "user")]
4600               (const_string "ignore")))])
4601
4602 (define_split
4603   [(set (match_operand:SI 0 "register_operand" "")
4604         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4605   "TARGET_SHMEDIA && reload_completed"
4606   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4607    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4608   "
4609 {
4610   rtx op1 = operands[1];
4611   if (GET_CODE (op1) == TRUNCATE)
4612     op1 = XEXP (op1, 0);
4613   operands[2]
4614     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4615                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4616 }")
4617
4618 (define_expand "extendqisi2"
4619   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4620         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4621   ""
4622   "")
4623
4624 (define_insn "*extendqisi2_compact"
4625   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4626         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4627   "TARGET_SH1"
4628   "@
4629         exts.b  %1,%0
4630         mov.b   %1,%0"
4631   [(set_attr "type" "arith,load")
4632    (set_attr_alternative "length"
4633      [(const_int 2)
4634        (if_then_else
4635         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4636         (const_int 4) (const_int 2))])])
4637
4638 (define_insn "*extendqisi2_media"
4639   [(set (match_operand:SI 0 "register_operand" "=r,r")
4640         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4641   "TARGET_SHMEDIA"
4642   "@
4643         #
4644         ld%M1.b %m1, %0"
4645   [(set_attr "type" "arith_media,load_media")
4646    (set (attr "highpart")
4647         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4648                (const_string "user")]
4649               (const_string "ignore")))])
4650
4651 (define_split
4652   [(set (match_operand:SI 0 "register_operand" "")
4653         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4654   "TARGET_SHMEDIA && reload_completed"
4655   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4656    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4657    "
4658 {
4659   rtx op1 = operands[1];
4660   if (GET_CODE (op1) == TRUNCATE)
4661     op1 = XEXP (op1, 0);
4662   operands[2]
4663     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4664                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4665 }")
4666
4667 (define_insn "extendqihi2"
4668   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4669         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4670   "TARGET_SH1"
4671   "@
4672         exts.b  %1,%0
4673         mov.b   %1,%0"
4674   [(set_attr "type" "arith,load")
4675    (set_attr_alternative "length"
4676      [(const_int 2)
4677        (if_then_else
4678         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4679         (const_int 4) (const_int 2))])])
4680
4681 /* It would seem useful to combine the truncXi patterns into the movXi
4682    patterns, but unary operators are ignored when matching constraints,
4683    so we need separate patterns.  */
4684 (define_insn "truncdisi2"
4685   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4686         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4687   "TARGET_SHMEDIA"
4688   "@
4689         add.l   %1, r63, %0
4690         st%M0.l %m0, %1
4691         fst%M0.s        %m0, %T1
4692         fmov.ls %1, %0
4693         fmov.sl %T1, %0
4694         fmov.s  %T1, %0"
4695   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4696    (set (attr "highpart")
4697         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4698                (const_string "user")]
4699               (const_string "extend")))])
4700
4701 (define_insn "truncdihi2"
4702   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4703         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4704   "TARGET_SHMEDIA"
4705   "@
4706         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4707         st%M0.w %m0, %1"
4708   [(set_attr "type"   "arith_media,store_media")
4709    (set_attr "length" "8,4")
4710    (set (attr "highpart")
4711         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4712                (const_string "user")]
4713               (const_string "extend")))])
4714
4715 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4716 ; Because we use zero extension, we can't provide signed QImode compares
4717 ; using a simple compare or conditional branch insn.
4718 (define_insn "truncdiqi2"
4719   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4720         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4721   "TARGET_SHMEDIA"
4722   "@
4723         andi    %1, 255, %0
4724         st%M0.b %m0, %1"
4725   [(set_attr "type"   "arith_media,store")
4726    (set (attr "highpart")
4727         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4728                (const_string "user")]
4729               (const_string "extend")))])
4730 ;; -------------------------------------------------------------------------
4731 ;; Move instructions
4732 ;; -------------------------------------------------------------------------
4733
4734 ;; define push and pop so it is easy for sh.c
4735 ;; We can't use push and pop on SHcompact because the stack must always
4736 ;; be 8-byte aligned.
4737
4738 (define_expand "push"
4739   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4740         (match_operand:SI 0 "register_operand" "r,l,x"))]
4741   "TARGET_SH1 && ! TARGET_SH5"
4742   "")
4743
4744 (define_expand "pop"
4745   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4746         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4747   "TARGET_SH1 && ! TARGET_SH5"
4748   "")
4749
4750 (define_expand "push_e"
4751   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4752                    (match_operand:SF 0 "" ""))
4753               (use (reg:PSI FPSCR_REG))
4754               (clobber (scratch:SI))])]
4755   "TARGET_SH1 && ! TARGET_SH5"
4756   "")
4757
4758 (define_insn "push_fpul"
4759   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4760   "TARGET_SH2E && ! TARGET_SH5"
4761   "sts.l        fpul,@-r15"
4762   [(set_attr "type" "fstore")
4763    (set_attr "late_fp_use" "yes")
4764    (set_attr "hit_stack" "yes")])
4765
4766 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4767 ;; so use that.
4768 (define_expand "push_4"
4769   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4770                    (match_operand:DF 0 "" ""))
4771               (use (reg:PSI FPSCR_REG))
4772               (clobber (scratch:SI))])]
4773   "TARGET_SH1 && ! TARGET_SH5"
4774   "")
4775
4776 (define_expand "pop_e"
4777   [(parallel [(set (match_operand:SF 0 "" "")
4778               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4779               (use (reg:PSI FPSCR_REG))
4780               (clobber (scratch:SI))])]
4781   "TARGET_SH1 && ! TARGET_SH5"
4782   "")
4783
4784 (define_insn "pop_fpul"
4785   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4786   "TARGET_SH2E && ! TARGET_SH5"
4787   "lds.l        @r15+,fpul"
4788   [(set_attr "type" "load")
4789    (set_attr "hit_stack" "yes")])
4790
4791 (define_expand "pop_4"
4792   [(parallel [(set (match_operand:DF 0 "" "")
4793                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4794               (use (reg:PSI FPSCR_REG))
4795               (clobber (scratch:SI))])]
4796   "TARGET_SH1 && ! TARGET_SH5"
4797   "")
4798
4799 (define_expand "push_fpscr"
4800   [(const_int 0)]
4801   "TARGET_SH2E"
4802   "
4803 {
4804   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4805                                                  gen_rtx_PRE_DEC (Pmode,
4806                                                           stack_pointer_rtx)),
4807                                         get_fpscr_rtx ()));
4808   add_reg_note (insn, REG_INC, stack_pointer_rtx);
4809   DONE;
4810 }")
4811
4812 (define_expand "pop_fpscr"
4813   [(const_int 0)]
4814   "TARGET_SH2E"
4815   "
4816 {
4817   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4818                                         gen_frame_mem (PSImode,
4819                                                  gen_rtx_POST_INC (Pmode,
4820                                                           stack_pointer_rtx))));
4821   add_reg_note (insn, REG_INC, stack_pointer_rtx);
4822   DONE;
4823 }")
4824
4825 ;; These two patterns can happen as the result of optimization, when
4826 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4827 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4828
4829 (define_insn "clrt"
4830   [(set (reg:SI T_REG) (const_int 0))]
4831   "TARGET_SH1"
4832   "clrt")
4833
4834 (define_insn "sett"
4835   [(set (reg:SI T_REG) (const_int 1))]
4836   "TARGET_SH1"
4837   "sett")
4838
4839 ;; t/r must come after r/r, lest reload will try to reload stuff like
4840 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4841 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4842 (define_insn "movsi_i"
4843   [(set (match_operand:SI 0 "general_movdst_operand"
4844             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4845         (match_operand:SI 1 "general_movsrc_operand"
4846          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4847   "TARGET_SH1
4848    && ! TARGET_SH2E
4849    && ! TARGET_SH2A
4850    && (register_operand (operands[0], SImode)
4851        || register_operand (operands[1], SImode))"
4852   "@
4853         mov.l   %1,%0
4854         mov     %1,%0
4855         mov     %1,%0
4856         cmp/pl  %1
4857         mov.l   %1,%0
4858         sts     %1,%0
4859         sts     %1,%0
4860         movt    %0
4861         mov.l   %1,%0
4862         sts.l   %1,%0
4863         sts.l   %1,%0
4864         lds     %1,%0
4865         lds     %1,%0
4866         lds.l   %1,%0
4867         lds.l   %1,%0
4868         fake    %1,%0"
4869   [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
4870    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4871
4872 ;; t/r must come after r/r, lest reload will try to reload stuff like
4873 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4874 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4875 ;; will require a reload.
4876 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4877 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4878 (define_insn "movsi_ie"
4879   [(set (match_operand:SI 0 "general_movdst_operand"
4880             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4881         (match_operand:SI 1 "general_movsrc_operand"
4882          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4883   "(TARGET_SH2E || TARGET_SH2A)
4884    && (register_operand (operands[0], SImode)
4885        || register_operand (operands[1], SImode))"
4886   "@
4887         mov.l   %1,%0
4888         mov     %1,%0
4889         mov     %1,%0
4890         movi20  %1,%0
4891         movi20s %1,%0
4892         cmp/pl  %1
4893         mov.l   %1,%0
4894         sts     %1,%0
4895         sts     %1,%0
4896         movt    %0
4897         mov.l   %1,%0
4898         sts.l   %1,%0
4899         sts.l   %1,%0
4900         lds     %1,%0
4901         lds     %1,%0
4902         lds.l   %1,%0
4903         lds.l   %1,%0
4904         lds.l   %1,%0
4905         sts.l   %1,%0
4906         fake    %1,%0
4907         lds     %1,%0
4908         sts     %1,%0
4909         fsts    fpul,%0
4910         flds    %1,fpul
4911         fmov    %1,%0
4912         ! move optimized away"
4913   [(set_attr "type" "pcload_si,move,movi8,move,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4914    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4915    (set_attr_alternative "length"
4916      [(const_int 2)
4917       (const_int 2)
4918       (const_int 2)
4919       (const_int 4)
4920       (const_int 4)
4921       (const_int 2)
4922       (if_then_else
4923         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4924         (const_int 4) (const_int 2))
4925       (const_int 2)
4926       (const_int 2)
4927       (const_int 2)
4928       (if_then_else
4929         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4930         (const_int 4) (const_int 2))
4931       (const_int 2)
4932       (const_int 2)
4933       (const_int 2)
4934       (const_int 2)
4935       (const_int 2)
4936       (const_int 2)
4937       (const_int 2)
4938       (const_int 2)
4939       (const_int 2)
4940       (const_int 2)
4941       (const_int 2)
4942       (const_int 2)
4943       (const_int 2)
4944       (const_int 2)
4945       (const_int 0)])])
4946
4947 (define_insn "movsi_i_lowpart"
4948   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4949         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4950    "TARGET_SH1
4951     && (register_operand (operands[0], SImode)
4952         || register_operand (operands[1], SImode))"
4953   "@
4954         mov.l   %1,%0
4955         mov     %1,%0
4956         mov     %1,%0
4957         mov.l   %1,%0
4958         sts     %1,%0
4959         sts     %1,%0
4960         movt    %0
4961         mov.l   %1,%0
4962         fake    %1,%0"
4963   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4964
4965 (define_insn_and_split "load_ra"
4966   [(set (match_operand:SI 0 "general_movdst_operand" "")
4967         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4968   "TARGET_SH1"
4969   "#"
4970   "&& ! currently_expanding_to_rtl"
4971   [(set (match_dup 0) (match_dup 1))]
4972   "
4973 {
4974   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4975     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4976 }")
4977
4978 ;; The '?'s in the following constraints may not reflect the time taken
4979 ;; to perform the move. They are there to discourage the use of floating-
4980 ;; point registers for storing integer values.
4981 (define_insn "*movsi_media"
4982   [(set (match_operand:SI 0 "general_movdst_operand"
4983                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4984         (match_operand:SI 1 "general_movsrc_operand"
4985          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4986   "TARGET_SHMEDIA_FPU
4987    && (register_operand (operands[0], SImode)
4988        || sh_register_operand (operands[1], SImode)
4989        || GET_CODE (operands[1]) == TRUNCATE)"
4990   "@
4991         add.l   %1, r63, %0
4992         movi    %1, %0
4993         #
4994         ld%M1.l %m1, %0
4995         st%M0.l %m0, %N1
4996         fld%M1.s        %m1, %0
4997         fst%M0.s        %m0, %1
4998         fmov.ls %N1, %0
4999         fmov.sl %1, %0
5000         fmov.s  %1, %0
5001         ptabs   %1, %0
5002         gettr   %1, %0
5003         pt      %1, %0"
5004   [(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")
5005    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5006    (set (attr "highpart")
5007         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5008                (const_string "user")]
5009               (const_string "ignore")))])
5010
5011 (define_insn "*movsi_media_nofpu"
5012   [(set (match_operand:SI 0 "general_movdst_operand"
5013                 "=r,r,r,r,m,*b,r,*b")
5014         (match_operand:SI 1 "general_movsrc_operand"
5015          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5016   "TARGET_SHMEDIA
5017    && (register_operand (operands[0], SImode)
5018        || sh_register_operand (operands[1], SImode)
5019        || GET_CODE (operands[1]) == TRUNCATE)"
5020   "@
5021         add.l   %1, r63, %0
5022         movi    %1, %0
5023         #
5024         ld%M1.l %m1, %0
5025         st%M0.l %m0, %N1
5026         ptabs   %1, %0
5027         gettr   %1, %0
5028         pt      %1, %0"
5029   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5030    (set_attr "length" "4,4,8,4,4,4,4,12")
5031    (set (attr "highpart")
5032         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5033                (const_string "user")]
5034               (const_string "ignore")))])
5035
5036 (define_expand "movsi_const"
5037   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5038         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5039                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5040    (set (match_dup 0)
5041         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5042                 (const:SI (unspec:SI [(match_dup 1)
5043                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5044   "TARGET_SHMEDIA && reload_completed
5045    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5046   "
5047 {
5048   if (GET_CODE (operands[1]) == LABEL_REF
5049       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5050     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5051   else if (GOTOFF_P (operands[1]))
5052     {
5053       rtx unspec = XEXP (operands[1], 0);
5054
5055       if (! UNSPEC_GOTOFF_P (unspec))
5056         {
5057           unspec = XEXP (unspec, 0);
5058           if (! UNSPEC_GOTOFF_P (unspec))
5059             abort ();
5060         }
5061       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5062           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5063         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5064     }
5065 }")
5066
5067 (define_expand "movsi_const_16bit"
5068   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5069         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5070                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5071   "TARGET_SHMEDIA && flag_pic && reload_completed
5072    && GET_CODE (operands[1]) == SYMBOL_REF"
5073   "")
5074
5075 (define_split
5076   [(set (match_operand:SI 0 "arith_reg_dest" "")
5077         (match_operand:SI 1 "immediate_operand" ""))]
5078   "TARGET_SHMEDIA && reload_completed
5079    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5080   [(const_int 0)]
5081   "
5082 {
5083   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5084
5085   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5086
5087   DONE;
5088 }")
5089
5090 (define_split
5091   [(set (match_operand:SI 0 "register_operand" "")
5092         (match_operand:SI 1 "immediate_operand" ""))]
5093   "TARGET_SHMEDIA && reload_completed
5094    && ((CONST_INT_P (operands[1])
5095         && ! satisfies_constraint_I16 (operands[1]))
5096        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5097   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5098
5099 (define_expand "movsi"
5100   [(set (match_operand:SI 0 "general_movdst_operand" "")
5101         (match_operand:SI 1 "general_movsrc_operand" ""))]
5102   ""
5103   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5104
5105 (define_expand "ic_invalidate_line"
5106   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5107                                 (match_dup 1)] UNSPEC_ICACHE)
5108               (clobber (scratch:SI))])]
5109   "TARGET_HARD_SH4 || TARGET_SH5"
5110   "
5111 {
5112   if (TARGET_SHMEDIA)
5113     {
5114       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5115       DONE;
5116     }
5117   else if (TARGET_SHCOMPACT)
5118     {
5119       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5120       operands[1] = force_reg (Pmode, operands[1]);
5121       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5122       DONE;
5123     }
5124   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5125     {
5126       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5127       DONE;
5128     }
5129   operands[0] = force_reg (Pmode, operands[0]);
5130   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5131                                                                Pmode)));
5132 }")
5133
5134 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5135 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5136 ;; the requirement *1*00 for associative address writes.  The alignment of
5137 ;; %0 implies that its least significant bit is cleared,
5138 ;; thus we clear the V bit of a matching entry if there is one.
5139 (define_insn "ic_invalidate_line_i"
5140   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5141                      (match_operand:SI 1 "register_operand" "r")]
5142                      UNSPEC_ICACHE)
5143    (clobber (match_scratch:SI 2 "=&r"))]
5144   "TARGET_HARD_SH4"
5145   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5146   [(set_attr "length" "8")
5147    (set_attr "type" "cwb")])
5148
5149 (define_insn "ic_invalidate_line_sh4a"
5150   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5151                     UNSPEC_ICACHE)]
5152   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5153   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5154   [(set_attr "length" "16")
5155    (set_attr "type" "cwb")])
5156
5157 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5158 ;; an add in the code that calculates the address.
5159 (define_insn "ic_invalidate_line_media"
5160   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5161                     UNSPEC_ICACHE)]
5162   "TARGET_SHMEDIA"
5163   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5164   [(set_attr "length" "16")
5165    (set_attr "type" "invalidate_line_media")])
5166
5167 (define_insn "ic_invalidate_line_compact"
5168   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5169                      (match_operand:SI 1 "register_operand" "r")]
5170                     UNSPEC_ICACHE)
5171    (clobber (reg:SI PR_REG))]
5172   "TARGET_SHCOMPACT"
5173   "jsr @%1%#"
5174   [(set_attr "type" "sfunc")
5175    (set_attr "needs_delay_slot" "yes")])
5176
5177 (define_expand "initialize_trampoline"
5178   [(match_operand:SI 0 "" "")
5179    (match_operand:SI 1 "" "")
5180    (match_operand:SI 2 "" "")]
5181   "TARGET_SHCOMPACT"
5182   "
5183 {
5184   rtx sfun, tramp;
5185
5186   tramp = force_reg (Pmode, operands[0]);
5187   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5188                                             SFUNC_STATIC));
5189   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5190   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5191
5192   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5193   DONE;
5194 }")
5195
5196 (define_insn "initialize_trampoline_compact"
5197   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5198                      (match_operand:SI 1 "register_operand" "r")
5199                      (reg:SI R2_REG) (reg:SI R3_REG)]
5200                     UNSPEC_INIT_TRAMP)
5201
5202    (clobber (reg:SI PR_REG))]
5203   "TARGET_SHCOMPACT"
5204   "jsr @%1%#"
5205   [(set_attr "type" "sfunc")
5206    (set_attr "needs_delay_slot" "yes")])
5207
5208 (define_insn "movqi_i"
5209   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5210         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5211   "TARGET_SH1
5212    && (arith_reg_operand (operands[0], QImode)
5213        || arith_reg_operand (operands[1], QImode))"
5214   "@
5215         mov     %1,%0
5216         mov     %1,%0
5217         mov.b   %1,%0
5218         mov.b   %1,%0
5219         movt    %0
5220         sts     %1,%0
5221         lds     %1,%0"
5222  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5223   (set_attr_alternative "length"
5224      [(const_int 2)
5225       (const_int 2)
5226       (if_then_else
5227         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5228         (const_int 4) (const_int 2))
5229       (if_then_else
5230         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5231         (const_int 4) (const_int 2))
5232       (const_int 2)
5233       (const_int 2)
5234       (const_int 2)])])
5235
5236 (define_insn "*movqi_media"
5237   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5238         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5239   "TARGET_SHMEDIA
5240    && (arith_reg_operand (operands[0], QImode)
5241        || extend_reg_or_0_operand (operands[1], QImode))"
5242   "@
5243         add.l   %1, r63, %0
5244         movi    %1, %0
5245         ld%M1.ub        %m1, %0
5246         st%M0.b %m0, %N1"
5247   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5248    (set (attr "highpart")
5249         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5250                (const_string "user")]
5251               (const_string "ignore")))])
5252
5253 (define_expand "movqi"
5254   [(set (match_operand:QI 0 "general_operand" "")
5255         (match_operand:QI 1 "general_operand"  ""))]
5256   ""
5257   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5258
5259 (define_expand "reload_inqi"
5260   [(set (match_operand:SI 2 "" "=&r")
5261         (match_operand:QI 1 "inqhi_operand" ""))
5262    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5263         (truncate:QI (match_dup 3)))]
5264   "TARGET_SHMEDIA"
5265   "
5266 {
5267   rtx inner = XEXP (operands[1], 0);
5268   int regno = REGNO (inner);
5269
5270   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5271   operands[1] = gen_rtx_REG (SImode, regno);
5272   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5273 }")
5274
5275 /* When storing r0, we have to avoid reg+reg addressing.  */
5276 (define_insn "movhi_i"
5277   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5278         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5279   "TARGET_SH1
5280    && (arith_reg_operand (operands[0], HImode)
5281        || arith_reg_operand (operands[1], HImode))
5282    && (!MEM_P (operands[0])
5283        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5284        || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5285        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5286   "@
5287         mov.w   %1,%0
5288         mov     %1,%0
5289         mov.w   %1,%0
5290         movt    %0
5291         mov.w   %1,%0
5292         sts     %1,%0
5293         lds     %1,%0
5294         fake    %1,%0"
5295   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5296
5297 (define_insn "*movhi_media"
5298   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5299         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5300   "TARGET_SHMEDIA
5301    && (arith_reg_operand (operands[0], HImode)
5302        || arith_reg_or_0_operand (operands[1], HImode))"
5303   "@
5304         add.l   %1, r63, %0
5305         movi    %1, %0
5306         #
5307         ld%M1.w %m1, %0
5308         st%M0.w %m0, %N1"
5309   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5310    (set (attr "highpart")
5311         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5312                (const_string "user")]
5313               (const_string "ignore")))])
5314
5315 (define_split
5316   [(set (match_operand:HI 0 "register_operand" "")
5317         (match_operand:HI 1 "immediate_operand" ""))]
5318   "TARGET_SHMEDIA && reload_completed
5319    && ! satisfies_constraint_I16 (operands[1])"
5320   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5321
5322 (define_expand "movhi"
5323   [(set (match_operand:HI 0 "general_movdst_operand" "")
5324         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5325   ""
5326   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5327
5328 (define_expand "reload_inhi"
5329   [(set (match_operand:SI 2 "" "=&r")
5330         (match_operand:HI 1 "inqhi_operand" ""))
5331    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5332         (truncate:HI (match_dup 3)))]
5333   "TARGET_SHMEDIA"
5334   "
5335 {
5336   rtx inner = XEXP (operands[1], 0);
5337   int regno = REGNO (inner);
5338
5339   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5340   operands[1] = gen_rtx_REG (SImode, regno);
5341   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5342 }")
5343
5344 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5345 ;; compiled with -m2 -ml -O3 -funroll-loops
5346 (define_insn "*movdi_i"
5347   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5348         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5349   "TARGET_SH1
5350    && (arith_reg_operand (operands[0], DImode)
5351        || arith_reg_operand (operands[1], DImode))"
5352   "* return output_movedouble (insn, operands, DImode);"
5353   [(set_attr "length" "4")
5354    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5355
5356 ;; If the output is a register and the input is memory or a register, we have
5357 ;; to be careful and see which word needs to be loaded first.
5358
5359 (define_split
5360   [(set (match_operand:DI 0 "general_movdst_operand" "")
5361         (match_operand:DI 1 "general_movsrc_operand" ""))]
5362   "TARGET_SH1 && reload_completed"
5363   [(set (match_dup 2) (match_dup 3))
5364    (set (match_dup 4) (match_dup 5))]
5365   "
5366 {
5367   int regno;
5368
5369   if ((MEM_P (operands[0])
5370        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5371       || (MEM_P (operands[1])
5372           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5373     FAIL;
5374
5375   switch (GET_CODE (operands[0]))
5376     {
5377     case REG:
5378       regno = REGNO (operands[0]);
5379       break;
5380     case SUBREG:
5381       regno = subreg_regno (operands[0]);
5382       break;
5383     case MEM:
5384       regno = -1;
5385       break;
5386     default:
5387       gcc_unreachable ();
5388     }
5389
5390   if (regno == -1
5391       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5392     {
5393       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5394       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5395       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5396       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5397     }
5398   else
5399     {
5400       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5401       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5402       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5403       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5404     }
5405
5406   if (operands[2] == 0 || operands[3] == 0
5407       || operands[4] == 0 || operands[5] == 0)
5408     FAIL;
5409 }")
5410
5411 ;; The '?'s in the following constraints may not reflect the time taken
5412 ;; to perform the move. They are there to discourage the use of floating-
5413 ;; point registers for storing integer values.
5414 (define_insn "*movdi_media"
5415   [(set (match_operand:DI 0 "general_movdst_operand"
5416                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5417         (match_operand:DI 1 "general_movsrc_operand"
5418          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5419   "TARGET_SHMEDIA_FPU
5420    && (register_operand (operands[0], DImode)
5421        || sh_register_operand (operands[1], DImode))"
5422   "@
5423         add     %1, r63, %0
5424         movi    %1, %0
5425         #
5426         ld%M1.q %m1, %0
5427         st%M0.q %m0, %N1
5428         fld%M1.d        %m1, %0
5429         fst%M0.d        %m0, %1
5430         fmov.qd %N1, %0
5431         fmov.dq %1, %0
5432         fmov.d  %1, %0
5433         ptabs   %1, %0
5434         gettr   %1, %0
5435         pt      %1, %0"
5436   [(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")
5437    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5438
5439 (define_insn "*movdi_media_nofpu"
5440   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5441         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5442   "TARGET_SHMEDIA
5443    && (register_operand (operands[0], DImode)
5444        || sh_register_operand (operands[1], DImode))"
5445   "@
5446         add     %1, r63, %0
5447         movi    %1, %0
5448         #
5449         ld%M1.q %m1, %0
5450         st%M0.q %m0, %N1
5451         ptabs   %1, %0
5452         gettr   %1, %0
5453         pt      %1, %0"
5454   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5455    (set_attr "length" "4,4,16,4,4,4,4,*")])
5456
5457 (define_insn "*movdi_media_I16"
5458   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5459         (match_operand:DI 1 "const_int_operand" "I16"))]
5460   "TARGET_SHMEDIA && reload_completed"
5461   "movi %1, %0"
5462   [(set_attr "type" "arith_media")
5463    (set_attr "length" "4")])
5464
5465 (define_split
5466   [(set (match_operand:DI 0 "arith_reg_dest" "")
5467         (match_operand:DI 1 "immediate_operand" ""))]
5468   "TARGET_SHMEDIA && reload_completed
5469    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5470   [(set (match_dup 0) (match_dup 1))]
5471   "
5472 {
5473   rtx insn;
5474
5475   if (TARGET_SHMEDIA64)
5476     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5477   else
5478     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5479
5480   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5481
5482   DONE;
5483 }")
5484
5485 (define_expand "movdi_const"
5486   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5487         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5488                               (const_int 48)] UNSPEC_EXTRACT_S16)))
5489    (set (match_dup 0)
5490         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5491                 (const:DI (unspec:DI [(match_dup 1)
5492                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
5493    (set (match_dup 0)
5494         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5495                 (const:DI (unspec:DI [(match_dup 1)
5496                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
5497    (set (match_dup 0)
5498         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5499                 (const:DI (unspec:DI [(match_dup 1)
5500                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5501   "TARGET_SHMEDIA64 && reload_completed
5502    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5503   "
5504 {
5505   sh_mark_label (operands[1], 4);
5506 }")
5507
5508 (define_expand "movdi_const_32bit"
5509   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5510         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5511                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5512    (set (match_dup 0)
5513         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5514                 (const:DI (unspec:DI [(match_dup 1)
5515                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5516   "TARGET_SHMEDIA32 && reload_completed
5517    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5518   "
5519 {
5520   sh_mark_label (operands[1], 2);
5521 }")
5522
5523 (define_expand "movdi_const_16bit"
5524   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5525         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5526                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5527   "TARGET_SHMEDIA && flag_pic && reload_completed
5528    && GET_CODE (operands[1]) == SYMBOL_REF"
5529   "")
5530
5531 (define_split
5532   [(set (match_operand:DI 0 "ext_dest_operand" "")
5533         (match_operand:DI 1 "immediate_operand" ""))]
5534   "TARGET_SHMEDIA && reload_completed
5535    && CONST_INT_P (operands[1])
5536    && ! satisfies_constraint_I16 (operands[1])"
5537   [(set (match_dup 0) (match_dup 2))
5538    (match_dup 1)]
5539   "
5540 {
5541   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5542   unsigned HOST_WIDE_INT low = val;
5543   unsigned HOST_WIDE_INT high = val;
5544   unsigned HOST_WIDE_INT sign;
5545   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5546
5547   /* Zero-extend the 16 least-significant bits.  */
5548   low &= 0xffff;
5549
5550   /* Arithmetic shift right the word by 16 bits.  */
5551   high >>= 16;
5552   if (GET_CODE (operands[0]) == SUBREG
5553       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5554     {
5555       high &= 0xffff;
5556       high ^= 0x8000;
5557       high -= 0x8000;
5558     }
5559   else
5560     {
5561       sign = 1;
5562       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5563       high ^= sign;
5564       high -= sign;
5565     }
5566   do
5567     {
5568       /* If we can't generate the constant with a two-insn movi / shori
5569          sequence, try some other strategies.  */
5570       if (! CONST_OK_FOR_I16 (high))
5571         {
5572           /* Try constant load / left shift.  We know VAL != 0.  */
5573           val2 = val ^ (val-1);
5574           if (val2 > 0x1ffff)
5575             {
5576               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5577
5578               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5579                   || (! CONST_OK_FOR_I16 (high >> 16)
5580                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5581                 {
5582                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5583                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5584                                                    GEN_INT (trailing_zeroes));
5585                   break;
5586                 }
5587             }
5588           /* Try constant load / right shift.  */
5589           val2 = (val >> 15) + 1;
5590           if (val2 == (val2 & -val2))
5591             {
5592               int shift = 49 - exact_log2 (val2);
5593
5594               val2 = trunc_int_for_mode (val << shift, DImode);
5595               if (CONST_OK_FOR_I16 (val2))
5596                 {
5597                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5598                                                    GEN_INT (shift));
5599                   break;
5600                 }
5601             }
5602           /* Try mperm.w .  */
5603           val2 = val & 0xffff;
5604           if ((val >> 16 & 0xffff) == val2
5605               && (val >> 32 & 0xffff) == val2
5606               && (val >> 48 & 0xffff) == val2)
5607             {
5608               val2 = (HOST_WIDE_INT) val >> 48;
5609               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5610               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5611               break;
5612             }
5613           /* Try movi / mshflo.l  */
5614           val2 = (HOST_WIDE_INT) val >> 32;
5615           if (val2 == ((unsigned HOST_WIDE_INT)
5616                         trunc_int_for_mode (val, SImode)))
5617             {
5618               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5619                                              operands[0]);
5620               break;
5621             }
5622           /* Try movi / mshflo.l w/ r63.  */
5623           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5624           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5625             {
5626               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5627                                              const0_rtx);
5628               break;
5629             }
5630         }
5631       val2 = high;
5632       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5633     }
5634   while (0);
5635   operands[2] = GEN_INT (val2);
5636 }")
5637
5638 (define_split
5639   [(set (match_operand:DI 0 "ext_dest_operand" "")
5640         (match_operand:DI 1 "immediate_operand" ""))]
5641   "TARGET_SHMEDIA && reload_completed
5642    && GET_CODE (operands[1]) == CONST_DOUBLE"
5643   [(set (match_dup 0) (match_dup 2))
5644   (set (match_dup 0)
5645        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5646   "
5647 {
5648   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5649   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5650   unsigned HOST_WIDE_INT val = low;
5651   unsigned HOST_WIDE_INT sign;
5652
5653   /* Zero-extend the 16 least-significant bits.  */
5654   val &= 0xffff;
5655   operands[1] = GEN_INT (val);
5656
5657   /* Arithmetic shift right the double-word by 16 bits.  */
5658   low >>= 16;
5659   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5660   high >>= 16;
5661   sign = 1;
5662   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5663   high ^= sign;
5664   high -= sign;
5665
5666   /* This will only be true if high is a sign-extension of low, i.e.,
5667      it must be either 0 or (unsigned)-1, and be zero iff the
5668      most-significant bit of low is set.  */
5669   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5670     operands[2] = GEN_INT (low);
5671   else
5672     operands[2] = immed_double_const (low, high, DImode);
5673 }")
5674
5675 (define_insn "shori_media"
5676   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5677         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5678                            (const_int 16))
5679                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5680   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5681   "@
5682         shori   %u2, %0
5683         #"
5684   [(set_attr "type" "arith_media,*")])
5685
5686 (define_insn "*shori_media_si"
5687   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5688         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5689                            (const_int 16))
5690                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5691   "TARGET_SHMEDIA"
5692   "shori        %u2, %0")
5693
5694 (define_expand "movdi"
5695   [(set (match_operand:DI 0 "general_movdst_operand" "")
5696         (match_operand:DI 1 "general_movsrc_operand" ""))]
5697   ""
5698   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5699
5700 (define_insn "movdf_media"
5701   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5702         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5703   "TARGET_SHMEDIA_FPU
5704    && (register_operand (operands[0], DFmode)
5705        || sh_register_operand (operands[1], DFmode))"
5706   "@
5707         fmov.d  %1, %0
5708         fmov.qd %N1, %0
5709         fmov.dq %1, %0
5710         add     %1, r63, %0
5711         #
5712         fld%M1.d        %m1, %0
5713         fst%M0.d        %m0, %1
5714         ld%M1.q %m1, %0
5715         st%M0.q %m0, %N1"
5716   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5717
5718 (define_insn "movdf_media_nofpu"
5719   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5720         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5721   "TARGET_SHMEDIA
5722    && (register_operand (operands[0], DFmode)
5723        || sh_register_operand (operands[1], DFmode))"
5724   "@
5725         add     %1, r63, %0
5726         #
5727         ld%M1.q %m1, %0
5728         st%M0.q %m0, %N1"
5729   [(set_attr "type" "arith_media,*,load_media,store_media")])
5730
5731 (define_split
5732   [(set (match_operand:DF 0 "arith_reg_dest" "")
5733         (match_operand:DF 1 "immediate_operand" ""))]
5734   "TARGET_SHMEDIA && reload_completed"
5735   [(set (match_dup 3) (match_dup 2))]
5736   "
5737 {
5738   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5739   long values[2];
5740   REAL_VALUE_TYPE value;
5741
5742   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5743   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5744
5745   if (HOST_BITS_PER_WIDE_INT >= 64)
5746     operands[2] = immed_double_const ((unsigned long) values[endian]
5747                                       | ((HOST_WIDE_INT) values[1 - endian]
5748                                          << 32), 0, DImode);
5749   else
5750     {
5751       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5752       operands[2] = immed_double_const (values[endian], values[1 - endian],
5753                                         DImode);
5754     }
5755
5756   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5757 }")
5758
5759 ;; ??? This should be a define expand.
5760
5761 (define_insn "movdf_k"
5762   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5763         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5764   "TARGET_SH1
5765    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5766        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5767        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5768        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5769    && (arith_reg_operand (operands[0], DFmode)
5770        || arith_reg_operand (operands[1], DFmode))"
5771   "* return output_movedouble (insn, operands, DFmode);"
5772   [(set_attr "length" "4")
5773    (set_attr "type" "move,pcload,load,store")])
5774
5775 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5776 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5777 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5778 ;; the d/m/c/X alternative, which is split later into single-precision
5779 ;; instructions.  And when not optimizing, no splits are done before fixing
5780 ;; up pcloads, so we need usable length information for that.
5781 (define_insn "movdf_i4"
5782   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5783         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
5784    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
5785    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
5786   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5787    && (arith_reg_operand (operands[0], DFmode)
5788        || arith_reg_operand (operands[1], DFmode))"
5789   {
5790     switch (which_alternative)
5791     {
5792     case 0:
5793       if (TARGET_FMOVD)
5794         return "fmov    %1,%0";
5795       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5796         return "fmov    %R1,%R0\n\tfmov %S1,%S0";
5797       else
5798         return "fmov    %S1,%S0\n\tfmov %R1,%R0";
5799     case 3:
5800     case 4:
5801       return "fmov.d    %1,%0";
5802     default:
5803       return "#";
5804     }
5805   }
5806   [(set_attr_alternative "length"
5807      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
5808       (const_int 4)
5809       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5810       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5811       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5812       (const_int 4)
5813       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5814       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5815       ;; increment or decrement r15 explicitly.
5816       (if_then_else
5817        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5818        (const_int 10) (const_int 8))
5819       (if_then_else
5820        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5821        (const_int 10) (const_int 8))])
5822    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5823    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5824    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5825                                            (const_string "double")
5826                                            (const_string "none")))])
5827
5828 ;; Moving DFmode between fp/general registers through memory
5829 ;; (the top of the stack) is faster than moving through fpul even for
5830 ;; little endian.  Because the type of an instruction is important for its
5831 ;; scheduling,  it is beneficial to split these operations, rather than
5832 ;; emitting them in one single chunk, even if this will expose a stack
5833 ;; use that will prevent scheduling of other stack accesses beyond this
5834 ;; instruction.
5835 (define_split
5836   [(set (match_operand:DF 0 "register_operand" "")
5837         (match_operand:DF 1 "register_operand" ""))
5838    (use (match_operand:PSI 2 "fpscr_operand" ""))
5839    (clobber (match_scratch:SI 3 "=X"))]
5840   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5841    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5842   [(const_int 0)]
5843   "
5844 {
5845   rtx insn, tos;
5846
5847   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5848     {
5849       emit_move_insn (stack_pointer_rtx,
5850                       plus_constant (stack_pointer_rtx, -8));
5851       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5852     }
5853   else
5854     tos = gen_tmp_stack_mem (DFmode,
5855                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5856   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5857   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5858     add_reg_note (insn, REG_INC, stack_pointer_rtx);
5859   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5860     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5861   else
5862     tos = gen_tmp_stack_mem (DFmode,
5863                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5864   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5865   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5866     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5867   else
5868     add_reg_note (insn, REG_INC, stack_pointer_rtx);
5869   DONE;
5870 }")
5871
5872 ;; local-alloc sometimes allocates scratch registers even when not required,
5873 ;; so we must be prepared to handle these.
5874
5875 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5876 (define_split
5877   [(set (match_operand:DF 0 "general_movdst_operand" "")
5878         (match_operand:DF 1 "general_movsrc_operand"  ""))
5879    (use (match_operand:PSI 2 "fpscr_operand" ""))
5880    (clobber (match_scratch:SI 3 ""))]
5881   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5882    && reload_completed
5883    && true_regnum (operands[0]) < 16
5884    && true_regnum (operands[1]) < 16"
5885   [(set (match_dup 0) (match_dup 1))]
5886   "
5887 {
5888   /* If this was a reg <-> mem operation with base + index reg addressing,
5889      we have to handle this in a special way.  */
5890   rtx mem = operands[0];
5891   int store_p = 1;
5892   if (! memory_operand (mem, DFmode))
5893     {
5894       mem = operands[1];
5895       store_p = 0;
5896     }
5897   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5898     mem = SUBREG_REG (mem);
5899   if (MEM_P (mem))
5900     {
5901       rtx addr = XEXP (mem, 0);
5902       if (GET_CODE (addr) == PLUS
5903           && REG_P (XEXP (addr, 0))
5904           && REG_P (XEXP (addr, 1)))
5905         {
5906           int offset;
5907           rtx reg0 = gen_rtx_REG (Pmode, 0);
5908           rtx regop = operands[store_p], word0 ,word1;
5909
5910           if (GET_CODE (regop) == SUBREG)
5911             alter_subreg (&regop);
5912           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5913             offset = 2;
5914           else
5915             offset = 4;
5916           mem = copy_rtx (mem);
5917           PUT_MODE (mem, SImode);
5918           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5919           alter_subreg (&word0);
5920           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5921           alter_subreg (&word1);
5922           if (store_p || ! refers_to_regno_p (REGNO (word0),
5923                                               REGNO (word0) + 1, addr, 0))
5924             {
5925               emit_insn (store_p
5926                          ? gen_movsi_ie (mem, word0)
5927                          : gen_movsi_ie (word0, mem));
5928               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5929               mem = copy_rtx (mem);
5930               emit_insn (store_p
5931                          ? gen_movsi_ie (mem, word1)
5932                          : gen_movsi_ie (word1, mem));
5933               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5934             }
5935           else
5936             {
5937               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5938               emit_insn (gen_movsi_ie (word1, mem));
5939               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5940               mem = copy_rtx (mem);
5941               emit_insn (gen_movsi_ie (word0, mem));
5942             }
5943           DONE;
5944         }
5945     }
5946 }")
5947
5948 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5949 (define_split
5950   [(set (match_operand:DF 0 "register_operand" "")
5951         (match_operand:DF 1 "memory_operand"  ""))
5952    (use (match_operand:PSI 2 "fpscr_operand" ""))
5953    (clobber (reg:SI R0_REG))]
5954   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5955   [(parallel [(set (match_dup 0) (match_dup 1))
5956               (use (match_dup 2))
5957               (clobber (scratch:SI))])]
5958   "")
5959
5960 (define_expand "reload_indf__frn"
5961   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5962                    (match_operand:DF 1 "immediate_operand" "FQ"))
5963               (use (reg:PSI FPSCR_REG))
5964               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5965   "TARGET_SH1"
5966   "")
5967
5968 (define_expand "reload_outdf__RnFRm"
5969   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5970                    (match_operand:DF 1 "register_operand" "af,r"))
5971               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5972   "TARGET_SH1"
5973   "")
5974
5975 ;; Simplify no-op moves.
5976 (define_split
5977   [(set (match_operand:SF 0 "register_operand" "")
5978         (match_operand:SF 1 "register_operand" ""))
5979    (use (match_operand:PSI 2 "fpscr_operand" ""))
5980    (clobber (match_scratch:SI 3 ""))]
5981   "TARGET_SH2E && reload_completed
5982    && true_regnum (operands[0]) == true_regnum (operands[1])"
5983   [(set (match_dup 0) (match_dup 0))]
5984   "")
5985
5986 ;; fmovd substitute post-reload splits
5987 (define_split
5988   [(set (match_operand:DF 0 "register_operand" "")
5989         (match_operand:DF 1 "register_operand" ""))
5990    (use (match_operand:PSI 2 "fpscr_operand" ""))
5991    (clobber (match_scratch:SI 3 ""))]
5992   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5993    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5994    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5995   [(const_int 0)]
5996   "
5997 {
5998   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5999   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6000                            gen_rtx_REG (SFmode, src), operands[2]));
6001   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6002                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6003   DONE;
6004 }")
6005
6006 (define_split
6007   [(set (match_operand:DF 0 "register_operand" "")
6008         (mem:DF (match_operand:SI 1 "register_operand" "")))
6009    (use (match_operand:PSI 2 "fpscr_operand" ""))
6010    (clobber (match_scratch:SI 3 ""))]
6011   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6012    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6013    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6014   [(const_int 0)]
6015   "
6016 {
6017   int regno = true_regnum (operands[0]);
6018   rtx insn;
6019   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6020   rtx mem2
6021     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6022   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6023                                            regno + !! TARGET_LITTLE_ENDIAN),
6024                                   mem2, operands[2]));
6025   add_reg_note (insn, REG_INC, operands[1]);
6026   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6027                                                regno + ! TARGET_LITTLE_ENDIAN),
6028                                   change_address (mem, SFmode, NULL_RTX),
6029                                   operands[2]));
6030   DONE;
6031 }")
6032
6033 (define_split
6034   [(set (match_operand:DF 0 "register_operand" "")
6035         (match_operand:DF 1 "memory_operand" ""))
6036    (use (match_operand:PSI 2 "fpscr_operand" ""))
6037    (clobber (match_scratch:SI 3 ""))]
6038   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6039    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6040   [(const_int 0)]
6041 {
6042   int regno = true_regnum (operands[0]);
6043   rtx addr, insn;
6044   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6045   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6046   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6047
6048   operands[1] = copy_rtx (mem2);
6049   addr = XEXP (mem2, 0);
6050
6051   switch (GET_CODE (addr))
6052     {
6053     case REG:
6054       /* This is complicated.  If the register is an arithmetic register
6055          we can just fall through to the REG+DISP case below.  Otherwise
6056          we have to use a combination of POST_INC and REG addressing...  */
6057       if (! arith_reg_operand (operands[1], SFmode))
6058         {
6059           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6060           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6061           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6062           
6063           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6064
6065           /* If we have modified the stack pointer, the value that we have
6066              read with post-increment might be modified by an interrupt,
6067              so write it back.  */
6068           if (REGNO (addr) == STACK_POINTER_REGNUM)
6069             emit_insn (gen_push_e (reg0));
6070           else
6071             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6072           break;
6073         }
6074       /* Fall through.  */
6075          
6076     case PLUS:
6077       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6078       operands[1] = copy_rtx (operands[1]);
6079       XEXP (operands[1], 0) = plus_constant (addr, 4);
6080       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6081       break;
6082       
6083     case POST_INC:
6084       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6085       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6086     
6087       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6088       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6089       break;
6090
6091     default:
6092       debug_rtx (addr);
6093       gcc_unreachable ();
6094     }
6095
6096   DONE;
6097 })
6098
6099 (define_split
6100   [(set (match_operand:DF 0 "memory_operand" "")
6101         (match_operand:DF 1 "register_operand" ""))
6102    (use (match_operand:PSI 2 "fpscr_operand" ""))
6103    (clobber (match_scratch:SI 3 ""))]
6104   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6105    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6106   [(const_int 0)]
6107 {
6108   int regno = true_regnum (operands[1]);
6109   rtx insn, addr;
6110   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6111   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6112
6113   operands[0] = copy_rtx (operands[0]);
6114   PUT_MODE (operands[0], SFmode);
6115   addr = XEXP (operands[0], 0);
6116
6117   switch (GET_CODE (addr))
6118     {
6119     case REG:
6120       /* This is complicated.  If the register is an arithmetic register
6121          we can just fall through to the REG+DISP case below.  Otherwise
6122          we have to use a combination of REG and PRE_DEC addressing...  */
6123       if (! arith_reg_operand (operands[0], SFmode))
6124         {
6125           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6126           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6127
6128           operands[0] = copy_rtx (operands[0]);
6129           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6130           
6131           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6132           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6133           break;
6134         }
6135       /* Fall through.  */
6136       
6137     case PLUS:
6138       /* Since REG+DISP addressing has already been decided upon by gcc
6139          we can rely upon it having chosen an arithmetic register as the
6140          register component of the address.  Just emit the lower numbered
6141          register first, to the lower address, then the higher numbered
6142          register to the higher address.  */
6143       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6144
6145       operands[0] = copy_rtx (operands[0]);
6146       XEXP (operands[0], 0) = plus_constant (addr, 4);
6147
6148       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));         
6149       break;
6150       
6151     case PRE_DEC:
6152       /* This is easy.  Output the word to go to the higher address
6153          first (ie the word in the higher numbered register) then the
6154          word to go to the lower address.  */
6155
6156       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6157       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6158
6159       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6160       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6161       break;
6162       
6163     default:
6164       /* FAIL; */
6165       debug_rtx (addr);
6166       gcc_unreachable ();
6167     }
6168
6169   DONE;
6170 })
6171
6172 ;; If the output is a register and the input is memory or a register, we have
6173 ;; to be careful and see which word needs to be loaded first.
6174
6175 (define_split
6176   [(set (match_operand:DF 0 "general_movdst_operand" "")
6177         (match_operand:DF 1 "general_movsrc_operand" ""))]
6178   "TARGET_SH1 && reload_completed"
6179   [(set (match_dup 2) (match_dup 3))
6180    (set (match_dup 4) (match_dup 5))]
6181   "
6182 {
6183   int regno;
6184
6185   if ((MEM_P (operands[0])
6186        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6187       || (MEM_P (operands[1])
6188           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6189     FAIL;
6190
6191   switch (GET_CODE (operands[0]))
6192     {
6193     case REG:
6194       regno = REGNO (operands[0]);
6195       break;
6196     case SUBREG:
6197       regno = subreg_regno (operands[0]);
6198       break;
6199     case MEM:
6200       regno = -1;
6201       break;
6202     default:
6203       gcc_unreachable ();
6204     }
6205
6206   if (regno == -1
6207       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6208     {
6209       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6210       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6211       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6212       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6213     }
6214   else
6215     {
6216       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6217       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6218       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6219       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6220     }
6221
6222   if (operands[2] == 0 || operands[3] == 0
6223       || operands[4] == 0 || operands[5] == 0)
6224     FAIL;
6225 }")
6226
6227 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6228 ;; used only once, let combine add in the index again.
6229
6230 (define_split
6231   [(set (match_operand:SI 0 "register_operand" "")
6232         (match_operand:SI 1 "" ""))
6233    (clobber (match_operand 2 "register_operand" ""))]
6234   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6235    && ALLOW_INDEXED_ADDRESS"
6236   [(use (reg:SI R0_REG))]
6237   "
6238 {
6239   rtx addr, reg, const_int;
6240
6241   if (!MEM_P (operands[1]))
6242     FAIL;
6243   addr = XEXP (operands[1], 0);
6244   if (GET_CODE (addr) != PLUS)
6245     FAIL;
6246   reg = XEXP (addr, 0);
6247   const_int = XEXP (addr, 1);
6248   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6249          && CONST_INT_P (const_int)))
6250     FAIL;
6251   emit_move_insn (operands[2], const_int);
6252   emit_move_insn (operands[0],
6253                   change_address (operands[1], VOIDmode,
6254                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6255   DONE;
6256 }")
6257
6258 (define_split
6259   [(set (match_operand:SI 1 "" "")
6260         (match_operand:SI 0 "register_operand" ""))
6261    (clobber (match_operand 2 "register_operand" ""))]
6262   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6263    && ALLOW_INDEXED_ADDRESS"
6264   [(use (reg:SI R0_REG))]
6265   "
6266 {
6267   rtx addr, reg, const_int;
6268
6269   if (!MEM_P (operands[1]))
6270     FAIL;
6271   addr = XEXP (operands[1], 0);
6272   if (GET_CODE (addr) != PLUS)
6273     FAIL;
6274   reg = XEXP (addr, 0);
6275   const_int = XEXP (addr, 1);
6276   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6277          && CONST_INT_P (const_int)))
6278     FAIL;
6279   emit_move_insn (operands[2], const_int);
6280   emit_move_insn (change_address (operands[1], VOIDmode,
6281                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6282                   operands[0]);
6283   DONE;
6284 }")
6285
6286 (define_expand "movdf"
6287   [(set (match_operand:DF 0 "general_movdst_operand" "")
6288         (match_operand:DF 1 "general_movsrc_operand" ""))]
6289   ""
6290   "
6291 {
6292   if (prepare_move_operands (operands, DFmode)) DONE;
6293   if (TARGET_SHMEDIA)
6294     {
6295       if (TARGET_SHMEDIA_FPU)
6296         emit_insn (gen_movdf_media (operands[0], operands[1]));
6297       else
6298         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6299       DONE;
6300     }
6301   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6302     {
6303       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6304       DONE;
6305     }
6306 }")
6307
6308 ;;This is incompatible with the way gcc uses subregs.
6309 ;;(define_insn "movv2sf_i"
6310 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6311 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6312 ;;  "TARGET_SHMEDIA_FPU
6313 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6314 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6315 ;;  "@
6316 ;;      #
6317 ;;      fld%M1.p        %m1, %0
6318 ;;      fst%M0.p        %m0, %1"
6319 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6320
6321 (define_insn_and_split "movv2sf_i"
6322   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6323         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6324   "TARGET_SHMEDIA_FPU"
6325   "#"
6326   "TARGET_SHMEDIA_FPU && reload_completed"
6327   [(set (match_dup 0) (match_dup 1))]
6328   "
6329 {
6330   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6331   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6332 }")
6333
6334 (define_expand "movv2sf"
6335   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6336         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6337   "TARGET_SHMEDIA_FPU"
6338   "
6339 {
6340   if (prepare_move_operands (operands, V2SFmode))
6341     DONE;
6342 }")
6343
6344 (define_expand "addv2sf3"
6345   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6346    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6347    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6348   "TARGET_SHMEDIA_FPU"
6349   "
6350 {
6351   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6352   DONE;
6353 }")
6354
6355 (define_expand "subv2sf3"
6356   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6357    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6358    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6359   "TARGET_SHMEDIA_FPU"
6360   "
6361 {
6362   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6363   DONE;
6364 }")
6365
6366 (define_expand "mulv2sf3"
6367   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6368    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6369    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6370   "TARGET_SHMEDIA_FPU"
6371   "
6372 {
6373   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6374   DONE;
6375 }")
6376
6377 (define_expand "divv2sf3"
6378   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6379    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6380    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6381   "TARGET_SHMEDIA_FPU"
6382   "
6383 {
6384   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6385   DONE;
6386 }")
6387
6388 (define_insn_and_split "*movv4sf_i"
6389   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6390         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6391   "TARGET_SHMEDIA_FPU"
6392   "#"
6393   "&& reload_completed"
6394   [(const_int 0)]
6395   "
6396 {
6397   int i;
6398
6399   for (i = 0; i < 4/2; i++)
6400     {
6401       rtx x, y;
6402
6403       if (MEM_P (operands[0]))
6404         x = adjust_address (operands[0], V2SFmode,
6405                             i * GET_MODE_SIZE (V2SFmode));
6406       else
6407         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6408
6409       if (MEM_P (operands[1]))
6410         y = adjust_address (operands[1], V2SFmode,
6411                             i * GET_MODE_SIZE (V2SFmode));
6412       else
6413         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6414
6415       emit_insn (gen_movv2sf_i (x, y));
6416     }
6417
6418   DONE;
6419 }"
6420   [(set_attr "length" "8")])
6421
6422 (define_expand "movv4sf"
6423   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6424         (match_operand:V4SF 1 "general_operand" ""))]
6425   "TARGET_SHMEDIA_FPU"
6426   "
6427 {
6428   if (prepare_move_operands (operands, V4SFmode))
6429     DONE;
6430 }")
6431
6432 (define_insn_and_split "*movv16sf_i"
6433   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6434         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6435   "TARGET_SHMEDIA_FPU"
6436   "#"
6437   "&& reload_completed"
6438   [(const_int 0)]
6439   "
6440 {
6441   int i;
6442
6443   for (i = 0; i < 16/2; i++)
6444     {
6445       rtx x,y;
6446
6447       if (MEM_P (operands[0]))
6448         x = adjust_address (operands[0], V2SFmode,
6449                             i * GET_MODE_SIZE (V2SFmode));
6450       else
6451         {
6452           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6453           alter_subreg (&x);
6454         }
6455
6456       if (MEM_P (operands[1]))
6457         y = adjust_address (operands[1], V2SFmode,
6458                             i * GET_MODE_SIZE (V2SFmode));
6459       else
6460         {
6461           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6462           alter_subreg (&y);
6463         }
6464
6465       emit_insn (gen_movv2sf_i (x, y));
6466     }
6467
6468   DONE;
6469 }"
6470   [(set_attr "length" "32")])
6471
6472 (define_expand "movv16sf"
6473   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6474         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6475   "TARGET_SHMEDIA_FPU"
6476   "
6477 {
6478   if (prepare_move_operands (operands, V16SFmode))
6479     DONE;
6480 }")
6481
6482 (define_insn "movsf_media"
6483   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6484         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6485   "TARGET_SHMEDIA_FPU
6486    && (register_operand (operands[0], SFmode)
6487        || sh_register_operand (operands[1], SFmode))"
6488   "@
6489         fmov.s  %1, %0
6490         fmov.ls %N1, %0
6491         fmov.sl %1, %0
6492         add.l   %1, r63, %0
6493         #
6494         fld%M1.s        %m1, %0
6495         fst%M0.s        %m0, %1
6496         ld%M1.l %m1, %0
6497         st%M0.l %m0, %N1"
6498   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6499    (set (attr "highpart")
6500         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6501                (const_string "user")]
6502               (const_string "ignore")))])
6503
6504 (define_insn "movsf_media_nofpu"
6505   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6506         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6507   "TARGET_SHMEDIA
6508    && (register_operand (operands[0], SFmode)
6509        || sh_register_operand (operands[1], SFmode))"
6510   "@
6511         add.l   %1, r63, %0
6512         #
6513         ld%M1.l %m1, %0
6514         st%M0.l %m0, %N1"
6515   [(set_attr "type" "arith_media,*,load_media,store_media")
6516    (set (attr "highpart")
6517         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6518                (const_string "user")]
6519               (const_string "ignore")))])
6520
6521 (define_split
6522   [(set (match_operand:SF 0 "arith_reg_dest" "")
6523         (match_operand:SF 1 "immediate_operand" ""))]
6524   "TARGET_SHMEDIA && reload_completed
6525    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6526   [(set (match_dup 3) (match_dup 2))]
6527   "
6528 {
6529   long values;
6530   REAL_VALUE_TYPE value;
6531
6532   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6533   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6534   operands[2] = GEN_INT (values);
6535
6536   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6537 }")
6538
6539 (define_insn "movsf_i"
6540   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6541         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6542   "TARGET_SH1
6543    && (! TARGET_SH2E
6544        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6545        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6546        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6547    && (arith_reg_operand (operands[0], SFmode)
6548        || arith_reg_operand (operands[1], SFmode))"
6549   "@
6550         mov     %1,%0
6551         mov     #0,%0
6552         mov.l   %1,%0
6553         mov.l   %1,%0
6554         mov.l   %1,%0
6555         lds     %1,%0
6556         sts     %1,%0"
6557   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6558
6559 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6560 ;; update_flow_info would not know where to put REG_EQUAL notes
6561 ;; when the destination changes mode.
6562 (define_insn "movsf_ie"
6563   [(set (match_operand:SF 0 "general_movdst_operand"
6564          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6565         (match_operand:SF 1 "general_movsrc_operand"
6566           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6567    (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"))
6568    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6569
6570   "TARGET_SH2E
6571    && (arith_reg_operand (operands[0], SFmode)
6572        || arith_reg_operand (operands[1], SFmode)
6573        || arith_reg_operand (operands[3], SImode)
6574        || (fpul_operand (operands[0], SFmode)
6575            && memory_operand (operands[1], SFmode)
6576            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6577        || (fpul_operand (operands[1], SFmode)
6578            && memory_operand (operands[0], SFmode)
6579            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6580   "@
6581         fmov    %1,%0
6582         mov     %1,%0
6583         fldi0   %0
6584         fldi1   %0
6585         #
6586         fmov.s  %1,%0
6587         fmov.s  %1,%0
6588         mov.l   %1,%0
6589         mov.l   %1,%0
6590         mov.l   %1,%0
6591         fsts    fpul,%0
6592         flds    %1,fpul
6593         lds.l   %1,%0
6594         #
6595         sts     %1,%0
6596         lds     %1,%0
6597         sts.l   %1,%0
6598         lds.l   %1,%0
6599         ! move optimized away"
6600   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6601    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6602    (set_attr_alternative "length"
6603      [(const_int 2)
6604       (const_int 2)
6605       (const_int 2)
6606       (const_int 2)
6607       (const_int 4)
6608       (if_then_else
6609         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6610         (const_int 4) (const_int 2))
6611       (if_then_else
6612         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6613         (const_int 4) (const_int 2))
6614       (const_int 2)
6615       (if_then_else
6616         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6617         (const_int 4) (const_int 2))
6618       (if_then_else
6619         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6620         (const_int 4) (const_int 2))
6621       (const_int 2)
6622       (const_int 2)
6623       (const_int 2)
6624       (const_int 4)
6625       (const_int 2)
6626       (const_int 2)
6627       (const_int 2)
6628       (const_int 2)
6629       (const_int 0)])
6630    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6631                                            (const_string "single")
6632                                            (const_string "single")))])
6633
6634 (define_split
6635   [(set (match_operand:SF 0 "register_operand" "")
6636         (match_operand:SF 1 "register_operand" ""))
6637    (use (match_operand:PSI 2 "fpscr_operand" ""))
6638    (clobber (reg:SI FPUL_REG))]
6639   "TARGET_SH1"
6640   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6641               (use (match_dup 2))
6642               (clobber (scratch:SI))])
6643    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6644               (use (match_dup 2))
6645               (clobber (scratch:SI))])]
6646   "")
6647
6648 (define_expand "movsf"
6649   [(set (match_operand:SF 0 "general_movdst_operand" "")
6650         (match_operand:SF 1 "general_movsrc_operand" ""))]
6651   ""
6652   "
6653 {
6654   if (prepare_move_operands (operands, SFmode))
6655     DONE;
6656   if (TARGET_SHMEDIA)
6657     {
6658       if (TARGET_SHMEDIA_FPU)
6659         emit_insn (gen_movsf_media (operands[0], operands[1]));
6660       else
6661         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6662       DONE;
6663     }
6664   if (TARGET_SH2E)
6665     {
6666       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6667       DONE;
6668     }
6669 }")
6670
6671 (define_insn "mov_nop"
6672   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6673   "TARGET_SH2E"
6674   ""
6675   [(set_attr "length" "0")
6676    (set_attr "type" "nil")])
6677
6678 (define_expand "reload_insf__frn"
6679   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6680                    (match_operand:SF 1 "immediate_operand" "FQ"))
6681               (use (reg:PSI FPSCR_REG))
6682               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6683   "TARGET_SH1"
6684   "")
6685
6686 (define_expand "reload_insi__i_fpul"
6687   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6688                    (match_operand:SI 1 "immediate_operand" "i"))
6689               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6690   "TARGET_SH1"
6691   "")
6692
6693 (define_expand "ptabs"
6694   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6695   "TARGET_SHMEDIA"
6696   "
6697 {
6698   if (!TARGET_PT_FIXED)
6699     {
6700       rtx eq = operands[1];
6701
6702       /* ??? For canonical RTL we really should remove any CONST from EQ
6703          before wrapping it in the AND, and finally wrap the EQ into a
6704          const if is constant.  However, for reload we must expose the
6705          input register or symbolic constant, and we can't have
6706          different insn structures outside of the operands for different
6707          alternatives of the same pattern.  */
6708       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6709                        GEN_INT (3));
6710       operands[1]
6711         = (gen_rtx_IF_THEN_ELSE
6712             (PDImode,
6713              eq,
6714              gen_rtx_MEM (PDImode, operands[1]),
6715              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6716                             PDImode, operands[1])));
6717     }
6718 }")
6719
6720 ;; expanded by ptabs expander.
6721 (define_insn "*extendsipdi_media"
6722   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6723         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6724                                                           "r,Csy")
6725                                       (const_int 3))
6726                               (const_int 3))
6727                           (mem:PDI (match_dup 1))
6728                           (sign_extend:PDI (match_dup 1))))]
6729   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6730   "@
6731         ptabs   %1, %0
6732         pt      %1, %0"
6733   [(set_attr "type"   "ptabs_media,pt_media")
6734    (set_attr "length" "4,*")])
6735
6736 (define_insn "*truncdipdi_media"
6737   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6738         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6739                                                           "r,Csy")
6740                                       (const_int 3))
6741                               (const_int 3))
6742                           (mem:PDI (match_dup 1))
6743                           (truncate:PDI (match_dup 1))))]
6744   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6745   "@
6746         ptabs   %1, %0
6747         pt      %1, %0"
6748   [(set_attr "type"   "ptabs_media,pt_media")
6749    (set_attr "length" "4,*")])
6750
6751 (define_insn "*movsi_y"
6752   [(set (match_operand:SI 0 "register_operand" "=y,y")
6753         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6754    (clobber (match_scratch:SI 2 "=&z,r"))]
6755   "TARGET_SH2E
6756    && (reload_in_progress || reload_completed)"
6757   "#"
6758   [(set_attr "length" "4")
6759    (set_attr "type" "pcload,move")])
6760
6761 (define_split
6762   [(set (match_operand:SI 0 "register_operand" "")
6763         (match_operand:SI 1 "immediate_operand" ""))
6764    (clobber (match_operand:SI 2 "register_operand" ""))]
6765   "TARGET_SH1"
6766   [(set (match_dup 2) (match_dup 1))
6767    (set (match_dup 0) (match_dup 2))]
6768   "")
6769
6770 (define_split
6771   [(set (match_operand:SI 0 "register_operand" "")
6772         (match_operand:SI 1 "memory_operand" ""))
6773    (clobber (reg:SI R0_REG))]
6774   "TARGET_SH1"
6775   [(set (match_dup 0) (match_dup 1))]
6776   "")
6777 \f
6778 ;; ------------------------------------------------------------------------
6779 ;; Define the real conditional branch instructions.
6780 ;; ------------------------------------------------------------------------
6781
6782 (define_insn "branch_true"
6783   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6784                            (label_ref (match_operand 0 "" ""))
6785                            (pc)))]
6786   "TARGET_SH1"
6787   "* return output_branch (1, insn, operands);"
6788   [(set_attr "type" "cbranch")])
6789
6790 (define_insn "branch_false"
6791   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6792                            (label_ref (match_operand 0 "" ""))
6793                            (pc)))]
6794   "TARGET_SH1"
6795   "* return output_branch (0, insn, operands);"
6796   [(set_attr "type" "cbranch")])
6797
6798 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6799 ;; which destination is too far away.
6800 ;; The const_int_operand is distinct for each branch target; it avoids
6801 ;; unwanted matches with redundant_insn.
6802 (define_insn "block_branch_redirect"
6803   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6804   "TARGET_SH1"
6805   ""
6806   [(set_attr "length" "0")])
6807
6808 ;; This one has the additional purpose to record a possible scratch register
6809 ;; for the following branch.
6810 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6811 ;; because the insn then might be deemed dead and deleted.  And we can't
6812 ;; make the use in the jump insn explicit because that would disable
6813 ;; delay slot scheduling from the target.
6814 (define_insn "indirect_jump_scratch"
6815   [(set (match_operand:SI 0 "register_operand" "=r")
6816         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6817    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6818   "TARGET_SH1"
6819   ""
6820   [(set_attr "length" "0")])
6821
6822 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6823 ;; being pulled into the delay slot of a condbranch that has been made to
6824 ;; jump around the unconditional jump because it was out of range.
6825 (define_insn "stuff_delay_slot"
6826   [(set (pc)
6827         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6828    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6829   "TARGET_SH1"
6830   ""
6831   [(set_attr "length" "0")
6832    (set_attr "cond_delay_slot" "yes")])
6833 \f
6834 ;; Conditional branch insns
6835
6836 (define_expand "cbranchint4_media"
6837   [(set (pc)
6838         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6839                        [(match_operand 1 "" "")
6840                         (match_operand 2 "" "")])
6841                       (match_operand 3 "" "")
6842                       (pc)))]
6843   "TARGET_SHMEDIA"
6844   "
6845 {
6846   enum machine_mode mode = GET_MODE (operands[1]);
6847   if (mode == VOIDmode)
6848     mode = GET_MODE (operands[2]);
6849   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6850     {
6851       operands[1] = force_reg (mode, operands[1]);
6852       if (CONSTANT_P (operands[2])
6853           && (! satisfies_constraint_I06 (operands[2])))
6854         operands[2] = force_reg (mode, operands[2]);
6855     }
6856   else
6857     {
6858       if (operands[1] != const0_rtx)
6859         operands[1] = force_reg (mode, operands[1]);
6860       if (operands[2] != const0_rtx)
6861         operands[2] = force_reg (mode, operands[2]);
6862     }
6863   switch (GET_CODE (operands[0]))
6864     {
6865     case LEU:
6866     case LE:
6867     case LTU:
6868     case LT:
6869       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6870                                     VOIDmode, operands[2], operands[1]);
6871       operands[1] = XEXP (operands[0], 0);
6872       operands[2] = XEXP (operands[0], 1);
6873       break;
6874     default:
6875       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6876                                     VOIDmode, operands[1], operands[2]);
6877       break;
6878     }
6879   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6880 }")
6881
6882 (define_expand "cbranchfp4_media"
6883   [(set (pc)
6884         (if_then_else (match_operator 0 "sh_float_comparison_operator"
6885                        [(match_operand 1 "" "")
6886                         (match_operand 2 "" "")])
6887                       (match_operand 3 "" "")
6888                       (pc)))]
6889   "TARGET_SHMEDIA"
6890   "
6891 {
6892   /* hack to generate same code.  */
6893   rtx tmp_di = GET_CODE (operands[0]) == UNORDERED ? NULL : gen_reg_rtx (DImode);
6894   rtx tmp = gen_reg_rtx (SImode);
6895   rtx cmp;
6896   if (GET_CODE (operands[0]) == NE)
6897     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6898   else
6899     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6900                           operands[1], operands[2]);
6901
6902   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6903   if (tmp_di) emit_insn (gen_extendsidi2 (tmp_di, tmp)); else tmp_di = tmp;
6904
6905   if (GET_CODE (cmp) == GET_CODE (operands[0]))
6906     operands[0] = gen_rtx_NE (VOIDmode, tmp_di, const0_rtx);
6907   else
6908     operands[0] = gen_rtx_EQ (VOIDmode, tmp_di, const0_rtx);
6909   operands[1] = tmp_di;
6910   operands[2] = const0_rtx;
6911   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6912 }")
6913
6914 (define_insn "*beq_media_i"
6915   [(set (pc)
6916         (if_then_else (match_operator 3 "equality_comparison_operator"
6917                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6918                          (match_operand:DI 2 "arith_operand" "r,I06")])
6919                       (match_operand 0 "target_operand" "b,b")
6920                       (pc)))]
6921   "TARGET_SHMEDIA"
6922   "@
6923         b%o3%'  %1, %2, %0%>
6924         b%o3i%' %1, %2, %0%>"
6925   [(set_attr "type" "cbranch_media")])
6926
6927 (define_insn "*beq_media_i32"
6928   [(set (pc)
6929         (if_then_else (match_operator 3 "equality_comparison_operator"
6930                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6931                          (match_operand:SI 2 "arith_operand" "r,I06")])
6932                       (match_operand 0 "target_operand" "b,b")
6933                       (pc)))]
6934   "TARGET_SHMEDIA"
6935   "@
6936         b%o3%'  %1, %2, %0%>
6937         b%o3i%' %1, %2, %0%>"
6938   [(set_attr "type" "cbranch_media")])
6939
6940 (define_insn "*bgt_media_i"
6941   [(set (pc)
6942         (if_then_else (match_operator 3 "greater_comparison_operator"
6943                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6944                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6945                       (match_operand 0 "target_operand" "b")
6946                       (pc)))]
6947   "TARGET_SHMEDIA"
6948   "b%o3%'       %N1, %N2, %0%>"
6949   [(set_attr "type" "cbranch_media")])
6950
6951 (define_insn "*bgt_media_i32"
6952   [(set (pc)
6953         (if_then_else (match_operator 3 "greater_comparison_operator"
6954                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6955                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6956                       (match_operand 0 "target_operand" "b")
6957                       (pc)))]
6958   "TARGET_SHMEDIA"
6959   "b%o3%'       %N1, %N2, %0%>"
6960   [(set_attr "type" "cbranch_media")])
6961
6962 ;; These are only needed to make invert_jump() happy - otherwise, jump
6963 ;; optimization will be silently disabled.
6964 (define_insn "*blt_media_i"
6965   [(set (pc)
6966         (if_then_else (match_operator 3 "less_comparison_operator"
6967                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6968                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6969                       (match_operand 0 "target_operand" "b")
6970                       (pc)))]
6971   "TARGET_SHMEDIA"
6972   "b%o3%'       %N2, %N1, %0%>"
6973   [(set_attr "type" "cbranch_media")])
6974
6975 (define_insn "*blt_media_i32"
6976   [(set (pc)
6977         (if_then_else (match_operator 3 "less_comparison_operator"
6978                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6979                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6980                       (match_operand 0 "target_operand" "b")
6981                       (pc)))]
6982   "TARGET_SHMEDIA"
6983   "b%o3%'       %N2, %N1, %0%>"
6984   [(set_attr "type" "cbranch_media")])
6985
6986 ;; combiner splitter for test-and-branch on single bit in register.  This
6987 ;; is endian dependent because the non-paradoxical subreg looks different
6988 ;; on big endian.
6989 (define_split
6990   [(set (pc)
6991         (if_then_else
6992           (match_operator 3 "equality_comparison_operator"
6993             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
6994                                                       "extend_reg_operand" "")
6995                                                     0)
6996                                          (const_int 1)
6997                                          (match_operand 2
6998                                           "const_int_operand" "")) 0)
6999              (const_int 0)])
7000           (match_operand 0 "target_operand" "")
7001           (pc)))
7002    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7003   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7004   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7005    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7006
7007   "
7008 {
7009   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7010   operands[6] = (GET_CODE (operands[3]) == EQ
7011                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7012                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7013 }")
7014
7015 ; operand 0 is the loop count pseudo register
7016 ; operand 1 is the number of loop iterations or 0 if it is unknown
7017 ; operand 2 is the maximum number of loop iterations
7018 ; operand 3 is the number of levels of enclosed loops
7019 ; operand 4 is the label to jump to at the top of the loop
7020
7021 (define_expand "doloop_end"
7022   [(parallel [(set (pc) (if_then_else
7023                           (ne:SI (match_operand:SI 0 "" "")
7024                               (const_int 1))
7025                           (label_ref (match_operand 4 "" ""))
7026                           (pc)))
7027               (set (match_dup 0)
7028                    (plus:SI (match_dup 0) (const_int -1)))
7029               (clobber (reg:SI T_REG))])]
7030   "TARGET_SH2"
7031   "
7032 {
7033   if (GET_MODE (operands[0]) != SImode)
7034     FAIL;
7035 }
7036 ")
7037
7038 (define_insn_and_split "doloop_end_split"
7039   [(set (pc)
7040         (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7041                           (const_int 1))
7042                       (label_ref (match_operand 1 "" ""))
7043                       (pc)))
7044    (set (match_dup 0)
7045         (plus (match_dup 0) (const_int -1)))
7046    (clobber (reg:SI T_REG))]
7047   "TARGET_SH2"
7048   "#"
7049   ""
7050   [(parallel [(set (reg:SI T_REG)
7051                    (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7052                           (const_int 1)))
7053               (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7054    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7055                            (label_ref (match_operand 1 "" ""))
7056                            (pc)))]
7057 ""
7058    [(set_attr "type" "cbranch")])
7059
7060 \f
7061 ;; ------------------------------------------------------------------------
7062 ;; Jump and linkage insns
7063 ;; ------------------------------------------------------------------------
7064
7065 (define_insn "jump_compact"
7066   [(set (pc)
7067         (label_ref (match_operand 0 "" "")))]
7068   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7069   "*
7070 {
7071   /* The length is 16 if the delay slot is unfilled.  */
7072   if (get_attr_length(insn) > 4)
7073     return output_far_jump(insn, operands[0]);
7074   else
7075     return   \"bra      %l0%#\";
7076 }"
7077   [(set_attr "type" "jump")
7078    (set_attr "needs_delay_slot" "yes")])
7079
7080 ;; ??? It would be much saner to explicitly use the scratch register
7081 ;; in the jump insn, and have indirect_jump_scratch only set it,
7082 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7083 ;; from the target then, as it uses simplejump_p.
7084 ;;(define_insn "jump_compact_far"
7085 ;;  [(set (pc)
7086 ;;      (label_ref (match_operand 0 "" "")))
7087 ;;   (use (match_operand 1 "register_operand" "r")]
7088 ;;  "TARGET_SH1"
7089 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7090 ;;  [(set_attr "type" "jump")
7091 ;;   (set_attr "needs_delay_slot" "yes")])
7092
7093 (define_insn "jump_media"
7094   [(set (pc)
7095         (match_operand 0 "target_operand" "b"))]
7096   "TARGET_SHMEDIA"
7097   "blink        %0, r63%>"
7098   [(set_attr "type" "jump_media")])
7099
7100 (define_expand "jump"
7101   [(set (pc)
7102         (label_ref (match_operand 0 "" "")))]
7103   ""
7104   "
7105 {
7106   if (TARGET_SH1)
7107     emit_jump_insn (gen_jump_compact (operands[0]));
7108   else if (TARGET_SHMEDIA)
7109     {
7110       if (reload_in_progress || reload_completed)
7111         FAIL;
7112       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7113                                                          operands[0])));
7114     }
7115   DONE;
7116 }")
7117
7118 (define_insn "force_mode_for_call"
7119   [(use (reg:PSI FPSCR_REG))]
7120   "TARGET_SHCOMPACT"
7121   ""
7122   [(set_attr "length" "0")
7123    (set (attr "fp_mode")
7124         (if_then_else (eq_attr "fpu_single" "yes")
7125                       (const_string "single") (const_string "double")))])
7126
7127 (define_insn "calli"
7128   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7129          (match_operand 1 "" ""))
7130    (use (reg:PSI FPSCR_REG))
7131    (clobber (reg:SI PR_REG))]
7132   "TARGET_SH1"
7133   "*
7134    {
7135      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7136         return \"jsr/n\\t@%0\";
7137      else
7138         return \"jsr\\t@%0%#\";
7139    }"
7140
7141   [(set_attr "type" "call")
7142    (set (attr "fp_mode")
7143         (if_then_else (eq_attr "fpu_single" "yes")
7144                       (const_string "single") (const_string "double")))
7145    (set_attr "needs_delay_slot" "yes")
7146    (set_attr "fp_set" "unknown")])
7147
7148 ;; This is TBR relative jump instruction for SH2A architecture.
7149 ;; Its use is enabled assigning an attribute "function_vector"
7150 ;; and the vector number to a function during its declaration.
7151
7152 (define_insn "calli_tbr_rel"
7153   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7154          (match_operand 1 "" ""))
7155    (use (reg:PSI FPSCR_REG))
7156    (clobber (reg:SI PR_REG))]
7157   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7158   "*
7159 {
7160   unsigned HOST_WIDE_INT vect_num;
7161   vect_num = sh2a_get_function_vector_number (operands[0]);
7162   operands[2] = GEN_INT (vect_num * 4);
7163
7164   return \"jsr/n\\t@@(%O2,tbr)\";
7165 }"
7166   [(set_attr "type" "call")
7167    (set (attr "fp_mode")
7168         (if_then_else (eq_attr "fpu_single" "yes")
7169                       (const_string "single") (const_string "double")))
7170    (set_attr "needs_delay_slot" "no")
7171    (set_attr "fp_set" "unknown")])
7172
7173 ;; This is a pc-rel call, using bsrf, for use with PIC.
7174
7175 (define_insn "calli_pcrel"
7176   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7177          (match_operand 1 "" ""))
7178    (use (reg:PSI FPSCR_REG))
7179    (use (reg:SI PIC_REG))
7180    (use (match_operand 2 "" ""))
7181    (clobber (reg:SI PR_REG))]
7182   "TARGET_SH2"
7183   "bsrf %0\\n%O2:%#"
7184   [(set_attr "type" "call")
7185    (set (attr "fp_mode")
7186         (if_then_else (eq_attr "fpu_single" "yes")
7187                       (const_string "single") (const_string "double")))
7188    (set_attr "needs_delay_slot" "yes")
7189    (set_attr "fp_set" "unknown")])
7190
7191 (define_insn_and_split "call_pcrel"
7192   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7193          (match_operand 1 "" ""))
7194    (use (reg:PSI FPSCR_REG))
7195    (use (reg:SI PIC_REG))
7196    (clobber (reg:SI PR_REG))
7197    (clobber (match_scratch:SI 2 "=r"))]
7198   "TARGET_SH2"
7199   "#"
7200   "reload_completed"
7201   [(const_int 0)]
7202   "
7203 {
7204   rtx lab = PATTERN (gen_call_site ());
7205
7206   if (SYMBOL_REF_LOCAL_P (operands[0]))
7207     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7208   else
7209     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7210   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7211   DONE;
7212 }"
7213   [(set_attr "type" "call")
7214    (set (attr "fp_mode")
7215         (if_then_else (eq_attr "fpu_single" "yes")
7216                       (const_string "single") (const_string "double")))
7217    (set_attr "needs_delay_slot" "yes")
7218    (set_attr "fp_set" "unknown")])
7219
7220 (define_insn "call_compact"
7221   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7222          (match_operand 1 "" ""))
7223    (match_operand 2 "immediate_operand" "n")
7224    (use (reg:SI R0_REG))
7225    (use (reg:SI R1_REG))
7226    (use (reg:PSI FPSCR_REG))
7227    (clobber (reg:SI PR_REG))]
7228   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7229   "jsr  @%0%#"
7230   [(set_attr "type" "call")
7231    (set (attr "fp_mode")
7232         (if_then_else (eq_attr "fpu_single" "yes")
7233                       (const_string "single") (const_string "double")))
7234    (set_attr "needs_delay_slot" "yes")])
7235
7236 (define_insn "call_compact_rettramp"
7237   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7238          (match_operand 1 "" ""))
7239    (match_operand 2 "immediate_operand" "n")
7240    (use (reg:SI R0_REG))
7241    (use (reg:SI R1_REG))
7242    (use (reg:PSI FPSCR_REG))
7243    (clobber (reg:SI R10_REG))
7244    (clobber (reg:SI PR_REG))]
7245   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7246   "jsr  @%0%#"
7247   [(set_attr "type" "call")
7248    (set (attr "fp_mode")
7249         (if_then_else (eq_attr "fpu_single" "yes")
7250                       (const_string "single") (const_string "double")))
7251    (set_attr "needs_delay_slot" "yes")])
7252
7253 (define_insn "call_media"
7254   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7255          (match_operand 1 "" ""))
7256    (clobber (reg:DI PR_MEDIA_REG))]
7257   "TARGET_SHMEDIA"
7258   "blink        %0, r18"
7259   [(set_attr "type" "jump_media")])
7260
7261 (define_insn "call_valuei"
7262   [(set (match_operand 0 "" "=rf")
7263         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7264               (match_operand 2 "" "")))
7265    (use (reg:PSI FPSCR_REG))
7266    (clobber (reg:SI PR_REG))]
7267   "TARGET_SH1"
7268   "*
7269    {
7270      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7271         return \"jsr/n\\t@%1\";
7272      else
7273         return \"jsr\\t@%1%#\";
7274    }"
7275   [(set_attr "type" "call")
7276    (set (attr "fp_mode")
7277         (if_then_else (eq_attr "fpu_single" "yes")
7278                       (const_string "single") (const_string "double")))
7279    (set_attr "needs_delay_slot" "yes")
7280    (set_attr "fp_set" "unknown")])
7281
7282 ;; This is TBR relative jump instruction for SH2A architecture.
7283 ;; Its use is enabled assigning an attribute "function_vector"
7284 ;; and the vector number to a function during its declaration.
7285
7286 (define_insn "call_valuei_tbr_rel"
7287   [(set (match_operand 0 "" "=rf")
7288         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7289               (match_operand 2 "" "")))
7290    (use (reg:PSI FPSCR_REG))
7291    (clobber (reg:SI PR_REG))]
7292   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7293   "*
7294 {
7295   unsigned HOST_WIDE_INT vect_num;
7296   vect_num = sh2a_get_function_vector_number (operands[1]);
7297   operands[3] = GEN_INT (vect_num * 4);
7298
7299   return \"jsr/n\\t@@(%O3,tbr)\";
7300 }"
7301   [(set_attr "type" "call")
7302    (set (attr "fp_mode")
7303         (if_then_else (eq_attr "fpu_single" "yes")
7304                       (const_string "single") (const_string "double")))
7305    (set_attr "needs_delay_slot" "no")
7306    (set_attr "fp_set" "unknown")])
7307
7308 (define_insn "call_valuei_pcrel"
7309   [(set (match_operand 0 "" "=rf")
7310         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7311               (match_operand 2 "" "")))
7312    (use (reg:PSI FPSCR_REG))
7313    (use (reg:SI PIC_REG))
7314    (use (match_operand 3 "" ""))
7315    (clobber (reg:SI PR_REG))]
7316   "TARGET_SH2"
7317   "bsrf %1\\n%O3:%#"
7318   [(set_attr "type" "call")
7319    (set (attr "fp_mode")
7320         (if_then_else (eq_attr "fpu_single" "yes")
7321                       (const_string "single") (const_string "double")))
7322    (set_attr "needs_delay_slot" "yes")
7323    (set_attr "fp_set" "unknown")])
7324
7325 (define_insn_and_split "call_value_pcrel"
7326   [(set (match_operand 0 "" "=rf")
7327         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7328               (match_operand 2 "" "")))
7329    (use (reg:PSI FPSCR_REG))
7330    (use (reg:SI PIC_REG))
7331    (clobber (reg:SI PR_REG))
7332    (clobber (match_scratch:SI 3 "=r"))]
7333   "TARGET_SH2"
7334   "#"
7335   "reload_completed"
7336   [(const_int 0)]
7337   "
7338 {
7339   rtx lab = PATTERN (gen_call_site ());
7340
7341   if (SYMBOL_REF_LOCAL_P (operands[1]))
7342     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7343   else
7344     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7345   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7346                                          operands[2], copy_rtx (lab)));
7347   DONE;
7348 }"
7349   [(set_attr "type" "call")
7350    (set (attr "fp_mode")
7351         (if_then_else (eq_attr "fpu_single" "yes")
7352                       (const_string "single") (const_string "double")))
7353    (set_attr "needs_delay_slot" "yes")
7354    (set_attr "fp_set" "unknown")])
7355
7356 (define_insn "call_value_compact"
7357   [(set (match_operand 0 "" "=rf")
7358         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7359               (match_operand 2 "" "")))
7360    (match_operand 3 "immediate_operand" "n")
7361    (use (reg:SI R0_REG))
7362    (use (reg:SI R1_REG))
7363    (use (reg:PSI FPSCR_REG))
7364    (clobber (reg:SI PR_REG))]
7365   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7366   "jsr  @%1%#"
7367   [(set_attr "type" "call")
7368    (set (attr "fp_mode")
7369         (if_then_else (eq_attr "fpu_single" "yes")
7370                       (const_string "single") (const_string "double")))
7371    (set_attr "needs_delay_slot" "yes")])
7372
7373 (define_insn "call_value_compact_rettramp"
7374   [(set (match_operand 0 "" "=rf")
7375         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7376               (match_operand 2 "" "")))
7377    (match_operand 3 "immediate_operand" "n")
7378    (use (reg:SI R0_REG))
7379    (use (reg:SI R1_REG))
7380    (use (reg:PSI FPSCR_REG))
7381    (clobber (reg:SI R10_REG))
7382    (clobber (reg:SI PR_REG))]
7383   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7384   "jsr  @%1%#"
7385   [(set_attr "type" "call")
7386    (set (attr "fp_mode")
7387         (if_then_else (eq_attr "fpu_single" "yes")
7388                       (const_string "single") (const_string "double")))
7389    (set_attr "needs_delay_slot" "yes")])
7390
7391 (define_insn "call_value_media"
7392   [(set (match_operand 0 "" "=rf")
7393         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7394               (match_operand 2 "" "")))
7395    (clobber (reg:DI PR_MEDIA_REG))]
7396   "TARGET_SHMEDIA"
7397   "blink        %1, r18"
7398   [(set_attr "type" "jump_media")])
7399
7400 (define_expand "call"
7401   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7402                             (match_operand 1 "" ""))
7403               (match_operand 2 "" "")
7404               (use (reg:PSI FPSCR_REG))
7405               (clobber (reg:SI PR_REG))])]
7406   ""
7407   "
7408 {
7409   if (TARGET_SHMEDIA)
7410     {
7411       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7412       emit_call_insn (gen_call_media (operands[0], operands[1]));
7413       DONE;
7414     }
7415   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7416     {
7417       rtx cookie_rtx = operands[2];
7418       long cookie = INTVAL (cookie_rtx);
7419       rtx func = XEXP (operands[0], 0);
7420       rtx r0, r1;
7421
7422       if (flag_pic)
7423         {
7424           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7425             {
7426               rtx reg = gen_reg_rtx (Pmode);
7427
7428               emit_insn (gen_symGOTPLT2reg (reg, func));
7429               func = reg;
7430             }
7431           else
7432             func = legitimize_pic_address (func, Pmode, 0);
7433         }
7434
7435       r0 = gen_rtx_REG (SImode, R0_REG);
7436       r1 = gen_rtx_REG (SImode, R1_REG);
7437
7438       /* Since such a call function may use all call-clobbered
7439          registers, we force a mode switch earlier, so that we don't
7440          run out of registers when adjusting fpscr for the call.  */
7441       emit_insn (gen_force_mode_for_call ());
7442
7443       operands[0]
7444         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7445                            SFUNC_GOT);
7446       operands[0] = force_reg (SImode, operands[0]);
7447
7448       emit_move_insn (r0, func);
7449       emit_move_insn (r1, cookie_rtx);
7450
7451       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7452         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7453                                                    operands[2]));
7454       else
7455         emit_call_insn (gen_call_compact (operands[0], operands[1],
7456                                           operands[2]));
7457
7458       DONE;
7459     }
7460   else if (TARGET_SHCOMPACT && flag_pic
7461            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7462            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7463     {
7464       rtx reg = gen_reg_rtx (Pmode);
7465
7466       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7467       XEXP (operands[0], 0) = reg;
7468     }
7469   if (!flag_pic && TARGET_SH2A
7470       && MEM_P (operands[0])
7471       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7472     {
7473       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7474         {
7475           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7476                                              operands[1]));
7477           DONE;
7478         }
7479     }
7480   if (flag_pic && TARGET_SH2
7481       && MEM_P (operands[0])
7482       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7483     {
7484       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7485       DONE;
7486     }
7487   else
7488   {
7489     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7490     operands[1] = operands[2];
7491   }
7492
7493   emit_call_insn (gen_calli (operands[0], operands[1]));
7494   DONE;
7495 }")
7496
7497 (define_insn "call_pop_compact"
7498   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7499          (match_operand 1 "" ""))
7500    (match_operand 2 "immediate_operand" "n")
7501    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7502                                  (match_operand 3 "immediate_operand" "n")))
7503    (use (reg:SI R0_REG))
7504    (use (reg:SI R1_REG))
7505    (use (reg:PSI FPSCR_REG))
7506    (clobber (reg:SI PR_REG))]
7507   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7508   "jsr  @%0%#"
7509   [(set_attr "type" "call")
7510    (set (attr "fp_mode")
7511         (if_then_else (eq_attr "fpu_single" "yes")
7512                       (const_string "single") (const_string "double")))
7513    (set_attr "needs_delay_slot" "yes")])
7514
7515 (define_insn "call_pop_compact_rettramp"
7516   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7517          (match_operand 1 "" ""))
7518    (match_operand 2 "immediate_operand" "n")
7519    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7520                                  (match_operand 3 "immediate_operand" "n")))
7521    (use (reg:SI R0_REG))
7522    (use (reg:SI R1_REG))
7523    (use (reg:PSI FPSCR_REG))
7524    (clobber (reg:SI R10_REG))
7525    (clobber (reg:SI PR_REG))]
7526   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7527   "jsr  @%0%#"
7528   [(set_attr "type" "call")
7529    (set (attr "fp_mode")
7530         (if_then_else (eq_attr "fpu_single" "yes")
7531                       (const_string "single") (const_string "double")))
7532    (set_attr "needs_delay_slot" "yes")])
7533
7534 (define_expand "call_pop"
7535   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7536                     (match_operand 1 "" ""))
7537              (match_operand 2 "" "")
7538              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7539                                            (match_operand 3 "" "")))])]
7540   "TARGET_SHCOMPACT"
7541   "
7542 {
7543   rtx cookie_rtx;
7544   long cookie;
7545   rtx func;
7546   rtx r0, r1;
7547
7548   gcc_assert (operands[2] && INTVAL (operands[2]));
7549   cookie_rtx = operands[2];
7550   cookie = INTVAL (cookie_rtx);
7551   func = XEXP (operands[0], 0);
7552
7553   if (flag_pic)
7554     {
7555       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7556         {
7557           rtx reg = gen_reg_rtx (Pmode);
7558           emit_insn (gen_symGOTPLT2reg (reg, func));
7559           func = reg;
7560         }
7561       else
7562         func = legitimize_pic_address (func, Pmode, 0);
7563     }
7564
7565   r0 = gen_rtx_REG (SImode, R0_REG);
7566   r1 = gen_rtx_REG (SImode, R1_REG);
7567
7568   /* Since such a call function may use all call-clobbered
7569      registers, we force a mode switch earlier, so that we don't
7570      run out of registers when adjusting fpscr for the call.  */
7571   emit_insn (gen_force_mode_for_call ());
7572
7573   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7574                                  SFUNC_GOT);
7575   operands[0] = force_reg (SImode, operands[0]);
7576
7577   emit_move_insn (r0, func);
7578   emit_move_insn (r1, cookie_rtx);
7579
7580   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7581     emit_call_insn (gen_call_pop_compact_rettramp
7582                      (operands[0], operands[1], operands[2], operands[3]));
7583   else
7584     emit_call_insn (gen_call_pop_compact
7585                      (operands[0], operands[1], operands[2], operands[3]));
7586
7587   DONE;
7588 }")
7589
7590 (define_expand "call_value"
7591   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7592                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7593                                  (match_operand 2 "" "")))
7594               (match_operand 3 "" "")
7595               (use (reg:PSI FPSCR_REG))
7596               (clobber (reg:SI PR_REG))])]
7597   ""
7598   "
7599 {
7600   if (TARGET_SHMEDIA)
7601     {
7602       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7603       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7604                                             operands[2]));
7605       DONE;
7606     }
7607   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7608     {
7609       rtx cookie_rtx = operands[3];
7610       long cookie = INTVAL (cookie_rtx);
7611       rtx func = XEXP (operands[1], 0);
7612       rtx r0, r1;
7613
7614       if (flag_pic)
7615         {
7616           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7617             {
7618               rtx reg = gen_reg_rtx (Pmode);
7619
7620               emit_insn (gen_symGOTPLT2reg (reg, func));
7621               func = reg;
7622             }
7623           else
7624             func = legitimize_pic_address (func, Pmode, 0);
7625         }
7626
7627       r0 = gen_rtx_REG (SImode, R0_REG);
7628       r1 = gen_rtx_REG (SImode, R1_REG);
7629
7630       /* Since such a call function may use all call-clobbered
7631          registers, we force a mode switch earlier, so that we don't
7632          run out of registers when adjusting fpscr for the call.  */
7633       emit_insn (gen_force_mode_for_call ());
7634
7635       operands[1]
7636         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7637                            SFUNC_GOT);
7638       operands[1] = force_reg (SImode, operands[1]);
7639
7640       emit_move_insn (r0, func);
7641       emit_move_insn (r1, cookie_rtx);
7642
7643       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7644         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7645                                                          operands[1],
7646                                                          operands[2],
7647                                                          operands[3]));
7648       else
7649         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7650                                                 operands[2], operands[3]));
7651
7652       DONE;
7653     }
7654   else if (TARGET_SHCOMPACT && flag_pic
7655            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7656            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7657     {
7658       rtx reg = gen_reg_rtx (Pmode);
7659
7660       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7661       XEXP (operands[1], 0) = reg;
7662     }
7663   if (!flag_pic && TARGET_SH2A
7664       && MEM_P (operands[1])
7665       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7666     {
7667       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7668         {
7669           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7670                                  XEXP (operands[1], 0), operands[2]));
7671           DONE;
7672         }
7673     }
7674   if (flag_pic && TARGET_SH2
7675       && MEM_P (operands[1])
7676       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7677     {
7678       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7679                                             operands[2]));
7680       DONE;
7681     }
7682   else
7683     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7684
7685   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7686   DONE;
7687 }")
7688
7689 (define_insn "sibcalli"
7690   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7691          (match_operand 1 "" ""))
7692    (use (reg:PSI FPSCR_REG))
7693    (return)]
7694   "TARGET_SH1"
7695   "jmp  @%0%#"
7696   [(set_attr "needs_delay_slot" "yes")
7697    (set (attr "fp_mode")
7698         (if_then_else (eq_attr "fpu_single" "yes")
7699                       (const_string "single") (const_string "double")))
7700    (set_attr "type" "jump_ind")])
7701
7702 (define_insn "sibcalli_pcrel"
7703   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7704          (match_operand 1 "" ""))
7705    (use (match_operand 2 "" ""))
7706    (use (reg:PSI FPSCR_REG))
7707    (return)]
7708   "TARGET_SH2"
7709   "braf %0\\n%O2:%#"
7710   [(set_attr "needs_delay_slot" "yes")
7711    (set (attr "fp_mode")
7712         (if_then_else (eq_attr "fpu_single" "yes")
7713                       (const_string "single") (const_string "double")))
7714    (set_attr "type" "jump_ind")])
7715
7716 ;; This uses an unspec to describe that the symbol_ref is very close.
7717 (define_insn "sibcalli_thunk"
7718   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7719                              UNSPEC_THUNK))
7720          (match_operand 1 "" ""))
7721    (use (reg:PSI FPSCR_REG))
7722    (return)]
7723   "TARGET_SH1"
7724   "bra  %O0"
7725   [(set_attr "needs_delay_slot" "yes")
7726    (set (attr "fp_mode")
7727         (if_then_else (eq_attr "fpu_single" "yes")
7728                       (const_string "single") (const_string "double")))
7729    (set_attr "type" "jump")
7730    (set_attr "length" "2")])
7731
7732 (define_insn_and_split "sibcall_pcrel"
7733   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7734          (match_operand 1 "" ""))
7735    (use (reg:PSI FPSCR_REG))
7736    (clobber (match_scratch:SI 2 "=k"))
7737    (return)]
7738   "TARGET_SH2"
7739   "#"
7740   "reload_completed"
7741   [(const_int 0)]
7742   "
7743 {
7744   rtx lab = PATTERN (gen_call_site ());
7745   rtx call_insn;
7746
7747   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7748   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7749                                                   copy_rtx (lab)));
7750   SIBLING_CALL_P (call_insn) = 1;
7751   DONE;
7752 }"
7753   [(set_attr "needs_delay_slot" "yes")
7754    (set (attr "fp_mode")
7755         (if_then_else (eq_attr "fpu_single" "yes")
7756                       (const_string "single") (const_string "double")))
7757    (set_attr "type" "jump_ind")])
7758
7759 (define_insn "sibcall_compact"
7760   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7761          (match_operand 1 "" ""))
7762    (return)
7763    (use (match_operand:SI 2 "register_operand" "z,x"))
7764    (use (reg:SI R1_REG))
7765    (use (reg:PSI FPSCR_REG))
7766    ;; We want to make sure the `x' above will only match MACH_REG
7767    ;; because sibcall_epilogue may clobber MACL_REG.
7768    (clobber (reg:SI MACL_REG))]
7769   "TARGET_SHCOMPACT"
7770   "@
7771         jmp     @%0%#
7772         jmp     @%0\\n  sts     %2, r0"
7773   [(set_attr "needs_delay_slot" "yes,no")
7774    (set_attr "length" "2,4")
7775    (set (attr "fp_mode") (const_string "single"))
7776    (set_attr "type" "jump_ind")])
7777
7778 (define_insn "sibcall_media"
7779   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7780          (match_operand 1 "" ""))
7781    (use (reg:SI PR_MEDIA_REG))
7782    (return)]
7783   "TARGET_SHMEDIA"
7784   "blink        %0, r63"
7785   [(set_attr "type" "jump_media")])
7786
7787 (define_expand "sibcall"
7788   [(parallel
7789     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7790            (match_operand 1 "" ""))
7791      (match_operand 2 "" "")
7792      (use (reg:PSI FPSCR_REG))
7793      (return)])]
7794   ""
7795   "
7796 {
7797   if (TARGET_SHMEDIA)
7798     {
7799       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7800       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7801       DONE;
7802     }
7803   else if (TARGET_SHCOMPACT && operands[2]
7804            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7805     {
7806       rtx cookie_rtx = operands[2];
7807       long cookie = INTVAL (cookie_rtx);
7808       rtx func = XEXP (operands[0], 0);
7809       rtx mach, r1;
7810
7811       if (flag_pic)
7812         {
7813           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7814             {
7815               rtx reg = gen_reg_rtx (Pmode);
7816
7817               emit_insn (gen_symGOT2reg (reg, func));
7818               func = reg;
7819             }
7820           else
7821             func = legitimize_pic_address (func, Pmode, 0);
7822         }
7823
7824       /* FIXME: if we could tell whether all argument registers are
7825          already taken, we could decide whether to force the use of
7826          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7827          simple way to tell.  We could use the CALL_COOKIE, but we
7828          can't currently tell a register used for regular argument
7829          passing from one that is unused.  If we leave it up to reload
7830          to decide which register to use, it seems to always choose
7831          R0_REG, which leaves no available registers in SIBCALL_REGS
7832          to hold the address of the trampoline.  */
7833       mach = gen_rtx_REG (SImode, MACH_REG);
7834       r1 = gen_rtx_REG (SImode, R1_REG);
7835
7836       /* Since such a call function may use all call-clobbered
7837          registers, we force a mode switch earlier, so that we don't
7838          run out of registers when adjusting fpscr for the call.  */
7839       emit_insn (gen_force_mode_for_call ());
7840
7841       operands[0]
7842         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7843                            SFUNC_GOT);
7844       operands[0] = force_reg (SImode, operands[0]);
7845
7846       /* We don't need a return trampoline, since the callee will
7847          return directly to the upper caller.  */
7848       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7849         {
7850           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7851           cookie_rtx = GEN_INT (cookie);
7852         }
7853
7854       emit_move_insn (mach, func);
7855       emit_move_insn (r1, cookie_rtx);
7856
7857       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7858       DONE;
7859     }
7860   else if (TARGET_SHCOMPACT && flag_pic
7861            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7862            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7863     {
7864       rtx reg = gen_reg_rtx (Pmode);
7865
7866       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7867       XEXP (operands[0], 0) = reg;
7868     }
7869   if (flag_pic && TARGET_SH2
7870       && MEM_P (operands[0])
7871       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7872       /* The PLT needs the PIC register, but the epilogue would have
7873          to restore it, so we can only use PC-relative PIC calls for
7874          static functions.  */
7875       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7876     {
7877       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7878       DONE;
7879     }
7880   else
7881     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7882
7883   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7884   DONE;
7885 }")
7886
7887 (define_insn "sibcall_valuei"
7888   [(set (match_operand 0 "" "=rf")
7889         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7890               (match_operand 2 "" "")))
7891    (use (reg:PSI FPSCR_REG))
7892    (return)]
7893   "TARGET_SH1"
7894   "jmp  @%1%#"
7895   [(set_attr "needs_delay_slot" "yes")
7896    (set (attr "fp_mode")
7897         (if_then_else (eq_attr "fpu_single" "yes")
7898                       (const_string "single") (const_string "double")))
7899    (set_attr "type" "jump_ind")])
7900
7901 (define_insn "sibcall_valuei_pcrel"
7902   [(set (match_operand 0 "" "=rf")
7903         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7904               (match_operand 2 "" "")))
7905    (use (match_operand 3 "" ""))
7906    (use (reg:PSI FPSCR_REG))
7907    (return)]
7908   "TARGET_SH2"
7909   "braf %1\\n%O3:%#"
7910   [(set_attr "needs_delay_slot" "yes")
7911    (set (attr "fp_mode")
7912         (if_then_else (eq_attr "fpu_single" "yes")
7913                       (const_string "single") (const_string "double")))
7914    (set_attr "type" "jump_ind")])
7915
7916 (define_insn_and_split "sibcall_value_pcrel"
7917   [(set (match_operand 0 "" "=rf")
7918         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7919               (match_operand 2 "" "")))
7920    (use (reg:PSI FPSCR_REG))
7921    (clobber (match_scratch:SI 3 "=k"))
7922    (return)]
7923   "TARGET_SH2"
7924   "#"
7925   "reload_completed"
7926   [(const_int 0)]
7927   "
7928 {
7929   rtx lab = PATTERN (gen_call_site ());
7930   rtx call_insn;
7931
7932   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7933   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7934                                                         operands[3],
7935                                                         operands[2],
7936                                                         copy_rtx (lab)));
7937   SIBLING_CALL_P (call_insn) = 1;
7938   DONE;
7939 }"
7940   [(set_attr "needs_delay_slot" "yes")
7941    (set (attr "fp_mode")
7942         (if_then_else (eq_attr "fpu_single" "yes")
7943                       (const_string "single") (const_string "double")))
7944    (set_attr "type" "jump_ind")])
7945
7946 (define_insn "sibcall_value_compact"
7947   [(set (match_operand 0 "" "=rf,rf")
7948         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7949               (match_operand 2 "" "")))
7950    (return)
7951    (use (match_operand:SI 3 "register_operand" "z,x"))
7952    (use (reg:SI R1_REG))
7953    (use (reg:PSI FPSCR_REG))
7954    ;; We want to make sure the `x' above will only match MACH_REG
7955    ;; because sibcall_epilogue may clobber MACL_REG.
7956    (clobber (reg:SI MACL_REG))]
7957   "TARGET_SHCOMPACT"
7958   "@
7959         jmp     @%1%#
7960         jmp     @%1\\n  sts     %3, r0"
7961   [(set_attr "needs_delay_slot" "yes,no")
7962    (set_attr "length" "2,4")
7963    (set (attr "fp_mode") (const_string "single"))
7964    (set_attr "type" "jump_ind")])
7965
7966 (define_insn "sibcall_value_media"
7967   [(set (match_operand 0 "" "=rf")
7968         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7969               (match_operand 2 "" "")))
7970    (use (reg:SI PR_MEDIA_REG))
7971    (return)]
7972   "TARGET_SHMEDIA"
7973   "blink        %1, r63"
7974   [(set_attr "type" "jump_media")])
7975
7976 (define_expand "sibcall_value"
7977   [(parallel
7978     [(set (match_operand 0 "arith_reg_operand" "")
7979           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7980                 (match_operand 2 "" "")))
7981      (match_operand 3 "" "")
7982      (use (reg:PSI FPSCR_REG))
7983      (return)])]
7984   ""
7985   "
7986 {
7987   if (TARGET_SHMEDIA)
7988     {
7989       operands[1] = shmedia_prepare_call_address (operands[1], 1);
7990       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
7991                                                operands[2]));
7992       DONE;
7993     }
7994   else if (TARGET_SHCOMPACT && operands[3]
7995            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7996     {
7997       rtx cookie_rtx = operands[3];
7998       long cookie = INTVAL (cookie_rtx);
7999       rtx func = XEXP (operands[1], 0);
8000       rtx mach, r1;
8001
8002       if (flag_pic)
8003         {
8004           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8005             {
8006               rtx reg = gen_reg_rtx (Pmode);
8007
8008               emit_insn (gen_symGOT2reg (reg, func));
8009               func = reg;
8010             }
8011           else
8012             func = legitimize_pic_address (func, Pmode, 0);
8013         }
8014
8015       /* FIXME: if we could tell whether all argument registers are
8016          already taken, we could decide whether to force the use of
8017          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8018          simple way to tell.  We could use the CALL_COOKIE, but we
8019          can't currently tell a register used for regular argument
8020          passing from one that is unused.  If we leave it up to reload
8021          to decide which register to use, it seems to always choose
8022          R0_REG, which leaves no available registers in SIBCALL_REGS
8023          to hold the address of the trampoline.  */
8024       mach = gen_rtx_REG (SImode, MACH_REG);
8025       r1 = gen_rtx_REG (SImode, R1_REG);
8026
8027       /* Since such a call function may use all call-clobbered
8028          registers, we force a mode switch earlier, so that we don't
8029          run out of registers when adjusting fpscr for the call.  */
8030       emit_insn (gen_force_mode_for_call ());
8031
8032       operands[1]
8033         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8034                            SFUNC_GOT);
8035       operands[1] = force_reg (SImode, operands[1]);
8036
8037       /* We don't need a return trampoline, since the callee will
8038          return directly to the upper caller.  */
8039       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8040         {
8041           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8042           cookie_rtx = GEN_INT (cookie);
8043         }
8044
8045       emit_move_insn (mach, func);
8046       emit_move_insn (r1, cookie_rtx);
8047
8048       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8049                                                  operands[2], mach));
8050       DONE;
8051     }
8052   else if (TARGET_SHCOMPACT && flag_pic
8053            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8054            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8055     {
8056       rtx reg = gen_reg_rtx (Pmode);
8057
8058       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8059       XEXP (operands[1], 0) = reg;
8060     }
8061   if (flag_pic && TARGET_SH2
8062       && MEM_P (operands[1])
8063       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8064       /* The PLT needs the PIC register, but the epilogue would have
8065          to restore it, so we can only use PC-relative PIC calls for
8066          static functions.  */
8067       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8068     {
8069       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8070                                                XEXP (operands[1], 0),
8071                                                operands[2]));
8072       DONE;
8073     }
8074   else
8075     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8076
8077   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8078   DONE;
8079 }")
8080
8081 (define_insn "call_value_pop_compact"
8082   [(set (match_operand 0 "" "=rf")
8083         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8084               (match_operand 2 "" "")))
8085    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8086                                  (match_operand 4 "immediate_operand" "n")))
8087    (match_operand 3 "immediate_operand" "n")
8088    (use (reg:SI R0_REG))
8089    (use (reg:SI R1_REG))
8090    (use (reg:PSI FPSCR_REG))
8091    (clobber (reg:SI PR_REG))]
8092   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8093   "jsr  @%1%#"
8094   [(set_attr "type" "call")
8095    (set (attr "fp_mode")
8096         (if_then_else (eq_attr "fpu_single" "yes")
8097                       (const_string "single") (const_string "double")))
8098    (set_attr "needs_delay_slot" "yes")])
8099
8100 (define_insn "call_value_pop_compact_rettramp"
8101   [(set (match_operand 0 "" "=rf")
8102         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8103               (match_operand 2 "" "")))
8104    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8105                                  (match_operand 4 "immediate_operand" "n")))
8106    (match_operand 3 "immediate_operand" "n")
8107    (use (reg:SI R0_REG))
8108    (use (reg:SI R1_REG))
8109    (use (reg:PSI FPSCR_REG))
8110    (clobber (reg:SI R10_REG))
8111    (clobber (reg:SI PR_REG))]
8112   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8113   "jsr  @%1%#"
8114   [(set_attr "type" "call")
8115    (set (attr "fp_mode")
8116         (if_then_else (eq_attr "fpu_single" "yes")
8117                       (const_string "single") (const_string "double")))
8118    (set_attr "needs_delay_slot" "yes")])
8119
8120 (define_expand "call_value_pop"
8121   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8122                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8123                                  (match_operand 2 "" "")))
8124               (match_operand 3 "" "")
8125               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8126                                             (match_operand 4 "" "")))])]
8127   "TARGET_SHCOMPACT"
8128   "
8129 {
8130   rtx cookie_rtx;
8131   long cookie;
8132   rtx func;
8133   rtx r0, r1;
8134
8135   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8136   cookie_rtx = operands[3];
8137   cookie = INTVAL (cookie_rtx);
8138   func = XEXP (operands[1], 0);
8139
8140   if (flag_pic)
8141     {
8142       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8143         {
8144           rtx reg = gen_reg_rtx (Pmode);
8145
8146           emit_insn (gen_symGOTPLT2reg (reg, func));
8147           func = reg;
8148         }
8149       else
8150         func = legitimize_pic_address (func, Pmode, 0);
8151     }
8152
8153   r0 = gen_rtx_REG (SImode, R0_REG);
8154   r1 = gen_rtx_REG (SImode, R1_REG);
8155
8156   /* Since such a call function may use all call-clobbered
8157      registers, we force a mode switch earlier, so that we don't
8158      run out of registers when adjusting fpscr for the call.  */
8159   emit_insn (gen_force_mode_for_call ());
8160
8161   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8162                                  SFUNC_GOT);
8163   operands[1] = force_reg (SImode, operands[1]);
8164
8165   emit_move_insn (r0, func);
8166   emit_move_insn (r1, cookie_rtx);
8167
8168   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8169     emit_call_insn (gen_call_value_pop_compact_rettramp
8170                         (operands[0], operands[1], operands[2],
8171                          operands[3], operands[4]));
8172   else
8173     emit_call_insn (gen_call_value_pop_compact
8174                         (operands[0], operands[1], operands[2],
8175                          operands[3], operands[4]));
8176
8177   DONE;
8178 }")
8179
8180 (define_expand "sibcall_epilogue"
8181   [(return)]
8182   ""
8183   "
8184 {
8185   sh_expand_epilogue (1);
8186   if (TARGET_SHCOMPACT)
8187     {
8188       rtx insn, set;
8189
8190       /* If epilogue clobbers r0, preserve it in macl.  */
8191       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8192         if ((set = single_set (insn))
8193             && REG_P (SET_DEST (set))
8194             && REGNO (SET_DEST (set)) == R0_REG)
8195           {
8196             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8197             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8198
8199             /* We can't tell at this point whether the sibcall is a
8200                sibcall_compact and, if it is, whether it uses r0 or
8201                mach as operand 2, so let the instructions that
8202                preserve r0 be optimized away if r0 turns out to be
8203                dead.  */
8204             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8205             emit_move_insn (r0, tmp);
8206             break;
8207           }
8208     }
8209   DONE;
8210 }")
8211
8212 (define_insn "indirect_jump_compact"
8213   [(set (pc)
8214         (match_operand:SI 0 "arith_reg_operand" "r"))]
8215   "TARGET_SH1"
8216   "jmp  @%0%#"
8217   [(set_attr "needs_delay_slot" "yes")
8218    (set_attr "type" "jump_ind")])
8219
8220 (define_expand "indirect_jump"
8221   [(set (pc)
8222         (match_operand 0 "register_operand" ""))]
8223   ""
8224   "
8225 {
8226   if (GET_MODE (operands[0]) != Pmode)
8227     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8228 }")
8229
8230 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8231 ;; which can be present in structured code from indirect jumps which can not
8232 ;; be present in structured code.  This allows -fprofile-arcs to work.
8233
8234 ;; For SH1 processors.
8235 (define_insn "casesi_jump_1"
8236   [(set (pc)
8237         (match_operand:SI 0 "register_operand" "r"))
8238    (use (label_ref (match_operand 1 "" "")))]
8239   "TARGET_SH1"
8240   "jmp  @%0%#"
8241   [(set_attr "needs_delay_slot" "yes")
8242    (set_attr "type" "jump_ind")])
8243
8244 ;; For all later processors.
8245 (define_insn "casesi_jump_2"
8246   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8247                       (label_ref (match_operand 1 "" ""))))
8248    (use (label_ref (match_operand 2 "" "")))]
8249   "TARGET_SH2
8250    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8251   "braf %0%#"
8252   [(set_attr "needs_delay_slot" "yes")
8253    (set_attr "type" "jump_ind")])
8254
8255 (define_insn "casesi_jump_media"
8256   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8257    (use (label_ref (match_operand 1 "" "")))]
8258   "TARGET_SHMEDIA"
8259   "blink        %0, r63"
8260   [(set_attr "type" "jump_media")])
8261
8262 ;; Call subroutine returning any type.
8263 ;; ??? This probably doesn't work.
8264
8265 (define_expand "untyped_call"
8266   [(parallel [(call (match_operand 0 "" "")
8267                     (const_int 0))
8268               (match_operand 1 "" "")
8269               (match_operand 2 "" "")])]
8270   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8271   "
8272 {
8273   int i;
8274
8275   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8276
8277   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8278     {
8279       rtx set = XVECEXP (operands[2], 0, i);
8280       emit_move_insn (SET_DEST (set), SET_SRC (set));
8281     }
8282
8283   /* The optimizer does not know that the call sets the function value
8284      registers we stored in the result block.  We avoid problems by
8285      claiming that all hard registers are used and clobbered at this
8286      point.  */
8287   emit_insn (gen_blockage ());
8288
8289   DONE;
8290 }")
8291 \f
8292 ;; ------------------------------------------------------------------------
8293 ;; Misc insns
8294 ;; ------------------------------------------------------------------------
8295
8296 (define_insn "dect"
8297   [(set (reg:SI T_REG)
8298         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8299    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8300   "TARGET_SH2"
8301   "dt   %0"
8302   [(set_attr "type" "arith")])
8303
8304 (define_insn "nop"
8305   [(const_int 0)]
8306   ""
8307   "nop")
8308
8309 ;; Load address of a label. This is only generated by the casesi expand,
8310 ;; and by machine_dependent_reorg (fixing up fp moves).
8311 ;; This must use unspec, because this only works for labels that are
8312 ;; within range,
8313
8314 (define_insn "mova"
8315   [(set (reg:SI R0_REG)
8316         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8317   "TARGET_SH1"
8318   "mova %O0,r0"
8319   [(set_attr "in_delay_slot" "no")
8320    (set_attr "type" "arith")])
8321
8322 ;; machine_dependent_reorg will make this a `mova'.
8323 (define_insn "mova_const"
8324   [(set (reg:SI R0_REG)
8325         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8326   "TARGET_SH1"
8327   "#"
8328   [(set_attr "in_delay_slot" "no")
8329    (set_attr "type" "arith")])
8330
8331 (define_expand "GOTaddr2picreg"
8332   [(set (reg:SI R0_REG)
8333         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8334                    UNSPEC_MOVA))
8335    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8336    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8337   "" "
8338 {
8339   if (TARGET_VXWORKS_RTP)
8340     {
8341       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8342       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8343       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8344       DONE;
8345     }
8346
8347   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8348   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8349
8350   if (TARGET_SHMEDIA)
8351     {
8352       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8353       rtx pic = operands[0];
8354       rtx lab = PATTERN (gen_call_site ());
8355       rtx insn, equiv;
8356
8357       equiv = operands[1];
8358       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8359                                     UNSPEC_PCREL_SYMOFF);
8360       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8361
8362       if (Pmode == SImode)
8363         {
8364           emit_insn (gen_movsi_const (pic, operands[1]));
8365           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8366         }
8367       else
8368         {
8369           emit_insn (gen_movdi_const (pic, operands[1]));
8370           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8371         }
8372
8373       insn = emit_move_insn (operands[0], tr);
8374
8375       set_unique_reg_note (insn, REG_EQUAL, equiv);
8376
8377       DONE;
8378     }
8379 }
8380 ")
8381
8382 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8383 ;; PIC register.
8384
8385 (define_expand "vxworks_picreg"
8386   [(set (reg:SI PIC_REG)
8387         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8388    (set (reg:SI R0_REG)
8389         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8390    (set (reg:SI PIC_REG)
8391         (mem:SI (reg:SI PIC_REG)))
8392    (set (reg:SI PIC_REG)
8393         (mem:SI (plus:SI (reg:SI PIC_REG)
8394                          (reg:SI R0_REG))))]
8395   "TARGET_VXWORKS_RTP")
8396
8397 (define_insn "*ptb"
8398   [(set (match_operand 0 "target_reg_operand" "=b")
8399         (const (unspec [(match_operand 1 "" "Csy")]
8400                              UNSPEC_DATALABEL)))]
8401   "TARGET_SHMEDIA && flag_pic
8402    && satisfies_constraint_Csy (operands[1])"
8403   "ptb/u        datalabel %1, %0"
8404   [(set_attr "type" "ptabs_media")
8405    (set_attr "length" "*")])
8406
8407 (define_insn "ptrel_si"
8408   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8409         (plus:SI (match_operand:SI 1 "register_operand" "r")
8410               (pc)))
8411    (match_operand:SI 2 "" "")]
8412   "TARGET_SHMEDIA"
8413   "%O2: ptrel/u %1, %0"
8414   [(set_attr "type" "ptabs_media")])
8415
8416 (define_insn "ptrel_di"
8417   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8418         (plus:DI (match_operand:DI 1 "register_operand" "r")
8419               (pc)))
8420    (match_operand:DI 2 "" "")]
8421   "TARGET_SHMEDIA"
8422   "%O2: ptrel/u %1, %0"
8423   [(set_attr "type" "ptabs_media")])
8424
8425 (define_expand "builtin_setjmp_receiver"
8426   [(match_operand 0 "" "")]
8427   "flag_pic"
8428   "
8429 {
8430   emit_insn (gen_GOTaddr2picreg ());
8431   DONE;
8432 }")
8433
8434 (define_expand "call_site"
8435   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8436   "TARGET_SH1"
8437   "
8438 {
8439   static HOST_WIDE_INT i = 0;
8440   operands[0] = GEN_INT (i);
8441   i++;
8442 }")
8443
8444 (define_expand "sym_label2reg"
8445   [(set (match_operand:SI 0 "" "")
8446         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8447                               (const (plus:SI (match_operand:SI 2 "" "")
8448                                               (const_int 2)))]
8449                              UNSPEC_SYMOFF)))]
8450   "TARGET_SH1" "")
8451
8452 (define_expand "symGOT_load"
8453   [(set (match_dup 2) (match_operand 1 "" ""))
8454    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8455    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8456   ""
8457   "
8458 {
8459   rtx insn, mem;
8460
8461   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8462   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8463
8464   if (TARGET_SHMEDIA)
8465     {
8466       rtx reg = operands[2];
8467
8468       if (Pmode == DImode)
8469         {      
8470           if (flag_pic > 1)
8471             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8472           else
8473             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8474         }
8475       else
8476         {
8477           if (flag_pic > 1)
8478             emit_insn (gen_movsi_const (reg, operands[1]));
8479           else
8480             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8481         }
8482     }
8483   else
8484     emit_move_insn (operands[2], operands[1]);
8485
8486   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8487                                              operands[2],
8488                                              gen_rtx_REG (Pmode, PIC_REG)));
8489
8490   /* When stack protector inserts codes after the result is set to
8491      R0, @(rX, r12) will cause a spill failure for R0.  Don't schedule
8492      insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8493      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8494      matter because this is a rare situation.  */
8495   if (!TARGET_SHMEDIA
8496       && flag_stack_protect
8497       && GET_CODE (operands[1]) == CONST
8498       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8499       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8500       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8501                  \"__stack_chk_guard\") == 0)
8502     emit_insn (gen_blockage ());
8503
8504   /* N.B. This is not constant for a GOTPLT relocation.  */
8505   mem = gen_rtx_MEM (Pmode, operands[3]);
8506   MEM_NOTRAP_P (mem) = 1;
8507   /* ??? Should we have a special alias set for the GOT?  */
8508   insn = emit_move_insn (operands[0], mem);
8509
8510   DONE;
8511 }")
8512
8513 (define_expand "sym2GOT"
8514   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8515   ""
8516   "")
8517
8518 (define_expand "symGOT2reg"
8519   [(match_operand 0 "" "") (match_operand 1 "" "")]
8520   ""
8521   "
8522 {
8523   rtx gotsym, insn;
8524
8525   gotsym = gen_sym2GOT (operands[1]);
8526   PUT_MODE (gotsym, Pmode);
8527   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8528
8529   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8530
8531   DONE;
8532 }")
8533
8534 (define_expand "symGOTPLT2reg"
8535   [(match_operand 0 "" "") (match_operand 1 "" "")]
8536   ""
8537   "
8538 {
8539   rtx pltsym = gen_rtx_CONST (Pmode,
8540                               gen_rtx_UNSPEC (Pmode,
8541                                               gen_rtvec (1, operands[1]),
8542                                               UNSPEC_GOTPLT));
8543   emit_insn (gen_symGOT_load (operands[0], pltsym));
8544   DONE;
8545 }")
8546
8547 (define_expand "sym2GOTOFF"
8548   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8549   ""
8550   "")
8551
8552 (define_expand "symGOTOFF2reg"
8553   [(match_operand 0 "" "") (match_operand 1 "" "")]
8554   ""
8555   "
8556 {
8557   rtx gotoffsym, insn;
8558   rtx t = (!can_create_pseudo_p ()
8559            ? operands[0]
8560            : gen_reg_rtx (GET_MODE (operands[0])));
8561
8562   gotoffsym = gen_sym2GOTOFF (operands[1]);
8563   PUT_MODE (gotoffsym, Pmode);
8564   emit_move_insn (t, gotoffsym);
8565   insn = emit_move_insn (operands[0],
8566                          gen_rtx_PLUS (Pmode, t,
8567                                        gen_rtx_REG (Pmode, PIC_REG)));
8568
8569   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8570
8571   DONE;
8572 }")
8573
8574 (define_expand "symPLT_label2reg"
8575   [(set (match_operand:SI 0 "" "")
8576         (const:SI
8577          (unspec:SI
8578           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8579            (const:SI (plus:SI (match_operand:SI 2 "" "")
8580                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8581    ;; Even though the PIC register is not really used by the call
8582    ;; sequence in which this is expanded, the PLT code assumes the PIC
8583    ;; register is set, so we must not skip its initialization.  Since
8584    ;; we only use this expand as part of calling sequences, and never
8585    ;; to take the address of a function, this is the best point to
8586    ;; insert the (use).  Using the PLT to take the address of a
8587    ;; function would be wrong, not only because the PLT entry could
8588    ;; then be called from a function that doesn't initialize the PIC
8589    ;; register to the proper GOT, but also because pointers to the
8590    ;; same function might not compare equal, should they be set by
8591    ;; different shared libraries.
8592    (use (reg:SI PIC_REG))]
8593   "TARGET_SH1"
8594   "")
8595
8596 (define_expand "sym2PIC"
8597   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8598   ""
8599   "")
8600
8601 ;; TLS code generation.
8602 ;; ??? this should be a define_insn_and_split
8603 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8604 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8605 ;; for details.
8606
8607 (define_insn "tls_global_dynamic"
8608   [(set (match_operand:SI 0 "register_operand" "=&z")
8609         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8610                                   UNSPEC_TLSGD))
8611               (const_int 0)))
8612    (use (reg:PSI FPSCR_REG))
8613    (use (reg:SI PIC_REG))
8614    (clobber (reg:SI PR_REG))
8615    (clobber (scratch:SI))]
8616   "TARGET_SH1"
8617   "*
8618 {
8619   return \"\\
8620 mov.l\\t1f,r4\\n\\
8621 \\tmova\\t2f,r0\\n\\
8622 \\tmov.l\\t2f,r1\\n\\
8623 \\tadd\\tr0,r1\\n\\
8624 \\tjsr\\t@r1\\n\\
8625 \\tadd\\tr12,r4\\n\\
8626 \\tbra\\t3f\\n\\
8627 \\tnop\\n\\
8628 \\t.align\\t2\\n\\
8629 1:\\t.long\\t%a1@TLSGD\\n\\
8630 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8631 3:\";
8632 }"
8633   [(set_attr "type" "tls_load")
8634    (set_attr "length" "26")])
8635
8636 (define_insn "tls_local_dynamic"
8637   [(set (match_operand:SI 0 "register_operand" "=&z")
8638         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8639                                   UNSPEC_TLSLDM))
8640               (const_int 0)))
8641    (use (reg:PSI FPSCR_REG))
8642    (use (reg:SI PIC_REG))
8643    (clobber (reg:SI PR_REG))
8644    (clobber (scratch:SI))]
8645   "TARGET_SH1"
8646   "*
8647 {
8648   return \"\\
8649 mov.l\\t1f,r4\\n\\
8650 \\tmova\\t2f,r0\\n\\
8651 \\tmov.l\\t2f,r1\\n\\
8652 \\tadd\\tr0,r1\\n\\
8653 \\tjsr\\t@r1\\n\\
8654 \\tadd\\tr12,r4\\n\\
8655 \\tbra\\t3f\\n\\
8656 \\tnop\\n\\
8657 \\t.align\\t2\\n\\
8658 1:\\t.long\\t%a1@TLSLDM\\n\\
8659 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8660 3:\";
8661 }"
8662   [(set_attr "type" "tls_load")
8663    (set_attr "length" "26")])
8664
8665 (define_expand "sym2DTPOFF"
8666   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8667   ""
8668   "")
8669
8670 (define_expand "symDTPOFF2reg"
8671   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8672   ""
8673   "
8674 {
8675   rtx dtpoffsym, insn;
8676   rtx t = (!can_create_pseudo_p ()
8677            ? operands[0]
8678            : gen_reg_rtx (GET_MODE (operands[0])));
8679
8680   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8681   PUT_MODE (dtpoffsym, Pmode);
8682   emit_move_insn (t, dtpoffsym);
8683   insn = emit_move_insn (operands[0],
8684                          gen_rtx_PLUS (Pmode, t, operands[2]));
8685   DONE;
8686 }")
8687
8688 (define_expand "sym2GOTTPOFF"
8689   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8690   ""
8691   "")
8692
8693 (define_insn "tls_initial_exec"
8694   [(set (match_operand:SI 0 "register_operand" "=&r")
8695         (unspec:SI [(match_operand:SI 1 "" "")]
8696                     UNSPEC_TLSIE))
8697    (use (reg:SI GBR_REG))
8698    (use (reg:SI PIC_REG))
8699    (clobber (reg:SI R0_REG))]
8700   ""
8701   "*
8702 {
8703   return \"\\
8704 mov.l\\t1f,r0\\n\\
8705 \\tstc\\tgbr,%0\\n\\
8706 \\tmov.l\\t@(r0,r12),r0\\n\\
8707 \\tbra\\t2f\\n\\
8708 \\tadd\\tr0,%0\\n\\
8709 \\t.align\\t2\\n\\
8710 1:\\t.long\\t%a1\\n\\
8711 2:\";
8712 }"
8713   [(set_attr "type" "tls_load")
8714    (set_attr "length" "16")])
8715
8716 (define_expand "sym2TPOFF"
8717   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8718   ""
8719   "")
8720
8721 (define_expand "symTPOFF2reg"
8722   [(match_operand 0 "" "") (match_operand 1 "" "")]
8723   ""
8724   "
8725 {
8726   rtx tpoffsym, insn;
8727
8728   tpoffsym = gen_sym2TPOFF (operands[1]);
8729   PUT_MODE (tpoffsym, Pmode);
8730   insn = emit_move_insn (operands[0], tpoffsym);
8731   DONE;
8732 }")
8733
8734 (define_insn "load_gbr"
8735   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8736    (use (reg:SI GBR_REG))]
8737   ""
8738   "stc  gbr,%0"
8739   [(set_attr "type" "tls_load")])
8740
8741 ;; case instruction for switch statements.
8742
8743 ;; Operand 0 is index
8744 ;; operand 1 is the minimum bound
8745 ;; operand 2 is the maximum bound - minimum bound + 1
8746 ;; operand 3 is CODE_LABEL for the table;
8747 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8748
8749 (define_expand "casesi"
8750   [(match_operand:SI 0 "arith_reg_operand" "")
8751    (match_operand:SI 1 "arith_reg_operand" "")
8752    (match_operand:SI 2 "arith_reg_operand" "")
8753    (match_operand 3 "" "") (match_operand 4 "" "")]
8754   ""
8755   "
8756 {
8757   rtx reg = gen_reg_rtx (SImode);
8758   rtx reg2 = gen_reg_rtx (SImode);
8759   if (TARGET_SHMEDIA)
8760     {
8761       rtx reg = gen_reg_rtx (DImode);
8762       rtx reg2 = gen_reg_rtx (DImode);
8763       rtx reg3 = gen_reg_rtx (Pmode);
8764       rtx reg4 = gen_reg_rtx (Pmode);
8765       rtx reg5 = gen_reg_rtx (Pmode);
8766       rtx load, test;
8767
8768       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8769       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8770       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8771
8772       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8773       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8774       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8775       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8776       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8777       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8778       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8779                                                (Pmode, operands[3])));
8780       /* Messy: can we subreg to clean this up? */
8781       if (Pmode == DImode)
8782         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8783       else
8784         load = gen_casesi_load_media (reg4,
8785                                       gen_rtx_SUBREG (DImode, reg3, 0),
8786                                       reg2, operands[3]);
8787       PUT_MODE (SET_SRC (load), Pmode);
8788       emit_insn (load);
8789       /* ??? The following add could be eliminated if we used ptrel.  */
8790       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8791       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8792       emit_barrier ();
8793       DONE;
8794     }
8795   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8796   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8797   /* If optimizing, casesi_worker depends on the mode of the instruction
8798      before label it 'uses' - operands[3].  */
8799   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8800                            reg));
8801   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8802   if (TARGET_SH2)
8803     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8804   else
8805     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8806   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8807      operands[3], but to lab.  We will fix this up in
8808      machine_dependent_reorg.  */
8809   emit_barrier ();
8810   DONE;
8811 }")
8812
8813 (define_expand "casesi_0"
8814   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8815    (set (match_dup 4) (minus:SI (match_dup 4)
8816                                 (match_operand:SI 1 "arith_operand" "")))
8817    (set (reg:SI T_REG)
8818         (gtu:SI (match_dup 4)
8819                 (match_operand:SI 2 "arith_reg_operand" "")))
8820    (set (pc)
8821         (if_then_else (ne (reg:SI T_REG)
8822                           (const_int 0))
8823                       (label_ref (match_operand 3 "" ""))
8824                       (pc)))]
8825   "TARGET_SH1"
8826   "")
8827
8828 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8829 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8830 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8831
8832 (define_insn "casesi_worker_0"
8833   [(set (match_operand:SI 0 "register_operand" "=r,r")
8834         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8835                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8836    (clobber (match_scratch:SI 3 "=X,1"))
8837    (clobber (match_scratch:SI 4 "=&z,z"))]
8838   "TARGET_SH1"
8839   "#")
8840
8841 (define_split
8842   [(set (match_operand:SI 0 "register_operand" "")
8843         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8844                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8845    (clobber (match_scratch:SI 3 ""))
8846    (clobber (match_scratch:SI 4 ""))]
8847   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8848   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8849    (parallel [(set (match_dup 0)
8850               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8851                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8852               (clobber (match_dup 3))])
8853    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8854   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8855
8856 (define_split
8857   [(set (match_operand:SI 0 "register_operand" "")
8858         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8859                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8860    (clobber (match_scratch:SI 3 ""))
8861    (clobber (match_scratch:SI 4 ""))]
8862   "TARGET_SH2 && reload_completed"
8863   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8864    (parallel [(set (match_dup 0)
8865               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8866                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8867               (clobber (match_dup 3))])]
8868   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8869
8870 (define_insn "casesi_worker_1"
8871   [(set (match_operand:SI 0 "register_operand" "=r,r")
8872         (unspec:SI [(reg:SI R0_REG)
8873                     (match_operand:SI 1 "register_operand" "0,r")
8874                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8875    (clobber (match_scratch:SI 3 "=X,1"))]
8876   "TARGET_SH1"
8877   "*
8878 {
8879   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8880
8881   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8882
8883   switch (GET_MODE (diff_vec))
8884     {
8885     case SImode:
8886       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8887     case HImode:
8888       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8889     case QImode:
8890       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8891         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8892       return \"mov.b    @(r0,%1),%0\";
8893     default:
8894       gcc_unreachable ();
8895     }
8896 }"
8897   [(set_attr "length" "4")])
8898
8899 (define_insn "casesi_worker_2"
8900   [(set (match_operand:SI 0 "register_operand" "=r,r")
8901         (unspec:SI [(reg:SI R0_REG)
8902                     (match_operand:SI 1 "register_operand" "0,r")
8903                     (label_ref (match_operand 2 "" ""))
8904                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8905    (clobber (match_operand:SI 4 "" "=X,1"))]
8906   "TARGET_SH2 && reload_completed && flag_pic"
8907   "*
8908 {
8909   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8910   const char *load;
8911
8912   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8913
8914   switch (GET_MODE (diff_vec))
8915     {
8916     case SImode:
8917       output_asm_insn (\"shll2    %1\", operands);
8918       load = \"mov.l    @(r0,%1),%0\"; break;
8919     case HImode:
8920       output_asm_insn (\"add    %1,%1\", operands);
8921       load = \"mov.w    @(r0,%1),%0\"; break;
8922     case QImode:
8923       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8924         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8925       else
8926         load = \"mov.b  @(r0,%1),%0\";
8927       break;
8928     default:
8929       gcc_unreachable ();
8930     }
8931   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8932   return load;
8933 }"
8934   [(set_attr "length" "8")])
8935
8936 (define_insn "casesi_shift_media"
8937   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8938         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8939                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8940                     UNSPEC_CASESI)))]
8941   "TARGET_SHMEDIA"
8942   "*
8943 {
8944   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8945
8946   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8947
8948   switch (GET_MODE (diff_vec))
8949     {
8950     case SImode:
8951       return \"shlli    %1, 2, %0\";
8952     case HImode:
8953       return \"shlli    %1, 1, %0\";
8954     case QImode:
8955       if (rtx_equal_p (operands[0], operands[1]))
8956         return \"\";
8957       return \"add      %1, r63, %0\";
8958     default:
8959       gcc_unreachable ();
8960     }
8961 }"
8962   [(set_attr "type" "arith_media")])
8963
8964 (define_insn "casesi_load_media"
8965   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8966         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8967                          (match_operand:DI 2 "arith_reg_operand" "r")
8968                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8969   "TARGET_SHMEDIA"
8970   "*
8971 {
8972   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8973
8974   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8975
8976   switch (GET_MODE (diff_vec))
8977     {
8978     case SImode:
8979       return \"ldx.l    %1, %2, %0\";
8980     case HImode:
8981 #if 0
8982       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8983         return \"ldx.uw %1, %2, %0\";
8984 #endif
8985       return \"ldx.w    %1, %2, %0\";
8986     case QImode:
8987       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8988         return \"ldx.ub %1, %2, %0\";
8989       return \"ldx.b    %1, %2, %0\";
8990     default:
8991       gcc_unreachable ();
8992     }
8993 }"
8994   [(set_attr "type" "load_media")])
8995
8996 (define_expand "return"
8997   [(return)]
8998   "reload_completed && ! sh_need_epilogue ()"
8999   "
9000 {
9001   if (TARGET_SHMEDIA)
9002     {
9003       emit_jump_insn (gen_return_media ());
9004       DONE;
9005     }
9006
9007   if (TARGET_SHCOMPACT
9008       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9009     {
9010       emit_jump_insn (gen_shcompact_return_tramp ());
9011       DONE;
9012     }
9013 }")
9014
9015 (define_insn "*return_i"
9016   [(return)]
9017   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9018                     && (crtl->args.info.call_cookie
9019                         & CALL_COOKIE_RET_TRAMP (1)))
9020    && reload_completed
9021    && lookup_attribute (\"trap_exit\",
9022                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9023   "*
9024   {
9025     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9026                         && !current_function_interrupt)
9027        return \"rts/n\";
9028     else
9029        return \"%@      %#\";
9030   }"
9031   [(set_attr "type" "return")
9032    (set_attr "needs_delay_slot" "yes")])
9033
9034 ;; trapa has no delay slot.
9035 (define_insn "*return_trapa"
9036   [(return)]
9037   "TARGET_SH1 && !TARGET_SHCOMPACT
9038    && reload_completed"
9039   "%@"
9040   [(set_attr "type" "return")])
9041
9042 (define_expand "shcompact_return_tramp"
9043   [(return)]
9044   "TARGET_SHCOMPACT
9045    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9046   "
9047 {
9048   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9049
9050   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9051   emit_jump_insn (gen_shcompact_return_tramp_i ());
9052   DONE;
9053 }")
9054
9055 (define_insn "shcompact_return_tramp_i"
9056   [(parallel [(return) (use (reg:SI R0_REG))])]
9057   "TARGET_SHCOMPACT
9058    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9059   "jmp  @r0%#"
9060   [(set_attr "type" "jump_ind")
9061    (set_attr "needs_delay_slot" "yes")])
9062
9063 (define_insn "return_media_i"
9064   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9065   "TARGET_SHMEDIA && reload_completed"
9066   "blink        %0, r63"
9067   [(set_attr "type" "jump_media")])
9068
9069 (define_insn "return_media_rte"
9070   [(return)]
9071   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9072   "rte"
9073   [(set_attr "type" "jump_media")])
9074
9075 (define_expand "return_media"
9076   [(return)]
9077   "TARGET_SHMEDIA && reload_completed"
9078   "
9079 {
9080   int tr_regno = sh_media_register_for_return ();
9081   rtx tr;
9082
9083   if (current_function_interrupt)
9084     {
9085       emit_jump_insn (gen_return_media_rte ());
9086       DONE;
9087     }
9088   if (tr_regno < 0)
9089     {
9090       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9091
9092       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9093       tr_regno = TR0_REG;
9094       tr = gen_rtx_REG (Pmode, tr_regno);
9095       emit_move_insn (tr, r18);
9096     }
9097   else
9098     tr = gen_rtx_REG (Pmode, tr_regno);
9099
9100   emit_jump_insn (gen_return_media_i (tr));
9101   DONE;
9102 }")
9103
9104 (define_insn "shcompact_preserve_incoming_args"
9105   [(set (match_operand:SI 0 "register_operand" "+r")
9106         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9107   "TARGET_SHCOMPACT"
9108   ""
9109   [(set_attr "length" "0")])
9110
9111 (define_insn "shcompact_incoming_args"
9112   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9113    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9114    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9115    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9116    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9117    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9118    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9119    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9120    (set (mem:BLK (reg:SI MACL_REG))
9121         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9122    (use (reg:SI R0_REG))
9123    (clobber (reg:SI R0_REG))
9124    (clobber (reg:SI MACL_REG))
9125    (clobber (reg:SI MACH_REG))
9126    (clobber (reg:SI PR_REG))]
9127   "TARGET_SHCOMPACT"
9128   "jsr  @r0%#"
9129   [(set_attr "needs_delay_slot" "yes")])
9130
9131 (define_insn "shmedia_save_restore_regs_compact"
9132   [(set (reg:SI SP_REG)
9133         (plus:SI (reg:SI SP_REG)
9134                  (match_operand:SI 0 "immediate_operand" "i")))
9135    (use (reg:SI R0_REG))
9136    (clobber (reg:SI PR_REG))]
9137   "TARGET_SHCOMPACT
9138    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9139        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9140   "jsr @r0%#"
9141   [(set_attr "needs_delay_slot" "yes")])
9142
9143 (define_expand "prologue"
9144   [(const_int 0)]
9145   ""
9146   "sh_expand_prologue (); DONE;")
9147
9148 (define_expand "epilogue"
9149   [(return)]
9150   ""
9151   "
9152 {
9153   sh_expand_epilogue (0);
9154   emit_jump_insn (gen_return ());
9155   DONE;
9156 }")
9157
9158 (define_expand "eh_return"
9159   [(use (match_operand 0 "register_operand" ""))]
9160   ""
9161 {
9162   rtx ra = operands[0];
9163
9164   if (TARGET_SHMEDIA64)
9165     emit_insn (gen_eh_set_ra_di (ra));
9166   else
9167     emit_insn (gen_eh_set_ra_si (ra));
9168
9169   DONE;
9170 })
9171
9172 ;; Clobber the return address on the stack.  We can't expand this
9173 ;; until we know where it will be put in the stack frame.
9174
9175 (define_insn "eh_set_ra_si"
9176   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9177       UNSPECV_EH_RETURN)
9178    (clobber (match_scratch:SI 1 "=&r"))]
9179   "! TARGET_SHMEDIA64"
9180   "#")
9181
9182 (define_insn "eh_set_ra_di"
9183   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9184       UNSPECV_EH_RETURN)
9185    (clobber (match_scratch:DI 1 "=&r"))]
9186   "TARGET_SHMEDIA64"
9187   "#")
9188
9189 (define_split
9190   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9191       UNSPECV_EH_RETURN)
9192    (clobber (match_scratch 1 ""))]
9193   "reload_completed"
9194   [(const_int 0)]
9195   "
9196 {
9197   sh_set_return_address (operands[0], operands[1]);
9198   DONE;
9199 }")
9200
9201 (define_insn "blockage"
9202   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9203   ""
9204   ""
9205   [(set_attr "length" "0")])
9206 \f
9207 ;; ------------------------------------------------------------------------
9208 ;; Scc instructions
9209 ;; ------------------------------------------------------------------------
9210
9211 (define_insn "movt"
9212   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9213         (eq:SI (reg:SI T_REG) (const_int 1)))]
9214   "TARGET_SH1"
9215   "movt %0"
9216   [(set_attr "type" "arith")])
9217
9218 (define_expand "cstore4_media"
9219   [(set (match_operand:SI 0 "register_operand" "=r")
9220         (match_operator:SI 1 "sh_float_comparison_operator"
9221          [(match_operand 2 "logical_operand" "")
9222           (match_operand 3 "cmp_operand" "")]))]
9223   "TARGET_SHMEDIA"
9224   "
9225 {
9226   enum machine_mode mode = GET_MODE (operands[2]);
9227   enum rtx_code code = GET_CODE (operands[1]);
9228   bool invert, swap;
9229   if (mode == VOIDmode)
9230     mode = GET_MODE (operands[3]);
9231   if (operands[2] == const0_rtx)
9232     {
9233       if (code == EQ || code == NE)
9234         operands[2] = operands[3], operands[3] = const0_rtx;
9235     }
9236   else
9237     operands[2] = force_reg (mode, operands[2]);
9238   if (operands[3] != const0_rtx)
9239     operands[3] = force_reg (mode, operands[3]);
9240
9241   switch (code)
9242     {
9243     case GEU:
9244     case GE:
9245       swap = invert = !FLOAT_MODE_P (mode);
9246       break;
9247
9248     case LEU:
9249     case LE:
9250       swap = FLOAT_MODE_P (mode), invert = !swap;
9251       break;
9252
9253     case LTU:
9254     case LT:
9255       swap = true, invert = false;
9256       break;
9257
9258     case GTU:
9259     case GT:
9260     case EQ:
9261     case UNORDERED:
9262       swap = invert = false;
9263       break;
9264
9265     case NE:
9266       swap = invert = true;
9267       break;
9268
9269     default:
9270       gcc_unreachable ();
9271   }
9272
9273   if (swap)
9274     {
9275       rtx tem = operands[2];
9276       operands[2] = operands[3];
9277       operands[3] = tem;
9278       code = swap_condition (code);
9279     }
9280
9281   if (invert)
9282     {
9283       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9284       code = reverse_condition (code);
9285       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9286       emit_insn (gen_cstore4_media (tem, operands[1],
9287                                     operands[2], operands[3]));
9288       code = EQ;
9289       operands[2] = tem;
9290       operands[3] = const0_rtx;
9291     }
9292
9293   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9294 }")
9295
9296 (define_expand "cstoresi4"
9297   [(set (match_operand:SI 0 "register_operand" "=r")
9298         (match_operator:SI 1 "comparison_operator"
9299          [(match_operand:SI 2 "cmpsi_operand" "")
9300           (match_operand:SI 3 "arith_operand" "")]))]
9301   "TARGET_SH1 || TARGET_SHMEDIA"
9302   "if (TARGET_SHMEDIA)
9303     {
9304       emit_insn (gen_cstore4_media (operands[0], operands[1],
9305                                     operands[2], operands[3]));
9306       DONE;
9307     }
9308
9309    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9310        && sh_expand_t_scc (operands))
9311      DONE;
9312
9313    if (! currently_expanding_to_rtl)
9314      FAIL;
9315    
9316    sh_emit_compare_and_set (operands, SImode);
9317    DONE;
9318 ")
9319
9320 (define_expand "cstoredi4"
9321   [(set (match_operand:SI 0 "register_operand" "=r")
9322         (match_operator:SI 1 "comparison_operator"
9323          [(match_operand:DI 2 "arith_operand" "")
9324           (match_operand:DI 3 "arith_operand" "")]))]
9325   "TARGET_SH2 || TARGET_SHMEDIA"
9326   "if (TARGET_SHMEDIA)
9327     {
9328       emit_insn (gen_cstore4_media (operands[0], operands[1],
9329                                     operands[2], operands[3]));
9330       DONE;
9331     }
9332
9333    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9334        && sh_expand_t_scc (operands))
9335      DONE;
9336
9337    if (! currently_expanding_to_rtl)
9338      FAIL;
9339    
9340    sh_emit_compare_and_set (operands, DImode);
9341    DONE;
9342 ")
9343
9344
9345
9346 ;; sne moves the complement of the T reg to DEST like this:
9347 ;;      cmp/eq ...
9348 ;;      mov    #-1,temp
9349 ;;      negc   temp,dest
9350 ;;   This is better than xoring compare result with 1 because it does
9351 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9352 ;;   loop.
9353
9354 (define_expand "movnegt"
9355   [(set (match_dup 1) (const_int -1))
9356    (parallel [(set (match_operand:SI 0 "" "")
9357                    (neg:SI (plus:SI (reg:SI T_REG)
9358                                     (match_dup 1))))
9359               (set (reg:SI T_REG)
9360                    (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9361                           (const_int 0)))])]
9362   ""
9363   "
9364 {
9365   operands[1] = gen_reg_rtx (SImode);
9366 }")
9367
9368
9369 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9370 ;; This prevents a regression that occurred when we switched from xor to
9371 ;; mov/neg for sne.
9372
9373 (define_split
9374   [(set (match_operand:SI 0 "arith_reg_dest" "")
9375         (plus:SI (reg:SI T_REG)
9376                  (const_int -1)))]
9377   "TARGET_SH1"
9378   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9379    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9380   "")
9381
9382 (define_expand "cstoresf4"
9383   [(set (match_operand:SI 0 "register_operand" "=r")
9384         (match_operator:SI 1 "sh_float_comparison_operator"
9385          [(match_operand:SF 2 "arith_operand" "")
9386           (match_operand:SF 3 "arith_operand" "")]))]
9387   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9388   "if (TARGET_SHMEDIA)
9389      {
9390        emit_insn (gen_cstore4_media (operands[0], operands[1],
9391                                      operands[2], operands[3]));
9392        DONE;
9393      }
9394
9395    if (! currently_expanding_to_rtl)
9396      FAIL;
9397    
9398    sh_emit_compare_and_set (operands, SFmode);
9399    DONE;
9400 ")
9401
9402 (define_expand "cstoredf4"
9403   [(set (match_operand:SI 0 "register_operand" "=r")
9404         (match_operator:SI 1 "sh_float_comparison_operator"
9405          [(match_operand:DF 2 "arith_operand" "")
9406           (match_operand:DF 3 "arith_operand" "")]))]
9407   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9408   "if (TARGET_SHMEDIA)
9409      {
9410        emit_insn (gen_cstore4_media (operands[0], operands[1],
9411                                      operands[2], operands[3]));
9412        DONE;
9413      }
9414
9415     if (! currently_expanding_to_rtl)
9416       FAIL;
9417    
9418    sh_emit_compare_and_set (operands, DFmode);
9419    DONE;
9420 ")
9421
9422
9423 ;; -------------------------------------------------------------------------
9424 ;; Instructions to cope with inline literal tables
9425 ;; -------------------------------------------------------------------------
9426
9427 ; 2 byte integer in line
9428
9429 (define_insn "consttable_2"
9430  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9431                     (match_operand 1 "" "")]
9432                    UNSPECV_CONST2)]
9433  ""
9434  "*
9435 {
9436   if (operands[1] != const0_rtx)
9437     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9438   return \"\";
9439 }"
9440  [(set_attr "length" "2")
9441  (set_attr "in_delay_slot" "no")])
9442
9443 ; 4 byte integer in line
9444
9445 (define_insn "consttable_4"
9446  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9447                     (match_operand 1 "" "")]
9448                    UNSPECV_CONST4)]
9449  ""
9450  "*
9451 {
9452   if (operands[1] != const0_rtx)
9453     {
9454       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9455       mark_symbol_refs_as_used (operands[0]);
9456     }
9457   return \"\";
9458 }"
9459  [(set_attr "length" "4")
9460   (set_attr "in_delay_slot" "no")])
9461
9462 ; 8 byte integer in line
9463
9464 (define_insn "consttable_8"
9465  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9466                     (match_operand 1 "" "")]
9467                    UNSPECV_CONST8)]
9468  ""
9469  "*
9470 {
9471   if (operands[1] != const0_rtx)
9472     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9473   return \"\";
9474 }"
9475  [(set_attr "length" "8")
9476   (set_attr "in_delay_slot" "no")])
9477
9478 ; 4 byte floating point
9479
9480 (define_insn "consttable_sf"
9481  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9482                     (match_operand 1 "" "")]
9483                    UNSPECV_CONST4)]
9484  ""
9485  "*
9486 {
9487   if (operands[1] != const0_rtx)
9488     {
9489       REAL_VALUE_TYPE d;
9490       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9491       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9492     }
9493   return \"\";
9494 }"
9495  [(set_attr "length" "4")
9496   (set_attr "in_delay_slot" "no")])
9497
9498 ; 8 byte floating point
9499
9500 (define_insn "consttable_df"
9501  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9502                     (match_operand 1 "" "")]
9503                    UNSPECV_CONST8)]
9504  ""
9505  "*
9506 {
9507   if (operands[1] != const0_rtx)
9508     {
9509       REAL_VALUE_TYPE d;
9510       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9511       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9512     }
9513   return \"\";
9514 }"
9515  [(set_attr "length" "8")
9516   (set_attr "in_delay_slot" "no")])
9517
9518 ;; Alignment is needed for some constant tables; it may also be added for
9519 ;; Instructions at the start of loops, or after unconditional branches.
9520 ;; ??? We would get more accurate lengths if we did instruction
9521 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9522 ;; here is too conservative.
9523
9524 ; align to a two byte boundary
9525
9526 (define_expand "align_2"
9527  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9528  ""
9529  "")
9530
9531 ; align to a four byte boundary
9532 ;; align_4 and align_log are instructions for the starts of loops, or
9533 ;; after unconditional branches, which may take up extra room.
9534
9535 (define_expand "align_4"
9536  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9537  ""
9538  "")
9539
9540 ; align to a cache line boundary
9541
9542 (define_insn "align_log"
9543  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9544  ""
9545  ""
9546  [(set_attr "length" "0")
9547   (set_attr "in_delay_slot" "no")])
9548
9549 ; emitted at the end of the literal table, used to emit the
9550 ; 32bit branch labels if needed.
9551
9552 (define_insn "consttable_end"
9553   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9554   ""
9555   "* return output_jump_label_table ();"
9556   [(set_attr "in_delay_slot" "no")])
9557
9558 ; emitted at the end of the window in the literal table.
9559
9560 (define_insn "consttable_window_end"
9561   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9562   ""
9563   ""
9564   [(set_attr "length" "0")
9565    (set_attr "in_delay_slot" "no")])
9566
9567 ;; -------------------------------------------------------------------------
9568 ;; Misc
9569 ;; -------------------------------------------------------------------------
9570
9571 ;; String/block move insn.
9572
9573 (define_expand "movmemsi"
9574   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9575                    (mem:BLK (match_operand:BLK 1 "" "")))
9576               (use (match_operand:SI 2 "nonmemory_operand" ""))
9577               (use (match_operand:SI 3 "immediate_operand" ""))
9578               (clobber (reg:SI PR_REG))
9579               (clobber (reg:SI R4_REG))
9580               (clobber (reg:SI R5_REG))
9581               (clobber (reg:SI R0_REG))])]
9582   "TARGET_SH1 && ! TARGET_SH5"
9583   "
9584 {
9585   if(expand_block_move (operands))
9586      DONE;
9587   else FAIL;
9588 }")
9589
9590 (define_insn "block_move_real"
9591   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9592                    (mem:BLK (reg:SI R5_REG)))
9593               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9594               (clobber (reg:SI PR_REG))
9595               (clobber (reg:SI R0_REG))])]
9596   "TARGET_SH1 && ! TARGET_HARD_SH4"
9597   "jsr  @%0%#"
9598   [(set_attr "type" "sfunc")
9599    (set_attr "needs_delay_slot" "yes")])
9600
9601 (define_insn "block_lump_real"
9602   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9603                    (mem:BLK (reg:SI R5_REG)))
9604               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9605               (use (reg:SI R6_REG))
9606               (clobber (reg:SI PR_REG))
9607               (clobber (reg:SI T_REG))
9608               (clobber (reg:SI R4_REG))
9609               (clobber (reg:SI R5_REG))
9610               (clobber (reg:SI R6_REG))
9611               (clobber (reg:SI R0_REG))])]
9612   "TARGET_SH1 && ! TARGET_HARD_SH4"
9613   "jsr  @%0%#"
9614   [(set_attr "type" "sfunc")
9615    (set_attr "needs_delay_slot" "yes")])
9616
9617 (define_insn "block_move_real_i4"
9618   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9619                    (mem:BLK (reg:SI R5_REG)))
9620               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9621               (clobber (reg:SI PR_REG))
9622               (clobber (reg:SI R0_REG))
9623               (clobber (reg:SI R1_REG))
9624               (clobber (reg:SI R2_REG))])]
9625   "TARGET_HARD_SH4"
9626   "jsr  @%0%#"
9627   [(set_attr "type" "sfunc")
9628    (set_attr "needs_delay_slot" "yes")])
9629
9630 (define_insn "block_lump_real_i4"
9631   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9632                    (mem:BLK (reg:SI R5_REG)))
9633               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9634               (use (reg:SI R6_REG))
9635               (clobber (reg:SI PR_REG))
9636               (clobber (reg:SI T_REG))
9637               (clobber (reg:SI R4_REG))
9638               (clobber (reg:SI R5_REG))
9639               (clobber (reg:SI R6_REG))
9640               (clobber (reg:SI R0_REG))
9641               (clobber (reg:SI R1_REG))
9642               (clobber (reg:SI R2_REG))
9643               (clobber (reg:SI R3_REG))])]
9644   "TARGET_HARD_SH4"
9645   "jsr  @%0%#"
9646   [(set_attr "type" "sfunc")
9647    (set_attr "needs_delay_slot" "yes")])
9648 \f
9649 ;; -------------------------------------------------------------------------
9650 ;; Floating point instructions.
9651 ;; -------------------------------------------------------------------------
9652
9653 ;; ??? All patterns should have a type attribute.
9654
9655 (define_expand "movpsi"
9656   [(set (match_operand:PSI 0 "register_operand" "")
9657         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9658   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9659   "")
9660
9661 ;; The c / m alternative is a fake to guide reload to load directly into
9662 ;; fpscr, since reload doesn't know how to use post-increment.
9663 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9664 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9665 ;; predicate after reload.
9666 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9667 ;; like a mac -> gpr move.
9668 (define_insn "fpu_switch"
9669   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9670         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9671   "TARGET_SH2E
9672    && (! reload_completed
9673        || true_regnum (operands[0]) != FPSCR_REG
9674        || !MEM_P (operands[1])
9675        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9676   "@
9677         ! precision stays the same
9678         lds.l   %1,fpscr
9679         mov.l   %1,%0
9680         #
9681         lds     %1,fpscr
9682         mov     %1,%0
9683         mov.l   %1,%0
9684         sts     fpscr,%0
9685         sts.l   fpscr,%0"
9686   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9687    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9688
9689 (define_peephole2
9690   [(set (reg:PSI FPSCR_REG)
9691         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9692   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9693   [(const_int 0)]
9694 {
9695   rtx fpscr, mem, new_insn;
9696
9697   fpscr = SET_DEST (PATTERN (curr_insn));
9698   mem = SET_SRC (PATTERN (curr_insn));
9699   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9700
9701   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9702   add_reg_note (new_insn, REG_INC, operands[0]);
9703   DONE;
9704 })
9705
9706 (define_split
9707   [(set (reg:PSI FPSCR_REG)
9708         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9709   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9710    && (flag_peephole2 ? epilogue_completed : reload_completed)"
9711   [(const_int 0)]
9712 {
9713   rtx fpscr, mem, new_insn;
9714
9715   fpscr = SET_DEST (PATTERN (curr_insn));
9716   mem = SET_SRC (PATTERN (curr_insn));
9717   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9718
9719   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9720   add_reg_note (new_insn, REG_INC, operands[0]);
9721
9722   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9723     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9724   DONE;
9725 })
9726
9727 ;; ??? This uses the fp unit, but has no type indicating that.
9728 ;; If we did that, this would either give a bogus latency or introduce
9729 ;; a bogus FIFO constraint.
9730 ;; Since this insn is currently only used for prologues/epilogues,
9731 ;; it is probably best to claim no function unit, which matches the
9732 ;; current setting.
9733 (define_insn "toggle_sz"
9734   [(set (reg:PSI FPSCR_REG)
9735         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9736   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9737   "fschg"
9738   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9739
9740 ;; There's no way we can use it today, since optimize mode switching
9741 ;; doesn't enable us to know from which mode we're switching to the
9742 ;; mode it requests, to tell whether we can use a relative mode switch
9743 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9744 ;; memory).
9745 (define_insn "toggle_pr"
9746   [(set (reg:PSI FPSCR_REG)
9747         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9748   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9749   "fpchg"
9750   [(set_attr "type" "fpscr_toggle")])
9751
9752 (define_expand "addsf3"
9753   [(set (match_operand:SF 0 "arith_reg_operand" "")
9754         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9755                  (match_operand:SF 2 "arith_reg_operand" "")))]
9756   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9757   "
9758 {
9759   if (TARGET_SH2E)
9760     {
9761       expand_sf_binop (&gen_addsf3_i, operands);
9762       DONE;
9763     }
9764 }")
9765
9766 (define_insn "*addsf3_media"
9767   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9768         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9769                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9770   "TARGET_SHMEDIA_FPU"
9771   "fadd.s       %1, %2, %0"
9772   [(set_attr "type" "fparith_media")])
9773
9774 (define_insn_and_split "unary_sf_op"
9775   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9776         (vec_select:V2SF
9777          (vec_concat:V2SF
9778           (vec_select:SF
9779            (match_dup 0)
9780            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9781           (match_operator:SF 2 "unary_float_operator"
9782             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9783                             (parallel [(match_operand 4
9784                                         "const_int_operand" "n")]))]))
9785          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9786   "TARGET_SHMEDIA_FPU"
9787   "#"
9788   "TARGET_SHMEDIA_FPU && reload_completed"
9789   [(set (match_dup 5) (match_dup 6))]
9790   "
9791 {
9792   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9793   rtx op1 = gen_rtx_REG (SFmode,
9794                          (true_regnum (operands[1])
9795                           + (INTVAL (operands[4]) ^ endian)));
9796
9797   operands[7] = gen_rtx_REG (SFmode,
9798                              (true_regnum (operands[0])
9799                               + (INTVAL (operands[3]) ^ endian)));
9800   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9801 }"
9802   [(set_attr "type" "fparith_media")])
9803
9804 (define_insn_and_split "binary_sf_op0"
9805   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9806         (vec_concat:V2SF
9807           (match_operator:SF 3 "binary_float_operator"
9808             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9809                             (parallel [(const_int 0)]))
9810              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9811                             (parallel [(const_int 0)]))])
9812           (vec_select:SF
9813            (match_dup 0)
9814            (parallel [(const_int 1)]))))]
9815   "TARGET_SHMEDIA_FPU"
9816   "#"
9817   "&& reload_completed"
9818   [(set (match_dup 4) (match_dup 5))]
9819   "
9820 {
9821   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9822   rtx op1 = gen_rtx_REG (SFmode,
9823                          true_regnum (operands[1]) + endian);
9824   rtx op2 = gen_rtx_REG (SFmode,
9825                          true_regnum (operands[2]) + endian);
9826
9827   operands[4] = gen_rtx_REG (SFmode,
9828                              true_regnum (operands[0]) + endian);
9829   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9830 }"
9831   [(set_attr "type" "fparith_media")])
9832
9833 (define_insn_and_split "binary_sf_op1"
9834   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9835         (vec_concat:V2SF
9836           (vec_select:SF
9837            (match_dup 0)
9838            (parallel [(const_int 0)]))
9839           (match_operator:SF 3 "binary_float_operator"
9840             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9841                             (parallel [(const_int 1)]))
9842              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9843                             (parallel [(const_int 1)]))])))]
9844   "TARGET_SHMEDIA_FPU"
9845   "#"
9846   "&& reload_completed"
9847   [(set (match_dup 4) (match_dup 5))]
9848   "
9849 {
9850   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9851   rtx op1 = gen_rtx_REG (SFmode,
9852                          true_regnum (operands[1]) + (1 ^ endian));
9853   rtx op2 = gen_rtx_REG (SFmode,
9854                          true_regnum (operands[2]) + (1 ^ endian));
9855
9856   operands[4] = gen_rtx_REG (SFmode,
9857                              true_regnum (operands[0]) + (1 ^ endian));
9858   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9859 }"
9860   [(set_attr "type" "fparith_media")])
9861
9862 (define_insn "addsf3_i"
9863   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9864         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9865                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9866    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9867   "TARGET_SH2E"
9868   "fadd %2,%0"
9869   [(set_attr "type" "fp")
9870    (set_attr "fp_mode" "single")])
9871
9872 (define_expand "subsf3"
9873   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9874         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9875                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9876   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9877   "
9878 {
9879   if (TARGET_SH2E)
9880     {
9881       expand_sf_binop (&gen_subsf3_i, operands);
9882       DONE;
9883     }
9884 }")
9885
9886 (define_insn "*subsf3_media"
9887   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9888         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9889                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9890   "TARGET_SHMEDIA_FPU"
9891   "fsub.s       %1, %2, %0"
9892   [(set_attr "type" "fparith_media")])
9893
9894 (define_insn "subsf3_i"
9895   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9896         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9897                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9898    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9899   "TARGET_SH2E"
9900   "fsub %2,%0"
9901   [(set_attr "type" "fp")
9902    (set_attr "fp_mode" "single")])
9903
9904 (define_expand "mulsf3"
9905   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9906         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9907                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9908   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9909   "")
9910
9911 (define_insn "*mulsf3_media"
9912   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9913         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9914                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9915   "TARGET_SHMEDIA_FPU"
9916   "fmul.s       %1, %2, %0"
9917   [(set_attr "type" "fparith_media")])
9918
9919 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9920 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
9921 ;; we start out with a mulsf pattern that does not depend on fpscr.
9922 ;; This is split after combine to introduce the dependency, in order to
9923 ;; get mode switching and scheduling right.
9924 (define_insn_and_split "mulsf3_ie"
9925   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9926         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9927                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9928   "TARGET_SH2E"
9929   "fmul %2,%0"
9930   "TARGET_SH4 || TARGET_SH2A_SINGLE"
9931   [(const_int 0)]
9932   "
9933 {
9934   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9935              get_fpscr_rtx ()));
9936   DONE;
9937 }"
9938   [(set_attr "type" "fp")])
9939
9940 (define_insn "mulsf3_i4"
9941   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9942         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9943                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9944    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9945   "TARGET_SH2E"
9946   "fmul %2,%0"
9947   [(set_attr "type" "fp")
9948    (set_attr "fp_mode" "single")])
9949
9950 (define_insn "mac_media"
9951   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9952         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9953                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9954                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
9955   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
9956   "fmac.s %1, %2, %0"
9957   [(set_attr "type" "fparith_media")])
9958
9959 (define_insn "*macsf3"
9960   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9961         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
9962                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9963                  (match_operand:SF 3 "arith_reg_operand" "0")))
9964    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
9965   "TARGET_SH2E && TARGET_FMAC"
9966   "fmac fr0,%2,%0"
9967   [(set_attr "type" "fp")
9968    (set_attr "fp_mode" "single")])
9969
9970 (define_expand "divsf3"
9971   [(set (match_operand:SF 0 "arith_reg_operand" "")
9972         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
9973                 (match_operand:SF 2 "arith_reg_operand" "")))]
9974   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9975   "
9976 {
9977   if (TARGET_SH2E)
9978     {
9979       expand_sf_binop (&gen_divsf3_i, operands);
9980       DONE;
9981     }
9982 }")
9983
9984 (define_insn "*divsf3_media"
9985   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9986         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9987                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9988   "TARGET_SHMEDIA_FPU"
9989   "fdiv.s       %1, %2, %0"
9990   [(set_attr "type" "fdiv_media")])
9991
9992 (define_insn "divsf3_i"
9993   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
9994         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
9995                  (match_operand:SF 2 "arith_reg_operand" "f")))
9996    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9997   "TARGET_SH2E"
9998   "fdiv %2,%0"
9999   [(set_attr "type" "fdiv")
10000    (set_attr "fp_mode" "single")])
10001
10002 (define_insn "floatdisf2"
10003   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10004         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10005   "TARGET_SHMEDIA_FPU"
10006   "float.qs %1, %0"
10007   [(set_attr "type" "fpconv_media")])
10008
10009 (define_expand "floatsisf2"
10010   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10011         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10012   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10013   "
10014 {
10015   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10016     {
10017       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10018       DONE;
10019     }
10020 }")
10021
10022 (define_insn "*floatsisf2_media"
10023   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10024         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10025   "TARGET_SHMEDIA_FPU"
10026   "float.ls     %1, %0"
10027   [(set_attr "type" "fpconv_media")])
10028
10029 (define_insn "floatsisf2_i4"
10030   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10031         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10032    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10033   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10034   "float        %1,%0"
10035   [(set_attr "type" "fp")
10036    (set_attr "fp_mode" "single")])
10037
10038 (define_insn "*floatsisf2_ie"
10039   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10040         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10041   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10042   "float        %1,%0"
10043   [(set_attr "type" "fp")])
10044
10045 (define_insn "fix_truncsfdi2"
10046   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10047         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10048   "TARGET_SHMEDIA_FPU"
10049   "ftrc.sq %1, %0"
10050   [(set_attr "type" "fpconv_media")])
10051
10052 (define_expand "fix_truncsfsi2"
10053   [(set (match_operand:SI 0 "fpul_operand" "=y")
10054         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10055   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10056   "
10057 {
10058   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10059     {
10060       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10061       DONE;
10062     }
10063 }")
10064
10065 (define_insn "*fix_truncsfsi2_media"
10066   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10067         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10068   "TARGET_SHMEDIA_FPU"
10069   "ftrc.sl      %1, %0"
10070   [(set_attr "type" "fpconv_media")])
10071
10072 (define_insn "fix_truncsfsi2_i4"
10073   [(set (match_operand:SI 0 "fpul_operand" "=y")
10074         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10075    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10076   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10077   "ftrc %1,%0"
10078   [(set_attr "type" "ftrc_s")
10079    (set_attr "fp_mode" "single")])
10080
10081 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10082 ;; fix_truncsfsi2_i4.
10083 ;; (define_insn "fix_truncsfsi2_i4_2"
10084 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10085 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10086 ;;   (use (reg:PSI FPSCR_REG))
10087 ;;   (clobber (reg:SI FPUL_REG))]
10088 ;;  "TARGET_SH4"
10089 ;;  "#"
10090 ;;  [(set_attr "length" "4")
10091 ;;   (set_attr "fp_mode" "single")])
10092
10093 ;;(define_split
10094 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10095 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10096 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10097 ;;   (clobber (reg:SI FPUL_REG))]
10098 ;;  "TARGET_SH4"
10099 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10100 ;;            (use (match_dup 2))])
10101 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10102
10103 (define_insn "*fixsfsi"
10104   [(set (match_operand:SI 0 "fpul_operand" "=y")
10105         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10106   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10107   "ftrc %1,%0"
10108   [(set_attr "type" "fp")])
10109
10110 (define_insn "cmpgtsf_t"
10111   [(set (reg:SI T_REG)
10112         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10113                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10114   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10115   "fcmp/gt      %1,%0"
10116   [(set_attr "type" "fp_cmp")
10117    (set_attr "fp_mode" "single")])
10118
10119 (define_insn "cmpeqsf_t"
10120   [(set (reg:SI T_REG)
10121         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10122                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10123   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10124   "fcmp/eq      %1,%0"
10125   [(set_attr "type" "fp_cmp")
10126    (set_attr "fp_mode" "single")])
10127
10128 (define_insn "ieee_ccmpeqsf_t"
10129   [(set (reg:SI T_REG)
10130         (ior:SI (reg:SI T_REG)
10131                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10132                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10133   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10134   "* return output_ieee_ccmpeq (insn, operands);"
10135   [(set_attr "length" "4")])
10136
10137
10138 (define_insn "cmpgtsf_t_i4"
10139   [(set (reg:SI T_REG)
10140         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10141                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10142    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10143   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10144   "fcmp/gt      %1,%0"
10145   [(set_attr "type" "fp_cmp")
10146    (set_attr "fp_mode" "single")])
10147
10148 (define_insn "cmpeqsf_t_i4"
10149   [(set (reg:SI T_REG)
10150         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10151                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10152    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10153   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10154   "fcmp/eq      %1,%0"
10155   [(set_attr "type" "fp_cmp")
10156    (set_attr "fp_mode" "single")])
10157
10158 (define_insn "*ieee_ccmpeqsf_t_4"
10159   [(set (reg:SI T_REG)
10160         (ior:SI (reg:SI T_REG)
10161                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10162                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10163    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10164   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10165   "* return output_ieee_ccmpeq (insn, operands);"
10166   [(set_attr "length" "4")
10167    (set_attr "fp_mode" "single")])
10168
10169 (define_insn "cmpeqsf_media"
10170   [(set (match_operand:SI 0 "register_operand" "=r")
10171         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10172                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10173   "TARGET_SHMEDIA_FPU"
10174   "fcmpeq.s     %1, %2, %0"
10175   [(set_attr "type" "fcmp_media")])
10176
10177 (define_insn "cmpgtsf_media"
10178   [(set (match_operand:SI 0 "register_operand" "=r")
10179         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10180                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10181   "TARGET_SHMEDIA_FPU"
10182   "fcmpgt.s     %1, %2, %0"
10183   [(set_attr "type" "fcmp_media")])
10184
10185 (define_insn "cmpgesf_media"
10186   [(set (match_operand:SI 0 "register_operand" "=r")
10187         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10188                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10189   "TARGET_SHMEDIA_FPU"
10190   "fcmpge.s     %1, %2, %0"
10191   [(set_attr "type" "fcmp_media")])
10192
10193 (define_insn "cmpunsf_media"
10194   [(set (match_operand:SI 0 "register_operand" "=r")
10195         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10196                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10197   "TARGET_SHMEDIA_FPU"
10198   "fcmpun.s     %1, %2, %0"
10199   [(set_attr "type" "fcmp_media")])
10200
10201 (define_expand "cbranchsf4"
10202   [(set (pc)
10203         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10204                        [(match_operand:SF 1 "arith_operand" "")
10205                         (match_operand:SF 2 "arith_operand" "")])
10206                       (match_operand 3 "" "")
10207                       (pc)))]
10208   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10209   "
10210 {
10211   if (TARGET_SHMEDIA)
10212     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10213                                           operands[3]));
10214   else
10215     sh_emit_compare_and_branch (operands, SFmode);
10216   DONE;
10217 }")
10218
10219 (define_expand "negsf2"
10220   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10221         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10222   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10223   "
10224 {
10225   if (TARGET_SH2E)
10226     {
10227       expand_sf_unop (&gen_negsf2_i, operands);
10228       DONE;
10229     }
10230 }")
10231
10232 (define_insn "*negsf2_media"
10233   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10234         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10235   "TARGET_SHMEDIA_FPU"
10236   "fneg.s       %1, %0"
10237   [(set_attr "type" "fmove_media")])
10238
10239 (define_insn "negsf2_i"
10240   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10241         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10242    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10243   "TARGET_SH2E"
10244   "fneg %0"
10245   [(set_attr "type" "fmove")
10246    (set_attr "fp_mode" "single")])
10247
10248 (define_expand "sqrtsf2"
10249   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10250         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10251   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10252   "
10253 {
10254   if (TARGET_SH3E)
10255     {
10256       expand_sf_unop (&gen_sqrtsf2_i, operands);
10257       DONE;
10258     }
10259 }")
10260
10261 (define_insn "*sqrtsf2_media"
10262   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10263         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10264   "TARGET_SHMEDIA_FPU"
10265   "fsqrt.s      %1, %0"
10266   [(set_attr "type" "fdiv_media")])
10267
10268 (define_insn "sqrtsf2_i"
10269   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10270         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10271    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10272   "TARGET_SH3E"
10273   "fsqrt        %0"
10274   [(set_attr "type" "fdiv")
10275    (set_attr "fp_mode" "single")])
10276
10277 (define_insn "rsqrtsf2"
10278   [(set (match_operand:SF 0 "register_operand" "=f")
10279         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10280                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10281    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10282   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10283    && operands[1] == CONST1_RTX (SFmode)"
10284   "fsrra        %0"
10285   [(set_attr "type" "fsrra")
10286    (set_attr "fp_mode" "single")])
10287
10288 (define_insn "fsca"
10289   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10290         (vec_concat:V2SF
10291          (unspec:SF [(mult:SF
10292                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10293                       (match_operand:SF 2 "immediate_operand" "i"))
10294                     ] UNSPEC_FSINA)
10295          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10296                     ] UNSPEC_FCOSA)))
10297    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10298   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10299    && operands[2] == sh_fsca_int2sf ()"
10300   "fsca fpul,%d0"
10301   [(set_attr "type" "fsca")
10302    (set_attr "fp_mode" "single")])
10303
10304 (define_expand "sinsf2"
10305   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10306         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10307                    UNSPEC_FSINA))]
10308   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10309   "
10310 {
10311   rtx scaled = gen_reg_rtx (SFmode);
10312   rtx truncated = gen_reg_rtx (SImode);
10313   rtx fsca = gen_reg_rtx (V2SFmode);
10314   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10315
10316   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10317   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10318   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10319                           get_fpscr_rtx ()));
10320   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10321   DONE;
10322 }")
10323
10324 (define_expand "cossf2"
10325   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10326         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10327                    UNSPEC_FCOSA))]
10328   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10329   "
10330 {
10331   rtx scaled = gen_reg_rtx (SFmode);
10332   rtx truncated = gen_reg_rtx (SImode);
10333   rtx fsca = gen_reg_rtx (V2SFmode);
10334   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10335
10336   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10337   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10338   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10339                           get_fpscr_rtx ()));
10340   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10341   DONE;
10342 }")
10343
10344 (define_expand "sindf2"
10345   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10346         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10347                    UNSPEC_FSINA))]
10348   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10349   "
10350 {
10351   rtx scaled = gen_reg_rtx (DFmode);
10352   rtx truncated = gen_reg_rtx (SImode);
10353   rtx fsca = gen_reg_rtx (V2SFmode);
10354   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10355   rtx sfresult = gen_reg_rtx (SFmode);
10356
10357   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10358   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10359   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10360                           get_fpscr_rtx ()));
10361   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10362   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10363   DONE;
10364 }")
10365
10366 (define_expand "cosdf2"
10367   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10368         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10369                    UNSPEC_FCOSA))]
10370   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10371   "
10372 {
10373   rtx scaled = gen_reg_rtx (DFmode);
10374   rtx truncated = gen_reg_rtx (SImode);
10375   rtx fsca = gen_reg_rtx (V2SFmode);
10376   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10377   rtx sfresult = gen_reg_rtx (SFmode);
10378
10379   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10380   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10381   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10382                           get_fpscr_rtx ()));
10383   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10384   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10385   DONE;
10386 }")
10387
10388 (define_expand "abssf2"
10389   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10390         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10391   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10392   "
10393 {
10394   if (TARGET_SH2E)
10395     {
10396       expand_sf_unop (&gen_abssf2_i, operands);
10397       DONE;
10398     }
10399 }")
10400
10401 (define_insn "*abssf2_media"
10402   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10403         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10404   "TARGET_SHMEDIA_FPU"
10405   "fabs.s       %1, %0"
10406   [(set_attr "type" "fmove_media")])
10407
10408 (define_insn "abssf2_i"
10409   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10410         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10411    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10412   "TARGET_SH2E"
10413   "fabs %0"
10414   [(set_attr "type" "fmove")
10415    (set_attr "fp_mode" "single")])
10416
10417 (define_expand "adddf3"
10418   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10419         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10420                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10421   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10422   "
10423 {
10424   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10425     {
10426       expand_df_binop (&gen_adddf3_i, operands);
10427       DONE;
10428     }
10429 }")
10430
10431 (define_insn "*adddf3_media"
10432   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10433         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10434                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10435   "TARGET_SHMEDIA_FPU"
10436   "fadd.d       %1, %2, %0"
10437   [(set_attr "type" "dfparith_media")])
10438
10439 (define_insn "adddf3_i"
10440   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10441         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10442                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10443    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10444   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10445   "fadd %2,%0"
10446   [(set_attr "type" "dfp_arith")
10447    (set_attr "fp_mode" "double")])
10448
10449 (define_expand "subdf3"
10450   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10451         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10452                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10453   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10454   "
10455 {
10456   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10457     {
10458       expand_df_binop (&gen_subdf3_i, operands);
10459       DONE;
10460     }
10461 }")
10462
10463 (define_insn "*subdf3_media"
10464   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10465         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10466                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10467   "TARGET_SHMEDIA_FPU"
10468   "fsub.d       %1, %2, %0"
10469   [(set_attr "type" "dfparith_media")])
10470
10471 (define_insn "subdf3_i"
10472   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10473         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10474                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10475    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10476   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10477   "fsub %2,%0"
10478   [(set_attr "type" "dfp_arith")
10479    (set_attr "fp_mode" "double")])
10480
10481 (define_expand "muldf3"
10482   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10483         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10484                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10485   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10486   "
10487 {
10488   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10489     {
10490       expand_df_binop (&gen_muldf3_i, operands);
10491       DONE;
10492     }
10493 }")
10494
10495 (define_insn "*muldf3_media"
10496   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10497         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10498                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10499   "TARGET_SHMEDIA_FPU"
10500   "fmul.d       %1, %2, %0"
10501   [(set_attr "type" "dfmul_media")])
10502
10503 (define_insn "muldf3_i"
10504   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10505         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10506                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10507    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10508   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10509   "fmul %2,%0"
10510   [(set_attr "type" "dfp_mul")
10511    (set_attr "fp_mode" "double")])
10512
10513 (define_expand "divdf3"
10514   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10515         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10516                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10517   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10518   "
10519 {
10520   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10521     {
10522       expand_df_binop (&gen_divdf3_i, operands);
10523       DONE;
10524     }
10525 }")
10526
10527 (define_insn "*divdf3_media"
10528   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10529         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10530                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10531   "TARGET_SHMEDIA_FPU"
10532   "fdiv.d       %1, %2, %0"
10533   [(set_attr "type" "dfdiv_media")])
10534
10535 (define_insn "divdf3_i"
10536   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10537         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10538                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10539    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10540   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10541   "fdiv %2,%0"
10542   [(set_attr "type" "dfdiv")
10543    (set_attr "fp_mode" "double")])
10544
10545 (define_insn "floatdidf2"
10546   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10547         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10548   "TARGET_SHMEDIA_FPU"
10549   "float.qd     %1, %0"
10550   [(set_attr "type" "dfpconv_media")])
10551
10552 (define_expand "floatsidf2"
10553   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10554         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10555   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10556   "
10557 {
10558   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10559     {
10560       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10561                                       get_fpscr_rtx ()));
10562       DONE;
10563     }
10564 }")
10565
10566 (define_insn "*floatsidf2_media"
10567   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10568         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10569   "TARGET_SHMEDIA_FPU"
10570   "float.ld     %1, %0"
10571   [(set_attr "type" "dfpconv_media")])
10572
10573 (define_insn "floatsidf2_i"
10574   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10575         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10576    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10577   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10578   "float        %1,%0"
10579   [(set_attr "type" "dfp_conv")
10580    (set_attr "fp_mode" "double")])
10581
10582 (define_insn "fix_truncdfdi2"
10583   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10584         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10585   "TARGET_SHMEDIA_FPU"
10586   "ftrc.dq      %1, %0"
10587   [(set_attr "type" "dfpconv_media")])
10588
10589 (define_expand "fix_truncdfsi2"
10590   [(set (match_operand:SI 0 "fpul_operand" "")
10591         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10592   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10593   "
10594 {
10595   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10596     {
10597       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10598                                           get_fpscr_rtx ()));
10599       DONE;
10600     }
10601 }")
10602
10603 (define_insn "*fix_truncdfsi2_media"
10604   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10605         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10606   "TARGET_SHMEDIA_FPU"
10607   "ftrc.dl      %1, %0"
10608   [(set_attr "type" "dfpconv_media")])
10609
10610 (define_insn "fix_truncdfsi2_i"
10611   [(set (match_operand:SI 0 "fpul_operand" "=y")
10612         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10613    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10614   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10615   "ftrc %1,%0"
10616   [(set_attr "type" "dfp_conv")
10617    (set_attr "dfp_comp" "no")
10618    (set_attr "fp_mode" "double")])
10619
10620 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10621 ;; fix_truncdfsi2_i.
10622 ;; (define_insn "fix_truncdfsi2_i4"
10623 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10624 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10625 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10626 ;;    (clobber (reg:SI FPUL_REG))]
10627 ;;   "TARGET_SH4"
10628 ;;   "#"
10629 ;;   [(set_attr "length" "4")
10630 ;;    (set_attr "fp_mode" "double")])
10631 ;;
10632 ;; (define_split
10633 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10634 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10635 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10636 ;;    (clobber (reg:SI FPUL_REG))]
10637 ;;   "TARGET_SH4"
10638 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10639 ;;            (use (match_dup 2))])
10640 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10641
10642 (define_insn "cmpgtdf_t"
10643   [(set (reg:SI T_REG)
10644         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10645                (match_operand:DF 1 "arith_reg_operand" "f")))
10646    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10647   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10648   "fcmp/gt      %1,%0"
10649   [(set_attr "type" "dfp_cmp")
10650    (set_attr "fp_mode" "double")])
10651
10652 (define_insn "cmpeqdf_t"
10653   [(set (reg:SI T_REG)
10654         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10655                (match_operand:DF 1 "arith_reg_operand" "f")))
10656    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10657   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10658   "fcmp/eq      %1,%0"
10659   [(set_attr "type" "dfp_cmp")
10660    (set_attr "fp_mode" "double")])
10661
10662 (define_insn "*ieee_ccmpeqdf_t"
10663   [(set (reg:SI T_REG)
10664         (ior:SI (reg:SI T_REG)
10665                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10666                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10667    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10668   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10669   "* return output_ieee_ccmpeq (insn, operands);"
10670   [(set_attr "length" "4")
10671    (set_attr "fp_mode" "double")])
10672
10673 (define_insn "cmpeqdf_media"
10674   [(set (match_operand:SI 0 "register_operand" "=r")
10675         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10676                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10677   "TARGET_SHMEDIA_FPU"
10678   "fcmpeq.d     %1,%2,%0"
10679   [(set_attr "type" "fcmp_media")])
10680
10681 (define_insn "cmpgtdf_media"
10682   [(set (match_operand:SI 0 "register_operand" "=r")
10683         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10684                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10685   "TARGET_SHMEDIA_FPU"
10686   "fcmpgt.d     %1,%2,%0"
10687   [(set_attr "type" "fcmp_media")])
10688
10689 (define_insn "cmpgedf_media"
10690   [(set (match_operand:SI 0 "register_operand" "=r")
10691         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10692                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10693   "TARGET_SHMEDIA_FPU"
10694   "fcmpge.d     %1,%2,%0"
10695   [(set_attr "type" "fcmp_media")])
10696
10697 (define_insn "cmpundf_media"
10698   [(set (match_operand:SI 0 "register_operand" "=r")
10699         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10700                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10701   "TARGET_SHMEDIA_FPU"
10702   "fcmpun.d     %1,%2,%0"
10703   [(set_attr "type" "fcmp_media")])
10704
10705 (define_expand "cbranchdf4"
10706   [(set (pc)
10707         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10708                        [(match_operand:DF 1 "arith_operand" "")
10709                         (match_operand:DF 2 "arith_operand" "")])
10710                       (match_operand 3 "" "")
10711                       (pc)))]
10712   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10713   "
10714 {
10715   if (TARGET_SHMEDIA)
10716     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10717                                           operands[3]));
10718   else
10719     sh_emit_compare_and_branch (operands, DFmode);
10720   DONE;
10721 }")
10722
10723
10724 (define_expand "negdf2"
10725   [(set (match_operand:DF 0 "arith_reg_operand" "")
10726         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10727   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10728   "
10729 {
10730   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10731     {
10732       expand_df_unop (&gen_negdf2_i, operands);
10733       DONE;
10734     }
10735 }")
10736
10737 (define_insn "*negdf2_media"
10738   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10739         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10740   "TARGET_SHMEDIA_FPU"
10741   "fneg.d       %1, %0"
10742   [(set_attr "type" "fmove_media")])
10743
10744 (define_insn "negdf2_i"
10745   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10746         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10747    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10748   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10749   "fneg %0"
10750   [(set_attr "type" "fmove")
10751    (set_attr "fp_mode" "double")])
10752
10753 (define_expand "sqrtdf2"
10754   [(set (match_operand:DF 0 "arith_reg_operand" "")
10755         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10756   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10757   "
10758 {
10759   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10760     {
10761       expand_df_unop (&gen_sqrtdf2_i, operands);
10762       DONE;
10763     }
10764 }")
10765
10766 (define_insn "*sqrtdf2_media"
10767   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10768         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10769   "TARGET_SHMEDIA_FPU"
10770   "fsqrt.d      %1, %0"
10771   [(set_attr "type" "dfdiv_media")])
10772
10773 (define_insn "sqrtdf2_i"
10774   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10775         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10776    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10777   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10778   "fsqrt        %0"
10779   [(set_attr "type" "dfdiv")
10780    (set_attr "fp_mode" "double")])
10781
10782 (define_expand "absdf2"
10783   [(set (match_operand:DF 0 "arith_reg_operand" "")
10784         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10785   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10786   "
10787 {
10788   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10789     {
10790       expand_df_unop (&gen_absdf2_i, operands);
10791       DONE;
10792     }
10793 }")
10794
10795 (define_insn "*absdf2_media"
10796   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10797         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10798   "TARGET_SHMEDIA_FPU"
10799   "fabs.d       %1, %0"
10800   [(set_attr "type" "fmove_media")])
10801
10802 (define_insn "absdf2_i"
10803   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10804         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10805    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10806   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10807   "fabs %0"
10808   [(set_attr "type" "fmove")
10809    (set_attr "fp_mode" "double")])
10810
10811 (define_expand "extendsfdf2"
10812   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10813         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10814   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10815   "
10816 {
10817   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10818     {
10819       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10820                                         get_fpscr_rtx ()));
10821       DONE;
10822     }
10823 }")
10824
10825 (define_insn "*extendsfdf2_media"
10826   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10827         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10828   "TARGET_SHMEDIA_FPU"
10829   "fcnv.sd      %1, %0"
10830   [(set_attr "type" "dfpconv_media")])
10831
10832 (define_insn "extendsfdf2_i4"
10833   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10834         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10835    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10836   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10837   "fcnvsd  %1,%0"
10838   [(set_attr "type" "fp")
10839    (set_attr "fp_mode" "double")])
10840
10841 (define_expand "truncdfsf2"
10842   [(set (match_operand:SF 0 "fpul_operand" "")
10843         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10844   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10845   "
10846 {
10847   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10848     {
10849       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10850                                        get_fpscr_rtx ()));
10851       DONE;
10852     }
10853 }")
10854
10855 (define_insn "*truncdfsf2_media"
10856   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10857         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10858   "TARGET_SHMEDIA_FPU"
10859   "fcnv.ds      %1, %0"
10860   [(set_attr "type" "dfpconv_media")])
10861
10862 (define_insn "truncdfsf2_i4"
10863   [(set (match_operand:SF 0 "fpul_operand" "=y")
10864         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10865    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10866   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10867   "fcnvds  %1,%0"
10868   [(set_attr "type" "fp")
10869    (set_attr "fp_mode" "double")])
10870 \f
10871 ;; Bit field extract patterns.  These give better code for packed bitfields,
10872 ;; because they allow auto-increment addresses to be generated.
10873
10874 (define_expand "insv"
10875   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10876                          (match_operand:SI 1 "immediate_operand" "")
10877                          (match_operand:SI 2 "immediate_operand" ""))
10878         (match_operand:SI 3 "general_operand" ""))]
10879   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10880   "
10881 {
10882   rtx addr_target, orig_address, shift_reg, qi_val;
10883   HOST_WIDE_INT bitsize, size, v = 0;
10884   rtx x = operands[3];
10885
10886   if (TARGET_SH2A && TARGET_BITOPS
10887       && (satisfies_constraint_Sbw (operands[0])
10888           || satisfies_constraint_Sbv (operands[0]))
10889       && satisfies_constraint_M (operands[1])
10890       && satisfies_constraint_K03 (operands[2]))
10891     {
10892       if (satisfies_constraint_N (operands[3]))
10893         {
10894           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10895           DONE;
10896         }
10897       else if (satisfies_constraint_M (operands[3]))
10898         {
10899           emit_insn (gen_bset_m2a (operands[0], operands[2]));
10900           DONE;
10901         }
10902       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10903                 && satisfies_constraint_M (operands[1]))
10904         {
10905           emit_insn (gen_bst_m2a (operands[0], operands[2]));
10906           DONE;
10907         }
10908       else if (REG_P (operands[3])
10909                && satisfies_constraint_M (operands[1]))
10910         {
10911           emit_insn (gen_bld_reg (operands[3], const0_rtx));
10912           emit_insn (gen_bst_m2a (operands[0], operands[2]));
10913           DONE;
10914         }
10915     }
10916   /* ??? expmed doesn't care for non-register predicates.  */
10917   if (! memory_operand (operands[0], VOIDmode)
10918       || ! immediate_operand (operands[1], VOIDmode)
10919       || ! immediate_operand (operands[2], VOIDmode)
10920       || ! general_operand (x, VOIDmode))
10921     FAIL;
10922   /* If this isn't a 16 / 24 / 32 bit field, or if
10923      it doesn't start on a byte boundary, then fail.  */
10924   bitsize = INTVAL (operands[1]);
10925   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10926       || (INTVAL (operands[2]) % 8) != 0)
10927     FAIL;
10928
10929   size = bitsize / 8;
10930   orig_address = XEXP (operands[0], 0);
10931   shift_reg = gen_reg_rtx (SImode);
10932   if (CONST_INT_P (x))
10933     {
10934       v = INTVAL (x);
10935       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10936     }
10937   else
10938     {
10939       emit_insn (gen_movsi (shift_reg, operands[3]));
10940       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10941     }
10942   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10943
10944   operands[0] = replace_equiv_address (operands[0], addr_target);
10945   emit_insn (gen_movqi (operands[0], qi_val));
10946
10947   while (size -= 1)
10948     {
10949       if (CONST_INT_P (x))
10950         qi_val
10951           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
10952       else
10953         {
10954           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
10955           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10956         }
10957       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
10958       emit_insn (gen_movqi (operands[0], qi_val));
10959     }
10960
10961   DONE;
10962 }")
10963
10964 (define_insn "movua"
10965   [(set (match_operand:SI 0 "register_operand" "=z")
10966         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
10967                    UNSPEC_MOVUA))]
10968   "TARGET_SH4A_ARCH"
10969   "movua.l      %1,%0"
10970   [(set_attr "type" "movua")])
10971
10972 ;; We shouldn't need this, but cse replaces increments with references
10973 ;; to other regs before flow has a chance to create post_inc
10974 ;; addressing modes, and only postreload's cse_move2add brings the
10975 ;; increments back to a usable form.
10976 (define_peephole2
10977   [(set (match_operand:SI 0 "register_operand" "")
10978         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
10979                          (const_int 32) (const_int 0)))
10980    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
10981   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
10982   [(set (match_operand:SI 0 "register_operand" "")
10983         (sign_extract:SI (mem:SI (post_inc:SI
10984                                   (match_operand:SI 1 "register_operand" "")))
10985                          (const_int 32) (const_int 0)))]
10986   "")
10987
10988 (define_expand "extv"
10989   [(set (match_operand:SI 0 "register_operand" "")
10990         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
10991                          (match_operand 2 "const_int_operand" "")
10992                          (match_operand 3 "const_int_operand" "")))]
10993   "TARGET_SH4A_ARCH || TARGET_SH2A"
10994 {
10995   if (TARGET_SH2A && TARGET_BITOPS
10996       && (satisfies_constraint_Sbw (operands[1])
10997           || satisfies_constraint_Sbv (operands[1]))
10998       && satisfies_constraint_M (operands[2])
10999       && satisfies_constraint_K03 (operands[3]))
11000    {
11001       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11002       if (REGNO (operands[0]) != T_REG)
11003         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11004       DONE;
11005    }
11006   if (TARGET_SH4A_ARCH
11007       && INTVAL (operands[2]) == 32
11008       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11009       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11010     {
11011       rtx src = adjust_address (operands[1], BLKmode, 0);
11012       set_mem_size (src, GEN_INT (4));
11013       emit_insn (gen_movua (operands[0], src));
11014       DONE;
11015     }
11016
11017   FAIL;
11018 })
11019
11020 (define_expand "extzv"
11021   [(set (match_operand:SI 0 "register_operand" "")
11022         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11023                          (match_operand 2 "const_int_operand" "")
11024                          (match_operand 3 "const_int_operand" "")))]
11025   "TARGET_SH4A_ARCH || TARGET_SH2A"
11026 {
11027   if (TARGET_SH2A && TARGET_BITOPS
11028       && (satisfies_constraint_Sbw (operands[1])
11029           || satisfies_constraint_Sbv (operands[1]))
11030       && satisfies_constraint_M (operands[2])
11031       && satisfies_constraint_K03 (operands[3]))
11032     {
11033       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11034       if (REGNO (operands[0]) != T_REG)
11035         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11036       DONE;
11037     }
11038   if (TARGET_SH4A_ARCH
11039       && INTVAL (operands[2]) == 32
11040       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11041       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11042     {
11043       rtx src = adjust_address (operands[1], BLKmode, 0);
11044       set_mem_size (src, GEN_INT (4));
11045       emit_insn (gen_movua (operands[0], src));
11046       DONE;
11047     }
11048
11049   FAIL;
11050 })
11051
11052 ;; SH2A instructions for bitwise operations.
11053
11054 ;; Clear a bit in a memory location.
11055 (define_insn "bclr_m2a"
11056   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11057         (and:QI
11058             (not:QI (ashift:QI (const_int 1)
11059                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11060             (match_dup 0)))]
11061   "TARGET_SH2A && TARGET_BITOPS"
11062   "@
11063         bclr.b\\t%1,%0
11064         bclr.b\\t%1,@(0,%t0)"
11065 [(set_attr "length" "4,4")])
11066
11067 (define_insn "bclrmem_m2a"
11068   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11069         (and:QI (match_dup 0)
11070                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11071   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11072   "@
11073         bclr.b\\t%W1,%0
11074         bclr.b\\t%W1,@(0,%t0)"
11075   [(set_attr "length" "4,4")])
11076
11077 ;; Set a bit in a memory location.
11078 (define_insn "bset_m2a"
11079   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11080         (ior:QI
11081             (ashift:QI (const_int 1)
11082                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11083             (match_dup 0)))]
11084   "TARGET_SH2A && TARGET_BITOPS"
11085   "@
11086         bset.b\\t%1,%0
11087         bset.b\\t%1,@(0,%t0)"
11088   [(set_attr "length" "4,4")])
11089
11090 (define_insn "bsetmem_m2a"
11091   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11092         (ior:QI (match_dup 0)
11093                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11094   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11095   "@
11096         bset.b\\t%V1,%0
11097         bset.b\\t%V1,@(0,%t0)"
11098   [(set_attr "length" "4,4")])
11099
11100 ;;; Transfer the contents of the T bit to a specified bit of memory.
11101 (define_insn "bst_m2a"
11102   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11103         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11104             (and:QI
11105                 (not:QI (ashift:QI (const_int 1)
11106                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11107                 (match_dup 0))
11108             (ior:QI
11109                 (ashift:QI (const_int 1) (match_dup 1))
11110                 (match_dup 0))))]
11111   "TARGET_SH2A && TARGET_BITOPS"
11112   "@
11113         bst.b\\t%1,%0
11114         bst.b\\t%1,@(0,%t0)"
11115   [(set_attr "length" "4")])
11116
11117 ;; Store a specified bit of memory in the T bit.
11118 (define_insn "bld_m2a"
11119   [(set (reg:SI T_REG)
11120         (zero_extract:SI
11121             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11122             (const_int 1)
11123             (match_operand 1 "const_int_operand" "K03,K03")))]
11124   "TARGET_SH2A && TARGET_BITOPS"
11125   "@
11126         bld.b\\t%1,%0
11127         bld.b\\t%1,@(0,%t0)"
11128   [(set_attr "length" "4,4")])
11129
11130 ;; Store a specified bit of memory in the T bit.
11131 (define_insn "bldsign_m2a"
11132   [(set (reg:SI T_REG)
11133         (sign_extract:SI
11134             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11135             (const_int 1)
11136             (match_operand 1 "const_int_operand" "K03,K03")))]
11137   "TARGET_SH2A && TARGET_BITOPS"
11138   "@
11139         bld.b\\t%1,%0
11140         bld.b\\t%1,@(0,%t0)"
11141   [(set_attr "length" "4,4")])
11142
11143 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11144 (define_insn "bld_reg"
11145   [(set (reg:SI T_REG)
11146         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11147                          (const_int 1)
11148                          (match_operand 1 "const_int_operand" "K03")))]
11149   "TARGET_SH2A"
11150   "bld\\t%1,%0")
11151
11152 (define_insn "*bld_regqi"
11153   [(set (reg:SI T_REG)
11154         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11155                          (const_int 1)
11156                          (match_operand 1 "const_int_operand" "K03")))]
11157   "TARGET_SH2A"
11158   "bld\\t%1,%0")
11159
11160 ;; Take logical and of a specified bit of memory with the T bit and
11161 ;; store its result in the T bit.
11162 (define_insn "band_m2a"
11163   [(set (reg:SI T_REG)
11164         (and:SI (reg:SI T_REG)
11165                 (zero_extract:SI
11166                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11167                     (const_int 1)
11168                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11169   "TARGET_SH2A && TARGET_BITOPS"
11170   "@
11171         band.b\\t%1,%0
11172         band.b\\t%1,@(0,%t0)"
11173   [(set_attr "length" "4,4")])
11174
11175 (define_insn "bandreg_m2a"
11176   [(set (match_operand:SI 0 "register_operand" "=r,r")
11177         (and:SI (zero_extract:SI
11178                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11179                     (const_int 1)
11180                     (match_operand 2 "const_int_operand" "K03,K03"))
11181                 (match_operand:SI 3 "register_operand" "r,r")))]
11182   "TARGET_SH2A && TARGET_BITOPS"
11183   "@
11184         band.b\\t%2,%1\;movt\\t%0
11185         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11186   [(set_attr "length" "6,6")])
11187
11188 ;; Take logical or of a specified bit of memory with the T bit and
11189 ;; store its result in the T bit.
11190 (define_insn "bor_m2a"
11191   [(set (reg:SI T_REG)
11192         (ior:SI (reg:SI T_REG)
11193                 (zero_extract:SI
11194                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11195                     (const_int 1)
11196                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11197   "TARGET_SH2A && TARGET_BITOPS"
11198   "@
11199         bor.b\\t%1,%0
11200         bor.b\\t%1,@(0,%t0)"
11201   [(set_attr "length" "4,4")])
11202
11203 (define_insn "borreg_m2a"
11204   [(set (match_operand:SI 0 "register_operand" "=r,r")
11205         (ior:SI (zero_extract:SI
11206                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11207                     (const_int 1)
11208                     (match_operand 2 "const_int_operand" "K03,K03"))
11209                 (match_operand:SI 3 "register_operand" "=r,r")))]
11210   "TARGET_SH2A && TARGET_BITOPS"
11211   "@
11212         bor.b\\t%2,%1\;movt\\t%0
11213         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11214   [(set_attr "length" "6,6")])
11215
11216 ;; Take exclusive or of a specified bit of memory with the T bit and
11217 ;; store its result in the T bit.
11218 (define_insn "bxor_m2a"
11219   [(set (reg:SI T_REG)
11220         (xor:SI (reg:SI T_REG)
11221                 (zero_extract:SI
11222                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11223                     (const_int 1)
11224                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11225   "TARGET_SH2A && TARGET_BITOPS"
11226   "@
11227         bxor.b\\t%1,%0
11228         bxor.b\\t%1,@(0,%t0)"
11229   [(set_attr "length" "4,4")])
11230
11231 (define_insn "bxorreg_m2a"
11232   [(set (match_operand:SI 0 "register_operand" "=r,r")
11233         (xor:SI (zero_extract:SI
11234                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11235                     (const_int 1)
11236                     (match_operand 2 "const_int_operand" "K03,K03"))
11237                 (match_operand:SI 3 "register_operand" "=r,r")))]
11238   "TARGET_SH2A && TARGET_BITOPS"
11239   "@
11240         bxor.b\\t%2,%1\;movt\\t%0
11241         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11242   [(set_attr "length" "6,6")])
11243
11244 \f
11245 ;; -------------------------------------------------------------------------
11246 ;; Peepholes
11247 ;; -------------------------------------------------------------------------
11248 ;; This matches cases where the bit in a memory location is set.
11249 (define_peephole2
11250   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11251         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11252    (set (match_dup 0)
11253         (ior:SI (match_dup 0)
11254         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11255    (set (match_dup 1)
11256         (match_operand 3 "arith_reg_operand" "r,r"))]
11257   "TARGET_SH2A && TARGET_BITOPS
11258    && satisfies_constraint_Pso (operands[2])
11259    && REGNO (operands[0]) == REGNO (operands[3])"
11260   [(set (match_dup 1)
11261         (ior:QI (match_dup 1)
11262                 (match_dup 2)))]
11263   "")
11264
11265 ;; This matches cases where the bit in a memory location is cleared.
11266 (define_peephole2
11267   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11268         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11269    (set (match_dup 0)
11270         (and:SI (match_dup 0)
11271         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11272    (set (match_dup 1)
11273         (match_operand 3 "arith_reg_operand" "r,r"))]
11274   "TARGET_SH2A && TARGET_BITOPS
11275    && satisfies_constraint_Psz (operands[2])
11276    && REGNO (operands[0]) == REGNO (operands[3])"
11277   [(set (match_dup 1)
11278         (and:QI (match_dup 1)
11279                 (match_dup 2)))]
11280   "")
11281
11282 ;; This matches cases where a stack pointer increment at the start of the
11283 ;; epilogue combines with a stack slot read loading the return value.
11284
11285 (define_peephole
11286   [(set (match_operand:SI 0 "arith_reg_operand" "")
11287         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11288    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11289   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11290   "mov.l        @%1+,%0")
11291
11292 ;; See the comment on the dt combiner pattern above.
11293
11294 (define_peephole
11295   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11296         (plus:SI (match_dup 0)
11297                  (const_int -1)))
11298    (set (reg:SI T_REG)
11299         (eq:SI (match_dup 0)
11300                (const_int 0)))]
11301   "TARGET_SH2"
11302   "dt   %0")
11303
11304 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11305 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11306 ;; reload when the constant is too large for a reg+offset address.
11307
11308 ;; ??? We would get much better code if this was done in reload.  This would
11309 ;; require modifying find_reloads_address to recognize that if the constant
11310 ;; is out-of-range for an immediate add, then we get better code by reloading
11311 ;; the constant into a register than by reloading the sum into a register,
11312 ;; since the former is one instruction shorter if the address does not need
11313 ;; to be offsettable.  Unfortunately this does not work, because there is
11314 ;; only one register, r0, that can be used as an index register.  This register
11315 ;; is also the function return value register.  So, if we try to force reload
11316 ;; to use double-reg addresses, then we end up with some instructions that
11317 ;; need to use r0 twice.  The only way to fix this is to change the calling
11318 ;; convention so that r0 is not used to return values.
11319
11320 (define_peephole
11321   [(set (match_operand:SI 0 "register_operand" "=r")
11322         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11323    (set (mem:SI (match_dup 0))
11324         (match_operand:SI 2 "general_movsrc_operand" ""))]
11325   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11326   "mov.l        %2,@(%0,%1)")
11327
11328 (define_peephole
11329   [(set (match_operand:SI 0 "register_operand" "=r")
11330         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11331    (set (match_operand:SI 2 "general_movdst_operand" "")
11332         (mem:SI (match_dup 0)))]
11333   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11334   "mov.l        @(%0,%1),%2")
11335
11336 (define_peephole
11337   [(set (match_operand:SI 0 "register_operand" "=r")
11338         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11339    (set (mem:HI (match_dup 0))
11340         (match_operand:HI 2 "general_movsrc_operand" ""))]
11341   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11342   "mov.w        %2,@(%0,%1)")
11343
11344 (define_peephole
11345   [(set (match_operand:SI 0 "register_operand" "=r")
11346         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11347    (set (match_operand:HI 2 "general_movdst_operand" "")
11348         (mem:HI (match_dup 0)))]
11349   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11350   "mov.w        @(%0,%1),%2")
11351
11352 (define_peephole
11353   [(set (match_operand:SI 0 "register_operand" "=r")
11354         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11355    (set (mem:QI (match_dup 0))
11356         (match_operand:QI 2 "general_movsrc_operand" ""))]
11357   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11358   "mov.b        %2,@(%0,%1)")
11359
11360 (define_peephole
11361   [(set (match_operand:SI 0 "register_operand" "=r")
11362         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11363    (set (match_operand:QI 2 "general_movdst_operand" "")
11364         (mem:QI (match_dup 0)))]
11365   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11366   "mov.b        @(%0,%1),%2")
11367
11368 (define_peephole
11369   [(set (match_operand:SI 0 "register_operand" "=r")
11370         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11371    (set (mem:SF (match_dup 0))
11372         (match_operand:SF 2 "general_movsrc_operand" ""))]
11373   "TARGET_SH1 && REGNO (operands[0]) == 0
11374    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11375        || (GET_CODE (operands[2]) == SUBREG
11376            && REGNO (SUBREG_REG (operands[2])) < 16))
11377    && reg_unused_after (operands[0], insn)"
11378   "mov.l        %2,@(%0,%1)")
11379
11380 (define_peephole
11381   [(set (match_operand:SI 0 "register_operand" "=r")
11382         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11383    (set (match_operand:SF 2 "general_movdst_operand" "")
11384
11385         (mem:SF (match_dup 0)))]
11386   "TARGET_SH1 && REGNO (operands[0]) == 0
11387    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11388        || (GET_CODE (operands[2]) == SUBREG
11389            && REGNO (SUBREG_REG (operands[2])) < 16))
11390    && reg_unused_after (operands[0], insn)"
11391   "mov.l        @(%0,%1),%2")
11392
11393 (define_peephole
11394   [(set (match_operand:SI 0 "register_operand" "=r")
11395         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11396    (set (mem:SF (match_dup 0))
11397         (match_operand:SF 2 "general_movsrc_operand" ""))]
11398   "TARGET_SH2E && REGNO (operands[0]) == 0
11399    && ((REG_P (operands[2])
11400         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11401        || (GET_CODE (operands[2]) == SUBREG
11402            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11403    && reg_unused_after (operands[0], insn)"
11404   "fmov{.s|}    %2,@(%0,%1)")
11405
11406 (define_peephole
11407   [(set (match_operand:SI 0 "register_operand" "=r")
11408         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11409    (set (match_operand:SF 2 "general_movdst_operand" "")
11410
11411         (mem:SF (match_dup 0)))]
11412   "TARGET_SH2E && REGNO (operands[0]) == 0
11413    && ((REG_P (operands[2])
11414         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11415        || (GET_CODE (operands[2]) == SUBREG
11416            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11417    && reg_unused_after (operands[0], insn)"
11418   "fmov{.s|}    @(%0,%1),%2")
11419
11420 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11421 (define_insn "sp_switch_1"
11422   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11423   "TARGET_SH1"
11424   "*
11425 {
11426   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11427   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11428   return \"mov r0,r15\";
11429 }"
11430   [(set_attr "length" "10")])
11431
11432 ;; Switch back to the original stack for interrupt functions with the
11433 ;; sp_switch attribute.  */
11434 (define_insn "sp_switch_2"
11435   [(const_int 2)]
11436   "TARGET_SH1"
11437   "mov.l @r15+,r15\;mov.l @r15+,r0"
11438   [(set_attr "length" "4")])
11439
11440 ;; Integer vector moves
11441
11442 (define_expand "movv8qi"
11443   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11444         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11445   "TARGET_SHMEDIA"
11446   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11447
11448 (define_insn "movv8qi_i"
11449   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11450         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11451   "TARGET_SHMEDIA
11452    && (register_operand (operands[0], V8QImode)
11453        || sh_register_operand (operands[1], V8QImode))"
11454   "@
11455         add     %1, r63, %0
11456         movi    %1, %0
11457         #
11458         ld%M1.q %m1, %0
11459         st%M0.q %m0, %N1"
11460   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11461    (set_attr "length" "4,4,16,4,4")])
11462
11463 (define_split
11464   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11465         (subreg:V8QI (const_int 0) 0))]
11466   "TARGET_SHMEDIA"
11467   [(set (match_dup 0)
11468         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11469                             (const_int 0) (const_int 0) (const_int 0)
11470                             (const_int 0) (const_int 0)]))])
11471
11472 (define_split
11473   [(set (match_operand 0 "arith_reg_dest" "")
11474         (match_operand 1 "sh_rep_vec" ""))]
11475   "TARGET_SHMEDIA && reload_completed
11476    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11477    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11478    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11479    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11480        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11481    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11482        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11483   [(set (match_dup 0) (match_dup 1))
11484    (match_dup 2)]
11485   "
11486 {
11487   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11488   rtx elt1 = XVECEXP (operands[1], 0, 1);
11489
11490   if (unit_size > 2)
11491     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11492   else
11493     {
11494       if (unit_size < 2)
11495         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11496       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11497     }
11498   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11499   operands[1] = XVECEXP (operands[1], 0, 0);
11500   if (unit_size < 2)
11501     {
11502       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11503         operands[1]
11504           = GEN_INT (TARGET_LITTLE_ENDIAN
11505                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11506                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11507       else
11508         {
11509           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11510           operands[1]
11511             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11512         }
11513     }
11514 }")
11515
11516 (define_split
11517   [(set (match_operand 0 "arith_reg_dest" "")
11518         (match_operand 1 "sh_const_vec" ""))]
11519   "TARGET_SHMEDIA && reload_completed
11520    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11521    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11522   [(set (match_dup 0) (match_dup 1))]
11523   "
11524 {
11525   rtx v = operands[1];
11526   enum machine_mode new_mode
11527     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11528
11529   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11530   operands[1]
11531     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11532 }")
11533
11534 (define_expand "movv2hi"
11535   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11536         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11537   "TARGET_SHMEDIA"
11538   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11539
11540 (define_insn "movv2hi_i"
11541   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11542         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11543   "TARGET_SHMEDIA
11544    && (register_operand (operands[0], V2HImode)
11545        || sh_register_operand (operands[1], V2HImode))"
11546   "@
11547         add.l   %1, r63, %0
11548         movi    %1, %0
11549         #
11550         ld%M1.l %m1, %0
11551         st%M0.l %m0, %N1"
11552   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11553    (set_attr "length" "4,4,16,4,4")
11554    (set (attr "highpart")
11555         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11556                (const_string "user")]
11557               (const_string "ignore")))])
11558
11559 (define_expand "movv4hi"
11560   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11561         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11562   "TARGET_SHMEDIA"
11563   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11564
11565 (define_insn "movv4hi_i"
11566   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11567         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11568   "TARGET_SHMEDIA
11569    && (register_operand (operands[0], V4HImode)
11570        || sh_register_operand (operands[1], V4HImode))"
11571   "@
11572         add     %1, r63, %0
11573         movi    %1, %0
11574         #
11575         ld%M1.q %m1, %0
11576         st%M0.q %m0, %N1"
11577   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11578    (set_attr "length" "4,4,16,4,4")
11579    (set_attr "highpart" "depend")])
11580
11581 (define_expand "movv2si"
11582   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11583         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11584   "TARGET_SHMEDIA"
11585   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11586
11587 (define_insn "movv2si_i"
11588   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11589         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11590   "TARGET_SHMEDIA
11591    && (register_operand (operands[0], V2SImode)
11592        || sh_register_operand (operands[1], V2SImode))"
11593   "@
11594         add     %1, r63, %0
11595         #
11596         #
11597         ld%M1.q %m1, %0
11598         st%M0.q %m0, %N1"
11599   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11600    (set_attr "length" "4,4,16,4,4")
11601    (set_attr "highpart" "depend")])
11602
11603 ;; Multimedia Intrinsics
11604
11605 (define_insn "absv2si2"
11606   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11607         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11608   "TARGET_SHMEDIA"
11609   "mabs.l       %1, %0"
11610   [(set_attr "type" "mcmp_media")
11611    (set_attr "highpart" "depend")])
11612
11613 (define_insn "absv4hi2"
11614   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11615         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11616   "TARGET_SHMEDIA"
11617   "mabs.w       %1, %0"
11618   [(set_attr "type" "mcmp_media")
11619    (set_attr "highpart" "depend")])
11620
11621 (define_insn "addv2si3"
11622   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11623         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11624                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11625   "TARGET_SHMEDIA"
11626   "madd.l       %1, %2, %0"
11627   [(set_attr "type" "arith_media")
11628    (set_attr "highpart" "depend")])
11629
11630 (define_insn "addv4hi3"
11631   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11632         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11633                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11634   "TARGET_SHMEDIA"
11635   "madd.w       %1, %2, %0"
11636   [(set_attr "type" "arith_media")
11637    (set_attr "highpart" "depend")])
11638
11639 (define_insn_and_split "addv2hi3"
11640   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11641         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11642                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11643   "TARGET_SHMEDIA"
11644   "#"
11645   "TARGET_SHMEDIA"
11646   [(const_int 0)]
11647   "
11648 {
11649   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11650   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11651   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11652   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11653   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11654
11655   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11656   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11657   DONE;
11658 }"
11659   [(set_attr "highpart" "must_split")])
11660
11661 (define_insn "ssaddv2si3"
11662   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11663         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11664                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11665   "TARGET_SHMEDIA"
11666   "madds.l      %1, %2, %0"
11667   [(set_attr "type" "mcmp_media")
11668    (set_attr "highpart" "depend")])
11669
11670 (define_insn "usaddv8qi3"
11671   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11672         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11673                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11674   "TARGET_SHMEDIA"
11675   "madds.ub     %1, %2, %0"
11676   [(set_attr "type" "mcmp_media")
11677    (set_attr "highpart" "depend")])
11678
11679 (define_insn "ssaddv4hi3"
11680   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11681         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11682                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11683   "TARGET_SHMEDIA"
11684   "madds.w      %1, %2, %0"
11685   [(set_attr "type" "mcmp_media")
11686    (set_attr "highpart" "depend")])
11687
11688 (define_insn "negcmpeqv8qi"
11689   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11690         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11691                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11692   "TARGET_SHMEDIA"
11693   "mcmpeq.b     %N1, %N2, %0"
11694   [(set_attr "type" "mcmp_media")
11695    (set_attr "highpart" "depend")])
11696
11697 (define_insn "negcmpeqv2si"
11698   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11699         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11700                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11701   "TARGET_SHMEDIA"
11702   "mcmpeq.l     %N1, %N2, %0"
11703   [(set_attr "type" "mcmp_media")
11704    (set_attr "highpart" "depend")])
11705
11706 (define_insn "negcmpeqv4hi"
11707   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11708         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11709                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11710   "TARGET_SHMEDIA"
11711   "mcmpeq.w     %N1, %N2, %0"
11712   [(set_attr "type" "mcmp_media")
11713    (set_attr "highpart" "depend")])
11714
11715 (define_insn "negcmpgtuv8qi"
11716   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11717         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11718                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11719   "TARGET_SHMEDIA"
11720   "mcmpgt.ub    %N1, %N2, %0"
11721   [(set_attr "type" "mcmp_media")
11722    (set_attr "highpart" "depend")])
11723
11724 (define_insn "negcmpgtv2si"
11725   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11726         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11727                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11728   "TARGET_SHMEDIA"
11729   "mcmpgt.l     %N1, %N2, %0"
11730   [(set_attr "type" "mcmp_media")
11731    (set_attr "highpart" "depend")])
11732
11733 (define_insn "negcmpgtv4hi"
11734   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11735         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11736                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11737   "TARGET_SHMEDIA"
11738   "mcmpgt.w     %N1, %N2, %0"
11739   [(set_attr "type" "mcmp_media")
11740    (set_attr "highpart" "depend")])
11741
11742 (define_insn "mcmv"
11743   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11744         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11745                         (match_operand:DI 2 "arith_reg_operand" "r"))
11746                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11747                         (not:DI (match_dup 2)))))]
11748   "TARGET_SHMEDIA"
11749   "mcmv %N1, %2, %0"
11750   [(set_attr "type" "arith_media")
11751    (set_attr "highpart" "depend")])
11752
11753 (define_insn "mcnvs_lw"
11754   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11755         (vec_concat:V4HI
11756          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11757          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11758   "TARGET_SHMEDIA"
11759   "mcnvs.lw     %N1, %N2, %0"
11760   [(set_attr "type" "mcmp_media")])
11761
11762 (define_insn "mcnvs_wb"
11763   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11764         (vec_concat:V8QI
11765          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11766          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11767   "TARGET_SHMEDIA"
11768   "mcnvs.wb     %N1, %N2, %0"
11769   [(set_attr "type" "mcmp_media")])
11770
11771 (define_insn "mcnvs_wub"
11772   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11773         (vec_concat:V8QI
11774          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11775          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11776   "TARGET_SHMEDIA"
11777   "mcnvs.wub    %N1, %N2, %0"
11778   [(set_attr "type" "mcmp_media")])
11779
11780 (define_insn "mextr_rl"
11781   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11782         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11783                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11784                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11785                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11786   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11787   "*
11788 {
11789   static char templ[21];
11790
11791   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11792            (int) INTVAL (operands[3]) >> 3);
11793   return templ;
11794 }"
11795   [(set_attr "type" "arith_media")])
11796
11797 (define_insn "*mextr_lr"
11798   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11799         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11800                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11801                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11802                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11803   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11804   "*
11805 {
11806   static char templ[21];
11807
11808   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11809            (int) INTVAL (operands[4]) >> 3);
11810   return templ;
11811 }"
11812   [(set_attr "type" "arith_media")])
11813
11814 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11815 ; vector then varies depending on endianness.
11816 (define_expand "mextr1"
11817   [(match_operand:DI 0 "arith_reg_dest" "")
11818    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11819    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11820   "TARGET_SHMEDIA"
11821   "
11822 {
11823   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11824                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11825   DONE;
11826 }")
11827
11828 (define_expand "mextr2"
11829   [(match_operand:DI 0 "arith_reg_dest" "")
11830    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11831    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11832   "TARGET_SHMEDIA"
11833   "
11834 {
11835   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11836                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11837   DONE;
11838 }")
11839
11840 (define_expand "mextr3"
11841   [(match_operand:DI 0 "arith_reg_dest" "")
11842    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11843    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11844   "TARGET_SHMEDIA"
11845   "
11846 {
11847   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11848                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11849   DONE;
11850 }")
11851
11852 (define_expand "mextr4"
11853   [(match_operand:DI 0 "arith_reg_dest" "")
11854    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11855    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11856   "TARGET_SHMEDIA"
11857   "
11858 {
11859   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11860                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11861   DONE;
11862 }")
11863
11864 (define_expand "mextr5"
11865   [(match_operand:DI 0 "arith_reg_dest" "")
11866    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11867    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11868   "TARGET_SHMEDIA"
11869   "
11870 {
11871   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11872                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11873   DONE;
11874 }")
11875
11876 (define_expand "mextr6"
11877   [(match_operand:DI 0 "arith_reg_dest" "")
11878    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11879    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11880   "TARGET_SHMEDIA"
11881   "
11882 {
11883   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11884                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11885   DONE;
11886 }")
11887
11888 (define_expand "mextr7"
11889   [(match_operand:DI 0 "arith_reg_dest" "")
11890    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11891    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11892   "TARGET_SHMEDIA"
11893   "
11894 {
11895   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11896                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11897   DONE;
11898 }")
11899
11900 (define_expand "mmacfx_wl"
11901   [(match_operand:V2SI 0 "arith_reg_dest" "")
11902    (match_operand:V2HI 1 "extend_reg_operand" "")
11903    (match_operand:V2HI 2 "extend_reg_operand" "")
11904    (match_operand:V2SI 3 "arith_reg_operand" "")]
11905   "TARGET_SHMEDIA"
11906   "
11907 {
11908   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11909                               operands[1], operands[2]));
11910   DONE;
11911 }")
11912
11913 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11914 ;; is depend
11915 (define_insn "mmacfx_wl_i"
11916   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11917         (ss_plus:V2SI
11918          (match_operand:V2SI 1 "arith_reg_operand" "0")
11919          (ss_truncate:V2SI
11920           (ashift:V2DI
11921            (sign_extend:V2DI
11922             (mult:V2SI
11923              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11924              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11925            (const_int 1)))))]
11926   "TARGET_SHMEDIA"
11927   "mmacfx.wl    %2, %3, %0"
11928   [(set_attr "type" "mac_media")
11929    (set_attr "highpart" "depend")])
11930
11931 (define_expand "mmacnfx_wl"
11932   [(match_operand:V2SI 0 "arith_reg_dest" "")
11933    (match_operand:V2HI 1 "extend_reg_operand" "")
11934    (match_operand:V2HI 2 "extend_reg_operand" "")
11935    (match_operand:V2SI 3 "arith_reg_operand" "")]
11936   "TARGET_SHMEDIA"
11937   "
11938 {
11939   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11940                                operands[1], operands[2]));
11941   DONE;
11942 }")
11943
11944 (define_insn "mmacnfx_wl_i"
11945   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11946         (ss_minus:V2SI
11947          (match_operand:V2SI 1 "arith_reg_operand" "0")
11948          (ss_truncate:V2SI
11949           (ashift:V2DI
11950            (sign_extend:V2DI
11951             (mult:V2SI
11952              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11953              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11954            (const_int 1)))))]
11955   "TARGET_SHMEDIA"
11956   "mmacnfx.wl   %2, %3, %0"
11957   [(set_attr "type" "mac_media")
11958    (set_attr "highpart" "depend")])
11959
11960 (define_insn "mulv2si3"
11961   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11962         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11963                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11964   "TARGET_SHMEDIA"
11965   "mmul.l       %1, %2, %0"
11966   [(set_attr "type" "d2mpy_media")
11967    (set_attr "highpart" "depend")])
11968
11969 (define_insn "mulv4hi3"
11970   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11971         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11972                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11973   "TARGET_SHMEDIA"
11974   "mmul.w       %1, %2, %0"
11975   [(set_attr "type" "dmpy_media")
11976    (set_attr "highpart" "depend")])
11977
11978 (define_insn "mmulfx_l"
11979   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11980         (ss_truncate:V2SI
11981          (ashiftrt:V2DI
11982           (mult:V2DI
11983            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11984            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11985           (const_int 31))))]
11986   "TARGET_SHMEDIA"
11987   "mmulfx.l     %1, %2, %0"
11988   [(set_attr "type" "d2mpy_media")
11989    (set_attr "highpart" "depend")])
11990
11991 (define_insn "mmulfx_w"
11992   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11993         (ss_truncate:V4HI
11994          (ashiftrt:V4SI
11995           (mult:V4SI
11996            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11997            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11998           (const_int 15))))]
11999   "TARGET_SHMEDIA"
12000   "mmulfx.w     %1, %2, %0"
12001   [(set_attr "type" "dmpy_media")
12002    (set_attr "highpart" "depend")])
12003
12004 (define_insn "mmulfxrp_w"
12005   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12006         (ss_truncate:V4HI
12007          (ashiftrt:V4SI
12008           (plus:V4SI
12009            (mult:V4SI
12010             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12011             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12012            (const_int 16384))
12013           (const_int 15))))]
12014   "TARGET_SHMEDIA"
12015   "mmulfxrp.w   %1, %2, %0"
12016   [(set_attr "type" "dmpy_media")
12017    (set_attr "highpart" "depend")])
12018
12019
12020 (define_expand "mmulhi_wl"
12021   [(match_operand:V2SI 0 "arith_reg_dest" "")
12022    (match_operand:V4HI 1 "arith_reg_operand" "")
12023    (match_operand:V4HI 2 "arith_reg_operand" "")]
12024   "TARGET_SHMEDIA"
12025   "
12026 {
12027   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12028              (operands[0], operands[1], operands[2]));
12029   DONE;
12030 }")
12031
12032 (define_expand "mmullo_wl"
12033   [(match_operand:V2SI 0 "arith_reg_dest" "")
12034    (match_operand:V4HI 1 "arith_reg_operand" "")
12035    (match_operand:V4HI 2 "arith_reg_operand" "")]
12036   "TARGET_SHMEDIA"
12037   "
12038 {
12039   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12040              (operands[0], operands[1], operands[2]));
12041   DONE;
12042 }")
12043
12044 (define_insn "mmul23_wl"
12045   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12046         (vec_select:V2SI
12047          (mult:V4SI
12048           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12049           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12050          (parallel [(const_int 2) (const_int 3)])))]
12051   "TARGET_SHMEDIA"
12052   "* return (TARGET_LITTLE_ENDIAN
12053              ? \"mmulhi.wl      %1, %2, %0\"
12054              : \"mmullo.wl      %1, %2, %0\");"
12055   [(set_attr "type" "dmpy_media")
12056    (set (attr "highpart")
12057         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12058          (const_string "user")))])
12059
12060 (define_insn "mmul01_wl"
12061   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12062         (vec_select:V2SI
12063          (mult:V4SI
12064           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12065           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12066          (parallel [(const_int 0) (const_int 1)])))]
12067   "TARGET_SHMEDIA"
12068   "* return (TARGET_LITTLE_ENDIAN
12069              ? \"mmullo.wl      %1, %2, %0\"
12070              : \"mmulhi.wl      %1, %2, %0\");"
12071   [(set_attr "type" "dmpy_media")
12072    (set (attr "highpart")
12073         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12074          (const_string "user")))])
12075
12076
12077 (define_expand "mmulsum_wq"
12078   [(match_operand:DI 0 "arith_reg_dest" "")
12079    (match_operand:V4HI 1 "arith_reg_operand" "")
12080    (match_operand:V4HI 2 "arith_reg_operand" "")
12081    (match_operand:DI 3 "arith_reg_operand" "")]
12082   "TARGET_SHMEDIA"
12083   "
12084 {
12085   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12086                                operands[1], operands[2]));
12087   DONE;
12088 }")
12089
12090 (define_insn "mmulsum_wq_i"
12091   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12092         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12093          (plus:DI
12094           (plus:DI
12095            (vec_select:DI
12096             (mult:V4DI
12097              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12098              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12099             (parallel [(const_int 0)]))
12100            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12101                                      (sign_extend:V4DI (match_dup 3)))
12102                           (parallel [(const_int 1)])))
12103           (plus:DI
12104            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12105                                      (sign_extend:V4DI (match_dup 3)))
12106                           (parallel [(const_int 2)]))
12107            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12108                                      (sign_extend:V4DI (match_dup 3)))
12109                           (parallel [(const_int 3)]))))))]
12110   "TARGET_SHMEDIA"
12111   "mmulsum.wq   %2, %3, %0"
12112   [(set_attr "type" "mac_media")])
12113
12114 (define_expand "mperm_w"
12115   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12116    (match_operand:V4HI 1 "arith_reg_operand" "r")
12117    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12118   "TARGET_SHMEDIA"
12119   "
12120 {
12121   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12122              (operands[0], operands[1], operands[2]));
12123   DONE;
12124 }")
12125
12126 ; This use of vec_select isn't exactly correct according to rtl.texi
12127 ; (because not constant), but it seems a straightforward extension.
12128 (define_insn "mperm_w_little"
12129   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12130         (vec_select:V4HI
12131          (match_operand:V4HI 1 "arith_reg_operand" "r")
12132          (parallel
12133           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12134                             (const_int 2) (const_int 0))
12135            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12136            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12137            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12138   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12139   "mperm.w      %1, %N2, %0"
12140   [(set_attr "type" "arith_media")])
12141
12142 (define_insn "mperm_w_big"
12143   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12144         (vec_select:V4HI
12145          (match_operand:V4HI 1 "arith_reg_operand" "r")
12146          (parallel
12147           [(zero_extract:QI (not:QI (match_operand:QI 2
12148                                      "extend_reg_or_0_operand" "rZ"))
12149                             (const_int 2) (const_int 0))
12150            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12151            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12152            (zero_extract:QI (not:QI (match_dup 2))
12153                             (const_int 2) (const_int 6))])))]
12154   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12155   "mperm.w      %1, %N2, %0"
12156   [(set_attr "type" "arith_media")])
12157
12158 (define_insn "mperm_w0"
12159   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12160         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12161                                           "trunc_hi_operand" "r"))))]
12162   "TARGET_SHMEDIA"
12163   "mperm.w      %1, r63, %0"
12164   [(set_attr "type" "arith_media")
12165    (set_attr "highpart" "ignore")])
12166
12167 (define_expand "msad_ubq"
12168   [(match_operand:DI 0 "arith_reg_dest" "")
12169    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12170    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12171    (match_operand:DI 3 "arith_reg_operand" "")]
12172   "TARGET_SHMEDIA"
12173   "
12174 {
12175   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12176                              operands[1], operands[2]));
12177   DONE;
12178 }")
12179
12180 (define_insn "msad_ubq_i"
12181   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12182         (plus:DI
12183          (plus:DI
12184           (plus:DI
12185            (plus:DI
12186             (match_operand:DI 1 "arith_reg_operand" "0")
12187             (abs:DI (vec_select:DI
12188                      (minus:V8DI
12189                       (zero_extend:V8DI
12190                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12191                       (zero_extend:V8DI
12192                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12193                      (parallel [(const_int 0)]))))
12194            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12195                                               (zero_extend:V8DI (match_dup 3)))
12196                                   (parallel [(const_int 1)]))))
12197           (plus:DI
12198            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12199                                               (zero_extend:V8DI (match_dup 3)))
12200                                   (parallel [(const_int 2)])))
12201            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12202                                               (zero_extend:V8DI (match_dup 3)))
12203                                   (parallel [(const_int 3)])))))
12204          (plus:DI
12205           (plus:DI
12206            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12207                                               (zero_extend:V8DI (match_dup 3)))
12208                                   (parallel [(const_int 4)])))
12209            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12210                                               (zero_extend:V8DI (match_dup 3)))
12211                                   (parallel [(const_int 5)]))))
12212           (plus:DI
12213            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12214                                               (zero_extend:V8DI (match_dup 3)))
12215                                   (parallel [(const_int 6)])))
12216            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12217                                               (zero_extend:V8DI (match_dup 3)))
12218                                   (parallel [(const_int 7)])))))))]
12219   "TARGET_SHMEDIA"
12220   "msad.ubq     %N2, %N3, %0"
12221   [(set_attr "type" "mac_media")])
12222
12223 (define_insn "mshalds_l"
12224   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12225         (ss_truncate:V2SI
12226          (ashift:V2DI
12227           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12228           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12229                   (const_int 31)))))]
12230   "TARGET_SHMEDIA"
12231   "mshalds.l    %1, %2, %0"
12232   [(set_attr "type" "mcmp_media")
12233    (set_attr "highpart" "depend")])
12234
12235 (define_insn "mshalds_w"
12236   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12237         (ss_truncate:V4HI
12238          (ashift:V4SI
12239           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12240           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12241                   (const_int 15)))))]
12242   "TARGET_SHMEDIA"
12243   "mshalds.w    %1, %2, %0"
12244   [(set_attr "type" "mcmp_media")
12245    (set_attr "highpart" "depend")])
12246
12247 (define_insn "ashrv2si3"
12248   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12249         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12250                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12251   "TARGET_SHMEDIA"
12252   "mshard.l     %1, %2, %0"
12253   [(set_attr "type" "arith_media")
12254    (set_attr "highpart" "depend")])
12255
12256 (define_insn "ashrv4hi3"
12257   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12258         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12259                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12260   "TARGET_SHMEDIA"
12261   "mshard.w     %1, %2, %0"
12262   [(set_attr "type" "arith_media")
12263    (set_attr "highpart" "depend")])
12264
12265 (define_insn "mshards_q"
12266   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12267         (ss_truncate:HI
12268          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12269                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12270   "TARGET_SHMEDIA"
12271   "mshards.q    %1, %N2, %0"
12272   [(set_attr "type" "mcmp_media")])
12273
12274 (define_expand "mshfhi_b"
12275   [(match_operand:V8QI 0 "arith_reg_dest" "")
12276    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12277    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12278   "TARGET_SHMEDIA"
12279   "
12280 {
12281   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12282              (operands[0], operands[1], operands[2]));
12283   DONE;
12284 }")
12285
12286 (define_expand "mshflo_b"
12287   [(match_operand:V8QI 0 "arith_reg_dest" "")
12288    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12289    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12290   "TARGET_SHMEDIA"
12291   "
12292 {
12293   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12294              (operands[0], operands[1], operands[2]));
12295   DONE;
12296 }")
12297
12298 (define_insn "mshf4_b"
12299   [(set
12300     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12301     (vec_select:V8QI
12302      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12303                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12304      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12305                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12306   "TARGET_SHMEDIA"
12307   "* return (TARGET_LITTLE_ENDIAN
12308              ? \"mshfhi.b       %N1, %N2, %0\"
12309              : \"mshflo.b       %N1, %N2, %0\");"
12310   [(set_attr "type" "arith_media")
12311    (set (attr "highpart")
12312         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12313          (const_string "user")))])
12314
12315 (define_insn "mshf0_b"
12316   [(set
12317     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12318     (vec_select:V8QI
12319      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12320                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12321      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12322                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12323   "TARGET_SHMEDIA"
12324   "* return (TARGET_LITTLE_ENDIAN
12325              ? \"mshflo.b       %N1, %N2, %0\"
12326              : \"mshfhi.b       %N1, %N2, %0\");"
12327   [(set_attr "type" "arith_media")
12328    (set (attr "highpart")
12329         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12330          (const_string "user")))])
12331
12332 (define_expand "mshfhi_l"
12333   [(match_operand:V2SI 0 "arith_reg_dest" "")
12334    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12335    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12336   "TARGET_SHMEDIA"
12337   "
12338 {
12339   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12340              (operands[0], operands[1], operands[2]));
12341   DONE;
12342 }")
12343
12344 (define_expand "mshflo_l"
12345   [(match_operand:V2SI 0 "arith_reg_dest" "")
12346    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12347    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12348   "TARGET_SHMEDIA"
12349   "
12350 {
12351   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12352              (operands[0], operands[1], operands[2]));
12353   DONE;
12354 }")
12355
12356 (define_insn "mshf4_l"
12357   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12358         (vec_select:V2SI
12359          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12360                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12361          (parallel [(const_int 1) (const_int 3)])))]
12362   "TARGET_SHMEDIA"
12363   "* return (TARGET_LITTLE_ENDIAN
12364              ? \"mshfhi.l       %N1, %N2, %0\"
12365              : \"mshflo.l       %N1, %N2, %0\");"
12366   [(set_attr "type" "arith_media")
12367    (set (attr "highpart")
12368         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12369          (const_string "user")))])
12370
12371 (define_insn "mshf0_l"
12372   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12373         (vec_select:V2SI
12374          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12375                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12376          (parallel [(const_int 0) (const_int 2)])))]
12377   "TARGET_SHMEDIA"
12378   "* return (TARGET_LITTLE_ENDIAN
12379              ? \"mshflo.l       %N1, %N2, %0\"
12380              : \"mshfhi.l       %N1, %N2, %0\");"
12381   [(set_attr "type" "arith_media")
12382    (set (attr "highpart")
12383         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12384          (const_string "user")))])
12385
12386 (define_expand "mshfhi_w"
12387   [(match_operand:V4HI 0 "arith_reg_dest" "")
12388    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12389    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12390   "TARGET_SHMEDIA"
12391   "
12392 {
12393   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12394              (operands[0], operands[1], operands[2]));
12395   DONE;
12396 }")
12397
12398 (define_expand "mshflo_w"
12399   [(match_operand:V4HI 0 "arith_reg_dest" "")
12400    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12401    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12402   "TARGET_SHMEDIA"
12403   "
12404 {
12405   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12406              (operands[0], operands[1], operands[2]));
12407   DONE;
12408 }")
12409
12410 (define_insn "mshf4_w"
12411   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12412         (vec_select:V4HI
12413          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12414                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12415          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12416   "TARGET_SHMEDIA"
12417   "* return (TARGET_LITTLE_ENDIAN
12418              ? \"mshfhi.w       %N1, %N2, %0\"
12419              : \"mshflo.w       %N1, %N2, %0\");"
12420   [(set_attr "type" "arith_media")
12421    (set (attr "highpart")
12422         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12423          (const_string "user")))])
12424
12425 (define_insn "mshf0_w"
12426   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12427         (vec_select:V4HI
12428          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12429                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12430          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12431   "TARGET_SHMEDIA"
12432   "* return (TARGET_LITTLE_ENDIAN
12433              ? \"mshflo.w       %N1, %N2, %0\"
12434              : \"mshfhi.w       %N1, %N2, %0\");"
12435   [(set_attr "type" "arith_media")
12436    (set (attr "highpart")
12437         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12438          (const_string "user")))])
12439
12440 (define_insn "mshflo_w_x"
12441   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12442         (vec_select:V4HI
12443          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12444                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12445          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12446   "TARGET_SHMEDIA"
12447   "mshflo.w     %N1, %N2, %0"
12448   [(set_attr "type" "arith_media")
12449    (set_attr "highpart" "ignore")])
12450
12451 /* These are useful to expand ANDs and as combiner patterns.  */
12452 (define_insn_and_split "mshfhi_l_di"
12453   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12454         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12455                              (const_int 32))
12456                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12457                         (const_int -4294967296))))]
12458   "TARGET_SHMEDIA"
12459   "@
12460         mshfhi.l        %N1, %N2, %0
12461         #"
12462   "TARGET_SHMEDIA && reload_completed
12463    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12464   [(set (match_dup 3) (match_dup 4))
12465    (set (match_dup 5) (match_dup 6))]
12466   "
12467 {
12468   operands[3] = gen_lowpart (SImode, operands[0]);
12469   operands[4] = gen_highpart (SImode, operands[1]);
12470   operands[5] = gen_highpart (SImode, operands[0]);
12471   operands[6] = gen_highpart (SImode, operands[2]);
12472 }"
12473   [(set_attr "type" "arith_media")])
12474
12475 (define_insn "*mshfhi_l_di_rev"
12476   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12477         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12478                         (const_int -4294967296))
12479                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12480                              (const_int 32))))]
12481   "TARGET_SHMEDIA"
12482   "mshfhi.l     %N2, %N1, %0"
12483   [(set_attr "type" "arith_media")])
12484
12485 (define_split
12486   [(set (match_operand:DI 0 "arith_reg_dest" "")
12487         (ior:DI (zero_extend:DI (match_operand:SI 1
12488                                               "extend_reg_or_0_operand" ""))
12489                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12490                         (const_int -4294967296))))
12491    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12492   "TARGET_SHMEDIA"
12493   [(const_int 0)]
12494   "
12495 {
12496   emit_insn (gen_ashldi3_media (operands[3],
12497                                 simplify_gen_subreg (DImode, operands[1],
12498                                                      SImode, 0),
12499                                 GEN_INT (32)));
12500   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12501   DONE;
12502 }")
12503
12504 (define_insn "mshflo_l_di"
12505   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12506         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12507                         (const_int 4294967295))
12508                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12509                            (const_int 32))))]
12510
12511   "TARGET_SHMEDIA"
12512   "mshflo.l     %N1, %N2, %0"
12513   [(set_attr "type" "arith_media")
12514    (set_attr "highpart" "ignore")])
12515
12516 (define_insn "*mshflo_l_di_rev"
12517   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12518         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12519                            (const_int 32))
12520                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12521                         (const_int 4294967295))))]
12522
12523   "TARGET_SHMEDIA"
12524   "mshflo.l     %N2, %N1, %0"
12525   [(set_attr "type" "arith_media")
12526    (set_attr "highpart" "ignore")])
12527
12528 ;; Combiner pattern for trampoline initialization.
12529 (define_insn_and_split "*double_shori"
12530   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12531         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12532                            (const_int 32))
12533                 (match_operand:DI 2 "const_int_operand" "n")))]
12534   "TARGET_SHMEDIA
12535    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12536   "#"
12537   "rtx_equal_p (operands[0], operands[1])"
12538   [(const_int 0)]
12539   "
12540 {
12541   HOST_WIDE_INT v = INTVAL (operands[2]);
12542
12543   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12544   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12545   DONE;
12546 }"
12547   [(set_attr "highpart" "ignore")])
12548
12549
12550 (define_insn "*mshflo_l_di_x"
12551   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12552         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12553                                  "rZ"))
12554                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12555                            (const_int 32))))]
12556
12557   "TARGET_SHMEDIA"
12558   "mshflo.l     %N1, %N2, %0"
12559   [(set_attr "type" "arith_media")
12560    (set_attr "highpart" "ignore")])
12561
12562 (define_insn_and_split "concat_v2sf"
12563   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12564 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12565         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12566                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12567
12568   "TARGET_SHMEDIA"
12569   "@
12570         mshflo.l        %N1, %N2, %0
12571         #
12572         #"
12573   "TARGET_SHMEDIA && reload_completed
12574    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12575   [(set (match_dup 3) (match_dup 1))
12576    (set (match_dup 4) (match_dup 2))]
12577   "
12578 {
12579   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12580   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12581 }"
12582   [(set_attr "type" "arith_media")
12583    (set_attr "highpart" "ignore")])
12584
12585 (define_insn "*mshflo_l_di_x_rev"
12586   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12587         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12588                            (const_int 32))
12589                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12590
12591   "TARGET_SHMEDIA"
12592   "mshflo.l     %N2, %N1, %0"
12593   [(set_attr "type" "arith_media")
12594    (set_attr "highpart" "ignore")])
12595
12596 (define_insn "ashlv2si3"
12597   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12598         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12599                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12600   "TARGET_SHMEDIA"
12601   "mshlld.l     %1, %2, %0"
12602   [(set_attr "type" "arith_media")
12603    (set_attr "highpart" "depend")])
12604
12605 (define_split
12606   [(set (match_operand 0 "any_register_operand" "")
12607         (match_operator 3 "shift_operator"
12608           [(match_operand 1 "any_register_operand" "")
12609            (match_operand 2 "shift_count_reg_operand" "")]))]
12610   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12611   [(set (match_dup 0) (match_dup 3))]
12612   "
12613 {
12614   rtx count = operands[2];
12615   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12616
12617   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12618          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12619          || GET_CODE (count) == TRUNCATE)
12620     count = XEXP (count, 0);
12621   inner_mode = GET_MODE (count);
12622   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12623                                subreg_lowpart_offset (outer_mode, inner_mode));
12624   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12625                                 operands[1], count);
12626 }")
12627
12628 (define_insn "ashlv4hi3"
12629   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12630         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12631                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12632   "TARGET_SHMEDIA"
12633   "mshlld.w     %1, %2, %0"
12634   [(set_attr "type" "arith_media")
12635    (set_attr "highpart" "depend")])
12636
12637 (define_insn "lshrv2si3"
12638   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12639         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12640                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12641   "TARGET_SHMEDIA"
12642   "mshlrd.l     %1, %2, %0"
12643   [(set_attr "type" "arith_media")
12644    (set_attr "highpart" "depend")])
12645
12646 (define_insn "lshrv4hi3"
12647   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12648         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12649                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12650   "TARGET_SHMEDIA"
12651   "mshlrd.w     %1, %2, %0"
12652   [(set_attr "type" "arith_media")
12653    (set_attr "highpart" "depend")])
12654
12655 (define_insn "subv2si3"
12656   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12657         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12658                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12659   "TARGET_SHMEDIA"
12660   "msub.l       %N1, %2, %0"
12661   [(set_attr "type" "arith_media")
12662    (set_attr "highpart" "depend")])
12663
12664 (define_insn "subv4hi3"
12665   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12666         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12667                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12668   "TARGET_SHMEDIA"
12669   "msub.w       %N1, %2, %0"
12670   [(set_attr "type" "arith_media")
12671    (set_attr "highpart" "depend")])
12672
12673 (define_insn_and_split "subv2hi3"
12674   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12675         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12676                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12677   "TARGET_SHMEDIA"
12678   "#"
12679   "TARGET_SHMEDIA"
12680   [(const_int 0)]
12681   "
12682 {
12683   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12684   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12685   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12686   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12687   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12688
12689   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12690   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12691   DONE;
12692 }"
12693   [(set_attr "highpart" "must_split")])
12694
12695 (define_insn "sssubv2si3"
12696   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12697         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12698                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12699   "TARGET_SHMEDIA"
12700   "msubs.l      %N1, %2, %0"
12701   [(set_attr "type" "mcmp_media")
12702    (set_attr "highpart" "depend")])
12703
12704 (define_insn "ussubv8qi3"
12705   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12706         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12707                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12708   "TARGET_SHMEDIA"
12709   "msubs.ub     %N1, %2, %0"
12710   [(set_attr "type" "mcmp_media")
12711    (set_attr "highpart" "depend")])
12712
12713 (define_insn "sssubv4hi3"
12714   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12715         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12716                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12717   "TARGET_SHMEDIA"
12718   "msubs.w      %N1, %2, %0"
12719   [(set_attr "type" "mcmp_media")
12720    (set_attr "highpart" "depend")])
12721
12722 ;; Floating Point Intrinsics
12723
12724 (define_insn "fcosa_s"
12725   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12726         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12727                    UNSPEC_FCOSA))]
12728   "TARGET_SHMEDIA"
12729   "fcosa.s      %1, %0"
12730   [(set_attr "type" "atrans_media")])
12731
12732 (define_insn "fsina_s"
12733   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12734         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12735                    UNSPEC_FSINA))]
12736   "TARGET_SHMEDIA"
12737   "fsina.s      %1, %0"
12738   [(set_attr "type" "atrans_media")])
12739
12740 (define_insn "fipr"
12741   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12742         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12743                                                     "fp_arith_reg_operand" "f")
12744                                                    (match_operand:V4SF 2
12745                                                     "fp_arith_reg_operand" "f"))
12746                                          (parallel [(const_int 0)]))
12747                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12748                                          (parallel [(const_int 1)])))
12749                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12750                                          (parallel [(const_int 2)]))
12751                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12752                                          (parallel [(const_int 3)])))))]
12753   "TARGET_SHMEDIA"
12754   "fipr.s       %1, %2, %0"
12755   [(set_attr "type" "fparith_media")])
12756
12757 (define_insn "fsrra_s"
12758   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12759         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12760                    UNSPEC_FSRRA))]
12761   "TARGET_SHMEDIA"
12762   "fsrra.s      %1, %0"
12763   [(set_attr "type" "atrans_media")])
12764
12765 (define_insn "ftrv"
12766   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12767         (plus:V4SF
12768          (plus:V4SF
12769           (mult:V4SF
12770            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12771                             (parallel [(const_int 0) (const_int 5)
12772                                        (const_int 10) (const_int 15)]))
12773            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12774           (mult:V4SF
12775            (vec_select:V4SF (match_dup 1)
12776                             (parallel [(const_int 4) (const_int 9)
12777                                        (const_int 14) (const_int 3)]))
12778            (vec_select:V4SF (match_dup 2)
12779                             (parallel [(const_int 1) (const_int 2)
12780                                        (const_int 3) (const_int 0)]))))
12781          (plus:V4SF
12782           (mult:V4SF
12783            (vec_select:V4SF (match_dup 1)
12784                             (parallel [(const_int 8) (const_int 13)
12785                                        (const_int 2) (const_int 7)]))
12786            (vec_select:V4SF (match_dup 2)
12787                             (parallel [(const_int 2) (const_int 3)
12788                                        (const_int 0) (const_int 1)])))
12789           (mult:V4SF
12790            (vec_select:V4SF (match_dup 1)
12791                             (parallel [(const_int 12) (const_int 1)
12792                                        (const_int 6) (const_int 11)]))
12793            (vec_select:V4SF (match_dup 2)
12794                             (parallel [(const_int 3) (const_int 0)
12795                                        (const_int 1) (const_int 2)]))))))]
12796   "TARGET_SHMEDIA"
12797   "ftrv.s %1, %2, %0"
12798   [(set_attr "type" "fparith_media")])
12799
12800 (define_insn "ldhi_l"
12801   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12802         (zero_extract:SI
12803          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12804                                   (const_int 3))
12805                           (const_int -3)))
12806          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12807          (const_int 0)))]
12808   "TARGET_SHMEDIA32"
12809   "ldhi.l       %U1, %0"
12810   [(set_attr "type" "load_media")])
12811
12812 (define_insn "ldhi_q"
12813   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12814         (zero_extract:DI
12815          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12816                                   (const_int 7))
12817                           (const_int -7)))
12818          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12819          (const_int 0)))]
12820   "TARGET_SHMEDIA32"
12821   "ldhi.q       %U1, %0"
12822   [(set_attr "type" "load_media")])
12823
12824 (define_insn_and_split "*ldhi_q_comb0"
12825   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12826         (zero_extract:DI
12827          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12828                                             "register_operand" "r")
12829                                            (match_operand:SI 2
12830                                             "ua_offset" "I06"))
12831                                   (const_int 7))
12832                           (const_int -7)))
12833          (plus:SI (and:SI (match_dup 1) (const_int 7))
12834                   (const_int 1))
12835          (const_int 0)))]
12836   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12837   "#"
12838   ""
12839   [(pc)]
12840   "emit_insn (gen_ldhi_q (operands[0],
12841                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12842    DONE;")
12843
12844
12845 (define_insn_and_split "*ldhi_q_comb1"
12846   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12847         (zero_extract:DI
12848          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12849                                             "register_operand" "r")
12850                                            (match_operand:SI 2
12851                                             "ua_offset" "I06"))
12852                                   (const_int 7))
12853                           (const_int -7)))
12854          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12855                                                    "ua_offset" "I06"))
12856                           (const_int 7))
12857                   (const_int 1))
12858          (const_int 0)))]
12859   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12860    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12861   "#"
12862   ""
12863   [(pc)]
12864   "emit_insn (gen_ldhi_q (operands[0],
12865                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12866    DONE;")
12867
12868
12869 (define_insn "ldlo_l"
12870   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12871         (zero_extract:SI
12872          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12873                          (const_int -4)))
12874          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12875          (and:SI (match_dup 1) (const_int 3))))]
12876   "TARGET_SHMEDIA32"
12877   "ldlo.l       %U1, %0"
12878   [(set_attr "type" "load_media")])
12879
12880 (define_insn "ldlo_q"
12881   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12882         (zero_extract:DI
12883          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12884                          (const_int -8)))
12885          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12886          (and:SI (match_dup 1) (const_int 7))))]
12887   "TARGET_SHMEDIA32"
12888   "ldlo.q       %U1, %0"
12889   [(set_attr "type" "load_media")])
12890
12891 (define_insn_and_split "*ldlo_q_comb0"
12892   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12893         (zero_extract:DI
12894          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12895                                   (match_operand:SI 2 "ua_offset" "I06"))
12896                          (const_int -8)))
12897          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12898          (and:SI (match_dup 1) (const_int 7))))]
12899   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12900   "#"
12901   ""
12902   [(pc)]
12903   "emit_insn (gen_ldlo_q (operands[0],
12904                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12905    DONE;")
12906
12907 (define_insn_and_split "*ldlo_q_comb1"
12908   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12909         (zero_extract:DI
12910          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12911                                   (match_operand:SI 2 "ua_offset" "I06"))
12912                          (const_int -8)))
12913          (minus:SI (const_int 8)
12914                    (and:SI (plus:SI (match_dup 1)
12915                                     (match_operand:SI 3 "ua_offset" "I06"))
12916                            (const_int 7)))
12917          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12918   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12919    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12920   "#"
12921   ""
12922   [(pc)]
12923   "emit_insn (gen_ldlo_q (operands[0],
12924                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12925    DONE;")
12926
12927 (define_insn "sthi_l"
12928   [(set (zero_extract:SI
12929          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12930                                   (const_int 3))
12931                           (const_int -3)))
12932          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12933          (const_int 0))
12934         (match_operand:SI 1 "arith_reg_operand" "r"))]
12935   "TARGET_SHMEDIA32"
12936   "sthi.l       %U0, %1"
12937   [(set_attr "type" "ustore_media")])
12938
12939 ;; All unaligned stores are considered to be 'narrow' because they typically
12940 ;; operate on less that a quadword, and when they operate on a full quadword,
12941 ;; the vanilla store high / store low sequence will cause a stall if not
12942 ;; scheduled apart.
12943 (define_insn "sthi_q"
12944   [(set (zero_extract:DI
12945          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12946                                   (const_int 7))
12947                           (const_int -7)))
12948          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12949          (const_int 0))
12950         (match_operand:DI 1 "arith_reg_operand" "r"))]
12951   "TARGET_SHMEDIA32"
12952   "sthi.q       %U0, %1"
12953   [(set_attr "type" "ustore_media")])
12954
12955 (define_insn_and_split "*sthi_q_comb0"
12956   [(set (zero_extract:DI
12957          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12958                                             "register_operand" "r")
12959                                            (match_operand:SI 1 "ua_offset"
12960                                             "I06"))
12961                                   (const_int 7))
12962                           (const_int -7)))
12963          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12964          (const_int 0))
12965         (match_operand:DI 2 "arith_reg_operand" "r"))]
12966   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12967   "#"
12968   ""
12969   [(pc)]
12970   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12971                           operands[2]));
12972    DONE;")
12973
12974 (define_insn_and_split "*sthi_q_comb1"
12975   [(set (zero_extract:DI
12976          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12977                                             "register_operand" "r")
12978                                            (match_operand:SI 1 "ua_offset"
12979                                             "I06"))
12980                                   (const_int 7))
12981                           (const_int -7)))
12982          (plus:SI (and:SI (plus:SI (match_dup 0)
12983                                    (match_operand:SI 2 "ua_offset" "I06"))
12984                           (const_int 7))
12985                   (const_int 1))
12986          (const_int 0))
12987         (match_operand:DI 3 "arith_reg_operand" "r"))]
12988   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12989    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12990   "#"
12991   ""
12992   [(pc)]
12993   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12994                           operands[3]));
12995    DONE;")
12996
12997 ;; This is highpart user because the address is used as full 64 bit.
12998 (define_insn "stlo_l"
12999   [(set (zero_extract:SI
13000          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13001                          (const_int -4)))
13002          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13003          (and:SI (match_dup 0) (const_int 3)))
13004         (match_operand:SI 1 "arith_reg_operand" "r"))]
13005   "TARGET_SHMEDIA32"
13006   "stlo.l       %U0, %1"
13007   [(set_attr "type" "ustore_media")])
13008
13009 (define_insn "stlo_q"
13010   [(set (zero_extract:DI
13011          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13012                          (const_int -8)))
13013          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13014          (and:SI (match_dup 0) (const_int 7)))
13015         (match_operand:DI 1 "arith_reg_operand" "r"))]
13016   "TARGET_SHMEDIA32"
13017   "stlo.q       %U0, %1"
13018   [(set_attr "type" "ustore_media")])
13019
13020 (define_insn_and_split "*stlo_q_comb0"
13021   [(set (zero_extract:DI
13022          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13023                                   (match_operand:SI 1 "ua_offset" "I06"))
13024                          (const_int -8)))
13025          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13026          (and:SI (match_dup 0) (const_int 7)))
13027         (match_operand:DI 2 "arith_reg_operand" "r"))]
13028   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13029   "#"
13030   ""
13031   [(pc)]
13032   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13033                           operands[2]));
13034    DONE;")
13035
13036 (define_insn_and_split "*stlo_q_comb1"
13037   [(set (zero_extract:DI
13038          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13039                                   (match_operand:SI 1 "ua_offset" "I06"))
13040                          (const_int -8)))
13041          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13042                                                   (match_operand:SI 2
13043                                                    "ua_offset" "I06"))
13044                                          (const_int 7)))
13045          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13046         (match_operand:DI 3 "arith_reg_operand" "r"))]
13047   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13048   "#"
13049   ""
13050   [(pc)]
13051   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13052                           operands[3]));
13053    DONE;")
13054
13055 (define_insn "ldhi_l64"
13056   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13057         (zero_extract:SI
13058          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13059                                   (const_int 3))
13060                           (const_int -3)))
13061          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13062          (const_int 0)))]
13063   "TARGET_SHMEDIA64"
13064   "ldhi.l       %U1, %0"
13065   [(set_attr "type" "load_media")])
13066
13067 (define_insn "ldhi_q64"
13068   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13069         (zero_extract:DI
13070          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13071                                   (const_int 7))
13072                           (const_int -7)))
13073          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13074          (const_int 0)))]
13075   "TARGET_SHMEDIA64"
13076   "ldhi.q       %U1, %0"
13077   [(set_attr "type" "load_media")])
13078
13079 (define_insn "ldlo_l64"
13080   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13081         (zero_extract:SI
13082          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13083                          (const_int -4)))
13084          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13085          (and:DI (match_dup 1) (const_int 3))))]
13086   "TARGET_SHMEDIA64"
13087   "ldlo.l       %U1, %0"
13088   [(set_attr "type" "load_media")])
13089
13090 (define_insn "ldlo_q64"
13091   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13092         (zero_extract:DI
13093          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13094                          (const_int -8)))
13095          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13096          (and:DI (match_dup 1) (const_int 7))))]
13097   "TARGET_SHMEDIA64"
13098   "ldlo.q       %U1, %0"
13099   [(set_attr "type" "load_media")])
13100
13101 (define_insn "sthi_l64"
13102   [(set (zero_extract:SI
13103          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13104                                   (const_int 3))
13105                           (const_int -3)))
13106          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13107          (const_int 0))
13108         (match_operand:SI 1 "arith_reg_operand" "r"))]
13109   "TARGET_SHMEDIA64"
13110   "sthi.l       %U0, %1"
13111   [(set_attr "type" "ustore_media")])
13112
13113 (define_insn "sthi_q64"
13114   [(set (zero_extract:DI
13115          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13116                                   (const_int 7))
13117                           (const_int -7)))
13118          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13119          (const_int 0))
13120         (match_operand:DI 1 "arith_reg_operand" "r"))]
13121   "TARGET_SHMEDIA64"
13122   "sthi.q       %U0, %1"
13123   [(set_attr "type" "ustore_media")])
13124
13125 (define_insn "stlo_l64"
13126   [(set (zero_extract:SI
13127          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13128                          (const_int -4)))
13129          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13130          (and:DI (match_dup 0) (const_int 3)))
13131         (match_operand:SI 1 "arith_reg_operand" "r"))]
13132   "TARGET_SHMEDIA64"
13133   "stlo.l       %U0, %1"
13134   [(set_attr "type" "ustore_media")])
13135
13136 (define_insn "stlo_q64"
13137   [(set (zero_extract:DI
13138          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13139                          (const_int -8)))
13140          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13141          (and:DI (match_dup 0) (const_int 7)))
13142         (match_operand:DI 1 "arith_reg_operand" "r"))]
13143   "TARGET_SHMEDIA64"
13144   "stlo.q       %U0, %1"
13145   [(set_attr "type" "ustore_media")])
13146
13147 (define_insn "nsb"
13148   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13149         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13150                    UNSPEC_NSB))]
13151   "TARGET_SHMEDIA"
13152   "nsb  %1, %0"
13153   [(set_attr "type" "arith_media")])
13154
13155 (define_insn "nsbsi"
13156   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13157         (zero_extend:SI
13158          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13159                     UNSPEC_NSB)))]
13160   "TARGET_SHMEDIA"
13161   "nsb  %1, %0"
13162   [(set_attr "type" "arith_media")])
13163
13164 (define_insn "nsbdi"
13165   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13166         (zero_extend:DI
13167          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13168                     UNSPEC_NSB)))]
13169   "TARGET_SHMEDIA"
13170   "nsb  %1, %0"
13171   [(set_attr "type" "arith_media")])
13172
13173 (define_expand "ffsdi2"
13174   [(set (match_operand:DI 0 "arith_reg_dest" "")
13175         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13176   "TARGET_SHMEDIA"
13177   "
13178 {
13179   rtx scratch = gen_reg_rtx (DImode);
13180   rtx last;
13181
13182   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13183   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13184   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13185   emit_insn (gen_nsbdi (scratch, scratch));
13186   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13187   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13188   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13189   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13190
13191   DONE;
13192 }")
13193
13194 (define_expand "ffssi2"
13195   [(set (match_operand:SI 0 "arith_reg_dest" "")
13196         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13197   "TARGET_SHMEDIA"
13198   "
13199 {
13200   rtx scratch = gen_reg_rtx (SImode);
13201   rtx discratch = gen_reg_rtx (DImode);
13202   rtx last;
13203
13204   emit_insn (gen_adddi3 (discratch,
13205                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13206                          constm1_rtx));
13207   emit_insn (gen_andcdi3 (discratch,
13208                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13209                           discratch));
13210   emit_insn (gen_nsbsi (scratch, discratch));
13211   last = emit_insn (gen_subsi3 (operands[0],
13212                                 force_reg (SImode, GEN_INT (63)), scratch));
13213   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13214
13215   DONE;
13216 }")
13217
13218 (define_insn "byterev"
13219   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13220         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13221                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13222                                     (const_int 4) (const_int 3) (const_int 2)
13223                                     (const_int 1) (const_int 0)])))]
13224   "TARGET_SHMEDIA"
13225   "byterev      %1, %0"
13226   [(set_attr "type" "arith_media")])
13227
13228 (define_insn "*prefetch_media"
13229   [(prefetch (match_operand:QI 0 "address_operand" "p")
13230              (match_operand:SI 1 "const_int_operand" "n")
13231              (match_operand:SI 2 "const_int_operand" "n"))]
13232   "TARGET_SHMEDIA"
13233   "*
13234 {
13235   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13236   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13237   return \"\";
13238 }"
13239   [(set_attr "type" "other")])
13240
13241 (define_insn "*prefetch_i4"
13242   [(prefetch (match_operand:SI 0 "register_operand" "r")
13243              (match_operand:SI 1 "const_int_operand" "n")
13244              (match_operand:SI 2 "const_int_operand" "n"))]
13245   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13246   "*
13247 {
13248   return \"pref @%0\";
13249 }"
13250   [(set_attr "type" "other")])
13251
13252 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13253 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13254 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13255 (define_expand "prefetch"
13256   [(prefetch (match_operand 0 "address_operand" "p")
13257              (match_operand:SI 1 "const_int_operand" "n")
13258              (match_operand:SI 2 "const_int_operand" "n"))]
13259   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13260    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13261   "
13262 {
13263   if (GET_MODE (operands[0]) != Pmode
13264       || !CONST_INT_P (operands[1])
13265       || !CONST_INT_P (operands[2]))
13266     FAIL;
13267   if (! TARGET_SHMEDIA)
13268     operands[0] = force_reg (Pmode, operands[0]);
13269 }")
13270
13271 (define_insn "prefetch_m2a"
13272   [(prefetch (match_operand:SI 0 "register_operand" "r")
13273              (match_operand:SI 1 "const_int_operand" "n")
13274              (match_operand:SI 2 "const_int_operand" "n"))]
13275   "TARGET_SH2A"
13276   "pref\\t@%0"
13277   [(set_attr "type" "other")])
13278
13279 (define_insn "alloco_i"
13280   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13281         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13282   "TARGET_SHMEDIA32"
13283   "*
13284 {
13285   rtx xops[2];
13286
13287   if (GET_CODE (operands[0]) == PLUS)
13288     {
13289       xops[0] = XEXP (operands[0], 0);
13290       xops[1] = XEXP (operands[0], 1);
13291     }
13292   else
13293     {
13294       xops[0] = operands[0];
13295       xops[1] = const0_rtx;
13296     }
13297   output_asm_insn (\"alloco   %0, %1\", xops);
13298   return \"\";
13299 }"
13300   [(set_attr "type" "other")])
13301
13302 (define_split
13303   [(set (match_operand 0 "any_register_operand" "")
13304         (match_operand 1 "" ""))]
13305   "TARGET_SHMEDIA && reload_completed"
13306   [(set (match_dup 0) (match_dup 1))]
13307   "
13308 {
13309   int n_changes = 0;
13310
13311   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13312   if (!n_changes)
13313     FAIL;
13314 }")
13315
13316 ; Stack Protector Patterns
13317
13318 (define_expand "stack_protect_set"
13319   [(set (match_operand 0 "memory_operand" "")
13320         (match_operand 1 "memory_operand" ""))]
13321   ""
13322 {
13323   if (TARGET_SHMEDIA)
13324     {
13325       if (TARGET_SHMEDIA64)
13326         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13327       else
13328         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13329     }
13330   else
13331     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13332
13333   DONE;
13334 })
13335
13336 (define_insn "stack_protect_set_si"
13337   [(set (match_operand:SI 0 "memory_operand" "=m")
13338         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13339    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13340   "!TARGET_SHMEDIA"
13341   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13342   [(set_attr "type" "other")
13343    (set_attr "length" "6")])
13344
13345 (define_insn "stack_protect_set_si_media"
13346   [(set (match_operand:SI 0 "memory_operand" "=m")
13347         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13348    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13349   "TARGET_SHMEDIA"
13350   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13351   [(set_attr "type" "other")
13352    (set_attr "length" "12")])
13353
13354 (define_insn "stack_protect_set_di_media"
13355   [(set (match_operand:DI 0 "memory_operand" "=m")
13356         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13357    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13358   "TARGET_SHMEDIA64"
13359   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13360   [(set_attr "type" "other")
13361    (set_attr "length" "12")])
13362
13363 (define_expand "stack_protect_test"
13364   [(match_operand 0 "memory_operand" "")
13365    (match_operand 1 "memory_operand" "")
13366    (match_operand 2 "" "")]
13367   ""
13368 {
13369   if (TARGET_SHMEDIA)
13370     {
13371       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13372       rtx test;
13373
13374       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13375       if (TARGET_SHMEDIA64)
13376         {
13377           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13378                                                       operands[1]));
13379           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13380         }
13381       else
13382         {
13383           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13384                                                       operands[1]));
13385           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13386         }
13387     }
13388   else
13389     {
13390       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13391       emit_jump_insn (gen_branch_true (operands[2]));
13392     }
13393
13394   DONE;
13395 })
13396
13397 (define_insn "stack_protect_test_si"
13398   [(set (reg:SI T_REG)
13399         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13400                     (match_operand:SI 1 "memory_operand" "m")]
13401                    UNSPEC_SP_TEST))
13402   (set (match_scratch:SI 2 "=&r") (const_int 0))
13403   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13404   "!TARGET_SHMEDIA"
13405   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13406   [(set_attr "type" "other")
13407    (set_attr "length" "10")])
13408
13409 (define_insn "stack_protect_test_si_media"
13410   [(set (match_operand:SI 0 "register_operand" "=&r")
13411         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13412                     (match_operand:SI 2 "memory_operand" "m")]
13413                    UNSPEC_SP_TEST))
13414   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13415   "TARGET_SHMEDIA"
13416   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13417   [(set_attr "type" "other")
13418    (set_attr "length" "16")])
13419
13420 (define_insn "stack_protect_test_di_media"
13421   [(set (match_operand:DI 0 "register_operand" "=&r")
13422         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13423                     (match_operand:DI 2 "memory_operand" "m")]
13424                    UNSPEC_SP_TEST))
13425   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13426   "TARGET_SHMEDIA64"
13427   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13428   [(set_attr "type" "other")
13429    (set_attr "length" "16")])