OSDN Git Service

* config/sh/sh.md (*movv4sf_i): Add general register cases to
[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 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
23
24
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
27
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
30
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
32
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
35
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
38
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42
43 ;; Special constraints for SH machine description:
44 ;;
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
49 ;;
50 ;; Special formats used for outputting SH instructions:
51 ;;
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
59 ;;
60 ;; Special predicates:
61 ;;
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
67
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
71
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
81
82   (FPSCR_REG    151)
83
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
87
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
90
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
106
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
111
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
115
116   (XD0_REG      136)
117
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
146   (UNSPEC_DIV_INV_M0    30)
147   (UNSPEC_DIV_INV_M1    31)
148   (UNSPEC_DIV_INV_M2    32)
149   (UNSPEC_DIV_INV_M3    33)
150   (UNSPEC_DIV_INV20     34)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153   (UNSPEC_SP_SET        40)
154   (UNSPEC_SP_TEST       41)
155
156   ;; These are used with unspec_volatile.
157   (UNSPECV_BLOCKAGE     0)
158   (UNSPECV_ALIGN        1)
159   (UNSPECV_CONST2       2)
160   (UNSPECV_CONST4       4)
161   (UNSPECV_CONST8       6)
162   (UNSPECV_WINDOW_END   10)
163   (UNSPECV_CONST_END    11)
164 ])
165
166 ;; -------------------------------------------------------------------------
167 ;; Attributes
168 ;; -------------------------------------------------------------------------
169
170 ;; Target CPU.
171
172 (define_attr "cpu"
173  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
174   (const (symbol_ref "sh_cpu_attr")))
175
176 (define_attr "endian" "big,little"
177  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
178                       (const_string "little") (const_string "big"))))
179
180 ;; Indicate if the default fpu mode is single precision.
181 (define_attr "fpu_single" "yes,no"
182   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
183                          (const_string "yes") (const_string "no"))))
184
185 (define_attr "fmovd" "yes,no"
186   (const (if_then_else (symbol_ref "TARGET_FMOVD")
187                        (const_string "yes") (const_string "no"))))
188 ;; pipeline model
189 (define_attr "pipe_model" "sh1,sh4,sh5media"
190   (const
191    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
192           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
193          (const_string "sh1"))))
194
195 ;; cbranch      conditional branch instructions
196 ;; jump         unconditional jumps
197 ;; arith        ordinary arithmetic
198 ;; arith3       a compound insn that behaves similarly to a sequence of
199 ;;              three insns of type arith
200 ;; arith3b      like above, but might end with a redirected branch
201 ;; load         from memory
202 ;; load_si      Likewise, SImode variant for general register.
203 ;; fload        Likewise, but load to fp register.
204 ;; store        to memory
205 ;; move         general purpose register to register
206 ;; mt_group     other sh4 mt instructions
207 ;; fmove        register to register, floating point
208 ;; smpy         word precision integer multiply
209 ;; dmpy         longword or doublelongword precision integer multiply
210 ;; return       rts
211 ;; pload        load of pr reg, which can't be put into delay slot of rts
212 ;; prset        copy register to pr reg, ditto
213 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
214 ;; prget        copy pr to register, ditto
215 ;; pcload       pc relative load of constant value
216 ;; pcfload      Likewise, but load to fp register.
217 ;; pcload_si    Likewise, SImode variant for general register.
218 ;; rte          return from exception
219 ;; sfunc        special function call with known used registers
220 ;; call         function call
221 ;; fp           floating point
222 ;; fdiv         floating point divide (or square root)
223 ;; gp_fpul      move from general purpose register to fpul
224 ;; fpul_gp      move from fpul to general purpose register
225 ;; mac_gp       move from mac[lh] to general purpose register
226 ;; dfp_arith, dfp_cmp,dfp_conv
227 ;; ftrc_s       fix_truncsfsi2_i4
228 ;; dfdiv        double precision floating point divide (or square root)
229 ;; cwb          ic_invalidate_line_i
230 ;; movua        SH4a unaligned load
231 ;; fsrra        square root reciprocal approximate
232 ;; fsca         sine and cosine approximate
233 ;; tls_load     load TLS related address
234 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
235 ;; cbranch_media SHmedia conditional branch instructions
236 ;; cmp_media    SHmedia compare instructions
237 ;; dfdiv_media  SHmedia double precision divide and square root
238 ;; dfmul_media  SHmedia double precision multiply instruction
239 ;; dfparith_media SHmedia double precision floating point arithmetic
240 ;; dfpconv_media SHmedia double precision floating point conversions
241 ;; dmpy_media   SHmedia longword multiply
242 ;; fcmp_media   SHmedia floating point compare instructions
243 ;; fdiv_media   SHmedia single precision divide and square root
244 ;; fload_media  SHmedia floating point register load instructions
245 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
246 ;; fparith_media SHmedia single precision floating point arithmetic
247 ;; fpconv_media SHmedia single precision floating point conversions
248 ;; fstore_media SHmedia floating point register store instructions
249 ;; gettr_media  SHmedia gettr instruction
250 ;; invalidate_line_media SHmedia invalidate_line sequence
251 ;; jump_media   SHmedia unconditional branch instructions
252 ;; load_media   SHmedia general register load instructions
253 ;; pt_media     SHmedia pt instruction (expanded by assembler)
254 ;; ptabs_media  SHmedia ptabs instruction
255 ;; store_media  SHmedia general register store instructions
256 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
257 ;; mac_media    SHmedia mac-style fixed point operations
258 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
259 ;; atrans_media SHmedia approximate transcendental functions
260 ;; ustore_media SHmedia unaligned stores
261 ;; nil          no-op move, will be deleted.
262
263 (define_attr "type"
264  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
265   (const_string "other"))
266
267 ;; We define a new attribute namely "insn_class".We use
268 ;; this for the DFA based pipeline description.
269 ;;
270 ;; mt_group      SH4 "mt" group instructions.
271 ;;
272 ;; ex_group      SH4 "ex" group instructions.
273 ;;
274 ;; ls_group      SH4 "ls" group instructions.
275 ;;
276
277 (define_attr "insn_class"
278   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
279   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
280          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
281          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
282          (eq_attr "type" "cbranch,jump") (const_string "br_group")
283          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
284            (const_string "fe_group")
285          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
286         (const_string "none")))
287 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
288 ;; so these do not belong in an insn group, although they are modeled
289 ;; with their own define_insn_reservations.
290
291 ;; Indicate what precision must be selected in fpscr for this insn, if any.
292
293 (define_attr "fp_mode" "single,double,none" (const_string "none"))
294
295 ;; Indicate if the fpu mode is set by this instruction
296 ;; "unknown" must have the value as "none" in fp_mode, and means
297 ;; that the instruction/abi has left the processor in an unknown
298 ;; state.
299 ;; "none" means that nothing has changed and no mode is set.
300 ;; This attribute is only used for the Renesas ABI.
301 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
302
303 ; If a conditional branch destination is within -252..258 bytes away
304 ; from the instruction it can be 2 bytes long.  Something in the
305 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
306 ; branches are initially assumed to be 16 bytes long.
307 ; In machine_dependent_reorg, we split all branches that are longer than
308 ; 2 bytes.
309
310 ;; The maximum range used for SImode constant pool entries is 1018.  A final
311 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
312 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
313 ;; instruction around the pool table, 2 bytes of alignment before the table,
314 ;; and 30 bytes of alignment after the table.  That gives a maximum total
315 ;; pool size of 1058 bytes.
316 ;; Worst case code/pool content size ratio is 1:2 (using asms).
317 ;; Thus, in the worst case, there is one instruction in front of a maximum
318 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
319 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
320 ;; If we have a forward branch, the initial table will be put after the
321 ;; unconditional branch.
322 ;;
323 ;; ??? We could do much better by keeping track of the actual pcloads within
324 ;; the branch range and in the pcload range in front of the branch range.
325
326 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
327 ;; inside an le.
328 (define_attr "short_cbranch_p" "no,yes"
329   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
330          (const_string "no")
331          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
332          (const_string "yes")
333          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
334          (const_string "no")
335          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
336          (const_string "yes")
337          ] (const_string "no")))
338
339 (define_attr "med_branch_p" "no,yes"
340   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
341               (const_int 1988))
342          (const_string "yes")
343          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
344          (const_string "no")
345          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
346               (const_int 8186))
347          (const_string "yes")
348          ] (const_string "no")))
349
350 (define_attr "med_cbranch_p" "no,yes"
351   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
352               (const_int 1986))
353          (const_string "yes")
354          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
355          (const_string "no")
356          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
357                (const_int 8184))
358          (const_string "yes")
359          ] (const_string "no")))
360
361 (define_attr "braf_branch_p" "no,yes"
362   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
363          (const_string "no")
364          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
365               (const_int 20660))
366          (const_string "yes")
367          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
368          (const_string "no")
369          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
370               (const_int 65530))
371          (const_string "yes")
372          ] (const_string "no")))
373
374 (define_attr "braf_cbranch_p" "no,yes"
375   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
376          (const_string "no")
377          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
378               (const_int 20658))
379          (const_string "yes")
380          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
381          (const_string "no")
382          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
383               (const_int 65528))
384          (const_string "yes")
385          ] (const_string "no")))
386
387 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
388 ; For wider ranges, we need a combination of a code and a data part.
389 ; If we can get a scratch register for a long range jump, the code
390 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
391 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
392 ; long; otherwise, it must be 6 bytes long.
393
394 ; All other instructions are two bytes long by default.
395
396 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
397 ;; but getattrtab doesn't understand this.
398 (define_attr "length" ""
399   (cond [(eq_attr "type" "cbranch")
400          (cond [(eq_attr "short_cbranch_p" "yes")
401                 (const_int 2)
402                 (eq_attr "med_cbranch_p" "yes")
403                 (const_int 6)
404                 (eq_attr "braf_cbranch_p" "yes")
405                 (const_int 12)
406 ;; ??? using pc is not computed transitively.
407                 (ne (match_dup 0) (match_dup 0))
408                 (const_int 14)
409                 (ne (symbol_ref ("flag_pic")) (const_int 0))
410                 (const_int 24)
411                 ] (const_int 16))
412          (eq_attr "type" "jump")
413          (cond [(eq_attr "med_branch_p" "yes")
414                 (const_int 2)
415                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
416                          (symbol_ref "INSN"))
417                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
418                          (symbol_ref "code_for_indirect_jump_scratch")))
419                 (cond [(eq_attr "braf_branch_p" "yes")
420                        (const_int 6)
421                        (eq (symbol_ref "flag_pic") (const_int 0))
422                        (const_int 10)
423                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
424                        (const_int 10)] (const_int 18))
425                 (eq_attr "braf_branch_p" "yes")
426                 (const_int 10)
427 ;; ??? using pc is not computed transitively.
428                 (ne (match_dup 0) (match_dup 0))
429                 (const_int 12)
430                 (ne (symbol_ref ("flag_pic")) (const_int 0))
431                 (const_int 22)
432                 ] (const_int 14))
433          (eq_attr "type" "pt_media")
434          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
435                        (const_int 20) (const_int 12))
436          (and (eq_attr "type" "jump_media")
437               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
438          (const_int 8)
439          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
440                          (const_int 4)
441                          (const_int 2))))
442
443 ;; DFA descriptions for the pipelines
444
445 (include "sh1.md")
446 (include "shmedia.md")
447 (include "sh4.md")
448
449 (include "predicates.md")
450
451 ;; Definitions for filling delay slots
452
453 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
454
455 ;; ??? This should be (nil) instead of (const_int 0)
456 (define_attr "hit_stack" "yes,no"
457         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
458                    (const_int 0))
459                (const_string "no")]
460               (const_string "yes")))
461
462 (define_attr "interrupt_function" "no,yes"
463   (const (symbol_ref "current_function_interrupt")))
464
465 (define_attr "in_delay_slot" "yes,no"
466   (cond [(eq_attr "type" "cbranch") (const_string "no")
467          (eq_attr "type" "pcload,pcload_si") (const_string "no")
468          (eq_attr "needs_delay_slot" "yes") (const_string "no")
469          (eq_attr "length" "2") (const_string "yes")
470          ] (const_string "no")))
471
472 (define_attr "cond_delay_slot" "yes,no"
473   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
474          ] (const_string "no")))
475
476 (define_attr "is_sfunc" ""
477   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
478
479 (define_attr "is_mac_media" ""
480   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
481
482 (define_attr "branch_zero" "yes,no"
483   (cond [(eq_attr "type" "!cbranch") (const_string "no")
484          (ne (symbol_ref "(next_active_insn (insn)\
485                            == (prev_active_insn\
486                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
487                           && get_attr_length (next_active_insn (insn)) == 2")
488              (const_int 0))
489          (const_string "yes")]
490         (const_string "no")))
491
492 ;; SH4 Double-precision computation with double-precision result -
493 ;; the two halves are ready at different times.
494 (define_attr "dfp_comp" "yes,no"
495   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
496         (const_string "no")))
497
498 ;; Insns for which the latency of a preceding fp insn is decreased by one.
499 (define_attr "late_fp_use" "yes,no" (const_string "no"))
500 ;; And feeding insns for which this relevant.
501 (define_attr "any_fp_comp" "yes,no"
502   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
503          (const_string "yes")]
504         (const_string "no")))
505
506 (define_attr "any_int_load" "yes,no"
507   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
508          (const_string "yes")]
509         (const_string "no")))
510
511 (define_attr "highpart" "user, ignore, extend, depend, must_split"
512   (const_string "user"))
513
514 (define_delay
515   (eq_attr "needs_delay_slot" "yes")
516   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
517
518 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
519 ;; and thus we can't put a pop instruction in its delay slot.
520 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
521 ;; instruction can go in the delay slot.
522
523 ;; Since a normal return (rts) implicitly uses the PR register,
524 ;; we can't allow PR register loads in an rts delay slot.
525
526 (define_delay
527   (eq_attr "type" "return")
528   [(and (eq_attr "in_delay_slot" "yes")
529         (ior (and (eq_attr "interrupt_function" "no")
530                   (eq_attr "type" "!pload,prset"))
531              (and (eq_attr "interrupt_function" "yes")
532                   (ior
533                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
534                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
535
536 ;; Since a call implicitly uses the PR register, we can't allow
537 ;; a PR register store in a jsr delay slot.
538
539 (define_delay
540   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
541   [(and (eq_attr "in_delay_slot" "yes")
542         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
543
544 ;; Say that we have annulled true branches, since this gives smaller and
545 ;; faster code when branches are predicted as not taken.
546
547 ;; ??? The non-annulled condition should really be "in_delay_slot",
548 ;; but insns that can be filled in non-annulled get priority over insns
549 ;; that can only be filled in anulled.
550
551 (define_delay
552   (and (eq_attr "type" "cbranch")
553        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
554   ;; SH2e has a hardware bug that pretty much prohibits the use of
555   ;; annuled delay slots.
556   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
557                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
558 \f
559 ;; -------------------------------------------------------------------------
560 ;; SImode signed integer comparisons
561 ;; -------------------------------------------------------------------------
562
563 (define_insn ""
564   [(set (reg:SI T_REG)
565         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
566                        (match_operand:SI 1 "arith_operand" "K08,r"))
567                (const_int 0)))]
568   "TARGET_SH1"
569   "tst  %1,%0"
570   [(set_attr "type" "mt_group")])
571
572 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
573 ;; That would still allow reload to create cmpi instructions, but would
574 ;; perhaps allow forcing the constant into a register when that is better.
575 ;; Probably should use r0 for mem/imm compares, but force constant into a
576 ;; register for pseudo/imm compares.
577
578 (define_insn "cmpeqsi_t"
579   [(set (reg:SI T_REG)
580         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
581                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
582   "TARGET_SH1"
583   "@
584         tst     %0,%0
585         cmp/eq  %1,%0
586         cmp/eq  %1,%0"
587    [(set_attr "type" "mt_group")])
588
589 (define_insn "cmpgtsi_t"
590   [(set (reg:SI T_REG)
591         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
592                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
593   "TARGET_SH1"
594   "@
595         cmp/gt  %1,%0
596         cmp/pl  %0"
597    [(set_attr "type" "mt_group")])
598
599 (define_insn "cmpgesi_t"
600   [(set (reg:SI T_REG)
601         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
602                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
603   "TARGET_SH1"
604   "@
605         cmp/ge  %1,%0
606         cmp/pz  %0"
607    [(set_attr "type" "mt_group")])
608
609 ;; -------------------------------------------------------------------------
610 ;; SImode unsigned integer comparisons
611 ;; -------------------------------------------------------------------------
612
613 (define_insn "cmpgeusi_t"
614   [(set (reg:SI T_REG)
615         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
616                 (match_operand:SI 1 "arith_reg_operand" "r")))]
617   "TARGET_SH1"
618   "cmp/hs       %1,%0"
619    [(set_attr "type" "mt_group")])
620
621 (define_insn "cmpgtusi_t"
622   [(set (reg:SI T_REG)
623         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
624                 (match_operand:SI 1 "arith_reg_operand" "r")))]
625   "TARGET_SH1"
626   "cmp/hi       %1,%0"
627    [(set_attr "type" "mt_group")])
628
629 ;; We save the compare operands in the cmpxx patterns and use them when
630 ;; we generate the branch.
631
632 (define_expand "cmpsi"
633   [(set (reg:SI T_REG)
634         (compare (match_operand:SI 0 "cmpsi_operand" "")
635                  (match_operand:SI 1 "arith_operand" "")))]
636   "TARGET_SH1 || TARGET_SHMEDIA"
637   "
638 {
639   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
640       && GET_CODE (operands[1]) != CONST_INT)
641     operands[0] = copy_to_mode_reg (SImode, operands[0]);
642   sh_compare_op0 = operands[0];
643   sh_compare_op1 = operands[1];
644   DONE;
645 }")
646 \f
647 ;; -------------------------------------------------------------------------
648 ;; DImode signed integer comparisons
649 ;; -------------------------------------------------------------------------
650
651 ;; ??? Could get better scheduling by splitting the initial test from the
652 ;; rest of the insn after reload.  However, the gain would hardly justify
653 ;; the sh.md size increase necessary to do that.
654
655 (define_insn ""
656   [(set (reg:SI T_REG)
657         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
658                        (match_operand:DI 1 "arith_operand" "r"))
659                (const_int 0)))]
660   "TARGET_SH1"
661   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
662                                  insn, operands);"
663   [(set_attr "length" "6")
664    (set_attr "type" "arith3b")])
665
666 (define_insn "cmpeqdi_t"
667   [(set (reg:SI T_REG)
668         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
669                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
670   "TARGET_SH1"
671   "@
672         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
673         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
674   [(set_attr "length" "6")
675    (set_attr "type" "arith3b")])
676
677 (define_split
678   [(set (reg:SI T_REG)
679         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
680                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
681 ;; If we applied this split when not optimizing, it would only be
682 ;; applied during the machine-dependent reorg, when no new basic blocks
683 ;; may be created.
684   "TARGET_SH1 && reload_completed && optimize"
685   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
686    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
687                            (label_ref (match_dup 6))
688                            (pc)))
689    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
690    (match_dup 6)]
691   "
692 {
693   operands[2]
694     = gen_rtx_REG (SImode,
695                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
696   operands[3]
697     = (operands[1] == const0_rtx
698        ? const0_rtx
699        : gen_rtx_REG (SImode,
700                       true_regnum (operands[1])
701                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
702   operands[4] = gen_lowpart (SImode, operands[0]);
703   operands[5] = gen_lowpart (SImode, operands[1]);
704   operands[6] = gen_label_rtx ();
705 }")
706
707 (define_insn "cmpgtdi_t"
708   [(set (reg:SI T_REG)
709         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
710                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
711   "TARGET_SH2"
712   "@
713         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
714         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
715   [(set_attr "length" "8")
716    (set_attr "type" "arith3")])
717
718 (define_insn "cmpgedi_t"
719   [(set (reg:SI T_REG)
720         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
722   "TARGET_SH2"
723   "@
724         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
725         cmp/pz\\t%S0"
726   [(set_attr "length" "8,2")
727    (set_attr "type" "arith3,mt_group")])
728 \f
729 ;; -------------------------------------------------------------------------
730 ;; DImode unsigned integer comparisons
731 ;; -------------------------------------------------------------------------
732
733 (define_insn "cmpgeudi_t"
734   [(set (reg:SI T_REG)
735         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
736                 (match_operand:DI 1 "arith_reg_operand" "r")))]
737   "TARGET_SH2"
738   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
739   [(set_attr "length" "8")
740    (set_attr "type" "arith3")])
741
742 (define_insn "cmpgtudi_t"
743   [(set (reg:SI T_REG)
744         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
745                 (match_operand:DI 1 "arith_reg_operand" "r")))]
746   "TARGET_SH2"
747   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
748   [(set_attr "length" "8")
749    (set_attr "type" "arith3")])
750
751 (define_insn "cmpeqsi_media"
752   [(set (match_operand:DI 0 "register_operand" "=r")
753         (eq:DI (match_operand:SI 1 "logical_operand" "%r")
754                (match_operand:SI 2 "cmp_operand" "Nr")))]
755   "TARGET_SHMEDIA"
756   "cmpeq        %1, %N2, %0"
757   [(set_attr "type" "cmp_media")])
758
759 (define_insn "cmpeqdi_media"
760   [(set (match_operand:DI 0 "register_operand" "=r")
761         (eq:DI (match_operand:DI 1 "register_operand" "%r")
762                (match_operand:DI 2 "cmp_operand" "Nr")))]
763   "TARGET_SHMEDIA"
764   "cmpeq        %1, %N2, %0"
765   [(set_attr "type" "cmp_media")])
766
767 (define_insn "cmpgtsi_media"
768   [(set (match_operand:DI 0 "register_operand" "=r")
769         (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
770                (match_operand:SI 2 "cmp_operand" "rN")))]
771   "TARGET_SHMEDIA"
772   "cmpgt        %N1, %N2, %0"
773   [(set_attr "type" "cmp_media")])
774
775 (define_insn "cmpgtdi_media"
776   [(set (match_operand:DI 0 "register_operand" "=r")
777         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
778                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
779   "TARGET_SHMEDIA"
780   "cmpgt        %N1, %N2, %0"
781   [(set_attr "type" "cmp_media")])
782
783 (define_insn "cmpgtusi_media"
784   [(set (match_operand:DI 0 "register_operand" "=r")
785         (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
786                 (match_operand:SI 2 "cmp_operand" "rN")))]
787   "TARGET_SHMEDIA"
788   "cmpgtu       %N1, %N2, %0"
789   [(set_attr "type" "cmp_media")])
790
791 (define_insn "cmpgtudi_media"
792   [(set (match_operand:DI 0 "register_operand" "=r")
793         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
794                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
795   "TARGET_SHMEDIA"
796   "cmpgtu       %N1, %N2, %0"
797   [(set_attr "type" "cmp_media")])
798
799 (define_insn "cmpsieqsi_media"
800   [(set (match_operand:SI 0 "register_operand" "=r")
801         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
802                (match_operand:SI 2 "cmp_operand" "Nr")))]
803   "TARGET_SHMEDIA"
804   "cmpeq        %1, %N2, %0"
805   [(set_attr "type" "cmp_media")])
806
807 (define_insn "cmpsieqdi_media"
808   [(set (match_operand:SI 0 "register_operand" "=r")
809         (eq:SI (match_operand:DI 1 "register_operand" "%r")
810                (match_operand:DI 2 "cmp_operand" "Nr")))]
811   "TARGET_SHMEDIA"
812   "cmpeq        %1, %N2, %0"
813   [(set_attr "type" "cmp_media")])
814
815 (define_insn "cmpsigtsi_media"
816   [(set (match_operand:SI 0 "register_operand" "=r")
817         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
818                (match_operand:SI 2 "cmp_operand" "rN")))]
819   "TARGET_SHMEDIA"
820   "cmpgt        %N1, %N2, %0"
821   [(set_attr "type" "cmp_media")])
822
823 (define_insn "cmpsigtdi_media"
824   [(set (match_operand:SI 0 "register_operand" "=r")
825         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
826                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
827   "TARGET_SHMEDIA"
828   "cmpgt        %N1, %N2, %0"
829   [(set_attr "type" "cmp_media")])
830
831 (define_insn "cmpsigtusi_media"
832   [(set (match_operand:SI 0 "register_operand" "=r")
833         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
834                 (match_operand:SI 2 "cmp_operand" "rN")))]
835   "TARGET_SHMEDIA"
836   "cmpgtu       %N1, %N2, %0"
837   [(set_attr "type" "cmp_media")])
838
839 (define_insn "cmpsigtudi_media"
840   [(set (match_operand:SI 0 "register_operand" "=r")
841         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
842                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
843   "TARGET_SHMEDIA"
844   "cmpgtu       %N1, %N2, %0"
845   [(set_attr "type" "cmp_media")])
846
847 ; These two patterns are for combine.
848 (define_insn "*cmpne0si_media"
849   [(set (match_operand:DI 0 "register_operand" "=r")
850         (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
851   "TARGET_SHMEDIA"
852   "cmpgtu       %1,r63,%0"
853   [(set_attr "type" "cmp_media")])
854
855 (define_insn "*cmpne0sisi_media"
856   [(set (match_operand:SI 0 "register_operand" "=r")
857         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
858   "TARGET_SHMEDIA"
859   "cmpgtu       %1,r63,%0"
860   [(set_attr "type" "cmp_media")])
861
862 ;; We save the compare operands in the cmpxx patterns and use them when
863 ;; we generate the branch.
864
865 (define_expand "cmpdi"
866   [(set (reg:SI T_REG)
867         (compare (match_operand:DI 0 "arith_operand" "")
868                  (match_operand:DI 1 "arith_operand" "")))]
869   "TARGET_SH2 || TARGET_SHMEDIA"
870   "
871 {
872   sh_compare_op0 = operands[0];
873   sh_compare_op1 = operands[1];
874   DONE;
875 }")
876 ;; -------------------------------------------------------------------------
877 ;; Conditional move instructions
878 ;; -------------------------------------------------------------------------
879
880 ;; The insn names may seem reversed, but note that cmveq performs the move
881 ;; if op1 == 0, and cmvne does it if op1 != 0.
882
883 (define_insn "movdicc_false"
884   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
885         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
886                              (const_int 0))
887          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
888          (match_operand:DI 3 "arith_reg_operand" "0")))]
889   "TARGET_SHMEDIA"
890   "cmveq        %1, %N2, %0"
891   [(set_attr "type" "arith_media")])
892
893 (define_insn "movdicc_true"
894   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
895         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
896                              (const_int 0))
897          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
898          (match_operand:DI 3 "arith_reg_operand" "0")))]
899   "TARGET_SHMEDIA"
900   "cmvne        %1, %N2, %0"
901   [(set_attr "type" "arith_media")])
902
903 (define_peephole2
904   [(set (match_operand:DI 0 "arith_reg_dest" "")
905         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
906                            [(match_operand:DI 1 "arith_reg_operand" "")
907                             (const_int 0)])
908          (match_operand:DI 2 "arith_reg_dest" "")
909          (match_dup 0)))
910    (set (match_dup 2) (match_dup 0))]
911   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
912   [(set (match_dup 2)
913         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
914   "
915 {
916   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
917                                 VOIDmode, operands[1], CONST0_RTX (DImode));
918 }")
919
920 (define_peephole2
921   [(set (match_operand:DI 0 "general_movdst_operand" "")
922         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
923    (set (match_operand:DI 2 "arith_reg_dest" "")
924         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
925                            [(match_operand:DI 3 "arith_reg_operand" "")
926                             (const_int 0)])
927          (match_dup 0)
928          (match_dup 2)))]
929   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
930   [(set (match_dup 2)
931         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
932   "")
933
934 (define_expand "movdicc"
935   [(set (match_operand:DI 0 "register_operand" "")
936         (if_then_else:DI (match_operand 1 "comparison_operator" "")
937                          (match_operand:DI 2 "register_operand" "")
938                          (match_operand:DI 3 "register_operand" "")))]
939   "TARGET_SHMEDIA"
940   "
941 {
942   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
943       && GET_MODE (sh_compare_op0) == DImode
944       && sh_compare_op1 == const0_rtx)
945     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
946                                   sh_compare_op0, sh_compare_op1);
947   else
948     {
949       rtx tmp;
950
951       if (no_new_pseudos)
952         FAIL;
953
954       tmp = gen_reg_rtx (DImode);
955
956       switch (GET_CODE (operands[1]))
957         {
958         case EQ:
959           emit_insn (gen_seq (tmp));
960           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
961           break;
962
963         case NE:
964           emit_insn (gen_seq (tmp));
965           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
966           break;
967
968         case GT:
969           emit_insn (gen_sgt (tmp));
970           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
971           break;
972
973         case LT:
974           emit_insn (gen_slt (tmp));
975           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
976           break;
977
978         case GE:
979           emit_insn (gen_slt (tmp));
980           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
981           break;
982
983         case LE:
984           emit_insn (gen_sgt (tmp));
985           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
986           break;
987
988         case GTU:
989           emit_insn (gen_sgtu (tmp));
990           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
991           break;
992
993         case LTU:
994           emit_insn (gen_sltu (tmp));
995           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
996           break;
997
998         case GEU:
999           emit_insn (gen_sltu (tmp));
1000           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1001           break;
1002
1003         case LEU:
1004           emit_insn (gen_sgtu (tmp));
1005           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1006           break;
1007
1008         case UNORDERED:
1009           emit_insn (gen_sunordered (tmp));
1010           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1011           break;
1012
1013         case ORDERED:
1014           emit_insn (gen_sunordered (tmp));
1015           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1016           break;
1017
1018         case UNEQ:
1019         case UNGE:
1020         case UNGT:
1021         case UNLE:
1022         case UNLT:
1023         case LTGT:
1024           FAIL;
1025
1026         default:
1027           gcc_unreachable ();
1028         }
1029     }
1030 }")
1031
1032 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1033 ;; SImode to DImode.
1034 (define_insn "movsicc_false"
1035   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1036         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1037                           (const_int 0))
1038          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1039          (match_operand:SI 3 "arith_reg_operand" "0")))]
1040   "TARGET_SHMEDIA"
1041   "cmveq        %1, %N2, %0"
1042   [(set_attr "type" "arith_media")])
1043
1044 (define_insn "movsicc_true"
1045   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1046         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1047                           (const_int 0))
1048          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1049          (match_operand:SI 3 "arith_reg_operand" "0")))]
1050   "TARGET_SHMEDIA"
1051   "cmvne        %1, %N2, %0"
1052   [(set_attr "type" "arith_media")])
1053
1054 (define_peephole2
1055   [(set (match_operand:SI 0 "arith_reg_dest" "")
1056         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1057                            [(match_operand:SI 1 "arith_reg_operand" "")
1058                             (const_int 0)])
1059          (match_operand:SI 2 "arith_reg_dest" "")
1060          (match_dup 0)))
1061    (set (match_dup 2) (match_dup 0))]
1062   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1063   [(set (match_dup 2)
1064         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1065   "
1066 {
1067   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1068                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1069 }")
1070
1071 (define_peephole2
1072   [(set (match_operand:SI 0 "general_movdst_operand" "")
1073         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1074    (set (match_operand:SI 2 "arith_reg_dest" "")
1075         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1076                            [(match_operand:SI 3 "arith_reg_operand" "")
1077                             (const_int 0)])
1078          (match_dup 0)
1079          (match_dup 2)))]
1080   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1081    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1082   [(set (match_dup 2)
1083         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1084   "
1085 {
1086   replace_rtx (operands[4], operands[0], operands[1]);
1087 }")
1088
1089 (define_peephole2
1090   [(set (match_operand 0 "any_register_operand" "")
1091         (match_operand 1 "any_register_operand" ""))
1092    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1093    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1094   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1095     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1096    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1097    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1098    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1099    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1100    && (REGNO_REG_CLASS (REGNO (operands[0]))
1101        == REGNO_REG_CLASS (REGNO (operands[2])))
1102    && (REGNO_REG_CLASS (REGNO (operands[1]))
1103        == REGNO_REG_CLASS (REGNO (operands[0])))"
1104   [(set (match_dup 0) (match_dup 3))
1105    (set (match_dup 4) (match_dup 5))]
1106   "
1107 {
1108   rtx set1, set2;
1109   rtx replacements[4];
1110
1111   /* We want to replace occurrences of operands[0] with operands[1] and
1112      operands[2] with operands[0] in operands[4]/operands[5].
1113      Doing just two replace_rtx calls naively would result in the second
1114      replacement undoing all that the first did if operands[1] and operands[2]
1115      are identical, so we must do this simultaneously.  */
1116   replacements[0] = operands[0];
1117   replacements[1] = operands[1];
1118   replacements[2] = operands[2];
1119   replacements[3] = operands[0];
1120   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1121       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1122       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1123     FAIL;
1124
1125   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1126   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1127   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1128   /* The operands array is aliased to recog_data.operand, which gets
1129      clobbered by extract_insn, so finish with it now.  */
1130   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1131   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1132   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1133      always uses emit_insn.  */
1134   /* Check that we don't violate matching constraints or earlyclobbers.  */
1135   extract_insn (emit_insn (set1));
1136   if (! constrain_operands (1))
1137     goto failure;
1138   extract_insn (emit (set2));
1139   if (! constrain_operands (1))
1140     {
1141       rtx tmp;
1142     failure:
1143       tmp = replacements[0];
1144       replacements[0] = replacements[1];
1145       replacements[1] = tmp;
1146       tmp = replacements[2];
1147       replacements[2] = replacements[3];
1148       replacements[3] = tmp;
1149       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1150       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1151       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1152       FAIL;
1153     }
1154   DONE;
1155 }")
1156
1157 ;; The register allocator is rather clumsy in handling multi-way conditional
1158 ;; moves, so allow the combiner to make them, and we split them up after
1159 ;; reload.  */
1160 (define_insn_and_split "*movsicc_umin"
1161   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1162         (umin:SI (if_then_else:SI
1163                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1164                        (const_int 0))
1165                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1166                    (match_operand:SI 3 "register_operand" "0"))
1167                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1168    (clobber (match_scratch:SI 5 "=&r"))]
1169   "TARGET_SHMEDIA && no_new_pseudos"
1170   "#"
1171   "TARGET_SHMEDIA && reload_completed"
1172   [(pc)]
1173   "
1174 {
1175   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1176                                 operands[3]));
1177   emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1178   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1179                                 operands[0]));
1180   DONE;
1181 }")
1182
1183 (define_expand "movsicc"
1184   [(set (match_operand:SI 0 "register_operand" "")
1185         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1186                          (match_operand:SI 2 "register_operand" "")
1187                          (match_operand:SI 3 "register_operand" "")))]
1188   "TARGET_SHMEDIA"
1189   "
1190 {
1191   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1192       && GET_MODE (sh_compare_op0) == SImode
1193       && sh_compare_op1 == const0_rtx)
1194     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1195                                   sh_compare_op0, sh_compare_op1);
1196   else
1197     {
1198       rtx tmp;
1199
1200       if (no_new_pseudos)
1201         FAIL;
1202
1203       tmp = gen_reg_rtx (SImode);
1204
1205       switch (GET_CODE (operands[1]))
1206         {
1207         case EQ:
1208           emit_insn (gen_seq (tmp));
1209           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1210           break;
1211
1212         case NE:
1213           emit_insn (gen_seq (tmp));
1214           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1215           break;
1216
1217         case GT:
1218           emit_insn (gen_sgt (tmp));
1219           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1220           break;
1221
1222         case LT:
1223           emit_insn (gen_slt (tmp));
1224           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1225           break;
1226
1227         case GE:
1228           emit_insn (gen_slt (tmp));
1229           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1230           break;
1231
1232         case LE:
1233           emit_insn (gen_sgt (tmp));
1234           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1235           break;
1236
1237         case GTU:
1238           emit_insn (gen_sgtu (tmp));
1239           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1240           break;
1241
1242         case LTU:
1243           emit_insn (gen_sltu (tmp));
1244           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1245           break;
1246
1247         case GEU:
1248           emit_insn (gen_sltu (tmp));
1249           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1250           break;
1251
1252         case LEU:
1253           emit_insn (gen_sgtu (tmp));
1254           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1255           break;
1256
1257         case UNORDERED:
1258           emit_insn (gen_sunordered (tmp));
1259           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1260           break;
1261
1262         case ORDERED:
1263           emit_insn (gen_sunordered (tmp));
1264           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1265           break;
1266
1267         case UNEQ:
1268         case UNGE:
1269         case UNGT:
1270         case UNLE:
1271         case UNLT:
1272         case LTGT:
1273           FAIL;
1274
1275         default:
1276           abort ();
1277         }
1278     }
1279 }")
1280
1281 (define_expand "movqicc"
1282   [(set (match_operand:QI 0 "register_operand" "")
1283         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1284                          (match_operand:QI 2 "register_operand" "")
1285                          (match_operand:QI 3 "register_operand" "")))]
1286   "TARGET_SHMEDIA"
1287   "
1288 {
1289   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1290   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1291   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1292   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1293   DONE;
1294 }")
1295 \f
1296 ;; -------------------------------------------------------------------------
1297 ;; Addition instructions
1298 ;; -------------------------------------------------------------------------
1299
1300 (define_expand "adddi3"
1301   [(set (match_operand:DI 0 "arith_reg_operand" "")
1302         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1303                  (match_operand:DI 2 "arith_operand" "")))]
1304   ""
1305   "
1306 {
1307   if (TARGET_SH1)
1308     {
1309       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1310         FAIL;
1311       operands[2] = force_reg (DImode, operands[2]);
1312       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1313       DONE;
1314     }
1315 }")
1316
1317 (define_insn "*adddi3_media"
1318   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1319         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1320                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1321   "TARGET_SHMEDIA"
1322   "@
1323         add     %1, %2, %0
1324         addi    %1, %2, %0"
1325   [(set_attr "type" "arith_media")])
1326
1327 (define_insn "*adddisi3_media"
1328   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1329         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1330                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1331   "TARGET_SHMEDIA"
1332   "@
1333         add.l   %1, %2, %0
1334         addi.l  %1, %2, %0"
1335   [(set_attr "type" "arith_media")
1336    (set_attr "highpart" "ignore")])
1337
1338 (define_insn "adddi3z_media"
1339   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1340         (zero_extend:DI
1341          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1342                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1343   "TARGET_SHMEDIA"
1344   "addz.l       %1, %N2, %0"
1345   [(set_attr "type" "arith_media")
1346    (set_attr "highpart" "ignore")])
1347
1348 (define_insn "adddi3_compact"
1349   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1350         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1351                  (match_operand:DI 2 "arith_reg_operand" "r")))
1352    (clobber (reg:SI T_REG))]
1353   "TARGET_SH1"
1354   "#"
1355   [(set_attr "length" "6")])
1356
1357 (define_split
1358   [(set (match_operand:DI 0 "arith_reg_dest" "")
1359         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1360                  (match_operand:DI 2 "arith_reg_operand" "")))
1361    (clobber (reg:SI T_REG))]
1362   "TARGET_SH1 && reload_completed"
1363   [(const_int 0)]
1364   "
1365 {
1366   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1367   high0 = gen_rtx_REG (SImode,
1368                        true_regnum (operands[0])
1369                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1370   high2 = gen_rtx_REG (SImode,
1371                        true_regnum (operands[2])
1372                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1373   emit_insn (gen_clrt ());
1374   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1375   emit_insn (gen_addc1 (high0, high0, high2));
1376   DONE;
1377 }")
1378
1379 (define_insn "addc"
1380   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1381         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1382                           (match_operand:SI 2 "arith_reg_operand" "r"))
1383                  (reg:SI T_REG)))
1384    (set (reg:SI T_REG)
1385         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1386   "TARGET_SH1"
1387   "addc %2,%0"
1388   [(set_attr "type" "arith")])
1389
1390 (define_insn "addc1"
1391   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1392         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1393                           (match_operand:SI 2 "arith_reg_operand" "r"))
1394                  (reg:SI T_REG)))
1395    (clobber (reg:SI T_REG))]
1396   "TARGET_SH1"
1397   "addc %2,%0"
1398   [(set_attr "type" "arith")])
1399
1400 (define_expand "addsi3"
1401   [(set (match_operand:SI 0 "arith_reg_operand" "")
1402         (plus:SI (match_operand:SI 1 "arith_operand" "")
1403                  (match_operand:SI 2 "arith_operand" "")))]
1404   ""
1405   "
1406 {
1407   if (TARGET_SHMEDIA)
1408     operands[1] = force_reg (SImode, operands[1]);
1409 }")
1410
1411 (define_insn "addsi3_media"
1412   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1413         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1414                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1415   "TARGET_SHMEDIA"
1416   "@
1417         add.l   %1, %2, %0
1418         addi.l  %1, %2, %0"
1419   [(set_attr "type" "arith_media")
1420    (set_attr "highpart" "ignore")])
1421
1422 (define_insn "addsidi3_media"
1423   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1424         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1425                                   "%r,r")
1426                                  (match_operand:SI 2 "arith_operand"
1427                                   "r,I10"))))]
1428   "TARGET_SHMEDIA"
1429   "@
1430         add.l   %1, %2, %0
1431         addi.l  %1, %2, %0"
1432   [(set_attr "type" "arith_media")
1433    (set_attr "highpart" "ignore")])
1434
1435 (define_insn "*addsi3_compact"
1436   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1437         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1438                  (match_operand:SI 2 "arith_operand" "rI08")))]
1439   "TARGET_SH1"
1440   "add  %2,%0"
1441   [(set_attr "type" "arith")])
1442
1443 ;; -------------------------------------------------------------------------
1444 ;; Subtraction instructions
1445 ;; -------------------------------------------------------------------------
1446
1447 (define_expand "subdi3"
1448   [(set (match_operand:DI 0 "arith_reg_operand" "")
1449         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1450                   (match_operand:DI 2 "arith_reg_operand" "")))]
1451   ""
1452   "
1453 {
1454   if (TARGET_SH1)
1455     {
1456       operands[1] = force_reg (DImode, operands[1]);
1457       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1458       DONE;
1459     }
1460 }")
1461
1462 (define_insn "*subdi3_media"
1463   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1464         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1465                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1466   "TARGET_SHMEDIA"
1467   "sub  %N1, %2, %0"
1468   [(set_attr "type" "arith_media")])
1469   
1470 (define_insn "subdisi3_media"
1471   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1472         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1473                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1474   "TARGET_SHMEDIA"
1475   "sub.l        %N1, %2, %0"
1476   [(set_attr "type" "arith_media")
1477    (set_attr "highpart" "ignore")])
1478
1479 (define_insn "subdi3_compact"
1480   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1481         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1482                  (match_operand:DI 2 "arith_reg_operand" "r")))
1483    (clobber (reg:SI T_REG))]
1484   "TARGET_SH1"
1485   "#"
1486   [(set_attr "length" "6")])
1487
1488 (define_split
1489   [(set (match_operand:DI 0 "arith_reg_dest" "")
1490         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1491                   (match_operand:DI 2 "arith_reg_operand" "")))
1492    (clobber (reg:SI T_REG))]
1493   "TARGET_SH1 && reload_completed"
1494   [(const_int 0)]
1495   "
1496 {
1497   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1498   high0 = gen_rtx_REG (SImode,
1499                        true_regnum (operands[0])
1500                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1501   high2 = gen_rtx_REG (SImode,
1502                        true_regnum (operands[2])
1503                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1504   emit_insn (gen_clrt ());
1505   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1506   emit_insn (gen_subc1 (high0, high0, high2));
1507   DONE;
1508 }")
1509
1510 (define_insn "subc"
1511   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1512         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1513                             (match_operand:SI 2 "arith_reg_operand" "r"))
1514                   (reg:SI T_REG)))
1515    (set (reg:SI T_REG)
1516         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1517                           (reg:SI T_REG))
1518                 (match_dup 1)))]
1519   "TARGET_SH1"
1520   "subc %2,%0"
1521   [(set_attr "type" "arith")])
1522
1523 (define_insn "subc1"
1524   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1525         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1526                             (match_operand:SI 2 "arith_reg_operand" "r"))
1527                   (reg:SI T_REG)))
1528    (clobber (reg:SI T_REG))]
1529   "TARGET_SH1"
1530   "subc %2,%0"
1531   [(set_attr "type" "arith")])
1532
1533 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1534 ;; pattern for this case.  This helps multimedia applications that compute
1535 ;; the sum of absolute differences.
1536 (define_insn "mov_neg_si_t"
1537   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1538   "TARGET_SH1"
1539   "subc %0,%0"
1540   [(set_attr "type" "arith")])
1541
1542 (define_insn "*subsi3_internal"
1543   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1544         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1545                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1546   "TARGET_SH1"
1547   "sub  %2,%0"
1548   [(set_attr "type" "arith")])
1549
1550 (define_insn_and_split "*subsi3_media"
1551   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1552         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1553                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1554   "TARGET_SHMEDIA
1555    && (operands[1] != constm1_rtx
1556        || (GET_CODE (operands[2]) != TRUNCATE
1557            && GET_CODE (operands[2]) != SUBREG))"
1558   "sub.l        %N1, %2, %0"
1559   "operands[1] == constm1_rtx"
1560   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1561   ""
1562   [(set_attr "type" "arith_media")
1563    (set_attr "highpart" "ignore")])
1564
1565 (define_split
1566   [(set (match_operand:SI 0 "arith_reg_dest" "")
1567         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1568                                                        "general_extend_operand"
1569                                                        "") 0)) 0)))]
1570   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1571   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1572    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1573   "")
1574
1575 (define_split
1576   [(set (match_operand:SI 0 "arith_reg_dest" "")
1577         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1578                                                        "general_extend_operand"
1579                                                        "") 0)) 3)))]
1580   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1581   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1582    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1583   "")
1584 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1585 ;; will sometimes save one instruction.  Otherwise we might get
1586 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1587 ;; are the same.
1588
1589 (define_expand "subsi3"
1590   [(set (match_operand:SI 0 "arith_reg_operand" "")
1591         (minus:SI (match_operand:SI 1 "arith_operand" "")
1592                   (match_operand:SI 2 "arith_reg_operand" "")))]
1593   ""
1594   "
1595 {
1596   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1597     {
1598       emit_insn (gen_negsi2 (operands[0], operands[2]));
1599       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1600       DONE;
1601     }
1602   if (TARGET_SHMEDIA)
1603     {
1604       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1605         FAIL;
1606       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1607         operands[1] = force_reg (SImode, operands[1]);
1608     }
1609 }")
1610 \f
1611 ;; -------------------------------------------------------------------------
1612 ;; Division instructions
1613 ;; -------------------------------------------------------------------------
1614
1615 ;; We take advantage of the library routines which don't clobber as many
1616 ;; registers as a normal function call would.
1617
1618 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1619 ;; also has an effect on the register that holds the address of the sfunc.
1620 ;; To make this work, we have an extra dummy insn that shows the use
1621 ;; of this register for reorg.
1622
1623 (define_insn "use_sfunc_addr"
1624   [(set (reg:SI PR_REG)
1625         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1626   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1627   ""
1628   [(set_attr "length" "0")])
1629
1630 (define_insn "udivsi3_sh2a"
1631   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1632         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1633                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1634   "TARGET_SH2A"
1635   "divu %2,%1"
1636   [(set_attr "type" "arith")
1637    (set_attr "in_delay_slot" "no")])
1638
1639 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1640 ;; hard register 0.  If we used hard register 0, then the next instruction
1641 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1642 ;; gets allocated to a stack slot that needs its address reloaded, then
1643 ;; there is nothing to prevent reload from using r0 to reload the address.
1644 ;; This reload would clobber the value in r0 we are trying to store.
1645 ;; If we let reload allocate r0, then this problem can never happen.
1646
1647 (define_insn "udivsi3_i1"
1648   [(set (match_operand:SI 0 "register_operand" "=z")
1649         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1650    (clobber (reg:SI T_REG))
1651    (clobber (reg:SI PR_REG))
1652    (clobber (reg:SI R4_REG))
1653    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1654   "TARGET_SH1 && ! TARGET_SH4"
1655   "jsr  @%1%#"
1656   [(set_attr "type" "sfunc")
1657    (set_attr "needs_delay_slot" "yes")])
1658
1659 ; Since shmedia-nofpu code could be linked against shcompact code, and
1660 ; the udivsi3 libcall has the same name, we must consider all registers
1661 ; clobbered that are in the union of the registers clobbered by the
1662 ; shmedia and the shcompact implementation.  Note, if the shcompact
1663 ; implementation actually used shcompact code, we'd need to clobber
1664 ; also r23 and fr23.
1665 (define_insn "udivsi3_i1_media"
1666   [(set (match_operand:SI 0 "register_operand" "=z")
1667         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1668    (clobber (reg:SI T_MEDIA_REG))
1669    (clobber (reg:SI PR_MEDIA_REG))
1670    (clobber (reg:SI R20_REG))
1671    (clobber (reg:SI R21_REG))
1672    (clobber (reg:SI R22_REG))
1673    (clobber (reg:DI TR0_REG))
1674    (clobber (reg:DI TR1_REG))
1675    (clobber (reg:DI TR2_REG))
1676    (use (match_operand 1 "target_operand" "b"))]
1677   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1678   "blink        %1, r18"
1679   [(set_attr "type" "sfunc")
1680    (set_attr "needs_delay_slot" "yes")])
1681
1682 (define_expand "udivsi3_i4_media"
1683   [(set (match_dup 3)
1684         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1685    (set (match_dup 4)
1686         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1687    (set (match_dup 5) (float:DF (match_dup 3)))
1688    (set (match_dup 6) (float:DF (match_dup 4)))
1689    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1690    (set (match_dup 8) (fix:DI (match_dup 7)))
1691    (set (match_operand:SI 0 "register_operand" "")
1692         (truncate:SI (match_dup 8)))]
1693   "TARGET_SHMEDIA_FPU"
1694   "
1695 {
1696   operands[3] = gen_reg_rtx (DImode);
1697   operands[4] = gen_reg_rtx (DImode);
1698   operands[5] = gen_reg_rtx (DFmode);
1699   operands[6] = gen_reg_rtx (DFmode);
1700   operands[7] = gen_reg_rtx (DFmode);
1701   operands[8] = gen_reg_rtx (DImode);
1702 }")
1703
1704 (define_insn "udivsi3_i4"
1705   [(set (match_operand:SI 0 "register_operand" "=y")
1706         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1707    (clobber (reg:SI T_REG))
1708    (clobber (reg:SI PR_REG))
1709    (clobber (reg:DF DR0_REG))
1710    (clobber (reg:DF DR2_REG))
1711    (clobber (reg:DF DR4_REG))
1712    (clobber (reg:SI R0_REG))
1713    (clobber (reg:SI R1_REG))
1714    (clobber (reg:SI R4_REG))
1715    (clobber (reg:SI R5_REG))
1716    (use (reg:PSI FPSCR_REG))
1717    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1718   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1719   "jsr  @%1%#"
1720   [(set_attr "type" "sfunc")
1721    (set_attr "fp_mode" "double")
1722    (set_attr "needs_delay_slot" "yes")])
1723
1724 (define_insn "udivsi3_i4_single"
1725   [(set (match_operand:SI 0 "register_operand" "=y")
1726         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1727    (clobber (reg:SI T_REG))
1728    (clobber (reg:SI PR_REG))
1729    (clobber (reg:DF DR0_REG))
1730    (clobber (reg:DF DR2_REG))
1731    (clobber (reg:DF DR4_REG))
1732    (clobber (reg:SI R0_REG))
1733    (clobber (reg:SI R1_REG))
1734    (clobber (reg:SI R4_REG))
1735    (clobber (reg:SI R5_REG))
1736    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1737   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1738   "jsr  @%1%#"
1739   [(set_attr "type" "sfunc")
1740    (set_attr "needs_delay_slot" "yes")])
1741
1742 (define_expand "udivsi3"
1743   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1744    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1745    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1746    (parallel [(set (match_operand:SI 0 "register_operand" "")
1747                    (udiv:SI (reg:SI R4_REG)
1748                             (reg:SI R5_REG)))
1749               (clobber (reg:SI T_REG))
1750               (clobber (reg:SI PR_REG))
1751               (clobber (reg:SI R4_REG))
1752               (use (match_dup 3))])]
1753   ""
1754   "
1755 {
1756   rtx first, last;
1757
1758   operands[3] = gen_reg_rtx (Pmode);
1759   /* Emit the move of the address to a pseudo outside of the libcall.  */
1760   if (TARGET_HARD_SH4 && TARGET_SH2E)
1761     {
1762       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1763       if (TARGET_FPU_SINGLE)
1764         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1765       else
1766         last = gen_udivsi3_i4 (operands[0], operands[3]);
1767     }
1768   else if (TARGET_SHMEDIA_FPU)
1769     {
1770       operands[1] = force_reg (SImode, operands[1]);
1771       operands[2] = force_reg (SImode, operands[2]);
1772       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1773       DONE;
1774     }
1775   else if (TARGET_SH2A)
1776     {
1777       operands[1] = force_reg (SImode, operands[1]);
1778       operands[2] = force_reg (SImode, operands[2]);
1779       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1780       DONE;
1781     }
1782   else if (TARGET_SH5)
1783     {
1784       function_symbol (operands[3],
1785                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1786                        SFUNC_STATIC);
1787
1788       if (TARGET_SHMEDIA)
1789         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1790       else if (TARGET_FPU_ANY)
1791         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1792       else
1793         last = gen_udivsi3_i1 (operands[0], operands[3]);
1794     }
1795   else
1796     {
1797       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1798       last = gen_udivsi3_i1 (operands[0], operands[3]);
1799     }
1800   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1801   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1802   last = emit_insn (last);
1803   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1804      invariant code motion can move it.  */
1805   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1806   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1807   DONE;
1808 }")
1809
1810 (define_insn "divsi3_sh2a"
1811   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1812         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1813                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1814   "TARGET_SH2A"
1815   "divs %2,%1"
1816   [(set_attr "type" "arith")
1817    (set_attr "in_delay_slot" "no")])
1818
1819 (define_insn "divsi3_i1"
1820   [(set (match_operand:SI 0 "register_operand" "=z")
1821         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1822    (clobber (reg:SI T_REG))
1823    (clobber (reg:SI PR_REG))
1824    (clobber (reg:SI R1_REG))
1825    (clobber (reg:SI R2_REG))
1826    (clobber (reg:SI R3_REG))
1827    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1828   "TARGET_SH1 && ! TARGET_SH4"
1829   "jsr  @%1%#"
1830   [(set_attr "type" "sfunc")
1831    (set_attr "needs_delay_slot" "yes")])
1832
1833 (define_insn "divsi3_i1_media"
1834   [(set (match_operand:SI 0 "register_operand" "=z")
1835         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1836    (clobber (reg:SI T_MEDIA_REG))
1837    (clobber (reg:SI PR_MEDIA_REG))
1838    (clobber (reg:SI R1_REG))
1839    (clobber (reg:SI R20_REG))
1840    (clobber (reg:SI R21_REG))
1841    (clobber (reg:SI TR0_REG))
1842    (use (match_operand 1 "target_operand" "b"))]
1843   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1844   "blink        %1, r18"
1845   [(set_attr "type" "sfunc")])
1846
1847 (define_insn "divsi3_media_2"
1848   [(set (match_operand:SI 0 "register_operand" "=z")
1849         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1850    (clobber (reg:SI T_MEDIA_REG))
1851    (clobber (reg:SI PR_MEDIA_REG))
1852    (clobber (reg:SI R1_REG))
1853    (clobber (reg:SI R21_REG))
1854    (clobber (reg:SI TR0_REG))
1855    (use (reg:SI R20_REG))
1856    (use (match_operand 1 "target_operand" "b"))]
1857   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1858   "blink        %1, r18"
1859   [(set_attr "type" "sfunc")])
1860
1861 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1862 ;; hard reg clobbers and data dependencies that we need when we want
1863 ;; to rematerialize the division into a call.
1864 (define_insn_and_split "divsi_inv_call"
1865   [(set (match_operand:SI 0 "register_operand" "=r")
1866         (div:SI (match_operand:SI 1 "register_operand" "r")
1867                 (match_operand:SI 2 "register_operand" "r")))
1868    (clobber (reg:SI R4_REG))
1869    (clobber (reg:SI R5_REG))
1870    (clobber (reg:SI T_MEDIA_REG))
1871    (clobber (reg:SI PR_MEDIA_REG))
1872    (clobber (reg:SI R1_REG))
1873    (clobber (reg:SI R21_REG))
1874    (clobber (reg:SI TR0_REG))
1875    (clobber (reg:SI R20_REG))
1876    (use (match_operand:SI 3 "register_operand" "r"))]
1877   "TARGET_SHMEDIA"
1878   "#"
1879   "&& (high_life_started || reload_completed)"
1880   [(set (match_dup 0) (match_dup 3))]
1881   ""
1882   [(set_attr "highpart" "must_split")])
1883
1884 ;; This is the combiner pattern for -mdiv=inv:call .
1885 (define_insn_and_split "*divsi_inv_call_combine"
1886   [(set (match_operand:SI 0 "register_operand" "=z")
1887         (div:SI (match_operand:SI 1 "register_operand" "r")
1888                 (match_operand:SI 2 "register_operand" "r")))
1889    (clobber (reg:SI R4_REG))
1890    (clobber (reg:SI R5_REG))
1891    (clobber (reg:SI T_MEDIA_REG))
1892    (clobber (reg:SI PR_MEDIA_REG))
1893    (clobber (reg:SI R1_REG))
1894    (clobber (reg:SI R21_REG))
1895    (clobber (reg:SI TR0_REG))
1896    (clobber (reg:SI R20_REG))
1897    (use (unspec:SI [(match_dup 1)
1898                     (match_operand:SI 3 "" "")
1899                     (unspec:SI [(match_operand:SI 4 "" "")
1900                                 (match_dup 3)
1901                                 (match_operand:DI 5 "" "")]
1902                      UNSPEC_DIV_INV_M2)
1903                     (match_operand:DI 6 "" "")
1904                     (const_int 0)
1905                     (const_int 0)]
1906          UNSPEC_DIV_INV_M3))]
1907   "TARGET_SHMEDIA"
1908   "#"
1909   "&& (high_life_started || reload_completed)"
1910   [(pc)]
1911   "
1912 {
1913   const char *name = sh_divsi3_libfunc;
1914   enum sh_function_kind kind = SFUNC_GOT;
1915   rtx sym;
1916
1917   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1918   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1919   while (TARGET_DIVIDE_INV_CALL2)
1920     {
1921       rtx x = operands[3];
1922
1923       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1924         break;
1925       x = XVECEXP (x, 0, 0);
1926       name = \"__sdivsi3_2\";
1927       kind = SFUNC_STATIC;
1928       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1929       break;
1930     }
1931   sym = function_symbol (NULL, name, kind);
1932   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1933   DONE;
1934 }"
1935   [(set_attr "highpart" "must_split")])
1936
1937 (define_expand "divsi3_i4_media"
1938   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1939    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1940    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1941    (set (match_operand:SI 0 "register_operand" "=r")
1942         (fix:SI (match_dup 5)))]
1943   "TARGET_SHMEDIA_FPU"
1944   "
1945 {
1946   operands[3] = gen_reg_rtx (DFmode);
1947   operands[4] = gen_reg_rtx (DFmode);
1948   operands[5] = gen_reg_rtx (DFmode);
1949 }")
1950
1951 (define_insn "divsi3_i4"
1952   [(set (match_operand:SI 0 "register_operand" "=y")
1953         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1954    (clobber (reg:SI PR_REG))
1955    (clobber (reg:DF DR0_REG))
1956    (clobber (reg:DF DR2_REG))
1957    (use (reg:PSI FPSCR_REG))
1958    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1959   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1960   "jsr  @%1%#"
1961   [(set_attr "type" "sfunc")
1962    (set_attr "fp_mode" "double")
1963    (set_attr "needs_delay_slot" "yes")])
1964
1965 (define_insn "divsi3_i4_single"
1966   [(set (match_operand:SI 0 "register_operand" "=y")
1967         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1968    (clobber (reg:SI PR_REG))
1969    (clobber (reg:DF DR0_REG))
1970    (clobber (reg:DF DR2_REG))
1971    (clobber (reg:SI R2_REG))
1972    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1973   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1974   "jsr  @%1%#"
1975   [(set_attr "type" "sfunc")
1976    (set_attr "needs_delay_slot" "yes")])
1977
1978 (define_expand "divsi3"
1979   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1980    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1981    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1982    (parallel [(set (match_operand:SI 0 "register_operand" "")
1983                    (div:SI (reg:SI R4_REG)
1984                            (reg:SI R5_REG)))
1985               (clobber (reg:SI T_REG))
1986               (clobber (reg:SI PR_REG))
1987               (clobber (reg:SI R1_REG))
1988               (clobber (reg:SI R2_REG))
1989               (clobber (reg:SI R3_REG))
1990               (use (match_dup 3))])]
1991   ""
1992   "
1993 {
1994   rtx first, last;
1995
1996   operands[3] = gen_reg_rtx (Pmode);
1997   /* Emit the move of the address to a pseudo outside of the libcall.  */
1998   if (TARGET_HARD_SH4 && TARGET_SH2E)
1999     {
2000       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2001       if (TARGET_FPU_SINGLE)
2002         last = gen_divsi3_i4_single (operands[0], operands[3]);
2003       else
2004         last = gen_divsi3_i4 (operands[0], operands[3]);
2005     }
2006   else if (TARGET_SH2A)
2007     {
2008       operands[1] = force_reg (SImode, operands[1]);
2009       operands[2] = force_reg (SImode, operands[2]);
2010       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2011       DONE;
2012     }
2013   else if (TARGET_DIVIDE_INV)
2014     {
2015       rtx dividend = operands[1];
2016       rtx divisor = operands[2];
2017       rtx tab_base;
2018       rtx nsb_res = gen_reg_rtx (DImode);
2019       rtx norm64 = gen_reg_rtx (DImode);
2020       rtx tab_ix = gen_reg_rtx (DImode);
2021       rtx norm32 = gen_reg_rtx (SImode);
2022       rtx i92 = force_reg (DImode, GEN_INT (92));
2023       rtx scratch0a = gen_reg_rtx (DImode);
2024       rtx scratch0b = gen_reg_rtx (DImode);
2025       rtx inv0 = gen_reg_rtx (SImode);
2026       rtx scratch1a = gen_reg_rtx (DImode);
2027       rtx scratch1b = gen_reg_rtx (DImode);
2028       rtx shift = gen_reg_rtx (DImode);
2029       rtx i2p27, i43;
2030       rtx inv1 = gen_reg_rtx (SImode);
2031       rtx scratch2a = gen_reg_rtx (DImode);
2032       rtx scratch2b = gen_reg_rtx (SImode);
2033       rtx inv2 = gen_reg_rtx (SImode);
2034       rtx scratch3a = gen_reg_rtx (DImode);
2035       rtx scratch3b = gen_reg_rtx (DImode);
2036       rtx scratch3c = gen_reg_rtx (DImode);
2037       rtx scratch3d = gen_reg_rtx (SImode);
2038       rtx scratch3e = gen_reg_rtx (DImode);
2039       rtx result = gen_reg_rtx (SImode);
2040
2041       if (! arith_reg_or_0_operand (dividend, SImode))
2042         dividend = force_reg (SImode, dividend);
2043       if (! arith_reg_operand (divisor, SImode))
2044         divisor = force_reg (SImode, divisor);
2045       if (flag_pic && Pmode != DImode)
2046         {
2047           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2048           tab_base = gen_datalabel_ref (tab_base);
2049           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2050         }
2051       else
2052         {
2053           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2054           tab_base = gen_datalabel_ref (tab_base);
2055           tab_base = force_reg (DImode, tab_base);
2056         }
2057       if (TARGET_DIVIDE_INV20U)
2058         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2059       else
2060         i2p27 = GEN_INT (0);
2061       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2062         i43 = force_reg (DImode, GEN_INT (43));
2063       else
2064         i43 = GEN_INT (0);
2065       emit_insn (gen_nsbdi (nsb_res,
2066                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2067       emit_insn (gen_ashldi3_media (norm64,
2068                                     gen_rtx_SUBREG (DImode, divisor, 0),
2069                                     nsb_res));
2070       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2071       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2072       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2073                                    inv0, scratch0a, scratch0b,
2074                                    scratch1a, scratch1b));
2075       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2076       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2077                                    scratch2a));
2078       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2079                                    i2p27, i43,
2080                                    scratch3a, scratch3b, scratch3c,
2081                                    scratch2a, scratch2b, scratch3d, scratch3e));
2082       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2083         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2084       else if (TARGET_DIVIDE_INV_FP)
2085         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2086                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2087                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2088                                      gen_reg_rtx (DFmode)));
2089       else
2090         emit_move_insn (operands[0], result);
2091       DONE;
2092     }
2093   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2094     {
2095       operands[1] = force_reg (SImode, operands[1]);
2096       operands[2] = force_reg (SImode, operands[2]);
2097       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2098       DONE;
2099     }
2100   else if (TARGET_SH5)
2101     {
2102       if (TARGET_DIVIDE_CALL2)
2103         {
2104           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2105           tab_base = gen_datalabel_ref (tab_base);
2106           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2107         }
2108       if (TARGET_FPU_ANY && TARGET_SH1)
2109         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2110       else if (TARGET_DIVIDE_CALL2)
2111         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2112       else
2113         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2114
2115       if (TARGET_SHMEDIA)
2116         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2117                 (operands[0], operands[3]));
2118       else if (TARGET_FPU_ANY)
2119         last = gen_divsi3_i4_single (operands[0], operands[3]);
2120       else
2121         last = gen_divsi3_i1 (operands[0], operands[3]);
2122     }
2123   else
2124     {
2125       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2126       last = gen_divsi3_i1 (operands[0], operands[3]);
2127     }
2128   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2129   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2130   last = emit_insn (last);
2131   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2132      invariant code motion can move it.  */
2133   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2134   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2135   DONE;
2136 }")
2137
2138 ;; operands: inv0, tab_base, tab_ix, norm32
2139 ;; scratch equiv in sdivsi3_2: r19, r21
2140 (define_expand "divsi_inv_m0"
2141   [(set (match_operand:SI 0 "register_operand" "=r")
2142         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2143                     (match_operand:DI 2 "register_operand" "r")
2144                     (match_operand:SI 3 "register_operand" "r")]
2145          UNSPEC_DIV_INV_M0))
2146    (clobber (match_operand:DI 4 "register_operand" "=r"))
2147    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2148   "TARGET_SHMEDIA"
2149   "
2150 {
2151 /*
2152 tab_base: r20
2153 tab_ix: r21
2154 norm32: r25
2155  ldx.ub r20, r21, r19 // u0.8
2156  shlli r21, 1, r21
2157  muls.l r25, r19, r19 // s2.38
2158  ldx.w r20, r21, r21  // s2.14
2159  shari r19, 24, r19   // truncate to s2.14
2160  sub r21, r19, r19    // some 11 bit inverse in s1.14
2161 */
2162
2163   rtx inv0 = operands[0];
2164   rtx tab_base = operands[1];
2165   rtx tab_ix = operands[2];
2166   rtx norm32 = operands[3];
2167   rtx scratch0 = operands[4];
2168   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2169   rtx scratch1 = operands[5];
2170   rtx mem;
2171
2172   mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2173   emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2174   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2175   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2176   mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2177   emit_insn (gen_extendhidi2 (scratch1, mem));
2178   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2179   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2180   DONE;
2181 }")
2182
2183 ;; operands: inv1, tab_base, tab_ix, norm32
2184 (define_insn_and_split "divsi_inv_m1"
2185   [(set (match_operand:SI 0 "register_operand" "=r")
2186         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2187                     (match_operand:DI 2 "register_operand" "r")
2188                     (match_operand:SI 3 "register_operand" "r")]
2189          UNSPEC_DIV_INV_M1))
2190    (clobber (match_operand:SI 4 "register_operand" "=r"))
2191    (clobber (match_operand:DI 5 "register_operand" "=r"))
2192    (clobber (match_operand:DI 6 "register_operand" "=r"))
2193    (clobber (match_operand:DI 7 "register_operand" "=r"))
2194    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2195   "TARGET_SHMEDIA"
2196   "#"
2197   "&& no_new_pseudos"
2198   [(pc)]
2199   "
2200 {
2201 /* inv0: r19
2202  muls.l r19, r19, r18 // u0.28
2203  muls.l r25, r18, r18 // s2.58
2204  shlli r19, 45, r0    // multiply by two and convert to s2.58
2205  sub r0, r18, r18
2206  shari r18, 28, r18   // some 18 bit inverse in s1.30
2207 */
2208
2209   rtx inv1 = operands[0];
2210   rtx tab_base = operands[1];
2211   rtx tab_ix = operands[2];
2212   rtx norm32 = operands[3];
2213   rtx inv0 = operands[4];
2214   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2215   rtx scratch0a = operands[5];
2216   rtx scratch0b = operands[6];
2217   rtx scratch0 = operands[7];
2218   rtx scratch1 = operands[8];
2219   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2220
2221   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2222                                scratch0a, scratch0b));
2223   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2224   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2225   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2226   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2227   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2228   DONE;
2229 }")
2230
2231 ;; operands: inv2, norm32, inv1, i92
2232 (define_insn_and_split "divsi_inv_m2"
2233   [(set (match_operand:SI 0 "register_operand" "=r")
2234         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2235                     (match_operand:SI 2 "register_operand" "r")
2236                     (match_operand:DI 3 "register_operand" "r")]
2237          UNSPEC_DIV_INV_M2))
2238    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2239   "TARGET_SHMEDIA"
2240   "#"
2241   "&& no_new_pseudos"
2242   [(pc)]
2243   "
2244 {
2245 /*
2246  muls.l r18, r25, r0  // s2.60
2247  shari r0, 16, r0     // s-16.44
2248   sub
2249  muls.l r0, r18, r19  // s-16.74
2250  shari r19, 30, r19   // s-16.44
2251 */
2252   rtx inv2 = operands[0];
2253   rtx norm32 = operands[1];
2254   rtx inv1 = operands[2];
2255   rtx i92 = operands[3];
2256   rtx scratch0 = operands[4];
2257   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2258
2259   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2260   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2261   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2262   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2263   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2264   DONE;
2265 }")
2266
2267 (define_insn_and_split "divsi_inv_m3"
2268   [(set (match_operand:SI 0 "register_operand" "=r")
2269         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2270                     (match_operand:SI 2 "register_operand" "r")
2271                     (match_operand:SI 3 "register_operand" "r")
2272                     (match_operand:DI 4 "register_operand" "r")
2273                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2274                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2275          UNSPEC_DIV_INV_M3))
2276    (clobber (match_operand:DI 7 "register_operand" "=r"))
2277    (clobber (match_operand:DI 8 "register_operand" "=r"))
2278    (clobber (match_operand:DI 9 "register_operand" "=r"))
2279    (clobber (match_operand:DI 10 "register_operand" "=r"))
2280    (clobber (match_operand:SI 11 "register_operand" "=r"))
2281    (clobber (match_operand:SI 12 "register_operand" "=r"))
2282    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2283   "TARGET_SHMEDIA"
2284   "#"
2285   "&& no_new_pseudos"
2286   [(pc)]
2287   "
2288 {
2289 /*
2290   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2291   r0: scratch0  r19: scratch1 r21: scratch2
2292
2293   muls.l r18, r4, r25 // s32.30
2294  muls.l r19, r4, r19  // s15.30
2295  shari r25, 63, r21
2296   shari r19, 14, r19  // s18.-14
2297  sub r25, r19, r0
2298  shard r0, r1, r0
2299  sub r0, r21, r0
2300 */
2301
2302   rtx result = operands[0];
2303   rtx dividend = operands[1];
2304   rtx inv1 = operands[2];
2305   rtx inv2 = operands[3];
2306   rtx shift = operands[4];
2307   rtx scratch0 = operands[7];
2308   rtx scratch1 = operands[8];
2309   rtx scratch2 = operands[9];
2310
2311   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2312   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2313   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2314   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2315   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2316   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2317   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2318   DONE;
2319 }")
2320
2321 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2322 ;; inv1: tab_base, tab_ix, norm32
2323 ;; inv2: norm32, inv1, i92
2324 (define_insn_and_split "divsi_inv_m1_3"
2325   [(set (match_operand:SI 0 "register_operand" "=r")
2326         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2327                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2328                                 (match_operand:DI 3 "register_operand" "r")
2329                                 (match_operand:SI 4 "register_operand" "r")]
2330                      UNSPEC_DIV_INV_M1)
2331                     (unspec:SI [(match_dup 4)
2332                                 (unspec:SI [(match_dup 2)
2333                                             (match_dup 3)
2334                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2335                                 (match_operand:SI 5 "" "")]
2336                      UNSPEC_DIV_INV_M2)
2337                     (match_operand:DI 6 "register_operand" "r")
2338                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2339                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2340          UNSPEC_DIV_INV_M3))
2341    (clobber (match_operand:DI 9 "register_operand" "=r"))
2342    (clobber (match_operand:DI 10 "register_operand" "=r"))
2343    (clobber (match_operand:DI 11 "register_operand" "=r"))
2344    (clobber (match_operand:DI 12 "register_operand" "=r"))
2345    (clobber (match_operand:SI 13 "register_operand" "=r"))
2346    (clobber (match_operand:SI 14 "register_operand" "=r"))
2347    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2348   "TARGET_SHMEDIA
2349    && (TARGET_DIVIDE_INV_MINLAT
2350        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2351   "#"
2352   "&& no_new_pseudos"
2353   [(pc)]
2354   "
2355 {
2356   rtx result = operands[0];
2357   rtx dividend = operands[1];
2358   rtx tab_base = operands[2];
2359   rtx tab_ix = operands[3];
2360   rtx norm32 = operands[4];
2361   /* rtx i92 = operands[5]; */
2362   rtx shift = operands[6];
2363   rtx i2p27 = operands[7];
2364   rtx i43 = operands[8];
2365   rtx scratch0 = operands[9];
2366   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2367   rtx scratch1 = operands[10];
2368   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2369   rtx scratch2 = operands[11];
2370   rtx scratch3 = operands[12];
2371   rtx scratch4 = operands[13];
2372   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2373   rtx scratch5 = operands[14];
2374   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2375   rtx scratch6 = operands[15];
2376
2377   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2378                                scratch0, scratch1));
2379   /* inv0 == scratch4 */
2380   if (! TARGET_DIVIDE_INV20U)
2381     {
2382       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2383       i2p27 = scratch0;
2384       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2385     }
2386   else
2387     {
2388       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2389       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2390     }
2391   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2392   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2393   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2394   /* inv1 == scratch4 */
2395
2396   if (TARGET_DIVIDE_INV_MINLAT)
2397     {
2398       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2399       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2400       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2401       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2402       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2403       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2404       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2405       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2406       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2407       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2408       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2409     }
2410   else
2411     {
2412       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2413       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2414       emit_insn (gen_nsbdi (scratch6,
2415                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2416       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2417       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2418       emit_insn (gen_divsi_inv20 (scratch2,
2419                                   norm32, scratch4, dividend,
2420                                   scratch6, scratch3, i43,
2421                                   /* scratch0 may be shared with i2p27.  */
2422                                   scratch0, scratch1, scratch5,
2423                                   label, label, i2p27));
2424     }
2425   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2426   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2427   DONE;
2428 }")
2429
2430 (define_insn "divsi_inv20"
2431   [(set (match_operand:DI 0 "register_operand" "=&r")
2432         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2433                     (match_operand:SI 2 "register_operand" "r")
2434                     (match_operand:SI 3 "register_operand" "r")
2435                     (match_operand:DI 4 "register_operand" "r")
2436                     (match_operand:DI 5 "register_operand" "r")
2437                     (match_operand:DI 6 "register_operand" "r")
2438                     (match_operand:DI 12 "register_operand" "r")
2439                     (match_operand 10 "target_operand" "b")
2440                     (match_operand 11 "immediate_operand" "i")]
2441          UNSPEC_DIV_INV20))
2442    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2443    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2444    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2445   "TARGET_SHMEDIA
2446    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2447   "*
2448 {
2449 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2450              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2451              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2452              %10 label (tr), %11 label (imm)
2453
2454  muls.l inv1, norm32, scratch0  // s2.60
2455   muls.l inv1, dividend, result // s32.30
2456   xor i2p27, result_sign, round_scratch
2457  bge/u dividend_nsb, i43, tr.. (label)
2458  shari scratch0, 16, scratch0   // s-16.44
2459  muls.l sratch0_si, inv1, scratch0 // s-16.74
2460   sub result, round_scratch, result
2461   shari dividend, 14, scratch1   // s19.-14
2462  shari scratch0, 30, scratch0   // s-16.44
2463  muls.l scratch0, scratch1, round_scratch // s15.30
2464 label:
2465  sub result, round_scratch, result */
2466
2467   int likely = TARGET_DIVIDE_INV20L;
2468
2469   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2470   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2471   output_asm_insn (likely
2472                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2473                    : \"bge/u\t%4, %6, %10\", operands);
2474   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2475   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2476   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2477   return (likely
2478           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2479           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2480 }")
2481
2482 (define_insn_and_split "divsi_inv_fp"
2483   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2484         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2485                 (match_operand:SI 2 "register_operand" "rf")))
2486    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2487    (clobber (match_operand:SI 4 "register_operand" "=r"))
2488    (clobber (match_operand:SI 5 "register_operand" "=r"))
2489    (clobber (match_operand:DF 6 "register_operand" "=r"))
2490    (clobber (match_operand:DF 7 "register_operand" "=r"))
2491    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2492   "TARGET_SHMEDIA_FPU"
2493   "#"
2494   "&& (high_life_started || reload_completed)"
2495   [(set (match_dup 0) (match_dup 3))]
2496   ""
2497   [(set_attr "highpart" "must_split")])
2498
2499 ;; If a matching group of divide-by-inverse instructions is in the same
2500 ;; basic block after gcse & loop optimizations, we want to transform them
2501 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2502 (define_insn_and_split "*divsi_inv_fp_combine"
2503   [(set (match_operand:SI 0 "register_operand" "=f")
2504         (div:SI (match_operand:SI 1 "register_operand" "f")
2505                 (match_operand:SI 2 "register_operand" "f")))
2506    (use (unspec:SI [(match_dup 1)
2507                     (match_operand:SI 3 "" "")
2508                     (unspec:SI [(match_operand:SI 4 "" "")
2509                                 (match_dup 3)
2510                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2511                     (match_operand:DI 6 "" "")
2512                     (const_int 0)
2513                     (const_int 0)] UNSPEC_DIV_INV_M3))
2514    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2515    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2516    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2517    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2518    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2519   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2520   "#"
2521   "&& 1"
2522   [(set (match_dup 9) (float:DF (match_dup 1)))
2523    (set (match_dup 10) (float:DF (match_dup 2)))
2524    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2525    (set (match_dup 8)
2526         (fix:SI (match_dup 11)))
2527    (set (match_dup 0) (match_dup 8))]
2528   "
2529 {
2530   if (! fp_arith_reg_operand (operands[1], SImode))
2531     {
2532       emit_move_insn (operands[7], operands[1]);
2533       operands[1] = operands[7];
2534     }
2535   if (! fp_arith_reg_operand (operands[2], SImode))
2536     {
2537       emit_move_insn (operands[8], operands[2]);
2538       operands[2] = operands[8];
2539     }
2540 }"
2541   [(set_attr "highpart" "must_split")])
2542 \f
2543 ;; -------------------------------------------------------------------------
2544 ;; Multiplication instructions
2545 ;; -------------------------------------------------------------------------
2546
2547 (define_insn "umulhisi3_i"
2548   [(set (reg:SI MACL_REG)
2549         (mult:SI (zero_extend:SI
2550                   (match_operand:HI 0 "arith_reg_operand" "r"))
2551                  (zero_extend:SI
2552                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2553   "TARGET_SH1"
2554   "mulu.w       %1,%0"
2555   [(set_attr "type" "smpy")])
2556
2557 (define_insn "mulhisi3_i"
2558   [(set (reg:SI MACL_REG)
2559         (mult:SI (sign_extend:SI
2560                   (match_operand:HI 0 "arith_reg_operand" "r"))
2561                  (sign_extend:SI
2562                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2563   "TARGET_SH1"
2564   "muls.w       %1,%0"
2565   [(set_attr "type" "smpy")])
2566
2567 (define_expand "mulhisi3"
2568   [(set (reg:SI MACL_REG)
2569         (mult:SI (sign_extend:SI
2570                   (match_operand:HI 1 "arith_reg_operand" ""))
2571                  (sign_extend:SI
2572                   (match_operand:HI 2 "arith_reg_operand" ""))))
2573    (set (match_operand:SI 0 "arith_reg_operand" "")
2574         (reg:SI MACL_REG))]
2575   "TARGET_SH1"
2576   "
2577 {
2578   rtx first, last;
2579
2580   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2581   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2582   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2583      invariant code motion can move it.  */
2584   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2585   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2586   /* expand_binop can't find a suitable code in umul_widen_optab to
2587      make a REG_EQUAL note from, so make one here.
2588      See also smulsi3_highpart.
2589      ??? Alternatively, we could put this at the calling site of expand_binop,
2590      i.e. expand_expr.  */
2591   REG_NOTES (last)
2592     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2593                          REG_NOTES (last));
2594   DONE;
2595 }")
2596
2597 (define_expand "umulhisi3"
2598   [(set (reg:SI MACL_REG)
2599         (mult:SI (zero_extend:SI
2600                   (match_operand:HI 1 "arith_reg_operand" ""))
2601                  (zero_extend:SI
2602                   (match_operand:HI 2 "arith_reg_operand" ""))))
2603    (set (match_operand:SI 0 "arith_reg_operand" "")
2604         (reg:SI MACL_REG))]
2605   "TARGET_SH1"
2606   "
2607 {
2608   rtx first, last;
2609
2610   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2611   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2612   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2613      invariant code motion can move it.  */
2614   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2615   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2616   /* expand_binop can't find a suitable code in umul_widen_optab to
2617      make a REG_EQUAL note from, so make one here.
2618      See also smulsi3_highpart.
2619      ??? Alternatively, we could put this at the calling site of expand_binop,
2620      i.e. expand_expr.  */
2621   REG_NOTES (last)
2622     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2623                          REG_NOTES (last));
2624   DONE;
2625 }")
2626
2627 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2628 ;; a call to a routine which clobbers known registers.
2629
2630 (define_insn ""
2631   [(set (match_operand:SI 1 "register_operand" "=z")
2632         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2633    (clobber (reg:SI MACL_REG))
2634    (clobber (reg:SI T_REG))
2635    (clobber (reg:SI PR_REG))
2636    (clobber (reg:SI R3_REG))
2637    (clobber (reg:SI R2_REG))
2638    (clobber (reg:SI R1_REG))
2639    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2640   "TARGET_SH1"
2641   "jsr  @%0%#"
2642   [(set_attr "type" "sfunc")
2643    (set_attr "needs_delay_slot" "yes")])
2644
2645 (define_expand "mulsi3_call"
2646   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2647    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2648    (parallel[(set (match_operand:SI 0 "register_operand" "")
2649                   (mult:SI (reg:SI R4_REG)
2650                            (reg:SI R5_REG)))
2651              (clobber (reg:SI MACL_REG))
2652              (clobber (reg:SI T_REG))
2653              (clobber (reg:SI PR_REG))
2654              (clobber (reg:SI R3_REG))
2655              (clobber (reg:SI R2_REG))
2656              (clobber (reg:SI R1_REG))
2657              (use (match_operand:SI 3 "register_operand" ""))])]
2658   "TARGET_SH1"
2659   "")
2660
2661 (define_insn "mul_r"
2662   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2663         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2664                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2665   "TARGET_SH2A"
2666   "mulr %2,%0"
2667   [(set_attr "type" "dmpy")])
2668
2669 (define_insn "mul_l"
2670   [(set (reg:SI MACL_REG)
2671         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2672                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2673   "TARGET_SH2"
2674   "mul.l        %1,%0"
2675   [(set_attr "type" "dmpy")])
2676
2677 (define_expand "mulsi3"
2678   [(set (reg:SI MACL_REG)
2679         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2680                   (match_operand:SI 2 "arith_reg_operand" "")))
2681    (set (match_operand:SI 0 "arith_reg_operand" "")
2682         (reg:SI MACL_REG))]
2683   "TARGET_SH1"
2684   "
2685 {
2686   rtx first, last;
2687
2688   if (!TARGET_SH2)
2689     {
2690       /* The address must be set outside the libcall,
2691          since it goes into a pseudo.  */
2692       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2693       rtx addr = force_reg (SImode, sym);
2694       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2695                                    operands[2], addr);
2696       first = insns;
2697       last = emit_insn (insns);
2698     }
2699   else
2700     {
2701       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2702
2703       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2704       /* consec_sets_giv can only recognize the first insn that sets a
2705          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2706          note.  */
2707       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2708     }
2709   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2710      invariant code motion can move it.  */
2711   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2712   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2713   DONE;
2714 }")
2715
2716 (define_insn "mulsidi3_i"
2717   [(set (reg:SI MACH_REG)
2718         (truncate:SI
2719          (lshiftrt:DI
2720           (mult:DI
2721            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2722            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2723           (const_int 32))))
2724    (set (reg:SI MACL_REG)
2725         (mult:SI (match_dup 0)
2726                  (match_dup 1)))]
2727   "TARGET_SH2"
2728   "dmuls.l      %1,%0"
2729   [(set_attr "type" "dmpy")])
2730
2731 (define_expand "mulsidi3"
2732   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2733         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2734                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2735   "TARGET_SH2 || TARGET_SHMEDIA"
2736   "
2737 {
2738   if (TARGET_SH2)
2739     {
2740        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2741                                         operands[2]));
2742        DONE;
2743     }
2744 }")
2745
2746 (define_insn "mulsidi3_media"
2747   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2748         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2749                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2750   "TARGET_SHMEDIA"
2751   "muls.l       %1, %2, %0"
2752   [(set_attr "type" "dmpy_media")
2753    (set_attr "highpart" "ignore")])
2754
2755 (define_insn "mulsidi3_compact"
2756   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2757         (mult:DI
2758          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2759          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2760    (clobber (reg:SI MACH_REG))
2761    (clobber (reg:SI MACL_REG))]
2762   "TARGET_SH2"
2763   "#")
2764
2765 (define_split
2766   [(set (match_operand:DI 0 "arith_reg_dest" "")
2767         (mult:DI
2768          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2769          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2770    (clobber (reg:SI MACH_REG))
2771    (clobber (reg:SI MACL_REG))]
2772   "TARGET_SH2"
2773   [(const_int 0)]
2774   "
2775 {
2776   rtx low_dst = gen_lowpart (SImode, operands[0]);
2777   rtx high_dst = gen_highpart (SImode, operands[0]);
2778
2779   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2780
2781   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2782   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2783   /* We need something to tag the possible REG_EQUAL notes on to.  */
2784   emit_move_insn (operands[0], operands[0]);
2785   DONE;
2786 }")
2787
2788 (define_insn "umulsidi3_i"
2789   [(set (reg:SI MACH_REG)
2790         (truncate:SI
2791          (lshiftrt:DI
2792           (mult:DI
2793            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2794            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2795           (const_int 32))))
2796    (set (reg:SI MACL_REG)
2797         (mult:SI (match_dup 0)
2798                  (match_dup 1)))]
2799   "TARGET_SH2"
2800   "dmulu.l      %1,%0"
2801   [(set_attr "type" "dmpy")])
2802
2803 (define_expand "umulsidi3"
2804   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2805         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2806                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2807   "TARGET_SH2 || TARGET_SHMEDIA"
2808   "
2809 {
2810   if (TARGET_SH2)
2811     {
2812        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2813                                          operands[2]));
2814        DONE;
2815     }
2816 }")
2817
2818 (define_insn "umulsidi3_media"
2819   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2820         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2821                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2822   "TARGET_SHMEDIA"
2823   "mulu.l       %1, %2, %0"
2824   [(set_attr "type" "dmpy_media")
2825    (set_attr "highpart" "ignore")])
2826
2827 (define_insn "umulsidi3_compact"
2828   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2829         (mult:DI
2830          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2831          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2832    (clobber (reg:SI MACH_REG))
2833    (clobber (reg:SI MACL_REG))]
2834   "TARGET_SH2"
2835   "#")
2836
2837 (define_split
2838   [(set (match_operand:DI 0 "arith_reg_dest" "")
2839         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2840                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2841    (clobber (reg:SI MACH_REG))
2842    (clobber (reg:SI MACL_REG))]
2843   "TARGET_SH2"
2844   [(const_int 0)]
2845   "
2846 {
2847   rtx low_dst = gen_lowpart (SImode, operands[0]);
2848   rtx high_dst = gen_highpart (SImode, operands[0]);
2849
2850   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2851
2852   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2853   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2854   /* We need something to tag the possible REG_EQUAL notes on to.  */
2855   emit_move_insn (operands[0], operands[0]);
2856   DONE;
2857 }")
2858
2859 (define_insn "smulsi3_highpart_i"
2860   [(set (reg:SI MACH_REG)
2861         (truncate:SI
2862          (lshiftrt:DI
2863           (mult:DI
2864            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2865            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2866           (const_int 32))))
2867    (clobber (reg:SI MACL_REG))]
2868   "TARGET_SH2"
2869   "dmuls.l      %1,%0"
2870   [(set_attr "type" "dmpy")])
2871
2872 (define_expand "smulsi3_highpart"
2873   [(parallel
2874     [(set (reg:SI MACH_REG)
2875           (truncate:SI
2876            (lshiftrt:DI
2877             (mult:DI
2878              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2879              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2880             (const_int 32))))
2881     (clobber (reg:SI MACL_REG))])
2882    (set (match_operand:SI 0 "arith_reg_operand" "")
2883         (reg:SI MACH_REG))]
2884   "TARGET_SH2"
2885   "
2886 {
2887   rtx first, last;
2888
2889   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2890   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2891   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2892      invariant code motion can move it.  */
2893   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2894   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2895   /* expand_binop can't find a suitable code in mul_highpart_optab to
2896      make a REG_EQUAL note from, so make one here.
2897      See also {,u}mulhisi.
2898      ??? Alternatively, we could put this at the calling site of expand_binop,
2899      i.e. expand_mult_highpart.  */
2900   REG_NOTES (last)
2901     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2902                          REG_NOTES (last));
2903   DONE;
2904 }")
2905
2906 (define_insn "umulsi3_highpart_i"
2907   [(set (reg:SI MACH_REG)
2908         (truncate:SI
2909          (lshiftrt:DI
2910           (mult:DI
2911            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2912            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2913           (const_int 32))))
2914    (clobber (reg:SI MACL_REG))]
2915   "TARGET_SH2"
2916   "dmulu.l      %1,%0"
2917   [(set_attr "type" "dmpy")])
2918
2919 (define_expand "umulsi3_highpart"
2920   [(parallel
2921     [(set (reg:SI MACH_REG)
2922           (truncate:SI
2923            (lshiftrt:DI
2924             (mult:DI
2925              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2926              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2927             (const_int 32))))
2928     (clobber (reg:SI MACL_REG))])
2929    (set (match_operand:SI 0 "arith_reg_operand" "")
2930         (reg:SI MACH_REG))]
2931   "TARGET_SH2"
2932   "
2933 {
2934   rtx first, last;
2935
2936   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2937   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2938   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2939      invariant code motion can move it.  */
2940   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2941   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2942   DONE;
2943 }")
2944
2945 (define_insn_and_split "muldi3"
2946   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2947         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2948                  (match_operand:DI 2 "arith_reg_operand" "r")))
2949    (clobber (match_scratch:DI 3 "=&r"))
2950    (clobber (match_scratch:DI 4 "=r"))]
2951   "TARGET_SHMEDIA"
2952   "#"
2953   "reload_completed"
2954   [(const_int 0)]
2955   "
2956 {
2957   rtx op3_v2si, op2_v2si;
2958
2959   op3_v2si = operands[3];
2960   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2961     {
2962       op3_v2si = XEXP (op3_v2si, 0);
2963       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2964     }
2965   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2966   op2_v2si = operands[2];
2967   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2968     {
2969       op2_v2si = XEXP (op2_v2si, 0);
2970       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2971     }
2972   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2973   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2974   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2975   emit_insn (gen_umulsidi3_media (operands[4],
2976                                  sh_gen_truncate (SImode, operands[1], 0),
2977                                  sh_gen_truncate (SImode, operands[2], 0)));
2978   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2979   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2980   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2981   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2982   DONE;
2983 }")
2984
2985 \f
2986 ;; -------------------------------------------------------------------------
2987 ;; Logical operations
2988 ;; -------------------------------------------------------------------------
2989
2990 (define_insn "*andsi3_compact"
2991   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2992         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2993                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2994   "TARGET_SH1"
2995   "and  %2,%0"
2996   [(set_attr "type" "arith")])
2997
2998 (define_insn "*andsi3_media"
2999   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3000         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3001                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3002   "TARGET_SHMEDIA"
3003   "@
3004         and     %1, %2, %0
3005         andi    %1, %2, %0"
3006   [(set_attr "type" "arith_media")])
3007
3008 ;; If the constant is 255, then emit an extu.b instruction instead of an
3009 ;; and, since that will give better code.
3010
3011 (define_expand "andsi3"
3012   [(set (match_operand:SI 0 "arith_reg_operand" "")
3013         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3014                 (match_operand:SI 2 "logical_operand" "")))]
3015   ""
3016   "
3017 {
3018   if (TARGET_SH1
3019       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3020     {
3021       emit_insn (gen_zero_extendqisi2 (operands[0],
3022                                        gen_lowpart (QImode, operands[1])));
3023       DONE;
3024     }
3025 }")
3026
3027 (define_insn_and_split "anddi3"
3028   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3029         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3030                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3031   "TARGET_SHMEDIA"
3032   "@
3033         and     %1, %2, %0
3034         andi    %1, %2, %0
3035         #"
3036   "reload_completed
3037    && ! logical_operand (operands[2], DImode)"
3038   [(const_int 0)]
3039   "
3040 {
3041   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3042     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3043   else
3044     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3045   DONE;
3046 }"
3047   [(set_attr "type" "arith_media")])
3048
3049 (define_insn "andcsi3"
3050   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3051         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3052                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3053   "TARGET_SHMEDIA"
3054   "andc %1,%2,%0"
3055   [(set_attr "type" "arith_media")])
3056
3057 (define_insn "andcdi3"
3058   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3059         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3060                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3061   "TARGET_SHMEDIA"
3062   "andc %1,%2,%0"
3063   [(set_attr "type" "arith_media")])
3064
3065 (define_expand "iorsi3"
3066   [(set (match_operand:SI 0 "arith_reg_operand" "")
3067         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3068                 (match_operand:SI 2 "logical_operand" "")))]
3069   ""
3070   "")
3071
3072 (define_insn "*iorsi3_compact"
3073   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3074         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3075                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3076   "TARGET_SH1"
3077   "or   %2,%0"
3078   [(set_attr "type" "arith")])
3079
3080 (define_insn "*iorsi3_media"
3081   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3082         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3083                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3084   "TARGET_SHMEDIA"
3085   "@
3086         or      %1, %2, %0
3087         ori     %1, %2, %0"
3088   [(set_attr "type" "arith_media")])
3089
3090 (define_insn "iordi3"
3091   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3092         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3093                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3094   "TARGET_SHMEDIA"
3095   "@
3096         or      %1, %2, %0
3097         ori     %1, %2, %0"
3098   [(set_attr "type" "arith_media")])
3099
3100 (define_insn_and_split "*logical_sidi3"
3101   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3102         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3103                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3104                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3105   "TARGET_SHMEDIA"
3106   "#"
3107   "&& reload_completed"
3108   [(set (match_dup 0) (match_dup 3))]
3109   "
3110 {
3111   operands[3]
3112     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3113                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3114                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3115 }")
3116
3117 (define_insn_and_split "*logical_sidisi3"
3118   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3119         (truncate:SI (sign_extend:DI
3120                         (match_operator:SI 3 "logical_operator"
3121                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3122                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3123   "TARGET_SHMEDIA"
3124   "#"
3125   "&& 1"
3126   [(set (match_dup 0) (match_dup 3))])
3127
3128 (define_insn_and_split "*logical_sidi3_2"
3129   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3130         (sign_extend:DI (truncate:SI (sign_extend:DI
3131                         (match_operator:SI 3 "logical_operator"
3132                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3133                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3134   "TARGET_SHMEDIA"
3135   "#"
3136   "&& 1"
3137   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3138
3139 (define_expand "xorsi3"
3140   [(set (match_operand:SI 0 "arith_reg_operand" "")
3141         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3142                 (match_operand:SI 2 "xor_operand" "")))]
3143   ""
3144   "")
3145
3146 (define_insn "*xorsi3_compact"
3147   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3148         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3149                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3150   "TARGET_SH1"
3151   "xor  %2,%0"
3152   [(set_attr "type" "arith")])
3153
3154 (define_insn "*xorsi3_media"
3155   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3156         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3157                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3158   "TARGET_SHMEDIA"
3159   "@
3160         xor     %1, %2, %0
3161         xori    %1, %2, %0"
3162   [(set_attr "type" "arith_media")])
3163
3164 (define_insn "xordi3"
3165   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3166         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3167                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3168   "TARGET_SHMEDIA"
3169   "@
3170         xor     %1, %2, %0
3171         xori    %1, %2, %0"
3172   [(set_attr "type" "arith_media")])
3173
3174 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3175 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3176 (define_split
3177   [(set (match_operand:DI 0 "arith_reg_dest" "")
3178         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3179                           [(match_operand 1 "any_register_operand" "")
3180                            (match_operand 2 "any_register_operand" "")])))]
3181   "TARGET_SHMEDIA"
3182   [(set (match_dup 5) (match_dup 4))
3183    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3184 "
3185 {
3186   enum machine_mode inmode = GET_MODE (operands[1]);
3187   int offset = 0;
3188
3189   if (GET_CODE (operands[0]) == SUBREG)
3190     {
3191       offset = SUBREG_BYTE (operands[0]);
3192       operands[0] = SUBREG_REG (operands[0]);
3193     }
3194   gcc_assert (GET_CODE (operands[0]) == REG);
3195   if (! TARGET_LITTLE_ENDIAN)
3196     offset += 8 - GET_MODE_SIZE (inmode);
3197   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3198 }")
3199 \f
3200 ;; -------------------------------------------------------------------------
3201 ;; Shifts and rotates
3202 ;; -------------------------------------------------------------------------
3203
3204 (define_expand "rotldi3"
3205   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3206         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3207                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3208   "TARGET_SHMEDIA"
3209   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3210
3211 (define_insn "rotldi3_mextr"
3212   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3213         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3214                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3215   "TARGET_SHMEDIA"
3216   "*
3217 {
3218   static char templ[16];
3219
3220   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3221            8 - (int) (INTVAL (operands[2]) >> 3));
3222   return templ;
3223 }"
3224   [(set_attr "type" "arith_media")])
3225
3226 (define_expand "rotrdi3"
3227   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3228         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3229                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3230   "TARGET_SHMEDIA"
3231   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3232
3233 (define_insn "rotrdi3_mextr"
3234   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3235         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3236                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3237   "TARGET_SHMEDIA"
3238   "*
3239 {
3240   static char templ[16];
3241
3242   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3243   return templ;
3244 }"
3245   [(set_attr "type" "arith_media")])
3246
3247 (define_split
3248   [(set (match_operand:DI 0 "arith_reg_dest" "")
3249         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3250                                          "ua_address_operand" "")))
3251                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3252                            (const_int 8))))
3253    (clobber (match_operand:DI 3 "register_operand" ""))]
3254   "TARGET_SHMEDIA"
3255   [(match_dup 4) (match_dup 5)]
3256   "
3257 {
3258   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3259                  (operands[3], operands[1]));
3260   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3261                               GEN_INT (56), GEN_INT (8));
3262 }")
3263
3264 (define_insn "rotlsi3_1"
3265   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3266         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3267                    (const_int 1)))
3268    (set (reg:SI T_REG)
3269         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3270   "TARGET_SH1"
3271   "rotl %0"
3272   [(set_attr "type" "arith")])
3273
3274 (define_insn "rotlsi3_31"
3275   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3276         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3277                    (const_int 31)))
3278    (clobber (reg:SI T_REG))]
3279   "TARGET_SH1"
3280   "rotr %0"
3281   [(set_attr "type" "arith")])
3282
3283 (define_insn "rotlsi3_16"
3284   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3285         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3286                    (const_int 16)))]
3287   "TARGET_SH1"
3288   "swap.w       %1,%0"
3289   [(set_attr "type" "arith")])
3290
3291 (define_expand "rotlsi3"
3292   [(set (match_operand:SI 0 "arith_reg_dest" "")
3293         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3294                    (match_operand:SI 2 "immediate_operand" "")))]
3295   "TARGET_SH1"
3296   "
3297 {
3298   static const char rot_tab[] = {
3299     000, 000, 000, 000, 000, 000, 010, 001,
3300     001, 001, 011, 013, 003, 003, 003, 003,
3301     003, 003, 003, 003, 003, 013, 012, 002,
3302     002, 002, 010, 000, 000, 000, 000, 000,
3303   };
3304
3305   int count, choice;
3306
3307   if (GET_CODE (operands[2]) != CONST_INT)
3308     FAIL;
3309   count = INTVAL (operands[2]);
3310   choice = rot_tab[count];
3311   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3312     FAIL;
3313   choice &= 7;
3314   switch (choice)
3315     {
3316     case 0:
3317       emit_move_insn (operands[0], operands[1]);
3318       count -= (count & 16) * 2;
3319       break;
3320     case 3:
3321      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3322      count -= 16;
3323      break;
3324     case 1:
3325     case 2:
3326       {
3327         rtx parts[2];
3328         parts[0] = gen_reg_rtx (SImode);
3329         parts[1] = gen_reg_rtx (SImode);
3330         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3331         emit_move_insn (parts[choice-1], operands[1]);
3332         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3333         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3334         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3335         count = (count & ~16) - 8;
3336       }
3337     }
3338
3339   for (; count > 0; count--)
3340     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3341   for (; count < 0; count++)
3342     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3343
3344   DONE;
3345 }")
3346
3347 (define_insn "*rotlhi3_8"
3348   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3349         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3350                    (const_int 8)))]
3351   "TARGET_SH1"
3352   "swap.b       %1,%0"
3353   [(set_attr "type" "arith")])
3354
3355 (define_expand "rotlhi3"
3356   [(set (match_operand:HI 0 "arith_reg_operand" "")
3357         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3358                    (match_operand:HI 2 "immediate_operand" "")))]
3359   "TARGET_SH1"
3360   "
3361 {
3362   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3363     FAIL;
3364 }")
3365
3366 ;;
3367 ;; shift left
3368
3369 (define_insn "ashlsi3_sh2a"
3370   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3371         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3372                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3373   "TARGET_SH2A"
3374   "shad %2,%0"
3375   [(set_attr "type" "arith")
3376    (set_attr "length" "4")])
3377
3378 ;; This pattern is used by init_expmed for computing the costs of shift
3379 ;; insns.
3380
3381 (define_insn_and_split "ashlsi3_std"
3382   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3383         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3384                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3385    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3386   "TARGET_SH3
3387    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3388        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3389   "@
3390    shld %2,%0
3391    add  %0,%0
3392    shll%O2      %0
3393    #"
3394   "TARGET_SH3
3395    && reload_completed
3396    && GET_CODE (operands[2]) == CONST_INT
3397    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3398   [(set (match_dup 3) (match_dup 2))
3399    (parallel
3400     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3401      (clobber (match_dup 4))])]
3402   "operands[4] = gen_rtx_SCRATCH (SImode);"
3403   [(set_attr "length" "*,*,*,4")
3404    (set_attr "type" "dyn_shift,arith,arith,arith")])
3405
3406 (define_insn "ashlhi3_k"
3407   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3408         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3409                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3410   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3411   "@
3412         add     %0,%0
3413         shll%O2 %0"
3414   [(set_attr "type" "arith")])
3415
3416 (define_insn "ashlsi3_n"
3417   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3418         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3419                    (match_operand:SI 2 "const_int_operand" "n")))
3420    (clobber (reg:SI T_REG))]
3421   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3422   "#"
3423   [(set (attr "length")
3424         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3425                (const_string "2")
3426                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3427                (const_string "4")
3428                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3429                (const_string "6")]
3430               (const_string "8")))
3431    (set_attr "type" "arith")])
3432
3433 (define_split
3434   [(set (match_operand:SI 0 "arith_reg_dest" "")
3435         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3436                    (match_operand:SI 2 "const_int_operand" "")))
3437    (clobber (reg:SI T_REG))]
3438   "TARGET_SH1 && reload_completed"
3439   [(use (reg:SI R0_REG))]
3440   "
3441 {
3442   gen_shifty_op (ASHIFT, operands);
3443   DONE;
3444 }")
3445
3446 (define_insn "ashlsi3_media"
3447   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3448         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3449                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3450   "TARGET_SHMEDIA"
3451   "@
3452         shlld.l %1, %2, %0
3453         shlli.l %1, %2, %0"
3454   [(set_attr "type" "arith_media")
3455    (set_attr "highpart" "ignore")])
3456
3457 (define_expand "ashlsi3"
3458   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3459                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3460                               (match_operand:SI 2 "nonmemory_operand" "")))
3461               (clobber (reg:SI T_REG))])]
3462   ""
3463   "
3464 {
3465   if (TARGET_SHMEDIA)
3466     {
3467       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3468       DONE;
3469     }
3470   if (GET_CODE (operands[2]) == CONST_INT
3471       && sh_dynamicalize_shift_p (operands[2]))
3472     operands[2] = force_reg (SImode, operands[2]);
3473   if (TARGET_SH3)
3474     {
3475       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3476       DONE;
3477     }
3478   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3479     FAIL;
3480 }")
3481
3482 (define_insn "*ashlhi3_n"
3483   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3484         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3485                    (match_operand:HI 2 "const_int_operand" "n")))
3486    (clobber (reg:SI T_REG))]
3487   "TARGET_SH1"
3488   "#"
3489   [(set (attr "length")
3490         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3491                (const_string "2")
3492                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3493                (const_string "4")]
3494               (const_string "6")))
3495    (set_attr "type" "arith")])
3496
3497 (define_expand "ashlhi3"
3498   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3499                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3500                               (match_operand:SI 2 "nonmemory_operand" "")))
3501               (clobber (reg:SI T_REG))])]
3502   "TARGET_SH1"
3503   "
3504 {
3505   if (GET_CODE (operands[2]) != CONST_INT)
3506     FAIL;
3507   /* It may be possible to call gen_ashlhi3 directly with more generic
3508      operands.  Make sure operands[1] is a HImode register here.  */
3509   if (!arith_reg_operand (operands[1], HImode))
3510     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3511 }")
3512
3513 (define_split
3514   [(set (match_operand:HI 0 "arith_reg_dest" "")
3515         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3516                    (match_operand:HI 2 "const_int_operand" "")))
3517    (clobber (reg:SI T_REG))]
3518   "TARGET_SH1 && reload_completed"
3519   [(use (reg:SI R0_REG))]
3520   "
3521 {
3522   gen_shifty_hi_op (ASHIFT, operands);
3523   DONE;
3524 }")
3525
3526 ;
3527 ; arithmetic shift right
3528 ;
3529
3530 (define_insn "ashrsi3_sh2a"
3531   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3532         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3533                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3534   "TARGET_SH2A"
3535   "shad %2,%0"
3536   [(set_attr "type" "dyn_shift")
3537    (set_attr "length" "4")])
3538
3539 (define_insn "ashrsi3_k"
3540   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3541         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3542                      (match_operand:SI 2 "const_int_operand" "M")))
3543    (clobber (reg:SI T_REG))]
3544   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3545   "shar %0"
3546   [(set_attr "type" "arith")])
3547
3548 ;; We can't do HImode right shifts correctly unless we start out with an
3549 ;; explicit zero / sign extension; doing that would result in worse overall
3550 ;; code, so just let the machine independent code widen the mode.
3551 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3552
3553
3554 ;; ??? This should be a define expand.
3555
3556 (define_insn "ashrsi2_16"
3557   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3558         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3559                      (const_int 16)))]
3560   "TARGET_SH1"
3561   "#"
3562   [(set_attr "length" "4")])
3563
3564 (define_split
3565   [(set (match_operand:SI 0 "arith_reg_dest" "")
3566         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3567                      (const_int 16)))]
3568   "TARGET_SH1"
3569   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3570    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3571   "operands[2] = gen_lowpart (HImode, operands[0]);")
3572
3573 ;; ??? This should be a define expand.
3574
3575 (define_insn "ashrsi2_31"
3576   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3577         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3578                      (const_int 31)))
3579    (clobber (reg:SI T_REG))]
3580   "TARGET_SH1"
3581   "#"
3582   [(set_attr "length" "4")])
3583
3584 (define_split
3585   [(set (match_operand:SI 0 "arith_reg_dest" "")
3586         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3587                      (const_int 31)))
3588    (clobber (reg:SI T_REG))]
3589   "TARGET_SH1"
3590   [(const_int 0)]
3591   "
3592 {
3593   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3594   emit_insn (gen_mov_neg_si_t (operands[0]));
3595   DONE;
3596 }")
3597
3598 (define_peephole2
3599   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3600    (set (reg:SI T_REG)
3601         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3602   "TARGET_SH1
3603    && peep2_reg_dead_p (2, operands[0])
3604    && peep2_reg_dead_p (2, operands[1])"
3605   [(const_int 0)]
3606   "
3607 {
3608   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3609   DONE;
3610 }")
3611
3612 (define_insn "ashlsi_c"
3613   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3614         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3615    (set (reg:SI T_REG)
3616         (lt:SI (match_dup 1) (const_int 0)))]
3617   "TARGET_SH1"
3618   "shll %0"
3619   [(set_attr "type" "arith")])
3620
3621 (define_insn "*ashlsi_c_void"
3622   [(set (reg:SI T_REG)
3623         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3624    (clobber (match_scratch:SI 1 "=0"))]
3625   "TARGET_SH1 && cse_not_expected"
3626   "shll %0"
3627   [(set_attr "type" "arith")])
3628
3629 (define_insn "ashrsi3_d"
3630   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3631         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3632                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3633   "TARGET_SH3"
3634   "shad %2,%0"
3635   [(set_attr "type" "dyn_shift")])
3636
3637 (define_insn "ashrsi3_n"
3638   [(set (reg:SI R4_REG)
3639         (ashiftrt:SI (reg:SI R4_REG)
3640                      (match_operand:SI 0 "const_int_operand" "i")))
3641    (clobber (reg:SI T_REG))
3642    (clobber (reg:SI PR_REG))
3643    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3644   "TARGET_SH1"
3645   "jsr  @%1%#"
3646   [(set_attr "type" "sfunc")
3647    (set_attr "needs_delay_slot" "yes")])
3648
3649 (define_insn "ashrsi3_media"
3650   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3651         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3652                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3653   "TARGET_SHMEDIA"
3654   "@
3655         shard.l %1, %2, %0
3656         shari.l %1, %2, %0"
3657   [(set_attr "type" "arith_media")
3658    (set_attr "highpart" "ignore")])
3659
3660 (define_expand "ashrsi3"
3661   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3662                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3663                                 (match_operand:SI 2 "nonmemory_operand" "")))
3664               (clobber (reg:SI T_REG))])]
3665   ""
3666   "
3667 {
3668   if (TARGET_SHMEDIA)
3669     {
3670       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3671       DONE;
3672     }
3673   if (expand_ashiftrt (operands))
3674     DONE;
3675   else
3676     FAIL;
3677 }")
3678
3679 ;; logical shift right
3680
3681 (define_insn "lshrsi3_sh2a"
3682   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3683         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3684                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3685   "TARGET_SH2A"
3686   "shld %2,%0"
3687   [(set_attr "type" "dyn_shift")
3688    (set_attr "length" "4")])
3689
3690 (define_insn "lshrsi3_d"
3691   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3692         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3693                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3694   "TARGET_SH3"
3695   "shld %2,%0"
3696   [(set_attr "type" "dyn_shift")])
3697
3698 ;;  Only the single bit shift clobbers the T bit.
3699
3700 (define_insn "lshrsi3_m"
3701   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3702         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3703                      (match_operand:SI 2 "const_int_operand" "M")))
3704    (clobber (reg:SI T_REG))]
3705   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3706   "shlr %0"
3707   [(set_attr "type" "arith")])
3708
3709 (define_insn "lshrsi3_k"
3710   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3711         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3712                      (match_operand:SI 2 "const_int_operand" "P27")))]
3713   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3714    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3715   "shlr%O2      %0"
3716   [(set_attr "type" "arith")])
3717
3718 (define_insn "lshrsi3_n"
3719   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3720         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3721                      (match_operand:SI 2 "const_int_operand" "n")))
3722    (clobber (reg:SI T_REG))]
3723   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3724   "#"
3725   [(set (attr "length")
3726         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3727                (const_string "2")
3728                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3729                (const_string "4")
3730                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3731                (const_string "6")]
3732               (const_string "8")))
3733    (set_attr "type" "arith")])
3734
3735 (define_split
3736   [(set (match_operand:SI 0 "arith_reg_dest" "")
3737         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3738                      (match_operand:SI 2 "const_int_operand" "")))
3739    (clobber (reg:SI T_REG))]
3740   "TARGET_SH1 && reload_completed"
3741   [(use (reg:SI R0_REG))]
3742   "
3743 {
3744   gen_shifty_op (LSHIFTRT, operands);
3745   DONE;
3746 }")
3747
3748 (define_insn "lshrsi3_media"
3749   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3750         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3751                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3752   "TARGET_SHMEDIA"
3753   "@
3754         shlrd.l %1, %2, %0
3755         shlri.l %1, %2, %0"
3756   [(set_attr "type" "arith_media")
3757    (set_attr "highpart" "ignore")])
3758
3759 (define_expand "lshrsi3"
3760   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3761                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3762                                 (match_operand:SI 2 "nonmemory_operand" "")))
3763               (clobber (reg:SI T_REG))])]
3764   ""
3765   "
3766 {
3767   if (TARGET_SHMEDIA)
3768     {
3769       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3770       DONE;
3771     }
3772   if (GET_CODE (operands[2]) == CONST_INT
3773       && sh_dynamicalize_shift_p (operands[2]))
3774     operands[2] = force_reg (SImode, operands[2]);
3775   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3776     {
3777       rtx count = copy_to_mode_reg (SImode, operands[2]);
3778       emit_insn (gen_negsi2 (count, count));
3779       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3780       DONE;
3781     }
3782   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3783     FAIL;
3784 }")
3785
3786 ;; ??? This should be a define expand.
3787
3788 (define_insn "ashldi3_k"
3789   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3790         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3791                    (const_int 1)))
3792    (clobber (reg:SI T_REG))]
3793   "TARGET_SH1"
3794   "shll %R0\;rotcl      %S0"
3795   [(set_attr "length" "4")
3796    (set_attr "type" "arith")])
3797
3798 (define_insn "ashldi3_media"
3799   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3800         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3801                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3802   "TARGET_SHMEDIA"
3803   "@
3804         shlld   %1, %2, %0
3805         shlli   %1, %2, %0"
3806   [(set_attr "type" "arith_media")])
3807
3808 (define_insn "*ashldisi3_media"
3809   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3810         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3811                    (match_operand:DI 2 "const_int_operand" "n")))]
3812   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3813   "shlli.l      %1, %2, %0"
3814   [(set_attr "type" "arith_media")
3815    (set_attr "highpart" "ignore")])
3816
3817 (define_expand "ashldi3"
3818   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3819                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3820                               (match_operand:DI 2 "immediate_operand" "")))
3821               (clobber (reg:SI T_REG))])]
3822   ""
3823   "
3824 {
3825   if (TARGET_SHMEDIA)
3826     {
3827       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3828       DONE;
3829     }
3830   if (GET_CODE (operands[2]) != CONST_INT
3831       || INTVAL (operands[2]) != 1)
3832     FAIL;
3833 }")
3834
3835 ;; ??? This should be a define expand.
3836
3837 (define_insn "lshrdi3_k"
3838   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3839         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3840                      (const_int 1)))
3841    (clobber (reg:SI T_REG))]
3842   "TARGET_SH1"
3843   "shlr %S0\;rotcr      %R0"
3844   [(set_attr "length" "4")
3845    (set_attr "type" "arith")])
3846
3847 (define_insn "lshrdi3_media"
3848   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3849         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3850                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3851   "TARGET_SHMEDIA
3852    && (arith_reg_dest (operands[0], DImode)
3853        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3854   "@
3855         shlrd   %1, %2, %0
3856         shlri   %1, %2, %0"
3857   [(set_attr "type" "arith_media")])
3858
3859 (define_insn "*lshrdisi3_media"
3860   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3861         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3862                      (match_operand:DI 2 "const_int_operand" "n")))]
3863   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3864   "shlri.l      %1, %2, %0"
3865   [(set_attr "type" "arith_media")
3866    (set_attr "highpart" "ignore")])
3867
3868 (define_expand "lshrdi3"
3869   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3870                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3871                                (match_operand:DI 2 "immediate_operand" "")))
3872              (clobber (reg:SI T_REG))])]
3873   ""
3874   "
3875 {
3876   if (TARGET_SHMEDIA)
3877     {
3878       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3879       DONE;
3880     }
3881   if (GET_CODE (operands[2]) != CONST_INT
3882       || INTVAL (operands[2]) != 1)
3883     FAIL;
3884 }")
3885
3886 ;; ??? This should be a define expand.
3887
3888 (define_insn "ashrdi3_k"
3889   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3890         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3891                      (const_int 1)))
3892    (clobber (reg:SI T_REG))]
3893   "TARGET_SH1"
3894   "shar %S0\;rotcr      %R0"
3895   [(set_attr "length" "4")
3896    (set_attr "type" "arith")])
3897
3898 (define_insn "ashrdi3_media"
3899   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3900         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3901                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3902   "TARGET_SHMEDIA
3903    && (arith_reg_dest (operands[0], DImode)
3904        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3905   "@
3906         shard   %1, %2, %0
3907         shari   %1, %2, %0"
3908   [(set_attr "type" "arith_media")])
3909
3910 (define_insn "*ashrdisi3_media"
3911   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3912         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3913                      (match_operand:DI 2 "const_int_operand" "n")))]
3914   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3915   "shari.l      %1, %2, %0"
3916   [(set_attr "type" "arith_media")
3917    (set_attr "highpart" "ignore")])
3918
3919 (define_insn "ashrdisi3_media_high"
3920   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3921         (truncate:SI
3922            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3923                         (match_operand:DI 2 "const_int_operand" "n"))))]
3924   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3925   "shari        %1, %2, %0"
3926   [(set_attr "type" "arith_media")])
3927
3928 (define_insn "ashrdisi3_media_opaque"
3929   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3930         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3931                     (match_operand:DI 2 "const_int_operand" "n")]
3932          UNSPEC_ASHIFTRT))]
3933   "TARGET_SHMEDIA"
3934   "shari        %1, %2, %0"
3935   [(set_attr "type" "arith_media")])
3936
3937 (define_expand "ashrdi3"
3938   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3939                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3940                                 (match_operand:DI 2 "immediate_operand" "")))
3941               (clobber (reg:SI T_REG))])]
3942   ""
3943   "
3944 {
3945   if (TARGET_SHMEDIA)
3946     {
3947       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3948       DONE;
3949     }
3950   if (GET_CODE (operands[2]) != CONST_INT
3951       || INTVAL (operands[2]) != 1)
3952     FAIL;
3953 }")
3954
3955 ;; combined left/right shift
3956
3957 (define_split
3958   [(set (match_operand:SI 0 "register_operand" "")
3959         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3960                            (match_operand:SI 2 "const_int_operand" ""))
3961                 (match_operand:SI 3 "const_int_operand" "")))]
3962   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3963   [(use (reg:SI R0_REG))]
3964   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3965    DONE;")
3966
3967 (define_split
3968   [(set (match_operand:SI 0 "register_operand" "")
3969         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3970                            (match_operand:SI 2 "const_int_operand" ""))
3971                 (match_operand:SI 3 "const_int_operand" "")))
3972    (clobber (reg:SI T_REG))]
3973   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3974   [(use (reg:SI R0_REG))]
3975   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3976    DONE;")
3977
3978 (define_insn ""
3979   [(set (match_operand:SI 0 "register_operand" "=r")
3980         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3981                            (match_operand:SI 2 "const_int_operand" "n"))
3982                 (match_operand:SI 3 "const_int_operand" "n")))
3983    (clobber (reg:SI T_REG))]
3984   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3985  "#"
3986   [(set (attr "length")
3987         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3988                (const_string "4")
3989                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3990                (const_string "6")
3991                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3992                (const_string "8")
3993                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
3994                (const_string "10")
3995                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
3996                (const_string "12")
3997                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
3998                (const_string "14")
3999                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4000                (const_string "16")]
4001               (const_string "18")))
4002    (set_attr "type" "arith")])
4003
4004 (define_insn ""
4005   [(set (match_operand:SI 0 "register_operand" "=z")
4006         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4007                            (match_operand:SI 2 "const_int_operand" "n"))
4008                 (match_operand:SI 3 "const_int_operand" "n")))
4009    (clobber (reg:SI T_REG))]
4010   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4011  "#"
4012   [(set (attr "length")
4013         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4014                (const_string "4")
4015                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4016                (const_string "6")
4017                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4018                (const_string "8")]
4019               (const_string "10")))
4020    (set_attr "type" "arith")])
4021
4022 ;; shift left / and combination with a scratch register: The combine pass
4023 ;; does not accept the individual instructions, even though they are
4024 ;; cheap.  But it needs a precise description so that it is usable after
4025 ;; reload.
4026 (define_insn "and_shl_scratch"
4027   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4028         (lshiftrt:SI
4029          (ashift:SI
4030           (and:SI
4031            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4032                         (match_operand:SI 2 "const_int_operand" "N,n"))
4033            (match_operand:SI 3 "" "0,r"))
4034           (match_operand:SI 4 "const_int_operand" "n,n"))
4035          (match_operand:SI 5 "const_int_operand" "n,n")))
4036    (clobber (reg:SI T_REG))]
4037   "TARGET_SH1"
4038   "#"
4039   [(set (attr "length")
4040         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4041                (const_string "4")
4042                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4043                (const_string "6")
4044                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4045                (const_string "8")
4046                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4047                (const_string "10")]
4048               (const_string "12")))
4049    (set_attr "type" "arith")])
4050
4051 (define_split
4052   [(set (match_operand:SI 0 "register_operand" "")
4053         (lshiftrt:SI
4054          (ashift:SI
4055           (and:SI
4056            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4057                         (match_operand:SI 2 "const_int_operand" ""))
4058            (match_operand:SI 3 "register_operand" ""))
4059           (match_operand:SI 4 "const_int_operand" ""))
4060          (match_operand:SI 5 "const_int_operand" "")))
4061    (clobber (reg:SI T_REG))]
4062   "TARGET_SH1"
4063   [(use (reg:SI R0_REG))]
4064   "
4065 {
4066   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4067
4068   if (INTVAL (operands[2]))
4069     {
4070       gen_shifty_op (LSHIFTRT, operands);
4071     }
4072   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4073   operands[2] = operands[4];
4074   gen_shifty_op (ASHIFT, operands);
4075   if (INTVAL (operands[5]))
4076     {
4077       operands[2] = operands[5];
4078       gen_shifty_op (LSHIFTRT, operands);
4079     }
4080   DONE;
4081 }")
4082
4083 ;; signed left/right shift combination.
4084 (define_split
4085   [(set (match_operand:SI 0 "register_operand" "")
4086         (sign_extract:SI
4087          (ashift:SI (match_operand:SI 1 "register_operand" "")
4088                     (match_operand:SI 2 "const_int_operand" ""))
4089          (match_operand:SI 3 "const_int_operand" "")
4090          (const_int 0)))
4091    (clobber (reg:SI T_REG))]
4092   "TARGET_SH1"
4093   [(use (reg:SI R0_REG))]
4094   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4095    DONE;")
4096
4097 (define_insn "shl_sext_ext"
4098   [(set (match_operand:SI 0 "register_operand" "=r")
4099         (sign_extract:SI
4100          (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          (const_int 0)))
4104    (clobber (reg:SI T_REG))]
4105   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4106   "#"
4107   [(set (attr "length")
4108         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4109                (const_string "2")
4110                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4111                (const_string "4")
4112                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4113                (const_string "6")
4114                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4115                (const_string "8")
4116                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4117                (const_string "10")
4118                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4119                (const_string "12")
4120                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4121                (const_string "14")
4122                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4123                (const_string "16")]
4124               (const_string "18")))
4125     (set_attr "type" "arith")])
4126
4127 (define_insn "shl_sext_sub"
4128   [(set (match_operand:SI 0 "register_operand" "=z")
4129         (sign_extract:SI
4130          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4131                     (match_operand:SI 2 "const_int_operand" "n"))
4132          (match_operand:SI 3 "const_int_operand" "n")
4133          (const_int 0)))
4134    (clobber (reg:SI T_REG))]
4135   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4136   "#"
4137   [(set (attr "length")
4138         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4139                (const_string "6")
4140                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4141                (const_string "8")
4142                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4143                (const_string "10")
4144                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4145                (const_string "12")]
4146               (const_string "14")))
4147     (set_attr "type" "arith")])
4148
4149 ;; These patterns are found in expansions of DImode shifts by 16, and
4150 ;; allow the xtrct instruction to be generated from C source.
4151
4152 (define_insn "xtrct_left"
4153   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4154         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4155                            (const_int 16))
4156                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4157                              (const_int 16))))]
4158   "TARGET_SH1"
4159   "xtrct        %1,%0"
4160   [(set_attr "type" "arith")])
4161
4162 (define_insn "xtrct_right"
4163   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4164         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4165                              (const_int 16))
4166                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4167                            (const_int 16))))]
4168   "TARGET_SH1"
4169   "xtrct        %2,%0"
4170   [(set_attr "type" "arith")])
4171
4172 ;; -------------------------------------------------------------------------
4173 ;; Unary arithmetic
4174 ;; -------------------------------------------------------------------------
4175
4176 (define_insn "negc"
4177   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4178         (neg:SI (plus:SI (reg:SI T_REG)
4179                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4180    (set (reg:SI T_REG)
4181         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4182                (const_int 0)))]
4183   "TARGET_SH1"
4184   "negc %1,%0"
4185   [(set_attr "type" "arith")])
4186
4187 (define_insn "*negdi_media"
4188   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4189         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4190   "TARGET_SHMEDIA"
4191   "sub  r63, %1, %0"
4192   [(set_attr "type" "arith_media")])
4193
4194 (define_expand "negdi2"
4195   [(set (match_operand:DI 0 "arith_reg_operand" "")
4196         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4197   ""
4198   "
4199 {
4200   if (TARGET_SH1)
4201     {
4202       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4203       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4204
4205       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4206       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4207
4208       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4209       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4210
4211       emit_insn (gen_clrt ());
4212       emit_insn (gen_negc (low_dst, low_src));
4213       emit_insn (gen_negc (high_dst, high_src));
4214       DONE;
4215     }
4216 }")
4217
4218 (define_insn "negsi2"
4219   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4220         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4221   "TARGET_SH1"
4222   "neg  %1,%0"
4223   [(set_attr "type" "arith")])
4224
4225 (define_insn "one_cmplsi2"
4226   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4227         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4228   "TARGET_SH1"
4229   "not  %1,%0"
4230   [(set_attr "type" "arith")])
4231
4232 (define_expand "one_cmpldi2"
4233   [(set (match_operand:DI 0 "arith_reg_dest" "")
4234         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4235                 (const_int -1)))]
4236   "TARGET_SHMEDIA" "")
4237
4238 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4239    This can be used as some kind of conditional execution, which is useful
4240    for abs.  */
4241 (define_split
4242   [(set (match_operand:SI 0 "arith_reg_dest" "")
4243         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4244                          (match_operand:SI 1 "arith_reg_operand" ""))
4245                  (reg:SI T_REG)))]
4246   "TARGET_HARD_SH4"
4247   [(const_int 0)]
4248   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4249    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4250    DONE;")
4251
4252 (define_insn "cneg"
4253   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4254         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4255                       (match_operand:SI 1 "arith_reg_operand" "0")
4256                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4257   "TARGET_HARD_SH4"
4258   "bf 0f\;neg %2,%0\\n0:"
4259   [(set_attr "type" "arith") ;; poor approximation
4260    (set_attr "length" "4")])
4261
4262 \f
4263 ;; -------------------------------------------------------------------------
4264 ;; Zero extension instructions
4265 ;; -------------------------------------------------------------------------
4266
4267 (define_insn "zero_extendsidi2"
4268   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4269         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4270   "TARGET_SHMEDIA"
4271   "addz.l       %1, r63, %0"
4272   [(set_attr "type" "arith_media")
4273    (set_attr "highpart" "extend")])
4274
4275 (define_insn "zero_extendhidi2"
4276   [(set (match_operand:DI 0 "register_operand" "=r,r")
4277         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4278   "TARGET_SHMEDIA"
4279   "@
4280         #
4281         ld%M1.uw        %m1, %0"
4282   [(set_attr "type" "*,load_media")
4283    (set (attr "highpart")
4284         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4285                (const_string "user")]
4286               (const_string "ignore")))])
4287
4288 (define_split
4289   [(set (match_operand:DI 0 "register_operand" "")
4290         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4291   "TARGET_SHMEDIA && reload_completed"
4292   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4293    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4294   "
4295 {
4296   if (GET_CODE (operands[1]) == TRUNCATE)
4297     operands[1] = XEXP (operands[1], 0);
4298 }")
4299
4300 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4301 ;; reload the entire truncate expression.
4302 (define_insn_and_split "*loaddi_trunc"
4303   [(set (match_operand 0 "any_register_operand" "=r")
4304         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4305   "TARGET_SHMEDIA && reload_completed"
4306   "#"
4307   "TARGET_SHMEDIA && reload_completed"
4308   [(set (match_dup 0) (match_dup 1))]
4309   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4310
4311 (define_insn "zero_extendqidi2"
4312   [(set (match_operand:DI 0 "register_operand" "=r,r")
4313         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4314   "TARGET_SHMEDIA"
4315   "@
4316         andi    %1, 255, %0
4317         ld%M1.ub        %m1, %0"
4318   [(set_attr "type" "arith_media,load_media")
4319    (set (attr "highpart")
4320         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4321                (const_string "user")]
4322               (const_string "ignore")))])
4323
4324 (define_expand "zero_extendhisi2"
4325   [(set (match_operand:SI 0 "arith_reg_operand" "")
4326         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4327   ""
4328   "
4329 {
4330   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4331     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4332 }")
4333
4334 (define_insn "*zero_extendhisi2_compact"
4335   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4336         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4337   "TARGET_SH1"
4338   "extu.w       %1,%0"
4339   [(set_attr "type" "arith")])
4340
4341 (define_insn "*zero_extendhisi2_media"
4342   [(set (match_operand:SI 0 "register_operand" "=r,r")
4343         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4344   "TARGET_SHMEDIA"
4345   "@
4346         #
4347         ld%M1.uw        %m1, %0"
4348   [(set_attr "type" "arith_media,load_media")
4349    (set (attr "highpart")
4350         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4351                (const_string "user")]
4352               (const_string "ignore")))])
4353
4354 (define_split
4355   [(set (match_operand:SI 0 "register_operand" "")
4356         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4357   "TARGET_SHMEDIA && reload_completed"
4358   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4359    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4360   "
4361 {
4362   rtx op1 = operands[1];
4363
4364   if (GET_CODE (op1) == TRUNCATE)
4365     op1 = XEXP (op1, 0);
4366   operands[2]
4367     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4368                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4369 }")
4370
4371 (define_expand "zero_extendqisi2"
4372   [(set (match_operand:SI 0 "arith_reg_operand" "")
4373         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4374   ""
4375   "
4376 {
4377   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4378     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4379 }")
4380
4381 (define_insn "*zero_extendqisi2_compact"
4382   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4383         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4384   "TARGET_SH1"
4385   "extu.b       %1,%0"
4386   [(set_attr "type" "arith")])
4387
4388 (define_insn "*zero_extendqisi2_media"
4389   [(set (match_operand:SI 0 "register_operand" "=r,r")
4390         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4391   "TARGET_SHMEDIA"
4392   "@
4393         andi    %1, 255, %0
4394         ld%M1.ub        %m1, %0"
4395   [(set_attr "type" "arith_media,load_media")
4396    (set (attr "highpart")
4397         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4398                (const_string "user")]
4399               (const_string "ignore")))])
4400
4401 (define_insn "zero_extendqihi2"
4402   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4403         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4404   "TARGET_SH1"
4405   "extu.b       %1,%0"
4406   [(set_attr "type" "arith")])
4407
4408 ;; -------------------------------------------------------------------------
4409 ;; Sign extension instructions
4410 ;; -------------------------------------------------------------------------
4411
4412 ;; ??? This should be a define expand.
4413 ;; ??? Or perhaps it should be dropped?
4414
4415 ;; convert_move generates good code for SH[1-4].
4416 (define_insn "extendsidi2"
4417   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4418         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4419   "TARGET_SHMEDIA"
4420   "@
4421         add.l   %1, r63, %0
4422         ld%M1.l %m1, %0
4423         fmov.sl %1, %0"
4424   [(set_attr "type" "arith_media,load_media,fpconv_media")
4425    (set (attr "highpart")
4426         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4427                (const_string "user")]
4428               (const_string "extend")))])
4429
4430 (define_insn "extendhidi2"
4431   [(set (match_operand:DI 0 "register_operand" "=r,r")
4432         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4433   "TARGET_SHMEDIA"
4434   "@
4435         #
4436         ld%M1.w %m1, %0"
4437   [(set_attr "type" "*,load_media")
4438    (set (attr "highpart")
4439         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4440                (const_string "user")]
4441               (const_string "ignore")))])
4442
4443 (define_split
4444   [(set (match_operand:DI 0 "register_operand" "")
4445         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4446   "TARGET_SHMEDIA && reload_completed"
4447   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4448    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4449   "
4450 {
4451   if (GET_CODE (operands[1]) == TRUNCATE)
4452     operands[1] = XEXP (operands[1], 0);
4453 }")
4454
4455 (define_insn "extendqidi2"
4456   [(set (match_operand:DI 0 "register_operand" "=r,r")
4457         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4458   "TARGET_SHMEDIA"
4459   "@
4460         #
4461         ld%M1.b %m1, %0"
4462   [(set_attr "type" "*,load_media")
4463    (set (attr "highpart")
4464         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4465                (const_string "user")]
4466               (const_string "ignore")))])
4467
4468 (define_split
4469   [(set (match_operand:DI 0 "register_operand" "")
4470         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4471   "TARGET_SHMEDIA && reload_completed"
4472   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4473    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4474   "
4475 {
4476   if (GET_CODE (operands[1]) == TRUNCATE)
4477     operands[1] = XEXP (operands[1], 0);
4478 }")
4479
4480 (define_expand "extendhisi2"
4481   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4482         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4483   ""
4484   "")
4485
4486 (define_insn "*extendhisi2_compact"
4487   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4488         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4489   "TARGET_SH1"
4490   "@
4491         exts.w  %1,%0
4492         mov.w   %1,%0"
4493   [(set_attr "type" "arith,load")])
4494
4495 (define_insn "*extendhisi2_media"
4496   [(set (match_operand:SI 0 "register_operand" "=r,r")
4497         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4498   "TARGET_SHMEDIA"
4499   "@
4500         #
4501         ld%M1.w %m1, %0"
4502   [(set_attr "type" "arith_media,load_media")
4503    (set (attr "highpart")
4504         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4505                (const_string "user")]
4506               (const_string "ignore")))])
4507
4508 (define_split
4509   [(set (match_operand:SI 0 "register_operand" "")
4510         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4511   "TARGET_SHMEDIA && reload_completed"
4512   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4513    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4514   "
4515 {
4516   rtx op1 = operands[1];
4517   if (GET_CODE (op1) == TRUNCATE)
4518     op1 = XEXP (op1, 0);
4519   operands[2]
4520     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4521                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4522 }")
4523
4524 (define_expand "extendqisi2"
4525   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4526         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4527   ""
4528   "")
4529
4530 (define_insn "*extendqisi2_compact"
4531   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4532         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4533   "TARGET_SH1"
4534   "@
4535         exts.b  %1,%0
4536         mov.b   %1,%0"
4537   [(set_attr "type" "arith,load")])
4538
4539 (define_insn "*extendqisi2_media"
4540   [(set (match_operand:SI 0 "register_operand" "=r,r")
4541         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4542   "TARGET_SHMEDIA"
4543   "@
4544         #
4545         ld%M1.b %m1, %0"
4546   [(set_attr "type" "arith_media,load_media")
4547    (set (attr "highpart")
4548         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4549                (const_string "user")]
4550               (const_string "ignore")))])
4551
4552 (define_split
4553   [(set (match_operand:SI 0 "register_operand" "")
4554         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4555   "TARGET_SHMEDIA && reload_completed"
4556   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4557    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4558    "
4559 {
4560   rtx op1 = operands[1];
4561   if (GET_CODE (op1) == TRUNCATE)
4562     op1 = XEXP (op1, 0);
4563   operands[2]
4564     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4565                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4566 }")
4567
4568 (define_insn "extendqihi2"
4569   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4570         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4571   "TARGET_SH1"
4572   "@
4573         exts.b  %1,%0
4574         mov.b   %1,%0"
4575   [(set_attr "type" "arith,load")])
4576
4577 /* It would seem useful to combine the truncXi patterns into the movXi
4578    patterns, but unary operators are ignored when matching constraints,
4579    so we need separate patterns.  */
4580 (define_insn "truncdisi2"
4581   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4582         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4583   "TARGET_SHMEDIA"
4584   "@
4585         add.l   %1, r63, %0
4586         st%M0.l %m0, %1
4587         fst%M0.s        %m0, %T1
4588         fmov.ls %1, %0
4589         fmov.sl %T1, %0
4590         fmov.s  %T1, %0"
4591   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4592    (set (attr "highpart")
4593         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4594                (const_string "user")]
4595               (const_string "extend")))])
4596
4597 (define_insn "truncdihi2"
4598   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4599         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4600   "TARGET_SHMEDIA"
4601   "@
4602         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4603         st%M0.w %m0, %1"
4604   [(set_attr "type"   "arith_media,store_media")
4605    (set_attr "length" "8,4")
4606    (set (attr "highpart")
4607         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4608                (const_string "user")]
4609               (const_string "extend")))])
4610
4611 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4612 ; Because we use zero extension, we can't provide signed QImode compares
4613 ; using a simple compare or conditional banch insn.
4614 (define_insn "truncdiqi2"
4615   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4616         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4617   "TARGET_SHMEDIA"
4618   "@
4619         andi    %1, 255, %0
4620         st%M0.b %m0, %1"
4621   [(set_attr "type"   "arith_media,store")
4622    (set (attr "highpart")
4623         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4624                (const_string "user")]
4625               (const_string "extend")))])
4626 ;; -------------------------------------------------------------------------
4627 ;; Move instructions
4628 ;; -------------------------------------------------------------------------
4629
4630 ;; define push and pop so it is easy for sh.c
4631 ;; We can't use push and pop on SHcompact because the stack must always
4632 ;; be 8-byte aligned.
4633
4634 (define_expand "push"
4635   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4636         (match_operand:SI 0 "register_operand" "r,l,x"))]
4637   "TARGET_SH1 && ! TARGET_SH5"
4638   "")
4639
4640 (define_expand "pop"
4641   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4642         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4643   "TARGET_SH1 && ! TARGET_SH5"
4644   "")
4645
4646 (define_expand "push_e"
4647   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4648                    (match_operand:SF 0 "" ""))
4649               (use (reg:PSI FPSCR_REG))
4650               (clobber (scratch:SI))])]
4651   "TARGET_SH1 && ! TARGET_SH5"
4652   "")
4653
4654 (define_insn "push_fpul"
4655   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4656   "TARGET_SH2E && ! TARGET_SH5"
4657   "sts.l        fpul,@-r15"
4658   [(set_attr "type" "store")
4659    (set_attr "late_fp_use" "yes")
4660    (set_attr "hit_stack" "yes")])
4661
4662 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4663 ;; so use that.
4664 (define_expand "push_4"
4665   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4666                    (match_operand:DF 0 "" ""))
4667               (use (reg:PSI FPSCR_REG))
4668               (clobber (scratch:SI))])]
4669   "TARGET_SH1 && ! TARGET_SH5"
4670   "")
4671
4672 (define_expand "pop_e"
4673   [(parallel [(set (match_operand:SF 0 "" "")
4674               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4675               (use (reg:PSI FPSCR_REG))
4676               (clobber (scratch:SI))])]
4677   "TARGET_SH1 && ! TARGET_SH5"
4678   "")
4679
4680 (define_insn "pop_fpul"
4681   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4682   "TARGET_SH2E && ! TARGET_SH5"
4683   "lds.l        @r15+,fpul"
4684   [(set_attr "type" "load")
4685    (set_attr "hit_stack" "yes")])
4686
4687 (define_expand "pop_4"
4688   [(parallel [(set (match_operand:DF 0 "" "")
4689                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4690               (use (reg:PSI FPSCR_REG))
4691               (clobber (scratch:SI))])]
4692   "TARGET_SH1 && ! TARGET_SH5"
4693   "")
4694
4695 (define_expand "push_fpscr"
4696   [(const_int 0)]
4697   "TARGET_SH2E"
4698   "
4699 {
4700   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4701                                                  gen_rtx_PRE_DEC (Pmode,
4702                                                           stack_pointer_rtx)),
4703                                         get_fpscr_rtx ()));
4704   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4705   DONE;
4706 }")
4707
4708 (define_expand "pop_fpscr"
4709   [(const_int 0)]
4710   "TARGET_SH2E"
4711   "
4712 {
4713   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4714                                         gen_frame_mem (PSImode,
4715                                                  gen_rtx_POST_INC (Pmode,
4716                                                           stack_pointer_rtx))));
4717   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4718   DONE;
4719 }")
4720
4721 ;; These two patterns can happen as the result of optimization, when
4722 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4723 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4724
4725 (define_insn "clrt"
4726   [(set (reg:SI T_REG) (const_int 0))]
4727   "TARGET_SH1"
4728   "clrt")
4729
4730 (define_insn "sett"
4731   [(set (reg:SI T_REG) (const_int 1))]
4732   "TARGET_SH1"
4733   "sett")
4734
4735 ;; t/r must come after r/r, lest reload will try to reload stuff like
4736 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4737 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4738 (define_insn "movsi_i"
4739   [(set (match_operand:SI 0 "general_movdst_operand"
4740             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4741         (match_operand:SI 1 "general_movsrc_operand"
4742          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4743   "TARGET_SH1
4744    && ! TARGET_SH2E
4745    && ! TARGET_SH2A
4746    && (register_operand (operands[0], SImode)
4747        || register_operand (operands[1], SImode))"
4748   "@
4749         mov.l   %1,%0
4750         mov     %1,%0
4751         cmp/pl  %1
4752         mov.l   %1,%0
4753         sts     %1,%0
4754         sts     %1,%0
4755         movt    %0
4756         mov.l   %1,%0
4757         sts.l   %1,%0
4758         sts.l   %1,%0
4759         lds     %1,%0
4760         lds     %1,%0
4761         lds.l   %1,%0
4762         lds.l   %1,%0
4763         fake    %1,%0"
4764   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4765    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4766
4767 ;; t/r must come after r/r, lest reload will try to reload stuff like
4768 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4769 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4770 ;; will require a reload.
4771 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4772 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4773 (define_insn "movsi_ie"
4774   [(set (match_operand:SI 0 "general_movdst_operand"
4775             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4776         (match_operand:SI 1 "general_movsrc_operand"
4777          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4778   "(TARGET_SH2E || TARGET_SH2A)
4779    && (register_operand (operands[0], SImode)
4780        || register_operand (operands[1], SImode))"
4781   "@
4782         mov.l   %1,%0
4783         mov     %1,%0
4784         movi20  %1,%0
4785         cmp/pl  %1
4786         mov.l   %1,%0
4787         sts     %1,%0
4788         sts     %1,%0
4789         movt    %0
4790         mov.l   %1,%0
4791         sts.l   %1,%0
4792         sts.l   %1,%0
4793         lds     %1,%0
4794         lds     %1,%0
4795         lds.l   %1,%0
4796         lds.l   %1,%0
4797         lds.l   %1,%0
4798         sts.l   %1,%0
4799         fake    %1,%0
4800         lds     %1,%0
4801         sts     %1,%0
4802         fsts    fpul,%0
4803         flds    %1,fpul
4804         fmov    %1,%0
4805         ! move optimized away"
4806   [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4807    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4808    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4809
4810 (define_insn "movsi_i_lowpart"
4811   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4812         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4813    "TARGET_SH1
4814     && (register_operand (operands[0], SImode)
4815         || register_operand (operands[1], SImode))"
4816   "@
4817         mov.l   %1,%0
4818         mov     %1,%0
4819         mov.l   %1,%0
4820         sts     %1,%0
4821         sts     %1,%0
4822         movt    %0
4823         mov.l   %1,%0
4824         fake    %1,%0"
4825   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4826
4827 (define_insn_and_split "load_ra"
4828   [(set (match_operand:SI 0 "general_movdst_operand" "")
4829         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4830   "TARGET_SH1"
4831   "#"
4832   "&& ! currently_expanding_to_rtl"
4833   [(set (match_dup 0) (match_dup 1))]
4834   "
4835 {
4836   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4837     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4838 }")
4839
4840 ;; The '?'s in the following constraints may not reflect the time taken
4841 ;; to perform the move. They are there to discourage the use of floating-
4842 ;; point registers for storing integer values.
4843 (define_insn "*movsi_media"
4844   [(set (match_operand:SI 0 "general_movdst_operand"
4845                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4846         (match_operand:SI 1 "general_movsrc_operand"
4847          "r,I16C16,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4848   "TARGET_SHMEDIA_FPU
4849    && (register_operand (operands[0], SImode)
4850        || sh_register_operand (operands[1], SImode)
4851        || GET_CODE (operands[1]) == TRUNCATE)"
4852   "@
4853         add.l   %1, r63, %0
4854         movi    %1, %0
4855         #
4856         ld%M1.l %m1, %0
4857         st%M0.l %m0, %N1
4858         fld%M1.s        %m1, %0
4859         fst%M0.s        %m0, %1
4860         fmov.ls %N1, %0
4861         fmov.sl %1, %0
4862         fmov.s  %1, %0
4863         ptabs   %1, %0
4864         gettr   %1, %0
4865         pt      %1, %0"
4866   [(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")
4867    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4868    (set (attr "highpart")
4869         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4870                (const_string "user")]
4871               (const_string "ignore")))])
4872
4873 (define_insn "*movsi_media_nofpu"
4874   [(set (match_operand:SI 0 "general_movdst_operand"
4875                 "=r,r,r,r,m,*b,r,*b")
4876         (match_operand:SI 1 "general_movsrc_operand"
4877          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
4878   "TARGET_SHMEDIA
4879    && (register_operand (operands[0], SImode)
4880        || sh_register_operand (operands[1], SImode)
4881        || GET_CODE (operands[1]) == TRUNCATE)"
4882   "@
4883         add.l   %1, r63, %0
4884         movi    %1, %0
4885         #
4886         ld%M1.l %m1, %0
4887         st%M0.l %m0, %N1
4888         ptabs   %1, %0
4889         gettr   %1, %0
4890         pt      %1, %0"
4891   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4892    (set_attr "length" "4,4,8,4,4,4,4,12")
4893    (set (attr "highpart")
4894         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4895                (const_string "user")]
4896               (const_string "ignore")))])
4897
4898 (define_expand "movsi_const"
4899   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4900         (const:SI (sign_extend:SI
4901                    (truncate:HI
4902                     (ashiftrt:SI
4903                      (match_operand:DI 1 "immediate_operand" "s")
4904                      (const_int 16))))))
4905    (set (match_dup 0)
4906         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4907                 (zero_extend:SI
4908                  (truncate:HI
4909                   (const:SI
4910                    (sign_extend:SI
4911                     (truncate:HI (match_dup 1))))))))]
4912   "TARGET_SHMEDIA && reload_completed
4913    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4914   "
4915 {
4916   if (GET_CODE (operands[1]) == LABEL_REF
4917       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4918     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4919   else if (GOTOFF_P (operands[1]))
4920     {
4921       rtx unspec = XEXP (operands[1], 0);
4922
4923       if (! UNSPEC_GOTOFF_P (unspec))
4924         {
4925           unspec = XEXP (unspec, 0);
4926           if (! UNSPEC_GOTOFF_P (unspec))
4927             abort ();
4928         }
4929       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4930           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4931         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4932     }
4933 }")
4934
4935 (define_expand "movsi_const_16bit"
4936   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4937         (const:SI (sign_extend:SI
4938                    (truncate:HI
4939                     (match_operand:DI 1 "immediate_operand" "s")))))]
4940   "TARGET_SHMEDIA && flag_pic && reload_completed
4941    && GET_CODE (operands[1]) == SYMBOL_REF"
4942   "")
4943
4944 (define_split
4945   [(set (match_operand:SI 0 "arith_reg_dest" "")
4946         (match_operand:SI 1 "immediate_operand" ""))]
4947   "TARGET_SHMEDIA && reload_completed
4948    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4949   [(const_int 0)]
4950   "
4951 {
4952   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4953
4954   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4955                                         REG_NOTES (insn));
4956
4957   DONE;
4958 }")
4959
4960 (define_split
4961   [(set (match_operand:SI 0 "register_operand" "")
4962         (match_operand:SI 1 "immediate_operand" ""))]
4963   "TARGET_SHMEDIA && reload_completed
4964    && ((GET_CODE (operands[1]) == CONST_INT
4965         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4966        || GET_CODE (operands[1]) == CONST_DOUBLE)"
4967   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4968
4969 (define_expand "movsi"
4970   [(set (match_operand:SI 0 "general_movdst_operand" "")
4971         (match_operand:SI 1 "general_movsrc_operand" ""))]
4972   ""
4973   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4974
4975 (define_expand "ic_invalidate_line"
4976   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4977                                 (match_dup 1)] UNSPEC_ICACHE)
4978               (clobber (scratch:SI))])]
4979   "TARGET_HARD_SH4 || TARGET_SH5"
4980   "
4981 {
4982   if (TARGET_SHMEDIA)
4983     {
4984       emit_insn (gen_ic_invalidate_line_media (operands[0]));
4985       DONE;
4986     }
4987   else if (TARGET_SHCOMPACT)
4988     {
4989       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4990       operands[1] = force_reg (Pmode, operands[1]);
4991       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
4992       DONE;
4993     }
4994   else if (TARGET_SH4A_ARCH)
4995     {
4996       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
4997       DONE;
4998     }
4999   operands[0] = force_reg (Pmode, operands[0]);
5000   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5001                                                                Pmode)));
5002 }")
5003
5004 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5005 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5006 ;; the requirement *1*00 for associative address writes.  The alignment of
5007 ;; %0 implies that its least significant bit is cleared,
5008 ;; thus we clear the V bit of a matching entry if there is one.
5009 (define_insn "ic_invalidate_line_i"
5010   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5011                      (match_operand:SI 1 "register_operand" "r")]
5012                      UNSPEC_ICACHE)
5013    (clobber (match_scratch:SI 2 "=&r"))]
5014   "TARGET_HARD_SH4"
5015   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5016   [(set_attr "length" "8")
5017    (set_attr "type" "cwb")])
5018
5019 (define_insn "ic_invalidate_line_sh4a"
5020   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5021                     UNSPEC_ICACHE)]
5022   "TARGET_SH4A_ARCH"
5023   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5024   [(set_attr "length" "16")
5025    (set_attr "type" "cwb")])
5026
5027 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5028 ;; an add in the code that calculates the address.
5029 (define_insn "ic_invalidate_line_media"
5030   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5031                     UNSPEC_ICACHE)]
5032   "TARGET_SHMEDIA"
5033   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5034   [(set_attr "length" "16")
5035    (set_attr "type" "invalidate_line_media")])
5036
5037 (define_insn "ic_invalidate_line_compact"
5038   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5039                      (match_operand:SI 1 "register_operand" "r")]
5040                     UNSPEC_ICACHE)
5041    (clobber (reg:SI PR_REG))]
5042   "TARGET_SHCOMPACT"
5043   "jsr @%1%#"
5044   [(set_attr "type" "sfunc")
5045    (set_attr "needs_delay_slot" "yes")])
5046
5047 (define_expand "initialize_trampoline"
5048   [(match_operand:SI 0 "" "")
5049    (match_operand:SI 1 "" "")
5050    (match_operand:SI 2 "" "")]
5051   "TARGET_SHCOMPACT"
5052   "
5053 {
5054   rtx sfun, tramp;
5055
5056   tramp = force_reg (Pmode, operands[0]);
5057   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5058                                             SFUNC_STATIC));
5059   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5060   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5061
5062   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5063   DONE;
5064 }")
5065
5066 (define_insn "initialize_trampoline_compact"
5067   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5068                      (match_operand:SI 1 "register_operand" "r")
5069                      (reg:SI R2_REG) (reg:SI R3_REG)]
5070                     UNSPEC_INIT_TRAMP)
5071
5072    (clobber (reg:SI PR_REG))]
5073   "TARGET_SHCOMPACT"
5074   "jsr @%1%#"
5075   [(set_attr "type" "sfunc")
5076    (set_attr "needs_delay_slot" "yes")])
5077
5078 (define_insn "movqi_i"
5079   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5080         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
5081   "TARGET_SH1
5082    && (arith_reg_operand (operands[0], QImode)
5083        || arith_reg_operand (operands[1], QImode))"
5084   "@
5085         mov     %1,%0
5086         mov.b   %1,%0
5087         mov.b   %1,%0
5088         movt    %0
5089         sts     %1,%0
5090         lds     %1,%0"
5091  [(set_attr "type" "move,load,store,move,move,move")])
5092
5093 (define_insn "*movqi_media"
5094   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5095         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
5096   "TARGET_SHMEDIA
5097    && (arith_reg_operand (operands[0], QImode)
5098        || extend_reg_or_0_operand (operands[1], QImode))"
5099   "@
5100         add.l   %1, r63, %0
5101         movi    %1, %0
5102         ld%M1.ub        %m1, %0
5103         st%M0.b %m0, %N1"
5104   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5105    (set (attr "highpart")
5106         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5107                (const_string "user")]
5108               (const_string "ignore")))])
5109
5110 (define_expand "movqi"
5111   [(set (match_operand:QI 0 "general_operand" "")
5112         (match_operand:QI 1 "general_operand"  ""))]
5113   ""
5114   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5115
5116 (define_expand "reload_inqi"
5117   [(set (match_operand:SI 2 "" "=&r")
5118         (match_operand:QI 1 "inqhi_operand" ""))
5119    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5120         (truncate:QI (match_dup 3)))]
5121   "TARGET_SHMEDIA"
5122   "
5123 {
5124   rtx inner = XEXP (operands[1], 0);
5125   int regno = REGNO (inner);
5126
5127   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5128   operands[1] = gen_rtx_REG (SImode, regno);
5129   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5130 }")
5131
5132 /* When storing r0, we have to avoid reg+reg addressing.  */
5133 (define_insn "movhi_i"
5134   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5135         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5136   "TARGET_SH1
5137    && (arith_reg_operand (operands[0], HImode)
5138        || arith_reg_operand (operands[1], HImode))
5139    && (GET_CODE (operands[0]) != MEM
5140        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5141        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5142        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5143   "@
5144         mov.w   %1,%0
5145         mov     %1,%0
5146         mov.w   %1,%0
5147         movt    %0
5148         mov.w   %1,%0
5149         sts     %1,%0
5150         lds     %1,%0
5151         fake    %1,%0"
5152   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5153
5154 (define_insn "*movhi_media"
5155   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5156         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
5157   "TARGET_SHMEDIA
5158    && (arith_reg_operand (operands[0], HImode)
5159        || arith_reg_or_0_operand (operands[1], HImode))"
5160   "@
5161         add.l   %1, r63, %0
5162         movi    %1, %0
5163         #
5164         ld%M1.w %m1, %0
5165         st%M0.w %m0, %N1"
5166   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5167    (set (attr "highpart")
5168         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5169                (const_string "user")]
5170               (const_string "ignore")))])
5171
5172 (define_split
5173   [(set (match_operand:HI 0 "register_operand" "")
5174         (match_operand:HI 1 "immediate_operand" ""))]
5175   "TARGET_SHMEDIA && reload_completed
5176    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5177   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5178
5179 (define_expand "movhi"
5180   [(set (match_operand:HI 0 "general_movdst_operand" "")
5181         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5182   ""
5183   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5184
5185 (define_expand "reload_inhi"
5186   [(set (match_operand:SI 2 "" "=&r")
5187         (match_operand:HI 1 "inqhi_operand" ""))
5188    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5189         (truncate:HI (match_dup 3)))]
5190   "TARGET_SHMEDIA"
5191   "
5192 {
5193   rtx inner = XEXP (operands[1], 0);
5194   int regno = REGNO (inner);
5195
5196   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5197   operands[1] = gen_rtx_REG (SImode, regno);
5198   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5199 }")
5200
5201 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5202 ;; compiled with -m2 -ml -O3 -funroll-loops
5203 (define_insn "*movdi_i"
5204   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5205         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5206   "TARGET_SH1
5207    && (arith_reg_operand (operands[0], DImode)
5208        || arith_reg_operand (operands[1], DImode))"
5209   "* return output_movedouble (insn, operands, DImode);"
5210   [(set_attr "length" "4")
5211    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5212
5213 ;; If the output is a register and the input is memory or a register, we have
5214 ;; to be careful and see which word needs to be loaded first.
5215
5216 (define_split
5217   [(set (match_operand:DI 0 "general_movdst_operand" "")
5218         (match_operand:DI 1 "general_movsrc_operand" ""))]
5219   "TARGET_SH1 && reload_completed"
5220   [(set (match_dup 2) (match_dup 3))
5221    (set (match_dup 4) (match_dup 5))]
5222   "
5223 {
5224   int regno;
5225
5226   if ((GET_CODE (operands[0]) == MEM
5227        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5228       || (GET_CODE (operands[1]) == MEM
5229           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5230     FAIL;
5231
5232   switch (GET_CODE (operands[0]))
5233     {
5234     case REG:
5235       regno = REGNO (operands[0]);
5236       break;
5237     case SUBREG:
5238       regno = subreg_regno (operands[0]);
5239       break;
5240     case MEM:
5241       regno = -1;
5242       break;
5243     default:
5244       gcc_unreachable ();
5245     }
5246
5247   if (regno == -1
5248       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5249     {
5250       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5251       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5252       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5253       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5254     }
5255   else
5256     {
5257       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5258       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5259       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5260       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5261     }
5262
5263   if (operands[2] == 0 || operands[3] == 0
5264       || operands[4] == 0 || operands[5] == 0)
5265     FAIL;
5266 }")
5267
5268 ;; The '?'s in the following constraints may not reflect the time taken
5269 ;; to perform the move. They are there to discourage the use of floating-
5270 ;; point registers for storing integer values.
5271 (define_insn "*movdi_media"
5272   [(set (match_operand:DI 0 "general_movdst_operand"
5273                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5274         (match_operand:DI 1 "general_movsrc_operand"
5275          "r,I16C16,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5276   "TARGET_SHMEDIA_FPU
5277    && (register_operand (operands[0], DImode)
5278        || sh_register_operand (operands[1], DImode))"
5279   "@
5280         add     %1, r63, %0
5281         movi    %1, %0
5282         #
5283         ld%M1.q %m1, %0
5284         st%M0.q %m0, %N1
5285         fld%M1.d        %m1, %0
5286         fst%M0.d        %m0, %1
5287         fmov.qd %N1, %0
5288         fmov.dq %1, %0
5289         fmov.d  %1, %0
5290         ptabs   %1, %0
5291         gettr   %1, %0
5292         pt      %1, %0"
5293   [(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")
5294    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5295
5296 (define_insn "*movdi_media_nofpu"
5297   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5298         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
5299   "TARGET_SHMEDIA
5300    && (register_operand (operands[0], DImode)
5301        || sh_register_operand (operands[1], DImode))"
5302   "@
5303         add     %1, r63, %0
5304         movi    %1, %0
5305         #
5306         ld%M1.q %m1, %0
5307         st%M0.q %m0, %N1
5308         ptabs   %1, %0
5309         gettr   %1, %0
5310         pt      %1, %0"
5311   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5312    (set_attr "length" "4,4,16,4,4,4,4,*")])
5313
5314 (define_insn "*movdi_media_I16"
5315   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5316         (match_operand:DI 1 "const_int_operand" "I16"))]
5317   "TARGET_SHMEDIA && reload_completed"
5318   "movi %1, %0"
5319   [(set_attr "type" "arith_media")
5320    (set_attr "length" "4")])
5321
5322 (define_split
5323   [(set (match_operand:DI 0 "arith_reg_dest" "")
5324         (match_operand:DI 1 "immediate_operand" ""))]
5325   "TARGET_SHMEDIA && reload_completed
5326    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5327   [(set (match_dup 0) (match_dup 1))]
5328   "
5329 {
5330   rtx insn;
5331
5332   if (TARGET_SHMEDIA64)
5333     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5334   else
5335     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5336
5337   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5338                                         REG_NOTES (insn));
5339
5340   DONE;
5341 }")
5342
5343 (define_expand "movdi_const"
5344   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5345         (const:DI (sign_extend:DI
5346                    (truncate:HI
5347                     (ashiftrt:DI
5348                      (match_operand:DI 1 "immediate_operand" "s")
5349                      (const_int 48))))))
5350    (set (match_dup 0)
5351         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5352                 (zero_extend:DI
5353                  (truncate:HI
5354                   (const:DI
5355                    (sign_extend:DI
5356                     (truncate:HI
5357                      (ashiftrt:SI
5358                       (match_dup 1)
5359                       (const_int 32)))))))))
5360    (set (match_dup 0)
5361         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5362                 (zero_extend:DI
5363                  (truncate:HI
5364                   (const:DI
5365                    (sign_extend:DI
5366                     (truncate:HI
5367                      (ashiftrt:SI
5368                       (match_dup 1)
5369                       (const_int 16)))))))))
5370    (set (match_dup 0)
5371         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5372                 (zero_extend:DI
5373                  (truncate:HI
5374                   (const:DI
5375                    (sign_extend:DI
5376                     (truncate:HI
5377                      (match_dup 1))))))))]
5378   "TARGET_SHMEDIA64 && reload_completed
5379    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5380   "
5381 {
5382   sh_mark_label (operands[1], 4);
5383 }")
5384
5385 (define_expand "movdi_const_32bit"
5386   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5387         (const:DI (sign_extend:DI
5388                    (truncate:HI
5389                     (ashiftrt:DI
5390                      (match_operand:DI 1 "immediate_operand" "s")
5391                      (const_int 16))))))
5392    (set (match_dup 0)
5393         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5394                 (zero_extend:DI
5395                  (truncate:HI
5396                   (const:DI
5397                    (sign_extend:DI
5398                     (truncate:HI
5399                      (match_dup 1))))))))]
5400   "TARGET_SHMEDIA32 && reload_completed
5401    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5402   "
5403 {
5404   sh_mark_label (operands[1], 2);
5405 }")
5406
5407 (define_expand "movdi_const_16bit"
5408   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5409         (const:DI (sign_extend:DI
5410                    (truncate:HI
5411                     (match_operand:DI 1 "immediate_operand" "s")))))]
5412   "TARGET_SHMEDIA && flag_pic && reload_completed
5413    && GET_CODE (operands[1]) == SYMBOL_REF"
5414   "")
5415
5416 (define_split
5417   [(set (match_operand:DI 0 "ext_dest_operand" "")
5418         (match_operand:DI 1 "immediate_operand" ""))]
5419   "TARGET_SHMEDIA && reload_completed
5420    && GET_CODE (operands[1]) == CONST_INT
5421    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5422   [(set (match_dup 0) (match_dup 2))
5423    (match_dup 1)]
5424   "
5425 {
5426   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5427   unsigned HOST_WIDE_INT low = val;
5428   unsigned HOST_WIDE_INT high = val;
5429   unsigned HOST_WIDE_INT sign;
5430   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5431
5432   /* Sign-extend the 16 least-significant bits.  */
5433   low &= 0xffff;
5434   low ^= 0x8000;
5435   low -= 0x8000;
5436
5437   /* Arithmetic shift right the word by 16 bits.  */
5438   high >>= 16;
5439   if (GET_CODE (operands[0]) == SUBREG
5440       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5441     {
5442       high &= 0xffff;
5443       high ^= 0x8000;
5444       high -= 0x8000;
5445     }
5446   else
5447     {
5448       sign = 1;
5449       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5450       high ^= sign;
5451       high -= sign;
5452     }
5453   do
5454     {
5455       /* If we can't generate the constant with a two-insn movi / shori
5456          sequence, try some other strategies.  */
5457       if (! CONST_OK_FOR_I16 (high))
5458         {
5459           /* Try constant load / left shift.  We know VAL != 0.  */
5460           val2 = val ^ (val-1);
5461           if (val2 > 0x1ffff)
5462             {
5463               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5464
5465               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5466                   || (! CONST_OK_FOR_I16 (high >> 16)
5467                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5468                 {
5469                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5470                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5471                                                    GEN_INT (trailing_zeroes));
5472                   break;
5473                 }
5474             }
5475           /* Try constant load / right shift.  */
5476           val2 = (val >> 15) + 1;
5477           if (val2 == (val2 & -val2))
5478             {
5479               int shift = 49 - exact_log2 (val2);
5480
5481               val2 = trunc_int_for_mode (val << shift, DImode);
5482               if (CONST_OK_FOR_I16 (val2))
5483                 {
5484                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5485                                                    GEN_INT (shift));
5486                   break;
5487                 }
5488             }
5489           /* Try mperm.w .  */
5490           val2 = val & 0xffff;
5491           if ((val >> 16 & 0xffff) == val2
5492               && (val >> 32 & 0xffff) == val2
5493               && (val >> 48 & 0xffff) == val2)
5494             {
5495               val2 = (HOST_WIDE_INT) val >> 48;
5496               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5497               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5498               break;
5499             }
5500           /* Try movi / mshflo.l  */
5501           val2 = (HOST_WIDE_INT) val >> 32;
5502           if (val2 == ((unsigned HOST_WIDE_INT)
5503                         trunc_int_for_mode (val, SImode)))
5504             {
5505               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5506                                              operands[0]);
5507               break;
5508             }
5509           /* Try movi / mshflo.l w/ r63.  */
5510           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5511           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5512             {
5513               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5514                                              const0_rtx);
5515               break;
5516             }
5517         }
5518       val2 = high;
5519       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5520     }
5521   while (0);
5522   operands[2] = GEN_INT (val2);
5523 }")
5524
5525 (define_split
5526   [(set (match_operand:DI 0 "ext_dest_operand" "")
5527         (match_operand:DI 1 "immediate_operand" ""))]
5528   "TARGET_SHMEDIA && reload_completed
5529    && GET_CODE (operands[1]) == CONST_DOUBLE"
5530   [(set (match_dup 0) (match_dup 2))
5531   (set (match_dup 0)
5532        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5533                (zero_extend:DI (truncate:HI (match_dup 1)))))]
5534   "
5535 {
5536   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5537   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5538   unsigned HOST_WIDE_INT val = low;
5539   unsigned HOST_WIDE_INT sign;
5540
5541   /* Sign-extend the 16 least-significant bits.  */
5542   val &= 0xffff;
5543   val ^= 0x8000;
5544   val -= 0x8000;
5545   operands[1] = GEN_INT (val);
5546
5547   /* Arithmetic shift right the double-word by 16 bits.  */
5548   low >>= 16;
5549   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5550   high >>= 16;
5551   sign = 1;
5552   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5553   high ^= sign;
5554   high -= sign;
5555
5556   /* This will only be true if high is a sign-extension of low, i.e.,
5557      it must be either 0 or (unsigned)-1, and be zero iff the
5558      most-significant bit of low is set.  */
5559   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5560     operands[2] = GEN_INT (low);
5561   else
5562     operands[2] = immed_double_const (low, high, DImode);
5563 }")
5564
5565 (define_insn "shori_media"
5566   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5567         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5568                            (const_int 16))
5569                 (zero_extend:DI
5570                  (truncate:HI
5571                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
5572   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5573   "@
5574         shori   %u2, %0
5575         #"
5576   [(set_attr "type" "arith_media,*")])
5577
5578 (define_insn "*shori_media_si"
5579   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5580         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5581                            (const_int 16))
5582                 (zero_extend:SI
5583                  (truncate:HI
5584                   (match_operand:SI 2 "immediate_operand" "I16C16")))))]
5585   "TARGET_SHMEDIA"
5586   "shori        %u2, %0")
5587
5588 (define_expand "movdi"
5589   [(set (match_operand:DI 0 "general_movdst_operand" "")
5590         (match_operand:DI 1 "general_movsrc_operand" ""))]
5591   ""
5592   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5593
5594 (define_insn "movdf_media"
5595   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5596         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5597   "TARGET_SHMEDIA_FPU
5598    && (register_operand (operands[0], DFmode)
5599        || sh_register_operand (operands[1], DFmode))"
5600   "@
5601         fmov.d  %1, %0
5602         fmov.qd %N1, %0
5603         fmov.dq %1, %0
5604         add     %1, r63, %0
5605         #
5606         fld%M1.d        %m1, %0
5607         fst%M0.d        %m0, %1
5608         ld%M1.q %m1, %0
5609         st%M0.q %m0, %N1"
5610   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5611
5612 (define_insn "movdf_media_nofpu"
5613   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5614         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5615   "TARGET_SHMEDIA
5616    && (register_operand (operands[0], DFmode)
5617        || sh_register_operand (operands[1], DFmode))"
5618   "@
5619         add     %1, r63, %0
5620         #
5621         ld%M1.q %m1, %0
5622         st%M0.q %m0, %N1"
5623   [(set_attr "type" "arith_media,*,load_media,store_media")])
5624
5625 (define_split
5626   [(set (match_operand:DF 0 "arith_reg_dest" "")
5627         (match_operand:DF 1 "immediate_operand" ""))]
5628   "TARGET_SHMEDIA && reload_completed"
5629   [(set (match_dup 3) (match_dup 2))]
5630   "
5631 {
5632   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5633   long values[2];
5634   REAL_VALUE_TYPE value;
5635
5636   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5637   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5638
5639   if (HOST_BITS_PER_WIDE_INT >= 64)
5640     operands[2] = immed_double_const ((unsigned long) values[endian]
5641                                       | ((HOST_WIDE_INT) values[1 - endian]
5642                                          << 32), 0, DImode);
5643   else
5644     {
5645       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5646       operands[2] = immed_double_const (values[endian], values[1 - endian],
5647                                         DImode);
5648     }
5649
5650   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5651 }")
5652
5653 ;; ??? This should be a define expand.
5654
5655 (define_insn "movdf_k"
5656   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5657         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5658   "TARGET_SH1
5659    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5660        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5661        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5662        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5663    && (arith_reg_operand (operands[0], DFmode)
5664        || arith_reg_operand (operands[1], DFmode))"
5665   "* return output_movedouble (insn, operands, DFmode);"
5666   [(set_attr "length" "4")
5667    (set_attr "type" "move,pcload,load,store")])
5668
5669 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5670 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5671 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5672 ;; the d/m/c/X alternative, which is split later into single-precision
5673 ;; instructions.  And when not optimizing, no splits are done before fixing
5674 ;; up pcloads, so we need usable length information for that.
5675 (define_insn "movdf_i4"
5676   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5677         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5678    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5679    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5680   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5681    && (arith_reg_operand (operands[0], DFmode)
5682        || arith_reg_operand (operands[1], DFmode))"
5683   "@
5684         fmov    %1,%0
5685         #
5686         #
5687         fmov.d  %1,%0
5688         fmov.d  %1,%0
5689         #
5690         #
5691         #
5692         #
5693         #"
5694   [(set_attr_alternative "length"
5695      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5696       (const_int 4)
5697       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5698       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5699       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5700       (const_int 4)
5701       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5702       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5703       ;; increment or decrement r15 explicitly.
5704       (if_then_else
5705        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5706        (const_int 10) (const_int 8))
5707       (if_then_else
5708        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5709        (const_int 10) (const_int 8))])
5710    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5711    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5712    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5713                                            (const_string "double")
5714                                            (const_string "none")))])
5715
5716 ;; Moving DFmode between fp/general registers through memory
5717 ;; (the top of the stack) is faster than moving through fpul even for
5718 ;; little endian.  Because the type of an instruction is important for its
5719 ;; scheduling,  it is beneficial to split these operations, rather than
5720 ;; emitting them in one single chunk, even if this will expose a stack
5721 ;; use that will prevent scheduling of other stack accesses beyond this
5722 ;; instruction.
5723 (define_split
5724   [(set (match_operand:DF 0 "register_operand" "")
5725         (match_operand:DF 1 "register_operand" ""))
5726    (use (match_operand:PSI 2 "fpscr_operand" ""))
5727    (clobber (match_scratch:SI 3 "=X"))]
5728   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5729    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5730   [(const_int 0)]
5731   "
5732 {
5733   rtx insn, tos;
5734
5735   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5736     {
5737       emit_move_insn (stack_pointer_rtx,
5738                       plus_constant (stack_pointer_rtx, -8));
5739       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5740     }
5741   else
5742     tos = gen_tmp_stack_mem (DFmode,
5743                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5744   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5745   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5746     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5747   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5748     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5749   else
5750     tos = gen_tmp_stack_mem (DFmode,
5751                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5752   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5753   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5754     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5755   else
5756     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5757   DONE;
5758 }")
5759
5760 ;; local-alloc sometimes allocates scratch registers even when not required,
5761 ;; so we must be prepared to handle these.
5762
5763 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5764 (define_split
5765   [(set (match_operand:DF 0 "general_movdst_operand" "")
5766         (match_operand:DF 1 "general_movsrc_operand"  ""))
5767    (use (match_operand:PSI 2 "fpscr_operand" ""))
5768    (clobber (match_scratch:SI 3 ""))]
5769   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5770    && reload_completed
5771    && true_regnum (operands[0]) < 16
5772    && true_regnum (operands[1]) < 16"
5773   [(set (match_dup 0) (match_dup 1))]
5774   "
5775 {
5776   /* If this was a reg <-> mem operation with base + index reg addressing,
5777      we have to handle this in a special way.  */
5778   rtx mem = operands[0];
5779   int store_p = 1;
5780   if (! memory_operand (mem, DFmode))
5781     {
5782       mem = operands[1];
5783       store_p = 0;
5784     }
5785   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5786     mem = SUBREG_REG (mem);
5787   if (GET_CODE (mem) == MEM)
5788     {
5789       rtx addr = XEXP (mem, 0);
5790       if (GET_CODE (addr) == PLUS
5791           && GET_CODE (XEXP (addr, 0)) == REG
5792           && GET_CODE (XEXP (addr, 1)) == REG)
5793         {
5794           int offset;
5795           rtx reg0 = gen_rtx_REG (Pmode, 0);
5796           rtx regop = operands[store_p], word0 ,word1;
5797
5798           if (GET_CODE (regop) == SUBREG)
5799             alter_subreg (&regop);
5800           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5801             offset = 2;
5802           else
5803             offset = 4;
5804           mem = copy_rtx (mem);
5805           PUT_MODE (mem, SImode);
5806           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5807           alter_subreg (&word0);
5808           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5809           alter_subreg (&word1);
5810           if (store_p || ! refers_to_regno_p (REGNO (word0),
5811                                               REGNO (word0) + 1, addr, 0))
5812             {
5813               emit_insn (store_p
5814                          ? gen_movsi_ie (mem, word0)
5815                          : gen_movsi_ie (word0, mem));
5816               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5817               mem = copy_rtx (mem);
5818               emit_insn (store_p
5819                          ? gen_movsi_ie (mem, word1)
5820                          : gen_movsi_ie (word1, mem));
5821               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5822             }
5823           else
5824             {
5825               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5826               emit_insn (gen_movsi_ie (word1, mem));
5827               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5828               mem = copy_rtx (mem);
5829               emit_insn (gen_movsi_ie (word0, mem));
5830             }
5831           DONE;
5832         }
5833     }
5834 }")
5835
5836 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5837 (define_split
5838   [(set (match_operand:DF 0 "register_operand" "")
5839         (match_operand:DF 1 "memory_operand"  ""))
5840    (use (match_operand:PSI 2 "fpscr_operand" ""))
5841    (clobber (reg:SI R0_REG))]
5842   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5843   [(parallel [(set (match_dup 0) (match_dup 1))
5844               (use (match_dup 2))
5845               (clobber (scratch:SI))])]
5846   "")
5847
5848 (define_expand "reload_indf"
5849   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
5850                    (match_operand:DF 1 "immediate_operand" "FQ"))
5851               (use (reg:PSI FPSCR_REG))
5852               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5853   "TARGET_SH1"
5854   "")
5855
5856 (define_expand "reload_outdf"
5857   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5858                    (match_operand:DF 1 "register_operand" "af,r"))
5859               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5860   "TARGET_SH1"
5861   "")
5862
5863 ;; Simplify no-op moves.
5864 (define_split
5865   [(set (match_operand:SF 0 "register_operand" "")
5866         (match_operand:SF 1 "register_operand" ""))
5867    (use (match_operand:PSI 2 "fpscr_operand" ""))
5868    (clobber (match_scratch:SI 3 ""))]
5869   "TARGET_SH2E && reload_completed
5870    && true_regnum (operands[0]) == true_regnum (operands[1])"
5871   [(set (match_dup 0) (match_dup 0))]
5872   "")
5873
5874 ;; fmovd substitute post-reload splits
5875 (define_split
5876   [(set (match_operand:DF 0 "register_operand" "")
5877         (match_operand:DF 1 "register_operand" ""))
5878    (use (match_operand:PSI 2 "fpscr_operand" ""))
5879    (clobber (match_scratch:SI 3 ""))]
5880   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5881    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5882    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5883   [(const_int 0)]
5884   "
5885 {
5886   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5887   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5888                            gen_rtx_REG (SFmode, src), operands[2]));
5889   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5890                            gen_rtx_REG (SFmode, src + 1), operands[2]));
5891   DONE;
5892 }")
5893
5894 (define_split
5895   [(set (match_operand:DF 0 "register_operand" "")
5896         (mem:DF (match_operand:SI 1 "register_operand" "")))
5897    (use (match_operand:PSI 2 "fpscr_operand" ""))
5898    (clobber (match_scratch:SI 3 ""))]
5899   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5900    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5901    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5902   [(const_int 0)]
5903   "
5904 {
5905   int regno = true_regnum (operands[0]);
5906   rtx insn;
5907   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5908   rtx mem2
5909     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5910   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5911                                            regno + !! TARGET_LITTLE_ENDIAN),
5912                                   mem2, operands[2]));
5913   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5914   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5915                                                regno + ! TARGET_LITTLE_ENDIAN),
5916                                   change_address (mem, SFmode, NULL_RTX),
5917                                   operands[2]));
5918   DONE;
5919 }")
5920
5921 (define_split
5922   [(set (match_operand:DF 0 "register_operand" "")
5923         (match_operand:DF 1 "memory_operand" ""))
5924    (use (match_operand:PSI 2 "fpscr_operand" ""))
5925    (clobber (match_scratch:SI 3 ""))]
5926   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5927    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5928   [(const_int 0)]
5929   "
5930 {
5931   int regno = true_regnum (operands[0]);
5932   rtx addr, insn, adjust = NULL_RTX;
5933   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
5934   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5935   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5936
5937   operands[1] = copy_rtx (mem2);
5938   addr = XEXP (mem2, 0);
5939   if (GET_CODE (addr) != POST_INC)
5940     {
5941       /* If we have to modify the stack pointer, the value that we have
5942          read with post-increment might be modified by an interrupt,
5943          so write it back.  */
5944       if (REGNO (addr) == STACK_POINTER_REGNUM)
5945         adjust = gen_push_e (reg0);
5946       else
5947         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5948       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5949     }
5950   addr = XEXP (addr, 0);
5951   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5952   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5953   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5954   if (adjust)
5955     emit_insn (adjust);
5956   else
5957     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5958   DONE;
5959 }")
5960
5961 (define_split
5962   [(set (match_operand:DF 0 "memory_operand" "")
5963         (match_operand:DF 1 "register_operand" ""))
5964    (use (match_operand:PSI 2 "fpscr_operand" ""))
5965    (clobber (match_scratch:SI 3 ""))]
5966   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5967    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5968   [(const_int 0)]
5969   "
5970 {
5971   int regno = true_regnum (operands[1]);
5972   rtx insn, addr, adjust = NULL_RTX;
5973
5974   operands[0] = copy_rtx (operands[0]);
5975   PUT_MODE (operands[0], SFmode);
5976   insn = emit_insn (gen_movsf_ie (operands[0],
5977                                   gen_rtx_REG (SFmode,
5978                                            regno + ! TARGET_LITTLE_ENDIAN),
5979                                   operands[2]));
5980   operands[0] = copy_rtx (operands[0]);
5981   addr = XEXP (operands[0], 0);
5982   if (GET_CODE (addr) != PRE_DEC)
5983     {
5984       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5985       emit_insn_before (adjust, insn);
5986       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5987     }
5988   addr = XEXP (addr, 0);
5989   if (! adjust)
5990     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5991   insn = emit_insn (gen_movsf_ie (operands[0],
5992                                   gen_rtx_REG (SFmode,
5993                                            regno + !! TARGET_LITTLE_ENDIAN),
5994                                   operands[2]));
5995   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5996   DONE;
5997 }")
5998
5999 ;; If the output is a register and the input is memory or a register, we have
6000 ;; to be careful and see which word needs to be loaded first.
6001
6002 (define_split
6003   [(set (match_operand:DF 0 "general_movdst_operand" "")
6004         (match_operand:DF 1 "general_movsrc_operand" ""))]
6005   "TARGET_SH1 && reload_completed"
6006   [(set (match_dup 2) (match_dup 3))
6007    (set (match_dup 4) (match_dup 5))]
6008   "
6009 {
6010   int regno;
6011
6012   if ((GET_CODE (operands[0]) == MEM
6013        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6014       || (GET_CODE (operands[1]) == MEM
6015           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6016     FAIL;
6017
6018   switch (GET_CODE (operands[0]))
6019     {
6020     case REG:
6021       regno = REGNO (operands[0]);
6022       break;
6023     case SUBREG:
6024       regno = subreg_regno (operands[0]);
6025       break;
6026     case MEM:
6027       regno = -1;
6028       break;
6029     default:
6030       gcc_unreachable ();
6031     }
6032
6033   if (regno == -1
6034       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6035     {
6036       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6037       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6038       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6039       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6040     }
6041   else
6042     {
6043       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6044       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6045       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6046       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6047     }
6048
6049   if (operands[2] == 0 || operands[3] == 0
6050       || operands[4] == 0 || operands[5] == 0)
6051     FAIL;
6052 }")
6053
6054 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6055 ;; used only once, let combine add in the index again.
6056
6057 (define_split
6058   [(set (match_operand:SI 0 "register_operand" "")
6059         (match_operand:SI 1 "" ""))
6060    (clobber (match_operand 2 "register_operand" ""))]
6061   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6062    && ALLOW_INDEXED_ADDRESS"
6063   [(use (reg:SI R0_REG))]
6064   "
6065 {
6066   rtx addr, reg, const_int;
6067
6068   if (GET_CODE (operands[1]) != MEM)
6069     FAIL;
6070   addr = XEXP (operands[1], 0);
6071   if (GET_CODE (addr) != PLUS)
6072     FAIL;
6073   reg = XEXP (addr, 0);
6074   const_int = XEXP (addr, 1);
6075   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6076          && GET_CODE (const_int) == CONST_INT))
6077     FAIL;
6078   emit_move_insn (operands[2], const_int);
6079   emit_move_insn (operands[0],
6080                   change_address (operands[1], VOIDmode,
6081                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6082   DONE;
6083 }")
6084
6085 (define_split
6086   [(set (match_operand:SI 1 "" "")
6087         (match_operand:SI 0 "register_operand" ""))
6088    (clobber (match_operand 2 "register_operand" ""))]
6089   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6090    && ALLOW_INDEXED_ADDRESS"
6091   [(use (reg:SI R0_REG))]
6092   "
6093 {
6094   rtx addr, reg, const_int;
6095
6096   if (GET_CODE (operands[1]) != MEM)
6097     FAIL;
6098   addr = XEXP (operands[1], 0);
6099   if (GET_CODE (addr) != PLUS)
6100     FAIL;
6101   reg = XEXP (addr, 0);
6102   const_int = XEXP (addr, 1);
6103   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6104          && GET_CODE (const_int) == CONST_INT))
6105     FAIL;
6106   emit_move_insn (operands[2], const_int);
6107   emit_move_insn (change_address (operands[1], VOIDmode,
6108                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6109                   operands[0]);
6110   DONE;
6111 }")
6112
6113 (define_expand "movdf"
6114   [(set (match_operand:DF 0 "general_movdst_operand" "")
6115         (match_operand:DF 1 "general_movsrc_operand" ""))]
6116   ""
6117   "
6118 {
6119   if (prepare_move_operands (operands, DFmode)) DONE;
6120   if (TARGET_SHMEDIA)
6121     {
6122       if (TARGET_SHMEDIA_FPU)
6123         emit_insn (gen_movdf_media (operands[0], operands[1]));
6124       else
6125         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6126       DONE;
6127     }
6128   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6129     {
6130       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6131       DONE;
6132     }
6133 }")
6134
6135 ;;This is incompatible with the way gcc uses subregs.
6136 ;;(define_insn "movv2sf_i"
6137 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6138 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6139 ;;  "TARGET_SHMEDIA_FPU
6140 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6141 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6142 ;;  "@
6143 ;;      #
6144 ;;      fld%M1.p        %m1, %0
6145 ;;      fst%M0.p        %m0, %1"
6146 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6147
6148 (define_insn_and_split "movv2sf_i"
6149   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6150         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6151   "TARGET_SHMEDIA_FPU"
6152   "#"
6153   "TARGET_SHMEDIA_FPU && reload_completed"
6154   [(set (match_dup 0) (match_dup 1))]
6155   "
6156 {
6157   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6158   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6159 }")
6160
6161 (define_expand "movv2sf"
6162   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6163         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6164   "TARGET_SHMEDIA_FPU"
6165   "
6166 {
6167   if (prepare_move_operands (operands, V2SFmode))
6168     DONE;
6169 }")
6170
6171 (define_expand "addv2sf3"
6172   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6173    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6174    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6175   "TARGET_SHMEDIA_FPU"
6176   "
6177 {
6178   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6179   DONE;
6180 }")
6181
6182 (define_expand "subv2sf3"
6183   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6184    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6185    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6186   "TARGET_SHMEDIA_FPU"
6187   "
6188 {
6189   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6190   DONE;
6191 }")
6192
6193 (define_expand "mulv2sf3"
6194   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6195    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6196    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6197   "TARGET_SHMEDIA_FPU"
6198   "
6199 {
6200   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6201   DONE;
6202 }")
6203
6204 (define_expand "divv2sf3"
6205   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6206    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6207    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6208   "TARGET_SHMEDIA_FPU"
6209   "
6210 {
6211   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6212   DONE;
6213 }")
6214
6215 (define_insn_and_split "*movv4sf_i"
6216   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6217         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6218   "TARGET_SHMEDIA_FPU"
6219   "#"
6220   "&& reload_completed"
6221   [(const_int 0)]
6222   "
6223 {
6224   int i;
6225
6226   for (i = 0; i < 4/2; i++)
6227     {
6228       rtx x, y;
6229
6230       if (GET_CODE (operands[0]) == MEM)
6231         x = adjust_address (operands[0], V2SFmode,
6232                             i * GET_MODE_SIZE (V2SFmode));
6233       else
6234         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6235
6236       if (GET_CODE (operands[1]) == MEM)
6237         y = adjust_address (operands[1], V2SFmode,
6238                             i * GET_MODE_SIZE (V2SFmode));
6239       else
6240         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6241
6242       emit_insn (gen_movv2sf_i (x, y));
6243     }
6244
6245   DONE;
6246 }"
6247   [(set_attr "length" "8")])
6248
6249 (define_expand "movv4sf"
6250   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6251         (match_operand:V4SF 1 "general_operand" ""))]
6252   "TARGET_SHMEDIA_FPU"
6253   "
6254 {
6255   if (prepare_move_operands (operands, V4SFmode))
6256     DONE;
6257 }")
6258
6259 (define_insn_and_split "*movv16sf_i"
6260   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6261         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6262   "TARGET_SHMEDIA_FPU"
6263   "#"
6264   "&& reload_completed"
6265   [(const_int 0)]
6266   "
6267 {
6268   int i;
6269
6270   for (i = 0; i < 16/2; i++)
6271     {
6272       rtx x,y;
6273
6274       if (GET_CODE (operands[0]) == MEM)
6275         x = adjust_address (operands[0], V2SFmode,
6276                             i * GET_MODE_SIZE (V2SFmode));
6277       else
6278         {
6279           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6280           alter_subreg (&x);
6281         }
6282
6283       if (GET_CODE (operands[1]) == MEM)
6284         y = adjust_address (operands[1], V2SFmode,
6285                             i * GET_MODE_SIZE (V2SFmode));
6286       else
6287         {
6288           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6289           alter_subreg (&y);
6290         }
6291
6292       emit_insn (gen_movv2sf_i (x, y));
6293     }
6294
6295   DONE;
6296 }"
6297   [(set_attr "length" "32")])
6298
6299 (define_expand "movv16sf"
6300   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6301         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6302   "TARGET_SHMEDIA_FPU"
6303   "
6304 {
6305   if (prepare_move_operands (operands, V16SFmode))
6306     DONE;
6307 }")
6308
6309 (define_insn "movsf_media"
6310   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6311         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6312   "TARGET_SHMEDIA_FPU
6313    && (register_operand (operands[0], SFmode)
6314        || sh_register_operand (operands[1], SFmode))"
6315   "@
6316         fmov.s  %1, %0
6317         fmov.ls %N1, %0
6318         fmov.sl %1, %0
6319         add.l   %1, r63, %0
6320         #
6321         fld%M1.s        %m1, %0
6322         fst%M0.s        %m0, %1
6323         ld%M1.l %m1, %0
6324         st%M0.l %m0, %N1"
6325   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6326    (set (attr "highpart")
6327         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6328                (const_string "user")]
6329               (const_string "ignore")))])
6330
6331 (define_insn "movsf_media_nofpu"
6332   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6333         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6334   "TARGET_SHMEDIA
6335    && (register_operand (operands[0], SFmode)
6336        || sh_register_operand (operands[1], SFmode))"
6337   "@
6338         add.l   %1, r63, %0
6339         #
6340         ld%M1.l %m1, %0
6341         st%M0.l %m0, %N1"
6342   [(set_attr "type" "arith_media,*,load_media,store_media")
6343    (set (attr "highpart")
6344         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6345                (const_string "user")]
6346               (const_string "ignore")))])
6347
6348 (define_split
6349   [(set (match_operand:SF 0 "arith_reg_dest" "")
6350         (match_operand:SF 1 "immediate_operand" ""))]
6351   "TARGET_SHMEDIA && reload_completed
6352    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6353   [(set (match_dup 3) (match_dup 2))]
6354   "
6355 {
6356   long values;
6357   REAL_VALUE_TYPE value;
6358
6359   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6360   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6361   operands[2] = GEN_INT (values);
6362
6363   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6364 }")
6365
6366 (define_insn "movsf_i"
6367   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6368         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6369   "TARGET_SH1
6370    && (! TARGET_SH2E
6371        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6372        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6373        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6374    && (arith_reg_operand (operands[0], SFmode)
6375        || arith_reg_operand (operands[1], SFmode))"
6376   "@
6377         mov     %1,%0
6378         mov     #0,%0
6379         mov.l   %1,%0
6380         mov.l   %1,%0
6381         mov.l   %1,%0
6382         lds     %1,%0
6383         sts     %1,%0"
6384   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6385
6386 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6387 ;; update_flow_info would not know where to put REG_EQUAL notes
6388 ;; when the destination changes mode.
6389 (define_insn "movsf_ie"
6390   [(set (match_operand:SF 0 "general_movdst_operand"
6391          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6392         (match_operand:SF 1 "general_movsrc_operand"
6393           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6394    (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"))
6395    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6396
6397   "TARGET_SH2E
6398    && (arith_reg_operand (operands[0], SFmode)
6399        || arith_reg_operand (operands[1], SFmode)
6400        || arith_reg_operand (operands[3], SImode)
6401        || (fpul_operand (operands[0], SFmode)
6402            && memory_operand (operands[1], SFmode)
6403            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6404        || (fpul_operand (operands[1], SFmode)
6405            && memory_operand (operands[0], SFmode)
6406            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6407   "@
6408         fmov    %1,%0
6409         mov     %1,%0
6410         fldi0   %0
6411         fldi1   %0
6412         #
6413         fmov.s  %1,%0
6414         fmov.s  %1,%0
6415         mov.l   %1,%0
6416         mov.l   %1,%0
6417         mov.l   %1,%0
6418         fsts    fpul,%0
6419         flds    %1,fpul
6420         lds.l   %1,%0
6421         #
6422         sts     %1,%0
6423         lds     %1,%0
6424         sts.l   %1,%0
6425         lds.l   %1,%0
6426         ! move optimized away"
6427   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6428    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6429    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6430    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6431                                            (const_string "single")
6432                                            (const_string "none")))])
6433
6434 (define_split
6435   [(set (match_operand:SF 0 "register_operand" "")
6436         (match_operand:SF 1 "register_operand" ""))
6437    (use (match_operand:PSI 2 "fpscr_operand" ""))
6438    (clobber (reg:SI FPUL_REG))]
6439   "TARGET_SH1"
6440   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6441               (use (match_dup 2))
6442               (clobber (scratch:SI))])
6443    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6444               (use (match_dup 2))
6445               (clobber (scratch:SI))])]
6446   "")
6447
6448 (define_expand "movsf"
6449   [(set (match_operand:SF 0 "general_movdst_operand" "")
6450         (match_operand:SF 1 "general_movsrc_operand" ""))]
6451   ""
6452   "
6453 {
6454   if (prepare_move_operands (operands, SFmode))
6455     DONE;
6456   if (TARGET_SHMEDIA)
6457     {
6458       if (TARGET_SHMEDIA_FPU)
6459         emit_insn (gen_movsf_media (operands[0], operands[1]));
6460       else
6461         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6462       DONE;
6463     }
6464   if (TARGET_SH2E)
6465     {
6466       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6467       DONE;
6468     }
6469 }")
6470
6471 (define_insn "mov_nop"
6472   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6473   "TARGET_SH2E"
6474   ""
6475   [(set_attr "length" "0")
6476    (set_attr "type" "nil")])
6477
6478 (define_expand "reload_insf"
6479   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6480                    (match_operand:SF 1 "immediate_operand" "FQ"))
6481               (use (reg:PSI FPSCR_REG))
6482               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6483   "TARGET_SH1"
6484   "")
6485
6486 (define_expand "reload_insi"
6487   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6488                    (match_operand:SI 1 "immediate_operand" "i"))
6489               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6490   "TARGET_SH1"
6491   "")
6492
6493 (define_expand "ptabs"
6494   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6495   "TARGET_SHMEDIA"
6496   "
6497 {
6498   if (!TARGET_PT_FIXED)
6499     {
6500       rtx eq = operands[1];
6501
6502       /* ??? For canonical RTL we really should remove any CONST from EQ
6503          before wrapping it in the AND, and finally wrap the EQ into a
6504          const if is constant.  However, for reload we must expose the
6505          input register or symbolic constant, and we can't have
6506          different insn structures outside of the operands for different
6507          alternatives of the same pattern.  */
6508       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6509                        GEN_INT (3));
6510       operands[1]
6511         = (gen_rtx_IF_THEN_ELSE
6512             (PDImode,
6513              eq,
6514              gen_rtx_MEM (PDImode, operands[1]),
6515              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6516                             PDImode, operands[1])));
6517     }
6518 }")
6519
6520 ;; expanded by ptabs expander.
6521 (define_insn "*extendsipdi_media"
6522   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6523         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6524                                                           "r,Csy")
6525                                       (const_int 3))
6526                               (const_int 3))
6527                           (mem:PDI (match_dup 1))
6528                           (sign_extend:PDI (match_dup 1))))]
6529   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6530   "@
6531         ptabs   %1, %0
6532         pt      %1, %0"
6533   [(set_attr "type"   "ptabs_media,pt_media")
6534    (set_attr "length" "4,*")])
6535
6536 (define_insn "*truncdipdi_media"
6537   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6538         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6539                                                           "r,Csy")
6540                                       (const_int 3))
6541                               (const_int 3))
6542                           (mem:PDI (match_dup 1))
6543                           (truncate:PDI (match_dup 1))))]
6544   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6545   "@
6546         ptabs   %1, %0
6547         pt      %1, %0"
6548   [(set_attr "type"   "ptabs_media,pt_media")
6549    (set_attr "length" "4,*")])
6550
6551 (define_insn "*movsi_y"
6552   [(set (match_operand:SI 0 "register_operand" "=y,y")
6553         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6554    (clobber (match_scratch:SI 2 "=&z,r"))]
6555   "TARGET_SH2E
6556    && (reload_in_progress || reload_completed)"
6557   "#"
6558   [(set_attr "length" "4")
6559    (set_attr "type" "pcload,move")])
6560
6561 (define_split
6562   [(set (match_operand:SI 0 "register_operand" "")
6563         (match_operand:SI 1 "immediate_operand" ""))
6564    (clobber (match_operand:SI 2 "register_operand" ""))]
6565   "TARGET_SH1"
6566   [(set (match_dup 2) (match_dup 1))
6567    (set (match_dup 0) (match_dup 2))]
6568   "")
6569
6570 (define_split
6571   [(set (match_operand:SI 0 "register_operand" "")
6572         (match_operand:SI 1 "memory_operand" ""))
6573    (clobber (reg:SI R0_REG))]
6574   "TARGET_SH1"
6575   [(set (match_dup 0) (match_dup 1))]
6576   "")
6577 \f
6578 ;; ------------------------------------------------------------------------
6579 ;; Define the real conditional branch instructions.
6580 ;; ------------------------------------------------------------------------
6581
6582 (define_insn "branch_true"
6583   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6584                            (label_ref (match_operand 0 "" ""))
6585                            (pc)))]
6586   "TARGET_SH1"
6587   "* return output_branch (1, insn, operands);"
6588   [(set_attr "type" "cbranch")])
6589
6590 (define_insn "branch_false"
6591   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6592                            (label_ref (match_operand 0 "" ""))
6593                            (pc)))]
6594   "TARGET_SH1"
6595   "* return output_branch (0, insn, operands);"
6596   [(set_attr "type" "cbranch")])
6597
6598 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6599 ;; which destination is too far away.
6600 ;; The const_int_operand is distinct for each branch target; it avoids
6601 ;; unwanted matches with redundant_insn.
6602 (define_insn "block_branch_redirect"
6603   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6604   "TARGET_SH1"
6605   ""
6606   [(set_attr "length" "0")])
6607
6608 ;; This one has the additional purpose to record a possible scratch register
6609 ;; for the following branch.
6610 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6611 ;; because the insn then might be deemed dead and deleted.  And we can't
6612 ;; make the use in the jump insn explicit because that would disable
6613 ;; delay slot scheduling from the target.
6614 (define_insn "indirect_jump_scratch"
6615   [(set (match_operand:SI 0 "register_operand" "=r")
6616         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6617    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6618   "TARGET_SH1"
6619   ""
6620   [(set_attr "length" "0")])
6621
6622 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6623 ;; being pulled into the delay slot of a condbranch that has been made to
6624 ;; jump around the unconditional jump because it was out of range.
6625 (define_insn "stuff_delay_slot"
6626   [(set (pc)
6627         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6628    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6629   "TARGET_SH1"
6630   ""
6631   [(set_attr "length" "0")
6632    (set_attr "cond_delay_slot" "yes")])
6633 \f
6634 ;; Conditional branch insns
6635
6636 (define_expand "beq_media"
6637   [(set (pc)
6638         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6639                           (match_operand:DI 2 "arith_operand" "r,I06"))
6640                       (match_operand 0 "" "")
6641                       (pc)))]
6642   "TARGET_SHMEDIA"
6643   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6644
6645 (define_insn "*beq_media_i"
6646   [(set (pc)
6647         (if_then_else (match_operator 3 "equality_comparison_operator"
6648                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6649                          (match_operand:DI 2 "arith_operand" "r,I06")])
6650                       (match_operand 0 "target_operand" "b,b")
6651                       (pc)))]
6652   "TARGET_SHMEDIA"
6653   "@
6654         b%o3%'  %1, %2, %0%>
6655         b%o3i%' %1, %2, %0%>"
6656   [(set_attr "type" "cbranch_media")])
6657
6658 (define_insn "*beq_media_i32"
6659   [(set (pc)
6660         (if_then_else (match_operator 3 "equality_comparison_operator"
6661                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6662                          (match_operand:SI 2 "arith_operand" "r,I06")])
6663                       (match_operand 0 "target_operand" "b,b")
6664                       (pc)))]
6665   "TARGET_SHMEDIA"
6666   "@
6667         b%o3%'  %1, %2, %0%>
6668         b%o3i%' %1, %2, %0%>"
6669   [(set_attr "type" "cbranch_media")])
6670
6671 (define_expand "bne_media"
6672   [(set (pc)
6673         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6674                           (match_operand:DI 2 "arith_operand" "r,I06"))
6675                       (match_operand 0 "" "")
6676                       (pc)))]
6677   "TARGET_SHMEDIA"
6678   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6679
6680 (define_expand "bgt_media"
6681   [(set (pc)
6682         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6683                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6684                       (match_operand 0 "" "")
6685                       (pc)))]
6686   "TARGET_SHMEDIA"
6687   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6688
6689 (define_expand "bge_media"
6690   [(set (pc)
6691         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6692                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6693                       (match_operand 0 "" "")
6694                       (pc)))]
6695   "TARGET_SHMEDIA"
6696   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6697
6698 (define_expand "bgtu_media"
6699   [(set (pc)
6700         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6701                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6702                       (match_operand 0 "" "")
6703                       (pc)))]
6704   "TARGET_SHMEDIA"
6705   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6706
6707 (define_expand "bgeu_media"
6708   [(set (pc)
6709         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6710                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6711                       (match_operand 0 "" "")
6712                       (pc)))]
6713   "TARGET_SHMEDIA"
6714   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6715
6716 (define_insn "*bgt_media_i"
6717   [(set (pc)
6718         (if_then_else (match_operator 3 "greater_comparison_operator"
6719                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6720                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6721                       (match_operand 0 "target_operand" "b")
6722                       (pc)))]
6723   "TARGET_SHMEDIA"
6724   "b%o3%'       %N1, %N2, %0%>"
6725   [(set_attr "type" "cbranch_media")])
6726
6727 (define_insn "*bgt_media_i32"
6728   [(set (pc)
6729         (if_then_else (match_operator 3 "greater_comparison_operator"
6730                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6731                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6732                       (match_operand 0 "target_operand" "b")
6733                       (pc)))]
6734   "TARGET_SHMEDIA"
6735   "b%o3%'       %N1, %N2, %0%>"
6736   [(set_attr "type" "cbranch_media")])
6737
6738 ;; These are only needed to make invert_jump() happy - otherwise, jump
6739 ;; optimization will be silently disabled.
6740 (define_insn "*blt_media_i"
6741   [(set (pc)
6742         (if_then_else (match_operator 3 "less_comparison_operator"
6743                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6744                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6745                       (match_operand 0 "target_operand" "b")
6746                       (pc)))]
6747   "TARGET_SHMEDIA"
6748   "b%o3%'       %N2, %N1, %0%>"
6749   [(set_attr "type" "cbranch_media")])
6750
6751 (define_insn "*blt_media_i32"
6752   [(set (pc)
6753         (if_then_else (match_operator 3 "less_comparison_operator"
6754                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6755                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6756                       (match_operand 0 "target_operand" "b")
6757                       (pc)))]
6758   "TARGET_SHMEDIA"
6759   "b%o3%'       %N2, %N1, %0%>"
6760   [(set_attr "type" "cbranch_media")])
6761
6762 (define_expand "beq"
6763   [(set (pc)
6764         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6765                       (label_ref (match_operand 0 "" ""))
6766                       (pc)))]
6767   ""
6768   "
6769 {
6770   if (TARGET_SHMEDIA)
6771     {
6772       enum machine_mode mode = GET_MODE (sh_compare_op0);
6773
6774       if (mode != DImode && mode != SImode)
6775         {
6776           rtx tmp = gen_reg_rtx (DImode);
6777
6778           emit_insn (gen_seq (tmp));
6779           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6780           DONE;
6781         }
6782
6783       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6784       if (CONSTANT_P (sh_compare_op1)
6785           && (GET_CODE (sh_compare_op1) != CONST_INT
6786               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6787         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6788       emit_jump_insn (gen_beq_media (operands[0],
6789                                      sh_compare_op0, sh_compare_op1));
6790       DONE;
6791     }
6792
6793   from_compare (operands, EQ);
6794 }")
6795
6796 (define_expand "bne"
6797   [(set (pc)
6798         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6799                       (label_ref (match_operand 0 "" ""))
6800                       (pc)))]
6801   ""
6802   "
6803 {
6804   if (TARGET_SHMEDIA)
6805     {
6806       enum machine_mode mode = GET_MODE (sh_compare_op0);
6807
6808       if (mode != DImode && mode != SImode)
6809         {
6810           rtx tmp = gen_reg_rtx (DImode);
6811
6812           emit_insn (gen_seq (tmp));
6813           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6814           DONE;
6815         }
6816
6817       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6818       if (CONSTANT_P (sh_compare_op1)
6819           && (GET_CODE (sh_compare_op1) != CONST_INT
6820               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6821         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6822       emit_jump_insn (gen_bne_media (operands[0],
6823                                      sh_compare_op0, sh_compare_op1));
6824       DONE;
6825     }
6826
6827   from_compare (operands, EQ);
6828 }")
6829
6830 (define_expand "bgt"
6831   [(set (pc)
6832         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6833                       (label_ref (match_operand 0 "" ""))
6834                       (pc)))]
6835   ""
6836   "
6837 {
6838   if (TARGET_SHMEDIA)
6839     {
6840       enum machine_mode mode = GET_MODE (sh_compare_op0);
6841
6842       if (mode != DImode && mode != SImode)
6843         {
6844           rtx tmp = gen_reg_rtx (DImode);
6845
6846           emit_insn (gen_sgt (tmp));
6847           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6848           DONE;
6849         }
6850
6851       if (sh_compare_op0 != const0_rtx)
6852         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6853       if (sh_compare_op1 != const0_rtx)
6854         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6855       emit_jump_insn (gen_bgt_media (operands[0],
6856                                      sh_compare_op0, sh_compare_op1));
6857       DONE;
6858     }
6859
6860   from_compare (operands, GT);
6861 }")
6862
6863 (define_expand "blt"
6864   [(set (pc)
6865         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6866                       (label_ref (match_operand 0 "" ""))
6867                       (pc)))]
6868   ""
6869   "
6870 {
6871   if (TARGET_SHMEDIA)
6872     {
6873       enum machine_mode mode = GET_MODE (sh_compare_op0);
6874
6875       if (mode != DImode && mode != SImode)
6876         {
6877           rtx tmp = gen_reg_rtx (DImode);
6878
6879           emit_insn (gen_slt (tmp));
6880           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6881           DONE;
6882         }
6883
6884       if (sh_compare_op0 != const0_rtx)
6885         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6886       if (sh_compare_op1 != const0_rtx)
6887         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6888       emit_jump_insn (gen_bgt_media (operands[0],
6889                                      sh_compare_op1, sh_compare_op0));
6890       DONE;
6891     }
6892
6893   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6894     {
6895       rtx tmp = sh_compare_op0;
6896       sh_compare_op0 = sh_compare_op1;
6897       sh_compare_op1 = tmp;
6898       emit_insn (gen_bgt (operands[0]));
6899       DONE;
6900     }
6901   from_compare (operands, GE);
6902 }")
6903
6904 (define_expand "ble"
6905   [(set (pc)
6906         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6907                       (label_ref (match_operand 0 "" ""))
6908                       (pc)))]
6909   ""
6910   "
6911 {
6912   if (TARGET_SHMEDIA)
6913     {
6914       enum machine_mode mode = GET_MODE (sh_compare_op0);
6915
6916       if (mode != DImode && mode != SImode)
6917         {
6918           rtx tmp = gen_reg_rtx (DImode);
6919
6920           emit_insn (gen_sle (tmp));
6921           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6922           DONE;
6923         }
6924
6925       if (sh_compare_op0 != const0_rtx)
6926         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6927       if (sh_compare_op1 != const0_rtx)
6928         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6929       emit_jump_insn (gen_bge_media (operands[0],
6930                                      sh_compare_op1, sh_compare_op0));
6931       DONE;
6932     }
6933
6934   if (TARGET_SH2E
6935       && TARGET_IEEE
6936       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6937     {
6938       rtx tmp = sh_compare_op0;
6939       sh_compare_op0 = sh_compare_op1;
6940       sh_compare_op1 = tmp;
6941       emit_insn (gen_bge (operands[0]));
6942       DONE;
6943     }
6944   from_compare (operands, GT);
6945 }")
6946
6947 (define_expand "bge"
6948   [(set (pc)
6949         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6950                       (label_ref (match_operand 0 "" ""))
6951                       (pc)))]
6952   ""
6953   "
6954 {
6955   if (TARGET_SHMEDIA)
6956     {
6957       enum machine_mode mode = GET_MODE (sh_compare_op0);
6958
6959       if (mode != DImode && mode != SImode)
6960         {
6961           rtx tmp = gen_reg_rtx (DImode);
6962
6963           emit_insn (gen_sge (tmp));
6964           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6965           DONE;
6966         }
6967
6968       if (sh_compare_op0 != const0_rtx)
6969         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6970       if (sh_compare_op1 != const0_rtx)
6971         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6972       emit_jump_insn (gen_bge_media (operands[0],
6973                                      sh_compare_op0, sh_compare_op1));
6974       DONE;
6975     }
6976
6977   if (TARGET_SH2E
6978       && ! TARGET_IEEE
6979       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6980     {
6981       rtx tmp = sh_compare_op0;
6982       sh_compare_op0 = sh_compare_op1;
6983       sh_compare_op1 = tmp;
6984       emit_insn (gen_ble (operands[0]));
6985       DONE;
6986     }
6987   from_compare (operands, GE);
6988 }")
6989
6990 (define_expand "bgtu"
6991   [(set (pc)
6992         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6993                       (label_ref (match_operand 0 "" ""))
6994                       (pc)))]
6995   ""
6996   "
6997 {
6998   if (TARGET_SHMEDIA)
6999     {
7000       enum machine_mode mode = GET_MODE (sh_compare_op0);
7001
7002       if (sh_compare_op0 != const0_rtx)
7003         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7004       if (sh_compare_op1 != const0_rtx)
7005         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7006       emit_jump_insn (gen_bgtu_media (operands[0],
7007                                       sh_compare_op0, sh_compare_op1));
7008       DONE;
7009     }
7010
7011   from_compare (operands, GTU);
7012 }")
7013
7014 (define_expand "bltu"
7015   [(set (pc)
7016         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7017                       (label_ref (match_operand 0 "" ""))
7018                       (pc)))]
7019   ""
7020   "
7021 {
7022   if (TARGET_SHMEDIA)
7023     {
7024       enum machine_mode mode = GET_MODE (sh_compare_op0);
7025
7026       if (sh_compare_op0 != const0_rtx)
7027         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7028       if (sh_compare_op1 != const0_rtx)
7029         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7030       emit_jump_insn (gen_bgtu_media (operands[0],
7031                                       sh_compare_op1, sh_compare_op0));
7032       DONE;
7033     }
7034
7035   from_compare (operands, GEU);
7036 }")
7037
7038 (define_expand "bgeu"
7039   [(set (pc)
7040         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7041                       (label_ref (match_operand 0 "" ""))
7042                       (pc)))]
7043   ""
7044   "
7045 {
7046   if (TARGET_SHMEDIA)
7047     {
7048       enum machine_mode mode = GET_MODE (sh_compare_op0);
7049
7050       if (sh_compare_op0 != const0_rtx)
7051         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7052       if (sh_compare_op1 != const0_rtx)
7053         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7054       emit_jump_insn (gen_bgeu_media (operands[0],
7055                                       sh_compare_op0, sh_compare_op1));
7056       DONE;
7057     }
7058
7059   from_compare (operands, GEU);
7060 }")
7061
7062 (define_expand "bleu"
7063   [(set (pc)
7064         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7065                       (label_ref (match_operand 0 "" ""))
7066                       (pc)))]
7067   ""
7068   "
7069 {
7070   if (TARGET_SHMEDIA)
7071     {
7072       enum machine_mode mode = GET_MODE (sh_compare_op0);
7073
7074       if (sh_compare_op0 != const0_rtx)
7075         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7076       if (sh_compare_op1 != const0_rtx)
7077         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7078       emit_jump_insn (gen_bgeu_media (operands[0],
7079                                       sh_compare_op1, sh_compare_op0));
7080       DONE;
7081     }
7082
7083   from_compare (operands, GTU);
7084 }")
7085
7086 (define_expand "bunordered"
7087   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7088    (set (pc)
7089         (if_then_else (ne (match_dup 1) (const_int 0))
7090                       (match_operand 0 "" "")
7091                       (pc)))]
7092   "TARGET_SHMEDIA"
7093   "
7094 {
7095   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7096   operands[1] = gen_reg_rtx (DImode);
7097   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7098   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7099 }")
7100
7101 ;; combiner splitter for test-and-branch on single bit in register.  This
7102 ;; is endian dependent because the non-paradoxical subreg looks different
7103 ;; on big endian.
7104 (define_split
7105   [(set (pc)
7106         (if_then_else
7107           (match_operator 3 "equality_comparison_operator"
7108             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7109                                                       "extend_reg_operand" "")
7110                                                     0)
7111                                          (const_int 1)
7112                                          (match_operand 2
7113                                           "const_int_operand" "")) 0)
7114              (const_int 0)])
7115           (match_operand 0 "target_operand" "")
7116           (pc)))
7117    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7118   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7119   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7120    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7121
7122   "
7123 {
7124   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7125   operands[6] = (GET_CODE (operands[3]) == EQ
7126                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7127                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7128 }")
7129 \f
7130 ;; ------------------------------------------------------------------------
7131 ;; Jump and linkage insns
7132 ;; ------------------------------------------------------------------------
7133
7134 (define_insn "jump_compact"
7135   [(set (pc)
7136         (label_ref (match_operand 0 "" "")))]
7137   "TARGET_SH1"
7138   "*
7139 {
7140   /* The length is 16 if the delay slot is unfilled.  */
7141   if (get_attr_length(insn) > 4)
7142     return output_far_jump(insn, operands[0]);
7143   else
7144     return   \"bra      %l0%#\";
7145 }"
7146   [(set_attr "type" "jump")
7147    (set_attr "needs_delay_slot" "yes")])
7148
7149 ;; ??? It would be much saner to explicitly use the scratch register
7150 ;; in the jump insn, and have indirect_jump_scratch only set it,
7151 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7152 ;; from the target then, as it uses simplejump_p.
7153 ;;(define_insn "jump_compact_far"
7154 ;;  [(set (pc)
7155 ;;      (label_ref (match_operand 0 "" "")))
7156 ;;   (use (match_operand 1 "register_operand" "r")]
7157 ;;  "TARGET_SH1"
7158 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7159 ;;  [(set_attr "type" "jump")
7160 ;;   (set_attr "needs_delay_slot" "yes")])
7161
7162 (define_insn "jump_media"
7163   [(set (pc)
7164         (match_operand 0 "target_operand" "b"))]
7165   "TARGET_SHMEDIA"
7166   "blink        %0, r63%>"
7167   [(set_attr "type" "jump_media")])
7168
7169 (define_expand "jump"
7170   [(set (pc)
7171         (label_ref (match_operand 0 "" "")))]
7172   ""
7173   "
7174 {
7175   if (TARGET_SH1)
7176     emit_jump_insn (gen_jump_compact (operands[0]));
7177   else if (TARGET_SHMEDIA)
7178     {
7179       if (reload_in_progress || reload_completed)
7180         FAIL;
7181       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7182                                                          operands[0])));
7183     }
7184   DONE;
7185 }")
7186
7187 (define_insn "force_mode_for_call"
7188   [(use (reg:PSI FPSCR_REG))]
7189   "TARGET_SHCOMPACT"
7190   ""
7191   [(set_attr "length" "0")
7192    (set (attr "fp_mode")
7193         (if_then_else (eq_attr "fpu_single" "yes")
7194                       (const_string "single") (const_string "double")))])
7195
7196 (define_insn "calli"
7197   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7198          (match_operand 1 "" ""))
7199    (use (reg:PSI FPSCR_REG))
7200    (clobber (reg:SI PR_REG))]
7201   "TARGET_SH1"
7202   "jsr  @%0%#"
7203   [(set_attr "type" "call")
7204    (set (attr "fp_mode")
7205         (if_then_else (eq_attr "fpu_single" "yes")
7206                       (const_string "single") (const_string "double")))
7207    (set_attr "needs_delay_slot" "yes")
7208    (set_attr "fp_set" "unknown")])
7209
7210 ;; This is a pc-rel call, using bsrf, for use with PIC.
7211
7212 (define_insn "calli_pcrel"
7213   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7214          (match_operand 1 "" ""))
7215    (use (reg:PSI FPSCR_REG))
7216    (use (reg:SI PIC_REG))
7217    (use (match_operand 2 "" ""))
7218    (clobber (reg:SI PR_REG))]
7219   "TARGET_SH2"
7220   "bsrf %0\\n%O2:%#"
7221   [(set_attr "type" "call")
7222    (set (attr "fp_mode")
7223         (if_then_else (eq_attr "fpu_single" "yes")
7224                       (const_string "single") (const_string "double")))
7225    (set_attr "needs_delay_slot" "yes")
7226    (set_attr "fp_set" "unknown")])
7227
7228 (define_insn_and_split "call_pcrel"
7229   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7230          (match_operand 1 "" ""))
7231    (use (reg:PSI FPSCR_REG))
7232    (use (reg:SI PIC_REG))
7233    (clobber (reg:SI PR_REG))
7234    (clobber (match_scratch:SI 2 "=r"))]
7235   "TARGET_SH2"
7236   "#"
7237   "reload_completed"
7238   [(const_int 0)]
7239   "
7240 {
7241   rtx lab = PATTERN (gen_call_site ());
7242
7243   if (SYMBOL_REF_LOCAL_P (operands[0]))
7244     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7245   else
7246     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7247   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7248   DONE;
7249 }"
7250   [(set_attr "type" "call")
7251    (set (attr "fp_mode")
7252         (if_then_else (eq_attr "fpu_single" "yes")
7253                       (const_string "single") (const_string "double")))
7254    (set_attr "needs_delay_slot" "yes")
7255    (set_attr "fp_set" "unknown")])
7256
7257 (define_insn "call_compact"
7258   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7259          (match_operand 1 "" ""))
7260    (match_operand 2 "immediate_operand" "n")
7261    (use (reg:SI R0_REG))
7262    (use (reg:SI R1_REG))
7263    (use (reg:PSI FPSCR_REG))
7264    (clobber (reg:SI PR_REG))]
7265   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7266   "jsr  @%0%#"
7267   [(set_attr "type" "call")
7268    (set (attr "fp_mode")
7269         (if_then_else (eq_attr "fpu_single" "yes")
7270                       (const_string "single") (const_string "double")))
7271    (set_attr "needs_delay_slot" "yes")])
7272
7273 (define_insn "call_compact_rettramp"
7274   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7275          (match_operand 1 "" ""))
7276    (match_operand 2 "immediate_operand" "n")
7277    (use (reg:SI R0_REG))
7278    (use (reg:SI R1_REG))
7279    (use (reg:PSI FPSCR_REG))
7280    (clobber (reg:SI R10_REG))
7281    (clobber (reg:SI PR_REG))]
7282   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7283   "jsr  @%0%#"
7284   [(set_attr "type" "call")
7285    (set (attr "fp_mode")
7286         (if_then_else (eq_attr "fpu_single" "yes")
7287                       (const_string "single") (const_string "double")))
7288    (set_attr "needs_delay_slot" "yes")])
7289
7290 (define_insn "call_media"
7291   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7292          (match_operand 1 "" ""))
7293    (clobber (reg:DI PR_MEDIA_REG))]
7294   "TARGET_SHMEDIA"
7295   "blink        %0, r18"
7296   [(set_attr "type" "jump_media")])
7297
7298 (define_insn "call_valuei"
7299   [(set (match_operand 0 "" "=rf")
7300         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7301               (match_operand 2 "" "")))
7302    (use (reg:PSI FPSCR_REG))
7303    (clobber (reg:SI PR_REG))]
7304   "TARGET_SH1"
7305   "jsr  @%1%#"
7306   [(set_attr "type" "call")
7307    (set (attr "fp_mode")
7308         (if_then_else (eq_attr "fpu_single" "yes")
7309                       (const_string "single") (const_string "double")))
7310    (set_attr "needs_delay_slot" "yes")
7311    (set_attr "fp_set" "unknown")])
7312
7313 (define_insn "call_valuei_pcrel"
7314   [(set (match_operand 0 "" "=rf")
7315         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7316               (match_operand 2 "" "")))
7317    (use (reg:PSI FPSCR_REG))
7318    (use (reg:SI PIC_REG))
7319    (use (match_operand 3 "" ""))
7320    (clobber (reg:SI PR_REG))]
7321   "TARGET_SH2"
7322   "bsrf %1\\n%O3:%#"
7323   [(set_attr "type" "call")
7324    (set (attr "fp_mode")
7325         (if_then_else (eq_attr "fpu_single" "yes")
7326                       (const_string "single") (const_string "double")))
7327    (set_attr "needs_delay_slot" "yes")
7328    (set_attr "fp_set" "unknown")])
7329
7330 (define_insn_and_split "call_value_pcrel"
7331   [(set (match_operand 0 "" "=rf")
7332         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7333               (match_operand 2 "" "")))
7334    (use (reg:PSI FPSCR_REG))
7335    (use (reg:SI PIC_REG))
7336    (clobber (reg:SI PR_REG))
7337    (clobber (match_scratch:SI 3 "=r"))]
7338   "TARGET_SH2"
7339   "#"
7340   "reload_completed"
7341   [(const_int 0)]
7342   "
7343 {
7344   rtx lab = PATTERN (gen_call_site ());
7345
7346   if (SYMBOL_REF_LOCAL_P (operands[1]))
7347     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7348   else
7349     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7350   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7351                                          operands[2], lab));
7352   DONE;
7353 }"
7354   [(set_attr "type" "call")
7355    (set (attr "fp_mode")
7356         (if_then_else (eq_attr "fpu_single" "yes")
7357                       (const_string "single") (const_string "double")))
7358    (set_attr "needs_delay_slot" "yes")
7359    (set_attr "fp_set" "unknown")])
7360
7361 (define_insn "call_value_compact"
7362   [(set (match_operand 0 "" "=rf")
7363         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7364               (match_operand 2 "" "")))
7365    (match_operand 3 "immediate_operand" "n")
7366    (use (reg:SI R0_REG))
7367    (use (reg:SI R1_REG))
7368    (use (reg:PSI FPSCR_REG))
7369    (clobber (reg:SI PR_REG))]
7370   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7371   "jsr  @%1%#"
7372   [(set_attr "type" "call")
7373    (set (attr "fp_mode")
7374         (if_then_else (eq_attr "fpu_single" "yes")
7375                       (const_string "single") (const_string "double")))
7376    (set_attr "needs_delay_slot" "yes")])
7377
7378 (define_insn "call_value_compact_rettramp"
7379   [(set (match_operand 0 "" "=rf")
7380         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7381               (match_operand 2 "" "")))
7382    (match_operand 3 "immediate_operand" "n")
7383    (use (reg:SI R0_REG))
7384    (use (reg:SI R1_REG))
7385    (use (reg:PSI FPSCR_REG))
7386    (clobber (reg:SI R10_REG))
7387    (clobber (reg:SI PR_REG))]
7388   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7389   "jsr  @%1%#"
7390   [(set_attr "type" "call")
7391    (set (attr "fp_mode")
7392         (if_then_else (eq_attr "fpu_single" "yes")
7393                       (const_string "single") (const_string "double")))
7394    (set_attr "needs_delay_slot" "yes")])
7395
7396 (define_insn "call_value_media"
7397   [(set (match_operand 0 "" "=rf")
7398         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7399               (match_operand 2 "" "")))
7400    (clobber (reg:DI PR_MEDIA_REG))]
7401   "TARGET_SHMEDIA"
7402   "blink        %1, r18"
7403   [(set_attr "type" "jump_media")])
7404
7405 (define_expand "call"
7406   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7407                             (match_operand 1 "" ""))
7408               (match_operand 2 "" "")
7409               (use (reg:PSI FPSCR_REG))
7410               (clobber (reg:SI PR_REG))])]
7411   ""
7412   "
7413 {
7414   if (TARGET_SHMEDIA)
7415     {
7416       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7417       emit_call_insn (gen_call_media (operands[0], operands[1]));
7418       DONE;
7419     }
7420   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7421     {
7422       rtx cookie_rtx = operands[2];
7423       long cookie = INTVAL (cookie_rtx);
7424       rtx func = XEXP (operands[0], 0);
7425       rtx r0, r1;
7426
7427       if (flag_pic)
7428         {
7429           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7430             {
7431               rtx reg = gen_reg_rtx (Pmode);
7432
7433               emit_insn (gen_symGOTPLT2reg (reg, func));
7434               func = reg;
7435             }
7436           else
7437             func = legitimize_pic_address (func, Pmode, 0);
7438         }
7439
7440       r0 = gen_rtx_REG (SImode, R0_REG);
7441       r1 = gen_rtx_REG (SImode, R1_REG);
7442
7443       /* Since such a call function may use all call-clobbered
7444          registers, we force a mode switch earlier, so that we don't
7445          run out of registers when adjusting fpscr for the call.  */
7446       emit_insn (gen_force_mode_for_call ());
7447
7448       operands[0]
7449         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7450                            SFUNC_GOT);
7451       operands[0] = force_reg (SImode, operands[0]);
7452
7453       emit_move_insn (r0, func);
7454       emit_move_insn (r1, cookie_rtx);
7455
7456       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7457         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7458                                                    operands[2]));
7459       else
7460         emit_call_insn (gen_call_compact (operands[0], operands[1],
7461                                           operands[2]));
7462
7463       DONE;
7464     }
7465   else if (TARGET_SHCOMPACT && flag_pic
7466            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7467            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7468     {
7469       rtx reg = gen_reg_rtx (Pmode);
7470
7471       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7472       XEXP (operands[0], 0) = reg;
7473     }
7474   if (flag_pic && TARGET_SH2
7475       && GET_CODE (operands[0]) == MEM
7476       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7477     {
7478       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7479       DONE;
7480     }
7481   else
7482   {
7483     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7484     operands[1] = operands[2];
7485   }
7486
7487   emit_call_insn (gen_calli (operands[0], operands[1]));
7488   DONE;
7489 }")
7490
7491 (define_insn "call_pop_compact"
7492   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7493          (match_operand 1 "" ""))
7494    (match_operand 2 "immediate_operand" "n")
7495    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7496                                  (match_operand 3 "immediate_operand" "n")))
7497    (use (reg:SI R0_REG))
7498    (use (reg:SI R1_REG))
7499    (use (reg:PSI FPSCR_REG))
7500    (clobber (reg:SI PR_REG))]
7501   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7502   "jsr  @%0%#"
7503   [(set_attr "type" "call")
7504    (set (attr "fp_mode")
7505         (if_then_else (eq_attr "fpu_single" "yes")
7506                       (const_string "single") (const_string "double")))
7507    (set_attr "needs_delay_slot" "yes")])
7508
7509 (define_insn "call_pop_compact_rettramp"
7510   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7511          (match_operand 1 "" ""))
7512    (match_operand 2 "immediate_operand" "n")
7513    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7514                                  (match_operand 3 "immediate_operand" "n")))
7515    (use (reg:SI R0_REG))
7516    (use (reg:SI R1_REG))
7517    (use (reg:PSI FPSCR_REG))
7518    (clobber (reg:SI R10_REG))
7519    (clobber (reg:SI PR_REG))]
7520   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7521   "jsr  @%0%#"
7522   [(set_attr "type" "call")
7523    (set (attr "fp_mode")
7524         (if_then_else (eq_attr "fpu_single" "yes")
7525                       (const_string "single") (const_string "double")))
7526    (set_attr "needs_delay_slot" "yes")])
7527
7528 (define_expand "call_pop"
7529   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7530                     (match_operand 1 "" ""))
7531              (match_operand 2 "" "")
7532              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7533                                            (match_operand 3 "" "")))])]
7534   "TARGET_SHCOMPACT"
7535   "
7536 {
7537   rtx cookie_rtx;
7538   long cookie;
7539   rtx func;
7540   rtx r0, r1;
7541
7542   gcc_assert (operands[2] && INTVAL (operands[2]));
7543   cookie_rtx = operands[2];
7544   cookie = INTVAL (cookie_rtx);
7545   func = XEXP (operands[0], 0);
7546
7547   if (flag_pic)
7548     {
7549       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7550         {
7551           rtx reg = gen_reg_rtx (Pmode);
7552           emit_insn (gen_symGOTPLT2reg (reg, func));
7553           func = reg;
7554         }
7555       else
7556         func = legitimize_pic_address (func, Pmode, 0);
7557     }
7558
7559   r0 = gen_rtx_REG (SImode, R0_REG);
7560   r1 = gen_rtx_REG (SImode, R1_REG);
7561
7562   /* Since such a call function may use all call-clobbered
7563      registers, we force a mode switch earlier, so that we don't
7564      run out of registers when adjusting fpscr for the call.  */
7565   emit_insn (gen_force_mode_for_call ());
7566
7567   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7568                                  SFUNC_GOT);
7569   operands[0] = force_reg (SImode, operands[0]);
7570
7571   emit_move_insn (r0, func);
7572   emit_move_insn (r1, cookie_rtx);
7573
7574   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7575     emit_call_insn (gen_call_pop_compact_rettramp
7576                      (operands[0], operands[1], operands[2], operands[3]));
7577   else
7578     emit_call_insn (gen_call_pop_compact
7579                      (operands[0], operands[1], operands[2], operands[3]));
7580
7581   DONE;
7582 }")
7583
7584 (define_expand "call_value"
7585   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7586                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7587                                  (match_operand 2 "" "")))
7588               (match_operand 3 "" "")
7589               (use (reg:PSI FPSCR_REG))
7590               (clobber (reg:SI PR_REG))])]
7591   ""
7592   "
7593 {
7594   if (TARGET_SHMEDIA)
7595     {
7596       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7597       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7598                                             operands[2]));
7599       DONE;
7600     }
7601   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7602     {
7603       rtx cookie_rtx = operands[3];
7604       long cookie = INTVAL (cookie_rtx);
7605       rtx func = XEXP (operands[1], 0);
7606       rtx r0, r1;
7607
7608       if (flag_pic)
7609         {
7610           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7611             {
7612               rtx reg = gen_reg_rtx (Pmode);
7613
7614               emit_insn (gen_symGOTPLT2reg (reg, func));
7615               func = reg;
7616             }
7617           else
7618             func = legitimize_pic_address (func, Pmode, 0);
7619         }
7620
7621       r0 = gen_rtx_REG (SImode, R0_REG);
7622       r1 = gen_rtx_REG (SImode, R1_REG);
7623
7624       /* Since such a call function may use all call-clobbered
7625          registers, we force a mode switch earlier, so that we don't
7626          run out of registers when adjusting fpscr for the call.  */
7627       emit_insn (gen_force_mode_for_call ());
7628
7629       operands[1]
7630         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7631                            SFUNC_GOT);
7632       operands[1] = force_reg (SImode, operands[1]);
7633
7634       emit_move_insn (r0, func);
7635       emit_move_insn (r1, cookie_rtx);
7636
7637       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7638         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7639                                                          operands[1],
7640                                                          operands[2],
7641                                                          operands[3]));
7642       else
7643         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7644                                                 operands[2], operands[3]));
7645
7646       DONE;
7647     }
7648   else if (TARGET_SHCOMPACT && flag_pic
7649            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7650            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7651     {
7652       rtx reg = gen_reg_rtx (Pmode);
7653
7654       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7655       XEXP (operands[1], 0) = reg;
7656     }
7657   if (flag_pic && TARGET_SH2
7658       && GET_CODE (operands[1]) == MEM
7659       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7660     {
7661       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7662                                             operands[2]));
7663       DONE;
7664     }
7665   else
7666     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7667
7668   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7669   DONE;
7670 }")
7671
7672 (define_insn "sibcalli"
7673   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7674          (match_operand 1 "" ""))
7675    (use (reg:PSI FPSCR_REG))
7676    (return)]
7677   "TARGET_SH1"
7678   "jmp  @%0%#"
7679   [(set_attr "needs_delay_slot" "yes")
7680    (set (attr "fp_mode")
7681         (if_then_else (eq_attr "fpu_single" "yes")
7682                       (const_string "single") (const_string "double")))
7683    (set_attr "type" "jump_ind")])
7684
7685 (define_insn "sibcalli_pcrel"
7686   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7687          (match_operand 1 "" ""))
7688    (use (match_operand 2 "" ""))
7689    (use (reg:PSI FPSCR_REG))
7690    (return)]
7691   "TARGET_SH2"
7692   "braf %0\\n%O2:%#"
7693   [(set_attr "needs_delay_slot" "yes")
7694    (set (attr "fp_mode")
7695         (if_then_else (eq_attr "fpu_single" "yes")
7696                       (const_string "single") (const_string "double")))
7697    (set_attr "type" "jump_ind")])
7698
7699 ;; This uses an unspec to describe that the symbol_ref is very close.
7700 (define_insn "sibcalli_thunk"
7701   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7702                              UNSPEC_THUNK))
7703          (match_operand 1 "" ""))
7704    (use (reg:PSI FPSCR_REG))
7705    (return)]
7706   "TARGET_SH1"
7707   "bra  %O0"
7708   [(set_attr "needs_delay_slot" "yes")
7709    (set (attr "fp_mode")
7710         (if_then_else (eq_attr "fpu_single" "yes")
7711                       (const_string "single") (const_string "double")))
7712    (set_attr "type" "jump")
7713    (set_attr "length" "2")])
7714
7715 (define_insn_and_split "sibcall_pcrel"
7716   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7717          (match_operand 1 "" ""))
7718    (use (reg:PSI FPSCR_REG))
7719    (clobber (match_scratch:SI 2 "=k"))
7720    (return)]
7721   "TARGET_SH2"
7722   "#"
7723   "reload_completed"
7724   [(const_int 0)]
7725   "
7726 {
7727   rtx lab = PATTERN (gen_call_site ());
7728   rtx call_insn;
7729
7730   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7731   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7732                                                   lab));
7733   SIBLING_CALL_P (call_insn) = 1;
7734   DONE;
7735 }"
7736   [(set_attr "needs_delay_slot" "yes")
7737    (set (attr "fp_mode")
7738         (if_then_else (eq_attr "fpu_single" "yes")
7739                       (const_string "single") (const_string "double")))
7740    (set_attr "type" "jump_ind")])
7741
7742 (define_insn "sibcall_compact"
7743   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7744          (match_operand 1 "" ""))
7745    (return)
7746    (use (match_operand:SI 2 "register_operand" "z,x"))
7747    (use (reg:SI R1_REG))
7748    (use (reg:PSI FPSCR_REG))
7749    ;; We want to make sure the `x' above will only match MACH_REG
7750    ;; because sibcall_epilogue may clobber MACL_REG.
7751    (clobber (reg:SI MACL_REG))]
7752   "TARGET_SHCOMPACT"
7753   "@
7754         jmp     @%0%#
7755         jmp     @%0\\n  sts     %2, r0"
7756   [(set_attr "needs_delay_slot" "yes,no")
7757    (set_attr "length" "2,4")
7758    (set (attr "fp_mode") (const_string "single"))
7759    (set_attr "type" "jump_ind")])
7760
7761 (define_insn "sibcall_media"
7762   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7763          (match_operand 1 "" ""))
7764    (use (reg:SI PR_MEDIA_REG))
7765    (return)]
7766   "TARGET_SHMEDIA"
7767   "blink        %0, r63"
7768   [(set_attr "type" "jump_media")])
7769
7770 (define_expand "sibcall"
7771   [(parallel
7772     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7773            (match_operand 1 "" ""))
7774      (match_operand 2 "" "")
7775      (use (reg:PSI FPSCR_REG))
7776      (return)])]
7777   ""
7778   "
7779 {
7780   if (TARGET_SHMEDIA)
7781     {
7782       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7783       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7784       DONE;
7785     }
7786   else if (TARGET_SHCOMPACT && operands[2]
7787            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7788     {
7789       rtx cookie_rtx = operands[2];
7790       long cookie = INTVAL (cookie_rtx);
7791       rtx func = XEXP (operands[0], 0);
7792       rtx mach, r1;
7793
7794       if (flag_pic)
7795         {
7796           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7797             {
7798               rtx reg = gen_reg_rtx (Pmode);
7799
7800               emit_insn (gen_symGOT2reg (reg, func));
7801               func = reg;
7802             }
7803           else
7804             func = legitimize_pic_address (func, Pmode, 0);
7805         }
7806
7807       /* FIXME: if we could tell whether all argument registers are
7808          already taken, we could decide whether to force the use of
7809          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7810          simple way to tell.  We could use the CALL_COOKIE, but we
7811          can't currently tell a register used for regular argument
7812          passing from one that is unused.  If we leave it up to reload
7813          to decide which register to use, it seems to always choose
7814          R0_REG, which leaves no available registers in SIBCALL_REGS
7815          to hold the address of the trampoline.  */
7816       mach = gen_rtx_REG (SImode, MACH_REG);
7817       r1 = gen_rtx_REG (SImode, R1_REG);
7818
7819       /* Since such a call function may use all call-clobbered
7820          registers, we force a mode switch earlier, so that we don't
7821          run out of registers when adjusting fpscr for the call.  */
7822       emit_insn (gen_force_mode_for_call ());
7823
7824       operands[0]
7825         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7826                            SFUNC_GOT);
7827       operands[0] = force_reg (SImode, operands[0]);
7828
7829       /* We don't need a return trampoline, since the callee will
7830          return directly to the upper caller.  */
7831       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7832         {
7833           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7834           cookie_rtx = GEN_INT (cookie);
7835         }
7836
7837       emit_move_insn (mach, func);
7838       emit_move_insn (r1, cookie_rtx);
7839
7840       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7841       DONE;
7842     }
7843   else if (TARGET_SHCOMPACT && flag_pic
7844            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7845            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7846     {
7847       rtx reg = gen_reg_rtx (Pmode);
7848
7849       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7850       XEXP (operands[0], 0) = reg;
7851     }
7852   if (flag_pic && TARGET_SH2
7853       && GET_CODE (operands[0]) == MEM
7854       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7855       /* The PLT needs the PIC register, but the epilogue would have
7856          to restore it, so we can only use PC-relative PIC calls for
7857          static functions.  */
7858       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7859     {
7860       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7861       DONE;
7862     }
7863   else
7864     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7865
7866   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7867   DONE;
7868 }")
7869
7870 (define_expand "sibcall_value"
7871   [(set (match_operand 0 "" "")
7872         (call (match_operand 1 "" "")
7873               (match_operand 2 "" "")))
7874    (match_operand 3 "" "")]
7875   ""
7876   "
7877 {
7878   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7879   DONE;
7880 }")
7881
7882 (define_insn "call_value_pop_compact"
7883   [(set (match_operand 0 "" "=rf")
7884         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7885               (match_operand 2 "" "")))
7886    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7887                                  (match_operand 4 "immediate_operand" "n")))
7888    (match_operand 3 "immediate_operand" "n")
7889    (use (reg:SI R0_REG))
7890    (use (reg:SI R1_REG))
7891    (use (reg:PSI FPSCR_REG))
7892    (clobber (reg:SI PR_REG))]
7893   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7894   "jsr  @%1%#"
7895   [(set_attr "type" "call")
7896    (set (attr "fp_mode")
7897         (if_then_else (eq_attr "fpu_single" "yes")
7898                       (const_string "single") (const_string "double")))
7899    (set_attr "needs_delay_slot" "yes")])
7900
7901 (define_insn "call_value_pop_compact_rettramp"
7902   [(set (match_operand 0 "" "=rf")
7903         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7904               (match_operand 2 "" "")))
7905    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7906                                  (match_operand 4 "immediate_operand" "n")))
7907    (match_operand 3 "immediate_operand" "n")
7908    (use (reg:SI R0_REG))
7909    (use (reg:SI R1_REG))
7910    (use (reg:PSI FPSCR_REG))
7911    (clobber (reg:SI R10_REG))
7912    (clobber (reg:SI PR_REG))]
7913   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7914   "jsr  @%1%#"
7915   [(set_attr "type" "call")
7916    (set (attr "fp_mode")
7917         (if_then_else (eq_attr "fpu_single" "yes")
7918                       (const_string "single") (const_string "double")))
7919    (set_attr "needs_delay_slot" "yes")])
7920
7921 (define_expand "call_value_pop"
7922   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7923                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7924                                  (match_operand 2 "" "")))
7925               (match_operand 3 "" "")
7926               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7927                                             (match_operand 4 "" "")))])]
7928   "TARGET_SHCOMPACT"
7929   "
7930 {
7931   rtx cookie_rtx;
7932   long cookie;
7933   rtx func;
7934   rtx r0, r1;
7935
7936   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7937   cookie_rtx = operands[3];
7938   cookie = INTVAL (cookie_rtx);
7939   func = XEXP (operands[1], 0);
7940
7941   if (flag_pic)
7942     {
7943       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7944         {
7945           rtx reg = gen_reg_rtx (Pmode);
7946
7947           emit_insn (gen_symGOTPLT2reg (reg, func));
7948           func = reg;
7949         }
7950       else
7951         func = legitimize_pic_address (func, Pmode, 0);
7952     }
7953
7954   r0 = gen_rtx_REG (SImode, R0_REG);
7955   r1 = gen_rtx_REG (SImode, R1_REG);
7956
7957   /* Since such a call function may use all call-clobbered
7958      registers, we force a mode switch earlier, so that we don't
7959      run out of registers when adjusting fpscr for the call.  */
7960   emit_insn (gen_force_mode_for_call ());
7961
7962   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7963                                  SFUNC_GOT);
7964   operands[1] = force_reg (SImode, operands[1]);
7965
7966   emit_move_insn (r0, func);
7967   emit_move_insn (r1, cookie_rtx);
7968
7969   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7970     emit_call_insn (gen_call_value_pop_compact_rettramp
7971                         (operands[0], operands[1], operands[2],
7972                          operands[3], operands[4]));
7973   else
7974     emit_call_insn (gen_call_value_pop_compact
7975                         (operands[0], operands[1], operands[2],
7976                          operands[3], operands[4]));
7977
7978   DONE;
7979 }")
7980
7981 (define_expand "sibcall_epilogue"
7982   [(return)]
7983   ""
7984   "
7985 {
7986   sh_expand_epilogue (1);
7987   if (TARGET_SHCOMPACT)
7988     {
7989       rtx insn, set;
7990
7991       /* If epilogue clobbers r0, preserve it in macl.  */
7992       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7993         if ((set = single_set (insn))
7994             && GET_CODE (SET_DEST (set)) == REG
7995             && REGNO (SET_DEST (set)) == R0_REG)
7996           {
7997             rtx r0 = gen_rtx_REG (SImode, R0_REG);
7998             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
7999             rtx i;
8000
8001             /* We can't tell at this point whether the sibcall is a
8002                sibcall_compact and, if it is, whether it uses r0 or
8003                mach as operand 2, so let the instructions that
8004                preserve r0 be optimized away if r0 turns out to be
8005                dead.  */
8006             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8007             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8008                                                REG_NOTES (i));
8009             i = emit_move_insn (r0, tmp);
8010             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8011                                                REG_NOTES (i));
8012             break;
8013           }
8014     }
8015   DONE;
8016 }")
8017
8018 (define_insn "indirect_jump_compact"
8019   [(set (pc)
8020         (match_operand:SI 0 "arith_reg_operand" "r"))]
8021   "TARGET_SH1"
8022   "jmp  @%0%#"
8023   [(set_attr "needs_delay_slot" "yes")
8024    (set_attr "type" "jump_ind")])
8025
8026 (define_expand "indirect_jump"
8027   [(set (pc)
8028         (match_operand 0 "register_operand" ""))]
8029   ""
8030   "
8031 {
8032   if (GET_MODE (operands[0]) != Pmode)
8033     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8034 }")
8035
8036 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8037 ;; which can be present in structured code from indirect jumps which can not
8038 ;; be present in structured code.  This allows -fprofile-arcs to work.
8039
8040 ;; For SH1 processors.
8041 (define_insn "casesi_jump_1"
8042   [(set (pc)
8043         (match_operand:SI 0 "register_operand" "r"))
8044    (use (label_ref (match_operand 1 "" "")))]
8045   "TARGET_SH1"
8046   "jmp  @%0%#"
8047   [(set_attr "needs_delay_slot" "yes")
8048    (set_attr "type" "jump_ind")])
8049
8050 ;; For all later processors.
8051 (define_insn "casesi_jump_2"
8052   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8053                       (label_ref (match_operand 1 "" ""))))
8054    (use (label_ref (match_operand 2 "" "")))]
8055   "TARGET_SH2
8056    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8057   "braf %0%#"
8058   [(set_attr "needs_delay_slot" "yes")
8059    (set_attr "type" "jump_ind")])
8060
8061 (define_insn "casesi_jump_media"
8062   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8063    (use (label_ref (match_operand 1 "" "")))]
8064   "TARGET_SHMEDIA"
8065   "blink        %0, r63"
8066   [(set_attr "type" "jump_media")])
8067
8068 ;; Call subroutine returning any type.
8069 ;; ??? This probably doesn't work.
8070
8071 (define_expand "untyped_call"
8072   [(parallel [(call (match_operand 0 "" "")
8073                     (const_int 0))
8074               (match_operand 1 "" "")
8075               (match_operand 2 "" "")])]
8076   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8077   "
8078 {
8079   int i;
8080
8081   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8082
8083   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8084     {
8085       rtx set = XVECEXP (operands[2], 0, i);
8086       emit_move_insn (SET_DEST (set), SET_SRC (set));
8087     }
8088
8089   /* The optimizer does not know that the call sets the function value
8090      registers we stored in the result block.  We avoid problems by
8091      claiming that all hard registers are used and clobbered at this
8092      point.  */
8093   emit_insn (gen_blockage ());
8094
8095   DONE;
8096 }")
8097 \f
8098 ;; ------------------------------------------------------------------------
8099 ;; Misc insns
8100 ;; ------------------------------------------------------------------------
8101
8102 (define_insn "dect"
8103   [(set (reg:SI T_REG)
8104         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8105    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8106   "TARGET_SH2"
8107   "dt   %0"
8108   [(set_attr "type" "arith")])
8109
8110 (define_insn "nop"
8111   [(const_int 0)]
8112   ""
8113   "nop")
8114
8115 ;; Load address of a label. This is only generated by the casesi expand,
8116 ;; and by machine_dependent_reorg (fixing up fp moves).
8117 ;; This must use unspec, because this only works for labels that are
8118 ;; within range,
8119
8120 (define_insn "mova"
8121   [(set (reg:SI R0_REG)
8122         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8123   "TARGET_SH1"
8124   "mova %O0,r0"
8125   [(set_attr "in_delay_slot" "no")
8126    (set_attr "type" "arith")])
8127
8128 ;; machine_dependent_reorg will make this a `mova'.
8129 (define_insn "mova_const"
8130   [(set (reg:SI R0_REG)
8131         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8132   "TARGET_SH1"
8133   "#"
8134   [(set_attr "in_delay_slot" "no")
8135    (set_attr "type" "arith")])
8136
8137 (define_expand "GOTaddr2picreg"
8138   [(set (reg:SI R0_REG)
8139         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8140                    UNSPEC_MOVA))
8141    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8142    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8143   "" "
8144 {
8145   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8146   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8147
8148   if (TARGET_SHMEDIA)
8149     {
8150       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8151       rtx pic = operands[0];
8152       rtx lab = PATTERN (gen_call_site ());
8153       rtx insn, equiv;
8154
8155       equiv = operands[1];
8156       operands[1] = gen_rtx_MINUS (Pmode,
8157                                    operands[1],
8158                                    gen_rtx_CONST
8159                                    (Pmode,
8160                                     gen_rtx_MINUS (Pmode,
8161                                                    gen_rtx_CONST (Pmode,
8162                                                                   lab),
8163                                                    pc_rtx)));
8164       operands[1] = gen_sym2PIC (operands[1]);
8165       PUT_MODE (operands[1], Pmode);
8166
8167       if (Pmode == SImode)
8168         {
8169           emit_insn (gen_movsi_const (pic, operands[1]));
8170           emit_insn (gen_ptrel_si (tr, pic, lab));
8171         }
8172       else
8173         {
8174           emit_insn (gen_movdi_const (pic, operands[1]));
8175           emit_insn (gen_ptrel_di (tr, pic, lab));
8176         }
8177
8178       insn = emit_move_insn (operands[0], tr);
8179
8180       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8181                                             REG_NOTES (insn));
8182
8183       DONE;
8184     }
8185 }
8186 ")
8187
8188 (define_insn "*ptb"
8189   [(set (match_operand 0 "target_reg_operand" "=b")
8190         (const (unspec [(match_operand 1 "" "Csy")]
8191                              UNSPEC_DATALABEL)))]
8192   "TARGET_SHMEDIA && flag_pic
8193    && EXTRA_CONSTRAINT_Csy (operands[1])"
8194   "ptb/u        datalabel %1, %0"
8195   [(set_attr "type" "ptabs_media")
8196    (set_attr "length" "*")])
8197
8198 (define_insn "ptrel_si"
8199   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8200         (plus:SI (match_operand:SI 1 "register_operand" "r")
8201               (pc)))
8202    (match_operand:SI 2 "" "")]
8203   "TARGET_SHMEDIA"
8204   "%O2: ptrel/u %1, %0"
8205   [(set_attr "type" "ptabs_media")])
8206
8207 (define_insn "ptrel_di"
8208   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8209         (plus:DI (match_operand:DI 1 "register_operand" "r")
8210               (pc)))
8211    (match_operand:DI 2 "" "")]
8212   "TARGET_SHMEDIA"
8213   "%O2: ptrel/u %1, %0"
8214   [(set_attr "type" "ptabs_media")])
8215
8216 (define_expand "builtin_setjmp_receiver"
8217   [(match_operand 0 "" "")]
8218   "flag_pic"
8219   "
8220 {
8221   emit_insn (gen_GOTaddr2picreg ());
8222   DONE;
8223 }")
8224
8225 (define_expand "call_site"
8226   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8227   "TARGET_SH1"
8228   "
8229 {
8230   static HOST_WIDE_INT i = 0;
8231   operands[0] = GEN_INT (i);
8232   i++;
8233 }")
8234
8235 (define_expand "sym_label2reg"
8236   [(set (match_operand:SI 0 "" "")
8237         (const:SI (minus:SI
8238                    (const:SI
8239                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8240                    (const:SI
8241                     (plus:SI
8242                      (match_operand:SI 2 "" "")
8243                      (const_int 2))))))]
8244   "TARGET_SH1" "")
8245
8246 (define_expand "symGOT_load"
8247   [(set (match_dup 2) (match_operand 1 "" ""))
8248    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8249    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8250   ""
8251   "
8252 {
8253   rtx insn, mem;
8254
8255   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8256   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8257
8258   if (TARGET_SHMEDIA)
8259     {
8260       rtx reg = operands[2];
8261
8262       if (Pmode == DImode)
8263         {      
8264           if (flag_pic > 1)
8265             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8266           else
8267             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8268         }
8269       else
8270         {
8271           if (flag_pic > 1)
8272             emit_insn (gen_movsi_const (reg, operands[1]));
8273           else
8274             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8275         }
8276     }
8277   else
8278     emit_move_insn (operands[2], operands[1]);
8279
8280   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8281                                              operands[2],
8282                                              gen_rtx_REG (Pmode, PIC_REG)));
8283
8284   /* N.B. This is not constant for a GOTPLT relocation.  */
8285   mem = gen_rtx_MEM (Pmode, operands[3]);
8286   MEM_NOTRAP_P (mem) = 1;
8287   /* ??? Should we have a special alias set for the GOT?  */
8288   insn = emit_move_insn (operands[0], mem);
8289
8290   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8291                                                                   0), 0, 0),
8292                                         REG_NOTES (insn));
8293
8294   DONE;
8295 }")
8296
8297 (define_expand "sym2GOT"
8298   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8299   ""
8300   "")
8301
8302 (define_expand "symGOT2reg"
8303   [(match_operand 0 "" "") (match_operand 1 "" "")]
8304   ""
8305   "
8306 {
8307   rtx gotsym, insn;
8308
8309   gotsym = gen_sym2GOT (operands[1]);
8310   PUT_MODE (gotsym, Pmode);
8311   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8312
8313   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8314
8315   DONE;
8316 }")
8317
8318 (define_expand "sym2GOTPLT"
8319   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
8320   ""
8321   "")
8322
8323 (define_expand "symGOTPLT2reg"
8324   [(match_operand 0 "" "") (match_operand 1 "" "")]
8325   ""
8326   "
8327 {
8328   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
8329   DONE;
8330 }")
8331
8332 (define_expand "sym2GOTOFF"
8333   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8334   ""
8335   "")
8336
8337 (define_expand "symGOTOFF2reg"
8338   [(match_operand 0 "" "") (match_operand 1 "" "")]
8339   ""
8340   "
8341 {
8342   rtx gotoffsym, insn;
8343   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8344
8345   gotoffsym = gen_sym2GOTOFF (operands[1]);
8346   PUT_MODE (gotoffsym, Pmode);
8347   emit_move_insn (t, gotoffsym);
8348   insn = emit_move_insn (operands[0],
8349                          gen_rtx_PLUS (Pmode, t,
8350                                        gen_rtx_REG (Pmode, PIC_REG)));
8351
8352   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8353                                         REG_NOTES (insn));
8354
8355   DONE;
8356 }")
8357
8358 (define_expand "symPLT_label2reg"
8359   [(set (match_operand:SI 0 "" "")
8360         (const:SI (minus:SI
8361                    (const:SI
8362                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8363                    (const:SI
8364                     (minus:SI
8365                      (const:SI (plus:SI
8366                                 (match_operand:SI 2 "" "")
8367                                 (const_int 2)))
8368                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8369    ;; Even though the PIC register is not really used by the call
8370    ;; sequence in which this is expanded, the PLT code assumes the PIC
8371    ;; register is set, so we must not skip its initialization.  Since
8372    ;; we only use this expand as part of calling sequences, and never
8373    ;; to take the address of a function, this is the best point to
8374    ;; insert the (use).  Using the PLT to take the address of a
8375    ;; function would be wrong, not only because the PLT entry could
8376    ;; then be called from a function that doesn't initialize the PIC
8377    ;; register to the proper GOT, but also because pointers to the
8378    ;; same function might not compare equal, should they be set by
8379    ;; different shared libraries.
8380    (use (reg:SI PIC_REG))]
8381   "TARGET_SH1"
8382   "")
8383
8384 (define_expand "sym2PIC"
8385   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8386   ""
8387   "")
8388
8389 ;; TLS code generation.
8390 ;; ??? this should be a define_insn_and_split
8391 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8392 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8393 ;; for details.
8394
8395 (define_insn "tls_global_dynamic"
8396   [(set (match_operand:SI 0 "register_operand" "=&z")
8397         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8398                                   UNSPEC_TLSGD))
8399               (const_int 0)))
8400    (use (reg:PSI FPSCR_REG))
8401    (use (reg:SI PIC_REG))
8402    (clobber (reg:SI PR_REG))
8403    (clobber (scratch:SI))]
8404   "TARGET_SH1"
8405   "*
8406 {
8407   return \"\\
8408 mov.l\\t1f,r4\\n\\
8409 \\tmova\\t2f,r0\\n\\
8410 \\tmov.l\\t2f,r1\\n\\
8411 \\tadd\\tr0,r1\\n\\
8412 \\tjsr\\t@r1\\n\\
8413 \\tadd\\tr12,r4\\n\\
8414 \\tbra\\t3f\\n\\
8415 \\tnop\\n\\
8416 \\t.align\\t2\\n\\
8417 1:\\t.long\\t%a1@TLSGD\\n\\
8418 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8419 3:\";
8420 }"
8421   [(set_attr "type" "tls_load")
8422    (set_attr "length" "26")])
8423
8424 (define_insn "tls_local_dynamic"
8425   [(set (match_operand:SI 0 "register_operand" "=&z")
8426         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8427                                   UNSPEC_TLSLDM))
8428               (const_int 0)))
8429    (use (reg:PSI FPSCR_REG))
8430    (use (reg:SI PIC_REG))
8431    (clobber (reg:SI PR_REG))
8432    (clobber (scratch:SI))]
8433   "TARGET_SH1"
8434   "*
8435 {
8436   return \"\\
8437 mov.l\\t1f,r4\\n\\
8438 \\tmova\\t2f,r0\\n\\
8439 \\tmov.l\\t2f,r1\\n\\
8440 \\tadd\\tr0,r1\\n\\
8441 \\tjsr\\t@r1\\n\\
8442 \\tadd\\tr12,r4\\n\\
8443 \\tbra\\t3f\\n\\
8444 \\tnop\\n\\
8445 \\t.align\\t2\\n\\
8446 1:\\t.long\\t%a1@TLSLDM\\n\\
8447 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8448 3:\";
8449 }"
8450   [(set_attr "type" "tls_load")
8451    (set_attr "length" "26")])
8452
8453 (define_expand "sym2DTPOFF"
8454   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8455   ""
8456   "")
8457
8458 (define_expand "symDTPOFF2reg"
8459   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8460   ""
8461   "
8462 {
8463   rtx dtpoffsym, insn;
8464   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8465
8466   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8467   PUT_MODE (dtpoffsym, Pmode);
8468   emit_move_insn (t, dtpoffsym);
8469   insn = emit_move_insn (operands[0],
8470                          gen_rtx_PLUS (Pmode, t, operands[2]));
8471   DONE;
8472 }")
8473
8474 (define_expand "sym2GOTTPOFF"
8475   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8476   ""
8477   "")
8478
8479 (define_insn "tls_initial_exec"
8480   [(set (match_operand:SI 0 "register_operand" "=&r")
8481         (unspec:SI [(match_operand:SI 1 "" "")]
8482                     UNSPEC_TLSIE))
8483    (use (reg:SI GBR_REG))
8484    (use (reg:SI PIC_REG))
8485    (clobber (reg:SI R0_REG))]
8486   ""
8487   "*
8488 {
8489   return \"\\
8490 mov.l\\t1f,r0\\n\\
8491 \\tstc\\tgbr,%0\\n\\
8492 \\tmov.l\\t@(r0,r12),r0\\n\\
8493 \\tbra\\t2f\\n\\
8494 \\tadd\\tr0,%0\\n\\
8495 \\t.align\\t2\\n\\
8496 1:\\t.long\\t%a1\\n\\
8497 2:\";
8498 }"
8499   [(set_attr "type" "tls_load")
8500    (set_attr "length" "16")])
8501
8502 (define_expand "sym2TPOFF"
8503   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8504   ""
8505   "")
8506
8507 (define_expand "symTPOFF2reg"
8508   [(match_operand 0 "" "") (match_operand 1 "" "")]
8509   ""
8510   "
8511 {
8512   rtx tpoffsym, insn;
8513
8514   tpoffsym = gen_sym2TPOFF (operands[1]);
8515   PUT_MODE (tpoffsym, Pmode);
8516   insn = emit_move_insn (operands[0], tpoffsym);
8517   DONE;
8518 }")
8519
8520 (define_insn "load_gbr"
8521   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8522    (use (reg:SI GBR_REG))]
8523   ""
8524   "stc  gbr,%0"
8525   [(set_attr "type" "tls_load")])
8526
8527 ;; case instruction for switch statements.
8528
8529 ;; Operand 0 is index
8530 ;; operand 1 is the minimum bound
8531 ;; operand 2 is the maximum bound - minimum bound + 1
8532 ;; operand 3 is CODE_LABEL for the table;
8533 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8534
8535 (define_expand "casesi"
8536   [(match_operand:SI 0 "arith_reg_operand" "")
8537    (match_operand:SI 1 "arith_reg_operand" "")
8538    (match_operand:SI 2 "arith_reg_operand" "")
8539    (match_operand 3 "" "") (match_operand 4 "" "")]
8540   ""
8541   "
8542 {
8543   rtx reg = gen_reg_rtx (SImode);
8544   rtx reg2 = gen_reg_rtx (SImode);
8545   if (TARGET_SHMEDIA)
8546     {
8547       rtx reg = gen_reg_rtx (DImode);
8548       rtx reg2 = gen_reg_rtx (DImode);
8549       rtx reg3 = gen_reg_rtx (Pmode);
8550       rtx reg4 = gen_reg_rtx (Pmode);
8551       rtx reg5 = gen_reg_rtx (Pmode);
8552       rtx load;
8553
8554       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8555       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8556       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8557
8558       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8559       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8560       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8561       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8562       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8563                                                (Pmode, operands[3])));
8564       /* Messy: can we subreg to clean this up? */
8565       if (Pmode == DImode)
8566         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8567       else
8568         load = gen_casesi_load_media (reg4,
8569                                       gen_rtx_SUBREG (DImode, reg3, 0),
8570                                       reg2, operands[3]);
8571       PUT_MODE (SET_SRC (load), Pmode);
8572       emit_insn (load);
8573       /* ??? The following add could be eliminated if we used ptrel.  */
8574       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8575       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8576       emit_barrier ();
8577       DONE;
8578     }
8579   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8580   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8581   /* If optimizing, casesi_worker depends on the mode of the instruction
8582      before label it 'uses' - operands[3].  */
8583   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8584                            reg));
8585   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8586   if (TARGET_SH2)
8587     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8588   else
8589     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8590   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8591      operands[3], but to lab.  We will fix this up in
8592      machine_dependent_reorg.  */
8593   emit_barrier ();
8594   DONE;
8595 }")
8596
8597 (define_expand "casesi_0"
8598   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8599    (set (match_dup 4) (minus:SI (match_dup 4)
8600                                 (match_operand:SI 1 "arith_operand" "")))
8601    (set (reg:SI T_REG)
8602         (gtu:SI (match_dup 4)
8603                 (match_operand:SI 2 "arith_reg_operand" "")))
8604    (set (pc)
8605         (if_then_else (ne (reg:SI T_REG)
8606                           (const_int 0))
8607                       (label_ref (match_operand 3 "" ""))
8608                       (pc)))]
8609   "TARGET_SH1"
8610   "")
8611
8612 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8613 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8614 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8615
8616 (define_insn "casesi_worker_0"
8617   [(set (match_operand:SI 0 "register_operand" "=r,r")
8618         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8619                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8620    (clobber (match_scratch:SI 3 "=X,1"))
8621    (clobber (match_scratch:SI 4 "=&z,z"))]
8622   "TARGET_SH1"
8623   "#")
8624
8625 (define_split
8626   [(set (match_operand:SI 0 "register_operand" "")
8627         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8628                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8629    (clobber (match_scratch:SI 3 ""))
8630    (clobber (match_scratch:SI 4 ""))]
8631   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8632   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8633    (parallel [(set (match_dup 0)
8634               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8635                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8636               (clobber (match_dup 3))])
8637    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8638   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8639
8640 (define_split
8641   [(set (match_operand:SI 0 "register_operand" "")
8642         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8643                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8644    (clobber (match_scratch:SI 3 ""))
8645    (clobber (match_scratch:SI 4 ""))]
8646   "TARGET_SH2 && reload_completed"
8647   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8648    (parallel [(set (match_dup 0)
8649               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8650                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8651               (clobber (match_dup 3))])]
8652   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8653
8654 (define_insn "casesi_worker_1"
8655   [(set (match_operand:SI 0 "register_operand" "=r,r")
8656         (unspec:SI [(reg:SI R0_REG)
8657                     (match_operand:SI 1 "register_operand" "0,r")
8658                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8659    (clobber (match_scratch:SI 3 "=X,1"))]
8660   "TARGET_SH1"
8661   "*
8662 {
8663   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8664
8665   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8666
8667   switch (GET_MODE (diff_vec))
8668     {
8669     case SImode:
8670       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8671     case HImode:
8672       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8673     case QImode:
8674       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8675         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8676       return \"mov.b    @(r0,%1),%0\";
8677     default:
8678       gcc_unreachable ();
8679     }
8680 }"
8681   [(set_attr "length" "4")])
8682
8683 (define_insn "casesi_worker_2"
8684   [(set (match_operand:SI 0 "register_operand" "=r,r")
8685         (unspec:SI [(reg:SI R0_REG)
8686                     (match_operand:SI 1 "register_operand" "0,r")
8687                     (label_ref (match_operand 2 "" ""))
8688                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8689    (clobber (match_operand:SI 4 "" "=X,1"))]
8690   "TARGET_SH2 && reload_completed && flag_pic"
8691   "*
8692 {
8693   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8694   const char *load;
8695
8696   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8697
8698   switch (GET_MODE (diff_vec))
8699     {
8700     case SImode:
8701       output_asm_insn (\"shll2    %1\", operands);
8702       load = \"mov.l    @(r0,%1),%0\"; break;
8703     case HImode:
8704       output_asm_insn (\"add    %1,%1\", operands);
8705       load = \"mov.w    @(r0,%1),%0\"; break;
8706     case QImode:
8707       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8708         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8709       else
8710         load = \"mov.b  @(r0,%1),%0\";
8711       break;
8712     default:
8713       gcc_unreachable ();
8714     }
8715   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8716   return load;
8717 }"
8718   [(set_attr "length" "8")])
8719
8720 (define_insn "casesi_shift_media"
8721   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8722         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8723                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8724                     UNSPEC_CASESI)))]
8725   "TARGET_SHMEDIA"
8726   "*
8727 {
8728   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8729
8730   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8731
8732   switch (GET_MODE (diff_vec))
8733     {
8734     case SImode:
8735       return \"shlli    %1, 2, %0\";
8736     case HImode:
8737       return \"shlli    %1, 1, %0\";
8738     case QImode:
8739       if (rtx_equal_p (operands[0], operands[1]))
8740         return \"\";
8741       return \"add      %1, r63, %0\";
8742     default:
8743       gcc_unreachable ();
8744     }
8745 }"
8746   [(set_attr "type" "arith_media")])
8747
8748 (define_insn "casesi_load_media"
8749   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8750         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8751                          (match_operand:DI 2 "arith_reg_operand" "r")
8752                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8753   "TARGET_SHMEDIA"
8754   "*
8755 {
8756   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8757
8758   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8759
8760   switch (GET_MODE (diff_vec))
8761     {
8762     case SImode:
8763       return \"ldx.l    %1, %2, %0\";
8764     case HImode:
8765 #if 0
8766       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8767         return \"ldx.uw %1, %2, %0\";
8768 #endif
8769       return \"ldx.w    %1, %2, %0\";
8770     case QImode:
8771       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8772         return \"ldx.ub %1, %2, %0\";
8773       return \"ldx.b    %1, %2, %0\";
8774     default:
8775       gcc_unreachable ();
8776     }
8777 }"
8778   [(set_attr "type" "load_media")])
8779
8780 (define_expand "return"
8781   [(return)]
8782   "reload_completed && ! sh_need_epilogue ()"
8783   "
8784 {
8785   if (TARGET_SHMEDIA)
8786     {
8787       emit_jump_insn (gen_return_media ());
8788       DONE;
8789     }
8790
8791   if (TARGET_SHCOMPACT
8792       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8793     {
8794       emit_jump_insn (gen_shcompact_return_tramp ());
8795       DONE;
8796     }
8797 }")
8798
8799 (define_insn "*return_i"
8800   [(return)]
8801   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8802                     && (current_function_args_info.call_cookie
8803                         & CALL_COOKIE_RET_TRAMP (1)))
8804    && reload_completed"
8805   "%@   %#"
8806   [(set_attr "type" "return")
8807    (set_attr "needs_delay_slot" "yes")])
8808
8809 (define_expand "shcompact_return_tramp"
8810   [(return)]
8811   "TARGET_SHCOMPACT
8812    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8813   "
8814 {
8815   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8816
8817   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8818   emit_jump_insn (gen_shcompact_return_tramp_i ());
8819   DONE;
8820 }")
8821
8822 (define_insn "shcompact_return_tramp_i"
8823   [(parallel [(return) (use (reg:SI R0_REG))])]
8824   "TARGET_SHCOMPACT
8825    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8826   "jmp  @r0%#"
8827   [(set_attr "type" "jump_ind")
8828    (set_attr "needs_delay_slot" "yes")])
8829
8830 (define_insn "return_media_i"
8831   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8832   "TARGET_SHMEDIA && reload_completed"
8833   "blink        %0, r63"
8834   [(set_attr "type" "jump_media")])
8835
8836 (define_insn "return_media_rte"
8837   [(return)]
8838   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8839   "rte"
8840   [(set_attr "type" "jump_media")])
8841
8842 (define_expand "return_media"
8843   [(return)]
8844   "TARGET_SHMEDIA && reload_completed"
8845   "
8846 {
8847   int tr_regno = sh_media_register_for_return ();
8848   rtx tr;
8849
8850   if (current_function_interrupt)
8851     {
8852       emit_jump_insn (gen_return_media_rte ());
8853       DONE;
8854     }
8855   if (tr_regno < 0)
8856     {
8857       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8858
8859       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8860       tr_regno = TR0_REG;
8861       tr = gen_rtx_REG (Pmode, tr_regno);
8862       emit_move_insn (tr, r18);
8863     }
8864   else
8865     tr = gen_rtx_REG (Pmode, tr_regno);
8866
8867   emit_jump_insn (gen_return_media_i (tr));
8868   DONE;
8869 }")
8870
8871 (define_insn "shcompact_preserve_incoming_args"
8872   [(set (match_operand:SI 0 "register_operand" "+r")
8873         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8874   "TARGET_SHCOMPACT"
8875   ""
8876   [(set_attr "length" "0")])
8877
8878 (define_insn "shcompact_incoming_args"
8879   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8880    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8881    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8882    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8883    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8884    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8885    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8886    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8887    (set (mem:BLK (reg:SI MACL_REG))
8888         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8889    (use (reg:SI R0_REG))
8890    (clobber (reg:SI R0_REG))
8891    (clobber (reg:SI MACL_REG))
8892    (clobber (reg:SI MACH_REG))
8893    (clobber (reg:SI PR_REG))]
8894   "TARGET_SHCOMPACT"
8895   "jsr  @r0%#"
8896   [(set_attr "needs_delay_slot" "yes")])
8897
8898 (define_insn "shmedia_save_restore_regs_compact"
8899   [(set (reg:SI SP_REG)
8900         (plus:SI (reg:SI SP_REG)
8901                  (match_operand:SI 0 "immediate_operand" "i")))
8902    (use (reg:SI R0_REG))
8903    (clobber (reg:SI PR_REG))]
8904   "TARGET_SHCOMPACT
8905    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8906        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8907   "jsr @r0%#"
8908   [(set_attr "needs_delay_slot" "yes")])
8909
8910 (define_expand "prologue"
8911   [(const_int 0)]
8912   ""
8913   "sh_expand_prologue (); DONE;")
8914
8915 (define_expand "epilogue"
8916   [(return)]
8917   ""
8918   "
8919 {
8920   sh_expand_epilogue (0);
8921   emit_jump_insn (gen_return ());
8922   DONE;
8923 }")
8924
8925 (define_expand "eh_return"
8926   [(use (match_operand 0 "register_operand" ""))]
8927   ""
8928 {
8929   rtx ra = operands[0];
8930
8931   if (TARGET_SHMEDIA64)
8932     emit_insn (gen_eh_set_ra_di (ra));
8933   else
8934     emit_insn (gen_eh_set_ra_si (ra));
8935
8936   DONE;
8937 })
8938
8939 ;; Clobber the return address on the stack.  We can't expand this
8940 ;; until we know where it will be put in the stack frame.
8941
8942 (define_insn "eh_set_ra_si"
8943   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8944    (clobber (match_scratch:SI 1 "=&r"))]
8945   "! TARGET_SHMEDIA64"
8946   "#")
8947
8948 (define_insn "eh_set_ra_di"
8949   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8950    (clobber (match_scratch:DI 1 "=&r"))]
8951   "TARGET_SHMEDIA64"
8952   "#")
8953
8954 (define_split
8955   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8956    (clobber (match_scratch 1 ""))]
8957   "reload_completed"
8958   [(const_int 0)]
8959   "
8960 {
8961   sh_set_return_address (operands[0], operands[1]);
8962   DONE;
8963 }")
8964
8965 (define_insn "blockage"
8966   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8967   ""
8968   ""
8969   [(set_attr "length" "0")])
8970 \f
8971 ;; ------------------------------------------------------------------------
8972 ;; Scc instructions
8973 ;; ------------------------------------------------------------------------
8974
8975 (define_insn "movt"
8976   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
8977         (eq:SI (reg:SI T_REG) (const_int 1)))]
8978   "TARGET_SH1"
8979   "movt %0"
8980   [(set_attr "type" "arith")])
8981
8982 (define_expand "seq"
8983   [(set (match_operand:SI 0 "arith_reg_dest" "")
8984         (match_dup 1))]
8985   ""
8986   "
8987 {
8988   if (TARGET_SHMEDIA)
8989     {
8990       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
8991       if (sh_compare_op1 != const0_rtx)
8992         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
8993                                     ? GET_MODE (sh_compare_op0)
8994                                     : GET_MODE (sh_compare_op1),
8995                                     sh_compare_op1);
8996       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
8997         {
8998           if (GET_MODE (operands[0]) != SImode)
8999             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9000
9001           switch (GET_MODE (sh_compare_op0))
9002             {
9003             case SImode:
9004               emit_insn (gen_cmpsieqsi_media (operands[0],
9005                                               sh_compare_op0, sh_compare_op1));
9006               break;
9007
9008             case DImode:
9009               emit_insn (gen_cmpsieqdi_media (operands[0],
9010                                               sh_compare_op0, sh_compare_op1));
9011               break;
9012
9013             case SFmode:
9014               if (! TARGET_SHMEDIA_FPU)
9015                 FAIL;
9016               emit_insn (gen_cmpsieqsf_media (operands[0],
9017                                               sh_compare_op0, sh_compare_op1));
9018               break;
9019
9020             case DFmode:
9021               if (! TARGET_SHMEDIA_FPU)
9022                 FAIL;
9023               emit_insn (gen_cmpsieqdf_media (operands[0],
9024                                               sh_compare_op0, sh_compare_op1));
9025               break;
9026
9027             default:
9028               FAIL;
9029             }
9030           DONE;
9031         }
9032
9033       if (GET_MODE (operands[0]) != DImode)
9034         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9035
9036       switch (GET_MODE (sh_compare_op0))
9037         {
9038         case SImode:
9039           emit_insn (gen_cmpeqsi_media (operands[0],
9040                                         sh_compare_op0, sh_compare_op1));
9041           break;
9042
9043         case DImode:
9044           emit_insn (gen_cmpeqdi_media (operands[0],
9045                                         sh_compare_op0, sh_compare_op1));
9046           break;
9047
9048         case SFmode:
9049           if (! TARGET_SHMEDIA_FPU)
9050             FAIL;
9051           emit_insn (gen_cmpeqsf_media (operands[0],
9052                                         sh_compare_op0, sh_compare_op1));
9053           break;
9054
9055         case DFmode:
9056           if (! TARGET_SHMEDIA_FPU)
9057             FAIL;
9058           emit_insn (gen_cmpeqdf_media (operands[0],
9059                                         sh_compare_op0, sh_compare_op1));
9060           break;
9061
9062         default:
9063           FAIL;
9064         }
9065       DONE;
9066     }
9067   if (sh_expand_t_scc (EQ, operands[0]))
9068     DONE;
9069   if (! currently_expanding_to_rtl)
9070     FAIL;
9071   operands[1] = prepare_scc_operands (EQ);
9072 }")
9073
9074 (define_expand "slt"
9075   [(set (match_operand:SI 0 "arith_reg_operand" "")
9076         (match_dup 1))]
9077   ""
9078   "
9079 {
9080   if (TARGET_SHMEDIA)
9081     {
9082       if (GET_MODE (operands[0]) != DImode)
9083         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9084       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9085       if (sh_compare_op1 != const0_rtx)
9086         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9087                                     ? GET_MODE (sh_compare_op0)
9088                                     : GET_MODE (sh_compare_op1),
9089                                     sh_compare_op1);
9090
9091       switch (GET_MODE (sh_compare_op0))
9092         {
9093         case SImode:
9094           emit_insn (gen_cmpgtsi_media (operands[0],
9095                                         sh_compare_op1, sh_compare_op0));
9096           break;
9097
9098         case DImode:
9099           emit_insn (gen_cmpgtdi_media (operands[0],
9100                                         sh_compare_op1, sh_compare_op0));
9101           break;
9102
9103         case SFmode:
9104           if (! TARGET_SHMEDIA_FPU)
9105             FAIL;
9106           emit_insn (gen_cmpgtsf_media (operands[0],
9107                                         sh_compare_op1, sh_compare_op0));
9108           break;
9109
9110         case DFmode:
9111           if (! TARGET_SHMEDIA_FPU)
9112             FAIL;
9113           emit_insn (gen_cmpgtdf_media (operands[0],
9114                                         sh_compare_op1, sh_compare_op0));
9115           break;
9116
9117         default:
9118           FAIL;
9119         }
9120       DONE;
9121     }
9122   if (! currently_expanding_to_rtl)
9123     FAIL;
9124   operands[1] = prepare_scc_operands (LT);
9125 }")
9126
9127 (define_expand "sle"
9128   [(match_operand:SI 0 "arith_reg_operand" "")]
9129   ""
9130   "
9131 {
9132   rtx tmp = sh_compare_op0;
9133
9134   if (TARGET_SHMEDIA)
9135     {
9136       if (GET_MODE (operands[0]) != DImode)
9137         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9138       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9139       if (sh_compare_op1 != const0_rtx)
9140         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9141                                     ? GET_MODE (sh_compare_op0)
9142                                     : GET_MODE (sh_compare_op1),
9143                                     sh_compare_op1);
9144
9145       switch (GET_MODE (sh_compare_op0))
9146         {
9147         case SImode:
9148           {
9149             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9150
9151             emit_insn (gen_cmpgtsi_media (tmp,
9152                                           sh_compare_op0, sh_compare_op1));
9153             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9154             break;
9155           }
9156
9157         case DImode:
9158           {
9159             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9160
9161             emit_insn (gen_cmpgtdi_media (tmp,
9162                                           sh_compare_op0, sh_compare_op1));
9163             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9164             break;
9165           }
9166
9167         case SFmode:
9168           if (! TARGET_SHMEDIA_FPU)
9169             FAIL;
9170           emit_insn (gen_cmpgesf_media (operands[0],
9171                                         sh_compare_op1, sh_compare_op0));
9172           break;
9173
9174         case DFmode:
9175           if (! TARGET_SHMEDIA_FPU)
9176             FAIL;
9177           emit_insn (gen_cmpgedf_media (operands[0],
9178                                         sh_compare_op1, sh_compare_op0));
9179           break;
9180
9181         default:
9182           FAIL;
9183         }
9184       DONE;
9185     }
9186
9187   sh_compare_op0 = sh_compare_op1;
9188   sh_compare_op1 = tmp;
9189   emit_insn (gen_sge (operands[0]));
9190   DONE;
9191 }")
9192
9193 (define_expand "sgt"
9194   [(set (match_operand:SI 0 "arith_reg_operand" "")
9195         (match_dup 1))]
9196   ""
9197   "
9198 {
9199   if (TARGET_SHMEDIA)
9200     {
9201       if (GET_MODE (operands[0]) != DImode)
9202         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9203       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9204       if (sh_compare_op1 != const0_rtx)
9205         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9206                                     ? GET_MODE (sh_compare_op0)
9207                                     : GET_MODE (sh_compare_op1),
9208                                     sh_compare_op1);
9209
9210       switch (GET_MODE (sh_compare_op0))
9211         {
9212         case SImode:
9213           emit_insn (gen_cmpgtsi_media (operands[0],
9214                                         sh_compare_op0, sh_compare_op1));
9215           break;
9216
9217         case DImode:
9218           emit_insn (gen_cmpgtdi_media (operands[0],
9219                                         sh_compare_op0, sh_compare_op1));
9220           break;
9221
9222         case SFmode:
9223           if (! TARGET_SHMEDIA_FPU)
9224             FAIL;
9225           emit_insn (gen_cmpgtsf_media (operands[0],
9226                                         sh_compare_op0, sh_compare_op1));
9227           break;
9228
9229         case DFmode:
9230           if (! TARGET_SHMEDIA_FPU)
9231             FAIL;
9232           emit_insn (gen_cmpgtdf_media (operands[0],
9233                                         sh_compare_op0, sh_compare_op1));
9234           break;
9235
9236         default:
9237           FAIL;
9238         }
9239       DONE;
9240     }
9241   if (! currently_expanding_to_rtl)
9242     FAIL;
9243   operands[1] = prepare_scc_operands (GT);
9244 }")
9245
9246 (define_expand "sge"
9247   [(set (match_operand:SI 0 "arith_reg_operand" "")
9248         (match_dup 1))]
9249   ""
9250   "
9251 {
9252   if (TARGET_SHMEDIA)
9253     {
9254       enum machine_mode mode = GET_MODE (sh_compare_op0);
9255
9256       if ((mode) == VOIDmode)
9257         mode = GET_MODE (sh_compare_op1);
9258       if (GET_MODE (operands[0]) != DImode)
9259         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9260       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9261       if (sh_compare_op1 != const0_rtx)
9262         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9263
9264       switch (mode)
9265         {
9266         case SImode:
9267           {
9268             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9269
9270             emit_insn (gen_cmpgtsi_media (tmp,
9271                                           sh_compare_op1, sh_compare_op0));
9272             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9273             break;
9274           }
9275
9276         case DImode:
9277           {
9278             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9279
9280             emit_insn (gen_cmpgtdi_media (tmp,
9281                                           sh_compare_op1, sh_compare_op0));
9282             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9283             break;
9284           }
9285
9286         case SFmode:
9287           if (! TARGET_SHMEDIA_FPU)
9288             FAIL;
9289           emit_insn (gen_cmpgesf_media (operands[0],
9290                                         sh_compare_op0, sh_compare_op1));
9291           break;
9292
9293         case DFmode:
9294           if (! TARGET_SHMEDIA_FPU)
9295             FAIL;
9296           emit_insn (gen_cmpgedf_media (operands[0],
9297                                         sh_compare_op0, sh_compare_op1));
9298           break;
9299
9300         default:
9301           FAIL;
9302         }
9303       DONE;
9304     }
9305
9306   if (! currently_expanding_to_rtl)
9307     FAIL;
9308   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9309     {
9310       if (TARGET_IEEE)
9311         {
9312           rtx lab = gen_label_rtx ();
9313           prepare_scc_operands (EQ);
9314           emit_jump_insn (gen_branch_true (lab));
9315           prepare_scc_operands (GT);
9316           emit_label (lab);
9317           emit_insn (gen_movt (operands[0]));
9318         }
9319       else
9320         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9321       DONE;
9322     }
9323   operands[1] = prepare_scc_operands (GE);
9324 }")
9325
9326 (define_expand "sgtu"
9327   [(set (match_operand:SI 0 "arith_reg_operand" "")
9328         (match_dup 1))]
9329   ""
9330   "
9331 {
9332   if (TARGET_SHMEDIA)
9333     {
9334       if (GET_MODE (operands[0]) != DImode)
9335         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9336       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9337       if (sh_compare_op1 != const0_rtx)
9338         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9339                                     ? GET_MODE (sh_compare_op0)
9340                                     : GET_MODE (sh_compare_op1),
9341                                     sh_compare_op1);
9342
9343       emit_insn (gen_cmpgtudi_media (operands[0],
9344                                      sh_compare_op0, sh_compare_op1));
9345       DONE;
9346     }
9347   if (! currently_expanding_to_rtl)
9348     FAIL;
9349   operands[1] = prepare_scc_operands (GTU);
9350 }")
9351
9352 (define_expand "sltu"
9353   [(set (match_operand:SI 0 "arith_reg_operand" "")
9354         (match_dup 1))]
9355   ""
9356   "
9357 {
9358   if (TARGET_SHMEDIA)
9359     {
9360       if (GET_MODE (operands[0]) != DImode)
9361         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9362       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9363       if (sh_compare_op1 != const0_rtx)
9364         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9365                                     ? GET_MODE (sh_compare_op0)
9366                                     : GET_MODE (sh_compare_op1),
9367                                     sh_compare_op1);
9368
9369       emit_insn (gen_cmpgtudi_media (operands[0],
9370                                      sh_compare_op1, sh_compare_op0));
9371       DONE;
9372     }
9373   if (! currently_expanding_to_rtl)
9374     FAIL;
9375   operands[1] = prepare_scc_operands (LTU);
9376 }")
9377
9378 (define_expand "sleu"
9379   [(set (match_operand:SI 0 "arith_reg_operand" "")
9380         (match_dup 1))]
9381   ""
9382   "
9383 {
9384   if (TARGET_SHMEDIA)
9385     {
9386       rtx tmp;
9387
9388       if (GET_MODE (operands[0]) != DImode)
9389         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9390       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9391       if (sh_compare_op1 != const0_rtx)
9392         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9393                                     ? GET_MODE (sh_compare_op0)
9394                                     : GET_MODE (sh_compare_op1),
9395                                     sh_compare_op1);
9396
9397       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9398
9399       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9400       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9401
9402       DONE;
9403     }
9404   if (! currently_expanding_to_rtl)
9405     FAIL;
9406   operands[1] = prepare_scc_operands (LEU);
9407 }")
9408
9409 (define_expand "sgeu"
9410   [(set (match_operand:SI 0 "arith_reg_operand" "")
9411         (match_dup 1))]
9412   ""
9413   "
9414 {
9415   if (TARGET_SHMEDIA)
9416     {
9417       rtx tmp;
9418
9419       if (GET_MODE (operands[0]) != DImode)
9420         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9421       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9422       if (sh_compare_op1 != const0_rtx)
9423         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9424                                     ? GET_MODE (sh_compare_op0)
9425                                     : GET_MODE (sh_compare_op1),
9426                                     sh_compare_op1);
9427
9428       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9429
9430       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9431       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9432
9433       DONE;
9434     }
9435
9436   if (! currently_expanding_to_rtl)
9437     FAIL;
9438   operands[1] = prepare_scc_operands (GEU);
9439 }")
9440
9441 ;; sne moves the complement of the T reg to DEST like this:
9442 ;;      cmp/eq ...
9443 ;;      mov    #-1,temp
9444 ;;      negc   temp,dest
9445 ;;   This is better than xoring compare result with 1 because it does
9446 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9447 ;;   loop.
9448
9449 (define_expand "sne"
9450   [(set (match_dup 2) (const_int -1))
9451    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9452                    (neg:SI (plus:SI (match_dup 1)
9453                                     (match_dup 2))))
9454               (set (reg:SI T_REG)
9455                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9456                           (const_int 0)))])]
9457   ""
9458   "
9459 {
9460   if (TARGET_SHMEDIA)
9461     {
9462       rtx tmp;
9463
9464       if (GET_MODE (operands[0]) != DImode)
9465         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9466
9467       if (! TARGET_SHMEDIA_FPU
9468           && GET_MODE (sh_compare_op0) != DImode
9469           && GET_MODE (sh_compare_op0) != SImode)
9470         FAIL;
9471
9472       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9473       if (sh_compare_op1 != const0_rtx)
9474         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9475                                     ? GET_MODE (sh_compare_op0)
9476                                     : GET_MODE (sh_compare_op1),
9477                                     sh_compare_op1);
9478
9479       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9480
9481       emit_insn (gen_seq (tmp));
9482       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9483
9484       DONE;
9485     }
9486
9487   if (sh_expand_t_scc (NE, operands[0]))
9488     DONE;
9489   if (! currently_expanding_to_rtl)
9490     FAIL;
9491   operands[1] = prepare_scc_operands (EQ);
9492   operands[2] = gen_reg_rtx (SImode);
9493 }")
9494
9495 (define_expand "sunordered"
9496   [(set (match_operand:DI 0 "arith_reg_operand" "")
9497         (unordered:DI (match_dup 1) (match_dup 2)))]
9498   "TARGET_SHMEDIA_FPU"
9499   "
9500 {
9501   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9502   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9503 }")
9504
9505 ;; Use the same trick for FP sle / sge
9506
9507 ;; Apart from the constant use and the T setting, this is like movt,
9508 ;; except that it uses the logically negated value of T, i.e.
9509 ;; operand[0] := T ? 0 : 1.
9510 (define_expand "movnegt"
9511   [(set (match_dup 2) (const_int -1))
9512    (parallel [(set (match_operand 0 "" "")
9513                    (neg:SI (plus:SI (match_dup 1)
9514                                     (match_dup 2))))
9515               (set (reg:SI T_REG)
9516                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9517                           (const_int 0)))])]
9518   "TARGET_SH1"
9519   "operands[2] = gen_reg_rtx (SImode);")
9520
9521 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9522 ;; This prevents a regression that occurred when we switched from xor to
9523 ;; mov/neg for sne.
9524
9525 (define_split
9526   [(set (match_operand:SI 0 "arith_reg_dest" "")
9527         (plus:SI (reg:SI T_REG)
9528                  (const_int -1)))]
9529   "TARGET_SH1"
9530   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9531    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9532   "")
9533
9534 ;; -------------------------------------------------------------------------
9535 ;; Instructions to cope with inline literal tables
9536 ;; -------------------------------------------------------------------------
9537
9538 ; 2 byte integer in line
9539
9540 (define_insn "consttable_2"
9541  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9542                     (match_operand 1 "" "")]
9543                    UNSPECV_CONST2)]
9544  ""
9545  "*
9546 {
9547   if (operands[1] != const0_rtx)
9548     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9549   return \"\";
9550 }"
9551  [(set_attr "length" "2")
9552  (set_attr "in_delay_slot" "no")])
9553
9554 ; 4 byte integer in line
9555
9556 (define_insn "consttable_4"
9557  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9558                     (match_operand 1 "" "")]
9559                    UNSPECV_CONST4)]
9560  ""
9561  "*
9562 {
9563   if (operands[1] != const0_rtx)
9564     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9565   return \"\";
9566 }"
9567  [(set_attr "length" "4")
9568   (set_attr "in_delay_slot" "no")])
9569
9570 ; 8 byte integer in line
9571
9572 (define_insn "consttable_8"
9573  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9574                     (match_operand 1 "" "")]
9575                    UNSPECV_CONST8)]
9576  ""
9577  "*
9578 {
9579   if (operands[1] != const0_rtx)
9580     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9581   return \"\";
9582 }"
9583  [(set_attr "length" "8")
9584   (set_attr "in_delay_slot" "no")])
9585
9586 ; 4 byte floating point
9587
9588 (define_insn "consttable_sf"
9589  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9590                     (match_operand 1 "" "")]
9591                    UNSPECV_CONST4)]
9592  ""
9593  "*
9594 {
9595   if (operands[1] != const0_rtx)
9596     {
9597       REAL_VALUE_TYPE d;
9598       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9599       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9600     }
9601   return \"\";
9602 }"
9603  [(set_attr "length" "4")
9604   (set_attr "in_delay_slot" "no")])
9605
9606 ; 8 byte floating point
9607
9608 (define_insn "consttable_df"
9609  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9610                     (match_operand 1 "" "")]
9611                    UNSPECV_CONST8)]
9612  ""
9613  "*
9614 {
9615   if (operands[1] != const0_rtx)
9616     {
9617       REAL_VALUE_TYPE d;
9618       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9619       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9620     }
9621   return \"\";
9622 }"
9623  [(set_attr "length" "8")
9624   (set_attr "in_delay_slot" "no")])
9625
9626 ;; Alignment is needed for some constant tables; it may also be added for
9627 ;; Instructions at the start of loops, or after unconditional branches.
9628 ;; ??? We would get more accurate lengths if we did instruction
9629 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9630 ;; here is too conservative.
9631
9632 ; align to a two byte boundary
9633
9634 (define_expand "align_2"
9635  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9636  ""
9637  "")
9638
9639 ; align to a four byte boundary
9640 ;; align_4 and align_log are instructions for the starts of loops, or
9641 ;; after unconditional branches, which may take up extra room.
9642
9643 (define_expand "align_4"
9644  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9645  ""
9646  "")
9647
9648 ; align to a cache line boundary
9649
9650 (define_insn "align_log"
9651  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9652  ""
9653  ""
9654  [(set_attr "length" "0")
9655   (set_attr "in_delay_slot" "no")])
9656
9657 ; emitted at the end of the literal table, used to emit the
9658 ; 32bit branch labels if needed.
9659
9660 (define_insn "consttable_end"
9661   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9662   ""
9663   "* return output_jump_label_table ();"
9664   [(set_attr "in_delay_slot" "no")])
9665
9666 ; emitted at the end of the window in the literal table.
9667
9668 (define_insn "consttable_window_end"
9669   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9670   ""
9671   ""
9672   [(set_attr "length" "0")
9673    (set_attr "in_delay_slot" "no")])
9674
9675 ;; -------------------------------------------------------------------------
9676 ;; Misc
9677 ;; -------------------------------------------------------------------------
9678
9679 ;; String/block move insn.
9680
9681 (define_expand "movmemsi"
9682   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9683                    (mem:BLK (match_operand:BLK 1 "" "")))
9684               (use (match_operand:SI 2 "nonmemory_operand" ""))
9685               (use (match_operand:SI 3 "immediate_operand" ""))
9686               (clobber (reg:SI PR_REG))
9687               (clobber (reg:SI R4_REG))
9688               (clobber (reg:SI R5_REG))
9689               (clobber (reg:SI R0_REG))])]
9690   "TARGET_SH1 && ! TARGET_SH5"
9691   "
9692 {
9693   if(expand_block_move (operands))
9694      DONE;
9695   else FAIL;
9696 }")
9697
9698 (define_insn "block_move_real"
9699   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9700                    (mem:BLK (reg:SI R5_REG)))
9701               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9702               (clobber (reg:SI PR_REG))
9703               (clobber (reg:SI R0_REG))])]
9704   "TARGET_SH1 && ! TARGET_HARD_SH4"
9705   "jsr  @%0%#"
9706   [(set_attr "type" "sfunc")
9707    (set_attr "needs_delay_slot" "yes")])
9708
9709 (define_insn "block_lump_real"
9710   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9711                    (mem:BLK (reg:SI R5_REG)))
9712               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9713               (use (reg:SI R6_REG))
9714               (clobber (reg:SI PR_REG))
9715               (clobber (reg:SI T_REG))
9716               (clobber (reg:SI R4_REG))
9717               (clobber (reg:SI R5_REG))
9718               (clobber (reg:SI R6_REG))
9719               (clobber (reg:SI R0_REG))])]
9720   "TARGET_SH1 && ! TARGET_HARD_SH4"
9721   "jsr  @%0%#"
9722   [(set_attr "type" "sfunc")
9723    (set_attr "needs_delay_slot" "yes")])
9724
9725 (define_insn "block_move_real_i4"
9726   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9727                    (mem:BLK (reg:SI R5_REG)))
9728               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9729               (clobber (reg:SI PR_REG))
9730               (clobber (reg:SI R0_REG))
9731               (clobber (reg:SI R1_REG))
9732               (clobber (reg:SI R2_REG))])]
9733   "TARGET_HARD_SH4"
9734   "jsr  @%0%#"
9735   [(set_attr "type" "sfunc")
9736    (set_attr "needs_delay_slot" "yes")])
9737
9738 (define_insn "block_lump_real_i4"
9739   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9740                    (mem:BLK (reg:SI R5_REG)))
9741               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9742               (use (reg:SI R6_REG))
9743               (clobber (reg:SI PR_REG))
9744               (clobber (reg:SI T_REG))
9745               (clobber (reg:SI R4_REG))
9746               (clobber (reg:SI R5_REG))
9747               (clobber (reg:SI R6_REG))
9748               (clobber (reg:SI R0_REG))
9749               (clobber (reg:SI R1_REG))
9750               (clobber (reg:SI R2_REG))
9751               (clobber (reg:SI R3_REG))])]
9752   "TARGET_HARD_SH4"
9753   "jsr  @%0%#"
9754   [(set_attr "type" "sfunc")
9755    (set_attr "needs_delay_slot" "yes")])
9756 \f
9757 ;; -------------------------------------------------------------------------
9758 ;; Floating point instructions.
9759 ;; -------------------------------------------------------------------------
9760
9761 ;; ??? All patterns should have a type attribute.
9762
9763 (define_expand "fpu_switch0"
9764   [(set (match_operand:SI 0 "" "") (match_dup 2))
9765    (set (match_dup 1) (mem:PSI (match_dup 0)))]
9766   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9767   "
9768 {
9769   operands[1] = get_fpscr_rtx ();
9770   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9771   if (flag_pic)
9772     operands[2] = legitimize_pic_address (operands[2], SImode,
9773                                           no_new_pseudos ? operands[0] : 0);
9774 }")
9775
9776 (define_expand "fpu_switch1"
9777   [(set (match_operand:SI 0 "" "") (match_dup 2))
9778    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
9779    (set (match_dup 1) (mem:PSI (match_dup 3)))]
9780   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9781   "
9782 {
9783   operands[1] = get_fpscr_rtx ();
9784   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9785   if (flag_pic)
9786     operands[2] = legitimize_pic_address (operands[2], SImode,
9787                                           no_new_pseudos ? operands[0] : 0);
9788   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9789 }")
9790
9791 (define_expand "movpsi"
9792   [(set (match_operand:PSI 0 "register_operand" "")
9793         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9794   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9795   "")
9796
9797 ;; The c / m alternative is a fake to guide reload to load directly into
9798 ;; fpscr, since reload doesn't know how to use post-increment.
9799 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9800 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9801 ;; predicate after reload.
9802 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9803 ;; like a mac -> gpr move.
9804 (define_insn "fpu_switch"
9805   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9806         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9807   "TARGET_SH2E
9808    && (! reload_completed
9809        || true_regnum (operands[0]) != FPSCR_REG
9810        || GET_CODE (operands[1]) != MEM
9811        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9812   "@
9813         ! precision stays the same
9814         lds.l   %1,fpscr
9815         mov.l   %1,%0
9816         #
9817         lds     %1,fpscr
9818         mov     %1,%0
9819         mov.l   %1,%0
9820         sts     fpscr,%0
9821         sts.l   fpscr,%0"
9822   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9823    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9824
9825 (define_split
9826   [(set (reg:PSI FPSCR_REG)
9827         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9828   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9829   [(set (match_dup 0) (match_dup 0))]
9830   "
9831 {
9832   rtx mem, insn;
9833
9834   mem = SET_SRC (PATTERN (curr_insn));
9835   mem = change_address (mem, PSImode, gen_rtx_POST_INC (Pmode, operands[0]));
9836   insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem));
9837   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9838 }")
9839
9840 (define_split
9841   [(set (reg:PSI FPSCR_REG)
9842         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9843   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9844   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
9845   "
9846 {
9847   rtx mem, insn;
9848
9849   mem = SET_SRC (PATTERN (curr_insn));
9850   mem = change_address (mem, PSImode, gen_rtx_POST_INC (Pmode, operands[0]));
9851   insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem));
9852   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9853 }")
9854
9855 ;; ??? This uses the fp unit, but has no type indicating that.
9856 ;; If we did that, this would either give a bogus latency or introduce
9857 ;; a bogus FIFO constraint.
9858 ;; Since this insn is currently only used for prologues/epilogues,
9859 ;; it is probably best to claim no function unit, which matches the
9860 ;; current setting.
9861 (define_insn "toggle_sz"
9862   [(set (reg:PSI FPSCR_REG)
9863         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9864   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9865   "fschg"
9866   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9867
9868 ;; There's no way we can use it today, since optimize mode switching
9869 ;; doesn't enable us to know from which mode we're switching to the
9870 ;; mode it requests, to tell whether we can use a relative mode switch
9871 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9872 ;; memory).
9873 (define_insn "toggle_pr"
9874   [(set (reg:PSI FPSCR_REG)
9875         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9876   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9877   "fpchg"
9878   [(set_attr "type" "fp")])
9879
9880 (define_expand "addsf3"
9881   [(set (match_operand:SF 0 "arith_reg_operand" "")
9882         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9883                  (match_operand:SF 2 "arith_reg_operand" "")))]
9884   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9885   "
9886 {
9887   if (TARGET_SH2E)
9888     {
9889       expand_sf_binop (&gen_addsf3_i, operands);
9890       DONE;
9891     }
9892 }")
9893
9894 (define_insn "*addsf3_media"
9895   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9896         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9897                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9898   "TARGET_SHMEDIA_FPU"
9899   "fadd.s       %1, %2, %0"
9900   [(set_attr "type" "fparith_media")])
9901
9902 (define_insn_and_split "unary_sf_op"
9903   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9904         (vec_select:V2SF
9905          (vec_concat:V2SF
9906           (vec_select:SF
9907            (match_dup 0)
9908            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9909           (match_operator:SF 2 "unary_float_operator"
9910             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9911                             (parallel [(match_operand 4
9912                                         "const_int_operand" "n")]))]))
9913          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9914   "TARGET_SHMEDIA_FPU"
9915   "#"
9916   "TARGET_SHMEDIA_FPU && reload_completed"
9917   [(set (match_dup 5) (match_dup 6))]
9918   "
9919 {
9920   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9921   rtx op1 = gen_rtx_REG (SFmode,
9922                          (true_regnum (operands[1])
9923                           + (INTVAL (operands[4]) ^ endian)));
9924
9925   operands[7] = gen_rtx_REG (SFmode,
9926                              (true_regnum (operands[0])
9927                               + (INTVAL (operands[3]) ^ endian)));
9928   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9929 }"
9930   [(set_attr "type" "fparith_media")])
9931
9932 (define_insn_and_split "binary_sf_op"
9933   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9934         (vec_select:V2SF
9935          (vec_concat:V2SF
9936           (vec_select:SF
9937            (match_dup 0)
9938            (parallel [(match_operand 7 "const_int_operand" "n")]))
9939           (match_operator:SF 3 "binary_float_operator"
9940             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9941                             (parallel [(match_operand 5
9942                                         "const_int_operand" "n")]))
9943              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9944                             (parallel [(match_operand 6
9945                                         "const_int_operand" "n")]))]))
9946          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9947   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9948   "#"
9949   "&& reload_completed"
9950   [(set (match_dup 8) (match_dup 9))]
9951   "
9952 {
9953   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9954   rtx op1 = gen_rtx_REG (SFmode,
9955                          (true_regnum (operands[1])
9956                           + (INTVAL (operands[5]) ^ endian)));
9957   rtx op2 = gen_rtx_REG (SFmode,
9958                          (true_regnum (operands[2])
9959                           + (INTVAL (operands[6]) ^ endian)));
9960
9961   operands[8] = gen_rtx_REG (SFmode,
9962                              (true_regnum (operands[0])
9963                               + (INTVAL (operands[4]) ^ endian)));
9964   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9965 }"
9966   [(set_attr "type" "fparith_media")])
9967
9968 (define_insn "addsf3_i"
9969   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9970         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9971                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9972    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9973   "TARGET_SH2E"
9974   "fadd %2,%0"
9975   [(set_attr "type" "fp")
9976    (set_attr "fp_mode" "single")])
9977
9978 (define_expand "subsf3"
9979   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9980         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9981                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9982   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9983   "
9984 {
9985   if (TARGET_SH2E)
9986     {
9987       expand_sf_binop (&gen_subsf3_i, operands);
9988       DONE;
9989     }
9990 }")
9991
9992 (define_insn "*subsf3_media"
9993   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9994         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9995                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9996   "TARGET_SHMEDIA_FPU"
9997   "fsub.s       %1, %2, %0"
9998   [(set_attr "type" "fparith_media")])
9999
10000 (define_insn "subsf3_i"
10001   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10002         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10003                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10004    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10005   "TARGET_SH2E"
10006   "fsub %2,%0"
10007   [(set_attr "type" "fp")
10008    (set_attr "fp_mode" "single")])
10009
10010 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10011 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
10012 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
10013 ;; SH3E, we use a separate insn for SH3E mulsf3.
10014
10015 (define_expand "mulsf3"
10016   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10017         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10018                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10019   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10020   "
10021 {
10022   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10023     expand_sf_binop (&gen_mulsf3_i4, operands);
10024   else if (TARGET_SH2E)
10025     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10026   if (! TARGET_SHMEDIA)
10027     DONE;
10028 }")
10029
10030 (define_insn "*mulsf3_media"
10031   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10032         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10033                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10034   "TARGET_SHMEDIA_FPU"
10035   "fmul.s       %1, %2, %0"
10036   [(set_attr "type" "fparith_media")])
10037
10038 (define_insn "mulsf3_i4"
10039   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10040         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10041                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10042    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10043   "TARGET_SH2E"
10044   "fmul %2,%0"
10045   [(set_attr "type" "fp")
10046    (set_attr "fp_mode" "single")])
10047
10048 (define_insn "mulsf3_ie"
10049   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10050         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10051                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10052   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10053   "fmul %2,%0"
10054   [(set_attr "type" "fp")])
10055
10056 (define_insn "mac_media"
10057   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10058         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10059                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10060                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10061   "TARGET_SHMEDIA_FPU"
10062   "fmac.s %1, %2, %0"
10063   [(set_attr "type" "fparith_media")])
10064
10065 (define_insn "*macsf3"
10066   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10067         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10068                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10069                  (match_operand:SF 3 "arith_reg_operand" "0")))
10070    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10071   "TARGET_SH2E && ! TARGET_SH4"
10072   "fmac fr0,%2,%0"
10073   [(set_attr "type" "fp")
10074    (set_attr "fp_mode" "single")])
10075
10076 (define_expand "divsf3"
10077   [(set (match_operand:SF 0 "arith_reg_operand" "")
10078         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10079                 (match_operand:SF 2 "arith_reg_operand" "")))]
10080   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10081   "
10082 {
10083   if (TARGET_SH2E)
10084     {
10085       expand_sf_binop (&gen_divsf3_i, operands);
10086       DONE;
10087     }
10088 }")
10089
10090 (define_insn "*divsf3_media"
10091   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10092         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10093                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10094   "TARGET_SHMEDIA_FPU"
10095   "fdiv.s       %1, %2, %0"
10096   [(set_attr "type" "fdiv_media")])
10097
10098 (define_insn "divsf3_i"
10099   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10100         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10101                  (match_operand:SF 2 "arith_reg_operand" "f")))
10102    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10103   "TARGET_SH2E"
10104   "fdiv %2,%0"
10105   [(set_attr "type" "fdiv")
10106    (set_attr "fp_mode" "single")])
10107
10108 (define_insn "floatdisf2"
10109   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10110         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10111   "TARGET_SHMEDIA_FPU"
10112   "float.qs %1, %0"
10113   [(set_attr "type" "fpconv_media")])
10114
10115 (define_expand "floatsisf2"
10116   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10117         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10118   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10119   "
10120 {
10121   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10122     {
10123       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10124       DONE;
10125     }
10126 }")
10127
10128 (define_insn "*floatsisf2_media"
10129   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10130         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10131   "TARGET_SHMEDIA_FPU"
10132   "float.ls     %1, %0"
10133   [(set_attr "type" "fpconv_media")])
10134
10135 (define_insn "floatsisf2_i4"
10136   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10137         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10138    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10139   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10140   "float        %1,%0"
10141   [(set_attr "type" "fp")
10142    (set_attr "fp_mode" "single")])
10143
10144 (define_insn "*floatsisf2_ie"
10145   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10146         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10147   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10148   "float        %1,%0"
10149   [(set_attr "type" "fp")])
10150
10151 (define_insn "fix_truncsfdi2"
10152   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10153         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10154   "TARGET_SHMEDIA_FPU"
10155   "ftrc.sq %1, %0"
10156   [(set_attr "type" "fpconv_media")])
10157
10158 (define_expand "fix_truncsfsi2"
10159   [(set (match_operand:SI 0 "fpul_operand" "=y")
10160         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10161   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10162   "
10163 {
10164   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10165     {
10166       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10167       DONE;
10168     }
10169 }")
10170
10171 (define_insn "*fix_truncsfsi2_media"
10172   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10173         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10174   "TARGET_SHMEDIA_FPU"
10175   "ftrc.sl      %1, %0"
10176   [(set_attr "type" "fpconv_media")])
10177
10178 (define_insn "fix_truncsfsi2_i4"
10179   [(set (match_operand:SI 0 "fpul_operand" "=y")
10180         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10181    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10182   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10183   "ftrc %1,%0"
10184   [(set_attr "type" "ftrc_s")
10185    (set_attr "fp_mode" "single")])
10186
10187 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10188 ;; fix_truncsfsi2_i4.
10189 ;; (define_insn "fix_truncsfsi2_i4_2"
10190 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10191 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10192 ;;   (use (reg:PSI FPSCR_REG))
10193 ;;   (clobber (reg:SI FPUL_REG))]
10194 ;;  "TARGET_SH4"
10195 ;;  "#"
10196 ;;  [(set_attr "length" "4")
10197 ;;   (set_attr "fp_mode" "single")])
10198
10199 ;;(define_split
10200 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10201 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10202 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10203 ;;   (clobber (reg:SI FPUL_REG))]
10204 ;;  "TARGET_SH4"
10205 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10206 ;;            (use (match_dup 2))])
10207 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10208
10209 (define_insn "*fixsfsi"
10210   [(set (match_operand:SI 0 "fpul_operand" "=y")
10211         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10212   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10213   "ftrc %1,%0"
10214   [(set_attr "type" "fp")])
10215
10216 (define_insn "cmpgtsf_t"
10217   [(set (reg:SI T_REG)
10218         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10219                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10220   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10221   "fcmp/gt      %1,%0"
10222   [(set_attr "type" "fp")
10223    (set_attr "fp_mode" "single")])
10224
10225 (define_insn "cmpeqsf_t"
10226   [(set (reg:SI T_REG)
10227         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10228                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10229   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10230   "fcmp/eq      %1,%0"
10231   [(set_attr "type" "fp")
10232    (set_attr "fp_mode" "single")])
10233
10234 (define_insn "ieee_ccmpeqsf_t"
10235   [(set (reg:SI T_REG)
10236         (ior:SI (reg:SI T_REG)
10237                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10238                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10239   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10240   "* return output_ieee_ccmpeq (insn, operands);"
10241   [(set_attr "length" "4")])
10242
10243
10244 (define_insn "cmpgtsf_t_i4"
10245   [(set (reg:SI T_REG)
10246         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10247                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10248    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10249   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10250   "fcmp/gt      %1,%0"
10251   [(set_attr "type" "fp")
10252    (set_attr "fp_mode" "single")])
10253
10254 (define_insn "cmpeqsf_t_i4"
10255   [(set (reg:SI T_REG)
10256         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10257                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10258    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10259   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10260   "fcmp/eq      %1,%0"
10261   [(set_attr "type" "fp")
10262    (set_attr "fp_mode" "single")])
10263
10264 (define_insn "*ieee_ccmpeqsf_t_4"
10265   [(set (reg:SI T_REG)
10266         (ior:SI (reg:SI T_REG)
10267                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10268                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10269    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10270   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10271   "* return output_ieee_ccmpeq (insn, operands);"
10272   [(set_attr "length" "4")
10273    (set_attr "fp_mode" "single")])
10274
10275 (define_insn "cmpeqsf_media"
10276   [(set (match_operand:DI 0 "register_operand" "=r")
10277         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10278                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10279   "TARGET_SHMEDIA_FPU"
10280   "fcmpeq.s     %1, %2, %0"
10281   [(set_attr "type" "fcmp_media")])
10282
10283 (define_insn "cmpsieqsf_media"
10284   [(set (match_operand:SI 0 "register_operand" "=r")
10285         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10286                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10287   "TARGET_SHMEDIA_FPU"
10288   "fcmpeq.s     %1, %2, %0"
10289   [(set_attr "type" "fcmp_media")])
10290
10291 (define_insn "cmpgtsf_media"
10292   [(set (match_operand:DI 0 "register_operand" "=r")
10293         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10294                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10295   "TARGET_SHMEDIA_FPU"
10296   "fcmpgt.s     %1, %2, %0"
10297   [(set_attr "type" "fcmp_media")])
10298
10299 (define_insn "cmpgesf_media"
10300   [(set (match_operand:DI 0 "register_operand" "=r")
10301         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10302                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10303   "TARGET_SHMEDIA_FPU"
10304   "fcmpge.s     %1, %2, %0"
10305   [(set_attr "type" "fcmp_media")])
10306
10307 (define_insn "cmpunsf_media"
10308   [(set (match_operand:DI 0 "register_operand" "=r")
10309         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10310                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10311   "TARGET_SHMEDIA_FPU"
10312   "fcmpun.s     %1, %2, %0"
10313   [(set_attr "type" "fcmp_media")])
10314
10315 (define_expand "cmpsf"
10316   [(set (reg:SI T_REG)
10317         (compare (match_operand:SF 0 "arith_operand" "")
10318                  (match_operand:SF 1 "arith_operand" "")))]
10319   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10320   "
10321 {
10322   sh_compare_op0 = operands[0];
10323   sh_compare_op1 = operands[1];
10324   DONE;
10325 }")
10326
10327 (define_expand "negsf2"
10328   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10329         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10330   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10331   "
10332 {
10333   if (TARGET_SH2E)
10334     {
10335       expand_sf_unop (&gen_negsf2_i, operands);
10336       DONE;
10337     }
10338 }")
10339
10340 (define_insn "*negsf2_media"
10341   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10342         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10343   "TARGET_SHMEDIA_FPU"
10344   "fneg.s       %1, %0"
10345   [(set_attr "type" "fmove_media")])
10346
10347 (define_insn "negsf2_i"
10348   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10349         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10350    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10351   "TARGET_SH2E"
10352   "fneg %0"
10353   [(set_attr "type" "fmove")
10354    (set_attr "fp_mode" "single")])
10355
10356 (define_expand "sqrtsf2"
10357   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10358         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10359   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10360   "
10361 {
10362   if (TARGET_SH3E)
10363     {
10364       expand_sf_unop (&gen_sqrtsf2_i, operands);
10365       DONE;
10366     }
10367 }")
10368
10369 (define_insn "*sqrtsf2_media"
10370   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10371         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10372   "TARGET_SHMEDIA_FPU"
10373   "fsqrt.s      %1, %0"
10374   [(set_attr "type" "fdiv_media")])
10375
10376 (define_insn "sqrtsf2_i"
10377   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10378         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10379    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10380   "TARGET_SH3E"
10381   "fsqrt        %0"
10382   [(set_attr "type" "fdiv")
10383    (set_attr "fp_mode" "single")])
10384
10385 (define_insn "rsqrtsf2"
10386   [(set (match_operand:SF 0 "register_operand" "=f")
10387         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10388                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10389    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10390   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10391    && operands[1] == CONST1_RTX (SFmode)"
10392   "fsrra        %0"
10393   [(set_attr "type" "fsrra")
10394    (set_attr "fp_mode" "single")])
10395
10396 (define_insn "fsca"
10397   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10398         (vec_concat:V2SF
10399          (unspec:SF [(mult:SF
10400                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10401                       (match_operand:SF 2 "immediate_operand" "i"))
10402                     ] UNSPEC_FSINA)
10403          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10404                     ] UNSPEC_FCOSA)))
10405    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10406   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10407    && operands[2] == sh_fsca_int2sf ()"
10408   "fsca fpul,%d0"
10409   [(set_attr "type" "fsca")
10410    (set_attr "fp_mode" "single")])
10411
10412 (define_expand "sinsf2"
10413   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10414         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10415                    UNSPEC_FSINA))]
10416   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10417   "
10418 {
10419   rtx scaled = gen_reg_rtx (SFmode);
10420   rtx truncated = gen_reg_rtx (SImode);
10421   rtx fsca = gen_reg_rtx (V2SFmode);
10422   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10423
10424   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10425   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10426   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10427                           get_fpscr_rtx ()));
10428   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10429   DONE;
10430 }")
10431
10432 (define_expand "cossf2"
10433   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10434         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10435                    UNSPEC_FCOSA))]
10436   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10437   "
10438 {
10439   rtx scaled = gen_reg_rtx (SFmode);
10440   rtx truncated = gen_reg_rtx (SImode);
10441   rtx fsca = gen_reg_rtx (V2SFmode);
10442   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10443
10444   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10445   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10446   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10447                           get_fpscr_rtx ()));
10448   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10449   DONE;
10450 }")
10451
10452 (define_expand "sindf2"
10453   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10454         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10455                    UNSPEC_FSINA))]
10456   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10457   "
10458 {
10459   rtx scaled = gen_reg_rtx (DFmode);
10460   rtx truncated = gen_reg_rtx (SImode);
10461   rtx fsca = gen_reg_rtx (V2SFmode);
10462   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10463   rtx sfresult = gen_reg_rtx (SFmode);
10464
10465   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10466   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10467   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10468                           get_fpscr_rtx ()));
10469   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10470   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10471   DONE;
10472 }")
10473
10474 (define_expand "cosdf2"
10475   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10476         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10477                    UNSPEC_FCOSA))]
10478   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10479   "
10480 {
10481   rtx scaled = gen_reg_rtx (DFmode);
10482   rtx truncated = gen_reg_rtx (SImode);
10483   rtx fsca = gen_reg_rtx (V2SFmode);
10484   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10485   rtx sfresult = gen_reg_rtx (SFmode);
10486
10487   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10488   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10489   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10490                           get_fpscr_rtx ()));
10491   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10492   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10493   DONE;
10494 }")
10495
10496 (define_expand "abssf2"
10497   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10498         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10499   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10500   "
10501 {
10502   if (TARGET_SH2E)
10503     {
10504       expand_sf_unop (&gen_abssf2_i, operands);
10505       DONE;
10506     }
10507 }")
10508
10509 (define_insn "*abssf2_media"
10510   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10511         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10512   "TARGET_SHMEDIA_FPU"
10513   "fabs.s       %1, %0"
10514   [(set_attr "type" "fmove_media")])
10515
10516 (define_insn "abssf2_i"
10517   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10518         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10519    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10520   "TARGET_SH2E"
10521   "fabs %0"
10522   [(set_attr "type" "fmove")
10523    (set_attr "fp_mode" "single")])
10524
10525 (define_expand "adddf3"
10526   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10527         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10528                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10529   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10530   "
10531 {
10532   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10533     {
10534       expand_df_binop (&gen_adddf3_i, operands);
10535       DONE;
10536     }
10537 }")
10538
10539 (define_insn "*adddf3_media"
10540   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10541         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10542                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10543   "TARGET_SHMEDIA_FPU"
10544   "fadd.d       %1, %2, %0"
10545   [(set_attr "type" "dfparith_media")])
10546
10547 (define_insn "adddf3_i"
10548   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10549         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10550                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10551    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10552   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10553   "fadd %2,%0"
10554   [(set_attr "type" "dfp_arith")
10555    (set_attr "fp_mode" "double")])
10556
10557 (define_expand "subdf3"
10558   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10559         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10560                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10561   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10562   "
10563 {
10564   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10565     {
10566       expand_df_binop (&gen_subdf3_i, operands);
10567       DONE;
10568     }
10569 }")
10570
10571 (define_insn "*subdf3_media"
10572   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10573         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10574                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10575   "TARGET_SHMEDIA_FPU"
10576   "fsub.d       %1, %2, %0"
10577   [(set_attr "type" "dfparith_media")])
10578
10579 (define_insn "subdf3_i"
10580   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10581         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10582                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10583    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10584   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10585   "fsub %2,%0"
10586   [(set_attr "type" "dfp_arith")
10587    (set_attr "fp_mode" "double")])
10588
10589 (define_expand "muldf3"
10590   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10591         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10592                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10593   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10594   "
10595 {
10596   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10597     {
10598       expand_df_binop (&gen_muldf3_i, operands);
10599       DONE;
10600     }
10601 }")
10602
10603 (define_insn "*muldf3_media"
10604   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10605         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10606                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10607   "TARGET_SHMEDIA_FPU"
10608   "fmul.d       %1, %2, %0"
10609   [(set_attr "type" "dfmul_media")])
10610
10611 (define_insn "muldf3_i"
10612   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10613         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10614                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10615    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10616   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10617   "fmul %2,%0"
10618   [(set_attr "type" "dfp_arith")
10619    (set_attr "fp_mode" "double")])
10620
10621 (define_expand "divdf3"
10622   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10623         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10624                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10625   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10626   "
10627 {
10628   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10629     {
10630       expand_df_binop (&gen_divdf3_i, operands);
10631       DONE;
10632     }
10633 }")
10634
10635 (define_insn "*divdf3_media"
10636   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10637         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10638                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10639   "TARGET_SHMEDIA_FPU"
10640   "fdiv.d       %1, %2, %0"
10641   [(set_attr "type" "dfdiv_media")])
10642
10643 (define_insn "divdf3_i"
10644   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10645         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10646                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10647    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10648   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10649   "fdiv %2,%0"
10650   [(set_attr "type" "dfdiv")
10651    (set_attr "fp_mode" "double")])
10652
10653 (define_insn "floatdidf2"
10654   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10655         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10656   "TARGET_SHMEDIA_FPU"
10657   "float.qd     %1, %0"
10658   [(set_attr "type" "dfpconv_media")])
10659
10660 (define_expand "floatsidf2"
10661   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10662         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10663   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10664   "
10665 {
10666   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10667     {
10668       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10669                                       get_fpscr_rtx ()));
10670       DONE;
10671     }
10672 }")
10673
10674 (define_insn "*floatsidf2_media"
10675   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10676         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10677   "TARGET_SHMEDIA_FPU"
10678   "float.ld     %1, %0"
10679   [(set_attr "type" "dfpconv_media")])
10680
10681 (define_insn "floatsidf2_i"
10682   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10683         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10684    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10685   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10686   "float        %1,%0"
10687   [(set_attr "type" "dfp_conv")
10688    (set_attr "fp_mode" "double")])
10689
10690 (define_insn "fix_truncdfdi2"
10691   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10692         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10693   "TARGET_SHMEDIA_FPU"
10694   "ftrc.dq      %1, %0"
10695   [(set_attr "type" "dfpconv_media")])
10696
10697 (define_expand "fix_truncdfsi2"
10698   [(set (match_operand:SI 0 "fpul_operand" "")
10699         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10700   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10701   "
10702 {
10703   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10704     {
10705       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10706                                           get_fpscr_rtx ()));
10707       DONE;
10708     }
10709 }")
10710
10711 (define_insn "*fix_truncdfsi2_media"
10712   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10713         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10714   "TARGET_SHMEDIA_FPU"
10715   "ftrc.dl      %1, %0"
10716   [(set_attr "type" "dfpconv_media")])
10717
10718 (define_insn "fix_truncdfsi2_i"
10719   [(set (match_operand:SI 0 "fpul_operand" "=y")
10720         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10721    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10722   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10723   "ftrc %1,%0"
10724   [(set_attr "type" "dfp_conv")
10725    (set_attr "dfp_comp" "no")
10726    (set_attr "fp_mode" "double")])
10727
10728 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10729 ;; fix_truncdfsi2_i.
10730 ;; (define_insn "fix_truncdfsi2_i4"
10731 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10732 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10733 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10734 ;;    (clobber (reg:SI FPUL_REG))]
10735 ;;   "TARGET_SH4"
10736 ;;   "#"
10737 ;;   [(set_attr "length" "4")
10738 ;;    (set_attr "fp_mode" "double")])
10739 ;;
10740 ;; (define_split
10741 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10742 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10743 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10744 ;;    (clobber (reg:SI FPUL_REG))]
10745 ;;   "TARGET_SH4"
10746 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10747 ;;            (use (match_dup 2))])
10748 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10749
10750 (define_insn "cmpgtdf_t"
10751   [(set (reg:SI T_REG)
10752         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10753                (match_operand:DF 1 "arith_reg_operand" "f")))
10754    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10755   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10756   "fcmp/gt      %1,%0"
10757   [(set_attr "type" "dfp_cmp")
10758    (set_attr "fp_mode" "double")])
10759
10760 (define_insn "cmpeqdf_t"
10761   [(set (reg:SI T_REG)
10762         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10763                (match_operand:DF 1 "arith_reg_operand" "f")))
10764    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10765   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10766   "fcmp/eq      %1,%0"
10767   [(set_attr "type" "dfp_cmp")
10768    (set_attr "fp_mode" "double")])
10769
10770 (define_insn "*ieee_ccmpeqdf_t"
10771   [(set (reg:SI T_REG)
10772         (ior:SI (reg:SI T_REG)
10773                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10774                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10775    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10776   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10777   "* return output_ieee_ccmpeq (insn, operands);"
10778   [(set_attr "length" "4")
10779    (set_attr "fp_mode" "double")])
10780
10781 (define_insn "cmpeqdf_media"
10782   [(set (match_operand:DI 0 "register_operand" "=r")
10783         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10784                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10785   "TARGET_SHMEDIA_FPU"
10786   "fcmpeq.d     %1,%2,%0"
10787   [(set_attr "type" "fcmp_media")])
10788
10789 (define_insn "cmpsieqdf_media"
10790   [(set (match_operand:SI 0 "register_operand" "=r")
10791         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10792                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10793   "TARGET_SHMEDIA_FPU"
10794   "fcmpeq.d     %1,%2,%0"
10795   [(set_attr "type" "fcmp_media")])
10796
10797 (define_insn "cmpgtdf_media"
10798   [(set (match_operand:DI 0 "register_operand" "=r")
10799         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10800                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10801   "TARGET_SHMEDIA_FPU"
10802   "fcmpgt.d     %1,%2,%0"
10803   [(set_attr "type" "fcmp_media")])
10804
10805 (define_insn "cmpgedf_media"
10806   [(set (match_operand:DI 0 "register_operand" "=r")
10807         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10808                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10809   "TARGET_SHMEDIA_FPU"
10810   "fcmpge.d     %1,%2,%0"
10811   [(set_attr "type" "fcmp_media")])
10812
10813 (define_insn "cmpundf_media"
10814   [(set (match_operand:DI 0 "register_operand" "=r")
10815         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10816                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10817   "TARGET_SHMEDIA_FPU"
10818   "fcmpun.d     %1,%2,%0"
10819   [(set_attr "type" "fcmp_media")])
10820
10821 (define_expand "cmpdf"
10822   [(set (reg:SI T_REG)
10823         (compare (match_operand:DF 0 "arith_operand" "")
10824                  (match_operand:DF 1 "arith_operand" "")))]
10825   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10826   "
10827 {
10828   sh_compare_op0 = operands[0];
10829   sh_compare_op1 = operands[1];
10830   DONE;
10831 }")
10832
10833 (define_expand "negdf2"
10834   [(set (match_operand:DF 0 "arith_reg_operand" "")
10835         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10836   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10837   "
10838 {
10839   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10840     {
10841       expand_df_unop (&gen_negdf2_i, operands);
10842       DONE;
10843     }
10844 }")
10845
10846 (define_insn "*negdf2_media"
10847   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10848         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10849   "TARGET_SHMEDIA_FPU"
10850   "fneg.d       %1, %0"
10851   [(set_attr "type" "fmove_media")])
10852
10853 (define_insn "negdf2_i"
10854   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10855         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10856    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10857   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10858   "fneg %0"
10859   [(set_attr "type" "fmove")
10860    (set_attr "fp_mode" "double")])
10861
10862 (define_expand "sqrtdf2"
10863   [(set (match_operand:DF 0 "arith_reg_operand" "")
10864         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10865   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10866   "
10867 {
10868   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10869     {
10870       expand_df_unop (&gen_sqrtdf2_i, operands);
10871       DONE;
10872     }
10873 }")
10874
10875 (define_insn "*sqrtdf2_media"
10876   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10877         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10878   "TARGET_SHMEDIA_FPU"
10879   "fsqrt.d      %1, %0"
10880   [(set_attr "type" "dfdiv_media")])
10881
10882 (define_insn "sqrtdf2_i"
10883   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10884         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10885    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10886   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10887   "fsqrt        %0"
10888   [(set_attr "type" "dfdiv")
10889    (set_attr "fp_mode" "double")])
10890
10891 (define_expand "absdf2"
10892   [(set (match_operand:DF 0 "arith_reg_operand" "")
10893         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10894   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10895   "
10896 {
10897   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10898     {
10899       expand_df_unop (&gen_absdf2_i, operands);
10900       DONE;
10901     }
10902 }")
10903
10904 (define_insn "*absdf2_media"
10905   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10906         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10907   "TARGET_SHMEDIA_FPU"
10908   "fabs.d       %1, %0"
10909   [(set_attr "type" "fmove_media")])
10910
10911 (define_insn "absdf2_i"
10912   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10913         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10914    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10915   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10916   "fabs %0"
10917   [(set_attr "type" "fmove")
10918    (set_attr "fp_mode" "double")])
10919
10920 (define_expand "extendsfdf2"
10921   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10922         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10923   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10924   "
10925 {
10926   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10927     {
10928       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10929                                         get_fpscr_rtx ()));
10930       DONE;
10931     }
10932 }")
10933
10934 (define_insn "*extendsfdf2_media"
10935   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10936         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10937   "TARGET_SHMEDIA_FPU"
10938   "fcnv.sd      %1, %0"
10939   [(set_attr "type" "dfpconv_media")])
10940
10941 (define_insn "extendsfdf2_i4"
10942   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10943         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10944    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10945   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10946   "fcnvsd  %1,%0"
10947   [(set_attr "type" "fp")
10948    (set_attr "fp_mode" "double")])
10949
10950 (define_expand "truncdfsf2"
10951   [(set (match_operand:SF 0 "fpul_operand" "")
10952         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10953   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10954   "
10955 {
10956   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10957     {
10958       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10959                                        get_fpscr_rtx ()));
10960       DONE;
10961     }
10962 }")
10963
10964 (define_insn "*truncdfsf2_media"
10965   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10966         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10967   "TARGET_SHMEDIA_FPU"
10968   "fcnv.ds      %1, %0"
10969   [(set_attr "type" "dfpconv_media")])
10970
10971 (define_insn "truncdfsf2_i4"
10972   [(set (match_operand:SF 0 "fpul_operand" "=y")
10973         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10974    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10975   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10976   "fcnvds  %1,%0"
10977   [(set_attr "type" "fp")
10978    (set_attr "fp_mode" "double")])
10979 \f
10980 ;; Bit field extract patterns.  These give better code for packed bitfields,
10981 ;; because they allow auto-increment addresses to be generated.
10982
10983 (define_expand "insv"
10984   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10985                          (match_operand:SI 1 "immediate_operand" "")
10986                          (match_operand:SI 2 "immediate_operand" ""))
10987         (match_operand:SI 3 "general_operand" ""))]
10988   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10989   "
10990 {
10991   rtx addr_target, orig_address, shift_reg, qi_val;
10992   HOST_WIDE_INT bitsize, size, v = 0;
10993   rtx x = operands[3];
10994
10995   /* ??? expmed doesn't care for non-register predicates.  */
10996   if (! memory_operand (operands[0], VOIDmode)
10997       || ! immediate_operand (operands[1], VOIDmode)
10998       || ! immediate_operand (operands[2], VOIDmode)
10999       || ! general_operand (x, VOIDmode))
11000     FAIL;
11001   /* If this isn't a 16 / 24 / 32 bit field, or if
11002      it doesn't start on a byte boundary, then fail.  */
11003   bitsize = INTVAL (operands[1]);
11004   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11005       || (INTVAL (operands[2]) % 8) != 0)
11006     FAIL;
11007
11008   size = bitsize / 8;
11009   orig_address = XEXP (operands[0], 0);
11010   shift_reg = gen_reg_rtx (SImode);
11011   if (GET_CODE (x) == CONST_INT)
11012     {
11013       v = INTVAL (x);
11014       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11015     }
11016   else
11017     {
11018       emit_insn (gen_movsi (shift_reg, operands[3]));
11019       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11020     }
11021   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11022
11023   operands[0] = replace_equiv_address (operands[0], addr_target);
11024   emit_insn (gen_movqi (operands[0], qi_val));
11025
11026   while (size -= 1)
11027     {
11028       if (GET_CODE (x) == CONST_INT)
11029         qi_val
11030           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11031       else
11032         {
11033           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11034           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11035         }
11036       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11037       emit_insn (gen_movqi (operands[0], qi_val));
11038     }
11039
11040   DONE;
11041 }")
11042
11043 (define_insn "movua"
11044   [(set (match_operand:SI 0 "register_operand" "=z")
11045         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11046                          (const_int 32) (const_int 0)))]
11047   "TARGET_SH4A_ARCH"
11048   "movua.l      %1,%0"
11049   [(set_attr "type" "movua")])
11050
11051 ;; We shouldn't need this, but cse replaces increments with references
11052 ;; to other regs before flow has a chance to create post_inc
11053 ;; addressing modes, and only postreload's cse_move2add brings the
11054 ;; increments back to a usable form.
11055 (define_peephole2
11056   [(set (match_operand:SI 0 "register_operand" "")
11057         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11058                          (const_int 32) (const_int 0)))
11059    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11060   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11061   [(set (match_operand:SI 0 "register_operand" "")
11062         (sign_extract:SI (mem:SI (post_inc:SI
11063                                   (match_operand:SI 1 "register_operand" "")))
11064                          (const_int 32) (const_int 0)))]
11065   "")
11066
11067 (define_expand "extv"
11068   [(set (match_operand:SI 0 "register_operand" "")
11069         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11070                          (match_operand 2 "const_int_operand" "")
11071                          (match_operand 3 "const_int_operand" "")))]
11072   "TARGET_SH4A_ARCH"
11073 {
11074   if (TARGET_SH4A_ARCH
11075       && INTVAL (operands[2]) == 32
11076       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11077       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11078     {
11079       emit_insn (gen_movua (operands[0],
11080                             adjust_address (operands[1], SImode, 0)));
11081       DONE;
11082     }
11083
11084   FAIL;
11085 })
11086
11087 (define_expand "extzv"
11088   [(set (match_operand:SI 0 "register_operand" "")
11089         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11090                          (match_operand 2 "const_int_operand" "")
11091                          (match_operand 3 "const_int_operand" "")))]
11092   "TARGET_SH4A_ARCH"
11093 {
11094   if (TARGET_SH4A_ARCH
11095       && INTVAL (operands[2]) == 32
11096       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11097       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11098     {
11099       emit_insn (gen_movua (operands[0],
11100                             adjust_address (operands[1], SImode, 0)));
11101       DONE;
11102     }
11103
11104   FAIL;
11105 })
11106
11107 \f
11108 ;; -------------------------------------------------------------------------
11109 ;; Peepholes
11110 ;; -------------------------------------------------------------------------
11111
11112 ;; This matches cases where a stack pointer increment at the start of the
11113 ;; epilogue combines with a stack slot read loading the return value.
11114
11115 (define_peephole
11116   [(set (match_operand:SI 0 "arith_reg_operand" "")
11117         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11118    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11119   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11120   "mov.l        @%1+,%0")
11121
11122 ;; See the comment on the dt combiner pattern above.
11123
11124 (define_peephole
11125   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11126         (plus:SI (match_dup 0)
11127                  (const_int -1)))
11128    (set (reg:SI T_REG)
11129         (eq:SI (match_dup 0)
11130                (const_int 0)))]
11131   "TARGET_SH2"
11132   "dt   %0")
11133
11134 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11135 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11136 ;; reload when the constant is too large for a reg+offset address.
11137
11138 ;; ??? We would get much better code if this was done in reload.  This would
11139 ;; require modifying find_reloads_address to recognize that if the constant
11140 ;; is out-of-range for an immediate add, then we get better code by reloading
11141 ;; the constant into a register than by reloading the sum into a register,
11142 ;; since the former is one instruction shorter if the address does not need
11143 ;; to be offsettable.  Unfortunately this does not work, because there is
11144 ;; only one register, r0, that can be used as an index register.  This register
11145 ;; is also the function return value register.  So, if we try to force reload
11146 ;; to use double-reg addresses, then we end up with some instructions that
11147 ;; need to use r0 twice.  The only way to fix this is to change the calling
11148 ;; convention so that r0 is not used to return values.
11149
11150 (define_peephole
11151   [(set (match_operand:SI 0 "register_operand" "=r")
11152         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11153    (set (mem:SI (match_dup 0))
11154         (match_operand:SI 2 "general_movsrc_operand" ""))]
11155   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11156   "mov.l        %2,@(%0,%1)")
11157
11158 (define_peephole
11159   [(set (match_operand:SI 0 "register_operand" "=r")
11160         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11161    (set (match_operand:SI 2 "general_movdst_operand" "")
11162         (mem:SI (match_dup 0)))]
11163   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11164   "mov.l        @(%0,%1),%2")
11165
11166 (define_peephole
11167   [(set (match_operand:SI 0 "register_operand" "=r")
11168         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11169    (set (mem:HI (match_dup 0))
11170         (match_operand:HI 2 "general_movsrc_operand" ""))]
11171   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11172   "mov.w        %2,@(%0,%1)")
11173
11174 (define_peephole
11175   [(set (match_operand:SI 0 "register_operand" "=r")
11176         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11177    (set (match_operand:HI 2 "general_movdst_operand" "")
11178         (mem:HI (match_dup 0)))]
11179   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11180   "mov.w        @(%0,%1),%2")
11181
11182 (define_peephole
11183   [(set (match_operand:SI 0 "register_operand" "=r")
11184         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11185    (set (mem:QI (match_dup 0))
11186         (match_operand:QI 2 "general_movsrc_operand" ""))]
11187   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11188   "mov.b        %2,@(%0,%1)")
11189
11190 (define_peephole
11191   [(set (match_operand:SI 0 "register_operand" "=r")
11192         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11193    (set (match_operand:QI 2 "general_movdst_operand" "")
11194         (mem:QI (match_dup 0)))]
11195   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11196   "mov.b        @(%0,%1),%2")
11197
11198 (define_peephole
11199   [(set (match_operand:SI 0 "register_operand" "=r")
11200         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11201    (set (mem:SF (match_dup 0))
11202         (match_operand:SF 2 "general_movsrc_operand" ""))]
11203   "TARGET_SH1 && REGNO (operands[0]) == 0
11204    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11205        || (GET_CODE (operands[2]) == SUBREG
11206            && REGNO (SUBREG_REG (operands[2])) < 16))
11207    && reg_unused_after (operands[0], insn)"
11208   "mov.l        %2,@(%0,%1)")
11209
11210 (define_peephole
11211   [(set (match_operand:SI 0 "register_operand" "=r")
11212         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11213    (set (match_operand:SF 2 "general_movdst_operand" "")
11214
11215         (mem:SF (match_dup 0)))]
11216   "TARGET_SH1 && REGNO (operands[0]) == 0
11217    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11218        || (GET_CODE (operands[2]) == SUBREG
11219            && REGNO (SUBREG_REG (operands[2])) < 16))
11220    && reg_unused_after (operands[0], insn)"
11221   "mov.l        @(%0,%1),%2")
11222
11223 (define_peephole
11224   [(set (match_operand:SI 0 "register_operand" "=r")
11225         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11226    (set (mem:SF (match_dup 0))
11227         (match_operand:SF 2 "general_movsrc_operand" ""))]
11228   "TARGET_SH2E && REGNO (operands[0]) == 0
11229    && ((GET_CODE (operands[2]) == REG
11230         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11231        || (GET_CODE (operands[2]) == SUBREG
11232            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11233    && reg_unused_after (operands[0], insn)"
11234   "fmov{.s|}    %2,@(%0,%1)")
11235
11236 (define_peephole
11237   [(set (match_operand:SI 0 "register_operand" "=r")
11238         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11239    (set (match_operand:SF 2 "general_movdst_operand" "")
11240
11241         (mem:SF (match_dup 0)))]
11242   "TARGET_SH2E && REGNO (operands[0]) == 0
11243    && ((GET_CODE (operands[2]) == REG
11244         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11245        || (GET_CODE (operands[2]) == SUBREG
11246            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11247    && reg_unused_after (operands[0], insn)"
11248   "fmov{.s|}    @(%0,%1),%2")
11249
11250 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11251 (define_insn "sp_switch_1"
11252   [(const_int 1)]
11253   "TARGET_SH1"
11254   "*
11255 {
11256   rtx xoperands[1];
11257
11258   xoperands[0] = sp_switch;
11259   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
11260   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
11261   return \"mov r0,r15\";
11262 }"
11263   [(set_attr "length" "10")])
11264
11265 ;; Switch back to the original stack for interrupt functions with the
11266 ;; sp_switch attribute.  */
11267 (define_insn "sp_switch_2"
11268   [(const_int 2)]
11269   "TARGET_SH1"
11270   "mov.l @r15+,r15\;mov.l @r15+,r0"
11271   [(set_attr "length" "4")])
11272
11273 ;; Integer vector moves
11274
11275 (define_expand "movv8qi"
11276   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11277         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11278   "TARGET_SHMEDIA"
11279   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11280
11281 (define_insn "movv8qi_i"
11282   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11283         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11284   "TARGET_SHMEDIA
11285    && (register_operand (operands[0], V8QImode)
11286        || sh_register_operand (operands[1], V8QImode))"
11287   "@
11288         add     %1, r63, %0
11289         movi    %1, %0
11290         #
11291         ld%M1.q %m1, %0
11292         st%M0.q %m0, %N1"
11293   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11294    (set_attr "length" "4,4,16,4,4")])
11295
11296 (define_split
11297   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11298         (subreg:V8QI (const_int 0) 0))]
11299   "TARGET_SHMEDIA"
11300   [(set (match_dup 0)
11301         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11302                             (const_int 0) (const_int 0) (const_int 0)
11303                             (const_int 0) (const_int 0)]))])
11304
11305 (define_split
11306   [(set (match_operand 0 "arith_reg_dest" "")
11307         (match_operand 1 "sh_rep_vec" ""))]
11308   "TARGET_SHMEDIA && reload_completed
11309    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11310    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11311    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11312    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11313        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11314    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11315        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11316   [(set (match_dup 0) (match_dup 1))
11317    (match_dup 2)]
11318   "
11319 {
11320   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11321   rtx elt1 = XVECEXP (operands[1], 0, 1);
11322
11323   if (unit_size > 2)
11324     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11325   else
11326     {
11327       if (unit_size < 2)
11328         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11329       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11330     }
11331   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11332   operands[1] = XVECEXP (operands[1], 0, 0);
11333   if (unit_size < 2)
11334     {
11335       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11336         operands[1]
11337           = GEN_INT (TARGET_LITTLE_ENDIAN
11338                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11339                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11340       else
11341         {
11342           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11343           operands[1]
11344             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11345         }
11346     }
11347 }")
11348
11349 (define_split
11350   [(set (match_operand 0 "arith_reg_dest" "")
11351         (match_operand 1 "sh_const_vec" ""))]
11352   "TARGET_SHMEDIA && reload_completed
11353    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11354    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11355   [(set (match_dup 0) (match_dup 1))]
11356   "
11357 {
11358   rtx v = operands[1];
11359   enum machine_mode new_mode
11360     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11361
11362   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11363   operands[1]
11364     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11365 }")
11366
11367 (define_expand "movv2hi"
11368   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11369         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11370   "TARGET_SHMEDIA"
11371   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11372
11373 (define_insn "movv2hi_i"
11374   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11375         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11376   "TARGET_SHMEDIA
11377    && (register_operand (operands[0], V2HImode)
11378        || sh_register_operand (operands[1], V2HImode))"
11379   "@
11380         add.l   %1, r63, %0
11381         movi    %1, %0
11382         #
11383         ld%M1.l %m1, %0
11384         st%M0.l %m0, %N1"
11385   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11386    (set_attr "length" "4,4,16,4,4")
11387    (set (attr "highpart")
11388         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11389                (const_string "user")]
11390               (const_string "ignore")))])
11391
11392 (define_expand "movv4hi"
11393   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11394         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11395   "TARGET_SHMEDIA"
11396   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11397
11398 (define_insn "movv4hi_i"
11399   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11400         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11401   "TARGET_SHMEDIA
11402    && (register_operand (operands[0], V4HImode)
11403        || sh_register_operand (operands[1], V4HImode))"
11404   "@
11405         add     %1, r63, %0
11406         movi    %1, %0
11407         #
11408         ld%M1.q %m1, %0
11409         st%M0.q %m0, %N1"
11410   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11411    (set_attr "length" "4,4,16,4,4")
11412    (set_attr "highpart" "depend")])
11413
11414 (define_expand "movv2si"
11415   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11416         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11417   "TARGET_SHMEDIA"
11418   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11419
11420 (define_insn "movv2si_i"
11421   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11422         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11423   "TARGET_SHMEDIA
11424    && (register_operand (operands[0], V2SImode)
11425        || sh_register_operand (operands[1], V2SImode))"
11426   "@
11427         add     %1, r63, %0
11428         #
11429         #
11430         ld%M1.q %m1, %0
11431         st%M0.q %m0, %N1"
11432   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11433    (set_attr "length" "4,4,16,4,4")
11434    (set_attr "highpart" "depend")])
11435
11436 ;; Multimedia Intrinsics
11437
11438 (define_insn "absv2si2"
11439   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11440         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11441   "TARGET_SHMEDIA"
11442   "mabs.l       %1, %0"
11443   [(set_attr "type" "mcmp_media")
11444    (set_attr "highpart" "depend")])
11445
11446 (define_insn "absv4hi2"
11447   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11448         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11449   "TARGET_SHMEDIA"
11450   "mabs.w       %1, %0"
11451   [(set_attr "type" "mcmp_media")
11452    (set_attr "highpart" "depend")])
11453
11454 (define_insn "addv2si3"
11455   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11456         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11457                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11458   "TARGET_SHMEDIA"
11459   "madd.l       %1, %2, %0"
11460   [(set_attr "type" "arith_media")
11461    (set_attr "highpart" "depend")])
11462
11463 (define_insn "addv4hi3"
11464   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11465         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11466                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11467   "TARGET_SHMEDIA"
11468   "madd.w       %1, %2, %0"
11469   [(set_attr "type" "arith_media")
11470    (set_attr "highpart" "depend")])
11471
11472 (define_insn_and_split "addv2hi3"
11473   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11474         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11475                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11476   "TARGET_SHMEDIA"
11477   "#"
11478   "TARGET_SHMEDIA"
11479   [(const_int 0)]
11480   "
11481 {
11482   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11483   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11484   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11485   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11486   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11487
11488   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11489   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11490   DONE;
11491 }"
11492   [(set_attr "highpart" "must_split")])
11493
11494 (define_insn "ssaddv2si3"
11495   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11496         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11497                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11498   "TARGET_SHMEDIA"
11499   "madds.l      %1, %2, %0"
11500   [(set_attr "type" "mcmp_media")
11501    (set_attr "highpart" "depend")])
11502
11503 (define_insn "usaddv8qi3"
11504   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11505         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11506                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11507   "TARGET_SHMEDIA"
11508   "madds.ub     %1, %2, %0"
11509   [(set_attr "type" "mcmp_media")
11510    (set_attr "highpart" "depend")])
11511
11512 (define_insn "ssaddv4hi3"
11513   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11514         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11515                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11516   "TARGET_SHMEDIA"
11517   "madds.w      %1, %2, %0"
11518   [(set_attr "type" "mcmp_media")
11519    (set_attr "highpart" "depend")])
11520
11521 (define_insn "negcmpeqv8qi"
11522   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11523         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11524                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11525   "TARGET_SHMEDIA"
11526   "mcmpeq.b     %N1, %N2, %0"
11527   [(set_attr "type" "mcmp_media")
11528    (set_attr "highpart" "depend")])
11529
11530 (define_insn "negcmpeqv2si"
11531   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11532         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11533                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11534   "TARGET_SHMEDIA"
11535   "mcmpeq.l     %N1, %N2, %0"
11536   [(set_attr "type" "mcmp_media")
11537    (set_attr "highpart" "depend")])
11538
11539 (define_insn "negcmpeqv4hi"
11540   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11541         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11542                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11543   "TARGET_SHMEDIA"
11544   "mcmpeq.w     %N1, %N2, %0"
11545   [(set_attr "type" "mcmp_media")
11546    (set_attr "highpart" "depend")])
11547
11548 (define_insn "negcmpgtuv8qi"
11549   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11550         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11551                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11552   "TARGET_SHMEDIA"
11553   "mcmpgt.ub    %N1, %N2, %0"
11554   [(set_attr "type" "mcmp_media")
11555    (set_attr "highpart" "depend")])
11556
11557 (define_insn "negcmpgtv2si"
11558   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11559         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11560                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11561   "TARGET_SHMEDIA"
11562   "mcmpgt.l     %N1, %N2, %0"
11563   [(set_attr "type" "mcmp_media")
11564    (set_attr "highpart" "depend")])
11565
11566 (define_insn "negcmpgtv4hi"
11567   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11568         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11569                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11570   "TARGET_SHMEDIA"
11571   "mcmpgt.w     %N1, %N2, %0"
11572   [(set_attr "type" "mcmp_media")
11573    (set_attr "highpart" "depend")])
11574
11575 (define_insn "mcmv"
11576   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11577         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11578                         (match_operand:DI 2 "arith_reg_operand" "r"))
11579                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11580                         (not:DI (match_dup 2)))))]
11581   "TARGET_SHMEDIA"
11582   "mcmv %N1, %2, %0"
11583   [(set_attr "type" "arith_media")
11584    (set_attr "highpart" "depend")])
11585
11586 (define_insn "mcnvs_lw"
11587   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11588         (vec_concat:V4HI
11589          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11590          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11591   "TARGET_SHMEDIA"
11592   "mcnvs.lw     %N1, %N2, %0"
11593   [(set_attr "type" "mcmp_media")])
11594
11595 (define_insn "mcnvs_wb"
11596   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11597         (vec_concat:V8QI
11598          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11599          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11600   "TARGET_SHMEDIA"
11601   "mcnvs.wb     %N1, %N2, %0"
11602   [(set_attr "type" "mcmp_media")])
11603
11604 (define_insn "mcnvs_wub"
11605   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11606         (vec_concat:V8QI
11607          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11608          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11609   "TARGET_SHMEDIA"
11610   "mcnvs.wub    %N1, %N2, %0"
11611   [(set_attr "type" "mcmp_media")])
11612
11613 (define_insn "mextr_rl"
11614   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11615         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11616                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11617                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11618                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11619   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11620   "*
11621 {
11622   static char templ[21];
11623
11624   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11625            (int) INTVAL (operands[3]) >> 3);
11626   return templ;
11627 }"
11628   [(set_attr "type" "arith_media")])
11629
11630 (define_insn "*mextr_lr"
11631   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11632         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11633                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11634                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11635                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11636   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11637   "*
11638 {
11639   static char templ[21];
11640
11641   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11642            (int) INTVAL (operands[4]) >> 3);
11643   return templ;
11644 }"
11645   [(set_attr "type" "arith_media")])
11646
11647 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11648 ; vector then varies depending on endianness.
11649 (define_expand "mextr1"
11650   [(match_operand:DI 0 "arith_reg_dest" "")
11651    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11652    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11653   "TARGET_SHMEDIA"
11654   "
11655 {
11656   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11657                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11658   DONE;
11659 }")
11660
11661 (define_expand "mextr2"
11662   [(match_operand:DI 0 "arith_reg_dest" "")
11663    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11664    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11665   "TARGET_SHMEDIA"
11666   "
11667 {
11668   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11669                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11670   DONE;
11671 }")
11672
11673 (define_expand "mextr3"
11674   [(match_operand:DI 0 "arith_reg_dest" "")
11675    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11676    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11677   "TARGET_SHMEDIA"
11678   "
11679 {
11680   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11681                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11682   DONE;
11683 }")
11684
11685 (define_expand "mextr4"
11686   [(match_operand:DI 0 "arith_reg_dest" "")
11687    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11688    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11689   "TARGET_SHMEDIA"
11690   "
11691 {
11692   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11693                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11694   DONE;
11695 }")
11696
11697 (define_expand "mextr5"
11698   [(match_operand:DI 0 "arith_reg_dest" "")
11699    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11700    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11701   "TARGET_SHMEDIA"
11702   "
11703 {
11704   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11705                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11706   DONE;
11707 }")
11708
11709 (define_expand "mextr6"
11710   [(match_operand:DI 0 "arith_reg_dest" "")
11711    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11712    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11713   "TARGET_SHMEDIA"
11714   "
11715 {
11716   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11717                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11718   DONE;
11719 }")
11720
11721 (define_expand "mextr7"
11722   [(match_operand:DI 0 "arith_reg_dest" "")
11723    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11724    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11725   "TARGET_SHMEDIA"
11726   "
11727 {
11728   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11729                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11730   DONE;
11731 }")
11732
11733 (define_expand "mmacfx_wl"
11734   [(match_operand:V2SI 0 "arith_reg_dest" "")
11735    (match_operand:V2HI 1 "extend_reg_operand" "")
11736    (match_operand:V2HI 2 "extend_reg_operand" "")
11737    (match_operand:V2SI 3 "arith_reg_operand" "")]
11738   "TARGET_SHMEDIA"
11739   "
11740 {
11741   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11742                               operands[1], operands[2]));
11743   DONE;
11744 }")
11745
11746 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11747 ;; is depend
11748 (define_insn "mmacfx_wl_i"
11749   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11750         (ss_plus:V2SI
11751          (match_operand:V2SI 1 "arith_reg_operand" "0")
11752          (ss_truncate:V2SI
11753           (ashift:V2DI
11754            (sign_extend:V2DI
11755             (mult:V2SI
11756              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11757              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11758            (const_int 1)))))]
11759   "TARGET_SHMEDIA"
11760   "mmacfx.wl    %2, %3, %0"
11761   [(set_attr "type" "mac_media")
11762    (set_attr "highpart" "depend")])
11763
11764 (define_expand "mmacnfx_wl"
11765   [(match_operand:V2SI 0 "arith_reg_dest" "")
11766    (match_operand:V2HI 1 "extend_reg_operand" "")
11767    (match_operand:V2HI 2 "extend_reg_operand" "")
11768    (match_operand:V2SI 3 "arith_reg_operand" "")]
11769   "TARGET_SHMEDIA"
11770   "
11771 {
11772   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11773                                operands[1], operands[2]));
11774   DONE;
11775 }")
11776
11777 (define_insn "mmacnfx_wl_i"
11778   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11779         (ss_minus:V2SI
11780          (match_operand:V2SI 1 "arith_reg_operand" "0")
11781          (ss_truncate:V2SI
11782           (ashift:V2DI
11783            (sign_extend:V2DI
11784             (mult:V2SI
11785              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11786              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11787            (const_int 1)))))]
11788   "TARGET_SHMEDIA"
11789   "mmacnfx.wl   %2, %3, %0"
11790   [(set_attr "type" "mac_media")
11791    (set_attr "highpart" "depend")])
11792
11793 (define_insn "mulv2si3"
11794   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11795         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11796                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11797   "TARGET_SHMEDIA"
11798   "mmul.l       %1, %2, %0"
11799   [(set_attr "type" "d2mpy_media")
11800    (set_attr "highpart" "depend")])
11801
11802 (define_insn "mulv4hi3"
11803   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11804         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11805                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11806   "TARGET_SHMEDIA"
11807   "mmul.w       %1, %2, %0"
11808   [(set_attr "type" "dmpy_media")
11809    (set_attr "highpart" "depend")])
11810
11811 (define_insn "mmulfx_l"
11812   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11813         (ss_truncate:V2SI
11814          (ashiftrt:V2DI
11815           (mult:V2DI
11816            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11817            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11818           (const_int 31))))]
11819   "TARGET_SHMEDIA"
11820   "mmulfx.l     %1, %2, %0"
11821   [(set_attr "type" "d2mpy_media")
11822    (set_attr "highpart" "depend")])
11823
11824 (define_insn "mmulfx_w"
11825   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11826         (ss_truncate:V4HI
11827          (ashiftrt:V4SI
11828           (mult:V4SI
11829            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11830            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11831           (const_int 15))))]
11832   "TARGET_SHMEDIA"
11833   "mmulfx.w     %1, %2, %0"
11834   [(set_attr "type" "dmpy_media")
11835    (set_attr "highpart" "depend")])
11836
11837 (define_insn "mmulfxrp_w"
11838   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11839         (ss_truncate:V4HI
11840          (ashiftrt:V4SI
11841           (plus:V4SI
11842            (mult:V4SI
11843             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11844             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11845            (const_int 16384))
11846           (const_int 15))))]
11847   "TARGET_SHMEDIA"
11848   "mmulfxrp.w   %1, %2, %0"
11849   [(set_attr "type" "dmpy_media")
11850    (set_attr "highpart" "depend")])
11851
11852
11853 (define_expand "mmulhi_wl"
11854   [(match_operand:V2SI 0 "arith_reg_dest" "")
11855    (match_operand:V4HI 1 "arith_reg_operand" "")
11856    (match_operand:V4HI 2 "arith_reg_operand" "")]
11857   "TARGET_SHMEDIA"
11858   "
11859 {
11860   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11861              (operands[0], operands[1], operands[2]));
11862   DONE;
11863 }")
11864
11865 (define_expand "mmullo_wl"
11866   [(match_operand:V2SI 0 "arith_reg_dest" "")
11867    (match_operand:V4HI 1 "arith_reg_operand" "")
11868    (match_operand:V4HI 2 "arith_reg_operand" "")]
11869   "TARGET_SHMEDIA"
11870   "
11871 {
11872   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11873              (operands[0], operands[1], operands[2]));
11874   DONE;
11875 }")
11876
11877 (define_insn "mmul23_wl"
11878   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11879         (vec_select:V2SI
11880          (mult:V4SI
11881           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11882           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11883          (parallel [(const_int 2) (const_int 3)])))]
11884   "TARGET_SHMEDIA"
11885   "* return (TARGET_LITTLE_ENDIAN
11886              ? \"mmulhi.wl      %1, %2, %0\"
11887              : \"mmullo.wl      %1, %2, %0\");"
11888   [(set_attr "type" "dmpy_media")
11889    (set (attr "highpart")
11890         (cond [(eq_attr "endian" "big") (const_string "ignore")]
11891          (const_string "user")))])
11892
11893 (define_insn "mmul01_wl"
11894   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11895         (vec_select:V2SI
11896          (mult:V4SI
11897           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11898           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11899          (parallel [(const_int 0) (const_int 1)])))]
11900   "TARGET_SHMEDIA"
11901   "* return (TARGET_LITTLE_ENDIAN
11902              ? \"mmullo.wl      %1, %2, %0\"
11903              : \"mmulhi.wl      %1, %2, %0\");"
11904   [(set_attr "type" "dmpy_media")
11905    (set (attr "highpart")
11906         (cond [(eq_attr "endian" "little") (const_string "ignore")]
11907          (const_string "user")))])
11908
11909
11910 (define_expand "mmulsum_wq"
11911   [(match_operand:DI 0 "arith_reg_dest" "")
11912    (match_operand:V4HI 1 "arith_reg_operand" "")
11913    (match_operand:V4HI 2 "arith_reg_operand" "")
11914    (match_operand:DI 3 "arith_reg_operand" "")]
11915   "TARGET_SHMEDIA"
11916   "
11917 {
11918   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11919                                operands[1], operands[2]));
11920   DONE;
11921 }")
11922
11923 (define_insn "mmulsum_wq_i"
11924   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11925         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11926          (plus:DI
11927           (plus:DI
11928            (vec_select:DI
11929             (mult:V4DI
11930              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11931              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11932             (parallel [(const_int 0)]))
11933            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11934                                      (sign_extend:V4DI (match_dup 3)))
11935                           (parallel [(const_int 1)])))
11936           (plus:DI
11937            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11938                                      (sign_extend:V4DI (match_dup 3)))
11939                           (parallel [(const_int 2)]))
11940            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11941                                      (sign_extend:V4DI (match_dup 3)))
11942                           (parallel [(const_int 3)]))))))]
11943   "TARGET_SHMEDIA"
11944   "mmulsum.wq   %2, %3, %0"
11945   [(set_attr "type" "mac_media")])
11946
11947 (define_expand "mperm_w"
11948   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11949    (match_operand:V4HI 1 "arith_reg_operand" "r")
11950    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11951   "TARGET_SHMEDIA"
11952   "
11953 {
11954   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11955              (operands[0], operands[1], operands[2]));
11956   DONE;
11957 }")
11958
11959 ; This use of vec_select isn't exactly correct according to rtl.texi
11960 ; (because not constant), but it seems a straightforward extension.
11961 (define_insn "mperm_w_little"
11962   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11963         (vec_select:V4HI
11964          (match_operand:V4HI 1 "arith_reg_operand" "r")
11965          (parallel
11966           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11967                             (const_int 2) (const_int 0))
11968            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11969            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11970            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11971   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11972   "mperm.w      %1, %N2, %0"
11973   [(set_attr "type" "arith_media")])
11974
11975 (define_insn "mperm_w_big"
11976   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11977         (vec_select:V4HI
11978          (match_operand:V4HI 1 "arith_reg_operand" "r")
11979          (parallel
11980           [(zero_extract:QI (not:QI (match_operand:QI 2
11981                                      "extend_reg_or_0_operand" "rZ"))
11982                             (const_int 2) (const_int 0))
11983            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11984            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11985            (zero_extract:QI (not:QI (match_dup 2))
11986                             (const_int 2) (const_int 6))])))]
11987   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11988   "mperm.w      %1, %N2, %0"
11989   [(set_attr "type" "arith_media")])
11990
11991 (define_insn "mperm_w0"
11992   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11993         (vec_duplicate:V4HI (truncate:HI (match_operand 1
11994                                           "trunc_hi_operand" "r"))))]
11995   "TARGET_SHMEDIA"
11996   "mperm.w      %1, r63, %0"
11997   [(set_attr "type" "arith_media")
11998    (set_attr "highpart" "ignore")])
11999
12000 (define_expand "msad_ubq"
12001   [(match_operand:DI 0 "arith_reg_dest" "")
12002    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12003    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12004    (match_operand:DI 3 "arith_reg_operand" "")]
12005   "TARGET_SHMEDIA"
12006   "
12007 {
12008   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12009                              operands[1], operands[2]));
12010   DONE;
12011 }")
12012
12013 (define_insn "msad_ubq_i"
12014   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12015         (plus:DI
12016          (plus:DI
12017           (plus:DI
12018            (plus:DI
12019             (match_operand:DI 1 "arith_reg_operand" "0")
12020             (abs:DI (vec_select:DI
12021                      (minus:V8DI
12022                       (zero_extend:V8DI
12023                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12024                       (zero_extend:V8DI
12025                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12026                      (parallel [(const_int 0)]))))
12027            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12028                                               (zero_extend:V8DI (match_dup 3)))
12029                                   (parallel [(const_int 1)]))))
12030           (plus:DI
12031            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12032                                               (zero_extend:V8DI (match_dup 3)))
12033                                   (parallel [(const_int 2)])))
12034            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12035                                               (zero_extend:V8DI (match_dup 3)))
12036                                   (parallel [(const_int 3)])))))
12037          (plus:DI
12038           (plus:DI
12039            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12040                                               (zero_extend:V8DI (match_dup 3)))
12041                                   (parallel [(const_int 4)])))
12042            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12043                                               (zero_extend:V8DI (match_dup 3)))
12044                                   (parallel [(const_int 5)]))))
12045           (plus:DI
12046            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12047                                               (zero_extend:V8DI (match_dup 3)))
12048                                   (parallel [(const_int 6)])))
12049            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12050                                               (zero_extend:V8DI (match_dup 3)))
12051                                   (parallel [(const_int 7)])))))))]
12052   "TARGET_SHMEDIA"
12053   "msad.ubq     %N2, %N3, %0"
12054   [(set_attr "type" "mac_media")])
12055
12056 (define_insn "mshalds_l"
12057   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12058         (ss_truncate:V2SI
12059          (ashift:V2DI
12060           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12061           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12062                   (const_int 31)))))]
12063   "TARGET_SHMEDIA"
12064   "mshalds.l    %1, %2, %0"
12065   [(set_attr "type" "mcmp_media")
12066    (set_attr "highpart" "depend")])
12067
12068 (define_insn "mshalds_w"
12069   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12070         (ss_truncate:V4HI
12071          (ashift:V4SI
12072           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12073           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12074                   (const_int 15)))))]
12075   "TARGET_SHMEDIA"
12076   "mshalds.w    %1, %2, %0"
12077   [(set_attr "type" "mcmp_media")
12078    (set_attr "highpart" "depend")])
12079
12080 (define_insn "ashrv2si3"
12081   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12082         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12083                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12084   "TARGET_SHMEDIA"
12085   "mshard.l     %1, %2, %0"
12086   [(set_attr "type" "arith_media")
12087    (set_attr "highpart" "depend")])
12088
12089 (define_insn "ashrv4hi3"
12090   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12091         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12092                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12093   "TARGET_SHMEDIA"
12094   "mshard.w     %1, %2, %0"
12095   [(set_attr "type" "arith_media")
12096    (set_attr "highpart" "depend")])
12097
12098 (define_insn "mshards_q"
12099   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12100         (ss_truncate:HI
12101          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12102                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12103   "TARGET_SHMEDIA"
12104   "mshards.q    %1, %N2, %0"
12105   [(set_attr "type" "mcmp_media")])
12106
12107 (define_expand "mshfhi_b"
12108   [(match_operand:V8QI 0 "arith_reg_dest" "")
12109    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12110    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12111   "TARGET_SHMEDIA"
12112   "
12113 {
12114   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12115              (operands[0], operands[1], operands[2]));
12116   DONE;
12117 }")
12118
12119 (define_expand "mshflo_b"
12120   [(match_operand:V8QI 0 "arith_reg_dest" "")
12121    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12122    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12123   "TARGET_SHMEDIA"
12124   "
12125 {
12126   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12127              (operands[0], operands[1], operands[2]));
12128   DONE;
12129 }")
12130
12131 (define_insn "mshf4_b"
12132   [(set
12133     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12134     (vec_select:V8QI
12135      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12136                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12137      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12138                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12139   "TARGET_SHMEDIA"
12140   "* return (TARGET_LITTLE_ENDIAN
12141              ? \"mshfhi.b       %N1, %N2, %0\"
12142              : \"mshflo.b       %N1, %N2, %0\");"
12143   [(set_attr "type" "arith_media")
12144    (set (attr "highpart")
12145         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12146          (const_string "user")))])
12147
12148 (define_insn "mshf0_b"
12149   [(set
12150     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12151     (vec_select:V8QI
12152      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12153                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12154      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12155                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12156   "TARGET_SHMEDIA"
12157   "* return (TARGET_LITTLE_ENDIAN
12158              ? \"mshflo.b       %N1, %N2, %0\"
12159              : \"mshfhi.b       %N1, %N2, %0\");"
12160   [(set_attr "type" "arith_media")
12161    (set (attr "highpart")
12162         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12163          (const_string "user")))])
12164
12165 (define_expand "mshfhi_l"
12166   [(match_operand:V2SI 0 "arith_reg_dest" "")
12167    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12168    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12169   "TARGET_SHMEDIA"
12170   "
12171 {
12172   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12173              (operands[0], operands[1], operands[2]));
12174   DONE;
12175 }")
12176
12177 (define_expand "mshflo_l"
12178   [(match_operand:V2SI 0 "arith_reg_dest" "")
12179    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12180    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12181   "TARGET_SHMEDIA"
12182   "
12183 {
12184   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12185              (operands[0], operands[1], operands[2]));
12186   DONE;
12187 }")
12188
12189 (define_insn "mshf4_l"
12190   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12191         (vec_select:V2SI
12192          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12193                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12194          (parallel [(const_int 1) (const_int 3)])))]
12195   "TARGET_SHMEDIA"
12196   "* return (TARGET_LITTLE_ENDIAN
12197              ? \"mshfhi.l       %N1, %N2, %0\"
12198              : \"mshflo.l       %N1, %N2, %0\");"
12199   [(set_attr "type" "arith_media")
12200    (set (attr "highpart")
12201         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12202          (const_string "user")))])
12203
12204 (define_insn "mshf0_l"
12205   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12206         (vec_select:V2SI
12207          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12208                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12209          (parallel [(const_int 0) (const_int 2)])))]
12210   "TARGET_SHMEDIA"
12211   "* return (TARGET_LITTLE_ENDIAN
12212              ? \"mshflo.l       %N1, %N2, %0\"
12213              : \"mshfhi.l       %N1, %N2, %0\");"
12214   [(set_attr "type" "arith_media")
12215    (set (attr "highpart")
12216         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12217          (const_string "user")))])
12218
12219 (define_expand "mshfhi_w"
12220   [(match_operand:V4HI 0 "arith_reg_dest" "")
12221    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12222    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12223   "TARGET_SHMEDIA"
12224   "
12225 {
12226   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12227              (operands[0], operands[1], operands[2]));
12228   DONE;
12229 }")
12230
12231 (define_expand "mshflo_w"
12232   [(match_operand:V4HI 0 "arith_reg_dest" "")
12233    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12234    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12235   "TARGET_SHMEDIA"
12236   "
12237 {
12238   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12239              (operands[0], operands[1], operands[2]));
12240   DONE;
12241 }")
12242
12243 (define_insn "mshf4_w"
12244   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12245         (vec_select:V4HI
12246          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12247                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12248          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12249   "TARGET_SHMEDIA"
12250   "* return (TARGET_LITTLE_ENDIAN
12251              ? \"mshfhi.w       %N1, %N2, %0\"
12252              : \"mshflo.w       %N1, %N2, %0\");"
12253   [(set_attr "type" "arith_media")
12254    (set (attr "highpart")
12255         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12256          (const_string "user")))])
12257
12258 (define_insn "mshf0_w"
12259   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12260         (vec_select:V4HI
12261          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12262                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12263          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12264   "TARGET_SHMEDIA"
12265   "* return (TARGET_LITTLE_ENDIAN
12266              ? \"mshflo.w       %N1, %N2, %0\"
12267              : \"mshfhi.w       %N1, %N2, %0\");"
12268   [(set_attr "type" "arith_media")
12269    (set (attr "highpart")
12270         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12271          (const_string "user")))])
12272
12273 (define_insn "mshflo_w_x"
12274   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12275         (vec_select:V4HI
12276          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12277                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12278          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12279   "TARGET_SHMEDIA"
12280   "mshflo.w     %N1, %N2, %0"
12281   [(set_attr "type" "arith_media")
12282    (set_attr "highpart" "ignore")])
12283
12284 /* These are useful to expand ANDs and as combiner patterns.  */
12285 (define_insn_and_split "mshfhi_l_di"
12286   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12287         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12288                              (const_int 32))
12289                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12290                         (const_int -4294967296))))]
12291   "TARGET_SHMEDIA"
12292   "@
12293         mshfhi.l        %N1, %N2, %0
12294         #"
12295   "TARGET_SHMEDIA && reload_completed
12296    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12297   [(set (match_dup 3) (match_dup 4))
12298    (set (match_dup 5) (match_dup 6))]
12299   "
12300 {
12301   operands[3] = gen_lowpart (SImode, operands[0]);
12302   operands[4] = gen_highpart (SImode, operands[1]);
12303   operands[5] = gen_highpart (SImode, operands[0]);
12304   operands[6] = gen_highpart (SImode, operands[2]);
12305 }"
12306   [(set_attr "type" "arith_media")])
12307
12308 (define_insn "*mshfhi_l_di_rev"
12309   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12310         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12311                         (const_int -4294967296))
12312                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12313                              (const_int 32))))]
12314   "TARGET_SHMEDIA"
12315   "mshfhi.l     %N2, %N1, %0"
12316   [(set_attr "type" "arith_media")])
12317
12318 (define_split
12319   [(set (match_operand:DI 0 "arith_reg_dest" "")
12320         (ior:DI (zero_extend:DI (match_operand:SI 1
12321                                               "extend_reg_or_0_operand" ""))
12322                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12323                         (const_int -4294967296))))
12324    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12325   "TARGET_SHMEDIA"
12326   [(const_int 0)]
12327   "
12328 {
12329   emit_insn (gen_ashldi3_media (operands[3],
12330                                 simplify_gen_subreg (DImode, operands[1],
12331                                                      SImode, 0),
12332                                 GEN_INT (32)));
12333   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12334   DONE;
12335 }")
12336
12337 (define_insn "mshflo_l_di"
12338   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12339         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12340                         (const_int 4294967295))
12341                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12342                            (const_int 32))))]
12343
12344   "TARGET_SHMEDIA"
12345   "mshflo.l     %N1, %N2, %0"
12346   [(set_attr "type" "arith_media")
12347    (set_attr "highpart" "ignore")])
12348
12349 (define_insn "*mshflo_l_di_rev"
12350   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12351         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12352                            (const_int 32))
12353                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12354                         (const_int 4294967295))))]
12355
12356   "TARGET_SHMEDIA"
12357   "mshflo.l     %N2, %N1, %0"
12358   [(set_attr "type" "arith_media")
12359    (set_attr "highpart" "ignore")])
12360
12361 ;; Combiner pattern for trampoline initialization.
12362 (define_insn_and_split "*double_shori"
12363   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12364         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12365                            (const_int 32))
12366                 (match_operand:DI 2 "const_int_operand" "n")))]
12367   "TARGET_SHMEDIA
12368    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
12369   "#"
12370   "rtx_equal_p (operands[0], operands[1])"
12371   [(const_int 0)]
12372   "
12373 {
12374   HOST_WIDE_INT v = INTVAL (operands[2]);
12375
12376   emit_insn (gen_shori_media (operands[0], operands[0],
12377              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
12378   emit_insn (gen_shori_media (operands[0], operands[0],
12379                               gen_int_mode (v, HImode)));
12380   DONE;
12381 }"
12382   [(set_attr "highpart" "ignore")])
12383
12384
12385 (define_insn "*mshflo_l_di_x"
12386   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12387         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12388                                  "rZ"))
12389                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12390                            (const_int 32))))]
12391
12392   "TARGET_SHMEDIA"
12393   "mshflo.l     %N1, %N2, %0"
12394   [(set_attr "type" "arith_media")
12395    (set_attr "highpart" "ignore")])
12396
12397 (define_insn_and_split "concat_v2sf"
12398   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12399 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12400         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12401                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12402
12403   "TARGET_SHMEDIA"
12404   "@
12405         mshflo.l        %N1, %N2, %0
12406         #
12407         #"
12408   "TARGET_SHMEDIA && reload_completed
12409    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12410   [(set (match_dup 3) (match_dup 1))
12411    (set (match_dup 4) (match_dup 2))]
12412   "
12413 {
12414   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12415   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12416 }"
12417   [(set_attr "type" "arith_media")
12418    (set_attr "highpart" "ignore")])
12419
12420 (define_insn "*mshflo_l_di_x_rev"
12421   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12422         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12423                            (const_int 32))
12424                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12425
12426   "TARGET_SHMEDIA"
12427   "mshflo.l     %N2, %N1, %0"
12428   [(set_attr "type" "arith_media")
12429    (set_attr "highpart" "ignore")])
12430
12431 (define_insn "ashlv2si3"
12432   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12433         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12434                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12435   "TARGET_SHMEDIA"
12436   "mshlld.l     %1, %2, %0"
12437   [(set_attr "type" "arith_media")
12438    (set_attr "highpart" "depend")])
12439
12440 (define_split
12441   [(set (match_operand 0 "any_register_operand" "")
12442         (match_operator 3 "shift_operator"
12443           [(match_operand 1 "any_register_operand" "")
12444            (match_operand 2 "shift_count_reg_operand" "")]))]
12445   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12446   [(set (match_dup 0) (match_dup 3))]
12447   "
12448 {
12449   rtx count = operands[2];
12450   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12451
12452   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12453          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12454          || GET_CODE (count) == TRUNCATE)
12455     count = XEXP (count, 0);
12456   inner_mode = GET_MODE (count);
12457   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12458                                subreg_lowpart_offset (outer_mode, inner_mode));
12459   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12460                                 operands[1], count);
12461 }")
12462
12463 (define_insn "ashlv4hi3"
12464   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12465         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12466                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12467   "TARGET_SHMEDIA"
12468   "mshlld.w     %1, %2, %0"
12469   [(set_attr "type" "arith_media")
12470    (set_attr "highpart" "depend")])
12471
12472 (define_insn "lshrv2si3"
12473   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12474         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12475                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12476   "TARGET_SHMEDIA"
12477   "mshlrd.l     %1, %2, %0"
12478   [(set_attr "type" "arith_media")
12479    (set_attr "highpart" "depend")])
12480
12481 (define_insn "lshrv4hi3"
12482   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12483         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12484                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12485   "TARGET_SHMEDIA"
12486   "mshlrd.w     %1, %2, %0"
12487   [(set_attr "type" "arith_media")
12488    (set_attr "highpart" "depend")])
12489
12490 (define_insn "subv2si3"
12491   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12492         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12493                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12494   "TARGET_SHMEDIA"
12495   "msub.l       %N1, %2, %0"
12496   [(set_attr "type" "arith_media")
12497    (set_attr "highpart" "depend")])
12498
12499 (define_insn "subv4hi3"
12500   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12501         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12502                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12503   "TARGET_SHMEDIA"
12504   "msub.w       %N1, %2, %0"
12505   [(set_attr "type" "arith_media")
12506    (set_attr "highpart" "depend")])
12507
12508 (define_insn_and_split "subv2hi3"
12509   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12510         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12511                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12512   "TARGET_SHMEDIA"
12513   "#"
12514   "TARGET_SHMEDIA"
12515   [(const_int 0)]
12516   "
12517 {
12518   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12519   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12520   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12521   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12522   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12523
12524   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12525   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12526   DONE;
12527 }"
12528   [(set_attr "highpart" "must_split")])
12529
12530 (define_insn "sssubv2si3"
12531   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12532         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12533                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12534   "TARGET_SHMEDIA"
12535   "msubs.l      %N1, %2, %0"
12536   [(set_attr "type" "mcmp_media")
12537    (set_attr "highpart" "depend")])
12538
12539 (define_insn "ussubv8qi3"
12540   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12541         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12542                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12543   "TARGET_SHMEDIA"
12544   "msubs.ub     %N1, %2, %0"
12545   [(set_attr "type" "mcmp_media")
12546    (set_attr "highpart" "depend")])
12547
12548 (define_insn "sssubv4hi3"
12549   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12550         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12551                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12552   "TARGET_SHMEDIA"
12553   "msubs.w      %N1, %2, %0"
12554   [(set_attr "type" "mcmp_media")
12555    (set_attr "highpart" "depend")])
12556
12557 ;; Floating Point Intrinsics
12558
12559 (define_insn "fcosa_s"
12560   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12561         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12562                    UNSPEC_FCOSA))]
12563   "TARGET_SHMEDIA"
12564   "fcosa.s      %1, %0"
12565   [(set_attr "type" "atrans_media")])
12566
12567 (define_insn "fsina_s"
12568   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12569         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12570                    UNSPEC_FSINA))]
12571   "TARGET_SHMEDIA"
12572   "fsina.s      %1, %0"
12573   [(set_attr "type" "atrans_media")])
12574
12575 (define_insn "fipr"
12576   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12577         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12578                                                     "fp_arith_reg_operand" "f")
12579                                                    (match_operand:V4SF 2
12580                                                     "fp_arith_reg_operand" "f"))
12581                                          (parallel [(const_int 0)]))
12582                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12583                                          (parallel [(const_int 1)])))
12584                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12585                                          (parallel [(const_int 2)]))
12586                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12587                                          (parallel [(const_int 3)])))))]
12588   "TARGET_SHMEDIA"
12589   "fipr.s       %1, %2, %0"
12590   [(set_attr "type" "fparith_media")])
12591
12592 (define_insn "fsrra_s"
12593   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12594         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12595                    UNSPEC_FSRRA))]
12596   "TARGET_SHMEDIA"
12597   "fsrra.s      %1, %0"
12598   [(set_attr "type" "atrans_media")])
12599
12600 (define_insn "ftrv"
12601   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12602         (plus:V4SF
12603          (plus:V4SF
12604           (mult:V4SF
12605            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12606                             (parallel [(const_int 0) (const_int 5)
12607                                        (const_int 10) (const_int 15)]))
12608            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12609           (mult:V4SF
12610            (vec_select:V4SF (match_dup 1)
12611                             (parallel [(const_int 4) (const_int 9)
12612                                        (const_int 14) (const_int 3)]))
12613            (vec_select:V4SF (match_dup 2)
12614                             (parallel [(const_int 1) (const_int 2)
12615                                        (const_int 3) (const_int 0)]))))
12616          (plus:V4SF
12617           (mult:V4SF
12618            (vec_select:V4SF (match_dup 1)
12619                             (parallel [(const_int 8) (const_int 13)
12620                                        (const_int 2) (const_int 7)]))
12621            (vec_select:V4SF (match_dup 2)
12622                             (parallel [(const_int 2) (const_int 3)
12623                                        (const_int 0) (const_int 1)])))
12624           (mult:V4SF
12625            (vec_select:V4SF (match_dup 1)
12626                             (parallel [(const_int 12) (const_int 1)
12627                                        (const_int 6) (const_int 11)]))
12628            (vec_select:V4SF (match_dup 2)
12629                             (parallel [(const_int 3) (const_int 0)
12630                                        (const_int 1) (const_int 2)]))))))]
12631   "TARGET_SHMEDIA"
12632   "ftrv.s %1, %2, %0"
12633   [(set_attr "type" "fparith_media")])
12634
12635 (define_insn "ldhi_l"
12636   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12637         (zero_extract:SI
12638          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12639                                   (const_int 3))
12640                           (const_int -3)))
12641          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12642          (const_int 0)))]
12643   "TARGET_SHMEDIA32"
12644   "ldhi.l       %U1, %0"
12645   [(set_attr "type" "load_media")])
12646
12647 (define_insn "ldhi_q"
12648   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12649         (zero_extract:DI
12650          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12651                                   (const_int 7))
12652                           (const_int -7)))
12653          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12654          (const_int 0)))]
12655   "TARGET_SHMEDIA32"
12656   "ldhi.q       %U1, %0"
12657   [(set_attr "type" "load_media")])
12658
12659 (define_insn_and_split "*ldhi_q_comb0"
12660   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12661         (zero_extract:DI
12662          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12663                                             "register_operand" "r")
12664                                            (match_operand:SI 2
12665                                             "ua_offset" "I06"))
12666                                   (const_int 7))
12667                           (const_int -7)))
12668          (plus:SI (and:SI (match_dup 1) (const_int 7))
12669                   (const_int 1))
12670          (const_int 0)))]
12671   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12672   "#"
12673   ""
12674   [(pc)]
12675   "emit_insn (gen_ldhi_q (operands[0],
12676                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12677    DONE;")
12678
12679
12680 (define_insn_and_split "*ldhi_q_comb1"
12681   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12682         (zero_extract:DI
12683          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12684                                             "register_operand" "r")
12685                                            (match_operand:SI 2
12686                                             "ua_offset" "I06"))
12687                                   (const_int 7))
12688                           (const_int -7)))
12689          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12690                                                    "ua_offset" "I06"))
12691                           (const_int 7))
12692                   (const_int 1))
12693          (const_int 0)))]
12694   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12695    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12696   "#"
12697   ""
12698   [(pc)]
12699   "emit_insn (gen_ldhi_q (operands[0],
12700                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12701    DONE;")
12702
12703
12704 (define_insn "ldlo_l"
12705   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12706         (zero_extract:SI
12707          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12708                          (const_int -4)))
12709          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12710          (and:SI (match_dup 1) (const_int 3))))]
12711   "TARGET_SHMEDIA32"
12712   "ldlo.l       %U1, %0"
12713   [(set_attr "type" "load_media")])
12714
12715 (define_insn "ldlo_q"
12716   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12717         (zero_extract:DI
12718          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12719                          (const_int -8)))
12720          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12721          (and:SI (match_dup 1) (const_int 7))))]
12722   "TARGET_SHMEDIA32"
12723   "ldlo.q       %U1, %0"
12724   [(set_attr "type" "load_media")])
12725
12726 (define_insn_and_split "*ldlo_q_comb0"
12727   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12728         (zero_extract:DI
12729          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12730                                   (match_operand:SI 2 "ua_offset" "I06"))
12731                          (const_int -8)))
12732          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12733          (and:SI (match_dup 1) (const_int 7))))]
12734   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12735   "#"
12736   ""
12737   [(pc)]
12738   "emit_insn (gen_ldlo_q (operands[0],
12739                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12740    DONE;")
12741
12742 (define_insn_and_split "*ldlo_q_comb1"
12743   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12744         (zero_extract:DI
12745          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12746                                   (match_operand:SI 2 "ua_offset" "I06"))
12747                          (const_int -8)))
12748          (minus:SI (const_int 8)
12749                    (and:SI (plus:SI (match_dup 1)
12750                                     (match_operand:SI 3 "ua_offset" "I06"))
12751                            (const_int 7)))
12752          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12753   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12754    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12755   "#"
12756   ""
12757   [(pc)]
12758   "emit_insn (gen_ldlo_q (operands[0],
12759                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12760    DONE;")
12761
12762 (define_insn "sthi_l"
12763   [(set (zero_extract:SI
12764          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12765                                   (const_int 3))
12766                           (const_int -3)))
12767          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12768          (const_int 0))
12769         (match_operand:SI 1 "arith_reg_operand" "r"))]
12770   "TARGET_SHMEDIA32"
12771   "sthi.l       %U0, %1"
12772   [(set_attr "type" "ustore_media")])
12773
12774 ;; All unaligned stores are considered to be 'narrow' because they typically
12775 ;; operate on less that a quadword, and when they operate on a full quadword,
12776 ;; the vanilla store high / store low sequence will cause a stall if not
12777 ;; scheduled apart.
12778 (define_insn "sthi_q"
12779   [(set (zero_extract:DI
12780          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12781                                   (const_int 7))
12782                           (const_int -7)))
12783          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12784          (const_int 0))
12785         (match_operand:DI 1 "arith_reg_operand" "r"))]
12786   "TARGET_SHMEDIA32"
12787   "sthi.q       %U0, %1"
12788   [(set_attr "type" "ustore_media")])
12789
12790 (define_insn_and_split "*sthi_q_comb0"
12791   [(set (zero_extract:DI
12792          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12793                                             "register_operand" "r")
12794                                            (match_operand:SI 1 "ua_offset"
12795                                             "I06"))
12796                                   (const_int 7))
12797                           (const_int -7)))
12798          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12799          (const_int 0))
12800         (match_operand:DI 2 "arith_reg_operand" "r"))]
12801   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12802   "#"
12803   ""
12804   [(pc)]
12805   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12806                           operands[2]));
12807    DONE;")
12808
12809 (define_insn_and_split "*sthi_q_comb1"
12810   [(set (zero_extract:DI
12811          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12812                                             "register_operand" "r")
12813                                            (match_operand:SI 1 "ua_offset"
12814                                             "I06"))
12815                                   (const_int 7))
12816                           (const_int -7)))
12817          (plus:SI (and:SI (plus:SI (match_dup 0)
12818                                    (match_operand:SI 2 "ua_offset" "I06"))
12819                           (const_int 7))
12820                   (const_int 1))
12821          (const_int 0))
12822         (match_operand:DI 3 "arith_reg_operand" "r"))]
12823   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12824    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12825   "#"
12826   ""
12827   [(pc)]
12828   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12829                           operands[3]));
12830    DONE;")
12831
12832 ;; This is highpart user because the address is used as full 64 bit.
12833 (define_insn "stlo_l"
12834   [(set (zero_extract:SI
12835          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12836                          (const_int -4)))
12837          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12838          (and:SI (match_dup 0) (const_int 3)))
12839         (match_operand:SI 1 "arith_reg_operand" "r"))]
12840   "TARGET_SHMEDIA32"
12841   "stlo.l       %U0, %1"
12842   [(set_attr "type" "ustore_media")])
12843
12844 (define_insn "stlo_q"
12845   [(set (zero_extract:DI
12846          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12847                          (const_int -8)))
12848          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12849          (and:SI (match_dup 0) (const_int 7)))
12850         (match_operand:DI 1 "arith_reg_operand" "r"))]
12851   "TARGET_SHMEDIA32"
12852   "stlo.q       %U0, %1"
12853   [(set_attr "type" "ustore_media")])
12854
12855 (define_insn_and_split "*stlo_q_comb0"
12856   [(set (zero_extract:DI
12857          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12858                                   (match_operand:SI 1 "ua_offset" "I06"))
12859                          (const_int -8)))
12860          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12861          (and:SI (match_dup 0) (const_int 7)))
12862         (match_operand:DI 2 "arith_reg_operand" "r"))]
12863   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12864   "#"
12865   ""
12866   [(pc)]
12867   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12868                           operands[2]));
12869    DONE;")
12870
12871 (define_insn_and_split "*stlo_q_comb1"
12872   [(set (zero_extract:DI
12873          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12874                                   (match_operand:SI 1 "ua_offset" "I06"))
12875                          (const_int -8)))
12876          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12877                                                   (match_operand:SI 2
12878                                                    "ua_offset" "I06"))
12879                                          (const_int 7)))
12880          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12881         (match_operand:DI 3 "arith_reg_operand" "r"))]
12882   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12883   "#"
12884   ""
12885   [(pc)]
12886   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12887                           operands[3]));
12888    DONE;")
12889
12890 (define_insn "ldhi_l64"
12891   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12892         (zero_extract:SI
12893          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12894                                   (const_int 3))
12895                           (const_int -3)))
12896          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12897          (const_int 0)))]
12898   "TARGET_SHMEDIA64"
12899   "ldhi.l       %U1, %0"
12900   [(set_attr "type" "load_media")])
12901
12902 (define_insn "ldhi_q64"
12903   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12904         (zero_extract:DI
12905          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12906                                   (const_int 7))
12907                           (const_int -7)))
12908          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12909          (const_int 0)))]
12910   "TARGET_SHMEDIA64"
12911   "ldhi.q       %U1, %0"
12912   [(set_attr "type" "load_media")])
12913
12914 (define_insn "ldlo_l64"
12915   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12916         (zero_extract:SI
12917          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12918                          (const_int -4)))
12919          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12920          (and:DI (match_dup 1) (const_int 3))))]
12921   "TARGET_SHMEDIA64"
12922   "ldlo.l       %U1, %0"
12923   [(set_attr "type" "load_media")])
12924
12925 (define_insn "ldlo_q64"
12926   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12927         (zero_extract:DI
12928          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12929                          (const_int -8)))
12930          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12931          (and:DI (match_dup 1) (const_int 7))))]
12932   "TARGET_SHMEDIA64"
12933   "ldlo.q       %U1, %0"
12934   [(set_attr "type" "load_media")])
12935
12936 (define_insn "sthi_l64"
12937   [(set (zero_extract:SI
12938          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12939                                   (const_int 3))
12940                           (const_int -3)))
12941          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12942          (const_int 0))
12943         (match_operand:SI 1 "arith_reg_operand" "r"))]
12944   "TARGET_SHMEDIA64"
12945   "sthi.l       %U0, %1"
12946   [(set_attr "type" "ustore_media")])
12947
12948 (define_insn "sthi_q64"
12949   [(set (zero_extract:DI
12950          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12951                                   (const_int 7))
12952                           (const_int -7)))
12953          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12954          (const_int 0))
12955         (match_operand:DI 1 "arith_reg_operand" "r"))]
12956   "TARGET_SHMEDIA64"
12957   "sthi.q       %U0, %1"
12958   [(set_attr "type" "ustore_media")])
12959
12960 (define_insn "stlo_l64"
12961   [(set (zero_extract:SI
12962          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12963                          (const_int -4)))
12964          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12965          (and:DI (match_dup 0) (const_int 3)))
12966         (match_operand:SI 1 "arith_reg_operand" "r"))]
12967   "TARGET_SHMEDIA64"
12968   "stlo.l       %U0, %1"
12969   [(set_attr "type" "ustore_media")])
12970
12971 (define_insn "stlo_q64"
12972   [(set (zero_extract:DI
12973          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12974                          (const_int -8)))
12975          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12976          (and:DI (match_dup 0) (const_int 7)))
12977         (match_operand:DI 1 "arith_reg_operand" "r"))]
12978   "TARGET_SHMEDIA64"
12979   "stlo.q       %U0, %1"
12980   [(set_attr "type" "ustore_media")])
12981
12982 (define_insn "nsb"
12983   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12984         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12985                    UNSPEC_NSB))]
12986   "TARGET_SHMEDIA"
12987   "nsb  %1, %0"
12988   [(set_attr "type" "arith_media")])
12989
12990 (define_insn "nsbsi"
12991   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12992         (zero_extend:SI
12993          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12994                     UNSPEC_NSB)))]
12995   "TARGET_SHMEDIA"
12996   "nsb  %1, %0"
12997   [(set_attr "type" "arith_media")])
12998
12999 (define_insn "nsbdi"
13000   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13001         (zero_extend:DI
13002          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13003                     UNSPEC_NSB)))]
13004   "TARGET_SHMEDIA"
13005   "nsb  %1, %0"
13006   [(set_attr "type" "arith_media")])
13007
13008 (define_expand "ffsdi2"
13009   [(set (match_operand:DI 0 "arith_reg_dest" "")
13010         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13011   "TARGET_SHMEDIA"
13012   "
13013 {
13014   rtx scratch = gen_reg_rtx (DImode);
13015   rtx last;
13016
13017   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13018   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13019   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13020   emit_insn (gen_nsbdi (scratch, scratch));
13021   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13022   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13023   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13024   REG_NOTES (last)
13025     = gen_rtx_EXPR_LIST (REG_EQUAL,
13026                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13027   DONE;
13028 }")
13029
13030 (define_expand "ffssi2"
13031   [(set (match_operand:SI 0 "arith_reg_dest" "")
13032         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13033   "TARGET_SHMEDIA"
13034   "
13035 {
13036   rtx scratch = gen_reg_rtx (SImode);
13037   rtx discratch = gen_reg_rtx (DImode);
13038   rtx last;
13039
13040   emit_insn (gen_adddi3 (discratch,
13041                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13042                          constm1_rtx));
13043   emit_insn (gen_andcdi3 (discratch,
13044                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13045                           discratch));
13046   emit_insn (gen_nsbsi (scratch, discratch));
13047   last = emit_insn (gen_subsi3 (operands[0],
13048                                 force_reg (SImode, GEN_INT (63)), scratch));
13049   REG_NOTES (last)
13050     = gen_rtx_EXPR_LIST (REG_EQUAL,
13051                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13052   DONE;
13053 }")
13054
13055 (define_insn "byterev"
13056   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13057         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13058                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13059                                     (const_int 4) (const_int 3) (const_int 2)
13060                                     (const_int 1) (const_int 0)])))]
13061   "TARGET_SHMEDIA"
13062   "byterev      %1, %0"
13063   [(set_attr "type" "arith_media")])
13064
13065 (define_insn "*prefetch_media"
13066   [(prefetch (match_operand:QI 0 "address_operand" "p")
13067              (match_operand:SI 1 "const_int_operand" "n")
13068              (match_operand:SI 2 "const_int_operand" "n"))]
13069   "TARGET_SHMEDIA"
13070   "*
13071 {
13072   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13073   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13074   return \"\";
13075 }"
13076   [(set_attr "type" "other")])
13077
13078 (define_insn "*prefetch_i4"
13079   [(prefetch (match_operand:SI 0 "register_operand" "r")
13080              (match_operand:SI 1 "const_int_operand" "n")
13081              (match_operand:SI 2 "const_int_operand" "n"))]
13082   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13083   "*
13084 {
13085   return \"pref @%0\";
13086 }"
13087   [(set_attr "type" "other")])
13088
13089 (define_expand "prefetch"
13090   [(prefetch (match_operand 0 "address_operand" "p")
13091              (match_operand:SI 1 "const_int_operand" "n")
13092              (match_operand:SI 2 "const_int_operand" "n"))]
13093   "TARGET_HARD_SH4 || TARGET_SH5"
13094   "
13095 {
13096   if (GET_MODE (operands[0]) != Pmode
13097       || GET_CODE (operands[1]) != CONST_INT
13098       || GET_CODE (operands[2]) != CONST_INT)
13099     FAIL;
13100   if (! TARGET_SHMEDIA)
13101     operands[0] = force_reg (Pmode, operands[0]);
13102 }")
13103
13104 (define_insn "alloco_i"
13105   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13106         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13107   "TARGET_SHMEDIA32"
13108   "*
13109 {
13110   rtx xops[2];
13111
13112   if (GET_CODE (operands[0]) == PLUS)
13113     {
13114       xops[0] = XEXP (operands[0], 0);
13115       xops[1] = XEXP (operands[0], 1);
13116     }
13117   else
13118     {
13119       xops[0] = operands[0];
13120       xops[1] = const0_rtx;
13121     }
13122   output_asm_insn (\"alloco   %0, %1\", xops);
13123   return \"\";
13124 }"
13125   [(set_attr "type" "other")])
13126
13127 (define_split
13128   [(set (match_operand 0 "any_register_operand" "")
13129         (match_operand 1 "" ""))]
13130   "TARGET_SHMEDIA && reload_completed"
13131   [(set (match_dup 0) (match_dup 1))]
13132   "
13133 {
13134   int n_changes = 0;
13135
13136   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13137   if (!n_changes)
13138     FAIL;
13139 }")
13140
13141 ; Stack Protector Patterns
13142
13143 (define_expand "stack_protect_set"
13144   [(set (match_operand 0 "memory_operand" "")
13145         (match_operand 1 "memory_operand" ""))]
13146   ""
13147 {
13148   if (TARGET_SHMEDIA)
13149     {
13150       if (TARGET_SHMEDIA64)
13151         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13152       else
13153         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13154     }
13155   else
13156     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13157
13158   DONE;
13159 })
13160
13161 (define_insn "stack_protect_set_si"
13162   [(set (match_operand:SI 0 "memory_operand" "=m")
13163         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13164    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13165   "!TARGET_SHMEDIA"
13166   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13167   [(set_attr "type" "other")
13168    (set_attr "length" "6")])
13169
13170 (define_insn "stack_protect_set_si_media"
13171   [(set (match_operand:SI 0 "memory_operand" "=m")
13172         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13173    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13174   "TARGET_SHMEDIA"
13175   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13176   [(set_attr "type" "other")
13177    (set_attr "length" "12")])
13178
13179 (define_insn "stack_protect_set_di_media"
13180   [(set (match_operand:DI 0 "memory_operand" "=m")
13181         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13182    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13183   "TARGET_SHMEDIA64"
13184   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13185   [(set_attr "type" "other")
13186    (set_attr "length" "12")])
13187
13188 (define_expand "stack_protect_test"
13189   [(match_operand 0 "memory_operand" "")
13190    (match_operand 1 "memory_operand" "")
13191    (match_operand 2 "" "")]
13192   ""
13193 {
13194   if (TARGET_SHMEDIA)
13195     {
13196       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13197
13198       if (TARGET_SHMEDIA64)
13199         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13200                                                     operands[1]));
13201       else
13202         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13203                                                     operands[1]));
13204
13205       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13206     }
13207   else
13208     {
13209       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13210       emit_jump_insn (gen_branch_true (operands[2]));
13211     }
13212
13213   DONE;
13214 })
13215
13216 (define_insn "stack_protect_test_si"
13217   [(set (reg:SI T_REG)
13218         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13219                     (match_operand:SI 1 "memory_operand" "m")]
13220                    UNSPEC_SP_TEST))
13221   (set (match_scratch:SI 2 "=&r") (const_int 0))
13222   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13223   "!TARGET_SHMEDIA"
13224   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13225   [(set_attr "type" "other")
13226    (set_attr "length" "10")])
13227
13228 (define_insn "stack_protect_test_si_media"
13229   [(set (match_operand:SI 0 "register_operand" "=&r")
13230         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13231                     (match_operand:SI 2 "memory_operand" "m")]
13232                    UNSPEC_SP_TEST))
13233   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13234   "TARGET_SHMEDIA"
13235   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13236   [(set_attr "type" "other")
13237    (set_attr "length" "16")])
13238
13239 (define_insn "stack_protect_test_di_media"
13240   [(set (match_operand:DI 0 "register_operand" "=&r")
13241         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13242                     (match_operand:DI 2 "memory_operand" "m")]
13243                    UNSPEC_SP_TEST))
13244   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13245   "TARGET_SHMEDIA64"
13246   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13247   [(set_attr "type" "other")
13248    (set_attr "length" "16")])