* Merge from mainline
[official-gcc.git] / gcc / config / sh / sh.md
blobff36d9a932aedf5e00e82e2159abb86b5e55aac3
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
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.
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.
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.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
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
43 ;; Special constraints for SH machine description:
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
50 ;; Special formats used for outputting SH instructions:
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
60 ;; Special predicates:
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
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
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)
82   (FPSCR_REG    151)
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
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)
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
116   (XD0_REG      136)
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)
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)
166 ;; -------------------------------------------------------------------------
167 ;; Attributes
168 ;; -------------------------------------------------------------------------
170 ;; Target CPU.
172 (define_attr "cpu"
173  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
174   (const (symbol_ref "sh_cpu_attr")))
176 (define_attr "endian" "big,little"
177  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
178                       (const_string "little") (const_string "big"))))
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"))))
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"))))
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.
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"))
267 ;; We define a new attribute namely "insn_class".We use
268 ;; this for the DFA based pipeline description.
270 ;; mt_group      SH4 "mt" group instructions.
272 ;; ex_group      SH4 "ex" group instructions.
274 ;; ls_group      SH4 "ls" group instructions.
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.
291 ;; Indicate what precision must be selected in fpscr for this insn, if any.
293 (define_attr "fp_mode" "single,double,none" (const_string "none"))
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"))
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.
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.
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.
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")))
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")))
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")))
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")))
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")))
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.
394 ; All other instructions are two bytes long by default.
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))))
443 ;; DFA descriptions for the pipelines
445 (include "sh1.md")
446 (include "shmedia.md")
447 (include "sh4.md")
449 (include "predicates.md")
451 ;; Definitions for filling delay slots
453 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
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")))
462 (define_attr "interrupt_function" "no,yes"
463   (const (symbol_ref "current_function_interrupt")))
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")))
472 (define_attr "cond_delay_slot" "yes,no"
473   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
474          ] (const_string "no")))
476 (define_attr "is_sfunc" ""
477   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
479 (define_attr "is_mac_media" ""
480   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
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")))
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")))
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")))
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")))
511 (define_attr "highpart" "user, ignore, extend, depend, must_split"
512   (const_string "user"))
514 (define_delay
515   (eq_attr "needs_delay_slot" "yes")
516   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
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.
523 ;; Since a normal return (rts) implicitly uses the PR register,
524 ;; we can't allow PR register loads in an rts delay slot.
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)])
536 ;; Since a call implicitly uses the PR register, we can't allow
537 ;; a PR register store in a jsr delay slot.
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)])
544 ;; Say that we have annulled true branches, since this gives smaller and
545 ;; faster code when branches are predicted as not taken.
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.
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)])
559 ;; -------------------------------------------------------------------------
560 ;; SImode signed integer comparisons
561 ;; -------------------------------------------------------------------------
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")])
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.
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")])
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")])
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")])
609 ;; -------------------------------------------------------------------------
610 ;; SImode unsigned integer comparisons
611 ;; -------------------------------------------------------------------------
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")])
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")])
629 ;; We save the compare operands in the cmpxx patterns and use them when
630 ;; we generate the branch.
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   "
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;
647 ;; -------------------------------------------------------------------------
648 ;; DImode signed integer comparisons
649 ;; -------------------------------------------------------------------------
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.
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")])
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")])
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   "
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 ();
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")])
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")])
729 ;; -------------------------------------------------------------------------
730 ;; DImode unsigned integer comparisons
731 ;; -------------------------------------------------------------------------
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
862 ;; We save the compare operands in the cmpxx patterns and use them when
863 ;; we generate the branch.
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   "
872   sh_compare_op0 = operands[0];
873   sh_compare_op1 = operands[1];
874   DONE;
876 ;; -------------------------------------------------------------------------
877 ;; Conditional move instructions
878 ;; -------------------------------------------------------------------------
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.
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")])
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")])
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   "
916   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
917                                 VOIDmode, operands[1], CONST0_RTX (DImode));
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   "")
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   "
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;
951       if (no_new_pseudos)
952         FAIL;
954       tmp = gen_reg_rtx (DImode);
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;
963         case NE:
964           emit_insn (gen_seq (tmp));
965           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
966           break;
968         case GT:
969           emit_insn (gen_sgt (tmp));
970           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
971           break;
973         case LT:
974           emit_insn (gen_slt (tmp));
975           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
976           break;
978         case GE:
979           emit_insn (gen_slt (tmp));
980           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
981           break;
983         case LE:
984           emit_insn (gen_sgt (tmp));
985           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
986           break;
988         case GTU:
989           emit_insn (gen_sgtu (tmp));
990           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
991           break;
993         case LTU:
994           emit_insn (gen_sltu (tmp));
995           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
996           break;
998         case GEU:
999           emit_insn (gen_sltu (tmp));
1000           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1001           break;
1003         case LEU:
1004           emit_insn (gen_sgtu (tmp));
1005           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1006           break;
1008         case UNORDERED:
1009           emit_insn (gen_sunordered (tmp));
1010           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1011           break;
1013         case ORDERED:
1014           emit_insn (gen_sunordered (tmp));
1015           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1016           break;
1018         case UNEQ:
1019         case UNGE:
1020         case UNGT:
1021         case UNLE:
1022         case UNLT:
1023         case LTGT:
1024           FAIL;
1026         default:
1027           gcc_unreachable ();
1028         }
1029     }
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")])
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")])
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   "
1067   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1068                                 VOIDmode, operands[1], CONST0_RTX (SImode));
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   "
1086   replace_rtx (operands[4], operands[0], operands[1]);
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   "
1108   rtx set1, set2;
1109   rtx replacements[4];
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;
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;
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   "
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;
1183 (define_insn "*movsicc_t_false"
1184   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1185         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1186                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1187                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1188   "TARGET_PRETEND_CMOVE
1189    && (arith_reg_operand (operands[1], SImode)
1190        || (immediate_operand (operands[1], SImode)
1191            && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1192   "bt 0f\;mov %1,%0\\n0:"
1193   [(set_attr "type" "mt_group,arith") ;; poor approximation
1194    (set_attr "length" "4")])
1196 (define_insn "*movsicc_t_true"
1197   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1198         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1199                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1200                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1201   "TARGET_PRETEND_CMOVE
1202    && (arith_reg_operand (operands[1], SImode)
1203        || (immediate_operand (operands[1], SImode)
1204            && CONST_OK_FOR_I08 (INTVAL (operands[1]))))"
1205   "bf 0f\;mov %1,%0\\n0:"
1206   [(set_attr "type" "mt_group,arith") ;; poor approximation
1207    (set_attr "length" "4")])
1209 (define_expand "movsicc"
1210   [(set (match_operand:SI 0 "arith_reg_dest" "")
1211         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1212                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1213                          (match_operand:SI 3 "arith_reg_operand" "")))]
1214   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1215   "
1217   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1218       && GET_MODE (sh_compare_op0) == SImode
1219       && (TARGET_SHMEDIA
1220           || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1221       && sh_compare_op1 == const0_rtx)
1222     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1223                                   sh_compare_op0, sh_compare_op1);
1224   else if (TARGET_PRETEND_CMOVE)
1225     {
1226       enum rtx_code code = GET_CODE (operands[1]);
1227       enum rtx_code new_code = code;
1228       rtx tmp;
1230       if (! currently_expanding_to_rtl)
1231         FAIL;
1232       switch (code)
1233         {
1234         case LT: case LE: case LEU: case LTU:
1235           if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1236             break;
1237         case NE:
1238           new_code = reverse_condition (code);
1239           break;
1240         case EQ: case GT: case GE: case GEU: case GTU:
1241           break;
1242         default:
1243           FAIL;
1244         }
1245       tmp = prepare_scc_operands (new_code);
1246       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1247                                     tmp, const0_rtx);
1248     }
1249   else
1250     {
1251       rtx tmp;
1253       if (no_new_pseudos)
1254         FAIL;
1256       tmp = gen_reg_rtx (SImode);
1258       switch (GET_CODE (operands[1]))
1259         {
1260         case EQ:
1261           emit_insn (gen_seq (tmp));
1262           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1263           break;
1265         case NE:
1266           emit_insn (gen_seq (tmp));
1267           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1268           break;
1270         case GT:
1271           emit_insn (gen_sgt (tmp));
1272           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1273           break;
1275         case LT:
1276           emit_insn (gen_slt (tmp));
1277           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1278           break;
1280         case GE:
1281           emit_insn (gen_slt (tmp));
1282           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1283           break;
1285         case LE:
1286           emit_insn (gen_sgt (tmp));
1287           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1288           break;
1290         case GTU:
1291           emit_insn (gen_sgtu (tmp));
1292           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1293           break;
1295         case LTU:
1296           emit_insn (gen_sltu (tmp));
1297           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1298           break;
1300         case GEU:
1301           emit_insn (gen_sltu (tmp));
1302           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1303           break;
1305         case LEU:
1306           emit_insn (gen_sgtu (tmp));
1307           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1308           break;
1310         case UNORDERED:
1311           emit_insn (gen_sunordered (tmp));
1312           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1313           break;
1315         case ORDERED:
1316           emit_insn (gen_sunordered (tmp));
1317           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1318           break;
1320         case UNEQ:
1321         case UNGE:
1322         case UNGT:
1323         case UNLE:
1324         case UNLT:
1325         case LTGT:
1326           FAIL;
1328         default:
1329           abort ();
1330         }
1331     }
1334 (define_expand "movqicc"
1335   [(set (match_operand:QI 0 "register_operand" "")
1336         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1337                          (match_operand:QI 2 "register_operand" "")
1338                          (match_operand:QI 3 "register_operand" "")))]
1339   "TARGET_SHMEDIA"
1340   "
1342   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1343   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1344   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1345   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1346   DONE;
1349 ;; -------------------------------------------------------------------------
1350 ;; Addition instructions
1351 ;; -------------------------------------------------------------------------
1353 (define_expand "adddi3"
1354   [(set (match_operand:DI 0 "arith_reg_operand" "")
1355         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1356                  (match_operand:DI 2 "arith_operand" "")))]
1357   ""
1358   "
1360   if (TARGET_SH1)
1361     {
1362       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1363         FAIL;
1364       operands[2] = force_reg (DImode, operands[2]);
1365       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1366       DONE;
1367     }
1370 (define_insn "*adddi3_media"
1371   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1372         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1373                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1374   "TARGET_SHMEDIA"
1375   "@
1376         add     %1, %2, %0
1377         addi    %1, %2, %0"
1378   [(set_attr "type" "arith_media")])
1380 (define_insn "*adddisi3_media"
1381   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1382         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1383                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1384   "TARGET_SHMEDIA"
1385   "@
1386         add.l   %1, %2, %0
1387         addi.l  %1, %2, %0"
1388   [(set_attr "type" "arith_media")
1389    (set_attr "highpart" "ignore")])
1391 (define_insn "adddi3z_media"
1392   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1393         (zero_extend:DI
1394          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1395                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1396   "TARGET_SHMEDIA"
1397   "addz.l       %1, %N2, %0"
1398   [(set_attr "type" "arith_media")
1399    (set_attr "highpart" "ignore")])
1401 (define_insn "adddi3_compact"
1402   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1403         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1404                  (match_operand:DI 2 "arith_reg_operand" "r")))
1405    (clobber (reg:SI T_REG))]
1406   "TARGET_SH1"
1407   "#"
1408   [(set_attr "length" "6")])
1410 (define_split
1411   [(set (match_operand:DI 0 "arith_reg_dest" "")
1412         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1413                  (match_operand:DI 2 "arith_reg_operand" "")))
1414    (clobber (reg:SI T_REG))]
1415   "TARGET_SH1 && reload_completed"
1416   [(const_int 0)]
1417   "
1419   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1420   high0 = gen_rtx_REG (SImode,
1421                        true_regnum (operands[0])
1422                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1423   high2 = gen_rtx_REG (SImode,
1424                        true_regnum (operands[2])
1425                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1426   emit_insn (gen_clrt ());
1427   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1428   emit_insn (gen_addc1 (high0, high0, high2));
1429   DONE;
1432 (define_insn "addc"
1433   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1434         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1435                           (match_operand:SI 2 "arith_reg_operand" "r"))
1436                  (reg:SI T_REG)))
1437    (set (reg:SI T_REG)
1438         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1439   "TARGET_SH1"
1440   "addc %2,%0"
1441   [(set_attr "type" "arith")])
1443 (define_insn "addc1"
1444   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1445         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1446                           (match_operand:SI 2 "arith_reg_operand" "r"))
1447                  (reg:SI T_REG)))
1448    (clobber (reg:SI T_REG))]
1449   "TARGET_SH1"
1450   "addc %2,%0"
1451   [(set_attr "type" "arith")])
1453 (define_expand "addsi3"
1454   [(set (match_operand:SI 0 "arith_reg_operand" "")
1455         (plus:SI (match_operand:SI 1 "arith_operand" "")
1456                  (match_operand:SI 2 "arith_operand" "")))]
1457   ""
1458   "
1460   if (TARGET_SHMEDIA)
1461     operands[1] = force_reg (SImode, operands[1]);
1464 (define_insn "addsi3_media"
1465   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1466         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1467                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1468   "TARGET_SHMEDIA"
1469   "@
1470         add.l   %1, %2, %0
1471         addi.l  %1, %2, %0"
1472   [(set_attr "type" "arith_media")
1473    (set_attr "highpart" "ignore")])
1475 (define_insn "addsidi3_media"
1476   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1477         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1478                                   "%r,r")
1479                                  (match_operand:SI 2 "arith_operand"
1480                                   "r,I10"))))]
1481   "TARGET_SHMEDIA"
1482   "@
1483         add.l   %1, %2, %0
1484         addi.l  %1, %2, %0"
1485   [(set_attr "type" "arith_media")
1486    (set_attr "highpart" "ignore")])
1488 (define_insn "*addsi3_compact"
1489   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1490         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1491                  (match_operand:SI 2 "arith_operand" "rI08")))]
1492   "TARGET_SH1"
1493   "add  %2,%0"
1494   [(set_attr "type" "arith")])
1496 ;; -------------------------------------------------------------------------
1497 ;; Subtraction instructions
1498 ;; -------------------------------------------------------------------------
1500 (define_expand "subdi3"
1501   [(set (match_operand:DI 0 "arith_reg_operand" "")
1502         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1503                   (match_operand:DI 2 "arith_reg_operand" "")))]
1504   ""
1505   "
1507   if (TARGET_SH1)
1508     {
1509       operands[1] = force_reg (DImode, operands[1]);
1510       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1511       DONE;
1512     }
1515 (define_insn "*subdi3_media"
1516   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1517         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1518                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1519   "TARGET_SHMEDIA"
1520   "sub  %N1, %2, %0"
1521   [(set_attr "type" "arith_media")])
1522   
1523 (define_insn "subdisi3_media"
1524   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1525         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1526                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1527   "TARGET_SHMEDIA"
1528   "sub.l        %N1, %2, %0"
1529   [(set_attr "type" "arith_media")
1530    (set_attr "highpart" "ignore")])
1532 (define_insn "subdi3_compact"
1533   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1534         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1535                  (match_operand:DI 2 "arith_reg_operand" "r")))
1536    (clobber (reg:SI T_REG))]
1537   "TARGET_SH1"
1538   "#"
1539   [(set_attr "length" "6")])
1541 (define_split
1542   [(set (match_operand:DI 0 "arith_reg_dest" "")
1543         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1544                   (match_operand:DI 2 "arith_reg_operand" "")))
1545    (clobber (reg:SI T_REG))]
1546   "TARGET_SH1 && reload_completed"
1547   [(const_int 0)]
1548   "
1550   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1551   high0 = gen_rtx_REG (SImode,
1552                        true_regnum (operands[0])
1553                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1554   high2 = gen_rtx_REG (SImode,
1555                        true_regnum (operands[2])
1556                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1557   emit_insn (gen_clrt ());
1558   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1559   emit_insn (gen_subc1 (high0, high0, high2));
1560   DONE;
1563 (define_insn "subc"
1564   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1565         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1566                             (match_operand:SI 2 "arith_reg_operand" "r"))
1567                   (reg:SI T_REG)))
1568    (set (reg:SI T_REG)
1569         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1570                           (reg:SI T_REG))
1571                 (match_dup 1)))]
1572   "TARGET_SH1"
1573   "subc %2,%0"
1574   [(set_attr "type" "arith")])
1576 (define_insn "subc1"
1577   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1578         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1579                             (match_operand:SI 2 "arith_reg_operand" "r"))
1580                   (reg:SI T_REG)))
1581    (clobber (reg:SI T_REG))]
1582   "TARGET_SH1"
1583   "subc %2,%0"
1584   [(set_attr "type" "arith")])
1586 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1587 ;; pattern for this case.  This helps multimedia applications that compute
1588 ;; the sum of absolute differences.
1589 (define_insn "mov_neg_si_t"
1590   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1591   "TARGET_SH1"
1592   "subc %0,%0"
1593   [(set_attr "type" "arith")])
1595 (define_insn "*subsi3_internal"
1596   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1597         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1598                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1599   "TARGET_SH1"
1600   "sub  %2,%0"
1601   [(set_attr "type" "arith")])
1603 (define_insn_and_split "*subsi3_media"
1604   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1605         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1606                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1607   "TARGET_SHMEDIA
1608    && (operands[1] != constm1_rtx
1609        || (GET_CODE (operands[2]) != TRUNCATE
1610            && GET_CODE (operands[2]) != SUBREG))"
1611   "sub.l        %N1, %2, %0"
1612   "operands[1] == constm1_rtx"
1613   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1614   ""
1615   [(set_attr "type" "arith_media")
1616    (set_attr "highpart" "ignore")])
1618 (define_split
1619   [(set (match_operand:SI 0 "arith_reg_dest" "")
1620         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1621                                                        "general_extend_operand"
1622                                                        "") 0)) 0)))]
1623   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1624   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1625    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1626   "")
1628 (define_split
1629   [(set (match_operand:SI 0 "arith_reg_dest" "")
1630         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1631                                                        "general_extend_operand"
1632                                                        "") 0)) 3)))]
1633   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1634   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1635    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1636   "")
1637 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1638 ;; will sometimes save one instruction.  Otherwise we might get
1639 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1640 ;; are the same.
1642 (define_expand "subsi3"
1643   [(set (match_operand:SI 0 "arith_reg_operand" "")
1644         (minus:SI (match_operand:SI 1 "arith_operand" "")
1645                   (match_operand:SI 2 "arith_reg_operand" "")))]
1646   ""
1647   "
1649   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1650     {
1651       emit_insn (gen_negsi2 (operands[0], operands[2]));
1652       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1653       DONE;
1654     }
1655   if (TARGET_SHMEDIA)
1656     {
1657       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1658         FAIL;
1659       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1660         operands[1] = force_reg (SImode, operands[1]);
1661     }
1664 ;; -------------------------------------------------------------------------
1665 ;; Division instructions
1666 ;; -------------------------------------------------------------------------
1668 ;; We take advantage of the library routines which don't clobber as many
1669 ;; registers as a normal function call would.
1671 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1672 ;; also has an effect on the register that holds the address of the sfunc.
1673 ;; To make this work, we have an extra dummy insn that shows the use
1674 ;; of this register for reorg.
1676 (define_insn "use_sfunc_addr"
1677   [(set (reg:SI PR_REG)
1678         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1679   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1680   ""
1681   [(set_attr "length" "0")])
1683 (define_insn "udivsi3_sh2a"
1684   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1685         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1686                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1687   "TARGET_SH2A"
1688   "divu %2,%1"
1689   [(set_attr "type" "arith")
1690    (set_attr "in_delay_slot" "no")])
1692 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1693 ;; hard register 0.  If we used hard register 0, then the next instruction
1694 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1695 ;; gets allocated to a stack slot that needs its address reloaded, then
1696 ;; there is nothing to prevent reload from using r0 to reload the address.
1697 ;; This reload would clobber the value in r0 we are trying to store.
1698 ;; If we let reload allocate r0, then this problem can never happen.
1700 (define_insn "udivsi3_i1"
1701   [(set (match_operand:SI 0 "register_operand" "=z")
1702         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1703    (clobber (reg:SI T_REG))
1704    (clobber (reg:SI PR_REG))
1705    (clobber (reg:SI R4_REG))
1706    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1707   "TARGET_SH1 && ! TARGET_SH4"
1708   "jsr  @%1%#"
1709   [(set_attr "type" "sfunc")
1710    (set_attr "needs_delay_slot" "yes")])
1712 ; Since shmedia-nofpu code could be linked against shcompact code, and
1713 ; the udivsi3 libcall has the same name, we must consider all registers
1714 ; clobbered that are in the union of the registers clobbered by the
1715 ; shmedia and the shcompact implementation.  Note, if the shcompact
1716 ; implementation actually used shcompact code, we'd need to clobber
1717 ; also r23 and fr23.
1718 (define_insn "udivsi3_i1_media"
1719   [(set (match_operand:SI 0 "register_operand" "=z")
1720         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1721    (clobber (reg:SI T_MEDIA_REG))
1722    (clobber (reg:SI PR_MEDIA_REG))
1723    (clobber (reg:SI R20_REG))
1724    (clobber (reg:SI R21_REG))
1725    (clobber (reg:SI R22_REG))
1726    (clobber (reg:DI TR0_REG))
1727    (clobber (reg:DI TR1_REG))
1728    (clobber (reg:DI TR2_REG))
1729    (use (match_operand 1 "target_operand" "b"))]
1730   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1731   "blink        %1, r18"
1732   [(set_attr "type" "sfunc")
1733    (set_attr "needs_delay_slot" "yes")])
1735 (define_expand "udivsi3_i4_media"
1736   [(set (match_dup 3)
1737         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1738    (set (match_dup 4)
1739         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1740    (set (match_dup 5) (float:DF (match_dup 3)))
1741    (set (match_dup 6) (float:DF (match_dup 4)))
1742    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1743    (set (match_dup 8) (fix:DI (match_dup 7)))
1744    (set (match_operand:SI 0 "register_operand" "")
1745         (truncate:SI (match_dup 8)))]
1746   "TARGET_SHMEDIA_FPU"
1747   "
1749   operands[3] = gen_reg_rtx (DImode);
1750   operands[4] = gen_reg_rtx (DImode);
1751   operands[5] = gen_reg_rtx (DFmode);
1752   operands[6] = gen_reg_rtx (DFmode);
1753   operands[7] = gen_reg_rtx (DFmode);
1754   operands[8] = gen_reg_rtx (DImode);
1757 (define_insn "udivsi3_i4"
1758   [(set (match_operand:SI 0 "register_operand" "=y")
1759         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1760    (clobber (reg:SI T_REG))
1761    (clobber (reg:SI PR_REG))
1762    (clobber (reg:DF DR0_REG))
1763    (clobber (reg:DF DR2_REG))
1764    (clobber (reg:DF DR4_REG))
1765    (clobber (reg:SI R0_REG))
1766    (clobber (reg:SI R1_REG))
1767    (clobber (reg:SI R4_REG))
1768    (clobber (reg:SI R5_REG))
1769    (use (reg:PSI FPSCR_REG))
1770    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1771   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1772   "jsr  @%1%#"
1773   [(set_attr "type" "sfunc")
1774    (set_attr "fp_mode" "double")
1775    (set_attr "needs_delay_slot" "yes")])
1777 (define_insn "udivsi3_i4_single"
1778   [(set (match_operand:SI 0 "register_operand" "=y")
1779         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1780    (clobber (reg:SI T_REG))
1781    (clobber (reg:SI PR_REG))
1782    (clobber (reg:DF DR0_REG))
1783    (clobber (reg:DF DR2_REG))
1784    (clobber (reg:DF DR4_REG))
1785    (clobber (reg:SI R0_REG))
1786    (clobber (reg:SI R1_REG))
1787    (clobber (reg:SI R4_REG))
1788    (clobber (reg:SI R5_REG))
1789    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1790   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1791   "jsr  @%1%#"
1792   [(set_attr "type" "sfunc")
1793    (set_attr "needs_delay_slot" "yes")])
1795 (define_insn "udivsi3_i4_int"
1796   [(set (match_operand:SI 0 "register_operand" "=z")
1797         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1798    (clobber (reg:SI T_REG))
1799    (clobber (reg:SI R1_REG))
1800    (clobber (reg:SI PR_REG))
1801    (clobber (reg:SI MACH_REG))
1802    (clobber (reg:SI MACL_REG))
1803    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1804   "TARGET_SH1"
1805   "jsr  @%1%#"
1806   [(set_attr "type" "sfunc")
1807    (set_attr "needs_delay_slot" "yes")])
1810 (define_expand "udivsi3"
1811   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1812    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1813    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1814    (parallel [(set (match_operand:SI 0 "register_operand" "")
1815                    (udiv:SI (reg:SI R4_REG)
1816                             (reg:SI R5_REG)))
1817               (clobber (reg:SI T_REG))
1818               (clobber (reg:SI PR_REG))
1819               (clobber (reg:SI R4_REG))
1820               (use (match_dup 3))])]
1821   ""
1822   "
1824   rtx first, last;
1826   operands[3] = gen_reg_rtx (Pmode);
1827   /* Emit the move of the address to a pseudo outside of the libcall.  */
1828   if (TARGET_DIVIDE_CALL_TABLE)
1829     {
1830       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1831       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1832     }
1833   else if (TARGET_DIVIDE_CALL_FP)
1834     {
1835       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1836       if (TARGET_FPU_SINGLE)
1837         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1838       else
1839         last = gen_udivsi3_i4 (operands[0], operands[3]);
1840     }
1841   else if (TARGET_SHMEDIA_FPU)
1842     {
1843       operands[1] = force_reg (SImode, operands[1]);
1844       operands[2] = force_reg (SImode, operands[2]);
1845       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1846       DONE;
1847     }
1848   else if (TARGET_SH2A)
1849     {
1850       operands[1] = force_reg (SImode, operands[1]);
1851       operands[2] = force_reg (SImode, operands[2]);
1852       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1853       DONE;
1854     }
1855   else if (TARGET_SH5)
1856     {
1857       function_symbol (operands[3],
1858                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1859                        SFUNC_STATIC);
1861       if (TARGET_SHMEDIA)
1862         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1863       else if (TARGET_FPU_ANY)
1864         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1865       else
1866         last = gen_udivsi3_i1 (operands[0], operands[3]);
1867     }
1868   else
1869     {
1870       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1871       last = gen_udivsi3_i1 (operands[0], operands[3]);
1872     }
1873   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1874   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1875   last = emit_insn (last);
1876   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1877      invariant code motion can move it.  */
1878   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1879   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1880   DONE;
1883 (define_insn "divsi3_sh2a"
1884   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1885         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1886                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1887   "TARGET_SH2A"
1888   "divs %2,%1"
1889   [(set_attr "type" "arith")
1890    (set_attr "in_delay_slot" "no")])
1892 (define_insn "divsi3_i1"
1893   [(set (match_operand:SI 0 "register_operand" "=z")
1894         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1895    (clobber (reg:SI T_REG))
1896    (clobber (reg:SI PR_REG))
1897    (clobber (reg:SI R1_REG))
1898    (clobber (reg:SI R2_REG))
1899    (clobber (reg:SI R3_REG))
1900    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1901   "TARGET_SH1 && ! TARGET_SH4"
1902   "jsr  @%1%#"
1903   [(set_attr "type" "sfunc")
1904    (set_attr "needs_delay_slot" "yes")])
1906 (define_insn "divsi3_i1_media"
1907   [(set (match_operand:SI 0 "register_operand" "=z")
1908         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1909    (clobber (reg:SI T_MEDIA_REG))
1910    (clobber (reg:SI PR_MEDIA_REG))
1911    (clobber (reg:SI R1_REG))
1912    (clobber (reg:SI R20_REG))
1913    (clobber (reg:SI R21_REG))
1914    (clobber (reg:SI TR0_REG))
1915    (use (match_operand 1 "target_operand" "b"))]
1916   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1917   "blink        %1, r18"
1918   [(set_attr "type" "sfunc")])
1920 (define_insn "divsi3_media_2"
1921   [(set (match_operand:SI 0 "register_operand" "=z")
1922         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1923    (clobber (reg:SI T_MEDIA_REG))
1924    (clobber (reg:SI PR_MEDIA_REG))
1925    (clobber (reg:SI R1_REG))
1926    (clobber (reg:SI R21_REG))
1927    (clobber (reg:SI TR0_REG))
1928    (use (reg:SI R20_REG))
1929    (use (match_operand 1 "target_operand" "b"))]
1930   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1931   "blink        %1, r18"
1932   [(set_attr "type" "sfunc")])
1934 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1935 ;; hard reg clobbers and data dependencies that we need when we want
1936 ;; to rematerialize the division into a call.
1937 (define_insn_and_split "divsi_inv_call"
1938   [(set (match_operand:SI 0 "register_operand" "=r")
1939         (div:SI (match_operand:SI 1 "register_operand" "r")
1940                 (match_operand:SI 2 "register_operand" "r")))
1941    (clobber (reg:SI R4_REG))
1942    (clobber (reg:SI R5_REG))
1943    (clobber (reg:SI T_MEDIA_REG))
1944    (clobber (reg:SI PR_MEDIA_REG))
1945    (clobber (reg:SI R1_REG))
1946    (clobber (reg:SI R21_REG))
1947    (clobber (reg:SI TR0_REG))
1948    (clobber (reg:SI R20_REG))
1949    (use (match_operand:SI 3 "register_operand" "r"))]
1950   "TARGET_SHMEDIA"
1951   "#"
1952   "&& (high_life_started || reload_completed)"
1953   [(set (match_dup 0) (match_dup 3))]
1954   ""
1955   [(set_attr "highpart" "must_split")])
1957 ;; This is the combiner pattern for -mdiv=inv:call .
1958 (define_insn_and_split "*divsi_inv_call_combine"
1959   [(set (match_operand:SI 0 "register_operand" "=z")
1960         (div:SI (match_operand:SI 1 "register_operand" "r")
1961                 (match_operand:SI 2 "register_operand" "r")))
1962    (clobber (reg:SI R4_REG))
1963    (clobber (reg:SI R5_REG))
1964    (clobber (reg:SI T_MEDIA_REG))
1965    (clobber (reg:SI PR_MEDIA_REG))
1966    (clobber (reg:SI R1_REG))
1967    (clobber (reg:SI R21_REG))
1968    (clobber (reg:SI TR0_REG))
1969    (clobber (reg:SI R20_REG))
1970    (use (unspec:SI [(match_dup 1)
1971                     (match_operand:SI 3 "" "")
1972                     (unspec:SI [(match_operand:SI 4 "" "")
1973                                 (match_dup 3)
1974                                 (match_operand:DI 5 "" "")]
1975                      UNSPEC_DIV_INV_M2)
1976                     (match_operand:DI 6 "" "")
1977                     (const_int 0)
1978                     (const_int 0)]
1979          UNSPEC_DIV_INV_M3))]
1980   "TARGET_SHMEDIA"
1981   "#"
1982   "&& (high_life_started || reload_completed)"
1983   [(pc)]
1984   "
1986   const char *name = sh_divsi3_libfunc;
1987   enum sh_function_kind kind = SFUNC_GOT;
1988   rtx sym;
1990   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1991   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1992   while (TARGET_DIVIDE_INV_CALL2)
1993     {
1994       rtx x = operands[3];
1996       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1997         break;
1998       x = XVECEXP (x, 0, 0);
1999       name = \"__sdivsi3_2\";
2000       kind = SFUNC_STATIC;
2001       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2002       break;
2003     }
2004   sym = function_symbol (NULL, name, kind);
2005   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2006   DONE;
2008   [(set_attr "highpart" "must_split")])
2010 (define_expand "divsi3_i4_media"
2011   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2012    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2013    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2014    (set (match_operand:SI 0 "register_operand" "=r")
2015         (fix:SI (match_dup 5)))]
2016   "TARGET_SHMEDIA_FPU"
2017   "
2019   operands[3] = gen_reg_rtx (DFmode);
2020   operands[4] = gen_reg_rtx (DFmode);
2021   operands[5] = gen_reg_rtx (DFmode);
2024 (define_insn "divsi3_i4"
2025   [(set (match_operand:SI 0 "register_operand" "=y")
2026         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2027    (clobber (reg:SI PR_REG))
2028    (clobber (reg:DF DR0_REG))
2029    (clobber (reg:DF DR2_REG))
2030    (use (reg:PSI FPSCR_REG))
2031    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2032   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2033   "jsr  @%1%#"
2034   [(set_attr "type" "sfunc")
2035    (set_attr "fp_mode" "double")
2036    (set_attr "needs_delay_slot" "yes")])
2038 (define_insn "divsi3_i4_single"
2039   [(set (match_operand:SI 0 "register_operand" "=y")
2040         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2041    (clobber (reg:SI PR_REG))
2042    (clobber (reg:DF DR0_REG))
2043    (clobber (reg:DF DR2_REG))
2044    (clobber (reg:SI R2_REG))
2045    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2046   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2047   "jsr  @%1%#"
2048   [(set_attr "type" "sfunc")
2049    (set_attr "needs_delay_slot" "yes")])
2051 (define_insn "divsi3_i4_int"
2052   [(set (match_operand:SI 0 "register_operand" "=z")
2053         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2054    (clobber (reg:SI T_REG))
2055    (clobber (reg:SI PR_REG))
2056    (clobber (reg:SI R1_REG))
2057    (clobber (reg:SI MACH_REG))
2058    (clobber (reg:SI MACL_REG))
2059    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2060   "TARGET_SH1"
2061   "jsr  @%1%#"
2062   [(set_attr "type" "sfunc")
2063    (set_attr "needs_delay_slot" "yes")])
2065 (define_expand "divsi3"
2066   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2067    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2068    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2069    (parallel [(set (match_operand:SI 0 "register_operand" "")
2070                    (div:SI (reg:SI R4_REG)
2071                            (reg:SI R5_REG)))
2072               (clobber (reg:SI T_REG))
2073               (clobber (reg:SI PR_REG))
2074               (clobber (reg:SI R1_REG))
2075               (clobber (reg:SI R2_REG))
2076               (clobber (reg:SI R3_REG))
2077               (use (match_dup 3))])]
2078   ""
2079   "
2081   rtx first, last;
2083   operands[3] = gen_reg_rtx (Pmode);
2084   /* Emit the move of the address to a pseudo outside of the libcall.  */
2085   if (TARGET_DIVIDE_CALL_TABLE)
2086     {
2087       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2088       last = gen_divsi3_i4_int (operands[0], operands[3]);
2089     }
2090   else if (TARGET_DIVIDE_CALL_FP)
2091     {
2092       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2093       if (TARGET_FPU_SINGLE)
2094         last = gen_divsi3_i4_single (operands[0], operands[3]);
2095       else
2096         last = gen_divsi3_i4 (operands[0], operands[3]);
2097     }
2098   else if (TARGET_SH2A)
2099     {
2100       operands[1] = force_reg (SImode, operands[1]);
2101       operands[2] = force_reg (SImode, operands[2]);
2102       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2103       DONE;
2104     }
2105   else if (TARGET_DIVIDE_INV)
2106     {
2107       rtx dividend = operands[1];
2108       rtx divisor = operands[2];
2109       rtx tab_base;
2110       rtx nsb_res = gen_reg_rtx (DImode);
2111       rtx norm64 = gen_reg_rtx (DImode);
2112       rtx tab_ix = gen_reg_rtx (DImode);
2113       rtx norm32 = gen_reg_rtx (SImode);
2114       rtx i92 = force_reg (DImode, GEN_INT (92));
2115       rtx scratch0a = gen_reg_rtx (DImode);
2116       rtx scratch0b = gen_reg_rtx (DImode);
2117       rtx inv0 = gen_reg_rtx (SImode);
2118       rtx scratch1a = gen_reg_rtx (DImode);
2119       rtx scratch1b = gen_reg_rtx (DImode);
2120       rtx shift = gen_reg_rtx (DImode);
2121       rtx i2p27, i43;
2122       rtx inv1 = gen_reg_rtx (SImode);
2123       rtx scratch2a = gen_reg_rtx (DImode);
2124       rtx scratch2b = gen_reg_rtx (SImode);
2125       rtx inv2 = gen_reg_rtx (SImode);
2126       rtx scratch3a = gen_reg_rtx (DImode);
2127       rtx scratch3b = gen_reg_rtx (DImode);
2128       rtx scratch3c = gen_reg_rtx (DImode);
2129       rtx scratch3d = gen_reg_rtx (SImode);
2130       rtx scratch3e = gen_reg_rtx (DImode);
2131       rtx result = gen_reg_rtx (SImode);
2133       if (! arith_reg_or_0_operand (dividend, SImode))
2134         dividend = force_reg (SImode, dividend);
2135       if (! arith_reg_operand (divisor, SImode))
2136         divisor = force_reg (SImode, divisor);
2137       if (flag_pic && Pmode != DImode)
2138         {
2139           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2140           tab_base = gen_datalabel_ref (tab_base);
2141           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2142         }
2143       else
2144         {
2145           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2146           tab_base = gen_datalabel_ref (tab_base);
2147           tab_base = force_reg (DImode, tab_base);
2148         }
2149       if (TARGET_DIVIDE_INV20U)
2150         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2151       else
2152         i2p27 = GEN_INT (0);
2153       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2154         i43 = force_reg (DImode, GEN_INT (43));
2155       else
2156         i43 = GEN_INT (0);
2157       emit_insn (gen_nsbdi (nsb_res,
2158                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2159       emit_insn (gen_ashldi3_media (norm64,
2160                                     gen_rtx_SUBREG (DImode, divisor, 0),
2161                                     nsb_res));
2162       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2163       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2164       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2165                                    inv0, scratch0a, scratch0b,
2166                                    scratch1a, scratch1b));
2167       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2168       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2169                                    scratch2a));
2170       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2171                                    i2p27, i43,
2172                                    scratch3a, scratch3b, scratch3c,
2173                                    scratch2a, scratch2b, scratch3d, scratch3e));
2174       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2175         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2176       else if (TARGET_DIVIDE_INV_FP)
2177         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2178                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2179                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2180                                      gen_reg_rtx (DFmode)));
2181       else
2182         emit_move_insn (operands[0], result);
2183       DONE;
2184     }
2185   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2186     {
2187       operands[1] = force_reg (SImode, operands[1]);
2188       operands[2] = force_reg (SImode, operands[2]);
2189       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2190       DONE;
2191     }
2192   else if (TARGET_SH5)
2193     {
2194       if (TARGET_DIVIDE_CALL2)
2195         {
2196           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2197           tab_base = gen_datalabel_ref (tab_base);
2198           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2199         }
2200       if (TARGET_FPU_ANY && TARGET_SH1)
2201         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2202       else if (TARGET_DIVIDE_CALL2)
2203         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2204       else
2205         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2207       if (TARGET_SHMEDIA)
2208         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2209                 (operands[0], operands[3]));
2210       else if (TARGET_FPU_ANY)
2211         last = gen_divsi3_i4_single (operands[0], operands[3]);
2212       else
2213         last = gen_divsi3_i1 (operands[0], operands[3]);
2214     }
2215   else
2216     {
2217       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2218       last = gen_divsi3_i1 (operands[0], operands[3]);
2219     }
2220   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2221   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2222   last = emit_insn (last);
2223   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2224      invariant code motion can move it.  */
2225   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2226   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2227   DONE;
2230 ;; operands: inv0, tab_base, tab_ix, norm32
2231 ;; scratch equiv in sdivsi3_2: r19, r21
2232 (define_expand "divsi_inv_m0"
2233   [(set (match_operand:SI 0 "register_operand" "=r")
2234         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2235                     (match_operand:DI 2 "register_operand" "r")
2236                     (match_operand:SI 3 "register_operand" "r")]
2237          UNSPEC_DIV_INV_M0))
2238    (clobber (match_operand:DI 4 "register_operand" "=r"))
2239    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2240   "TARGET_SHMEDIA"
2241   "
2244 tab_base: r20
2245 tab_ix: r21
2246 norm32: r25
2247  ldx.ub r20, r21, r19 // u0.8
2248  shlli r21, 1, r21
2249  muls.l r25, r19, r19 // s2.38
2250  ldx.w r20, r21, r21  // s2.14
2251  shari r19, 24, r19   // truncate to s2.14
2252  sub r21, r19, r19    // some 11 bit inverse in s1.14
2255   rtx inv0 = operands[0];
2256   rtx tab_base = operands[1];
2257   rtx tab_ix = operands[2];
2258   rtx norm32 = operands[3];
2259   rtx scratch0 = operands[4];
2260   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2261   rtx scratch1 = operands[5];
2262   rtx mem;
2264   mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2265   emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2266   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2267   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2268   mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2269   emit_insn (gen_extendhidi2 (scratch1, mem));
2270   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2271   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2272   DONE;
2275 ;; operands: inv1, tab_base, tab_ix, norm32
2276 (define_insn_and_split "divsi_inv_m1"
2277   [(set (match_operand:SI 0 "register_operand" "=r")
2278         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2279                     (match_operand:DI 2 "register_operand" "r")
2280                     (match_operand:SI 3 "register_operand" "r")]
2281          UNSPEC_DIV_INV_M1))
2282    (clobber (match_operand:SI 4 "register_operand" "=r"))
2283    (clobber (match_operand:DI 5 "register_operand" "=r"))
2284    (clobber (match_operand:DI 6 "register_operand" "=r"))
2285    (clobber (match_operand:DI 7 "register_operand" "=r"))
2286    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2287   "TARGET_SHMEDIA"
2288   "#"
2289   "&& no_new_pseudos"
2290   [(pc)]
2291   "
2293 /* inv0: r19
2294  muls.l r19, r19, r18 // u0.28
2295  muls.l r25, r18, r18 // s2.58
2296  shlli r19, 45, r0    // multiply by two and convert to s2.58
2297  sub r0, r18, r18
2298  shari r18, 28, r18   // some 18 bit inverse in s1.30
2301   rtx inv1 = operands[0];
2302   rtx tab_base = operands[1];
2303   rtx tab_ix = operands[2];
2304   rtx norm32 = operands[3];
2305   rtx inv0 = operands[4];
2306   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2307   rtx scratch0a = operands[5];
2308   rtx scratch0b = operands[6];
2309   rtx scratch0 = operands[7];
2310   rtx scratch1 = operands[8];
2311   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2313   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2314                                scratch0a, scratch0b));
2315   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2316   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2317   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2318   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2319   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2320   DONE;
2323 ;; operands: inv2, norm32, inv1, i92
2324 (define_insn_and_split "divsi_inv_m2"
2325   [(set (match_operand:SI 0 "register_operand" "=r")
2326         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2327                     (match_operand:SI 2 "register_operand" "r")
2328                     (match_operand:DI 3 "register_operand" "r")]
2329          UNSPEC_DIV_INV_M2))
2330    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2331   "TARGET_SHMEDIA"
2332   "#"
2333   "&& no_new_pseudos"
2334   [(pc)]
2335   "
2338  muls.l r18, r25, r0  // s2.60
2339  shari r0, 16, r0     // s-16.44
2340   sub
2341  muls.l r0, r18, r19  // s-16.74
2342  shari r19, 30, r19   // s-16.44
2344   rtx inv2 = operands[0];
2345   rtx norm32 = operands[1];
2346   rtx inv1 = operands[2];
2347   rtx i92 = operands[3];
2348   rtx scratch0 = operands[4];
2349   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2351   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2352   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2353   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2354   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2355   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2356   DONE;
2359 (define_insn_and_split "divsi_inv_m3"
2360   [(set (match_operand:SI 0 "register_operand" "=r")
2361         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2362                     (match_operand:SI 2 "register_operand" "r")
2363                     (match_operand:SI 3 "register_operand" "r")
2364                     (match_operand:DI 4 "register_operand" "r")
2365                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2366                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2367          UNSPEC_DIV_INV_M3))
2368    (clobber (match_operand:DI 7 "register_operand" "=r"))
2369    (clobber (match_operand:DI 8 "register_operand" "=r"))
2370    (clobber (match_operand:DI 9 "register_operand" "=r"))
2371    (clobber (match_operand:DI 10 "register_operand" "=r"))
2372    (clobber (match_operand:SI 11 "register_operand" "=r"))
2373    (clobber (match_operand:SI 12 "register_operand" "=r"))
2374    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2375   "TARGET_SHMEDIA"
2376   "#"
2377   "&& no_new_pseudos"
2378   [(pc)]
2379   "
2382   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2383   r0: scratch0  r19: scratch1 r21: scratch2
2385   muls.l r18, r4, r25 // s32.30
2386  muls.l r19, r4, r19  // s15.30
2387  shari r25, 63, r21
2388   shari r19, 14, r19  // s18.-14
2389  sub r25, r19, r0
2390  shard r0, r1, r0
2391  sub r0, r21, r0
2394   rtx result = operands[0];
2395   rtx dividend = operands[1];
2396   rtx inv1 = operands[2];
2397   rtx inv2 = operands[3];
2398   rtx shift = operands[4];
2399   rtx scratch0 = operands[7];
2400   rtx scratch1 = operands[8];
2401   rtx scratch2 = operands[9];
2403   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2404   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2405   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2406   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2407   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2408   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2409   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2410   DONE;
2413 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2414 ;; inv1: tab_base, tab_ix, norm32
2415 ;; inv2: norm32, inv1, i92
2416 (define_insn_and_split "divsi_inv_m1_3"
2417   [(set (match_operand:SI 0 "register_operand" "=r")
2418         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2419                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2420                                 (match_operand:DI 3 "register_operand" "r")
2421                                 (match_operand:SI 4 "register_operand" "r")]
2422                      UNSPEC_DIV_INV_M1)
2423                     (unspec:SI [(match_dup 4)
2424                                 (unspec:SI [(match_dup 2)
2425                                             (match_dup 3)
2426                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2427                                 (match_operand:SI 5 "" "")]
2428                      UNSPEC_DIV_INV_M2)
2429                     (match_operand:DI 6 "register_operand" "r")
2430                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2431                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2432          UNSPEC_DIV_INV_M3))
2433    (clobber (match_operand:DI 9 "register_operand" "=r"))
2434    (clobber (match_operand:DI 10 "register_operand" "=r"))
2435    (clobber (match_operand:DI 11 "register_operand" "=r"))
2436    (clobber (match_operand:DI 12 "register_operand" "=r"))
2437    (clobber (match_operand:SI 13 "register_operand" "=r"))
2438    (clobber (match_operand:SI 14 "register_operand" "=r"))
2439    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2440   "TARGET_SHMEDIA
2441    && (TARGET_DIVIDE_INV_MINLAT
2442        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2443   "#"
2444   "&& no_new_pseudos"
2445   [(pc)]
2446   "
2448   rtx result = operands[0];
2449   rtx dividend = operands[1];
2450   rtx tab_base = operands[2];
2451   rtx tab_ix = operands[3];
2452   rtx norm32 = operands[4];
2453   /* rtx i92 = operands[5]; */
2454   rtx shift = operands[6];
2455   rtx i2p27 = operands[7];
2456   rtx i43 = operands[8];
2457   rtx scratch0 = operands[9];
2458   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2459   rtx scratch1 = operands[10];
2460   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2461   rtx scratch2 = operands[11];
2462   rtx scratch3 = operands[12];
2463   rtx scratch4 = operands[13];
2464   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2465   rtx scratch5 = operands[14];
2466   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2467   rtx scratch6 = operands[15];
2469   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2470                                scratch0, scratch1));
2471   /* inv0 == scratch4 */
2472   if (! TARGET_DIVIDE_INV20U)
2473     {
2474       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2475       i2p27 = scratch0;
2476       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2477     }
2478   else
2479     {
2480       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2481       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2482     }
2483   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2484   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2485   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2486   /* inv1 == scratch4 */
2488   if (TARGET_DIVIDE_INV_MINLAT)
2489     {
2490       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2491       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2492       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2493       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2494       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2495       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2496       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2497       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2498       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2499       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2500       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2501     }
2502   else
2503     {
2504       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2505       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2506       emit_insn (gen_nsbdi (scratch6,
2507                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2508       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2509       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2510       emit_insn (gen_divsi_inv20 (scratch2,
2511                                   norm32, scratch4, dividend,
2512                                   scratch6, scratch3, i43,
2513                                   /* scratch0 may be shared with i2p27.  */
2514                                   scratch0, scratch1, scratch5,
2515                                   label, label, i2p27));
2516     }
2517   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2518   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2519   DONE;
2522 (define_insn "divsi_inv20"
2523   [(set (match_operand:DI 0 "register_operand" "=&r")
2524         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2525                     (match_operand:SI 2 "register_operand" "r")
2526                     (match_operand:SI 3 "register_operand" "r")
2527                     (match_operand:DI 4 "register_operand" "r")
2528                     (match_operand:DI 5 "register_operand" "r")
2529                     (match_operand:DI 6 "register_operand" "r")
2530                     (match_operand:DI 12 "register_operand" "r")
2531                     (match_operand 10 "target_operand" "b")
2532                     (match_operand 11 "immediate_operand" "i")]
2533          UNSPEC_DIV_INV20))
2534    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2535    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2536    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2537   "TARGET_SHMEDIA
2538    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2539   "*
2541 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2542              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2543              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2544              %10 label (tr), %11 label (imm)
2546  muls.l inv1, norm32, scratch0  // s2.60
2547   muls.l inv1, dividend, result // s32.30
2548   xor i2p27, result_sign, round_scratch
2549  bge/u dividend_nsb, i43, tr.. (label)
2550  shari scratch0, 16, scratch0   // s-16.44
2551  muls.l sratch0_si, inv1, scratch0 // s-16.74
2552   sub result, round_scratch, result
2553   shari dividend, 14, scratch1   // s19.-14
2554  shari scratch0, 30, scratch0   // s-16.44
2555  muls.l scratch0, scratch1, round_scratch // s15.30
2556 label:
2557  sub result, round_scratch, result */
2559   int likely = TARGET_DIVIDE_INV20L;
2561   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2562   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2563   output_asm_insn (likely
2564                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2565                    : \"bge/u\t%4, %6, %10\", operands);
2566   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2567   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2568   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2569   return (likely
2570           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2571           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2574 (define_insn_and_split "divsi_inv_fp"
2575   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2576         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2577                 (match_operand:SI 2 "register_operand" "rf")))
2578    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2579    (clobber (match_operand:SI 4 "register_operand" "=r"))
2580    (clobber (match_operand:SI 5 "register_operand" "=r"))
2581    (clobber (match_operand:DF 6 "register_operand" "=r"))
2582    (clobber (match_operand:DF 7 "register_operand" "=r"))
2583    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2584   "TARGET_SHMEDIA_FPU"
2585   "#"
2586   "&& (high_life_started || reload_completed)"
2587   [(set (match_dup 0) (match_dup 3))]
2588   ""
2589   [(set_attr "highpart" "must_split")])
2591 ;; If a matching group of divide-by-inverse instructions is in the same
2592 ;; basic block after gcse & loop optimizations, we want to transform them
2593 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2594 (define_insn_and_split "*divsi_inv_fp_combine"
2595   [(set (match_operand:SI 0 "register_operand" "=f")
2596         (div:SI (match_operand:SI 1 "register_operand" "f")
2597                 (match_operand:SI 2 "register_operand" "f")))
2598    (use (unspec:SI [(match_dup 1)
2599                     (match_operand:SI 3 "" "")
2600                     (unspec:SI [(match_operand:SI 4 "" "")
2601                                 (match_dup 3)
2602                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2603                     (match_operand:DI 6 "" "")
2604                     (const_int 0)
2605                     (const_int 0)] UNSPEC_DIV_INV_M3))
2606    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2607    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2608    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2609    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2610    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2611   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2612   "#"
2613   "&& 1"
2614   [(set (match_dup 9) (float:DF (match_dup 1)))
2615    (set (match_dup 10) (float:DF (match_dup 2)))
2616    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2617    (set (match_dup 8)
2618         (fix:SI (match_dup 11)))
2619    (set (match_dup 0) (match_dup 8))]
2620   "
2622   if (! fp_arith_reg_operand (operands[1], SImode))
2623     {
2624       emit_move_insn (operands[7], operands[1]);
2625       operands[1] = operands[7];
2626     }
2627   if (! fp_arith_reg_operand (operands[2], SImode))
2628     {
2629       emit_move_insn (operands[8], operands[2]);
2630       operands[2] = operands[8];
2631     }
2633   [(set_attr "highpart" "must_split")])
2635 ;; -------------------------------------------------------------------------
2636 ;; Multiplication instructions
2637 ;; -------------------------------------------------------------------------
2639 (define_insn "umulhisi3_i"
2640   [(set (reg:SI MACL_REG)
2641         (mult:SI (zero_extend:SI
2642                   (match_operand:HI 0 "arith_reg_operand" "r"))
2643                  (zero_extend:SI
2644                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2645   "TARGET_SH1"
2646   "mulu.w       %1,%0"
2647   [(set_attr "type" "smpy")])
2649 (define_insn "mulhisi3_i"
2650   [(set (reg:SI MACL_REG)
2651         (mult:SI (sign_extend:SI
2652                   (match_operand:HI 0 "arith_reg_operand" "r"))
2653                  (sign_extend:SI
2654                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2655   "TARGET_SH1"
2656   "muls.w       %1,%0"
2657   [(set_attr "type" "smpy")])
2659 (define_expand "mulhisi3"
2660   [(set (reg:SI MACL_REG)
2661         (mult:SI (sign_extend:SI
2662                   (match_operand:HI 1 "arith_reg_operand" ""))
2663                  (sign_extend:SI
2664                   (match_operand:HI 2 "arith_reg_operand" ""))))
2665    (set (match_operand:SI 0 "arith_reg_operand" "")
2666         (reg:SI MACL_REG))]
2667   "TARGET_SH1"
2668   "
2670   rtx first, last;
2672   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2673   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2674   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2675      invariant code motion can move it.  */
2676   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2677   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2678   /* expand_binop can't find a suitable code in umul_widen_optab to
2679      make a REG_EQUAL note from, so make one here.
2680      See also smulsi3_highpart.
2681      ??? Alternatively, we could put this at the calling site of expand_binop,
2682      i.e. expand_expr.  */
2683   REG_NOTES (last)
2684     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2685                          REG_NOTES (last));
2686   DONE;
2689 (define_expand "umulhisi3"
2690   [(set (reg:SI MACL_REG)
2691         (mult:SI (zero_extend:SI
2692                   (match_operand:HI 1 "arith_reg_operand" ""))
2693                  (zero_extend:SI
2694                   (match_operand:HI 2 "arith_reg_operand" ""))))
2695    (set (match_operand:SI 0 "arith_reg_operand" "")
2696         (reg:SI MACL_REG))]
2697   "TARGET_SH1"
2698   "
2700   rtx first, last;
2702   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2703   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2704   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2705      invariant code motion can move it.  */
2706   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2707   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2708   /* expand_binop can't find a suitable code in umul_widen_optab to
2709      make a REG_EQUAL note from, so make one here.
2710      See also smulsi3_highpart.
2711      ??? Alternatively, we could put this at the calling site of expand_binop,
2712      i.e. expand_expr.  */
2713   REG_NOTES (last)
2714     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2715                          REG_NOTES (last));
2716   DONE;
2719 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2720 ;; a call to a routine which clobbers known registers.
2722 (define_insn ""
2723   [(set (match_operand:SI 1 "register_operand" "=z")
2724         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2725    (clobber (reg:SI MACL_REG))
2726    (clobber (reg:SI T_REG))
2727    (clobber (reg:SI PR_REG))
2728    (clobber (reg:SI R3_REG))
2729    (clobber (reg:SI R2_REG))
2730    (clobber (reg:SI R1_REG))
2731    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2732   "TARGET_SH1"
2733   "jsr  @%0%#"
2734   [(set_attr "type" "sfunc")
2735    (set_attr "needs_delay_slot" "yes")])
2737 (define_expand "mulsi3_call"
2738   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2739    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2740    (parallel[(set (match_operand:SI 0 "register_operand" "")
2741                   (mult:SI (reg:SI R4_REG)
2742                            (reg:SI R5_REG)))
2743              (clobber (reg:SI MACL_REG))
2744              (clobber (reg:SI T_REG))
2745              (clobber (reg:SI PR_REG))
2746              (clobber (reg:SI R3_REG))
2747              (clobber (reg:SI R2_REG))
2748              (clobber (reg:SI R1_REG))
2749              (use (match_operand:SI 3 "register_operand" ""))])]
2750   "TARGET_SH1"
2751   "")
2753 (define_insn "mul_r"
2754   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2755         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2756                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2757   "TARGET_SH2A"
2758   "mulr %2,%0"
2759   [(set_attr "type" "dmpy")])
2761 (define_insn "mul_l"
2762   [(set (reg:SI MACL_REG)
2763         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2764                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2765   "TARGET_SH2"
2766   "mul.l        %1,%0"
2767   [(set_attr "type" "dmpy")])
2769 (define_expand "mulsi3"
2770   [(set (reg:SI MACL_REG)
2771         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2772                   (match_operand:SI 2 "arith_reg_operand" "")))
2773    (set (match_operand:SI 0 "arith_reg_operand" "")
2774         (reg:SI MACL_REG))]
2775   "TARGET_SH1"
2776   "
2778   rtx first, last;
2780   if (!TARGET_SH2)
2781     {
2782       /* The address must be set outside the libcall,
2783          since it goes into a pseudo.  */
2784       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2785       rtx addr = force_reg (SImode, sym);
2786       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2787                                    operands[2], addr);
2788       first = insns;
2789       last = emit_insn (insns);
2790     }
2791   else
2792     {
2793       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2795       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2796       /* consec_sets_giv can only recognize the first insn that sets a
2797          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2798          note.  */
2799       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2800     }
2801   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2802      invariant code motion can move it.  */
2803   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2804   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2805   DONE;
2808 (define_insn "mulsidi3_i"
2809   [(set (reg:SI MACH_REG)
2810         (truncate:SI
2811          (lshiftrt:DI
2812           (mult:DI
2813            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2814            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2815           (const_int 32))))
2816    (set (reg:SI MACL_REG)
2817         (mult:SI (match_dup 0)
2818                  (match_dup 1)))]
2819   "TARGET_SH2"
2820   "dmuls.l      %1,%0"
2821   [(set_attr "type" "dmpy")])
2823 (define_expand "mulsidi3"
2824   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2825         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2826                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2827   "TARGET_SH2 || TARGET_SHMEDIA"
2828   "
2830   if (TARGET_SH2)
2831     {
2832        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2833                                         operands[2]));
2834        DONE;
2835     }
2838 (define_insn "mulsidi3_media"
2839   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2840         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2841                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2842   "TARGET_SHMEDIA"
2843   "muls.l       %1, %2, %0"
2844   [(set_attr "type" "dmpy_media")
2845    (set_attr "highpart" "ignore")])
2847 (define_insn "mulsidi3_compact"
2848   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2849         (mult:DI
2850          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2851          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2852    (clobber (reg:SI MACH_REG))
2853    (clobber (reg:SI MACL_REG))]
2854   "TARGET_SH2"
2855   "#")
2857 (define_split
2858   [(set (match_operand:DI 0 "arith_reg_dest" "")
2859         (mult:DI
2860          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2861          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2862    (clobber (reg:SI MACH_REG))
2863    (clobber (reg:SI MACL_REG))]
2864   "TARGET_SH2"
2865   [(const_int 0)]
2866   "
2868   rtx low_dst = gen_lowpart (SImode, operands[0]);
2869   rtx high_dst = gen_highpart (SImode, operands[0]);
2871   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2873   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2874   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2875   /* We need something to tag the possible REG_EQUAL notes on to.  */
2876   emit_move_insn (operands[0], operands[0]);
2877   DONE;
2880 (define_insn "umulsidi3_i"
2881   [(set (reg:SI MACH_REG)
2882         (truncate:SI
2883          (lshiftrt:DI
2884           (mult:DI
2885            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2886            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2887           (const_int 32))))
2888    (set (reg:SI MACL_REG)
2889         (mult:SI (match_dup 0)
2890                  (match_dup 1)))]
2891   "TARGET_SH2"
2892   "dmulu.l      %1,%0"
2893   [(set_attr "type" "dmpy")])
2895 (define_expand "umulsidi3"
2896   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2897         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2898                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2899   "TARGET_SH2 || TARGET_SHMEDIA"
2900   "
2902   if (TARGET_SH2)
2903     {
2904        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2905                                          operands[2]));
2906        DONE;
2907     }
2910 (define_insn "umulsidi3_media"
2911   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2912         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2913                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2914   "TARGET_SHMEDIA"
2915   "mulu.l       %1, %2, %0"
2916   [(set_attr "type" "dmpy_media")
2917    (set_attr "highpart" "ignore")])
2919 (define_insn "umulsidi3_compact"
2920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2921         (mult:DI
2922          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2923          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2924    (clobber (reg:SI MACH_REG))
2925    (clobber (reg:SI MACL_REG))]
2926   "TARGET_SH2"
2927   "#")
2929 (define_split
2930   [(set (match_operand:DI 0 "arith_reg_dest" "")
2931         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2932                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2933    (clobber (reg:SI MACH_REG))
2934    (clobber (reg:SI MACL_REG))]
2935   "TARGET_SH2"
2936   [(const_int 0)]
2937   "
2939   rtx low_dst = gen_lowpart (SImode, operands[0]);
2940   rtx high_dst = gen_highpart (SImode, operands[0]);
2942   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2944   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2945   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2946   /* We need something to tag the possible REG_EQUAL notes on to.  */
2947   emit_move_insn (operands[0], operands[0]);
2948   DONE;
2951 (define_insn "smulsi3_highpart_i"
2952   [(set (reg:SI MACH_REG)
2953         (truncate:SI
2954          (lshiftrt:DI
2955           (mult:DI
2956            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2957            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2958           (const_int 32))))
2959    (clobber (reg:SI MACL_REG))]
2960   "TARGET_SH2"
2961   "dmuls.l      %1,%0"
2962   [(set_attr "type" "dmpy")])
2964 (define_expand "smulsi3_highpart"
2965   [(parallel
2966     [(set (reg:SI MACH_REG)
2967           (truncate:SI
2968            (lshiftrt:DI
2969             (mult:DI
2970              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2971              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2972             (const_int 32))))
2973     (clobber (reg:SI MACL_REG))])
2974    (set (match_operand:SI 0 "arith_reg_operand" "")
2975         (reg:SI MACH_REG))]
2976   "TARGET_SH2"
2977   "
2979   rtx first, last;
2981   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2982   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2983   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2984      invariant code motion can move it.  */
2985   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2986   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2987   /* expand_binop can't find a suitable code in mul_highpart_optab to
2988      make a REG_EQUAL note from, so make one here.
2989      See also {,u}mulhisi.
2990      ??? Alternatively, we could put this at the calling site of expand_binop,
2991      i.e. expand_mult_highpart.  */
2992   REG_NOTES (last)
2993     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2994                          REG_NOTES (last));
2995   DONE;
2998 (define_insn "umulsi3_highpart_i"
2999   [(set (reg:SI MACH_REG)
3000         (truncate:SI
3001          (lshiftrt:DI
3002           (mult:DI
3003            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3004            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3005           (const_int 32))))
3006    (clobber (reg:SI MACL_REG))]
3007   "TARGET_SH2"
3008   "dmulu.l      %1,%0"
3009   [(set_attr "type" "dmpy")])
3011 (define_expand "umulsi3_highpart"
3012   [(parallel
3013     [(set (reg:SI MACH_REG)
3014           (truncate:SI
3015            (lshiftrt:DI
3016             (mult:DI
3017              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3018              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3019             (const_int 32))))
3020     (clobber (reg:SI MACL_REG))])
3021    (set (match_operand:SI 0 "arith_reg_operand" "")
3022         (reg:SI MACH_REG))]
3023   "TARGET_SH2"
3024   "
3026   rtx first, last;
3028   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3029   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
3030   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
3031      invariant code motion can move it.  */
3032   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
3033   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3034   DONE;
3037 (define_insn_and_split "muldi3"
3038   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3039         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3040                  (match_operand:DI 2 "arith_reg_operand" "r")))
3041    (clobber (match_scratch:DI 3 "=&r"))
3042    (clobber (match_scratch:DI 4 "=r"))]
3043   "TARGET_SHMEDIA"
3044   "#"
3045   "reload_completed"
3046   [(const_int 0)]
3047   "
3049   rtx op3_v2si, op2_v2si;
3051   op3_v2si = operands[3];
3052   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3053     {
3054       op3_v2si = XEXP (op3_v2si, 0);
3055       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3056     }
3057   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3058   op2_v2si = operands[2];
3059   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3060     {
3061       op2_v2si = XEXP (op2_v2si, 0);
3062       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3063     }
3064   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3065   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3066   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3067   emit_insn (gen_umulsidi3_media (operands[4],
3068                                  sh_gen_truncate (SImode, operands[1], 0),
3069                                  sh_gen_truncate (SImode, operands[2], 0)));
3070   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3071   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3072   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3073   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3074   DONE;
3078 ;; -------------------------------------------------------------------------
3079 ;; Logical operations
3080 ;; -------------------------------------------------------------------------
3082 (define_insn "*andsi3_compact"
3083   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3084         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3085                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3086   "TARGET_SH1"
3087   "and  %2,%0"
3088   [(set_attr "type" "arith")])
3090 (define_insn "*andsi3_media"
3091   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3092         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3093                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3094   "TARGET_SHMEDIA"
3095   "@
3096         and     %1, %2, %0
3097         andi    %1, %2, %0"
3098   [(set_attr "type" "arith_media")])
3100 ;; If the constant is 255, then emit an extu.b instruction instead of an
3101 ;; and, since that will give better code.
3103 (define_expand "andsi3"
3104   [(set (match_operand:SI 0 "arith_reg_operand" "")
3105         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3106                 (match_operand:SI 2 "logical_operand" "")))]
3107   ""
3108   "
3110   if (TARGET_SH1
3111       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3112     {
3113       emit_insn (gen_zero_extendqisi2 (operands[0],
3114                                        gen_lowpart (QImode, operands[1])));
3115       DONE;
3116     }
3119 (define_insn_and_split "anddi3"
3120   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3121         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3122                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3123   "TARGET_SHMEDIA"
3124   "@
3125         and     %1, %2, %0
3126         andi    %1, %2, %0
3127         #"
3128   "reload_completed
3129    && ! logical_operand (operands[2], DImode)"
3130   [(const_int 0)]
3131   "
3133   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3134     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3135   else
3136     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3137   DONE;
3139   [(set_attr "type" "arith_media")])
3141 (define_insn "andcsi3"
3142   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3143         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3144                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3145   "TARGET_SHMEDIA"
3146   "andc %1,%2,%0"
3147   [(set_attr "type" "arith_media")])
3149 (define_insn "andcdi3"
3150   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3151         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3152                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3153   "TARGET_SHMEDIA"
3154   "andc %1,%2,%0"
3155   [(set_attr "type" "arith_media")])
3157 (define_expand "iorsi3"
3158   [(set (match_operand:SI 0 "arith_reg_operand" "")
3159         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3160                 (match_operand:SI 2 "logical_operand" "")))]
3161   ""
3162   "")
3164 (define_insn "*iorsi3_compact"
3165   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3166         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3167                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3168   "TARGET_SH1"
3169   "or   %2,%0"
3170   [(set_attr "type" "arith")])
3172 (define_insn "*iorsi3_media"
3173   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3174         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3175                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3176   "TARGET_SHMEDIA"
3177   "@
3178         or      %1, %2, %0
3179         ori     %1, %2, %0"
3180   [(set_attr "type" "arith_media")])
3182 (define_insn "iordi3"
3183   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3184         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3185                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3186   "TARGET_SHMEDIA"
3187   "@
3188         or      %1, %2, %0
3189         ori     %1, %2, %0"
3190   [(set_attr "type" "arith_media")])
3192 (define_insn_and_split "*logical_sidi3"
3193   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3194         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3195                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3196                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3197   "TARGET_SHMEDIA"
3198   "#"
3199   "&& reload_completed"
3200   [(set (match_dup 0) (match_dup 3))]
3201   "
3203   operands[3]
3204     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3205                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3206                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3209 (define_insn_and_split "*logical_sidisi3"
3210   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3211         (truncate:SI (sign_extend:DI
3212                         (match_operator:SI 3 "logical_operator"
3213                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3214                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3215   "TARGET_SHMEDIA"
3216   "#"
3217   "&& 1"
3218   [(set (match_dup 0) (match_dup 3))])
3220 (define_insn_and_split "*logical_sidi3_2"
3221   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3222         (sign_extend:DI (truncate:SI (sign_extend:DI
3223                         (match_operator:SI 3 "logical_operator"
3224                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3225                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3226   "TARGET_SHMEDIA"
3227   "#"
3228   "&& 1"
3229   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3231 (define_expand "xorsi3"
3232   [(set (match_operand:SI 0 "arith_reg_operand" "")
3233         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3234                 (match_operand:SI 2 "xor_operand" "")))]
3235   ""
3236   "")
3238 (define_insn "*xorsi3_compact"
3239   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3240         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3241                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3242   "TARGET_SH1"
3243   "xor  %2,%0"
3244   [(set_attr "type" "arith")])
3246 (define_insn "*xorsi3_media"
3247   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3248         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3249                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3250   "TARGET_SHMEDIA"
3251   "@
3252         xor     %1, %2, %0
3253         xori    %1, %2, %0"
3254   [(set_attr "type" "arith_media")])
3256 (define_insn "xordi3"
3257   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3258         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3259                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3260   "TARGET_SHMEDIA"
3261   "@
3262         xor     %1, %2, %0
3263         xori    %1, %2, %0"
3264   [(set_attr "type" "arith_media")])
3266 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3267 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3268 (define_split
3269   [(set (match_operand:DI 0 "arith_reg_dest" "")
3270         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3271                           [(match_operand 1 "any_register_operand" "")
3272                            (match_operand 2 "any_register_operand" "")])))]
3273   "TARGET_SHMEDIA"
3274   [(set (match_dup 5) (match_dup 4))
3275    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3278   enum machine_mode inmode = GET_MODE (operands[1]);
3279   int offset = 0;
3281   if (GET_CODE (operands[0]) == SUBREG)
3282     {
3283       offset = SUBREG_BYTE (operands[0]);
3284       operands[0] = SUBREG_REG (operands[0]);
3285     }
3286   gcc_assert (GET_CODE (operands[0]) == REG);
3287   if (! TARGET_LITTLE_ENDIAN)
3288     offset += 8 - GET_MODE_SIZE (inmode);
3289   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3292 ;; -------------------------------------------------------------------------
3293 ;; Shifts and rotates
3294 ;; -------------------------------------------------------------------------
3296 (define_expand "rotldi3"
3297   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3298         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3299                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3300   "TARGET_SHMEDIA"
3301   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3303 (define_insn "rotldi3_mextr"
3304   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3305         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3306                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3307   "TARGET_SHMEDIA"
3308   "*
3310   static char templ[16];
3312   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3313            8 - (int) (INTVAL (operands[2]) >> 3));
3314   return templ;
3316   [(set_attr "type" "arith_media")])
3318 (define_expand "rotrdi3"
3319   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3320         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3321                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3322   "TARGET_SHMEDIA"
3323   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3325 (define_insn "rotrdi3_mextr"
3326   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3327         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3328                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3329   "TARGET_SHMEDIA"
3330   "*
3332   static char templ[16];
3334   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3335   return templ;
3337   [(set_attr "type" "arith_media")])
3339 (define_split
3340   [(set (match_operand:DI 0 "arith_reg_dest" "")
3341         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3342                                          "ua_address_operand" "")))
3343                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3344                            (const_int 8))))
3345    (clobber (match_operand:DI 3 "register_operand" ""))]
3346   "TARGET_SHMEDIA"
3347   [(match_dup 4) (match_dup 5)]
3348   "
3350   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3351                  (operands[3], operands[1]));
3352   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3353                               GEN_INT (56), GEN_INT (8));
3356 (define_insn "rotlsi3_1"
3357   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3358         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3359                    (const_int 1)))
3360    (set (reg:SI T_REG)
3361         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3362   "TARGET_SH1"
3363   "rotl %0"
3364   [(set_attr "type" "arith")])
3366 (define_insn "rotlsi3_31"
3367   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3368         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3369                    (const_int 31)))
3370    (clobber (reg:SI T_REG))]
3371   "TARGET_SH1"
3372   "rotr %0"
3373   [(set_attr "type" "arith")])
3375 (define_insn "rotlsi3_16"
3376   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3377         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3378                    (const_int 16)))]
3379   "TARGET_SH1"
3380   "swap.w       %1,%0"
3381   [(set_attr "type" "arith")])
3383 (define_expand "rotlsi3"
3384   [(set (match_operand:SI 0 "arith_reg_dest" "")
3385         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3386                    (match_operand:SI 2 "immediate_operand" "")))]
3387   "TARGET_SH1"
3388   "
3390   static const char rot_tab[] = {
3391     000, 000, 000, 000, 000, 000, 010, 001,
3392     001, 001, 011, 013, 003, 003, 003, 003,
3393     003, 003, 003, 003, 003, 013, 012, 002,
3394     002, 002, 010, 000, 000, 000, 000, 000,
3395   };
3397   int count, choice;
3399   if (GET_CODE (operands[2]) != CONST_INT)
3400     FAIL;
3401   count = INTVAL (operands[2]);
3402   choice = rot_tab[count];
3403   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3404     FAIL;
3405   choice &= 7;
3406   switch (choice)
3407     {
3408     case 0:
3409       emit_move_insn (operands[0], operands[1]);
3410       count -= (count & 16) * 2;
3411       break;
3412     case 3:
3413      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3414      count -= 16;
3415      break;
3416     case 1:
3417     case 2:
3418       {
3419         rtx parts[2];
3420         parts[0] = gen_reg_rtx (SImode);
3421         parts[1] = gen_reg_rtx (SImode);
3422         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3423         emit_move_insn (parts[choice-1], operands[1]);
3424         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3425         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3426         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3427         count = (count & ~16) - 8;
3428       }
3429     }
3431   for (; count > 0; count--)
3432     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3433   for (; count < 0; count++)
3434     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3436   DONE;
3439 (define_insn "*rotlhi3_8"
3440   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3441         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3442                    (const_int 8)))]
3443   "TARGET_SH1"
3444   "swap.b       %1,%0"
3445   [(set_attr "type" "arith")])
3447 (define_expand "rotlhi3"
3448   [(set (match_operand:HI 0 "arith_reg_operand" "")
3449         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3450                    (match_operand:HI 2 "immediate_operand" "")))]
3451   "TARGET_SH1"
3452   "
3454   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3455     FAIL;
3459 ;; shift left
3461 (define_insn "ashlsi3_sh2a"
3462   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3463         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3464                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3465   "TARGET_SH2A"
3466   "shad %2,%0"
3467   [(set_attr "type" "arith")
3468    (set_attr "length" "4")])
3470 ;; This pattern is used by init_expmed for computing the costs of shift
3471 ;; insns.
3473 (define_insn_and_split "ashlsi3_std"
3474   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3475         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3476                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3477    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3478   "TARGET_SH3
3479    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3480        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3481   "@
3482    shld %2,%0
3483    add  %0,%0
3484    shll%O2      %0
3485    #"
3486   "TARGET_SH3
3487    && reload_completed
3488    && GET_CODE (operands[2]) == CONST_INT
3489    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3490   [(set (match_dup 3) (match_dup 2))
3491    (parallel
3492     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3493      (clobber (match_dup 4))])]
3494   "operands[4] = gen_rtx_SCRATCH (SImode);"
3495   [(set_attr "length" "*,*,*,4")
3496    (set_attr "type" "dyn_shift,arith,arith,arith")])
3498 (define_insn "ashlhi3_k"
3499   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3500         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3501                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3502   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3503   "@
3504         add     %0,%0
3505         shll%O2 %0"
3506   [(set_attr "type" "arith")])
3508 (define_insn "ashlsi3_n"
3509   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3510         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3511                    (match_operand:SI 2 "const_int_operand" "n")))
3512    (clobber (reg:SI T_REG))]
3513   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3514   "#"
3515   [(set (attr "length")
3516         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3517                (const_string "2")
3518                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3519                (const_string "4")
3520                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3521                (const_string "6")]
3522               (const_string "8")))
3523    (set_attr "type" "arith")])
3525 (define_split
3526   [(set (match_operand:SI 0 "arith_reg_dest" "")
3527         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3528                    (match_operand:SI 2 "const_int_operand" "")))
3529    (clobber (reg:SI T_REG))]
3530   "TARGET_SH1 && reload_completed"
3531   [(use (reg:SI R0_REG))]
3532   "
3534   gen_shifty_op (ASHIFT, operands);
3535   DONE;
3538 (define_insn "ashlsi3_media"
3539   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3540         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3541                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3542   "TARGET_SHMEDIA"
3543   "@
3544         shlld.l %1, %2, %0
3545         shlli.l %1, %2, %0"
3546   [(set_attr "type" "arith_media")
3547    (set_attr "highpart" "ignore")])
3549 (define_expand "ashlsi3"
3550   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3551                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3552                               (match_operand:SI 2 "nonmemory_operand" "")))
3553               (clobber (reg:SI T_REG))])]
3554   ""
3555   "
3557   if (TARGET_SHMEDIA)
3558     {
3559       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3560       DONE;
3561     }
3562   if (GET_CODE (operands[2]) == CONST_INT
3563       && sh_dynamicalize_shift_p (operands[2]))
3564     operands[2] = force_reg (SImode, operands[2]);
3565   if (TARGET_SH3)
3566     {
3567       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3568       DONE;
3569     }
3570   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3571     FAIL;
3574 (define_insn "*ashlhi3_n"
3575   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3576         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3577                    (match_operand:HI 2 "const_int_operand" "n")))
3578    (clobber (reg:SI T_REG))]
3579   "TARGET_SH1"
3580   "#"
3581   [(set (attr "length")
3582         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3583                (const_string "2")
3584                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3585                (const_string "4")]
3586               (const_string "6")))
3587    (set_attr "type" "arith")])
3589 (define_expand "ashlhi3"
3590   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3591                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3592                               (match_operand:SI 2 "nonmemory_operand" "")))
3593               (clobber (reg:SI T_REG))])]
3594   "TARGET_SH1"
3595   "
3597   if (GET_CODE (operands[2]) != CONST_INT)
3598     FAIL;
3599   /* It may be possible to call gen_ashlhi3 directly with more generic
3600      operands.  Make sure operands[1] is a HImode register here.  */
3601   if (!arith_reg_operand (operands[1], HImode))
3602     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3605 (define_split
3606   [(set (match_operand:HI 0 "arith_reg_dest" "")
3607         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3608                    (match_operand:HI 2 "const_int_operand" "")))
3609    (clobber (reg:SI T_REG))]
3610   "TARGET_SH1 && reload_completed"
3611   [(use (reg:SI R0_REG))]
3612   "
3614   gen_shifty_hi_op (ASHIFT, operands);
3615   DONE;
3619 ; arithmetic shift right
3622 (define_insn "ashrsi3_sh2a"
3623   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3624         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3625                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3626   "TARGET_SH2A"
3627   "shad %2,%0"
3628   [(set_attr "type" "dyn_shift")
3629    (set_attr "length" "4")])
3631 (define_insn "ashrsi3_k"
3632   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3633         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3634                      (match_operand:SI 2 "const_int_operand" "M")))
3635    (clobber (reg:SI T_REG))]
3636   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3637   "shar %0"
3638   [(set_attr "type" "arith")])
3640 ;; We can't do HImode right shifts correctly unless we start out with an
3641 ;; explicit zero / sign extension; doing that would result in worse overall
3642 ;; code, so just let the machine independent code widen the mode.
3643 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3646 ;; ??? This should be a define expand.
3648 (define_insn "ashrsi2_16"
3649   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3650         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3651                      (const_int 16)))]
3652   "TARGET_SH1"
3653   "#"
3654   [(set_attr "length" "4")])
3656 (define_split
3657   [(set (match_operand:SI 0 "arith_reg_dest" "")
3658         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3659                      (const_int 16)))]
3660   "TARGET_SH1"
3661   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3662    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3663   "operands[2] = gen_lowpart (HImode, operands[0]);")
3665 ;; ??? This should be a define expand.
3667 (define_insn "ashrsi2_31"
3668   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3669         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3670                      (const_int 31)))
3671    (clobber (reg:SI T_REG))]
3672   "TARGET_SH1"
3673   "#"
3674   [(set_attr "length" "4")])
3676 (define_split
3677   [(set (match_operand:SI 0 "arith_reg_dest" "")
3678         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3679                      (const_int 31)))
3680    (clobber (reg:SI T_REG))]
3681   "TARGET_SH1"
3682   [(const_int 0)]
3683   "
3685   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3686   emit_insn (gen_mov_neg_si_t (operands[0]));
3687   DONE;
3690 (define_peephole2
3691   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3692    (set (reg:SI T_REG)
3693         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3694   "TARGET_SH1
3695    && peep2_reg_dead_p (2, operands[0])
3696    && peep2_reg_dead_p (2, operands[1])"
3697   [(const_int 0)]
3698   "
3700   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3701   DONE;
3704 (define_insn "ashlsi_c"
3705   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3706         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3707    (set (reg:SI T_REG)
3708         (lt:SI (match_dup 1) (const_int 0)))]
3709   "TARGET_SH1"
3710   "shll %0"
3711   [(set_attr "type" "arith")])
3713 (define_insn "*ashlsi_c_void"
3714   [(set (reg:SI T_REG)
3715         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3716    (clobber (match_scratch:SI 1 "=0"))]
3717   "TARGET_SH1 && cse_not_expected"
3718   "shll %0"
3719   [(set_attr "type" "arith")])
3721 (define_insn "ashrsi3_d"
3722   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3723         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3724                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3725   "TARGET_SH3"
3726   "shad %2,%0"
3727   [(set_attr "type" "dyn_shift")])
3729 (define_insn "ashrsi3_n"
3730   [(set (reg:SI R4_REG)
3731         (ashiftrt:SI (reg:SI R4_REG)
3732                      (match_operand:SI 0 "const_int_operand" "i")))
3733    (clobber (reg:SI T_REG))
3734    (clobber (reg:SI PR_REG))
3735    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3736   "TARGET_SH1"
3737   "jsr  @%1%#"
3738   [(set_attr "type" "sfunc")
3739    (set_attr "needs_delay_slot" "yes")])
3741 (define_insn "ashrsi3_media"
3742   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3743         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3744                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3745   "TARGET_SHMEDIA"
3746   "@
3747         shard.l %1, %2, %0
3748         shari.l %1, %2, %0"
3749   [(set_attr "type" "arith_media")
3750    (set_attr "highpart" "ignore")])
3752 (define_expand "ashrsi3"
3753   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3754                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3755                                 (match_operand:SI 2 "nonmemory_operand" "")))
3756               (clobber (reg:SI T_REG))])]
3757   ""
3758   "
3760   if (TARGET_SHMEDIA)
3761     {
3762       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3763       DONE;
3764     }
3765   if (expand_ashiftrt (operands))
3766     DONE;
3767   else
3768     FAIL;
3771 ;; logical shift right
3773 (define_insn "lshrsi3_sh2a"
3774   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3775         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3776                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3777   "TARGET_SH2A"
3778   "shld %2,%0"
3779   [(set_attr "type" "dyn_shift")
3780    (set_attr "length" "4")])
3782 (define_insn "lshrsi3_d"
3783   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3784         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3785                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3786   "TARGET_SH3"
3787   "shld %2,%0"
3788   [(set_attr "type" "dyn_shift")])
3790 ;;  Only the single bit shift clobbers the T bit.
3792 (define_insn "lshrsi3_m"
3793   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3794         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3795                      (match_operand:SI 2 "const_int_operand" "M")))
3796    (clobber (reg:SI T_REG))]
3797   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3798   "shlr %0"
3799   [(set_attr "type" "arith")])
3801 (define_insn "lshrsi3_k"
3802   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3803         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3804                      (match_operand:SI 2 "const_int_operand" "P27")))]
3805   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3806    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3807   "shlr%O2      %0"
3808   [(set_attr "type" "arith")])
3810 (define_insn "lshrsi3_n"
3811   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3812         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3813                      (match_operand:SI 2 "const_int_operand" "n")))
3814    (clobber (reg:SI T_REG))]
3815   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3816   "#"
3817   [(set (attr "length")
3818         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3819                (const_string "2")
3820                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3821                (const_string "4")
3822                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3823                (const_string "6")]
3824               (const_string "8")))
3825    (set_attr "type" "arith")])
3827 (define_split
3828   [(set (match_operand:SI 0 "arith_reg_dest" "")
3829         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3830                      (match_operand:SI 2 "const_int_operand" "")))
3831    (clobber (reg:SI T_REG))]
3832   "TARGET_SH1 && reload_completed"
3833   [(use (reg:SI R0_REG))]
3834   "
3836   gen_shifty_op (LSHIFTRT, operands);
3837   DONE;
3840 (define_insn "lshrsi3_media"
3841   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3842         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3843                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3844   "TARGET_SHMEDIA"
3845   "@
3846         shlrd.l %1, %2, %0
3847         shlri.l %1, %2, %0"
3848   [(set_attr "type" "arith_media")
3849    (set_attr "highpart" "ignore")])
3851 (define_expand "lshrsi3"
3852   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3853                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3854                                 (match_operand:SI 2 "nonmemory_operand" "")))
3855               (clobber (reg:SI T_REG))])]
3856   ""
3857   "
3859   if (TARGET_SHMEDIA)
3860     {
3861       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3862       DONE;
3863     }
3864   if (GET_CODE (operands[2]) == CONST_INT
3865       && sh_dynamicalize_shift_p (operands[2]))
3866     operands[2] = force_reg (SImode, operands[2]);
3867   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3868     {
3869       rtx count = copy_to_mode_reg (SImode, operands[2]);
3870       emit_insn (gen_negsi2 (count, count));
3871       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3872       DONE;
3873     }
3874   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3875     FAIL;
3878 ;; ??? This should be a define expand.
3880 (define_insn "ashldi3_k"
3881   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3882         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3883                    (const_int 1)))
3884    (clobber (reg:SI T_REG))]
3885   "TARGET_SH1"
3886   "shll %R0\;rotcl      %S0"
3887   [(set_attr "length" "4")
3888    (set_attr "type" "arith")])
3890 (define_insn "ashldi3_media"
3891   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3892         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3893                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3894   "TARGET_SHMEDIA"
3895   "@
3896         shlld   %1, %2, %0
3897         shlli   %1, %2, %0"
3898   [(set_attr "type" "arith_media")])
3900 (define_insn "*ashldisi3_media"
3901   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3902         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3903                    (match_operand:DI 2 "const_int_operand" "n")))]
3904   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3905   "shlli.l      %1, %2, %0"
3906   [(set_attr "type" "arith_media")
3907    (set_attr "highpart" "ignore")])
3909 (define_expand "ashldi3"
3910   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3911                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3912                               (match_operand:DI 2 "immediate_operand" "")))
3913               (clobber (reg:SI T_REG))])]
3914   ""
3915   "
3917   if (TARGET_SHMEDIA)
3918     {
3919       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3920       DONE;
3921     }
3922   if (GET_CODE (operands[2]) != CONST_INT
3923       || INTVAL (operands[2]) != 1)
3924     FAIL;
3927 ;; ??? This should be a define expand.
3929 (define_insn "lshrdi3_k"
3930   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3931         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3932                      (const_int 1)))
3933    (clobber (reg:SI T_REG))]
3934   "TARGET_SH1"
3935   "shlr %S0\;rotcr      %R0"
3936   [(set_attr "length" "4")
3937    (set_attr "type" "arith")])
3939 (define_insn "lshrdi3_media"
3940   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3941         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3942                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3943   "TARGET_SHMEDIA
3944    && (arith_reg_dest (operands[0], DImode)
3945        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3946   "@
3947         shlrd   %1, %2, %0
3948         shlri   %1, %2, %0"
3949   [(set_attr "type" "arith_media")])
3951 (define_insn "*lshrdisi3_media"
3952   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3953         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3954                      (match_operand:DI 2 "const_int_operand" "n")))]
3955   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3956   "shlri.l      %1, %2, %0"
3957   [(set_attr "type" "arith_media")
3958    (set_attr "highpart" "ignore")])
3960 (define_expand "lshrdi3"
3961   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3962                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3963                                (match_operand:DI 2 "immediate_operand" "")))
3964              (clobber (reg:SI T_REG))])]
3965   ""
3966   "
3968   if (TARGET_SHMEDIA)
3969     {
3970       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3971       DONE;
3972     }
3973   if (GET_CODE (operands[2]) != CONST_INT
3974       || INTVAL (operands[2]) != 1)
3975     FAIL;
3978 ;; ??? This should be a define expand.
3980 (define_insn "ashrdi3_k"
3981   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3982         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3983                      (const_int 1)))
3984    (clobber (reg:SI T_REG))]
3985   "TARGET_SH1"
3986   "shar %S0\;rotcr      %R0"
3987   [(set_attr "length" "4")
3988    (set_attr "type" "arith")])
3990 (define_insn "ashrdi3_media"
3991   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3992         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3993                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3994   "TARGET_SHMEDIA
3995    && (arith_reg_dest (operands[0], DImode)
3996        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3997   "@
3998         shard   %1, %2, %0
3999         shari   %1, %2, %0"
4000   [(set_attr "type" "arith_media")])
4002 (define_insn "*ashrdisi3_media"
4003   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4004         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4005                      (match_operand:DI 2 "const_int_operand" "n")))]
4006   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4007   "shari.l      %1, %2, %0"
4008   [(set_attr "type" "arith_media")
4009    (set_attr "highpart" "ignore")])
4011 (define_insn "ashrdisi3_media_high"
4012   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4013         (truncate:SI
4014            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4015                         (match_operand:DI 2 "const_int_operand" "n"))))]
4016   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4017   "shari        %1, %2, %0"
4018   [(set_attr "type" "arith_media")])
4020 (define_insn "ashrdisi3_media_opaque"
4021   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4022         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4023                     (match_operand:DI 2 "const_int_operand" "n")]
4024          UNSPEC_ASHIFTRT))]
4025   "TARGET_SHMEDIA"
4026   "shari        %1, %2, %0"
4027   [(set_attr "type" "arith_media")])
4029 (define_expand "ashrdi3"
4030   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4031                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4032                                 (match_operand:DI 2 "immediate_operand" "")))
4033               (clobber (reg:SI T_REG))])]
4034   ""
4035   "
4037   if (TARGET_SHMEDIA)
4038     {
4039       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4040       DONE;
4041     }
4042   if (GET_CODE (operands[2]) != CONST_INT
4043       || INTVAL (operands[2]) != 1)
4044     FAIL;
4047 ;; combined left/right shift
4049 (define_split
4050   [(set (match_operand:SI 0 "register_operand" "")
4051         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4052                            (match_operand:SI 2 "const_int_operand" ""))
4053                 (match_operand:SI 3 "const_int_operand" "")))]
4054   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4055   [(use (reg:SI R0_REG))]
4056   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4057    DONE;")
4059 (define_split
4060   [(set (match_operand:SI 0 "register_operand" "")
4061         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4062                            (match_operand:SI 2 "const_int_operand" ""))
4063                 (match_operand:SI 3 "const_int_operand" "")))
4064    (clobber (reg:SI T_REG))]
4065   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4066   [(use (reg:SI R0_REG))]
4067   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4068    DONE;")
4070 (define_insn ""
4071   [(set (match_operand:SI 0 "register_operand" "=r")
4072         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4073                            (match_operand:SI 2 "const_int_operand" "n"))
4074                 (match_operand:SI 3 "const_int_operand" "n")))
4075    (clobber (reg:SI T_REG))]
4076   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4077  "#"
4078   [(set (attr "length")
4079         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4080                (const_string "4")
4081                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4082                (const_string "6")
4083                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4084                (const_string "8")
4085                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4086                (const_string "10")
4087                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4088                (const_string "12")
4089                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4090                (const_string "14")
4091                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4092                (const_string "16")]
4093               (const_string "18")))
4094    (set_attr "type" "arith")])
4096 (define_insn ""
4097   [(set (match_operand:SI 0 "register_operand" "=z")
4098         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4099                            (match_operand:SI 2 "const_int_operand" "n"))
4100                 (match_operand:SI 3 "const_int_operand" "n")))
4101    (clobber (reg:SI T_REG))]
4102   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4103  "#"
4104   [(set (attr "length")
4105         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4106                (const_string "4")
4107                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4108                (const_string "6")
4109                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4110                (const_string "8")]
4111               (const_string "10")))
4112    (set_attr "type" "arith")])
4114 ;; shift left / and combination with a scratch register: The combine pass
4115 ;; does not accept the individual instructions, even though they are
4116 ;; cheap.  But it needs a precise description so that it is usable after
4117 ;; reload.
4118 (define_insn "and_shl_scratch"
4119   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4120         (lshiftrt:SI
4121          (ashift:SI
4122           (and:SI
4123            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4124                         (match_operand:SI 2 "const_int_operand" "N,n"))
4125            (match_operand:SI 3 "" "0,r"))
4126           (match_operand:SI 4 "const_int_operand" "n,n"))
4127          (match_operand:SI 5 "const_int_operand" "n,n")))
4128    (clobber (reg:SI T_REG))]
4129   "TARGET_SH1"
4130   "#"
4131   [(set (attr "length")
4132         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4133                (const_string "4")
4134                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4135                (const_string "6")
4136                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4137                (const_string "8")
4138                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4139                (const_string "10")]
4140               (const_string "12")))
4141    (set_attr "type" "arith")])
4143 (define_split
4144   [(set (match_operand:SI 0 "register_operand" "")
4145         (lshiftrt:SI
4146          (ashift:SI
4147           (and:SI
4148            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4149                         (match_operand:SI 2 "const_int_operand" ""))
4150            (match_operand:SI 3 "register_operand" ""))
4151           (match_operand:SI 4 "const_int_operand" ""))
4152          (match_operand:SI 5 "const_int_operand" "")))
4153    (clobber (reg:SI T_REG))]
4154   "TARGET_SH1"
4155   [(use (reg:SI R0_REG))]
4156   "
4158   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4160   if (INTVAL (operands[2]))
4161     {
4162       gen_shifty_op (LSHIFTRT, operands);
4163     }
4164   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4165   operands[2] = operands[4];
4166   gen_shifty_op (ASHIFT, operands);
4167   if (INTVAL (operands[5]))
4168     {
4169       operands[2] = operands[5];
4170       gen_shifty_op (LSHIFTRT, operands);
4171     }
4172   DONE;
4175 ;; signed left/right shift combination.
4176 (define_split
4177   [(set (match_operand:SI 0 "register_operand" "")
4178         (sign_extract:SI
4179          (ashift:SI (match_operand:SI 1 "register_operand" "")
4180                     (match_operand:SI 2 "const_int_operand" ""))
4181          (match_operand:SI 3 "const_int_operand" "")
4182          (const_int 0)))
4183    (clobber (reg:SI T_REG))]
4184   "TARGET_SH1"
4185   [(use (reg:SI R0_REG))]
4186   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4187    DONE;")
4189 (define_insn "shl_sext_ext"
4190   [(set (match_operand:SI 0 "register_operand" "=r")
4191         (sign_extract:SI
4192          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4193                     (match_operand:SI 2 "const_int_operand" "n"))
4194          (match_operand:SI 3 "const_int_operand" "n")
4195          (const_int 0)))
4196    (clobber (reg:SI T_REG))]
4197   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4198   "#"
4199   [(set (attr "length")
4200         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4201                (const_string "2")
4202                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4203                (const_string "4")
4204                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4205                (const_string "6")
4206                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4207                (const_string "8")
4208                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4209                (const_string "10")
4210                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4211                (const_string "12")
4212                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4213                (const_string "14")
4214                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4215                (const_string "16")]
4216               (const_string "18")))
4217     (set_attr "type" "arith")])
4219 (define_insn "shl_sext_sub"
4220   [(set (match_operand:SI 0 "register_operand" "=z")
4221         (sign_extract:SI
4222          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4223                     (match_operand:SI 2 "const_int_operand" "n"))
4224          (match_operand:SI 3 "const_int_operand" "n")
4225          (const_int 0)))
4226    (clobber (reg:SI T_REG))]
4227   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4228   "#"
4229   [(set (attr "length")
4230         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4231                (const_string "6")
4232                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4233                (const_string "8")
4234                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4235                (const_string "10")
4236                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4237                (const_string "12")]
4238               (const_string "14")))
4239     (set_attr "type" "arith")])
4241 ;; These patterns are found in expansions of DImode shifts by 16, and
4242 ;; allow the xtrct instruction to be generated from C source.
4244 (define_insn "xtrct_left"
4245   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4246         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4247                            (const_int 16))
4248                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4249                              (const_int 16))))]
4250   "TARGET_SH1"
4251   "xtrct        %1,%0"
4252   [(set_attr "type" "arith")])
4254 (define_insn "xtrct_right"
4255   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4256         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4257                              (const_int 16))
4258                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4259                            (const_int 16))))]
4260   "TARGET_SH1"
4261   "xtrct        %2,%0"
4262   [(set_attr "type" "arith")])
4264 ;; -------------------------------------------------------------------------
4265 ;; Unary arithmetic
4266 ;; -------------------------------------------------------------------------
4268 (define_insn "negc"
4269   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4270         (neg:SI (plus:SI (reg:SI T_REG)
4271                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4272    (set (reg:SI T_REG)
4273         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4274                (const_int 0)))]
4275   "TARGET_SH1"
4276   "negc %1,%0"
4277   [(set_attr "type" "arith")])
4279 (define_insn "*negdi_media"
4280   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4281         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4282   "TARGET_SHMEDIA"
4283   "sub  r63, %1, %0"
4284   [(set_attr "type" "arith_media")])
4286 (define_expand "negdi2"
4287   [(set (match_operand:DI 0 "arith_reg_operand" "")
4288         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4289   ""
4290   "
4292   if (TARGET_SH1)
4293     {
4294       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4295       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4297       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4298       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4300       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4301       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4303       emit_insn (gen_clrt ());
4304       emit_insn (gen_negc (low_dst, low_src));
4305       emit_insn (gen_negc (high_dst, high_src));
4306       DONE;
4307     }
4310 (define_insn "negsi2"
4311   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4312         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4313   "TARGET_SH1"
4314   "neg  %1,%0"
4315   [(set_attr "type" "arith")])
4317 (define_insn "one_cmplsi2"
4318   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4319         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4320   "TARGET_SH1"
4321   "not  %1,%0"
4322   [(set_attr "type" "arith")])
4324 (define_expand "one_cmpldi2"
4325   [(set (match_operand:DI 0 "arith_reg_dest" "")
4326         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4327                 (const_int -1)))]
4328   "TARGET_SHMEDIA" "")
4330 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4331    This can be used as some kind of conditional execution, which is useful
4332    for abs.  */
4333 (define_split
4334   [(set (match_operand:SI 0 "arith_reg_dest" "")
4335         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4336                          (match_operand:SI 1 "arith_reg_operand" ""))
4337                  (reg:SI T_REG)))]
4338   "TARGET_HARD_SH4"
4339   [(const_int 0)]
4340   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4341    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4342    DONE;")
4344 (define_insn "cneg"
4345   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4346         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4347                       (match_operand:SI 1 "arith_reg_operand" "0")
4348                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4349   "TARGET_HARD_SH4"
4350   "bf 0f\;neg %2,%0\\n0:"
4351   [(set_attr "type" "arith") ;; poor approximation
4352    (set_attr "length" "4")])
4355 ;; -------------------------------------------------------------------------
4356 ;; Zero extension instructions
4357 ;; -------------------------------------------------------------------------
4359 (define_insn "zero_extendsidi2"
4360   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4361         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4362   "TARGET_SHMEDIA"
4363   "addz.l       %1, r63, %0"
4364   [(set_attr "type" "arith_media")
4365    (set_attr "highpart" "extend")])
4367 (define_insn "zero_extendhidi2"
4368   [(set (match_operand:DI 0 "register_operand" "=r,r")
4369         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4370   "TARGET_SHMEDIA"
4371   "@
4372         #
4373         ld%M1.uw        %m1, %0"
4374   [(set_attr "type" "*,load_media")
4375    (set (attr "highpart")
4376         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4377                (const_string "user")]
4378               (const_string "ignore")))])
4380 (define_split
4381   [(set (match_operand:DI 0 "register_operand" "")
4382         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4383   "TARGET_SHMEDIA && reload_completed"
4384   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4385    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4386   "
4388   if (GET_CODE (operands[1]) == TRUNCATE)
4389     operands[1] = XEXP (operands[1], 0);
4392 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4393 ;; reload the entire truncate expression.
4394 (define_insn_and_split "*loaddi_trunc"
4395   [(set (match_operand 0 "any_register_operand" "=r")
4396         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4397   "TARGET_SHMEDIA && reload_completed"
4398   "#"
4399   "TARGET_SHMEDIA && reload_completed"
4400   [(set (match_dup 0) (match_dup 1))]
4401   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4403 (define_insn "zero_extendqidi2"
4404   [(set (match_operand:DI 0 "register_operand" "=r,r")
4405         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4406   "TARGET_SHMEDIA"
4407   "@
4408         andi    %1, 255, %0
4409         ld%M1.ub        %m1, %0"
4410   [(set_attr "type" "arith_media,load_media")
4411    (set (attr "highpart")
4412         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4413                (const_string "user")]
4414               (const_string "ignore")))])
4416 (define_expand "zero_extendhisi2"
4417   [(set (match_operand:SI 0 "arith_reg_operand" "")
4418         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4419   ""
4420   "
4422   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4423     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4426 (define_insn "*zero_extendhisi2_compact"
4427   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4428         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4429   "TARGET_SH1"
4430   "extu.w       %1,%0"
4431   [(set_attr "type" "arith")])
4433 (define_insn "*zero_extendhisi2_media"
4434   [(set (match_operand:SI 0 "register_operand" "=r,r")
4435         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4436   "TARGET_SHMEDIA"
4437   "@
4438         #
4439         ld%M1.uw        %m1, %0"
4440   [(set_attr "type" "arith_media,load_media")
4441    (set (attr "highpart")
4442         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4443                (const_string "user")]
4444               (const_string "ignore")))])
4446 (define_split
4447   [(set (match_operand:SI 0 "register_operand" "")
4448         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4449   "TARGET_SHMEDIA && reload_completed"
4450   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4451    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4452   "
4454   rtx op1 = operands[1];
4456   if (GET_CODE (op1) == TRUNCATE)
4457     op1 = XEXP (op1, 0);
4458   operands[2]
4459     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4460                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4463 (define_expand "zero_extendqisi2"
4464   [(set (match_operand:SI 0 "arith_reg_operand" "")
4465         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4466   ""
4467   "
4469   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4470     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4473 (define_insn "*zero_extendqisi2_compact"
4474   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4475         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4476   "TARGET_SH1"
4477   "extu.b       %1,%0"
4478   [(set_attr "type" "arith")])
4480 (define_insn "*zero_extendqisi2_media"
4481   [(set (match_operand:SI 0 "register_operand" "=r,r")
4482         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4483   "TARGET_SHMEDIA"
4484   "@
4485         andi    %1, 255, %0
4486         ld%M1.ub        %m1, %0"
4487   [(set_attr "type" "arith_media,load_media")
4488    (set (attr "highpart")
4489         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4490                (const_string "user")]
4491               (const_string "ignore")))])
4493 (define_insn "zero_extendqihi2"
4494   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4495         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4496   "TARGET_SH1"
4497   "extu.b       %1,%0"
4498   [(set_attr "type" "arith")])
4500 ;; -------------------------------------------------------------------------
4501 ;; Sign extension instructions
4502 ;; -------------------------------------------------------------------------
4504 ;; ??? This should be a define expand.
4505 ;; ??? Or perhaps it should be dropped?
4507 ;; convert_move generates good code for SH[1-4].
4508 (define_insn "extendsidi2"
4509   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4510         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4511   "TARGET_SHMEDIA"
4512   "@
4513         add.l   %1, r63, %0
4514         ld%M1.l %m1, %0
4515         fmov.sl %1, %0"
4516   [(set_attr "type" "arith_media,load_media,fpconv_media")
4517    (set (attr "highpart")
4518         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4519                (const_string "user")]
4520               (const_string "extend")))])
4522 (define_insn "extendhidi2"
4523   [(set (match_operand:DI 0 "register_operand" "=r,r")
4524         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4525   "TARGET_SHMEDIA"
4526   "@
4527         #
4528         ld%M1.w %m1, %0"
4529   [(set_attr "type" "*,load_media")
4530    (set (attr "highpart")
4531         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4532                (const_string "user")]
4533               (const_string "ignore")))])
4535 (define_split
4536   [(set (match_operand:DI 0 "register_operand" "")
4537         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4538   "TARGET_SHMEDIA && reload_completed"
4539   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4540    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4541   "
4543   if (GET_CODE (operands[1]) == TRUNCATE)
4544     operands[1] = XEXP (operands[1], 0);
4547 (define_insn "extendqidi2"
4548   [(set (match_operand:DI 0 "register_operand" "=r,r")
4549         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4550   "TARGET_SHMEDIA"
4551   "@
4552         #
4553         ld%M1.b %m1, %0"
4554   [(set_attr "type" "*,load_media")
4555    (set (attr "highpart")
4556         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4557                (const_string "user")]
4558               (const_string "ignore")))])
4560 (define_split
4561   [(set (match_operand:DI 0 "register_operand" "")
4562         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4563   "TARGET_SHMEDIA && reload_completed"
4564   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4565    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4566   "
4568   if (GET_CODE (operands[1]) == TRUNCATE)
4569     operands[1] = XEXP (operands[1], 0);
4572 (define_expand "extendhisi2"
4573   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4574         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4575   ""
4576   "")
4578 (define_insn "*extendhisi2_compact"
4579   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4580         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4581   "TARGET_SH1"
4582   "@
4583         exts.w  %1,%0
4584         mov.w   %1,%0"
4585   [(set_attr "type" "arith,load")])
4587 (define_insn "*extendhisi2_media"
4588   [(set (match_operand:SI 0 "register_operand" "=r,r")
4589         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4590   "TARGET_SHMEDIA"
4591   "@
4592         #
4593         ld%M1.w %m1, %0"
4594   [(set_attr "type" "arith_media,load_media")
4595    (set (attr "highpart")
4596         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4597                (const_string "user")]
4598               (const_string "ignore")))])
4600 (define_split
4601   [(set (match_operand:SI 0 "register_operand" "")
4602         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4603   "TARGET_SHMEDIA && reload_completed"
4604   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4605    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4606   "
4608   rtx op1 = operands[1];
4609   if (GET_CODE (op1) == TRUNCATE)
4610     op1 = XEXP (op1, 0);
4611   operands[2]
4612     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4613                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4616 (define_expand "extendqisi2"
4617   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4618         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4619   ""
4620   "")
4622 (define_insn "*extendqisi2_compact"
4623   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4624         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4625   "TARGET_SH1"
4626   "@
4627         exts.b  %1,%0
4628         mov.b   %1,%0"
4629   [(set_attr "type" "arith,load")])
4631 (define_insn "*extendqisi2_media"
4632   [(set (match_operand:SI 0 "register_operand" "=r,r")
4633         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4634   "TARGET_SHMEDIA"
4635   "@
4636         #
4637         ld%M1.b %m1, %0"
4638   [(set_attr "type" "arith_media,load_media")
4639    (set (attr "highpart")
4640         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4641                (const_string "user")]
4642               (const_string "ignore")))])
4644 (define_split
4645   [(set (match_operand:SI 0 "register_operand" "")
4646         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4647   "TARGET_SHMEDIA && reload_completed"
4648   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4649    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4650    "
4652   rtx op1 = operands[1];
4653   if (GET_CODE (op1) == TRUNCATE)
4654     op1 = XEXP (op1, 0);
4655   operands[2]
4656     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4657                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4660 (define_insn "extendqihi2"
4661   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4662         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4663   "TARGET_SH1"
4664   "@
4665         exts.b  %1,%0
4666         mov.b   %1,%0"
4667   [(set_attr "type" "arith,load")])
4669 /* It would seem useful to combine the truncXi patterns into the movXi
4670    patterns, but unary operators are ignored when matching constraints,
4671    so we need separate patterns.  */
4672 (define_insn "truncdisi2"
4673   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4674         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4675   "TARGET_SHMEDIA"
4676   "@
4677         add.l   %1, r63, %0
4678         st%M0.l %m0, %1
4679         fst%M0.s        %m0, %T1
4680         fmov.ls %1, %0
4681         fmov.sl %T1, %0
4682         fmov.s  %T1, %0"
4683   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4684    (set (attr "highpart")
4685         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4686                (const_string "user")]
4687               (const_string "extend")))])
4689 (define_insn "truncdihi2"
4690   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4691         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4692   "TARGET_SHMEDIA"
4693   "@
4694         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4695         st%M0.w %m0, %1"
4696   [(set_attr "type"   "arith_media,store_media")
4697    (set_attr "length" "8,4")
4698    (set (attr "highpart")
4699         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4700                (const_string "user")]
4701               (const_string "extend")))])
4703 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4704 ; Because we use zero extension, we can't provide signed QImode compares
4705 ; using a simple compare or conditional banch insn.
4706 (define_insn "truncdiqi2"
4707   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4708         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4709   "TARGET_SHMEDIA"
4710   "@
4711         andi    %1, 255, %0
4712         st%M0.b %m0, %1"
4713   [(set_attr "type"   "arith_media,store")
4714    (set (attr "highpart")
4715         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4716                (const_string "user")]
4717               (const_string "extend")))])
4718 ;; -------------------------------------------------------------------------
4719 ;; Move instructions
4720 ;; -------------------------------------------------------------------------
4722 ;; define push and pop so it is easy for sh.c
4723 ;; We can't use push and pop on SHcompact because the stack must always
4724 ;; be 8-byte aligned.
4726 (define_expand "push"
4727   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4728         (match_operand:SI 0 "register_operand" "r,l,x"))]
4729   "TARGET_SH1 && ! TARGET_SH5"
4730   "")
4732 (define_expand "pop"
4733   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4734         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4735   "TARGET_SH1 && ! TARGET_SH5"
4736   "")
4738 (define_expand "push_e"
4739   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4740                    (match_operand:SF 0 "" ""))
4741               (use (reg:PSI FPSCR_REG))
4742               (clobber (scratch:SI))])]
4743   "TARGET_SH1 && ! TARGET_SH5"
4744   "")
4746 (define_insn "push_fpul"
4747   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4748   "TARGET_SH2E && ! TARGET_SH5"
4749   "sts.l        fpul,@-r15"
4750   [(set_attr "type" "store")
4751    (set_attr "late_fp_use" "yes")
4752    (set_attr "hit_stack" "yes")])
4754 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4755 ;; so use that.
4756 (define_expand "push_4"
4757   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4758                    (match_operand:DF 0 "" ""))
4759               (use (reg:PSI FPSCR_REG))
4760               (clobber (scratch:SI))])]
4761   "TARGET_SH1 && ! TARGET_SH5"
4762   "")
4764 (define_expand "pop_e"
4765   [(parallel [(set (match_operand:SF 0 "" "")
4766               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4767               (use (reg:PSI FPSCR_REG))
4768               (clobber (scratch:SI))])]
4769   "TARGET_SH1 && ! TARGET_SH5"
4770   "")
4772 (define_insn "pop_fpul"
4773   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4774   "TARGET_SH2E && ! TARGET_SH5"
4775   "lds.l        @r15+,fpul"
4776   [(set_attr "type" "load")
4777    (set_attr "hit_stack" "yes")])
4779 (define_expand "pop_4"
4780   [(parallel [(set (match_operand:DF 0 "" "")
4781                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4782               (use (reg:PSI FPSCR_REG))
4783               (clobber (scratch:SI))])]
4784   "TARGET_SH1 && ! TARGET_SH5"
4785   "")
4787 (define_expand "push_fpscr"
4788   [(const_int 0)]
4789   "TARGET_SH2E"
4790   "
4792   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4793                                                  gen_rtx_PRE_DEC (Pmode,
4794                                                           stack_pointer_rtx)),
4795                                         get_fpscr_rtx ()));
4796   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4797   DONE;
4800 (define_expand "pop_fpscr"
4801   [(const_int 0)]
4802   "TARGET_SH2E"
4803   "
4805   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4806                                         gen_frame_mem (PSImode,
4807                                                  gen_rtx_POST_INC (Pmode,
4808                                                           stack_pointer_rtx))));
4809   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4810   DONE;
4813 ;; These two patterns can happen as the result of optimization, when
4814 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4815 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4817 (define_insn "clrt"
4818   [(set (reg:SI T_REG) (const_int 0))]
4819   "TARGET_SH1"
4820   "clrt")
4822 (define_insn "sett"
4823   [(set (reg:SI T_REG) (const_int 1))]
4824   "TARGET_SH1"
4825   "sett")
4827 ;; t/r must come after r/r, lest reload will try to reload stuff like
4828 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4829 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4830 (define_insn "movsi_i"
4831   [(set (match_operand:SI 0 "general_movdst_operand"
4832             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4833         (match_operand:SI 1 "general_movsrc_operand"
4834          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4835   "TARGET_SH1
4836    && ! TARGET_SH2E
4837    && ! TARGET_SH2A
4838    && (register_operand (operands[0], SImode)
4839        || register_operand (operands[1], SImode))"
4840   "@
4841         mov.l   %1,%0
4842         mov     %1,%0
4843         cmp/pl  %1
4844         mov.l   %1,%0
4845         sts     %1,%0
4846         sts     %1,%0
4847         movt    %0
4848         mov.l   %1,%0
4849         sts.l   %1,%0
4850         sts.l   %1,%0
4851         lds     %1,%0
4852         lds     %1,%0
4853         lds.l   %1,%0
4854         lds.l   %1,%0
4855         fake    %1,%0"
4856   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4857    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4859 ;; t/r must come after r/r, lest reload will try to reload stuff like
4860 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4861 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4862 ;; will require a reload.
4863 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4864 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4865 (define_insn "movsi_ie"
4866   [(set (match_operand:SI 0 "general_movdst_operand"
4867             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4868         (match_operand:SI 1 "general_movsrc_operand"
4869          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4870   "(TARGET_SH2E || TARGET_SH2A)
4871    && (register_operand (operands[0], SImode)
4872        || register_operand (operands[1], SImode))"
4873   "@
4874         mov.l   %1,%0
4875         mov     %1,%0
4876         movi20  %1,%0
4877         cmp/pl  %1
4878         mov.l   %1,%0
4879         sts     %1,%0
4880         sts     %1,%0
4881         movt    %0
4882         mov.l   %1,%0
4883         sts.l   %1,%0
4884         sts.l   %1,%0
4885         lds     %1,%0
4886         lds     %1,%0
4887         lds.l   %1,%0
4888         lds.l   %1,%0
4889         lds.l   %1,%0
4890         sts.l   %1,%0
4891         fake    %1,%0
4892         lds     %1,%0
4893         sts     %1,%0
4894         fsts    fpul,%0
4895         flds    %1,fpul
4896         fmov    %1,%0
4897         ! move optimized away"
4898   [(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")
4899    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4900    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4902 (define_insn "movsi_i_lowpart"
4903   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4904         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4905    "TARGET_SH1
4906     && (register_operand (operands[0], SImode)
4907         || register_operand (operands[1], SImode))"
4908   "@
4909         mov.l   %1,%0
4910         mov     %1,%0
4911         mov.l   %1,%0
4912         sts     %1,%0
4913         sts     %1,%0
4914         movt    %0
4915         mov.l   %1,%0
4916         fake    %1,%0"
4917   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4919 (define_insn_and_split "load_ra"
4920   [(set (match_operand:SI 0 "general_movdst_operand" "")
4921         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4922   "TARGET_SH1"
4923   "#"
4924   "&& ! currently_expanding_to_rtl"
4925   [(set (match_dup 0) (match_dup 1))]
4926   "
4928   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4929     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4932 ;; The '?'s in the following constraints may not reflect the time taken
4933 ;; to perform the move. They are there to discourage the use of floating-
4934 ;; point registers for storing integer values.
4935 (define_insn "*movsi_media"
4936   [(set (match_operand:SI 0 "general_movdst_operand"
4937                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4938         (match_operand:SI 1 "general_movsrc_operand"
4939          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4940   "TARGET_SHMEDIA_FPU
4941    && (register_operand (operands[0], SImode)
4942        || sh_register_operand (operands[1], SImode)
4943        || GET_CODE (operands[1]) == TRUNCATE)"
4944   "@
4945         add.l   %1, r63, %0
4946         movi    %1, %0
4947         #
4948         ld%M1.l %m1, %0
4949         st%M0.l %m0, %N1
4950         fld%M1.s        %m1, %0
4951         fst%M0.s        %m0, %1
4952         fmov.ls %N1, %0
4953         fmov.sl %1, %0
4954         fmov.s  %1, %0
4955         ptabs   %1, %0
4956         gettr   %1, %0
4957         pt      %1, %0"
4958   [(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")
4959    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4960    (set (attr "highpart")
4961         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4962                (const_string "user")]
4963               (const_string "ignore")))])
4965 (define_insn "*movsi_media_nofpu"
4966   [(set (match_operand:SI 0 "general_movdst_operand"
4967                 "=r,r,r,r,m,*b,r,*b")
4968         (match_operand:SI 1 "general_movsrc_operand"
4969          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
4970   "TARGET_SHMEDIA
4971    && (register_operand (operands[0], SImode)
4972        || sh_register_operand (operands[1], SImode)
4973        || GET_CODE (operands[1]) == TRUNCATE)"
4974   "@
4975         add.l   %1, r63, %0
4976         movi    %1, %0
4977         #
4978         ld%M1.l %m1, %0
4979         st%M0.l %m0, %N1
4980         ptabs   %1, %0
4981         gettr   %1, %0
4982         pt      %1, %0"
4983   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4984    (set_attr "length" "4,4,8,4,4,4,4,12")
4985    (set (attr "highpart")
4986         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4987                (const_string "user")]
4988               (const_string "ignore")))])
4990 (define_expand "movsi_const"
4991   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4992         (const:SI (sign_extend:SI
4993                    (truncate:HI
4994                     (ashiftrt:SI
4995                      (match_operand:DI 1 "immediate_operand" "s")
4996                      (const_int 16))))))
4997    (set (match_dup 0)
4998         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4999                 (const:SI
5000                   (zero_extend:SI
5001                    (truncate:HI (match_dup 1))))))]
5002   "TARGET_SHMEDIA && reload_completed
5003    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5004   "
5006   if (GET_CODE (operands[1]) == LABEL_REF
5007       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5008     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5009   else if (GOTOFF_P (operands[1]))
5010     {
5011       rtx unspec = XEXP (operands[1], 0);
5013       if (! UNSPEC_GOTOFF_P (unspec))
5014         {
5015           unspec = XEXP (unspec, 0);
5016           if (! UNSPEC_GOTOFF_P (unspec))
5017             abort ();
5018         }
5019       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5020           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5021         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5022     }
5025 (define_expand "movsi_const_16bit"
5026   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5027         (const:SI (sign_extend:SI
5028                    (truncate:HI
5029                     (match_operand:DI 1 "immediate_operand" "s")))))]
5030   "TARGET_SHMEDIA && flag_pic && reload_completed
5031    && GET_CODE (operands[1]) == SYMBOL_REF"
5032   "")
5034 (define_split
5035   [(set (match_operand:SI 0 "arith_reg_dest" "")
5036         (match_operand:SI 1 "immediate_operand" ""))]
5037   "TARGET_SHMEDIA && reload_completed
5038    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5039   [(const_int 0)]
5040   "
5042   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5044   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5045                                         REG_NOTES (insn));
5047   DONE;
5050 (define_split
5051   [(set (match_operand:SI 0 "register_operand" "")
5052         (match_operand:SI 1 "immediate_operand" ""))]
5053   "TARGET_SHMEDIA && reload_completed
5054    && ((GET_CODE (operands[1]) == CONST_INT
5055         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
5056        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5057   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5059 (define_expand "movsi"
5060   [(set (match_operand:SI 0 "general_movdst_operand" "")
5061         (match_operand:SI 1 "general_movsrc_operand" ""))]
5062   ""
5063   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5065 (define_expand "ic_invalidate_line"
5066   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5067                                 (match_dup 1)] UNSPEC_ICACHE)
5068               (clobber (scratch:SI))])]
5069   "TARGET_HARD_SH4 || TARGET_SH5"
5070   "
5072   if (TARGET_SHMEDIA)
5073     {
5074       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5075       DONE;
5076     }
5077   else if (TARGET_SHCOMPACT)
5078     {
5079       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5080       operands[1] = force_reg (Pmode, operands[1]);
5081       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5082       DONE;
5083     }
5084   else if (TARGET_SH4A_ARCH)
5085     {
5086       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5087       DONE;
5088     }
5089   operands[0] = force_reg (Pmode, operands[0]);
5090   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5091                                                                Pmode)));
5094 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5095 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5096 ;; the requirement *1*00 for associative address writes.  The alignment of
5097 ;; %0 implies that its least significant bit is cleared,
5098 ;; thus we clear the V bit of a matching entry if there is one.
5099 (define_insn "ic_invalidate_line_i"
5100   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5101                      (match_operand:SI 1 "register_operand" "r")]
5102                      UNSPEC_ICACHE)
5103    (clobber (match_scratch:SI 2 "=&r"))]
5104   "TARGET_HARD_SH4"
5105   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5106   [(set_attr "length" "8")
5107    (set_attr "type" "cwb")])
5109 (define_insn "ic_invalidate_line_sh4a"
5110   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5111                     UNSPEC_ICACHE)]
5112   "TARGET_SH4A_ARCH"
5113   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5114   [(set_attr "length" "16")
5115    (set_attr "type" "cwb")])
5117 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5118 ;; an add in the code that calculates the address.
5119 (define_insn "ic_invalidate_line_media"
5120   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5121                     UNSPEC_ICACHE)]
5122   "TARGET_SHMEDIA"
5123   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5124   [(set_attr "length" "16")
5125    (set_attr "type" "invalidate_line_media")])
5127 (define_insn "ic_invalidate_line_compact"
5128   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5129                      (match_operand:SI 1 "register_operand" "r")]
5130                     UNSPEC_ICACHE)
5131    (clobber (reg:SI PR_REG))]
5132   "TARGET_SHCOMPACT"
5133   "jsr @%1%#"
5134   [(set_attr "type" "sfunc")
5135    (set_attr "needs_delay_slot" "yes")])
5137 (define_expand "initialize_trampoline"
5138   [(match_operand:SI 0 "" "")
5139    (match_operand:SI 1 "" "")
5140    (match_operand:SI 2 "" "")]
5141   "TARGET_SHCOMPACT"
5142   "
5144   rtx sfun, tramp;
5146   tramp = force_reg (Pmode, operands[0]);
5147   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5148                                             SFUNC_STATIC));
5149   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5150   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5152   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5153   DONE;
5156 (define_insn "initialize_trampoline_compact"
5157   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5158                      (match_operand:SI 1 "register_operand" "r")
5159                      (reg:SI R2_REG) (reg:SI R3_REG)]
5160                     UNSPEC_INIT_TRAMP)
5162    (clobber (reg:SI PR_REG))]
5163   "TARGET_SHCOMPACT"
5164   "jsr @%1%#"
5165   [(set_attr "type" "sfunc")
5166    (set_attr "needs_delay_slot" "yes")])
5168 (define_insn "movqi_i"
5169   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5170         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
5171   "TARGET_SH1
5172    && (arith_reg_operand (operands[0], QImode)
5173        || arith_reg_operand (operands[1], QImode))"
5174   "@
5175         mov     %1,%0
5176         mov.b   %1,%0
5177         mov.b   %1,%0
5178         movt    %0
5179         sts     %1,%0
5180         lds     %1,%0"
5181  [(set_attr "type" "move,load,store,move,move,move")])
5183 (define_insn "*movqi_media"
5184   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5185         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5186   "TARGET_SHMEDIA
5187    && (arith_reg_operand (operands[0], QImode)
5188        || extend_reg_or_0_operand (operands[1], QImode))"
5189   "@
5190         add.l   %1, r63, %0
5191         movi    %1, %0
5192         ld%M1.ub        %m1, %0
5193         st%M0.b %m0, %N1"
5194   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5195    (set (attr "highpart")
5196         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5197                (const_string "user")]
5198               (const_string "ignore")))])
5200 (define_expand "movqi"
5201   [(set (match_operand:QI 0 "general_operand" "")
5202         (match_operand:QI 1 "general_operand"  ""))]
5203   ""
5204   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5206 (define_expand "reload_inqi"
5207   [(set (match_operand:SI 2 "" "=&r")
5208         (match_operand:QI 1 "inqhi_operand" ""))
5209    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5210         (truncate:QI (match_dup 3)))]
5211   "TARGET_SHMEDIA"
5212   "
5214   rtx inner = XEXP (operands[1], 0);
5215   int regno = REGNO (inner);
5217   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5218   operands[1] = gen_rtx_REG (SImode, regno);
5219   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5222 /* When storing r0, we have to avoid reg+reg addressing.  */
5223 (define_insn "movhi_i"
5224   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5225         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5226   "TARGET_SH1
5227    && (arith_reg_operand (operands[0], HImode)
5228        || arith_reg_operand (operands[1], HImode))
5229    && (GET_CODE (operands[0]) != MEM
5230        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5231        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5232        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5233   "@
5234         mov.w   %1,%0
5235         mov     %1,%0
5236         mov.w   %1,%0
5237         movt    %0
5238         mov.w   %1,%0
5239         sts     %1,%0
5240         lds     %1,%0
5241         fake    %1,%0"
5242   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5244 (define_insn "*movhi_media"
5245   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5246         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5247   "TARGET_SHMEDIA
5248    && (arith_reg_operand (operands[0], HImode)
5249        || arith_reg_or_0_operand (operands[1], HImode))"
5250   "@
5251         add.l   %1, r63, %0
5252         movi    %1, %0
5253         #
5254         ld%M1.w %m1, %0
5255         st%M0.w %m0, %N1"
5256   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5257    (set (attr "highpart")
5258         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5259                (const_string "user")]
5260               (const_string "ignore")))])
5262 (define_split
5263   [(set (match_operand:HI 0 "register_operand" "")
5264         (match_operand:HI 1 "immediate_operand" ""))]
5265   "TARGET_SHMEDIA && reload_completed
5266    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5267   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5269 (define_expand "movhi"
5270   [(set (match_operand:HI 0 "general_movdst_operand" "")
5271         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5272   ""
5273   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5275 (define_expand "reload_inhi"
5276   [(set (match_operand:SI 2 "" "=&r")
5277         (match_operand:HI 1 "inqhi_operand" ""))
5278    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5279         (truncate:HI (match_dup 3)))]
5280   "TARGET_SHMEDIA"
5281   "
5283   rtx inner = XEXP (operands[1], 0);
5284   int regno = REGNO (inner);
5286   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5287   operands[1] = gen_rtx_REG (SImode, regno);
5288   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5291 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5292 ;; compiled with -m2 -ml -O3 -funroll-loops
5293 (define_insn "*movdi_i"
5294   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5295         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5296   "TARGET_SH1
5297    && (arith_reg_operand (operands[0], DImode)
5298        || arith_reg_operand (operands[1], DImode))"
5299   "* return output_movedouble (insn, operands, DImode);"
5300   [(set_attr "length" "4")
5301    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5303 ;; If the output is a register and the input is memory or a register, we have
5304 ;; to be careful and see which word needs to be loaded first.
5306 (define_split
5307   [(set (match_operand:DI 0 "general_movdst_operand" "")
5308         (match_operand:DI 1 "general_movsrc_operand" ""))]
5309   "TARGET_SH1 && reload_completed"
5310   [(set (match_dup 2) (match_dup 3))
5311    (set (match_dup 4) (match_dup 5))]
5312   "
5314   int regno;
5316   if ((GET_CODE (operands[0]) == MEM
5317        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5318       || (GET_CODE (operands[1]) == MEM
5319           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5320     FAIL;
5322   switch (GET_CODE (operands[0]))
5323     {
5324     case REG:
5325       regno = REGNO (operands[0]);
5326       break;
5327     case SUBREG:
5328       regno = subreg_regno (operands[0]);
5329       break;
5330     case MEM:
5331       regno = -1;
5332       break;
5333     default:
5334       gcc_unreachable ();
5335     }
5337   if (regno == -1
5338       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5339     {
5340       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5341       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5342       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5343       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5344     }
5345   else
5346     {
5347       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5348       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5349       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5350       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5351     }
5353   if (operands[2] == 0 || operands[3] == 0
5354       || operands[4] == 0 || operands[5] == 0)
5355     FAIL;
5358 ;; The '?'s in the following constraints may not reflect the time taken
5359 ;; to perform the move. They are there to discourage the use of floating-
5360 ;; point registers for storing integer values.
5361 (define_insn "*movdi_media"
5362   [(set (match_operand:DI 0 "general_movdst_operand"
5363                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5364         (match_operand:DI 1 "general_movsrc_operand"
5365          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5366   "TARGET_SHMEDIA_FPU
5367    && (register_operand (operands[0], DImode)
5368        || sh_register_operand (operands[1], DImode))"
5369   "@
5370         add     %1, r63, %0
5371         movi    %1, %0
5372         #
5373         ld%M1.q %m1, %0
5374         st%M0.q %m0, %N1
5375         fld%M1.d        %m1, %0
5376         fst%M0.d        %m0, %1
5377         fmov.qd %N1, %0
5378         fmov.dq %1, %0
5379         fmov.d  %1, %0
5380         ptabs   %1, %0
5381         gettr   %1, %0
5382         pt      %1, %0"
5383   [(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")
5384    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5386 (define_insn "*movdi_media_nofpu"
5387   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5388         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5389   "TARGET_SHMEDIA
5390    && (register_operand (operands[0], DImode)
5391        || sh_register_operand (operands[1], DImode))"
5392   "@
5393         add     %1, r63, %0
5394         movi    %1, %0
5395         #
5396         ld%M1.q %m1, %0
5397         st%M0.q %m0, %N1
5398         ptabs   %1, %0
5399         gettr   %1, %0
5400         pt      %1, %0"
5401   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5402    (set_attr "length" "4,4,16,4,4,4,4,*")])
5404 (define_insn "*movdi_media_I16"
5405   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5406         (match_operand:DI 1 "const_int_operand" "I16"))]
5407   "TARGET_SHMEDIA && reload_completed"
5408   "movi %1, %0"
5409   [(set_attr "type" "arith_media")
5410    (set_attr "length" "4")])
5412 (define_split
5413   [(set (match_operand:DI 0 "arith_reg_dest" "")
5414         (match_operand:DI 1 "immediate_operand" ""))]
5415   "TARGET_SHMEDIA && reload_completed
5416    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5417   [(set (match_dup 0) (match_dup 1))]
5418   "
5420   rtx insn;
5422   if (TARGET_SHMEDIA64)
5423     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5424   else
5425     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5427   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5428                                         REG_NOTES (insn));
5430   DONE;
5433 (define_expand "movdi_const"
5434   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5435         (const:DI (sign_extend:DI
5436                    (truncate:HI
5437                     (ashiftrt:DI
5438                      (match_operand:DI 1 "immediate_operand" "s")
5439                      (const_int 48))))))
5440    (set (match_dup 0)
5441         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5442                 (const:DI
5443                  (zero_extend:DI
5444                   (truncate:HI
5445                    (ashiftrt:SI
5446                     (match_dup 1)
5447                     (const_int 32)))))))
5448    (set (match_dup 0)
5449         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5450                 (const:DI
5451                  (zero_extend:DI
5452                   (truncate:HI
5453                    (ashiftrt:SI
5454                     (match_dup 1)
5455                     (const_int 16)))))))
5456    (set (match_dup 0)
5457         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5458                 (const:DI
5459                  (zero_extend:DI
5460                   (truncate:HI
5461                    (match_dup 1))))))]
5462   "TARGET_SHMEDIA64 && reload_completed
5463    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5464   "
5466   sh_mark_label (operands[1], 4);
5469 (define_expand "movdi_const_32bit"
5470   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5471         (const:DI (sign_extend:DI
5472                    (truncate:HI
5473                     (ashiftrt:DI
5474                      (match_operand:DI 1 "immediate_operand" "s")
5475                      (const_int 16))))))
5476    (set (match_dup 0)
5477         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5478                 (const:DI
5479                  (zero_extend:DI
5480                   (truncate:HI
5481                    (match_dup 1))))))]
5482   "TARGET_SHMEDIA32 && reload_completed
5483    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5484   "
5486   sh_mark_label (operands[1], 2);
5489 (define_expand "movdi_const_16bit"
5490   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5491         (const:DI (sign_extend:DI
5492                    (truncate:HI
5493                     (match_operand:DI 1 "immediate_operand" "s")))))]
5494   "TARGET_SHMEDIA && flag_pic && reload_completed
5495    && GET_CODE (operands[1]) == SYMBOL_REF"
5496   "")
5498 (define_split
5499   [(set (match_operand:DI 0 "ext_dest_operand" "")
5500         (match_operand:DI 1 "immediate_operand" ""))]
5501   "TARGET_SHMEDIA && reload_completed
5502    && GET_CODE (operands[1]) == CONST_INT
5503    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5504   [(set (match_dup 0) (match_dup 2))
5505    (match_dup 1)]
5506   "
5508   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5509   unsigned HOST_WIDE_INT low = val;
5510   unsigned HOST_WIDE_INT high = val;
5511   unsigned HOST_WIDE_INT sign;
5512   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5514   /* Zero-extend the 16 least-significant bits.  */
5515   low &= 0xffff;
5517   /* Arithmetic shift right the word by 16 bits.  */
5518   high >>= 16;
5519   if (GET_CODE (operands[0]) == SUBREG
5520       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5521     {
5522       high &= 0xffff;
5523       high ^= 0x8000;
5524       high -= 0x8000;
5525     }
5526   else
5527     {
5528       sign = 1;
5529       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5530       high ^= sign;
5531       high -= sign;
5532     }
5533   do
5534     {
5535       /* If we can't generate the constant with a two-insn movi / shori
5536          sequence, try some other strategies.  */
5537       if (! CONST_OK_FOR_I16 (high))
5538         {
5539           /* Try constant load / left shift.  We know VAL != 0.  */
5540           val2 = val ^ (val-1);
5541           if (val2 > 0x1ffff)
5542             {
5543               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5545               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5546                   || (! CONST_OK_FOR_I16 (high >> 16)
5547                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5548                 {
5549                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5550                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5551                                                    GEN_INT (trailing_zeroes));
5552                   break;
5553                 }
5554             }
5555           /* Try constant load / right shift.  */
5556           val2 = (val >> 15) + 1;
5557           if (val2 == (val2 & -val2))
5558             {
5559               int shift = 49 - exact_log2 (val2);
5561               val2 = trunc_int_for_mode (val << shift, DImode);
5562               if (CONST_OK_FOR_I16 (val2))
5563                 {
5564                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5565                                                    GEN_INT (shift));
5566                   break;
5567                 }
5568             }
5569           /* Try mperm.w .  */
5570           val2 = val & 0xffff;
5571           if ((val >> 16 & 0xffff) == val2
5572               && (val >> 32 & 0xffff) == val2
5573               && (val >> 48 & 0xffff) == val2)
5574             {
5575               val2 = (HOST_WIDE_INT) val >> 48;
5576               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5577               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5578               break;
5579             }
5580           /* Try movi / mshflo.l  */
5581           val2 = (HOST_WIDE_INT) val >> 32;
5582           if (val2 == ((unsigned HOST_WIDE_INT)
5583                         trunc_int_for_mode (val, SImode)))
5584             {
5585               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5586                                              operands[0]);
5587               break;
5588             }
5589           /* Try movi / mshflo.l w/ r63.  */
5590           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5591           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5592             {
5593               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5594                                              const0_rtx);
5595               break;
5596             }
5597         }
5598       val2 = high;
5599       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5600     }
5601   while (0);
5602   operands[2] = GEN_INT (val2);
5605 (define_split
5606   [(set (match_operand:DI 0 "ext_dest_operand" "")
5607         (match_operand:DI 1 "immediate_operand" ""))]
5608   "TARGET_SHMEDIA && reload_completed
5609    && GET_CODE (operands[1]) == CONST_DOUBLE"
5610   [(set (match_dup 0) (match_dup 2))
5611   (set (match_dup 0)
5612        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5613   "
5615   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5616   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5617   unsigned HOST_WIDE_INT val = low;
5618   unsigned HOST_WIDE_INT sign;
5620   /* Zero-extend the 16 least-significant bits.  */
5621   val &= 0xffff;
5622   operands[1] = GEN_INT (val);
5624   /* Arithmetic shift right the double-word by 16 bits.  */
5625   low >>= 16;
5626   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5627   high >>= 16;
5628   sign = 1;
5629   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5630   high ^= sign;
5631   high -= sign;
5633   /* This will only be true if high is a sign-extension of low, i.e.,
5634      it must be either 0 or (unsigned)-1, and be zero iff the
5635      most-significant bit of low is set.  */
5636   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5637     operands[2] = GEN_INT (low);
5638   else
5639     operands[2] = immed_double_const (low, high, DImode);
5642 (define_insn "shori_media"
5643   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5644         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5645                            (const_int 16))
5646                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5647   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5648   "@
5649         shori   %u2, %0
5650         #"
5651   [(set_attr "type" "arith_media,*")])
5653 (define_insn "*shori_media_si"
5654   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5655         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5656                            (const_int 16))
5657                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5658   "TARGET_SHMEDIA"
5659   "shori        %u2, %0")
5661 (define_expand "movdi"
5662   [(set (match_operand:DI 0 "general_movdst_operand" "")
5663         (match_operand:DI 1 "general_movsrc_operand" ""))]
5664   ""
5665   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5667 (define_insn "movdf_media"
5668   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5669         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5670   "TARGET_SHMEDIA_FPU
5671    && (register_operand (operands[0], DFmode)
5672        || sh_register_operand (operands[1], DFmode))"
5673   "@
5674         fmov.d  %1, %0
5675         fmov.qd %N1, %0
5676         fmov.dq %1, %0
5677         add     %1, r63, %0
5678         #
5679         fld%M1.d        %m1, %0
5680         fst%M0.d        %m0, %1
5681         ld%M1.q %m1, %0
5682         st%M0.q %m0, %N1"
5683   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5685 (define_insn "movdf_media_nofpu"
5686   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5687         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5688   "TARGET_SHMEDIA
5689    && (register_operand (operands[0], DFmode)
5690        || sh_register_operand (operands[1], DFmode))"
5691   "@
5692         add     %1, r63, %0
5693         #
5694         ld%M1.q %m1, %0
5695         st%M0.q %m0, %N1"
5696   [(set_attr "type" "arith_media,*,load_media,store_media")])
5698 (define_split
5699   [(set (match_operand:DF 0 "arith_reg_dest" "")
5700         (match_operand:DF 1 "immediate_operand" ""))]
5701   "TARGET_SHMEDIA && reload_completed"
5702   [(set (match_dup 3) (match_dup 2))]
5703   "
5705   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5706   long values[2];
5707   REAL_VALUE_TYPE value;
5709   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5710   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5712   if (HOST_BITS_PER_WIDE_INT >= 64)
5713     operands[2] = immed_double_const ((unsigned long) values[endian]
5714                                       | ((HOST_WIDE_INT) values[1 - endian]
5715                                          << 32), 0, DImode);
5716   else
5717     {
5718       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5719       operands[2] = immed_double_const (values[endian], values[1 - endian],
5720                                         DImode);
5721     }
5723   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5726 ;; ??? This should be a define expand.
5728 (define_insn "movdf_k"
5729   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5730         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5731   "TARGET_SH1
5732    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5733        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5734        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5735        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5736    && (arith_reg_operand (operands[0], DFmode)
5737        || arith_reg_operand (operands[1], DFmode))"
5738   "* return output_movedouble (insn, operands, DFmode);"
5739   [(set_attr "length" "4")
5740    (set_attr "type" "move,pcload,load,store")])
5742 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5743 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5744 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5745 ;; the d/m/c/X alternative, which is split later into single-precision
5746 ;; instructions.  And when not optimizing, no splits are done before fixing
5747 ;; up pcloads, so we need usable length information for that.
5748 (define_insn "movdf_i4"
5749   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5750         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5751    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5752    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5753   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5754    && (arith_reg_operand (operands[0], DFmode)
5755        || arith_reg_operand (operands[1], DFmode))"
5756   "@
5757         fmov    %1,%0
5758         #
5759         #
5760         fmov.d  %1,%0
5761         fmov.d  %1,%0
5762         #
5763         #
5764         #
5765         #
5766         #"
5767   [(set_attr_alternative "length"
5768      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5769       (const_int 4)
5770       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5771       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5772       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5773       (const_int 4)
5774       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5775       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5776       ;; increment or decrement r15 explicitly.
5777       (if_then_else
5778        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5779        (const_int 10) (const_int 8))
5780       (if_then_else
5781        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5782        (const_int 10) (const_int 8))])
5783    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5784    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5785    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5786                                            (const_string "double")
5787                                            (const_string "none")))])
5789 ;; Moving DFmode between fp/general registers through memory
5790 ;; (the top of the stack) is faster than moving through fpul even for
5791 ;; little endian.  Because the type of an instruction is important for its
5792 ;; scheduling,  it is beneficial to split these operations, rather than
5793 ;; emitting them in one single chunk, even if this will expose a stack
5794 ;; use that will prevent scheduling of other stack accesses beyond this
5795 ;; instruction.
5796 (define_split
5797   [(set (match_operand:DF 0 "register_operand" "")
5798         (match_operand:DF 1 "register_operand" ""))
5799    (use (match_operand:PSI 2 "fpscr_operand" ""))
5800    (clobber (match_scratch:SI 3 "=X"))]
5801   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5802    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5803   [(const_int 0)]
5804   "
5806   rtx insn, tos;
5808   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5809     {
5810       emit_move_insn (stack_pointer_rtx,
5811                       plus_constant (stack_pointer_rtx, -8));
5812       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5813     }
5814   else
5815     tos = gen_tmp_stack_mem (DFmode,
5816                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5817   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5818   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5819     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5820   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5821     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5822   else
5823     tos = gen_tmp_stack_mem (DFmode,
5824                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5825   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5826   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5827     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5828   else
5829     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5830   DONE;
5833 ;; local-alloc sometimes allocates scratch registers even when not required,
5834 ;; so we must be prepared to handle these.
5836 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5837 (define_split
5838   [(set (match_operand:DF 0 "general_movdst_operand" "")
5839         (match_operand:DF 1 "general_movsrc_operand"  ""))
5840    (use (match_operand:PSI 2 "fpscr_operand" ""))
5841    (clobber (match_scratch:SI 3 ""))]
5842   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5843    && reload_completed
5844    && true_regnum (operands[0]) < 16
5845    && true_regnum (operands[1]) < 16"
5846   [(set (match_dup 0) (match_dup 1))]
5847   "
5849   /* If this was a reg <-> mem operation with base + index reg addressing,
5850      we have to handle this in a special way.  */
5851   rtx mem = operands[0];
5852   int store_p = 1;
5853   if (! memory_operand (mem, DFmode))
5854     {
5855       mem = operands[1];
5856       store_p = 0;
5857     }
5858   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5859     mem = SUBREG_REG (mem);
5860   if (GET_CODE (mem) == MEM)
5861     {
5862       rtx addr = XEXP (mem, 0);
5863       if (GET_CODE (addr) == PLUS
5864           && GET_CODE (XEXP (addr, 0)) == REG
5865           && GET_CODE (XEXP (addr, 1)) == REG)
5866         {
5867           int offset;
5868           rtx reg0 = gen_rtx_REG (Pmode, 0);
5869           rtx regop = operands[store_p], word0 ,word1;
5871           if (GET_CODE (regop) == SUBREG)
5872             alter_subreg (&regop);
5873           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5874             offset = 2;
5875           else
5876             offset = 4;
5877           mem = copy_rtx (mem);
5878           PUT_MODE (mem, SImode);
5879           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5880           alter_subreg (&word0);
5881           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5882           alter_subreg (&word1);
5883           if (store_p || ! refers_to_regno_p (REGNO (word0),
5884                                               REGNO (word0) + 1, addr, 0))
5885             {
5886               emit_insn (store_p
5887                          ? gen_movsi_ie (mem, word0)
5888                          : gen_movsi_ie (word0, mem));
5889               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5890               mem = copy_rtx (mem);
5891               emit_insn (store_p
5892                          ? gen_movsi_ie (mem, word1)
5893                          : gen_movsi_ie (word1, mem));
5894               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5895             }
5896           else
5897             {
5898               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5899               emit_insn (gen_movsi_ie (word1, mem));
5900               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5901               mem = copy_rtx (mem);
5902               emit_insn (gen_movsi_ie (word0, mem));
5903             }
5904           DONE;
5905         }
5906     }
5909 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5910 (define_split
5911   [(set (match_operand:DF 0 "register_operand" "")
5912         (match_operand:DF 1 "memory_operand"  ""))
5913    (use (match_operand:PSI 2 "fpscr_operand" ""))
5914    (clobber (reg:SI R0_REG))]
5915   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5916   [(parallel [(set (match_dup 0) (match_dup 1))
5917               (use (match_dup 2))
5918               (clobber (scratch:SI))])]
5919   "")
5921 (define_expand "reload_indf__frn"
5922   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5923                    (match_operand:DF 1 "immediate_operand" "FQ"))
5924               (use (reg:PSI FPSCR_REG))
5925               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5926   "TARGET_SH1"
5927   "")
5929 (define_expand "reload_outdf__RnFRm"
5930   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5931                    (match_operand:DF 1 "register_operand" "af,r"))
5932               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5933   "TARGET_SH1"
5934   "")
5936 ;; Simplify no-op moves.
5937 (define_split
5938   [(set (match_operand:SF 0 "register_operand" "")
5939         (match_operand:SF 1 "register_operand" ""))
5940    (use (match_operand:PSI 2 "fpscr_operand" ""))
5941    (clobber (match_scratch:SI 3 ""))]
5942   "TARGET_SH2E && reload_completed
5943    && true_regnum (operands[0]) == true_regnum (operands[1])"
5944   [(set (match_dup 0) (match_dup 0))]
5945   "")
5947 ;; fmovd substitute post-reload splits
5948 (define_split
5949   [(set (match_operand:DF 0 "register_operand" "")
5950         (match_operand:DF 1 "register_operand" ""))
5951    (use (match_operand:PSI 2 "fpscr_operand" ""))
5952    (clobber (match_scratch:SI 3 ""))]
5953   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5954    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5955    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5956   [(const_int 0)]
5957   "
5959   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5960   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5961                            gen_rtx_REG (SFmode, src), operands[2]));
5962   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5963                            gen_rtx_REG (SFmode, src + 1), operands[2]));
5964   DONE;
5967 (define_split
5968   [(set (match_operand:DF 0 "register_operand" "")
5969         (mem:DF (match_operand:SI 1 "register_operand" "")))
5970    (use (match_operand:PSI 2 "fpscr_operand" ""))
5971    (clobber (match_scratch:SI 3 ""))]
5972   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5973    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5974    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5975   [(const_int 0)]
5976   "
5978   int regno = true_regnum (operands[0]);
5979   rtx insn;
5980   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5981   rtx mem2
5982     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5983   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5984                                            regno + !! TARGET_LITTLE_ENDIAN),
5985                                   mem2, operands[2]));
5986   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5987   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5988                                                regno + ! TARGET_LITTLE_ENDIAN),
5989                                   change_address (mem, SFmode, NULL_RTX),
5990                                   operands[2]));
5991   DONE;
5994 (define_split
5995   [(set (match_operand:DF 0 "register_operand" "")
5996         (match_operand:DF 1 "memory_operand" ""))
5997    (use (match_operand:PSI 2 "fpscr_operand" ""))
5998    (clobber (match_scratch:SI 3 ""))]
5999   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6000    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6001   [(const_int 0)]
6002   "
6004   int regno = true_regnum (operands[0]);
6005   rtx addr, insn, adjust = NULL_RTX;
6006   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6007   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6008   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6010   operands[1] = copy_rtx (mem2);
6011   addr = XEXP (mem2, 0);
6012   if (GET_CODE (addr) != POST_INC)
6013     {
6014       /* If we have to modify the stack pointer, the value that we have
6015          read with post-increment might be modified by an interrupt,
6016          so write it back.  */
6017       if (REGNO (addr) == STACK_POINTER_REGNUM)
6018         adjust = gen_push_e (reg0);
6019       else
6020         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6021       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6022     }
6023   addr = XEXP (addr, 0);
6024   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6025   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6026   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6027   if (adjust)
6028     emit_insn (adjust);
6029   else
6030     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6031   DONE;
6034 (define_split
6035   [(set (match_operand:DF 0 "memory_operand" "")
6036         (match_operand:DF 1 "register_operand" ""))
6037    (use (match_operand:PSI 2 "fpscr_operand" ""))
6038    (clobber (match_scratch:SI 3 ""))]
6039   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6040    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6041   [(const_int 0)]
6042   "
6044   int regno = true_regnum (operands[1]);
6045   rtx insn, addr, adjust = NULL_RTX;
6047   operands[0] = copy_rtx (operands[0]);
6048   PUT_MODE (operands[0], SFmode);
6049   insn = emit_insn (gen_movsf_ie (operands[0],
6050                                   gen_rtx_REG (SFmode,
6051                                            regno + ! TARGET_LITTLE_ENDIAN),
6052                                   operands[2]));
6053   operands[0] = copy_rtx (operands[0]);
6054   addr = XEXP (operands[0], 0);
6055   if (GET_CODE (addr) != PRE_DEC)
6056     {
6057       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6058       emit_insn_before (adjust, insn);
6059       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6060     }
6061   addr = XEXP (addr, 0);
6062   if (! adjust)
6063     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6064   insn = emit_insn (gen_movsf_ie (operands[0],
6065                                   gen_rtx_REG (SFmode,
6066                                            regno + !! TARGET_LITTLE_ENDIAN),
6067                                   operands[2]));
6068   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6069   DONE;
6072 ;; If the output is a register and the input is memory or a register, we have
6073 ;; to be careful and see which word needs to be loaded first.
6075 (define_split
6076   [(set (match_operand:DF 0 "general_movdst_operand" "")
6077         (match_operand:DF 1 "general_movsrc_operand" ""))]
6078   "TARGET_SH1 && reload_completed"
6079   [(set (match_dup 2) (match_dup 3))
6080    (set (match_dup 4) (match_dup 5))]
6081   "
6083   int regno;
6085   if ((GET_CODE (operands[0]) == MEM
6086        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6087       || (GET_CODE (operands[1]) == MEM
6088           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6089     FAIL;
6091   switch (GET_CODE (operands[0]))
6092     {
6093     case REG:
6094       regno = REGNO (operands[0]);
6095       break;
6096     case SUBREG:
6097       regno = subreg_regno (operands[0]);
6098       break;
6099     case MEM:
6100       regno = -1;
6101       break;
6102     default:
6103       gcc_unreachable ();
6104     }
6106   if (regno == -1
6107       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6108     {
6109       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6110       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6111       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6112       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6113     }
6114   else
6115     {
6116       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6117       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6118       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6119       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6120     }
6122   if (operands[2] == 0 || operands[3] == 0
6123       || operands[4] == 0 || operands[5] == 0)
6124     FAIL;
6127 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6128 ;; used only once, let combine add in the index again.
6130 (define_split
6131   [(set (match_operand:SI 0 "register_operand" "")
6132         (match_operand:SI 1 "" ""))
6133    (clobber (match_operand 2 "register_operand" ""))]
6134   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6135    && ALLOW_INDEXED_ADDRESS"
6136   [(use (reg:SI R0_REG))]
6137   "
6139   rtx addr, reg, const_int;
6141   if (GET_CODE (operands[1]) != MEM)
6142     FAIL;
6143   addr = XEXP (operands[1], 0);
6144   if (GET_CODE (addr) != PLUS)
6145     FAIL;
6146   reg = XEXP (addr, 0);
6147   const_int = XEXP (addr, 1);
6148   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6149          && GET_CODE (const_int) == CONST_INT))
6150     FAIL;
6151   emit_move_insn (operands[2], const_int);
6152   emit_move_insn (operands[0],
6153                   change_address (operands[1], VOIDmode,
6154                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6155   DONE;
6158 (define_split
6159   [(set (match_operand:SI 1 "" "")
6160         (match_operand:SI 0 "register_operand" ""))
6161    (clobber (match_operand 2 "register_operand" ""))]
6162   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6163    && ALLOW_INDEXED_ADDRESS"
6164   [(use (reg:SI R0_REG))]
6165   "
6167   rtx addr, reg, const_int;
6169   if (GET_CODE (operands[1]) != MEM)
6170     FAIL;
6171   addr = XEXP (operands[1], 0);
6172   if (GET_CODE (addr) != PLUS)
6173     FAIL;
6174   reg = XEXP (addr, 0);
6175   const_int = XEXP (addr, 1);
6176   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6177          && GET_CODE (const_int) == CONST_INT))
6178     FAIL;
6179   emit_move_insn (operands[2], const_int);
6180   emit_move_insn (change_address (operands[1], VOIDmode,
6181                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6182                   operands[0]);
6183   DONE;
6186 (define_expand "movdf"
6187   [(set (match_operand:DF 0 "general_movdst_operand" "")
6188         (match_operand:DF 1 "general_movsrc_operand" ""))]
6189   ""
6190   "
6192   if (prepare_move_operands (operands, DFmode)) DONE;
6193   if (TARGET_SHMEDIA)
6194     {
6195       if (TARGET_SHMEDIA_FPU)
6196         emit_insn (gen_movdf_media (operands[0], operands[1]));
6197       else
6198         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6199       DONE;
6200     }
6201   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6202     {
6203       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6204       DONE;
6205     }
6208 ;;This is incompatible with the way gcc uses subregs.
6209 ;;(define_insn "movv2sf_i"
6210 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6211 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6212 ;;  "TARGET_SHMEDIA_FPU
6213 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6214 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6215 ;;  "@
6216 ;;      #
6217 ;;      fld%M1.p        %m1, %0
6218 ;;      fst%M0.p        %m0, %1"
6219 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6221 (define_insn_and_split "movv2sf_i"
6222   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6223         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6224   "TARGET_SHMEDIA_FPU"
6225   "#"
6226   "TARGET_SHMEDIA_FPU && reload_completed"
6227   [(set (match_dup 0) (match_dup 1))]
6228   "
6230   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6231   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6234 (define_expand "movv2sf"
6235   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6236         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6237   "TARGET_SHMEDIA_FPU"
6238   "
6240   if (prepare_move_operands (operands, V2SFmode))
6241     DONE;
6244 (define_expand "addv2sf3"
6245   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6246    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6247    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6248   "TARGET_SHMEDIA_FPU"
6249   "
6251   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6252   DONE;
6255 (define_expand "subv2sf3"
6256   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6257    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6258    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6259   "TARGET_SHMEDIA_FPU"
6260   "
6262   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6263   DONE;
6266 (define_expand "mulv2sf3"
6267   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6268    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6269    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6270   "TARGET_SHMEDIA_FPU"
6271   "
6273   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6274   DONE;
6277 (define_expand "divv2sf3"
6278   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6279    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6280    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6281   "TARGET_SHMEDIA_FPU"
6282   "
6284   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6285   DONE;
6288 (define_insn_and_split "*movv4sf_i"
6289   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6290         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6291   "TARGET_SHMEDIA_FPU"
6292   "#"
6293   "&& reload_completed"
6294   [(const_int 0)]
6295   "
6297   int i;
6299   for (i = 0; i < 4/2; i++)
6300     {
6301       rtx x, y;
6303       if (GET_CODE (operands[0]) == MEM)
6304         x = adjust_address (operands[0], V2SFmode,
6305                             i * GET_MODE_SIZE (V2SFmode));
6306       else
6307         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6309       if (GET_CODE (operands[1]) == MEM)
6310         y = adjust_address (operands[1], V2SFmode,
6311                             i * GET_MODE_SIZE (V2SFmode));
6312       else
6313         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6315       emit_insn (gen_movv2sf_i (x, y));
6316     }
6318   DONE;
6320   [(set_attr "length" "8")])
6322 (define_expand "movv4sf"
6323   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6324         (match_operand:V4SF 1 "general_operand" ""))]
6325   "TARGET_SHMEDIA_FPU"
6326   "
6328   if (prepare_move_operands (operands, V4SFmode))
6329     DONE;
6332 (define_insn_and_split "*movv16sf_i"
6333   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6334         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6335   "TARGET_SHMEDIA_FPU"
6336   "#"
6337   "&& reload_completed"
6338   [(const_int 0)]
6339   "
6341   int i;
6343   for (i = 0; i < 16/2; i++)
6344     {
6345       rtx x,y;
6347       if (GET_CODE (operands[0]) == MEM)
6348         x = adjust_address (operands[0], V2SFmode,
6349                             i * GET_MODE_SIZE (V2SFmode));
6350       else
6351         {
6352           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6353           alter_subreg (&x);
6354         }
6356       if (GET_CODE (operands[1]) == MEM)
6357         y = adjust_address (operands[1], V2SFmode,
6358                             i * GET_MODE_SIZE (V2SFmode));
6359       else
6360         {
6361           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6362           alter_subreg (&y);
6363         }
6365       emit_insn (gen_movv2sf_i (x, y));
6366     }
6368   DONE;
6370   [(set_attr "length" "32")])
6372 (define_expand "movv16sf"
6373   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6374         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6375   "TARGET_SHMEDIA_FPU"
6376   "
6378   if (prepare_move_operands (operands, V16SFmode))
6379     DONE;
6382 (define_insn "movsf_media"
6383   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6384         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6385   "TARGET_SHMEDIA_FPU
6386    && (register_operand (operands[0], SFmode)
6387        || sh_register_operand (operands[1], SFmode))"
6388   "@
6389         fmov.s  %1, %0
6390         fmov.ls %N1, %0
6391         fmov.sl %1, %0
6392         add.l   %1, r63, %0
6393         #
6394         fld%M1.s        %m1, %0
6395         fst%M0.s        %m0, %1
6396         ld%M1.l %m1, %0
6397         st%M0.l %m0, %N1"
6398   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6399    (set (attr "highpart")
6400         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6401                (const_string "user")]
6402               (const_string "ignore")))])
6404 (define_insn "movsf_media_nofpu"
6405   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6406         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6407   "TARGET_SHMEDIA
6408    && (register_operand (operands[0], SFmode)
6409        || sh_register_operand (operands[1], SFmode))"
6410   "@
6411         add.l   %1, r63, %0
6412         #
6413         ld%M1.l %m1, %0
6414         st%M0.l %m0, %N1"
6415   [(set_attr "type" "arith_media,*,load_media,store_media")
6416    (set (attr "highpart")
6417         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6418                (const_string "user")]
6419               (const_string "ignore")))])
6421 (define_split
6422   [(set (match_operand:SF 0 "arith_reg_dest" "")
6423         (match_operand:SF 1 "immediate_operand" ""))]
6424   "TARGET_SHMEDIA && reload_completed
6425    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6426   [(set (match_dup 3) (match_dup 2))]
6427   "
6429   long values;
6430   REAL_VALUE_TYPE value;
6432   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6433   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6434   operands[2] = GEN_INT (values);
6436   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6439 (define_insn "movsf_i"
6440   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6441         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6442   "TARGET_SH1
6443    && (! TARGET_SH2E
6444        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6445        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6446        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6447    && (arith_reg_operand (operands[0], SFmode)
6448        || arith_reg_operand (operands[1], SFmode))"
6449   "@
6450         mov     %1,%0
6451         mov     #0,%0
6452         mov.l   %1,%0
6453         mov.l   %1,%0
6454         mov.l   %1,%0
6455         lds     %1,%0
6456         sts     %1,%0"
6457   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6459 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6460 ;; update_flow_info would not know where to put REG_EQUAL notes
6461 ;; when the destination changes mode.
6462 (define_insn "movsf_ie"
6463   [(set (match_operand:SF 0 "general_movdst_operand"
6464          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6465         (match_operand:SF 1 "general_movsrc_operand"
6466           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6467    (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"))
6468    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6470   "TARGET_SH2E
6471    && (arith_reg_operand (operands[0], SFmode)
6472        || arith_reg_operand (operands[1], SFmode)
6473        || arith_reg_operand (operands[3], SImode)
6474        || (fpul_operand (operands[0], SFmode)
6475            && memory_operand (operands[1], SFmode)
6476            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6477        || (fpul_operand (operands[1], SFmode)
6478            && memory_operand (operands[0], SFmode)
6479            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6480   "@
6481         fmov    %1,%0
6482         mov     %1,%0
6483         fldi0   %0
6484         fldi1   %0
6485         #
6486         fmov.s  %1,%0
6487         fmov.s  %1,%0
6488         mov.l   %1,%0
6489         mov.l   %1,%0
6490         mov.l   %1,%0
6491         fsts    fpul,%0
6492         flds    %1,fpul
6493         lds.l   %1,%0
6494         #
6495         sts     %1,%0
6496         lds     %1,%0
6497         sts.l   %1,%0
6498         lds.l   %1,%0
6499         ! move optimized away"
6500   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6501    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6502    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6503    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6504                                            (const_string "single")
6505                                            (const_string "none")))])
6507 (define_split
6508   [(set (match_operand:SF 0 "register_operand" "")
6509         (match_operand:SF 1 "register_operand" ""))
6510    (use (match_operand:PSI 2 "fpscr_operand" ""))
6511    (clobber (reg:SI FPUL_REG))]
6512   "TARGET_SH1"
6513   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6514               (use (match_dup 2))
6515               (clobber (scratch:SI))])
6516    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6517               (use (match_dup 2))
6518               (clobber (scratch:SI))])]
6519   "")
6521 (define_expand "movsf"
6522   [(set (match_operand:SF 0 "general_movdst_operand" "")
6523         (match_operand:SF 1 "general_movsrc_operand" ""))]
6524   ""
6525   "
6527   if (prepare_move_operands (operands, SFmode))
6528     DONE;
6529   if (TARGET_SHMEDIA)
6530     {
6531       if (TARGET_SHMEDIA_FPU)
6532         emit_insn (gen_movsf_media (operands[0], operands[1]));
6533       else
6534         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6535       DONE;
6536     }
6537   if (TARGET_SH2E)
6538     {
6539       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6540       DONE;
6541     }
6544 (define_insn "mov_nop"
6545   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6546   "TARGET_SH2E"
6547   ""
6548   [(set_attr "length" "0")
6549    (set_attr "type" "nil")])
6551 (define_expand "reload_insf__frn"
6552   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6553                    (match_operand:SF 1 "immediate_operand" "FQ"))
6554               (use (reg:PSI FPSCR_REG))
6555               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6556   "TARGET_SH1"
6557   "")
6559 (define_expand "reload_insi__i_fpul"
6560   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6561                    (match_operand:SI 1 "immediate_operand" "i"))
6562               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6563   "TARGET_SH1"
6564   "")
6566 (define_expand "ptabs"
6567   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6568   "TARGET_SHMEDIA"
6569   "
6571   if (!TARGET_PT_FIXED)
6572     {
6573       rtx eq = operands[1];
6575       /* ??? For canonical RTL we really should remove any CONST from EQ
6576          before wrapping it in the AND, and finally wrap the EQ into a
6577          const if is constant.  However, for reload we must expose the
6578          input register or symbolic constant, and we can't have
6579          different insn structures outside of the operands for different
6580          alternatives of the same pattern.  */
6581       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6582                        GEN_INT (3));
6583       operands[1]
6584         = (gen_rtx_IF_THEN_ELSE
6585             (PDImode,
6586              eq,
6587              gen_rtx_MEM (PDImode, operands[1]),
6588              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6589                             PDImode, operands[1])));
6590     }
6593 ;; expanded by ptabs expander.
6594 (define_insn "*extendsipdi_media"
6595   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6596         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6597                                                           "r,Csy")
6598                                       (const_int 3))
6599                               (const_int 3))
6600                           (mem:PDI (match_dup 1))
6601                           (sign_extend:PDI (match_dup 1))))]
6602   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6603   "@
6604         ptabs   %1, %0
6605         pt      %1, %0"
6606   [(set_attr "type"   "ptabs_media,pt_media")
6607    (set_attr "length" "4,*")])
6609 (define_insn "*truncdipdi_media"
6610   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6611         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6612                                                           "r,Csy")
6613                                       (const_int 3))
6614                               (const_int 3))
6615                           (mem:PDI (match_dup 1))
6616                           (truncate:PDI (match_dup 1))))]
6617   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6618   "@
6619         ptabs   %1, %0
6620         pt      %1, %0"
6621   [(set_attr "type"   "ptabs_media,pt_media")
6622    (set_attr "length" "4,*")])
6624 (define_insn "*movsi_y"
6625   [(set (match_operand:SI 0 "register_operand" "=y,y")
6626         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6627    (clobber (match_scratch:SI 2 "=&z,r"))]
6628   "TARGET_SH2E
6629    && (reload_in_progress || reload_completed)"
6630   "#"
6631   [(set_attr "length" "4")
6632    (set_attr "type" "pcload,move")])
6634 (define_split
6635   [(set (match_operand:SI 0 "register_operand" "")
6636         (match_operand:SI 1 "immediate_operand" ""))
6637    (clobber (match_operand:SI 2 "register_operand" ""))]
6638   "TARGET_SH1"
6639   [(set (match_dup 2) (match_dup 1))
6640    (set (match_dup 0) (match_dup 2))]
6641   "")
6643 (define_split
6644   [(set (match_operand:SI 0 "register_operand" "")
6645         (match_operand:SI 1 "memory_operand" ""))
6646    (clobber (reg:SI R0_REG))]
6647   "TARGET_SH1"
6648   [(set (match_dup 0) (match_dup 1))]
6649   "")
6651 ;; ------------------------------------------------------------------------
6652 ;; Define the real conditional branch instructions.
6653 ;; ------------------------------------------------------------------------
6655 (define_insn "branch_true"
6656   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6657                            (label_ref (match_operand 0 "" ""))
6658                            (pc)))]
6659   "TARGET_SH1"
6660   "* return output_branch (1, insn, operands);"
6661   [(set_attr "type" "cbranch")])
6663 (define_insn "branch_false"
6664   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6665                            (label_ref (match_operand 0 "" ""))
6666                            (pc)))]
6667   "TARGET_SH1"
6668   "* return output_branch (0, insn, operands);"
6669   [(set_attr "type" "cbranch")])
6671 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6672 ;; which destination is too far away.
6673 ;; The const_int_operand is distinct for each branch target; it avoids
6674 ;; unwanted matches with redundant_insn.
6675 (define_insn "block_branch_redirect"
6676   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6677   "TARGET_SH1"
6678   ""
6679   [(set_attr "length" "0")])
6681 ;; This one has the additional purpose to record a possible scratch register
6682 ;; for the following branch.
6683 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6684 ;; because the insn then might be deemed dead and deleted.  And we can't
6685 ;; make the use in the jump insn explicit because that would disable
6686 ;; delay slot scheduling from the target.
6687 (define_insn "indirect_jump_scratch"
6688   [(set (match_operand:SI 0 "register_operand" "=r")
6689         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6690    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6691   "TARGET_SH1"
6692   ""
6693   [(set_attr "length" "0")])
6695 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6696 ;; being pulled into the delay slot of a condbranch that has been made to
6697 ;; jump around the unconditional jump because it was out of range.
6698 (define_insn "stuff_delay_slot"
6699   [(set (pc)
6700         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6701    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6702   "TARGET_SH1"
6703   ""
6704   [(set_attr "length" "0")
6705    (set_attr "cond_delay_slot" "yes")])
6707 ;; Conditional branch insns
6709 (define_expand "beq_media"
6710   [(set (pc)
6711         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6712                           (match_operand:DI 2 "arith_operand" "r,I06"))
6713                       (match_operand 0 "" "")
6714                       (pc)))]
6715   "TARGET_SHMEDIA"
6716   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6718 (define_insn "*beq_media_i"
6719   [(set (pc)
6720         (if_then_else (match_operator 3 "equality_comparison_operator"
6721                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6722                          (match_operand:DI 2 "arith_operand" "r,I06")])
6723                       (match_operand 0 "target_operand" "b,b")
6724                       (pc)))]
6725   "TARGET_SHMEDIA"
6726   "@
6727         b%o3%'  %1, %2, %0%>
6728         b%o3i%' %1, %2, %0%>"
6729   [(set_attr "type" "cbranch_media")])
6731 (define_insn "*beq_media_i32"
6732   [(set (pc)
6733         (if_then_else (match_operator 3 "equality_comparison_operator"
6734                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6735                          (match_operand:SI 2 "arith_operand" "r,I06")])
6736                       (match_operand 0 "target_operand" "b,b")
6737                       (pc)))]
6738   "TARGET_SHMEDIA"
6739   "@
6740         b%o3%'  %1, %2, %0%>
6741         b%o3i%' %1, %2, %0%>"
6742   [(set_attr "type" "cbranch_media")])
6744 (define_expand "bne_media"
6745   [(set (pc)
6746         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6747                           (match_operand:DI 2 "arith_operand" "r,I06"))
6748                       (match_operand 0 "" "")
6749                       (pc)))]
6750   "TARGET_SHMEDIA"
6751   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6753 (define_expand "bgt_media"
6754   [(set (pc)
6755         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6756                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6757                       (match_operand 0 "" "")
6758                       (pc)))]
6759   "TARGET_SHMEDIA"
6760   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6762 (define_expand "bge_media"
6763   [(set (pc)
6764         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6765                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6766                       (match_operand 0 "" "")
6767                       (pc)))]
6768   "TARGET_SHMEDIA"
6769   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6771 (define_expand "bgtu_media"
6772   [(set (pc)
6773         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6774                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6775                       (match_operand 0 "" "")
6776                       (pc)))]
6777   "TARGET_SHMEDIA"
6778   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6780 (define_expand "bgeu_media"
6781   [(set (pc)
6782         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6783                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6784                       (match_operand 0 "" "")
6785                       (pc)))]
6786   "TARGET_SHMEDIA"
6787   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6789 (define_insn "*bgt_media_i"
6790   [(set (pc)
6791         (if_then_else (match_operator 3 "greater_comparison_operator"
6792                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6793                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6794                       (match_operand 0 "target_operand" "b")
6795                       (pc)))]
6796   "TARGET_SHMEDIA"
6797   "b%o3%'       %N1, %N2, %0%>"
6798   [(set_attr "type" "cbranch_media")])
6800 (define_insn "*bgt_media_i32"
6801   [(set (pc)
6802         (if_then_else (match_operator 3 "greater_comparison_operator"
6803                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6804                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6805                       (match_operand 0 "target_operand" "b")
6806                       (pc)))]
6807   "TARGET_SHMEDIA"
6808   "b%o3%'       %N1, %N2, %0%>"
6809   [(set_attr "type" "cbranch_media")])
6811 ;; These are only needed to make invert_jump() happy - otherwise, jump
6812 ;; optimization will be silently disabled.
6813 (define_insn "*blt_media_i"
6814   [(set (pc)
6815         (if_then_else (match_operator 3 "less_comparison_operator"
6816                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6817                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6818                       (match_operand 0 "target_operand" "b")
6819                       (pc)))]
6820   "TARGET_SHMEDIA"
6821   "b%o3%'       %N2, %N1, %0%>"
6822   [(set_attr "type" "cbranch_media")])
6824 (define_insn "*blt_media_i32"
6825   [(set (pc)
6826         (if_then_else (match_operator 3 "less_comparison_operator"
6827                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6828                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6829                       (match_operand 0 "target_operand" "b")
6830                       (pc)))]
6831   "TARGET_SHMEDIA"
6832   "b%o3%'       %N2, %N1, %0%>"
6833   [(set_attr "type" "cbranch_media")])
6835 (define_expand "beq"
6836   [(set (pc)
6837         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6838                       (label_ref (match_operand 0 "" ""))
6839                       (pc)))]
6840   ""
6841   "
6843   if (TARGET_SHMEDIA)
6844     {
6845       enum machine_mode mode = GET_MODE (sh_compare_op0);
6847       if (mode != DImode && mode != SImode)
6848         {
6849           rtx tmp = gen_reg_rtx (DImode);
6851           emit_insn (gen_seq (tmp));
6852           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6853           DONE;
6854         }
6856       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6857       if (CONSTANT_P (sh_compare_op1)
6858           && (GET_CODE (sh_compare_op1) != CONST_INT
6859               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6860         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6861       emit_jump_insn (gen_beq_media (operands[0],
6862                                      sh_compare_op0, sh_compare_op1));
6863       DONE;
6864     }
6866   from_compare (operands, EQ);
6869 (define_expand "bne"
6870   [(set (pc)
6871         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6872                       (label_ref (match_operand 0 "" ""))
6873                       (pc)))]
6874   ""
6875   "
6877   if (TARGET_SHMEDIA)
6878     {
6879       enum machine_mode mode = GET_MODE (sh_compare_op0);
6881       if (mode != DImode && mode != SImode)
6882         {
6883           rtx tmp = gen_reg_rtx (DImode);
6885           emit_insn (gen_seq (tmp));
6886           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6887           DONE;
6888         }
6890       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6891       if (CONSTANT_P (sh_compare_op1)
6892           && (GET_CODE (sh_compare_op1) != CONST_INT
6893               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6894         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6895       emit_jump_insn (gen_bne_media (operands[0],
6896                                      sh_compare_op0, sh_compare_op1));
6897       DONE;
6898     }
6900   from_compare (operands, EQ);
6903 (define_expand "bgt"
6904   [(set (pc)
6905         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6906                       (label_ref (match_operand 0 "" ""))
6907                       (pc)))]
6908   ""
6909   "
6911   if (TARGET_SHMEDIA)
6912     {
6913       enum machine_mode mode = GET_MODE (sh_compare_op0);
6915       if (mode != DImode && mode != SImode)
6916         {
6917           rtx tmp = gen_reg_rtx (DImode);
6919           emit_insn (gen_sgt (tmp));
6920           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6921           DONE;
6922         }
6924       if (sh_compare_op0 != const0_rtx)
6925         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6926       if (sh_compare_op1 != const0_rtx)
6927         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6928       emit_jump_insn (gen_bgt_media (operands[0],
6929                                      sh_compare_op0, sh_compare_op1));
6930       DONE;
6931     }
6933   from_compare (operands, GT);
6936 (define_expand "blt"
6937   [(set (pc)
6938         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6939                       (label_ref (match_operand 0 "" ""))
6940                       (pc)))]
6941   ""
6942   "
6944   if (TARGET_SHMEDIA)
6945     {
6946       enum machine_mode mode = GET_MODE (sh_compare_op0);
6948       if (mode != DImode && mode != SImode)
6949         {
6950           rtx tmp = gen_reg_rtx (DImode);
6952           emit_insn (gen_slt (tmp));
6953           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6954           DONE;
6955         }
6957       if (sh_compare_op0 != const0_rtx)
6958         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6959       if (sh_compare_op1 != const0_rtx)
6960         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6961       emit_jump_insn (gen_bgt_media (operands[0],
6962                                      sh_compare_op1, sh_compare_op0));
6963       DONE;
6964     }
6966   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6967     {
6968       rtx tmp = sh_compare_op0;
6969       sh_compare_op0 = sh_compare_op1;
6970       sh_compare_op1 = tmp;
6971       emit_insn (gen_bgt (operands[0]));
6972       DONE;
6973     }
6974   from_compare (operands, GE);
6977 (define_expand "ble"
6978   [(set (pc)
6979         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6980                       (label_ref (match_operand 0 "" ""))
6981                       (pc)))]
6982   ""
6983   "
6985   if (TARGET_SHMEDIA)
6986     {
6987       enum machine_mode mode = GET_MODE (sh_compare_op0);
6989       if (mode != DImode && mode != SImode)
6990         {
6991           rtx tmp = gen_reg_rtx (DImode);
6993           emit_insn (gen_sle (tmp));
6994           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6995           DONE;
6996         }
6998       if (sh_compare_op0 != const0_rtx)
6999         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7000       if (sh_compare_op1 != const0_rtx)
7001         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7002       emit_jump_insn (gen_bge_media (operands[0],
7003                                      sh_compare_op1, sh_compare_op0));
7004       DONE;
7005     }
7007   if (TARGET_SH2E
7008       && TARGET_IEEE
7009       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7010     {
7011       rtx tmp = sh_compare_op0;
7012       sh_compare_op0 = sh_compare_op1;
7013       sh_compare_op1 = tmp;
7014       emit_insn (gen_bge (operands[0]));
7015       DONE;
7016     }
7017   from_compare (operands, GT);
7020 (define_expand "bge"
7021   [(set (pc)
7022         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7023                       (label_ref (match_operand 0 "" ""))
7024                       (pc)))]
7025   ""
7026   "
7028   if (TARGET_SHMEDIA)
7029     {
7030       enum machine_mode mode = GET_MODE (sh_compare_op0);
7032       if (mode != DImode && mode != SImode)
7033         {
7034           rtx tmp = gen_reg_rtx (DImode);
7036           emit_insn (gen_sge (tmp));
7037           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7038           DONE;
7039         }
7041       if (sh_compare_op0 != const0_rtx)
7042         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7043       if (sh_compare_op1 != const0_rtx)
7044         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7045       emit_jump_insn (gen_bge_media (operands[0],
7046                                      sh_compare_op0, sh_compare_op1));
7047       DONE;
7048     }
7050   if (TARGET_SH2E
7051       && ! TARGET_IEEE
7052       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7053     {
7054       rtx tmp = sh_compare_op0;
7055       sh_compare_op0 = sh_compare_op1;
7056       sh_compare_op1 = tmp;
7057       emit_insn (gen_ble (operands[0]));
7058       DONE;
7059     }
7060   from_compare (operands, GE);
7063 (define_expand "bgtu"
7064   [(set (pc)
7065         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7066                       (label_ref (match_operand 0 "" ""))
7067                       (pc)))]
7068   ""
7069   "
7071   if (TARGET_SHMEDIA)
7072     {
7073       enum machine_mode mode = GET_MODE (sh_compare_op0);
7075       if (sh_compare_op0 != const0_rtx)
7076         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7077       if (sh_compare_op1 != const0_rtx)
7078         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7079       emit_jump_insn (gen_bgtu_media (operands[0],
7080                                       sh_compare_op0, sh_compare_op1));
7081       DONE;
7082     }
7084   from_compare (operands, GTU);
7087 (define_expand "bltu"
7088   [(set (pc)
7089         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7090                       (label_ref (match_operand 0 "" ""))
7091                       (pc)))]
7092   ""
7093   "
7095   if (TARGET_SHMEDIA)
7096     {
7097       enum machine_mode mode = GET_MODE (sh_compare_op0);
7099       if (sh_compare_op0 != const0_rtx)
7100         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7101       if (sh_compare_op1 != const0_rtx)
7102         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7103       emit_jump_insn (gen_bgtu_media (operands[0],
7104                                       sh_compare_op1, sh_compare_op0));
7105       DONE;
7106     }
7108   from_compare (operands, GEU);
7111 (define_expand "bgeu"
7112   [(set (pc)
7113         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7114                       (label_ref (match_operand 0 "" ""))
7115                       (pc)))]
7116   ""
7117   "
7119   if (TARGET_SHMEDIA)
7120     {
7121       enum machine_mode mode = GET_MODE (sh_compare_op0);
7123       if (sh_compare_op0 != const0_rtx)
7124         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7125       if (sh_compare_op1 != const0_rtx)
7126         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7127       emit_jump_insn (gen_bgeu_media (operands[0],
7128                                       sh_compare_op0, sh_compare_op1));
7129       DONE;
7130     }
7132   from_compare (operands, GEU);
7135 (define_expand "bleu"
7136   [(set (pc)
7137         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7138                       (label_ref (match_operand 0 "" ""))
7139                       (pc)))]
7140   ""
7141   "
7143   if (TARGET_SHMEDIA)
7144     {
7145       enum machine_mode mode = GET_MODE (sh_compare_op0);
7147       if (sh_compare_op0 != const0_rtx)
7148         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7149       if (sh_compare_op1 != const0_rtx)
7150         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7151       emit_jump_insn (gen_bgeu_media (operands[0],
7152                                       sh_compare_op1, sh_compare_op0));
7153       DONE;
7154     }
7156   from_compare (operands, GTU);
7159 (define_expand "bunordered"
7160   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7161    (set (pc)
7162         (if_then_else (ne (match_dup 1) (const_int 0))
7163                       (match_operand 0 "" "")
7164                       (pc)))]
7165   "TARGET_SHMEDIA"
7166   "
7168   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7169   operands[1] = gen_reg_rtx (DImode);
7170   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7171   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7174 ;; combiner splitter for test-and-branch on single bit in register.  This
7175 ;; is endian dependent because the non-paradoxical subreg looks different
7176 ;; on big endian.
7177 (define_split
7178   [(set (pc)
7179         (if_then_else
7180           (match_operator 3 "equality_comparison_operator"
7181             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7182                                                       "extend_reg_operand" "")
7183                                                     0)
7184                                          (const_int 1)
7185                                          (match_operand 2
7186                                           "const_int_operand" "")) 0)
7187              (const_int 0)])
7188           (match_operand 0 "target_operand" "")
7189           (pc)))
7190    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7191   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7192   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7193    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7195   "
7197   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7198   operands[6] = (GET_CODE (operands[3]) == EQ
7199                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7200                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7203 ;; ------------------------------------------------------------------------
7204 ;; Jump and linkage insns
7205 ;; ------------------------------------------------------------------------
7207 (define_insn "jump_compact"
7208   [(set (pc)
7209         (label_ref (match_operand 0 "" "")))]
7210   "TARGET_SH1"
7211   "*
7213   /* The length is 16 if the delay slot is unfilled.  */
7214   if (get_attr_length(insn) > 4)
7215     return output_far_jump(insn, operands[0]);
7216   else
7217     return   \"bra      %l0%#\";
7219   [(set_attr "type" "jump")
7220    (set_attr "needs_delay_slot" "yes")])
7222 ;; ??? It would be much saner to explicitly use the scratch register
7223 ;; in the jump insn, and have indirect_jump_scratch only set it,
7224 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7225 ;; from the target then, as it uses simplejump_p.
7226 ;;(define_insn "jump_compact_far"
7227 ;;  [(set (pc)
7228 ;;      (label_ref (match_operand 0 "" "")))
7229 ;;   (use (match_operand 1 "register_operand" "r")]
7230 ;;  "TARGET_SH1"
7231 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7232 ;;  [(set_attr "type" "jump")
7233 ;;   (set_attr "needs_delay_slot" "yes")])
7235 (define_insn "jump_media"
7236   [(set (pc)
7237         (match_operand 0 "target_operand" "b"))]
7238   "TARGET_SHMEDIA"
7239   "blink        %0, r63%>"
7240   [(set_attr "type" "jump_media")])
7242 (define_expand "jump"
7243   [(set (pc)
7244         (label_ref (match_operand 0 "" "")))]
7245   ""
7246   "
7248   if (TARGET_SH1)
7249     emit_jump_insn (gen_jump_compact (operands[0]));
7250   else if (TARGET_SHMEDIA)
7251     {
7252       if (reload_in_progress || reload_completed)
7253         FAIL;
7254       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7255                                                          operands[0])));
7256     }
7257   DONE;
7260 (define_insn "force_mode_for_call"
7261   [(use (reg:PSI FPSCR_REG))]
7262   "TARGET_SHCOMPACT"
7263   ""
7264   [(set_attr "length" "0")
7265    (set (attr "fp_mode")
7266         (if_then_else (eq_attr "fpu_single" "yes")
7267                       (const_string "single") (const_string "double")))])
7269 (define_insn "calli"
7270   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7271          (match_operand 1 "" ""))
7272    (use (reg:PSI FPSCR_REG))
7273    (clobber (reg:SI PR_REG))]
7274   "TARGET_SH1"
7275   "jsr  @%0%#"
7276   [(set_attr "type" "call")
7277    (set (attr "fp_mode")
7278         (if_then_else (eq_attr "fpu_single" "yes")
7279                       (const_string "single") (const_string "double")))
7280    (set_attr "needs_delay_slot" "yes")
7281    (set_attr "fp_set" "unknown")])
7283 ;; This is a pc-rel call, using bsrf, for use with PIC.
7285 (define_insn "calli_pcrel"
7286   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7287          (match_operand 1 "" ""))
7288    (use (reg:PSI FPSCR_REG))
7289    (use (reg:SI PIC_REG))
7290    (use (match_operand 2 "" ""))
7291    (clobber (reg:SI PR_REG))]
7292   "TARGET_SH2"
7293   "bsrf %0\\n%O2:%#"
7294   [(set_attr "type" "call")
7295    (set (attr "fp_mode")
7296         (if_then_else (eq_attr "fpu_single" "yes")
7297                       (const_string "single") (const_string "double")))
7298    (set_attr "needs_delay_slot" "yes")
7299    (set_attr "fp_set" "unknown")])
7301 (define_insn_and_split "call_pcrel"
7302   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7303          (match_operand 1 "" ""))
7304    (use (reg:PSI FPSCR_REG))
7305    (use (reg:SI PIC_REG))
7306    (clobber (reg:SI PR_REG))
7307    (clobber (match_scratch:SI 2 "=r"))]
7308   "TARGET_SH2"
7309   "#"
7310   "reload_completed"
7311   [(const_int 0)]
7312   "
7314   rtx lab = PATTERN (gen_call_site ());
7316   if (SYMBOL_REF_LOCAL_P (operands[0]))
7317     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7318   else
7319     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7320   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7321   DONE;
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")])
7330 (define_insn "call_compact"
7331   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7332          (match_operand 1 "" ""))
7333    (match_operand 2 "immediate_operand" "n")
7334    (use (reg:SI R0_REG))
7335    (use (reg:SI R1_REG))
7336    (use (reg:PSI FPSCR_REG))
7337    (clobber (reg:SI PR_REG))]
7338   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7339   "jsr  @%0%#"
7340   [(set_attr "type" "call")
7341    (set (attr "fp_mode")
7342         (if_then_else (eq_attr "fpu_single" "yes")
7343                       (const_string "single") (const_string "double")))
7344    (set_attr "needs_delay_slot" "yes")])
7346 (define_insn "call_compact_rettramp"
7347   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7348          (match_operand 1 "" ""))
7349    (match_operand 2 "immediate_operand" "n")
7350    (use (reg:SI R0_REG))
7351    (use (reg:SI R1_REG))
7352    (use (reg:PSI FPSCR_REG))
7353    (clobber (reg:SI R10_REG))
7354    (clobber (reg:SI PR_REG))]
7355   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7356   "jsr  @%0%#"
7357   [(set_attr "type" "call")
7358    (set (attr "fp_mode")
7359         (if_then_else (eq_attr "fpu_single" "yes")
7360                       (const_string "single") (const_string "double")))
7361    (set_attr "needs_delay_slot" "yes")])
7363 (define_insn "call_media"
7364   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7365          (match_operand 1 "" ""))
7366    (clobber (reg:DI PR_MEDIA_REG))]
7367   "TARGET_SHMEDIA"
7368   "blink        %0, r18"
7369   [(set_attr "type" "jump_media")])
7371 (define_insn "call_valuei"
7372   [(set (match_operand 0 "" "=rf")
7373         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7374               (match_operand 2 "" "")))
7375    (use (reg:PSI FPSCR_REG))
7376    (clobber (reg:SI PR_REG))]
7377   "TARGET_SH1"
7378   "jsr  @%1%#"
7379   [(set_attr "type" "call")
7380    (set (attr "fp_mode")
7381         (if_then_else (eq_attr "fpu_single" "yes")
7382                       (const_string "single") (const_string "double")))
7383    (set_attr "needs_delay_slot" "yes")
7384    (set_attr "fp_set" "unknown")])
7386 (define_insn "call_valuei_pcrel"
7387   [(set (match_operand 0 "" "=rf")
7388         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7389               (match_operand 2 "" "")))
7390    (use (reg:PSI FPSCR_REG))
7391    (use (reg:SI PIC_REG))
7392    (use (match_operand 3 "" ""))
7393    (clobber (reg:SI PR_REG))]
7394   "TARGET_SH2"
7395   "bsrf %1\\n%O3:%#"
7396   [(set_attr "type" "call")
7397    (set (attr "fp_mode")
7398         (if_then_else (eq_attr "fpu_single" "yes")
7399                       (const_string "single") (const_string "double")))
7400    (set_attr "needs_delay_slot" "yes")
7401    (set_attr "fp_set" "unknown")])
7403 (define_insn_and_split "call_value_pcrel"
7404   [(set (match_operand 0 "" "=rf")
7405         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7406               (match_operand 2 "" "")))
7407    (use (reg:PSI FPSCR_REG))
7408    (use (reg:SI PIC_REG))
7409    (clobber (reg:SI PR_REG))
7410    (clobber (match_scratch:SI 3 "=r"))]
7411   "TARGET_SH2"
7412   "#"
7413   "reload_completed"
7414   [(const_int 0)]
7415   "
7417   rtx lab = PATTERN (gen_call_site ());
7419   if (SYMBOL_REF_LOCAL_P (operands[1]))
7420     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7421   else
7422     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7423   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7424                                          operands[2], lab));
7425   DONE;
7427   [(set_attr "type" "call")
7428    (set (attr "fp_mode")
7429         (if_then_else (eq_attr "fpu_single" "yes")
7430                       (const_string "single") (const_string "double")))
7431    (set_attr "needs_delay_slot" "yes")
7432    (set_attr "fp_set" "unknown")])
7434 (define_insn "call_value_compact"
7435   [(set (match_operand 0 "" "=rf")
7436         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7437               (match_operand 2 "" "")))
7438    (match_operand 3 "immediate_operand" "n")
7439    (use (reg:SI R0_REG))
7440    (use (reg:SI R1_REG))
7441    (use (reg:PSI FPSCR_REG))
7442    (clobber (reg:SI PR_REG))]
7443   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7444   "jsr  @%1%#"
7445   [(set_attr "type" "call")
7446    (set (attr "fp_mode")
7447         (if_then_else (eq_attr "fpu_single" "yes")
7448                       (const_string "single") (const_string "double")))
7449    (set_attr "needs_delay_slot" "yes")])
7451 (define_insn "call_value_compact_rettramp"
7452   [(set (match_operand 0 "" "=rf")
7453         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7454               (match_operand 2 "" "")))
7455    (match_operand 3 "immediate_operand" "n")
7456    (use (reg:SI R0_REG))
7457    (use (reg:SI R1_REG))
7458    (use (reg:PSI FPSCR_REG))
7459    (clobber (reg:SI R10_REG))
7460    (clobber (reg:SI PR_REG))]
7461   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7462   "jsr  @%1%#"
7463   [(set_attr "type" "call")
7464    (set (attr "fp_mode")
7465         (if_then_else (eq_attr "fpu_single" "yes")
7466                       (const_string "single") (const_string "double")))
7467    (set_attr "needs_delay_slot" "yes")])
7469 (define_insn "call_value_media"
7470   [(set (match_operand 0 "" "=rf")
7471         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7472               (match_operand 2 "" "")))
7473    (clobber (reg:DI PR_MEDIA_REG))]
7474   "TARGET_SHMEDIA"
7475   "blink        %1, r18"
7476   [(set_attr "type" "jump_media")])
7478 (define_expand "call"
7479   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7480                             (match_operand 1 "" ""))
7481               (match_operand 2 "" "")
7482               (use (reg:PSI FPSCR_REG))
7483               (clobber (reg:SI PR_REG))])]
7484   ""
7485   "
7487   if (TARGET_SHMEDIA)
7488     {
7489       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7490       emit_call_insn (gen_call_media (operands[0], operands[1]));
7491       DONE;
7492     }
7493   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7494     {
7495       rtx cookie_rtx = operands[2];
7496       long cookie = INTVAL (cookie_rtx);
7497       rtx func = XEXP (operands[0], 0);
7498       rtx r0, r1;
7500       if (flag_pic)
7501         {
7502           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7503             {
7504               rtx reg = gen_reg_rtx (Pmode);
7506               emit_insn (gen_symGOTPLT2reg (reg, func));
7507               func = reg;
7508             }
7509           else
7510             func = legitimize_pic_address (func, Pmode, 0);
7511         }
7513       r0 = gen_rtx_REG (SImode, R0_REG);
7514       r1 = gen_rtx_REG (SImode, R1_REG);
7516       /* Since such a call function may use all call-clobbered
7517          registers, we force a mode switch earlier, so that we don't
7518          run out of registers when adjusting fpscr for the call.  */
7519       emit_insn (gen_force_mode_for_call ());
7521       operands[0]
7522         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7523                            SFUNC_GOT);
7524       operands[0] = force_reg (SImode, operands[0]);
7526       emit_move_insn (r0, func);
7527       emit_move_insn (r1, cookie_rtx);
7529       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7530         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7531                                                    operands[2]));
7532       else
7533         emit_call_insn (gen_call_compact (operands[0], operands[1],
7534                                           operands[2]));
7536       DONE;
7537     }
7538   else if (TARGET_SHCOMPACT && flag_pic
7539            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7540            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7541     {
7542       rtx reg = gen_reg_rtx (Pmode);
7544       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7545       XEXP (operands[0], 0) = reg;
7546     }
7547   if (flag_pic && TARGET_SH2
7548       && GET_CODE (operands[0]) == MEM
7549       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7550     {
7551       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7552       DONE;
7553     }
7554   else
7555   {
7556     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7557     operands[1] = operands[2];
7558   }
7560   emit_call_insn (gen_calli (operands[0], operands[1]));
7561   DONE;
7564 (define_insn "call_pop_compact"
7565   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7566          (match_operand 1 "" ""))
7567    (match_operand 2 "immediate_operand" "n")
7568    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7569                                  (match_operand 3 "immediate_operand" "n")))
7570    (use (reg:SI R0_REG))
7571    (use (reg:SI R1_REG))
7572    (use (reg:PSI FPSCR_REG))
7573    (clobber (reg:SI PR_REG))]
7574   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7575   "jsr  @%0%#"
7576   [(set_attr "type" "call")
7577    (set (attr "fp_mode")
7578         (if_then_else (eq_attr "fpu_single" "yes")
7579                       (const_string "single") (const_string "double")))
7580    (set_attr "needs_delay_slot" "yes")])
7582 (define_insn "call_pop_compact_rettramp"
7583   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7584          (match_operand 1 "" ""))
7585    (match_operand 2 "immediate_operand" "n")
7586    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7587                                  (match_operand 3 "immediate_operand" "n")))
7588    (use (reg:SI R0_REG))
7589    (use (reg:SI R1_REG))
7590    (use (reg:PSI FPSCR_REG))
7591    (clobber (reg:SI R10_REG))
7592    (clobber (reg:SI PR_REG))]
7593   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7594   "jsr  @%0%#"
7595   [(set_attr "type" "call")
7596    (set (attr "fp_mode")
7597         (if_then_else (eq_attr "fpu_single" "yes")
7598                       (const_string "single") (const_string "double")))
7599    (set_attr "needs_delay_slot" "yes")])
7601 (define_expand "call_pop"
7602   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7603                     (match_operand 1 "" ""))
7604              (match_operand 2 "" "")
7605              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7606                                            (match_operand 3 "" "")))])]
7607   "TARGET_SHCOMPACT"
7608   "
7610   rtx cookie_rtx;
7611   long cookie;
7612   rtx func;
7613   rtx r0, r1;
7615   gcc_assert (operands[2] && INTVAL (operands[2]));
7616   cookie_rtx = operands[2];
7617   cookie = INTVAL (cookie_rtx);
7618   func = XEXP (operands[0], 0);
7620   if (flag_pic)
7621     {
7622       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7623         {
7624           rtx reg = gen_reg_rtx (Pmode);
7625           emit_insn (gen_symGOTPLT2reg (reg, func));
7626           func = reg;
7627         }
7628       else
7629         func = legitimize_pic_address (func, Pmode, 0);
7630     }
7632   r0 = gen_rtx_REG (SImode, R0_REG);
7633   r1 = gen_rtx_REG (SImode, R1_REG);
7635   /* Since such a call function may use all call-clobbered
7636      registers, we force a mode switch earlier, so that we don't
7637      run out of registers when adjusting fpscr for the call.  */
7638   emit_insn (gen_force_mode_for_call ());
7640   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7641                                  SFUNC_GOT);
7642   operands[0] = force_reg (SImode, operands[0]);
7644   emit_move_insn (r0, func);
7645   emit_move_insn (r1, cookie_rtx);
7647   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7648     emit_call_insn (gen_call_pop_compact_rettramp
7649                      (operands[0], operands[1], operands[2], operands[3]));
7650   else
7651     emit_call_insn (gen_call_pop_compact
7652                      (operands[0], operands[1], operands[2], operands[3]));
7654   DONE;
7657 (define_expand "call_value"
7658   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7659                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7660                                  (match_operand 2 "" "")))
7661               (match_operand 3 "" "")
7662               (use (reg:PSI FPSCR_REG))
7663               (clobber (reg:SI PR_REG))])]
7664   ""
7665   "
7667   if (TARGET_SHMEDIA)
7668     {
7669       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7670       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7671                                             operands[2]));
7672       DONE;
7673     }
7674   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7675     {
7676       rtx cookie_rtx = operands[3];
7677       long cookie = INTVAL (cookie_rtx);
7678       rtx func = XEXP (operands[1], 0);
7679       rtx r0, r1;
7681       if (flag_pic)
7682         {
7683           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7684             {
7685               rtx reg = gen_reg_rtx (Pmode);
7687               emit_insn (gen_symGOTPLT2reg (reg, func));
7688               func = reg;
7689             }
7690           else
7691             func = legitimize_pic_address (func, Pmode, 0);
7692         }
7694       r0 = gen_rtx_REG (SImode, R0_REG);
7695       r1 = gen_rtx_REG (SImode, R1_REG);
7697       /* Since such a call function may use all call-clobbered
7698          registers, we force a mode switch earlier, so that we don't
7699          run out of registers when adjusting fpscr for the call.  */
7700       emit_insn (gen_force_mode_for_call ());
7702       operands[1]
7703         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7704                            SFUNC_GOT);
7705       operands[1] = force_reg (SImode, operands[1]);
7707       emit_move_insn (r0, func);
7708       emit_move_insn (r1, cookie_rtx);
7710       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7711         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7712                                                          operands[1],
7713                                                          operands[2],
7714                                                          operands[3]));
7715       else
7716         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7717                                                 operands[2], operands[3]));
7719       DONE;
7720     }
7721   else if (TARGET_SHCOMPACT && flag_pic
7722            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7723            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7724     {
7725       rtx reg = gen_reg_rtx (Pmode);
7727       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7728       XEXP (operands[1], 0) = reg;
7729     }
7730   if (flag_pic && TARGET_SH2
7731       && GET_CODE (operands[1]) == MEM
7732       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7733     {
7734       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7735                                             operands[2]));
7736       DONE;
7737     }
7738   else
7739     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7741   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7742   DONE;
7745 (define_insn "sibcalli"
7746   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7747          (match_operand 1 "" ""))
7748    (use (reg:PSI FPSCR_REG))
7749    (return)]
7750   "TARGET_SH1"
7751   "jmp  @%0%#"
7752   [(set_attr "needs_delay_slot" "yes")
7753    (set (attr "fp_mode")
7754         (if_then_else (eq_attr "fpu_single" "yes")
7755                       (const_string "single") (const_string "double")))
7756    (set_attr "type" "jump_ind")])
7758 (define_insn "sibcalli_pcrel"
7759   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7760          (match_operand 1 "" ""))
7761    (use (match_operand 2 "" ""))
7762    (use (reg:PSI FPSCR_REG))
7763    (return)]
7764   "TARGET_SH2"
7765   "braf %0\\n%O2:%#"
7766   [(set_attr "needs_delay_slot" "yes")
7767    (set (attr "fp_mode")
7768         (if_then_else (eq_attr "fpu_single" "yes")
7769                       (const_string "single") (const_string "double")))
7770    (set_attr "type" "jump_ind")])
7772 ;; This uses an unspec to describe that the symbol_ref is very close.
7773 (define_insn "sibcalli_thunk"
7774   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7775                              UNSPEC_THUNK))
7776          (match_operand 1 "" ""))
7777    (use (reg:PSI FPSCR_REG))
7778    (return)]
7779   "TARGET_SH1"
7780   "bra  %O0"
7781   [(set_attr "needs_delay_slot" "yes")
7782    (set (attr "fp_mode")
7783         (if_then_else (eq_attr "fpu_single" "yes")
7784                       (const_string "single") (const_string "double")))
7785    (set_attr "type" "jump")
7786    (set_attr "length" "2")])
7788 (define_insn_and_split "sibcall_pcrel"
7789   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7790          (match_operand 1 "" ""))
7791    (use (reg:PSI FPSCR_REG))
7792    (clobber (match_scratch:SI 2 "=k"))
7793    (return)]
7794   "TARGET_SH2"
7795   "#"
7796   "reload_completed"
7797   [(const_int 0)]
7798   "
7800   rtx lab = PATTERN (gen_call_site ());
7801   rtx call_insn;
7803   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7804   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7805                                                   lab));
7806   SIBLING_CALL_P (call_insn) = 1;
7807   DONE;
7809   [(set_attr "needs_delay_slot" "yes")
7810    (set (attr "fp_mode")
7811         (if_then_else (eq_attr "fpu_single" "yes")
7812                       (const_string "single") (const_string "double")))
7813    (set_attr "type" "jump_ind")])
7815 (define_insn "sibcall_compact"
7816   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7817          (match_operand 1 "" ""))
7818    (return)
7819    (use (match_operand:SI 2 "register_operand" "z,x"))
7820    (use (reg:SI R1_REG))
7821    (use (reg:PSI FPSCR_REG))
7822    ;; We want to make sure the `x' above will only match MACH_REG
7823    ;; because sibcall_epilogue may clobber MACL_REG.
7824    (clobber (reg:SI MACL_REG))]
7825   "TARGET_SHCOMPACT"
7826   "@
7827         jmp     @%0%#
7828         jmp     @%0\\n  sts     %2, r0"
7829   [(set_attr "needs_delay_slot" "yes,no")
7830    (set_attr "length" "2,4")
7831    (set (attr "fp_mode") (const_string "single"))
7832    (set_attr "type" "jump_ind")])
7834 (define_insn "sibcall_media"
7835   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7836          (match_operand 1 "" ""))
7837    (use (reg:SI PR_MEDIA_REG))
7838    (return)]
7839   "TARGET_SHMEDIA"
7840   "blink        %0, r63"
7841   [(set_attr "type" "jump_media")])
7843 (define_expand "sibcall"
7844   [(parallel
7845     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7846            (match_operand 1 "" ""))
7847      (match_operand 2 "" "")
7848      (use (reg:PSI FPSCR_REG))
7849      (return)])]
7850   ""
7851   "
7853   if (TARGET_SHMEDIA)
7854     {
7855       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7856       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7857       DONE;
7858     }
7859   else if (TARGET_SHCOMPACT && operands[2]
7860            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7861     {
7862       rtx cookie_rtx = operands[2];
7863       long cookie = INTVAL (cookie_rtx);
7864       rtx func = XEXP (operands[0], 0);
7865       rtx mach, r1;
7867       if (flag_pic)
7868         {
7869           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7870             {
7871               rtx reg = gen_reg_rtx (Pmode);
7873               emit_insn (gen_symGOT2reg (reg, func));
7874               func = reg;
7875             }
7876           else
7877             func = legitimize_pic_address (func, Pmode, 0);
7878         }
7880       /* FIXME: if we could tell whether all argument registers are
7881          already taken, we could decide whether to force the use of
7882          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7883          simple way to tell.  We could use the CALL_COOKIE, but we
7884          can't currently tell a register used for regular argument
7885          passing from one that is unused.  If we leave it up to reload
7886          to decide which register to use, it seems to always choose
7887          R0_REG, which leaves no available registers in SIBCALL_REGS
7888          to hold the address of the trampoline.  */
7889       mach = gen_rtx_REG (SImode, MACH_REG);
7890       r1 = gen_rtx_REG (SImode, R1_REG);
7892       /* Since such a call function may use all call-clobbered
7893          registers, we force a mode switch earlier, so that we don't
7894          run out of registers when adjusting fpscr for the call.  */
7895       emit_insn (gen_force_mode_for_call ());
7897       operands[0]
7898         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7899                            SFUNC_GOT);
7900       operands[0] = force_reg (SImode, operands[0]);
7902       /* We don't need a return trampoline, since the callee will
7903          return directly to the upper caller.  */
7904       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7905         {
7906           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7907           cookie_rtx = GEN_INT (cookie);
7908         }
7910       emit_move_insn (mach, func);
7911       emit_move_insn (r1, cookie_rtx);
7913       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7914       DONE;
7915     }
7916   else if (TARGET_SHCOMPACT && flag_pic
7917            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7918            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7919     {
7920       rtx reg = gen_reg_rtx (Pmode);
7922       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7923       XEXP (operands[0], 0) = reg;
7924     }
7925   if (flag_pic && TARGET_SH2
7926       && GET_CODE (operands[0]) == MEM
7927       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7928       /* The PLT needs the PIC register, but the epilogue would have
7929          to restore it, so we can only use PC-relative PIC calls for
7930          static functions.  */
7931       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7932     {
7933       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7934       DONE;
7935     }
7936   else
7937     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7939   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7940   DONE;
7943 (define_expand "sibcall_value"
7944   [(set (match_operand 0 "" "")
7945         (call (match_operand 1 "" "")
7946               (match_operand 2 "" "")))
7947    (match_operand 3 "" "")]
7948   ""
7949   "
7951   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7952   DONE;
7955 (define_insn "call_value_pop_compact"
7956   [(set (match_operand 0 "" "=rf")
7957         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7958               (match_operand 2 "" "")))
7959    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7960                                  (match_operand 4 "immediate_operand" "n")))
7961    (match_operand 3 "immediate_operand" "n")
7962    (use (reg:SI R0_REG))
7963    (use (reg:SI R1_REG))
7964    (use (reg:PSI FPSCR_REG))
7965    (clobber (reg:SI PR_REG))]
7966   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7967   "jsr  @%1%#"
7968   [(set_attr "type" "call")
7969    (set (attr "fp_mode")
7970         (if_then_else (eq_attr "fpu_single" "yes")
7971                       (const_string "single") (const_string "double")))
7972    (set_attr "needs_delay_slot" "yes")])
7974 (define_insn "call_value_pop_compact_rettramp"
7975   [(set (match_operand 0 "" "=rf")
7976         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7977               (match_operand 2 "" "")))
7978    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7979                                  (match_operand 4 "immediate_operand" "n")))
7980    (match_operand 3 "immediate_operand" "n")
7981    (use (reg:SI R0_REG))
7982    (use (reg:SI R1_REG))
7983    (use (reg:PSI FPSCR_REG))
7984    (clobber (reg:SI R10_REG))
7985    (clobber (reg:SI PR_REG))]
7986   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7987   "jsr  @%1%#"
7988   [(set_attr "type" "call")
7989    (set (attr "fp_mode")
7990         (if_then_else (eq_attr "fpu_single" "yes")
7991                       (const_string "single") (const_string "double")))
7992    (set_attr "needs_delay_slot" "yes")])
7994 (define_expand "call_value_pop"
7995   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7996                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7997                                  (match_operand 2 "" "")))
7998               (match_operand 3 "" "")
7999               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8000                                             (match_operand 4 "" "")))])]
8001   "TARGET_SHCOMPACT"
8002   "
8004   rtx cookie_rtx;
8005   long cookie;
8006   rtx func;
8007   rtx r0, r1;
8009   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8010   cookie_rtx = operands[3];
8011   cookie = INTVAL (cookie_rtx);
8012   func = XEXP (operands[1], 0);
8014   if (flag_pic)
8015     {
8016       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8017         {
8018           rtx reg = gen_reg_rtx (Pmode);
8020           emit_insn (gen_symGOTPLT2reg (reg, func));
8021           func = reg;
8022         }
8023       else
8024         func = legitimize_pic_address (func, Pmode, 0);
8025     }
8027   r0 = gen_rtx_REG (SImode, R0_REG);
8028   r1 = gen_rtx_REG (SImode, R1_REG);
8030   /* Since such a call function may use all call-clobbered
8031      registers, we force a mode switch earlier, so that we don't
8032      run out of registers when adjusting fpscr for the call.  */
8033   emit_insn (gen_force_mode_for_call ());
8035   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8036                                  SFUNC_GOT);
8037   operands[1] = force_reg (SImode, operands[1]);
8039   emit_move_insn (r0, func);
8040   emit_move_insn (r1, cookie_rtx);
8042   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8043     emit_call_insn (gen_call_value_pop_compact_rettramp
8044                         (operands[0], operands[1], operands[2],
8045                          operands[3], operands[4]));
8046   else
8047     emit_call_insn (gen_call_value_pop_compact
8048                         (operands[0], operands[1], operands[2],
8049                          operands[3], operands[4]));
8051   DONE;
8054 (define_expand "sibcall_epilogue"
8055   [(return)]
8056   ""
8057   "
8059   sh_expand_epilogue (1);
8060   if (TARGET_SHCOMPACT)
8061     {
8062       rtx insn, set;
8064       /* If epilogue clobbers r0, preserve it in macl.  */
8065       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8066         if ((set = single_set (insn))
8067             && GET_CODE (SET_DEST (set)) == REG
8068             && REGNO (SET_DEST (set)) == R0_REG)
8069           {
8070             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8071             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8072             rtx i;
8074             /* We can't tell at this point whether the sibcall is a
8075                sibcall_compact and, if it is, whether it uses r0 or
8076                mach as operand 2, so let the instructions that
8077                preserve r0 be optimized away if r0 turns out to be
8078                dead.  */
8079             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8080             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8081                                                REG_NOTES (i));
8082             i = emit_move_insn (r0, tmp);
8083             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8084                                                REG_NOTES (i));
8085             break;
8086           }
8087     }
8088   DONE;
8091 (define_insn "indirect_jump_compact"
8092   [(set (pc)
8093         (match_operand:SI 0 "arith_reg_operand" "r"))]
8094   "TARGET_SH1"
8095   "jmp  @%0%#"
8096   [(set_attr "needs_delay_slot" "yes")
8097    (set_attr "type" "jump_ind")])
8099 (define_expand "indirect_jump"
8100   [(set (pc)
8101         (match_operand 0 "register_operand" ""))]
8102   ""
8103   "
8105   if (GET_MODE (operands[0]) != Pmode)
8106     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8109 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8110 ;; which can be present in structured code from indirect jumps which can not
8111 ;; be present in structured code.  This allows -fprofile-arcs to work.
8113 ;; For SH1 processors.
8114 (define_insn "casesi_jump_1"
8115   [(set (pc)
8116         (match_operand:SI 0 "register_operand" "r"))
8117    (use (label_ref (match_operand 1 "" "")))]
8118   "TARGET_SH1"
8119   "jmp  @%0%#"
8120   [(set_attr "needs_delay_slot" "yes")
8121    (set_attr "type" "jump_ind")])
8123 ;; For all later processors.
8124 (define_insn "casesi_jump_2"
8125   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8126                       (label_ref (match_operand 1 "" ""))))
8127    (use (label_ref (match_operand 2 "" "")))]
8128   "TARGET_SH2
8129    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8130   "braf %0%#"
8131   [(set_attr "needs_delay_slot" "yes")
8132    (set_attr "type" "jump_ind")])
8134 (define_insn "casesi_jump_media"
8135   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8136    (use (label_ref (match_operand 1 "" "")))]
8137   "TARGET_SHMEDIA"
8138   "blink        %0, r63"
8139   [(set_attr "type" "jump_media")])
8141 ;; Call subroutine returning any type.
8142 ;; ??? This probably doesn't work.
8144 (define_expand "untyped_call"
8145   [(parallel [(call (match_operand 0 "" "")
8146                     (const_int 0))
8147               (match_operand 1 "" "")
8148               (match_operand 2 "" "")])]
8149   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8150   "
8152   int i;
8154   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8156   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8157     {
8158       rtx set = XVECEXP (operands[2], 0, i);
8159       emit_move_insn (SET_DEST (set), SET_SRC (set));
8160     }
8162   /* The optimizer does not know that the call sets the function value
8163      registers we stored in the result block.  We avoid problems by
8164      claiming that all hard registers are used and clobbered at this
8165      point.  */
8166   emit_insn (gen_blockage ());
8168   DONE;
8171 ;; ------------------------------------------------------------------------
8172 ;; Misc insns
8173 ;; ------------------------------------------------------------------------
8175 (define_insn "dect"
8176   [(set (reg:SI T_REG)
8177         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8178    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8179   "TARGET_SH2"
8180   "dt   %0"
8181   [(set_attr "type" "arith")])
8183 (define_insn "nop"
8184   [(const_int 0)]
8185   ""
8186   "nop")
8188 ;; Load address of a label. This is only generated by the casesi expand,
8189 ;; and by machine_dependent_reorg (fixing up fp moves).
8190 ;; This must use unspec, because this only works for labels that are
8191 ;; within range,
8193 (define_insn "mova"
8194   [(set (reg:SI R0_REG)
8195         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8196   "TARGET_SH1"
8197   "mova %O0,r0"
8198   [(set_attr "in_delay_slot" "no")
8199    (set_attr "type" "arith")])
8201 ;; machine_dependent_reorg will make this a `mova'.
8202 (define_insn "mova_const"
8203   [(set (reg:SI R0_REG)
8204         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8205   "TARGET_SH1"
8206   "#"
8207   [(set_attr "in_delay_slot" "no")
8208    (set_attr "type" "arith")])
8210 (define_expand "GOTaddr2picreg"
8211   [(set (reg:SI R0_REG)
8212         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8213                    UNSPEC_MOVA))
8214    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8215    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8216   "" "
8218   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8219   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8221   if (TARGET_SHMEDIA)
8222     {
8223       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8224       rtx pic = operands[0];
8225       rtx lab = PATTERN (gen_call_site ());
8226       rtx insn, equiv;
8228       equiv = operands[1];
8229       operands[1] = gen_rtx_MINUS (Pmode,
8230                                    operands[1],
8231                                    gen_rtx_CONST
8232                                    (Pmode,
8233                                     gen_rtx_MINUS (Pmode,
8234                                                    gen_rtx_CONST (Pmode,
8235                                                                   lab),
8236                                                    pc_rtx)));
8237       operands[1] = gen_sym2PIC (operands[1]);
8238       PUT_MODE (operands[1], Pmode);
8240       if (Pmode == SImode)
8241         {
8242           emit_insn (gen_movsi_const (pic, operands[1]));
8243           emit_insn (gen_ptrel_si (tr, pic, lab));
8244         }
8245       else
8246         {
8247           emit_insn (gen_movdi_const (pic, operands[1]));
8248           emit_insn (gen_ptrel_di (tr, pic, lab));
8249         }
8251       insn = emit_move_insn (operands[0], tr);
8253       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8254                                             REG_NOTES (insn));
8256       DONE;
8257     }
8261 (define_insn "*ptb"
8262   [(set (match_operand 0 "target_reg_operand" "=b")
8263         (const (unspec [(match_operand 1 "" "Csy")]
8264                              UNSPEC_DATALABEL)))]
8265   "TARGET_SHMEDIA && flag_pic
8266    && EXTRA_CONSTRAINT_Csy (operands[1])"
8267   "ptb/u        datalabel %1, %0"
8268   [(set_attr "type" "ptabs_media")
8269    (set_attr "length" "*")])
8271 (define_insn "ptrel_si"
8272   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8273         (plus:SI (match_operand:SI 1 "register_operand" "r")
8274               (pc)))
8275    (match_operand:SI 2 "" "")]
8276   "TARGET_SHMEDIA"
8277   "%O2: ptrel/u %1, %0"
8278   [(set_attr "type" "ptabs_media")])
8280 (define_insn "ptrel_di"
8281   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8282         (plus:DI (match_operand:DI 1 "register_operand" "r")
8283               (pc)))
8284    (match_operand:DI 2 "" "")]
8285   "TARGET_SHMEDIA"
8286   "%O2: ptrel/u %1, %0"
8287   [(set_attr "type" "ptabs_media")])
8289 (define_expand "builtin_setjmp_receiver"
8290   [(match_operand 0 "" "")]
8291   "flag_pic"
8292   "
8294   emit_insn (gen_GOTaddr2picreg ());
8295   DONE;
8298 (define_expand "call_site"
8299   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8300   "TARGET_SH1"
8301   "
8303   static HOST_WIDE_INT i = 0;
8304   operands[0] = GEN_INT (i);
8305   i++;
8308 (define_expand "sym_label2reg"
8309   [(set (match_operand:SI 0 "" "")
8310         (const:SI (minus:SI
8311                    (const:SI
8312                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8313                    (const:SI
8314                     (plus:SI
8315                      (match_operand:SI 2 "" "")
8316                      (const_int 2))))))]
8317   "TARGET_SH1" "")
8319 (define_expand "symGOT_load"
8320   [(set (match_dup 2) (match_operand 1 "" ""))
8321    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8322    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8323   ""
8324   "
8326   rtx insn, mem;
8328   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8329   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8331   if (TARGET_SHMEDIA)
8332     {
8333       rtx reg = operands[2];
8335       if (Pmode == DImode)
8336         {      
8337           if (flag_pic > 1)
8338             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8339           else
8340             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8341         }
8342       else
8343         {
8344           if (flag_pic > 1)
8345             emit_insn (gen_movsi_const (reg, operands[1]));
8346           else
8347             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8348         }
8349     }
8350   else
8351     emit_move_insn (operands[2], operands[1]);
8353   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8354                                              operands[2],
8355                                              gen_rtx_REG (Pmode, PIC_REG)));
8357   /* N.B. This is not constant for a GOTPLT relocation.  */
8358   mem = gen_rtx_MEM (Pmode, operands[3]);
8359   MEM_NOTRAP_P (mem) = 1;
8360   /* ??? Should we have a special alias set for the GOT?  */
8361   insn = emit_move_insn (operands[0], mem);
8363   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8364                                                                   0), 0, 0),
8365                                         REG_NOTES (insn));
8367   DONE;
8370 (define_expand "sym2GOT"
8371   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8372   ""
8373   "")
8375 (define_expand "symGOT2reg"
8376   [(match_operand 0 "" "") (match_operand 1 "" "")]
8377   ""
8378   "
8380   rtx gotsym, insn;
8382   gotsym = gen_sym2GOT (operands[1]);
8383   PUT_MODE (gotsym, Pmode);
8384   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8386   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8388   DONE;
8391 (define_expand "symGOTPLT2reg"
8392   [(match_operand 0 "" "") (match_operand 1 "" "")]
8393   ""
8394   "
8396   rtx pltsym = gen_rtx_CONST (Pmode,
8397                               gen_rtx_UNSPEC (Pmode,
8398                                               gen_rtvec (1, operands[1]),
8399                                               UNSPEC_GOTPLT));
8400   emit_insn (gen_symGOT_load (operands[0], pltsym));
8401   DONE;
8404 (define_expand "sym2GOTOFF"
8405   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8406   ""
8407   "")
8409 (define_expand "symGOTOFF2reg"
8410   [(match_operand 0 "" "") (match_operand 1 "" "")]
8411   ""
8412   "
8414   rtx gotoffsym, insn;
8415   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8417   gotoffsym = gen_sym2GOTOFF (operands[1]);
8418   PUT_MODE (gotoffsym, Pmode);
8419   emit_move_insn (t, gotoffsym);
8420   insn = emit_move_insn (operands[0],
8421                          gen_rtx_PLUS (Pmode, t,
8422                                        gen_rtx_REG (Pmode, PIC_REG)));
8424   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8425                                         REG_NOTES (insn));
8427   DONE;
8430 (define_expand "symPLT_label2reg"
8431   [(set (match_operand:SI 0 "" "")
8432         (const:SI (minus:SI
8433                    (const:SI
8434                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8435                    (const:SI
8436                     (minus:SI
8437                      (const:SI (plus:SI
8438                                 (match_operand:SI 2 "" "")
8439                                 (const_int 2)))
8440                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8441    ;; Even though the PIC register is not really used by the call
8442    ;; sequence in which this is expanded, the PLT code assumes the PIC
8443    ;; register is set, so we must not skip its initialization.  Since
8444    ;; we only use this expand as part of calling sequences, and never
8445    ;; to take the address of a function, this is the best point to
8446    ;; insert the (use).  Using the PLT to take the address of a
8447    ;; function would be wrong, not only because the PLT entry could
8448    ;; then be called from a function that doesn't initialize the PIC
8449    ;; register to the proper GOT, but also because pointers to the
8450    ;; same function might not compare equal, should they be set by
8451    ;; different shared libraries.
8452    (use (reg:SI PIC_REG))]
8453   "TARGET_SH1"
8454   "")
8456 (define_expand "sym2PIC"
8457   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8458   ""
8459   "")
8461 ;; TLS code generation.
8462 ;; ??? this should be a define_insn_and_split
8463 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8464 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8465 ;; for details.
8467 (define_insn "tls_global_dynamic"
8468   [(set (match_operand:SI 0 "register_operand" "=&z")
8469         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8470                                   UNSPEC_TLSGD))
8471               (const_int 0)))
8472    (use (reg:PSI FPSCR_REG))
8473    (use (reg:SI PIC_REG))
8474    (clobber (reg:SI PR_REG))
8475    (clobber (scratch:SI))]
8476   "TARGET_SH1"
8477   "*
8479   return \"\\
8480 mov.l\\t1f,r4\\n\\
8481 \\tmova\\t2f,r0\\n\\
8482 \\tmov.l\\t2f,r1\\n\\
8483 \\tadd\\tr0,r1\\n\\
8484 \\tjsr\\t@r1\\n\\
8485 \\tadd\\tr12,r4\\n\\
8486 \\tbra\\t3f\\n\\
8487 \\tnop\\n\\
8488 \\t.align\\t2\\n\\
8489 1:\\t.long\\t%a1@TLSGD\\n\\
8490 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8491 3:\";
8493   [(set_attr "type" "tls_load")
8494    (set_attr "length" "26")])
8496 (define_insn "tls_local_dynamic"
8497   [(set (match_operand:SI 0 "register_operand" "=&z")
8498         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8499                                   UNSPEC_TLSLDM))
8500               (const_int 0)))
8501    (use (reg:PSI FPSCR_REG))
8502    (use (reg:SI PIC_REG))
8503    (clobber (reg:SI PR_REG))
8504    (clobber (scratch:SI))]
8505   "TARGET_SH1"
8506   "*
8508   return \"\\
8509 mov.l\\t1f,r4\\n\\
8510 \\tmova\\t2f,r0\\n\\
8511 \\tmov.l\\t2f,r1\\n\\
8512 \\tadd\\tr0,r1\\n\\
8513 \\tjsr\\t@r1\\n\\
8514 \\tadd\\tr12,r4\\n\\
8515 \\tbra\\t3f\\n\\
8516 \\tnop\\n\\
8517 \\t.align\\t2\\n\\
8518 1:\\t.long\\t%a1@TLSLDM\\n\\
8519 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8520 3:\";
8522   [(set_attr "type" "tls_load")
8523    (set_attr "length" "26")])
8525 (define_expand "sym2DTPOFF"
8526   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8527   ""
8528   "")
8530 (define_expand "symDTPOFF2reg"
8531   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8532   ""
8533   "
8535   rtx dtpoffsym, insn;
8536   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8538   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8539   PUT_MODE (dtpoffsym, Pmode);
8540   emit_move_insn (t, dtpoffsym);
8541   insn = emit_move_insn (operands[0],
8542                          gen_rtx_PLUS (Pmode, t, operands[2]));
8543   DONE;
8546 (define_expand "sym2GOTTPOFF"
8547   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8548   ""
8549   "")
8551 (define_insn "tls_initial_exec"
8552   [(set (match_operand:SI 0 "register_operand" "=&r")
8553         (unspec:SI [(match_operand:SI 1 "" "")]
8554                     UNSPEC_TLSIE))
8555    (use (reg:SI GBR_REG))
8556    (use (reg:SI PIC_REG))
8557    (clobber (reg:SI R0_REG))]
8558   ""
8559   "*
8561   return \"\\
8562 mov.l\\t1f,r0\\n\\
8563 \\tstc\\tgbr,%0\\n\\
8564 \\tmov.l\\t@(r0,r12),r0\\n\\
8565 \\tbra\\t2f\\n\\
8566 \\tadd\\tr0,%0\\n\\
8567 \\t.align\\t2\\n\\
8568 1:\\t.long\\t%a1\\n\\
8569 2:\";
8571   [(set_attr "type" "tls_load")
8572    (set_attr "length" "16")])
8574 (define_expand "sym2TPOFF"
8575   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8576   ""
8577   "")
8579 (define_expand "symTPOFF2reg"
8580   [(match_operand 0 "" "") (match_operand 1 "" "")]
8581   ""
8582   "
8584   rtx tpoffsym, insn;
8586   tpoffsym = gen_sym2TPOFF (operands[1]);
8587   PUT_MODE (tpoffsym, Pmode);
8588   insn = emit_move_insn (operands[0], tpoffsym);
8589   DONE;
8592 (define_insn "load_gbr"
8593   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8594    (use (reg:SI GBR_REG))]
8595   ""
8596   "stc  gbr,%0"
8597   [(set_attr "type" "tls_load")])
8599 ;; case instruction for switch statements.
8601 ;; Operand 0 is index
8602 ;; operand 1 is the minimum bound
8603 ;; operand 2 is the maximum bound - minimum bound + 1
8604 ;; operand 3 is CODE_LABEL for the table;
8605 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8607 (define_expand "casesi"
8608   [(match_operand:SI 0 "arith_reg_operand" "")
8609    (match_operand:SI 1 "arith_reg_operand" "")
8610    (match_operand:SI 2 "arith_reg_operand" "")
8611    (match_operand 3 "" "") (match_operand 4 "" "")]
8612   ""
8613   "
8615   rtx reg = gen_reg_rtx (SImode);
8616   rtx reg2 = gen_reg_rtx (SImode);
8617   if (TARGET_SHMEDIA)
8618     {
8619       rtx reg = gen_reg_rtx (DImode);
8620       rtx reg2 = gen_reg_rtx (DImode);
8621       rtx reg3 = gen_reg_rtx (Pmode);
8622       rtx reg4 = gen_reg_rtx (Pmode);
8623       rtx reg5 = gen_reg_rtx (Pmode);
8624       rtx load;
8626       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8627       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8628       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8630       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8631       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8632       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8633       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8634       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8635                                                (Pmode, operands[3])));
8636       /* Messy: can we subreg to clean this up? */
8637       if (Pmode == DImode)
8638         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8639       else
8640         load = gen_casesi_load_media (reg4,
8641                                       gen_rtx_SUBREG (DImode, reg3, 0),
8642                                       reg2, operands[3]);
8643       PUT_MODE (SET_SRC (load), Pmode);
8644       emit_insn (load);
8645       /* ??? The following add could be eliminated if we used ptrel.  */
8646       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8647       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8648       emit_barrier ();
8649       DONE;
8650     }
8651   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8652   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8653   /* If optimizing, casesi_worker depends on the mode of the instruction
8654      before label it 'uses' - operands[3].  */
8655   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8656                            reg));
8657   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8658   if (TARGET_SH2)
8659     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8660   else
8661     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8662   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8663      operands[3], but to lab.  We will fix this up in
8664      machine_dependent_reorg.  */
8665   emit_barrier ();
8666   DONE;
8669 (define_expand "casesi_0"
8670   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8671    (set (match_dup 4) (minus:SI (match_dup 4)
8672                                 (match_operand:SI 1 "arith_operand" "")))
8673    (set (reg:SI T_REG)
8674         (gtu:SI (match_dup 4)
8675                 (match_operand:SI 2 "arith_reg_operand" "")))
8676    (set (pc)
8677         (if_then_else (ne (reg:SI T_REG)
8678                           (const_int 0))
8679                       (label_ref (match_operand 3 "" ""))
8680                       (pc)))]
8681   "TARGET_SH1"
8682   "")
8684 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8685 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8686 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8688 (define_insn "casesi_worker_0"
8689   [(set (match_operand:SI 0 "register_operand" "=r,r")
8690         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8691                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8692    (clobber (match_scratch:SI 3 "=X,1"))
8693    (clobber (match_scratch:SI 4 "=&z,z"))]
8694   "TARGET_SH1"
8695   "#")
8697 (define_split
8698   [(set (match_operand:SI 0 "register_operand" "")
8699         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8700                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8701    (clobber (match_scratch:SI 3 ""))
8702    (clobber (match_scratch:SI 4 ""))]
8703   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8704   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8705    (parallel [(set (match_dup 0)
8706               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8707                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8708               (clobber (match_dup 3))])
8709    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8710   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8712 (define_split
8713   [(set (match_operand:SI 0 "register_operand" "")
8714         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8715                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8716    (clobber (match_scratch:SI 3 ""))
8717    (clobber (match_scratch:SI 4 ""))]
8718   "TARGET_SH2 && reload_completed"
8719   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8720    (parallel [(set (match_dup 0)
8721               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8722                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8723               (clobber (match_dup 3))])]
8724   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8726 (define_insn "casesi_worker_1"
8727   [(set (match_operand:SI 0 "register_operand" "=r,r")
8728         (unspec:SI [(reg:SI R0_REG)
8729                     (match_operand:SI 1 "register_operand" "0,r")
8730                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8731    (clobber (match_scratch:SI 3 "=X,1"))]
8732   "TARGET_SH1"
8733   "*
8735   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8737   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8739   switch (GET_MODE (diff_vec))
8740     {
8741     case SImode:
8742       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8743     case HImode:
8744       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8745     case QImode:
8746       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8747         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8748       return \"mov.b    @(r0,%1),%0\";
8749     default:
8750       gcc_unreachable ();
8751     }
8753   [(set_attr "length" "4")])
8755 (define_insn "casesi_worker_2"
8756   [(set (match_operand:SI 0 "register_operand" "=r,r")
8757         (unspec:SI [(reg:SI R0_REG)
8758                     (match_operand:SI 1 "register_operand" "0,r")
8759                     (label_ref (match_operand 2 "" ""))
8760                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8761    (clobber (match_operand:SI 4 "" "=X,1"))]
8762   "TARGET_SH2 && reload_completed && flag_pic"
8763   "*
8765   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8766   const char *load;
8768   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8770   switch (GET_MODE (diff_vec))
8771     {
8772     case SImode:
8773       output_asm_insn (\"shll2    %1\", operands);
8774       load = \"mov.l    @(r0,%1),%0\"; break;
8775     case HImode:
8776       output_asm_insn (\"add    %1,%1\", operands);
8777       load = \"mov.w    @(r0,%1),%0\"; break;
8778     case QImode:
8779       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8780         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8781       else
8782         load = \"mov.b  @(r0,%1),%0\";
8783       break;
8784     default:
8785       gcc_unreachable ();
8786     }
8787   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8788   return load;
8790   [(set_attr "length" "8")])
8792 (define_insn "casesi_shift_media"
8793   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8794         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8795                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8796                     UNSPEC_CASESI)))]
8797   "TARGET_SHMEDIA"
8798   "*
8800   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8802   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8804   switch (GET_MODE (diff_vec))
8805     {
8806     case SImode:
8807       return \"shlli    %1, 2, %0\";
8808     case HImode:
8809       return \"shlli    %1, 1, %0\";
8810     case QImode:
8811       if (rtx_equal_p (operands[0], operands[1]))
8812         return \"\";
8813       return \"add      %1, r63, %0\";
8814     default:
8815       gcc_unreachable ();
8816     }
8818   [(set_attr "type" "arith_media")])
8820 (define_insn "casesi_load_media"
8821   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8822         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8823                          (match_operand:DI 2 "arith_reg_operand" "r")
8824                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8825   "TARGET_SHMEDIA"
8826   "*
8828   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8830   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8832   switch (GET_MODE (diff_vec))
8833     {
8834     case SImode:
8835       return \"ldx.l    %1, %2, %0\";
8836     case HImode:
8837 #if 0
8838       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8839         return \"ldx.uw %1, %2, %0\";
8840 #endif
8841       return \"ldx.w    %1, %2, %0\";
8842     case QImode:
8843       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8844         return \"ldx.ub %1, %2, %0\";
8845       return \"ldx.b    %1, %2, %0\";
8846     default:
8847       gcc_unreachable ();
8848     }
8850   [(set_attr "type" "load_media")])
8852 (define_expand "return"
8853   [(return)]
8854   "reload_completed && ! sh_need_epilogue ()"
8855   "
8857   if (TARGET_SHMEDIA)
8858     {
8859       emit_jump_insn (gen_return_media ());
8860       DONE;
8861     }
8863   if (TARGET_SHCOMPACT
8864       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8865     {
8866       emit_jump_insn (gen_shcompact_return_tramp ());
8867       DONE;
8868     }
8871 (define_insn "*return_i"
8872   [(return)]
8873   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8874                     && (current_function_args_info.call_cookie
8875                         & CALL_COOKIE_RET_TRAMP (1)))
8876    && reload_completed
8877    && lookup_attribute (\"trap_exit\",
8878                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
8879   "%@   %#"
8880   [(set_attr "type" "return")
8881    (set_attr "needs_delay_slot" "yes")])
8883 ;; trapa has no delay slot.
8884 (define_insn "*return_trapa"
8885   [(return)]
8886   "TARGET_SH1 && !TARGET_SHCOMPACT
8887    && reload_completed"
8888   "%@"
8889   [(set_attr "type" "return")])
8891 (define_expand "shcompact_return_tramp"
8892   [(return)]
8893   "TARGET_SHCOMPACT
8894    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8895   "
8897   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8899   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8900   emit_jump_insn (gen_shcompact_return_tramp_i ());
8901   DONE;
8904 (define_insn "shcompact_return_tramp_i"
8905   [(parallel [(return) (use (reg:SI R0_REG))])]
8906   "TARGET_SHCOMPACT
8907    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8908   "jmp  @r0%#"
8909   [(set_attr "type" "jump_ind")
8910    (set_attr "needs_delay_slot" "yes")])
8912 (define_insn "return_media_i"
8913   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8914   "TARGET_SHMEDIA && reload_completed"
8915   "blink        %0, r63"
8916   [(set_attr "type" "jump_media")])
8918 (define_insn "return_media_rte"
8919   [(return)]
8920   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8921   "rte"
8922   [(set_attr "type" "jump_media")])
8924 (define_expand "return_media"
8925   [(return)]
8926   "TARGET_SHMEDIA && reload_completed"
8927   "
8929   int tr_regno = sh_media_register_for_return ();
8930   rtx tr;
8932   if (current_function_interrupt)
8933     {
8934       emit_jump_insn (gen_return_media_rte ());
8935       DONE;
8936     }
8937   if (tr_regno < 0)
8938     {
8939       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8941       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8942       tr_regno = TR0_REG;
8943       tr = gen_rtx_REG (Pmode, tr_regno);
8944       emit_move_insn (tr, r18);
8945     }
8946   else
8947     tr = gen_rtx_REG (Pmode, tr_regno);
8949   emit_jump_insn (gen_return_media_i (tr));
8950   DONE;
8953 (define_insn "shcompact_preserve_incoming_args"
8954   [(set (match_operand:SI 0 "register_operand" "+r")
8955         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8956   "TARGET_SHCOMPACT"
8957   ""
8958   [(set_attr "length" "0")])
8960 (define_insn "shcompact_incoming_args"
8961   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8962    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8963    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8964    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8965    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8966    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8967    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8968    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8969    (set (mem:BLK (reg:SI MACL_REG))
8970         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8971    (use (reg:SI R0_REG))
8972    (clobber (reg:SI R0_REG))
8973    (clobber (reg:SI MACL_REG))
8974    (clobber (reg:SI MACH_REG))
8975    (clobber (reg:SI PR_REG))]
8976   "TARGET_SHCOMPACT"
8977   "jsr  @r0%#"
8978   [(set_attr "needs_delay_slot" "yes")])
8980 (define_insn "shmedia_save_restore_regs_compact"
8981   [(set (reg:SI SP_REG)
8982         (plus:SI (reg:SI SP_REG)
8983                  (match_operand:SI 0 "immediate_operand" "i")))
8984    (use (reg:SI R0_REG))
8985    (clobber (reg:SI PR_REG))]
8986   "TARGET_SHCOMPACT
8987    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8988        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8989   "jsr @r0%#"
8990   [(set_attr "needs_delay_slot" "yes")])
8992 (define_expand "prologue"
8993   [(const_int 0)]
8994   ""
8995   "sh_expand_prologue (); DONE;")
8997 (define_expand "epilogue"
8998   [(return)]
8999   ""
9000   "
9002   sh_expand_epilogue (0);
9003   emit_jump_insn (gen_return ());
9004   DONE;
9007 (define_expand "eh_return"
9008   [(use (match_operand 0 "register_operand" ""))]
9009   ""
9011   rtx ra = operands[0];
9013   if (TARGET_SHMEDIA64)
9014     emit_insn (gen_eh_set_ra_di (ra));
9015   else
9016     emit_insn (gen_eh_set_ra_si (ra));
9018   DONE;
9021 ;; Clobber the return address on the stack.  We can't expand this
9022 ;; until we know where it will be put in the stack frame.
9024 (define_insn "eh_set_ra_si"
9025   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9026    (clobber (match_scratch:SI 1 "=&r"))]
9027   "! TARGET_SHMEDIA64"
9028   "#")
9030 (define_insn "eh_set_ra_di"
9031   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
9032    (clobber (match_scratch:DI 1 "=&r"))]
9033   "TARGET_SHMEDIA64"
9034   "#")
9036 (define_split
9037   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
9038    (clobber (match_scratch 1 ""))]
9039   "reload_completed"
9040   [(const_int 0)]
9041   "
9043   sh_set_return_address (operands[0], operands[1]);
9044   DONE;
9047 (define_insn "blockage"
9048   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9049   ""
9050   ""
9051   [(set_attr "length" "0")])
9053 ;; ------------------------------------------------------------------------
9054 ;; Scc instructions
9055 ;; ------------------------------------------------------------------------
9057 (define_insn "movt"
9058   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9059         (eq:SI (reg:SI T_REG) (const_int 1)))]
9060   "TARGET_SH1"
9061   "movt %0"
9062   [(set_attr "type" "arith")])
9064 (define_expand "seq"
9065   [(set (match_operand:SI 0 "arith_reg_dest" "")
9066         (match_dup 1))]
9067   ""
9068   "
9070   if (TARGET_SHMEDIA)
9071     {
9072       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9073       if (sh_compare_op1 != const0_rtx)
9074         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9075                                     ? GET_MODE (sh_compare_op0)
9076                                     : GET_MODE (sh_compare_op1),
9077                                     sh_compare_op1);
9078       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9079         {
9080           if (GET_MODE (operands[0]) != SImode)
9081             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9083           switch (GET_MODE (sh_compare_op0))
9084             {
9085             case SImode:
9086               emit_insn (gen_cmpsieqsi_media (operands[0],
9087                                               sh_compare_op0, sh_compare_op1));
9088               break;
9090             case DImode:
9091               emit_insn (gen_cmpsieqdi_media (operands[0],
9092                                               sh_compare_op0, sh_compare_op1));
9093               break;
9095             case SFmode:
9096               if (! TARGET_SHMEDIA_FPU)
9097                 FAIL;
9098               emit_insn (gen_cmpsieqsf_media (operands[0],
9099                                               sh_compare_op0, sh_compare_op1));
9100               break;
9102             case DFmode:
9103               if (! TARGET_SHMEDIA_FPU)
9104                 FAIL;
9105               emit_insn (gen_cmpsieqdf_media (operands[0],
9106                                               sh_compare_op0, sh_compare_op1));
9107               break;
9109             default:
9110               FAIL;
9111             }
9112           DONE;
9113         }
9115       if (GET_MODE (operands[0]) != DImode)
9116         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9118       switch (GET_MODE (sh_compare_op0))
9119         {
9120         case SImode:
9121           emit_insn (gen_cmpeqsi_media (operands[0],
9122                                         sh_compare_op0, sh_compare_op1));
9123           break;
9125         case DImode:
9126           emit_insn (gen_cmpeqdi_media (operands[0],
9127                                         sh_compare_op0, sh_compare_op1));
9128           break;
9130         case SFmode:
9131           if (! TARGET_SHMEDIA_FPU)
9132             FAIL;
9133           emit_insn (gen_cmpeqsf_media (operands[0],
9134                                         sh_compare_op0, sh_compare_op1));
9135           break;
9137         case DFmode:
9138           if (! TARGET_SHMEDIA_FPU)
9139             FAIL;
9140           emit_insn (gen_cmpeqdf_media (operands[0],
9141                                         sh_compare_op0, sh_compare_op1));
9142           break;
9144         default:
9145           FAIL;
9146         }
9147       DONE;
9148     }
9149   if (sh_expand_t_scc (EQ, operands[0]))
9150     DONE;
9151   if (! currently_expanding_to_rtl)
9152     FAIL;
9153   operands[1] = prepare_scc_operands (EQ);
9156 (define_expand "slt"
9157   [(set (match_operand:SI 0 "arith_reg_operand" "")
9158         (match_dup 1))]
9159   ""
9160   "
9162   if (TARGET_SHMEDIA)
9163     {
9164       if (GET_MODE (operands[0]) != DImode)
9165         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9166       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9167       if (sh_compare_op1 != const0_rtx)
9168         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9169                                     ? GET_MODE (sh_compare_op0)
9170                                     : GET_MODE (sh_compare_op1),
9171                                     sh_compare_op1);
9173       switch (GET_MODE (sh_compare_op0))
9174         {
9175         case SImode:
9176           emit_insn (gen_cmpgtsi_media (operands[0],
9177                                         sh_compare_op1, sh_compare_op0));
9178           break;
9180         case DImode:
9181           emit_insn (gen_cmpgtdi_media (operands[0],
9182                                         sh_compare_op1, sh_compare_op0));
9183           break;
9185         case SFmode:
9186           if (! TARGET_SHMEDIA_FPU)
9187             FAIL;
9188           emit_insn (gen_cmpgtsf_media (operands[0],
9189                                         sh_compare_op1, sh_compare_op0));
9190           break;
9192         case DFmode:
9193           if (! TARGET_SHMEDIA_FPU)
9194             FAIL;
9195           emit_insn (gen_cmpgtdf_media (operands[0],
9196                                         sh_compare_op1, sh_compare_op0));
9197           break;
9199         default:
9200           FAIL;
9201         }
9202       DONE;
9203     }
9204   if (! currently_expanding_to_rtl)
9205     FAIL;
9206   operands[1] = prepare_scc_operands (LT);
9209 (define_expand "sle"
9210   [(match_operand:SI 0 "arith_reg_operand" "")]
9211   ""
9212   "
9214   rtx tmp = sh_compare_op0;
9216   if (TARGET_SHMEDIA)
9217     {
9218       if (GET_MODE (operands[0]) != DImode)
9219         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9220       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9221       if (sh_compare_op1 != const0_rtx)
9222         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9223                                     ? GET_MODE (sh_compare_op0)
9224                                     : GET_MODE (sh_compare_op1),
9225                                     sh_compare_op1);
9227       switch (GET_MODE (sh_compare_op0))
9228         {
9229         case SImode:
9230           {
9231             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9233             emit_insn (gen_cmpgtsi_media (tmp,
9234                                           sh_compare_op0, sh_compare_op1));
9235             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9236             break;
9237           }
9239         case DImode:
9240           {
9241             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9243             emit_insn (gen_cmpgtdi_media (tmp,
9244                                           sh_compare_op0, sh_compare_op1));
9245             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9246             break;
9247           }
9249         case SFmode:
9250           if (! TARGET_SHMEDIA_FPU)
9251             FAIL;
9252           emit_insn (gen_cmpgesf_media (operands[0],
9253                                         sh_compare_op1, sh_compare_op0));
9254           break;
9256         case DFmode:
9257           if (! TARGET_SHMEDIA_FPU)
9258             FAIL;
9259           emit_insn (gen_cmpgedf_media (operands[0],
9260                                         sh_compare_op1, sh_compare_op0));
9261           break;
9263         default:
9264           FAIL;
9265         }
9266       DONE;
9267     }
9269   sh_compare_op0 = sh_compare_op1;
9270   sh_compare_op1 = tmp;
9271   emit_insn (gen_sge (operands[0]));
9272   DONE;
9275 (define_expand "sgt"
9276   [(set (match_operand:SI 0 "arith_reg_operand" "")
9277         (match_dup 1))]
9278   ""
9279   "
9281   if (TARGET_SHMEDIA)
9282     {
9283       if (GET_MODE (operands[0]) != DImode)
9284         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9285       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9286       if (sh_compare_op1 != const0_rtx)
9287         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9288                                     ? GET_MODE (sh_compare_op0)
9289                                     : GET_MODE (sh_compare_op1),
9290                                     sh_compare_op1);
9292       switch (GET_MODE (sh_compare_op0))
9293         {
9294         case SImode:
9295           emit_insn (gen_cmpgtsi_media (operands[0],
9296                                         sh_compare_op0, sh_compare_op1));
9297           break;
9299         case DImode:
9300           emit_insn (gen_cmpgtdi_media (operands[0],
9301                                         sh_compare_op0, sh_compare_op1));
9302           break;
9304         case SFmode:
9305           if (! TARGET_SHMEDIA_FPU)
9306             FAIL;
9307           emit_insn (gen_cmpgtsf_media (operands[0],
9308                                         sh_compare_op0, sh_compare_op1));
9309           break;
9311         case DFmode:
9312           if (! TARGET_SHMEDIA_FPU)
9313             FAIL;
9314           emit_insn (gen_cmpgtdf_media (operands[0],
9315                                         sh_compare_op0, sh_compare_op1));
9316           break;
9318         default:
9319           FAIL;
9320         }
9321       DONE;
9322     }
9323   if (! currently_expanding_to_rtl)
9324     FAIL;
9325   operands[1] = prepare_scc_operands (GT);
9328 (define_expand "sge"
9329   [(set (match_operand:SI 0 "arith_reg_operand" "")
9330         (match_dup 1))]
9331   ""
9332   "
9334   if (TARGET_SHMEDIA)
9335     {
9336       enum machine_mode mode = GET_MODE (sh_compare_op0);
9338       if ((mode) == VOIDmode)
9339         mode = GET_MODE (sh_compare_op1);
9340       if (GET_MODE (operands[0]) != DImode)
9341         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9342       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9343       if (sh_compare_op1 != const0_rtx)
9344         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9346       switch (mode)
9347         {
9348         case SImode:
9349           {
9350             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9352             emit_insn (gen_cmpgtsi_media (tmp,
9353                                           sh_compare_op1, sh_compare_op0));
9354             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9355             break;
9356           }
9358         case DImode:
9359           {
9360             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9362             emit_insn (gen_cmpgtdi_media (tmp,
9363                                           sh_compare_op1, sh_compare_op0));
9364             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9365             break;
9366           }
9368         case SFmode:
9369           if (! TARGET_SHMEDIA_FPU)
9370             FAIL;
9371           emit_insn (gen_cmpgesf_media (operands[0],
9372                                         sh_compare_op0, sh_compare_op1));
9373           break;
9375         case DFmode:
9376           if (! TARGET_SHMEDIA_FPU)
9377             FAIL;
9378           emit_insn (gen_cmpgedf_media (operands[0],
9379                                         sh_compare_op0, sh_compare_op1));
9380           break;
9382         default:
9383           FAIL;
9384         }
9385       DONE;
9386     }
9388   if (! currently_expanding_to_rtl)
9389     FAIL;
9390   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9391     {
9392       if (TARGET_IEEE)
9393         {
9394           rtx lab = gen_label_rtx ();
9395           prepare_scc_operands (EQ);
9396           emit_jump_insn (gen_branch_true (lab));
9397           prepare_scc_operands (GT);
9398           emit_label (lab);
9399           emit_insn (gen_movt (operands[0]));
9400         }
9401       else
9402         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9403       DONE;
9404     }
9405   operands[1] = prepare_scc_operands (GE);
9408 (define_expand "sgtu"
9409   [(set (match_operand:SI 0 "arith_reg_operand" "")
9410         (match_dup 1))]
9411   ""
9412   "
9414   if (TARGET_SHMEDIA)
9415     {
9416       if (GET_MODE (operands[0]) != DImode)
9417         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9418       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9419       if (sh_compare_op1 != const0_rtx)
9420         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9421                                     ? GET_MODE (sh_compare_op0)
9422                                     : GET_MODE (sh_compare_op1),
9423                                     sh_compare_op1);
9425       emit_insn (gen_cmpgtudi_media (operands[0],
9426                                      sh_compare_op0, sh_compare_op1));
9427       DONE;
9428     }
9429   if (! currently_expanding_to_rtl)
9430     FAIL;
9431   operands[1] = prepare_scc_operands (GTU);
9434 (define_expand "sltu"
9435   [(set (match_operand:SI 0 "arith_reg_operand" "")
9436         (match_dup 1))]
9437   ""
9438   "
9440   if (TARGET_SHMEDIA)
9441     {
9442       if (GET_MODE (operands[0]) != DImode)
9443         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9444       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9445       if (sh_compare_op1 != const0_rtx)
9446         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9447                                     ? GET_MODE (sh_compare_op0)
9448                                     : GET_MODE (sh_compare_op1),
9449                                     sh_compare_op1);
9451       emit_insn (gen_cmpgtudi_media (operands[0],
9452                                      sh_compare_op1, sh_compare_op0));
9453       DONE;
9454     }
9455   if (! currently_expanding_to_rtl)
9456     FAIL;
9457   operands[1] = prepare_scc_operands (LTU);
9460 (define_expand "sleu"
9461   [(set (match_operand:SI 0 "arith_reg_operand" "")
9462         (match_dup 1))]
9463   ""
9464   "
9466   if (TARGET_SHMEDIA)
9467     {
9468       rtx tmp;
9470       if (GET_MODE (operands[0]) != DImode)
9471         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
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);
9479       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9481       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9482       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9484       DONE;
9485     }
9486   if (! currently_expanding_to_rtl)
9487     FAIL;
9488   operands[1] = prepare_scc_operands (LEU);
9491 (define_expand "sgeu"
9492   [(set (match_operand:SI 0 "arith_reg_operand" "")
9493         (match_dup 1))]
9494   ""
9495   "
9497   if (TARGET_SHMEDIA)
9498     {
9499       rtx tmp;
9501       if (GET_MODE (operands[0]) != DImode)
9502         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9503       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9504       if (sh_compare_op1 != const0_rtx)
9505         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9506                                     ? GET_MODE (sh_compare_op0)
9507                                     : GET_MODE (sh_compare_op1),
9508                                     sh_compare_op1);
9510       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9512       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9513       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9515       DONE;
9516     }
9518   if (! currently_expanding_to_rtl)
9519     FAIL;
9520   operands[1] = prepare_scc_operands (GEU);
9523 ;; sne moves the complement of the T reg to DEST like this:
9524 ;;      cmp/eq ...
9525 ;;      mov    #-1,temp
9526 ;;      negc   temp,dest
9527 ;;   This is better than xoring compare result with 1 because it does
9528 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9529 ;;   loop.
9531 (define_expand "sne"
9532   [(set (match_dup 2) (const_int -1))
9533    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9534                    (neg:SI (plus:SI (match_dup 1)
9535                                     (match_dup 2))))
9536               (set (reg:SI T_REG)
9537                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9538                           (const_int 0)))])]
9539   ""
9540   "
9542   if (TARGET_SHMEDIA)
9543     {
9544       rtx tmp;
9546       if (GET_MODE (operands[0]) != DImode)
9547         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9549       if (! TARGET_SHMEDIA_FPU
9550           && GET_MODE (sh_compare_op0) != DImode
9551           && GET_MODE (sh_compare_op0) != SImode)
9552         FAIL;
9554       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9555       if (sh_compare_op1 != const0_rtx)
9556         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9557                                     ? GET_MODE (sh_compare_op0)
9558                                     : GET_MODE (sh_compare_op1),
9559                                     sh_compare_op1);
9561       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9563       emit_insn (gen_seq (tmp));
9564       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9566       DONE;
9567     }
9569   if (sh_expand_t_scc (NE, operands[0]))
9570     DONE;
9571   if (! currently_expanding_to_rtl)
9572     FAIL;
9573   operands[1] = prepare_scc_operands (EQ);
9574   operands[2] = gen_reg_rtx (SImode);
9577 (define_expand "sunordered"
9578   [(set (match_operand:DI 0 "arith_reg_operand" "")
9579         (unordered:DI (match_dup 1) (match_dup 2)))]
9580   "TARGET_SHMEDIA_FPU"
9581   "
9583   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9584   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9587 ;; Use the same trick for FP sle / sge
9589 ;; Apart from the constant use and the T setting, this is like movt,
9590 ;; except that it uses the logically negated value of T, i.e.
9591 ;; operand[0] := T ? 0 : 1.
9592 (define_expand "movnegt"
9593   [(set (match_dup 2) (const_int -1))
9594    (parallel [(set (match_operand 0 "" "")
9595                    (neg:SI (plus:SI (match_dup 1)
9596                                     (match_dup 2))))
9597               (set (reg:SI T_REG)
9598                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9599                           (const_int 0)))])]
9600   "TARGET_SH1"
9601   "operands[2] = gen_reg_rtx (SImode);")
9603 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9604 ;; This prevents a regression that occurred when we switched from xor to
9605 ;; mov/neg for sne.
9607 (define_split
9608   [(set (match_operand:SI 0 "arith_reg_dest" "")
9609         (plus:SI (reg:SI T_REG)
9610                  (const_int -1)))]
9611   "TARGET_SH1"
9612   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9613    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9614   "")
9616 ;; -------------------------------------------------------------------------
9617 ;; Instructions to cope with inline literal tables
9618 ;; -------------------------------------------------------------------------
9620 ; 2 byte integer in line
9622 (define_insn "consttable_2"
9623  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9624                     (match_operand 1 "" "")]
9625                    UNSPECV_CONST2)]
9626  ""
9627  "*
9629   if (operands[1] != const0_rtx)
9630     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9631   return \"\";
9633  [(set_attr "length" "2")
9634  (set_attr "in_delay_slot" "no")])
9636 ; 4 byte integer in line
9638 (define_insn "consttable_4"
9639  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9640                     (match_operand 1 "" "")]
9641                    UNSPECV_CONST4)]
9642  ""
9643  "*
9645   if (operands[1] != const0_rtx)
9646     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9647   return \"\";
9649  [(set_attr "length" "4")
9650   (set_attr "in_delay_slot" "no")])
9652 ; 8 byte integer in line
9654 (define_insn "consttable_8"
9655  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9656                     (match_operand 1 "" "")]
9657                    UNSPECV_CONST8)]
9658  ""
9659  "*
9661   if (operands[1] != const0_rtx)
9662     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9663   return \"\";
9665  [(set_attr "length" "8")
9666   (set_attr "in_delay_slot" "no")])
9668 ; 4 byte floating point
9670 (define_insn "consttable_sf"
9671  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9672                     (match_operand 1 "" "")]
9673                    UNSPECV_CONST4)]
9674  ""
9675  "*
9677   if (operands[1] != const0_rtx)
9678     {
9679       REAL_VALUE_TYPE d;
9680       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9681       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9682     }
9683   return \"\";
9685  [(set_attr "length" "4")
9686   (set_attr "in_delay_slot" "no")])
9688 ; 8 byte floating point
9690 (define_insn "consttable_df"
9691  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9692                     (match_operand 1 "" "")]
9693                    UNSPECV_CONST8)]
9694  ""
9695  "*
9697   if (operands[1] != const0_rtx)
9698     {
9699       REAL_VALUE_TYPE d;
9700       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9701       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9702     }
9703   return \"\";
9705  [(set_attr "length" "8")
9706   (set_attr "in_delay_slot" "no")])
9708 ;; Alignment is needed for some constant tables; it may also be added for
9709 ;; Instructions at the start of loops, or after unconditional branches.
9710 ;; ??? We would get more accurate lengths if we did instruction
9711 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9712 ;; here is too conservative.
9714 ; align to a two byte boundary
9716 (define_expand "align_2"
9717  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9718  ""
9719  "")
9721 ; align to a four byte boundary
9722 ;; align_4 and align_log are instructions for the starts of loops, or
9723 ;; after unconditional branches, which may take up extra room.
9725 (define_expand "align_4"
9726  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9727  ""
9728  "")
9730 ; align to a cache line boundary
9732 (define_insn "align_log"
9733  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9734  ""
9735  ""
9736  [(set_attr "length" "0")
9737   (set_attr "in_delay_slot" "no")])
9739 ; emitted at the end of the literal table, used to emit the
9740 ; 32bit branch labels if needed.
9742 (define_insn "consttable_end"
9743   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9744   ""
9745   "* return output_jump_label_table ();"
9746   [(set_attr "in_delay_slot" "no")])
9748 ; emitted at the end of the window in the literal table.
9750 (define_insn "consttable_window_end"
9751   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9752   ""
9753   ""
9754   [(set_attr "length" "0")
9755    (set_attr "in_delay_slot" "no")])
9757 ;; -------------------------------------------------------------------------
9758 ;; Misc
9759 ;; -------------------------------------------------------------------------
9761 ;; String/block move insn.
9763 (define_expand "movmemsi"
9764   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9765                    (mem:BLK (match_operand:BLK 1 "" "")))
9766               (use (match_operand:SI 2 "nonmemory_operand" ""))
9767               (use (match_operand:SI 3 "immediate_operand" ""))
9768               (clobber (reg:SI PR_REG))
9769               (clobber (reg:SI R4_REG))
9770               (clobber (reg:SI R5_REG))
9771               (clobber (reg:SI R0_REG))])]
9772   "TARGET_SH1 && ! TARGET_SH5"
9773   "
9775   if(expand_block_move (operands))
9776      DONE;
9777   else FAIL;
9780 (define_insn "block_move_real"
9781   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9782                    (mem:BLK (reg:SI R5_REG)))
9783               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9784               (clobber (reg:SI PR_REG))
9785               (clobber (reg:SI R0_REG))])]
9786   "TARGET_SH1 && ! TARGET_HARD_SH4"
9787   "jsr  @%0%#"
9788   [(set_attr "type" "sfunc")
9789    (set_attr "needs_delay_slot" "yes")])
9791 (define_insn "block_lump_real"
9792   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9793                    (mem:BLK (reg:SI R5_REG)))
9794               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9795               (use (reg:SI R6_REG))
9796               (clobber (reg:SI PR_REG))
9797               (clobber (reg:SI T_REG))
9798               (clobber (reg:SI R4_REG))
9799               (clobber (reg:SI R5_REG))
9800               (clobber (reg:SI R6_REG))
9801               (clobber (reg:SI R0_REG))])]
9802   "TARGET_SH1 && ! TARGET_HARD_SH4"
9803   "jsr  @%0%#"
9804   [(set_attr "type" "sfunc")
9805    (set_attr "needs_delay_slot" "yes")])
9807 (define_insn "block_move_real_i4"
9808   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9809                    (mem:BLK (reg:SI R5_REG)))
9810               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9811               (clobber (reg:SI PR_REG))
9812               (clobber (reg:SI R0_REG))
9813               (clobber (reg:SI R1_REG))
9814               (clobber (reg:SI R2_REG))])]
9815   "TARGET_HARD_SH4"
9816   "jsr  @%0%#"
9817   [(set_attr "type" "sfunc")
9818    (set_attr "needs_delay_slot" "yes")])
9820 (define_insn "block_lump_real_i4"
9821   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9822                    (mem:BLK (reg:SI R5_REG)))
9823               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9824               (use (reg:SI R6_REG))
9825               (clobber (reg:SI PR_REG))
9826               (clobber (reg:SI T_REG))
9827               (clobber (reg:SI R4_REG))
9828               (clobber (reg:SI R5_REG))
9829               (clobber (reg:SI R6_REG))
9830               (clobber (reg:SI R0_REG))
9831               (clobber (reg:SI R1_REG))
9832               (clobber (reg:SI R2_REG))
9833               (clobber (reg:SI R3_REG))])]
9834   "TARGET_HARD_SH4"
9835   "jsr  @%0%#"
9836   [(set_attr "type" "sfunc")
9837    (set_attr "needs_delay_slot" "yes")])
9839 ;; -------------------------------------------------------------------------
9840 ;; Floating point instructions.
9841 ;; -------------------------------------------------------------------------
9843 ;; ??? All patterns should have a type attribute.
9845 (define_expand "movpsi"
9846   [(set (match_operand:PSI 0 "register_operand" "")
9847         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9848   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9849   "")
9851 ;; The c / m alternative is a fake to guide reload to load directly into
9852 ;; fpscr, since reload doesn't know how to use post-increment.
9853 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9854 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9855 ;; predicate after reload.
9856 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9857 ;; like a mac -> gpr move.
9858 (define_insn "fpu_switch"
9859   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9860         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9861   "TARGET_SH2E
9862    && (! reload_completed
9863        || true_regnum (operands[0]) != FPSCR_REG
9864        || GET_CODE (operands[1]) != MEM
9865        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9866   "@
9867         ! precision stays the same
9868         lds.l   %1,fpscr
9869         mov.l   %1,%0
9870         #
9871         lds     %1,fpscr
9872         mov     %1,%0
9873         mov.l   %1,%0
9874         sts     fpscr,%0
9875         sts.l   fpscr,%0"
9876   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9877    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9879 (define_peephole2
9880   [(set (reg:PSI FPSCR_REG)
9881         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9882   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9883   [(const_int 0)]
9885   rtx fpscr, mem, new_insn;
9887   fpscr = SET_DEST (PATTERN (curr_insn));
9888   mem = SET_SRC (PATTERN (curr_insn));
9889   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9891   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9892   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9893   DONE;
9896 (define_split
9897   [(set (reg:PSI FPSCR_REG)
9898         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9899   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9900    && (flag_peephole2 ? flow2_completed : reload_completed)"
9901   [(const_int 0)]
9903   rtx fpscr, mem, new_insn;
9905   fpscr = SET_DEST (PATTERN (curr_insn));
9906   mem = SET_SRC (PATTERN (curr_insn));
9907   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9909   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9910   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9912   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9913     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9914   DONE;
9917 ;; ??? This uses the fp unit, but has no type indicating that.
9918 ;; If we did that, this would either give a bogus latency or introduce
9919 ;; a bogus FIFO constraint.
9920 ;; Since this insn is currently only used for prologues/epilogues,
9921 ;; it is probably best to claim no function unit, which matches the
9922 ;; current setting.
9923 (define_insn "toggle_sz"
9924   [(set (reg:PSI FPSCR_REG)
9925         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9926   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9927   "fschg"
9928   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9930 ;; There's no way we can use it today, since optimize mode switching
9931 ;; doesn't enable us to know from which mode we're switching to the
9932 ;; mode it requests, to tell whether we can use a relative mode switch
9933 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9934 ;; memory).
9935 (define_insn "toggle_pr"
9936   [(set (reg:PSI FPSCR_REG)
9937         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9938   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9939   "fpchg"
9940   [(set_attr "type" "fp")])
9942 (define_expand "addsf3"
9943   [(set (match_operand:SF 0 "arith_reg_operand" "")
9944         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9945                  (match_operand:SF 2 "arith_reg_operand" "")))]
9946   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9947   "
9949   if (TARGET_SH2E)
9950     {
9951       expand_sf_binop (&gen_addsf3_i, operands);
9952       DONE;
9953     }
9956 (define_insn "*addsf3_media"
9957   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9958         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9959                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9960   "TARGET_SHMEDIA_FPU"
9961   "fadd.s       %1, %2, %0"
9962   [(set_attr "type" "fparith_media")])
9964 (define_insn_and_split "unary_sf_op"
9965   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9966         (vec_select:V2SF
9967          (vec_concat:V2SF
9968           (vec_select:SF
9969            (match_dup 0)
9970            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9971           (match_operator:SF 2 "unary_float_operator"
9972             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9973                             (parallel [(match_operand 4
9974                                         "const_int_operand" "n")]))]))
9975          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9976   "TARGET_SHMEDIA_FPU"
9977   "#"
9978   "TARGET_SHMEDIA_FPU && reload_completed"
9979   [(set (match_dup 5) (match_dup 6))]
9980   "
9982   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9983   rtx op1 = gen_rtx_REG (SFmode,
9984                          (true_regnum (operands[1])
9985                           + (INTVAL (operands[4]) ^ endian)));
9987   operands[7] = gen_rtx_REG (SFmode,
9988                              (true_regnum (operands[0])
9989                               + (INTVAL (operands[3]) ^ endian)));
9990   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9992   [(set_attr "type" "fparith_media")])
9994 (define_insn_and_split "binary_sf_op"
9995   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9996         (vec_select:V2SF
9997          (vec_concat:V2SF
9998           (vec_select:SF
9999            (match_dup 0)
10000            (parallel [(match_operand 7 "const_int_operand" "n")]))
10001           (match_operator:SF 3 "binary_float_operator"
10002             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10003                             (parallel [(match_operand 5
10004                                         "const_int_operand" "n")]))
10005              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10006                             (parallel [(match_operand 6
10007                                         "const_int_operand" "n")]))]))
10008          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
10009   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
10010   "#"
10011   "&& reload_completed"
10012   [(set (match_dup 8) (match_dup 9))]
10013   "
10015   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10016   rtx op1 = gen_rtx_REG (SFmode,
10017                          (true_regnum (operands[1])
10018                           + (INTVAL (operands[5]) ^ endian)));
10019   rtx op2 = gen_rtx_REG (SFmode,
10020                          (true_regnum (operands[2])
10021                           + (INTVAL (operands[6]) ^ endian)));
10023   operands[8] = gen_rtx_REG (SFmode,
10024                              (true_regnum (operands[0])
10025                               + (INTVAL (operands[4]) ^ endian)));
10026   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10028   [(set_attr "type" "fparith_media")])
10030 (define_insn "addsf3_i"
10031   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10032         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10033                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10034    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10035   "TARGET_SH2E"
10036   "fadd %2,%0"
10037   [(set_attr "type" "fp")
10038    (set_attr "fp_mode" "single")])
10040 (define_expand "subsf3"
10041   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10042         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10043                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10044   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10045   "
10047   if (TARGET_SH2E)
10048     {
10049       expand_sf_binop (&gen_subsf3_i, operands);
10050       DONE;
10051     }
10054 (define_insn "*subsf3_media"
10055   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10056         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10057                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10058   "TARGET_SHMEDIA_FPU"
10059   "fsub.s       %1, %2, %0"
10060   [(set_attr "type" "fparith_media")])
10062 (define_insn "subsf3_i"
10063   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10064         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10065                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10066    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10067   "TARGET_SH2E"
10068   "fsub %2,%0"
10069   [(set_attr "type" "fp")
10070    (set_attr "fp_mode" "single")])
10072 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10073 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
10074 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
10075 ;; SH3E, we use a separate insn for SH3E mulsf3.
10077 (define_expand "mulsf3"
10078   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10079         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10080                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10081   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10082   "
10084   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10085     expand_sf_binop (&gen_mulsf3_i4, operands);
10086   else if (TARGET_SH2E)
10087     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10088   if (! TARGET_SHMEDIA)
10089     DONE;
10092 (define_insn "*mulsf3_media"
10093   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10094         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10095                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10096   "TARGET_SHMEDIA_FPU"
10097   "fmul.s       %1, %2, %0"
10098   [(set_attr "type" "fparith_media")])
10100 (define_insn "mulsf3_i4"
10101   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10102         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10103                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10104    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10105   "TARGET_SH2E"
10106   "fmul %2,%0"
10107   [(set_attr "type" "fp")
10108    (set_attr "fp_mode" "single")])
10110 (define_insn "mulsf3_ie"
10111   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10112         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10113                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10114   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10115   "fmul %2,%0"
10116   [(set_attr "type" "fp")])
10118 (define_insn "mac_media"
10119   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10120         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10121                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10122                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10123   "TARGET_SHMEDIA_FPU"
10124   "fmac.s %1, %2, %0"
10125   [(set_attr "type" "fparith_media")])
10127 (define_insn "*macsf3"
10128   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10129         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10130                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10131                  (match_operand:SF 3 "arith_reg_operand" "0")))
10132    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10133   "TARGET_SH2E && ! TARGET_SH4"
10134   "fmac fr0,%2,%0"
10135   [(set_attr "type" "fp")
10136    (set_attr "fp_mode" "single")])
10138 (define_expand "divsf3"
10139   [(set (match_operand:SF 0 "arith_reg_operand" "")
10140         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10141                 (match_operand:SF 2 "arith_reg_operand" "")))]
10142   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10143   "
10145   if (TARGET_SH2E)
10146     {
10147       expand_sf_binop (&gen_divsf3_i, operands);
10148       DONE;
10149     }
10152 (define_insn "*divsf3_media"
10153   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10154         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10155                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10156   "TARGET_SHMEDIA_FPU"
10157   "fdiv.s       %1, %2, %0"
10158   [(set_attr "type" "fdiv_media")])
10160 (define_insn "divsf3_i"
10161   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10162         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10163                  (match_operand:SF 2 "arith_reg_operand" "f")))
10164    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10165   "TARGET_SH2E"
10166   "fdiv %2,%0"
10167   [(set_attr "type" "fdiv")
10168    (set_attr "fp_mode" "single")])
10170 (define_insn "floatdisf2"
10171   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10172         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10173   "TARGET_SHMEDIA_FPU"
10174   "float.qs %1, %0"
10175   [(set_attr "type" "fpconv_media")])
10177 (define_expand "floatsisf2"
10178   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10179         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10180   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10181   "
10183   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10184     {
10185       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10186       DONE;
10187     }
10190 (define_insn "*floatsisf2_media"
10191   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10192         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10193   "TARGET_SHMEDIA_FPU"
10194   "float.ls     %1, %0"
10195   [(set_attr "type" "fpconv_media")])
10197 (define_insn "floatsisf2_i4"
10198   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10199         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10200    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10201   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10202   "float        %1,%0"
10203   [(set_attr "type" "fp")
10204    (set_attr "fp_mode" "single")])
10206 (define_insn "*floatsisf2_ie"
10207   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10208         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10209   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10210   "float        %1,%0"
10211   [(set_attr "type" "fp")])
10213 (define_insn "fix_truncsfdi2"
10214   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10215         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10216   "TARGET_SHMEDIA_FPU"
10217   "ftrc.sq %1, %0"
10218   [(set_attr "type" "fpconv_media")])
10220 (define_expand "fix_truncsfsi2"
10221   [(set (match_operand:SI 0 "fpul_operand" "=y")
10222         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10223   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10224   "
10226   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10227     {
10228       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10229       DONE;
10230     }
10233 (define_insn "*fix_truncsfsi2_media"
10234   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10235         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10236   "TARGET_SHMEDIA_FPU"
10237   "ftrc.sl      %1, %0"
10238   [(set_attr "type" "fpconv_media")])
10240 (define_insn "fix_truncsfsi2_i4"
10241   [(set (match_operand:SI 0 "fpul_operand" "=y")
10242         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10243    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10244   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10245   "ftrc %1,%0"
10246   [(set_attr "type" "ftrc_s")
10247    (set_attr "fp_mode" "single")])
10249 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10250 ;; fix_truncsfsi2_i4.
10251 ;; (define_insn "fix_truncsfsi2_i4_2"
10252 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10253 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10254 ;;   (use (reg:PSI FPSCR_REG))
10255 ;;   (clobber (reg:SI FPUL_REG))]
10256 ;;  "TARGET_SH4"
10257 ;;  "#"
10258 ;;  [(set_attr "length" "4")
10259 ;;   (set_attr "fp_mode" "single")])
10261 ;;(define_split
10262 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10263 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10264 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10265 ;;   (clobber (reg:SI FPUL_REG))]
10266 ;;  "TARGET_SH4"
10267 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10268 ;;            (use (match_dup 2))])
10269 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10271 (define_insn "*fixsfsi"
10272   [(set (match_operand:SI 0 "fpul_operand" "=y")
10273         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10274   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10275   "ftrc %1,%0"
10276   [(set_attr "type" "fp")])
10278 (define_insn "cmpgtsf_t"
10279   [(set (reg:SI T_REG)
10280         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10281                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10282   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10283   "fcmp/gt      %1,%0"
10284   [(set_attr "type" "fp")
10285    (set_attr "fp_mode" "single")])
10287 (define_insn "cmpeqsf_t"
10288   [(set (reg:SI T_REG)
10289         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10290                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10291   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10292   "fcmp/eq      %1,%0"
10293   [(set_attr "type" "fp")
10294    (set_attr "fp_mode" "single")])
10296 (define_insn "ieee_ccmpeqsf_t"
10297   [(set (reg:SI T_REG)
10298         (ior:SI (reg:SI T_REG)
10299                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10300                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10301   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10302   "* return output_ieee_ccmpeq (insn, operands);"
10303   [(set_attr "length" "4")])
10306 (define_insn "cmpgtsf_t_i4"
10307   [(set (reg:SI T_REG)
10308         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10309                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10310    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10311   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10312   "fcmp/gt      %1,%0"
10313   [(set_attr "type" "fp")
10314    (set_attr "fp_mode" "single")])
10316 (define_insn "cmpeqsf_t_i4"
10317   [(set (reg:SI T_REG)
10318         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10319                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10320    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10321   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10322   "fcmp/eq      %1,%0"
10323   [(set_attr "type" "fp")
10324    (set_attr "fp_mode" "single")])
10326 (define_insn "*ieee_ccmpeqsf_t_4"
10327   [(set (reg:SI T_REG)
10328         (ior:SI (reg:SI T_REG)
10329                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10330                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10331    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10332   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10333   "* return output_ieee_ccmpeq (insn, operands);"
10334   [(set_attr "length" "4")
10335    (set_attr "fp_mode" "single")])
10337 (define_insn "cmpeqsf_media"
10338   [(set (match_operand:DI 0 "register_operand" "=r")
10339         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10340                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10341   "TARGET_SHMEDIA_FPU"
10342   "fcmpeq.s     %1, %2, %0"
10343   [(set_attr "type" "fcmp_media")])
10345 (define_insn "cmpsieqsf_media"
10346   [(set (match_operand:SI 0 "register_operand" "=r")
10347         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10348                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10349   "TARGET_SHMEDIA_FPU"
10350   "fcmpeq.s     %1, %2, %0"
10351   [(set_attr "type" "fcmp_media")])
10353 (define_insn "cmpgtsf_media"
10354   [(set (match_operand:DI 0 "register_operand" "=r")
10355         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10356                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10357   "TARGET_SHMEDIA_FPU"
10358   "fcmpgt.s     %1, %2, %0"
10359   [(set_attr "type" "fcmp_media")])
10361 (define_insn "cmpgesf_media"
10362   [(set (match_operand:DI 0 "register_operand" "=r")
10363         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10364                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10365   "TARGET_SHMEDIA_FPU"
10366   "fcmpge.s     %1, %2, %0"
10367   [(set_attr "type" "fcmp_media")])
10369 (define_insn "cmpunsf_media"
10370   [(set (match_operand:DI 0 "register_operand" "=r")
10371         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10372                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10373   "TARGET_SHMEDIA_FPU"
10374   "fcmpun.s     %1, %2, %0"
10375   [(set_attr "type" "fcmp_media")])
10377 (define_expand "cmpsf"
10378   [(set (reg:SI T_REG)
10379         (compare (match_operand:SF 0 "arith_operand" "")
10380                  (match_operand:SF 1 "arith_operand" "")))]
10381   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10382   "
10384   sh_compare_op0 = operands[0];
10385   sh_compare_op1 = operands[1];
10386   DONE;
10389 (define_expand "negsf2"
10390   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10391         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10392   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10393   "
10395   if (TARGET_SH2E)
10396     {
10397       expand_sf_unop (&gen_negsf2_i, operands);
10398       DONE;
10399     }
10402 (define_insn "*negsf2_media"
10403   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10404         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10405   "TARGET_SHMEDIA_FPU"
10406   "fneg.s       %1, %0"
10407   [(set_attr "type" "fmove_media")])
10409 (define_insn "negsf2_i"
10410   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10411         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10412    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10413   "TARGET_SH2E"
10414   "fneg %0"
10415   [(set_attr "type" "fmove")
10416    (set_attr "fp_mode" "single")])
10418 (define_expand "sqrtsf2"
10419   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10420         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10421   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10422   "
10424   if (TARGET_SH3E)
10425     {
10426       expand_sf_unop (&gen_sqrtsf2_i, operands);
10427       DONE;
10428     }
10431 (define_insn "*sqrtsf2_media"
10432   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10433         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10434   "TARGET_SHMEDIA_FPU"
10435   "fsqrt.s      %1, %0"
10436   [(set_attr "type" "fdiv_media")])
10438 (define_insn "sqrtsf2_i"
10439   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10440         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10441    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10442   "TARGET_SH3E"
10443   "fsqrt        %0"
10444   [(set_attr "type" "fdiv")
10445    (set_attr "fp_mode" "single")])
10447 (define_insn "rsqrtsf2"
10448   [(set (match_operand:SF 0 "register_operand" "=f")
10449         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10450                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10451    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10452   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10453    && operands[1] == CONST1_RTX (SFmode)"
10454   "fsrra        %0"
10455   [(set_attr "type" "fsrra")
10456    (set_attr "fp_mode" "single")])
10458 (define_insn "fsca"
10459   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10460         (vec_concat:V2SF
10461          (unspec:SF [(mult:SF
10462                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10463                       (match_operand:SF 2 "immediate_operand" "i"))
10464                     ] UNSPEC_FSINA)
10465          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10466                     ] UNSPEC_FCOSA)))
10467    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10468   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10469    && operands[2] == sh_fsca_int2sf ()"
10470   "fsca fpul,%d0"
10471   [(set_attr "type" "fsca")
10472    (set_attr "fp_mode" "single")])
10474 (define_expand "sinsf2"
10475   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10476         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10477                    UNSPEC_FSINA))]
10478   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10479   "
10481   rtx scaled = gen_reg_rtx (SFmode);
10482   rtx truncated = gen_reg_rtx (SImode);
10483   rtx fsca = gen_reg_rtx (V2SFmode);
10484   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10486   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10487   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10488   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10489                           get_fpscr_rtx ()));
10490   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10491   DONE;
10494 (define_expand "cossf2"
10495   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10496         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10497                    UNSPEC_FCOSA))]
10498   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10499   "
10501   rtx scaled = gen_reg_rtx (SFmode);
10502   rtx truncated = gen_reg_rtx (SImode);
10503   rtx fsca = gen_reg_rtx (V2SFmode);
10504   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10506   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10507   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10508   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10509                           get_fpscr_rtx ()));
10510   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10511   DONE;
10514 (define_expand "sindf2"
10515   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10516         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10517                    UNSPEC_FSINA))]
10518   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10519   "
10521   rtx scaled = gen_reg_rtx (DFmode);
10522   rtx truncated = gen_reg_rtx (SImode);
10523   rtx fsca = gen_reg_rtx (V2SFmode);
10524   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10525   rtx sfresult = gen_reg_rtx (SFmode);
10527   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10528   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10529   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10530                           get_fpscr_rtx ()));
10531   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10532   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10533   DONE;
10536 (define_expand "cosdf2"
10537   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10538         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10539                    UNSPEC_FCOSA))]
10540   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10541   "
10543   rtx scaled = gen_reg_rtx (DFmode);
10544   rtx truncated = gen_reg_rtx (SImode);
10545   rtx fsca = gen_reg_rtx (V2SFmode);
10546   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10547   rtx sfresult = gen_reg_rtx (SFmode);
10549   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10550   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10551   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10552                           get_fpscr_rtx ()));
10553   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10554   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10555   DONE;
10558 (define_expand "abssf2"
10559   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10560         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10561   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10562   "
10564   if (TARGET_SH2E)
10565     {
10566       expand_sf_unop (&gen_abssf2_i, operands);
10567       DONE;
10568     }
10571 (define_insn "*abssf2_media"
10572   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10573         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10574   "TARGET_SHMEDIA_FPU"
10575   "fabs.s       %1, %0"
10576   [(set_attr "type" "fmove_media")])
10578 (define_insn "abssf2_i"
10579   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10580         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10581    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10582   "TARGET_SH2E"
10583   "fabs %0"
10584   [(set_attr "type" "fmove")
10585    (set_attr "fp_mode" "single")])
10587 (define_expand "adddf3"
10588   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10589         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10590                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10591   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10592   "
10594   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10595     {
10596       expand_df_binop (&gen_adddf3_i, operands);
10597       DONE;
10598     }
10601 (define_insn "*adddf3_media"
10602   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10603         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10604                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10605   "TARGET_SHMEDIA_FPU"
10606   "fadd.d       %1, %2, %0"
10607   [(set_attr "type" "dfparith_media")])
10609 (define_insn "adddf3_i"
10610   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10611         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10612                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10613    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10614   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10615   "fadd %2,%0"
10616   [(set_attr "type" "dfp_arith")
10617    (set_attr "fp_mode" "double")])
10619 (define_expand "subdf3"
10620   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10621         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10622                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10623   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10624   "
10626   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10627     {
10628       expand_df_binop (&gen_subdf3_i, operands);
10629       DONE;
10630     }
10633 (define_insn "*subdf3_media"
10634   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10635         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10636                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10637   "TARGET_SHMEDIA_FPU"
10638   "fsub.d       %1, %2, %0"
10639   [(set_attr "type" "dfparith_media")])
10641 (define_insn "subdf3_i"
10642   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10643         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10644                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10645    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10646   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10647   "fsub %2,%0"
10648   [(set_attr "type" "dfp_arith")
10649    (set_attr "fp_mode" "double")])
10651 (define_expand "muldf3"
10652   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10653         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10654                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10655   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10656   "
10658   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10659     {
10660       expand_df_binop (&gen_muldf3_i, operands);
10661       DONE;
10662     }
10665 (define_insn "*muldf3_media"
10666   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10667         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10668                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10669   "TARGET_SHMEDIA_FPU"
10670   "fmul.d       %1, %2, %0"
10671   [(set_attr "type" "dfmul_media")])
10673 (define_insn "muldf3_i"
10674   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10675         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10676                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10677    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10678   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10679   "fmul %2,%0"
10680   [(set_attr "type" "dfp_arith")
10681    (set_attr "fp_mode" "double")])
10683 (define_expand "divdf3"
10684   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10685         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10686                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10687   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10688   "
10690   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10691     {
10692       expand_df_binop (&gen_divdf3_i, operands);
10693       DONE;
10694     }
10697 (define_insn "*divdf3_media"
10698   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10699         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10700                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10701   "TARGET_SHMEDIA_FPU"
10702   "fdiv.d       %1, %2, %0"
10703   [(set_attr "type" "dfdiv_media")])
10705 (define_insn "divdf3_i"
10706   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10707         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10708                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10709    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10710   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10711   "fdiv %2,%0"
10712   [(set_attr "type" "dfdiv")
10713    (set_attr "fp_mode" "double")])
10715 (define_insn "floatdidf2"
10716   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10717         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10718   "TARGET_SHMEDIA_FPU"
10719   "float.qd     %1, %0"
10720   [(set_attr "type" "dfpconv_media")])
10722 (define_expand "floatsidf2"
10723   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10724         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10725   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10726   "
10728   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10729     {
10730       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10731                                       get_fpscr_rtx ()));
10732       DONE;
10733     }
10736 (define_insn "*floatsidf2_media"
10737   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10738         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10739   "TARGET_SHMEDIA_FPU"
10740   "float.ld     %1, %0"
10741   [(set_attr "type" "dfpconv_media")])
10743 (define_insn "floatsidf2_i"
10744   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10745         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10746    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10747   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10748   "float        %1,%0"
10749   [(set_attr "type" "dfp_conv")
10750    (set_attr "fp_mode" "double")])
10752 (define_insn "fix_truncdfdi2"
10753   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10754         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10755   "TARGET_SHMEDIA_FPU"
10756   "ftrc.dq      %1, %0"
10757   [(set_attr "type" "dfpconv_media")])
10759 (define_expand "fix_truncdfsi2"
10760   [(set (match_operand:SI 0 "fpul_operand" "")
10761         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10762   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10763   "
10765   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10766     {
10767       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10768                                           get_fpscr_rtx ()));
10769       DONE;
10770     }
10773 (define_insn "*fix_truncdfsi2_media"
10774   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10775         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10776   "TARGET_SHMEDIA_FPU"
10777   "ftrc.dl      %1, %0"
10778   [(set_attr "type" "dfpconv_media")])
10780 (define_insn "fix_truncdfsi2_i"
10781   [(set (match_operand:SI 0 "fpul_operand" "=y")
10782         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10783    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10784   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10785   "ftrc %1,%0"
10786   [(set_attr "type" "dfp_conv")
10787    (set_attr "dfp_comp" "no")
10788    (set_attr "fp_mode" "double")])
10790 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10791 ;; fix_truncdfsi2_i.
10792 ;; (define_insn "fix_truncdfsi2_i4"
10793 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10794 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10795 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10796 ;;    (clobber (reg:SI FPUL_REG))]
10797 ;;   "TARGET_SH4"
10798 ;;   "#"
10799 ;;   [(set_attr "length" "4")
10800 ;;    (set_attr "fp_mode" "double")])
10802 ;; (define_split
10803 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10804 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10805 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10806 ;;    (clobber (reg:SI FPUL_REG))]
10807 ;;   "TARGET_SH4"
10808 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10809 ;;            (use (match_dup 2))])
10810 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10812 (define_insn "cmpgtdf_t"
10813   [(set (reg:SI T_REG)
10814         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10815                (match_operand:DF 1 "arith_reg_operand" "f")))
10816    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10817   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10818   "fcmp/gt      %1,%0"
10819   [(set_attr "type" "dfp_cmp")
10820    (set_attr "fp_mode" "double")])
10822 (define_insn "cmpeqdf_t"
10823   [(set (reg:SI T_REG)
10824         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10825                (match_operand:DF 1 "arith_reg_operand" "f")))
10826    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10827   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10828   "fcmp/eq      %1,%0"
10829   [(set_attr "type" "dfp_cmp")
10830    (set_attr "fp_mode" "double")])
10832 (define_insn "*ieee_ccmpeqdf_t"
10833   [(set (reg:SI T_REG)
10834         (ior:SI (reg:SI T_REG)
10835                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10836                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10837    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10838   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10839   "* return output_ieee_ccmpeq (insn, operands);"
10840   [(set_attr "length" "4")
10841    (set_attr "fp_mode" "double")])
10843 (define_insn "cmpeqdf_media"
10844   [(set (match_operand:DI 0 "register_operand" "=r")
10845         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10846                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10847   "TARGET_SHMEDIA_FPU"
10848   "fcmpeq.d     %1,%2,%0"
10849   [(set_attr "type" "fcmp_media")])
10851 (define_insn "cmpsieqdf_media"
10852   [(set (match_operand:SI 0 "register_operand" "=r")
10853         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10854                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10855   "TARGET_SHMEDIA_FPU"
10856   "fcmpeq.d     %1,%2,%0"
10857   [(set_attr "type" "fcmp_media")])
10859 (define_insn "cmpgtdf_media"
10860   [(set (match_operand:DI 0 "register_operand" "=r")
10861         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10862                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10863   "TARGET_SHMEDIA_FPU"
10864   "fcmpgt.d     %1,%2,%0"
10865   [(set_attr "type" "fcmp_media")])
10867 (define_insn "cmpgedf_media"
10868   [(set (match_operand:DI 0 "register_operand" "=r")
10869         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10870                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10871   "TARGET_SHMEDIA_FPU"
10872   "fcmpge.d     %1,%2,%0"
10873   [(set_attr "type" "fcmp_media")])
10875 (define_insn "cmpundf_media"
10876   [(set (match_operand:DI 0 "register_operand" "=r")
10877         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10878                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10879   "TARGET_SHMEDIA_FPU"
10880   "fcmpun.d     %1,%2,%0"
10881   [(set_attr "type" "fcmp_media")])
10883 (define_expand "cmpdf"
10884   [(set (reg:SI T_REG)
10885         (compare (match_operand:DF 0 "arith_operand" "")
10886                  (match_operand:DF 1 "arith_operand" "")))]
10887   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10888   "
10890   sh_compare_op0 = operands[0];
10891   sh_compare_op1 = operands[1];
10892   DONE;
10895 (define_expand "negdf2"
10896   [(set (match_operand:DF 0 "arith_reg_operand" "")
10897         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10898   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10899   "
10901   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10902     {
10903       expand_df_unop (&gen_negdf2_i, operands);
10904       DONE;
10905     }
10908 (define_insn "*negdf2_media"
10909   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10910         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10911   "TARGET_SHMEDIA_FPU"
10912   "fneg.d       %1, %0"
10913   [(set_attr "type" "fmove_media")])
10915 (define_insn "negdf2_i"
10916   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10917         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10918    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10919   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10920   "fneg %0"
10921   [(set_attr "type" "fmove")
10922    (set_attr "fp_mode" "double")])
10924 (define_expand "sqrtdf2"
10925   [(set (match_operand:DF 0 "arith_reg_operand" "")
10926         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10927   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10928   "
10930   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10931     {
10932       expand_df_unop (&gen_sqrtdf2_i, operands);
10933       DONE;
10934     }
10937 (define_insn "*sqrtdf2_media"
10938   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10939         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10940   "TARGET_SHMEDIA_FPU"
10941   "fsqrt.d      %1, %0"
10942   [(set_attr "type" "dfdiv_media")])
10944 (define_insn "sqrtdf2_i"
10945   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10946         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10947    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10948   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10949   "fsqrt        %0"
10950   [(set_attr "type" "dfdiv")
10951    (set_attr "fp_mode" "double")])
10953 (define_expand "absdf2"
10954   [(set (match_operand:DF 0 "arith_reg_operand" "")
10955         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10956   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10957   "
10959   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10960     {
10961       expand_df_unop (&gen_absdf2_i, operands);
10962       DONE;
10963     }
10966 (define_insn "*absdf2_media"
10967   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10968         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10969   "TARGET_SHMEDIA_FPU"
10970   "fabs.d       %1, %0"
10971   [(set_attr "type" "fmove_media")])
10973 (define_insn "absdf2_i"
10974   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10975         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10976    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10977   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10978   "fabs %0"
10979   [(set_attr "type" "fmove")
10980    (set_attr "fp_mode" "double")])
10982 (define_expand "extendsfdf2"
10983   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10984         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10985   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10986   "
10988   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10989     {
10990       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10991                                         get_fpscr_rtx ()));
10992       DONE;
10993     }
10996 (define_insn "*extendsfdf2_media"
10997   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10998         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10999   "TARGET_SHMEDIA_FPU"
11000   "fcnv.sd      %1, %0"
11001   [(set_attr "type" "dfpconv_media")])
11003 (define_insn "extendsfdf2_i4"
11004   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11005         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11006    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11007   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11008   "fcnvsd  %1,%0"
11009   [(set_attr "type" "fp")
11010    (set_attr "fp_mode" "double")])
11012 (define_expand "truncdfsf2"
11013   [(set (match_operand:SF 0 "fpul_operand" "")
11014         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11015   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11016   "
11018   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11019     {
11020       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11021                                        get_fpscr_rtx ()));
11022       DONE;
11023     }
11026 (define_insn "*truncdfsf2_media"
11027   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11028         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11029   "TARGET_SHMEDIA_FPU"
11030   "fcnv.ds      %1, %0"
11031   [(set_attr "type" "dfpconv_media")])
11033 (define_insn "truncdfsf2_i4"
11034   [(set (match_operand:SF 0 "fpul_operand" "=y")
11035         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11036    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11037   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11038   "fcnvds  %1,%0"
11039   [(set_attr "type" "fp")
11040    (set_attr "fp_mode" "double")])
11042 ;; Bit field extract patterns.  These give better code for packed bitfields,
11043 ;; because they allow auto-increment addresses to be generated.
11045 (define_expand "insv"
11046   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11047                          (match_operand:SI 1 "immediate_operand" "")
11048                          (match_operand:SI 2 "immediate_operand" ""))
11049         (match_operand:SI 3 "general_operand" ""))]
11050   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11051   "
11053   rtx addr_target, orig_address, shift_reg, qi_val;
11054   HOST_WIDE_INT bitsize, size, v = 0;
11055   rtx x = operands[3];
11057   /* ??? expmed doesn't care for non-register predicates.  */
11058   if (! memory_operand (operands[0], VOIDmode)
11059       || ! immediate_operand (operands[1], VOIDmode)
11060       || ! immediate_operand (operands[2], VOIDmode)
11061       || ! general_operand (x, VOIDmode))
11062     FAIL;
11063   /* If this isn't a 16 / 24 / 32 bit field, or if
11064      it doesn't start on a byte boundary, then fail.  */
11065   bitsize = INTVAL (operands[1]);
11066   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11067       || (INTVAL (operands[2]) % 8) != 0)
11068     FAIL;
11070   size = bitsize / 8;
11071   orig_address = XEXP (operands[0], 0);
11072   shift_reg = gen_reg_rtx (SImode);
11073   if (GET_CODE (x) == CONST_INT)
11074     {
11075       v = INTVAL (x);
11076       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11077     }
11078   else
11079     {
11080       emit_insn (gen_movsi (shift_reg, operands[3]));
11081       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11082     }
11083   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11085   operands[0] = replace_equiv_address (operands[0], addr_target);
11086   emit_insn (gen_movqi (operands[0], qi_val));
11088   while (size -= 1)
11089     {
11090       if (GET_CODE (x) == CONST_INT)
11091         qi_val
11092           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11093       else
11094         {
11095           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11096           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11097         }
11098       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11099       emit_insn (gen_movqi (operands[0], qi_val));
11100     }
11102   DONE;
11105 (define_insn "movua"
11106   [(set (match_operand:SI 0 "register_operand" "=z")
11107         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11108                          (const_int 32) (const_int 0)))]
11109   "TARGET_SH4A_ARCH"
11110   "movua.l      %1,%0"
11111   [(set_attr "type" "movua")])
11113 ;; We shouldn't need this, but cse replaces increments with references
11114 ;; to other regs before flow has a chance to create post_inc
11115 ;; addressing modes, and only postreload's cse_move2add brings the
11116 ;; increments back to a usable form.
11117 (define_peephole2
11118   [(set (match_operand:SI 0 "register_operand" "")
11119         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11120                          (const_int 32) (const_int 0)))
11121    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11122   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11123   [(set (match_operand:SI 0 "register_operand" "")
11124         (sign_extract:SI (mem:SI (post_inc:SI
11125                                   (match_operand:SI 1 "register_operand" "")))
11126                          (const_int 32) (const_int 0)))]
11127   "")
11129 (define_expand "extv"
11130   [(set (match_operand:SI 0 "register_operand" "")
11131         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11132                          (match_operand 2 "const_int_operand" "")
11133                          (match_operand 3 "const_int_operand" "")))]
11134   "TARGET_SH4A_ARCH"
11136   if (TARGET_SH4A_ARCH
11137       && INTVAL (operands[2]) == 32
11138       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11139       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11140     {
11141       emit_insn (gen_movua (operands[0],
11142                             adjust_address (operands[1], SImode, 0)));
11143       DONE;
11144     }
11146   FAIL;
11149 (define_expand "extzv"
11150   [(set (match_operand:SI 0 "register_operand" "")
11151         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11152                          (match_operand 2 "const_int_operand" "")
11153                          (match_operand 3 "const_int_operand" "")))]
11154   "TARGET_SH4A_ARCH"
11156   if (TARGET_SH4A_ARCH
11157       && INTVAL (operands[2]) == 32
11158       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11159       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11160     {
11161       emit_insn (gen_movua (operands[0],
11162                             adjust_address (operands[1], SImode, 0)));
11163       DONE;
11164     }
11166   FAIL;
11170 ;; -------------------------------------------------------------------------
11171 ;; Peepholes
11172 ;; -------------------------------------------------------------------------
11174 ;; This matches cases where a stack pointer increment at the start of the
11175 ;; epilogue combines with a stack slot read loading the return value.
11177 (define_peephole
11178   [(set (match_operand:SI 0 "arith_reg_operand" "")
11179         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11180    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11181   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11182   "mov.l        @%1+,%0")
11184 ;; See the comment on the dt combiner pattern above.
11186 (define_peephole
11187   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11188         (plus:SI (match_dup 0)
11189                  (const_int -1)))
11190    (set (reg:SI T_REG)
11191         (eq:SI (match_dup 0)
11192                (const_int 0)))]
11193   "TARGET_SH2"
11194   "dt   %0")
11196 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11197 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11198 ;; reload when the constant is too large for a reg+offset address.
11200 ;; ??? We would get much better code if this was done in reload.  This would
11201 ;; require modifying find_reloads_address to recognize that if the constant
11202 ;; is out-of-range for an immediate add, then we get better code by reloading
11203 ;; the constant into a register than by reloading the sum into a register,
11204 ;; since the former is one instruction shorter if the address does not need
11205 ;; to be offsettable.  Unfortunately this does not work, because there is
11206 ;; only one register, r0, that can be used as an index register.  This register
11207 ;; is also the function return value register.  So, if we try to force reload
11208 ;; to use double-reg addresses, then we end up with some instructions that
11209 ;; need to use r0 twice.  The only way to fix this is to change the calling
11210 ;; convention so that r0 is not used to return values.
11212 (define_peephole
11213   [(set (match_operand:SI 0 "register_operand" "=r")
11214         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11215    (set (mem:SI (match_dup 0))
11216         (match_operand:SI 2 "general_movsrc_operand" ""))]
11217   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11218   "mov.l        %2,@(%0,%1)")
11220 (define_peephole
11221   [(set (match_operand:SI 0 "register_operand" "=r")
11222         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11223    (set (match_operand:SI 2 "general_movdst_operand" "")
11224         (mem:SI (match_dup 0)))]
11225   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11226   "mov.l        @(%0,%1),%2")
11228 (define_peephole
11229   [(set (match_operand:SI 0 "register_operand" "=r")
11230         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11231    (set (mem:HI (match_dup 0))
11232         (match_operand:HI 2 "general_movsrc_operand" ""))]
11233   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11234   "mov.w        %2,@(%0,%1)")
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:HI 2 "general_movdst_operand" "")
11240         (mem:HI (match_dup 0)))]
11241   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11242   "mov.w        @(%0,%1),%2")
11244 (define_peephole
11245   [(set (match_operand:SI 0 "register_operand" "=r")
11246         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11247    (set (mem:QI (match_dup 0))
11248         (match_operand:QI 2 "general_movsrc_operand" ""))]
11249   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11250   "mov.b        %2,@(%0,%1)")
11252 (define_peephole
11253   [(set (match_operand:SI 0 "register_operand" "=r")
11254         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11255    (set (match_operand:QI 2 "general_movdst_operand" "")
11256         (mem:QI (match_dup 0)))]
11257   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11258   "mov.b        @(%0,%1),%2")
11260 (define_peephole
11261   [(set (match_operand:SI 0 "register_operand" "=r")
11262         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11263    (set (mem:SF (match_dup 0))
11264         (match_operand:SF 2 "general_movsrc_operand" ""))]
11265   "TARGET_SH1 && REGNO (operands[0]) == 0
11266    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11267        || (GET_CODE (operands[2]) == SUBREG
11268            && REGNO (SUBREG_REG (operands[2])) < 16))
11269    && reg_unused_after (operands[0], insn)"
11270   "mov.l        %2,@(%0,%1)")
11272 (define_peephole
11273   [(set (match_operand:SI 0 "register_operand" "=r")
11274         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11275    (set (match_operand:SF 2 "general_movdst_operand" "")
11277         (mem:SF (match_dup 0)))]
11278   "TARGET_SH1 && REGNO (operands[0]) == 0
11279    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11280        || (GET_CODE (operands[2]) == SUBREG
11281            && REGNO (SUBREG_REG (operands[2])) < 16))
11282    && reg_unused_after (operands[0], insn)"
11283   "mov.l        @(%0,%1),%2")
11285 (define_peephole
11286   [(set (match_operand:SI 0 "register_operand" "=r")
11287         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11288    (set (mem:SF (match_dup 0))
11289         (match_operand:SF 2 "general_movsrc_operand" ""))]
11290   "TARGET_SH2E && REGNO (operands[0]) == 0
11291    && ((GET_CODE (operands[2]) == REG
11292         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11293        || (GET_CODE (operands[2]) == SUBREG
11294            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11295    && reg_unused_after (operands[0], insn)"
11296   "fmov{.s|}    %2,@(%0,%1)")
11298 (define_peephole
11299   [(set (match_operand:SI 0 "register_operand" "=r")
11300         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11301    (set (match_operand:SF 2 "general_movdst_operand" "")
11303         (mem:SF (match_dup 0)))]
11304   "TARGET_SH2E && REGNO (operands[0]) == 0
11305    && ((GET_CODE (operands[2]) == REG
11306         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11307        || (GET_CODE (operands[2]) == SUBREG
11308            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11309    && reg_unused_after (operands[0], insn)"
11310   "fmov{.s|}    @(%0,%1),%2")
11312 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11313 (define_insn "sp_switch_1"
11314   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11315   "TARGET_SH1"
11316   "*
11318   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11319   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11320   return \"mov r0,r15\";
11322   [(set_attr "length" "10")])
11324 ;; Switch back to the original stack for interrupt functions with the
11325 ;; sp_switch attribute.  */
11326 (define_insn "sp_switch_2"
11327   [(const_int 2)]
11328   "TARGET_SH1"
11329   "mov.l @r15+,r15\;mov.l @r15+,r0"
11330   [(set_attr "length" "4")])
11332 ;; Integer vector moves
11334 (define_expand "movv8qi"
11335   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11336         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11337   "TARGET_SHMEDIA"
11338   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11340 (define_insn "movv8qi_i"
11341   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11342         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11343   "TARGET_SHMEDIA
11344    && (register_operand (operands[0], V8QImode)
11345        || sh_register_operand (operands[1], V8QImode))"
11346   "@
11347         add     %1, r63, %0
11348         movi    %1, %0
11349         #
11350         ld%M1.q %m1, %0
11351         st%M0.q %m0, %N1"
11352   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11353    (set_attr "length" "4,4,16,4,4")])
11355 (define_split
11356   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11357         (subreg:V8QI (const_int 0) 0))]
11358   "TARGET_SHMEDIA"
11359   [(set (match_dup 0)
11360         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11361                             (const_int 0) (const_int 0) (const_int 0)
11362                             (const_int 0) (const_int 0)]))])
11364 (define_split
11365   [(set (match_operand 0 "arith_reg_dest" "")
11366         (match_operand 1 "sh_rep_vec" ""))]
11367   "TARGET_SHMEDIA && reload_completed
11368    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11369    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11370    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11371    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11372        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11373    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11374        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11375   [(set (match_dup 0) (match_dup 1))
11376    (match_dup 2)]
11377   "
11379   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11380   rtx elt1 = XVECEXP (operands[1], 0, 1);
11382   if (unit_size > 2)
11383     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11384   else
11385     {
11386       if (unit_size < 2)
11387         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11388       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11389     }
11390   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11391   operands[1] = XVECEXP (operands[1], 0, 0);
11392   if (unit_size < 2)
11393     {
11394       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11395         operands[1]
11396           = GEN_INT (TARGET_LITTLE_ENDIAN
11397                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11398                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11399       else
11400         {
11401           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11402           operands[1]
11403             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11404         }
11405     }
11408 (define_split
11409   [(set (match_operand 0 "arith_reg_dest" "")
11410         (match_operand 1 "sh_const_vec" ""))]
11411   "TARGET_SHMEDIA && reload_completed
11412    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11413    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11414   [(set (match_dup 0) (match_dup 1))]
11415   "
11417   rtx v = operands[1];
11418   enum machine_mode new_mode
11419     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11421   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11422   operands[1]
11423     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11426 (define_expand "movv2hi"
11427   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11428         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11429   "TARGET_SHMEDIA"
11430   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11432 (define_insn "movv2hi_i"
11433   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11434         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11435   "TARGET_SHMEDIA
11436    && (register_operand (operands[0], V2HImode)
11437        || sh_register_operand (operands[1], V2HImode))"
11438   "@
11439         add.l   %1, r63, %0
11440         movi    %1, %0
11441         #
11442         ld%M1.l %m1, %0
11443         st%M0.l %m0, %N1"
11444   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11445    (set_attr "length" "4,4,16,4,4")
11446    (set (attr "highpart")
11447         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11448                (const_string "user")]
11449               (const_string "ignore")))])
11451 (define_expand "movv4hi"
11452   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11453         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11454   "TARGET_SHMEDIA"
11455   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11457 (define_insn "movv4hi_i"
11458   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11459         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11460   "TARGET_SHMEDIA
11461    && (register_operand (operands[0], V4HImode)
11462        || sh_register_operand (operands[1], V4HImode))"
11463   "@
11464         add     %1, r63, %0
11465         movi    %1, %0
11466         #
11467         ld%M1.q %m1, %0
11468         st%M0.q %m0, %N1"
11469   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11470    (set_attr "length" "4,4,16,4,4")
11471    (set_attr "highpart" "depend")])
11473 (define_expand "movv2si"
11474   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11475         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11476   "TARGET_SHMEDIA"
11477   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11479 (define_insn "movv2si_i"
11480   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11481         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11482   "TARGET_SHMEDIA
11483    && (register_operand (operands[0], V2SImode)
11484        || sh_register_operand (operands[1], V2SImode))"
11485   "@
11486         add     %1, r63, %0
11487         #
11488         #
11489         ld%M1.q %m1, %0
11490         st%M0.q %m0, %N1"
11491   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11492    (set_attr "length" "4,4,16,4,4")
11493    (set_attr "highpart" "depend")])
11495 ;; Multimedia Intrinsics
11497 (define_insn "absv2si2"
11498   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11499         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11500   "TARGET_SHMEDIA"
11501   "mabs.l       %1, %0"
11502   [(set_attr "type" "mcmp_media")
11503    (set_attr "highpart" "depend")])
11505 (define_insn "absv4hi2"
11506   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11507         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11508   "TARGET_SHMEDIA"
11509   "mabs.w       %1, %0"
11510   [(set_attr "type" "mcmp_media")
11511    (set_attr "highpart" "depend")])
11513 (define_insn "addv2si3"
11514   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11515         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11516                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11517   "TARGET_SHMEDIA"
11518   "madd.l       %1, %2, %0"
11519   [(set_attr "type" "arith_media")
11520    (set_attr "highpart" "depend")])
11522 (define_insn "addv4hi3"
11523   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11524         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11525                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11526   "TARGET_SHMEDIA"
11527   "madd.w       %1, %2, %0"
11528   [(set_attr "type" "arith_media")
11529    (set_attr "highpart" "depend")])
11531 (define_insn_and_split "addv2hi3"
11532   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11533         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11534                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11535   "TARGET_SHMEDIA"
11536   "#"
11537   "TARGET_SHMEDIA"
11538   [(const_int 0)]
11539   "
11541   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11542   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11543   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11544   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11545   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11547   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11548   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11549   DONE;
11551   [(set_attr "highpart" "must_split")])
11553 (define_insn "ssaddv2si3"
11554   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11555         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11556                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11557   "TARGET_SHMEDIA"
11558   "madds.l      %1, %2, %0"
11559   [(set_attr "type" "mcmp_media")
11560    (set_attr "highpart" "depend")])
11562 (define_insn "usaddv8qi3"
11563   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11564         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11565                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11566   "TARGET_SHMEDIA"
11567   "madds.ub     %1, %2, %0"
11568   [(set_attr "type" "mcmp_media")
11569    (set_attr "highpart" "depend")])
11571 (define_insn "ssaddv4hi3"
11572   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11573         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11574                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11575   "TARGET_SHMEDIA"
11576   "madds.w      %1, %2, %0"
11577   [(set_attr "type" "mcmp_media")
11578    (set_attr "highpart" "depend")])
11580 (define_insn "negcmpeqv8qi"
11581   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11582         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11583                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11584   "TARGET_SHMEDIA"
11585   "mcmpeq.b     %N1, %N2, %0"
11586   [(set_attr "type" "mcmp_media")
11587    (set_attr "highpart" "depend")])
11589 (define_insn "negcmpeqv2si"
11590   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11591         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11592                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11593   "TARGET_SHMEDIA"
11594   "mcmpeq.l     %N1, %N2, %0"
11595   [(set_attr "type" "mcmp_media")
11596    (set_attr "highpart" "depend")])
11598 (define_insn "negcmpeqv4hi"
11599   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11600         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11601                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11602   "TARGET_SHMEDIA"
11603   "mcmpeq.w     %N1, %N2, %0"
11604   [(set_attr "type" "mcmp_media")
11605    (set_attr "highpart" "depend")])
11607 (define_insn "negcmpgtuv8qi"
11608   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11609         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11610                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11611   "TARGET_SHMEDIA"
11612   "mcmpgt.ub    %N1, %N2, %0"
11613   [(set_attr "type" "mcmp_media")
11614    (set_attr "highpart" "depend")])
11616 (define_insn "negcmpgtv2si"
11617   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11618         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11619                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11620   "TARGET_SHMEDIA"
11621   "mcmpgt.l     %N1, %N2, %0"
11622   [(set_attr "type" "mcmp_media")
11623    (set_attr "highpart" "depend")])
11625 (define_insn "negcmpgtv4hi"
11626   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11627         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11628                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11629   "TARGET_SHMEDIA"
11630   "mcmpgt.w     %N1, %N2, %0"
11631   [(set_attr "type" "mcmp_media")
11632    (set_attr "highpart" "depend")])
11634 (define_insn "mcmv"
11635   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11636         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11637                         (match_operand:DI 2 "arith_reg_operand" "r"))
11638                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11639                         (not:DI (match_dup 2)))))]
11640   "TARGET_SHMEDIA"
11641   "mcmv %N1, %2, %0"
11642   [(set_attr "type" "arith_media")
11643    (set_attr "highpart" "depend")])
11645 (define_insn "mcnvs_lw"
11646   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11647         (vec_concat:V4HI
11648          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11649          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11650   "TARGET_SHMEDIA"
11651   "mcnvs.lw     %N1, %N2, %0"
11652   [(set_attr "type" "mcmp_media")])
11654 (define_insn "mcnvs_wb"
11655   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11656         (vec_concat:V8QI
11657          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11658          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11659   "TARGET_SHMEDIA"
11660   "mcnvs.wb     %N1, %N2, %0"
11661   [(set_attr "type" "mcmp_media")])
11663 (define_insn "mcnvs_wub"
11664   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11665         (vec_concat:V8QI
11666          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11667          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11668   "TARGET_SHMEDIA"
11669   "mcnvs.wub    %N1, %N2, %0"
11670   [(set_attr "type" "mcmp_media")])
11672 (define_insn "mextr_rl"
11673   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11674         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11675                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11676                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11677                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11678   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11679   "*
11681   static char templ[21];
11683   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11684            (int) INTVAL (operands[3]) >> 3);
11685   return templ;
11687   [(set_attr "type" "arith_media")])
11689 (define_insn "*mextr_lr"
11690   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11691         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11692                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11693                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11694                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11695   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11696   "*
11698   static char templ[21];
11700   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11701            (int) INTVAL (operands[4]) >> 3);
11702   return templ;
11704   [(set_attr "type" "arith_media")])
11706 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11707 ; vector then varies depending on endianness.
11708 (define_expand "mextr1"
11709   [(match_operand:DI 0 "arith_reg_dest" "")
11710    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11711    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11712   "TARGET_SHMEDIA"
11713   "
11715   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11716                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11717   DONE;
11720 (define_expand "mextr2"
11721   [(match_operand:DI 0 "arith_reg_dest" "")
11722    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11723    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11724   "TARGET_SHMEDIA"
11725   "
11727   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11728                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11729   DONE;
11732 (define_expand "mextr3"
11733   [(match_operand:DI 0 "arith_reg_dest" "")
11734    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11735    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11736   "TARGET_SHMEDIA"
11737   "
11739   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11740                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11741   DONE;
11744 (define_expand "mextr4"
11745   [(match_operand:DI 0 "arith_reg_dest" "")
11746    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11747    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11748   "TARGET_SHMEDIA"
11749   "
11751   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11752                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11753   DONE;
11756 (define_expand "mextr5"
11757   [(match_operand:DI 0 "arith_reg_dest" "")
11758    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11759    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11760   "TARGET_SHMEDIA"
11761   "
11763   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11764                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11765   DONE;
11768 (define_expand "mextr6"
11769   [(match_operand:DI 0 "arith_reg_dest" "")
11770    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11771    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11772   "TARGET_SHMEDIA"
11773   "
11775   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11776                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11777   DONE;
11780 (define_expand "mextr7"
11781   [(match_operand:DI 0 "arith_reg_dest" "")
11782    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11783    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11784   "TARGET_SHMEDIA"
11785   "
11787   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11788                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11789   DONE;
11792 (define_expand "mmacfx_wl"
11793   [(match_operand:V2SI 0 "arith_reg_dest" "")
11794    (match_operand:V2HI 1 "extend_reg_operand" "")
11795    (match_operand:V2HI 2 "extend_reg_operand" "")
11796    (match_operand:V2SI 3 "arith_reg_operand" "")]
11797   "TARGET_SHMEDIA"
11798   "
11800   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11801                               operands[1], operands[2]));
11802   DONE;
11805 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11806 ;; is depend
11807 (define_insn "mmacfx_wl_i"
11808   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11809         (ss_plus:V2SI
11810          (match_operand:V2SI 1 "arith_reg_operand" "0")
11811          (ss_truncate:V2SI
11812           (ashift:V2DI
11813            (sign_extend:V2DI
11814             (mult:V2SI
11815              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11816              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11817            (const_int 1)))))]
11818   "TARGET_SHMEDIA"
11819   "mmacfx.wl    %2, %3, %0"
11820   [(set_attr "type" "mac_media")
11821    (set_attr "highpart" "depend")])
11823 (define_expand "mmacnfx_wl"
11824   [(match_operand:V2SI 0 "arith_reg_dest" "")
11825    (match_operand:V2HI 1 "extend_reg_operand" "")
11826    (match_operand:V2HI 2 "extend_reg_operand" "")
11827    (match_operand:V2SI 3 "arith_reg_operand" "")]
11828   "TARGET_SHMEDIA"
11829   "
11831   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11832                                operands[1], operands[2]));
11833   DONE;
11836 (define_insn "mmacnfx_wl_i"
11837   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11838         (ss_minus:V2SI
11839          (match_operand:V2SI 1 "arith_reg_operand" "0")
11840          (ss_truncate:V2SI
11841           (ashift:V2DI
11842            (sign_extend:V2DI
11843             (mult:V2SI
11844              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11845              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11846            (const_int 1)))))]
11847   "TARGET_SHMEDIA"
11848   "mmacnfx.wl   %2, %3, %0"
11849   [(set_attr "type" "mac_media")
11850    (set_attr "highpart" "depend")])
11852 (define_insn "mulv2si3"
11853   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11854         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11855                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11856   "TARGET_SHMEDIA"
11857   "mmul.l       %1, %2, %0"
11858   [(set_attr "type" "d2mpy_media")
11859    (set_attr "highpart" "depend")])
11861 (define_insn "mulv4hi3"
11862   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11863         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11864                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11865   "TARGET_SHMEDIA"
11866   "mmul.w       %1, %2, %0"
11867   [(set_attr "type" "dmpy_media")
11868    (set_attr "highpart" "depend")])
11870 (define_insn "mmulfx_l"
11871   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11872         (ss_truncate:V2SI
11873          (ashiftrt:V2DI
11874           (mult:V2DI
11875            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11876            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11877           (const_int 31))))]
11878   "TARGET_SHMEDIA"
11879   "mmulfx.l     %1, %2, %0"
11880   [(set_attr "type" "d2mpy_media")
11881    (set_attr "highpart" "depend")])
11883 (define_insn "mmulfx_w"
11884   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11885         (ss_truncate:V4HI
11886          (ashiftrt:V4SI
11887           (mult:V4SI
11888            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11889            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11890           (const_int 15))))]
11891   "TARGET_SHMEDIA"
11892   "mmulfx.w     %1, %2, %0"
11893   [(set_attr "type" "dmpy_media")
11894    (set_attr "highpart" "depend")])
11896 (define_insn "mmulfxrp_w"
11897   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11898         (ss_truncate:V4HI
11899          (ashiftrt:V4SI
11900           (plus:V4SI
11901            (mult:V4SI
11902             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11903             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11904            (const_int 16384))
11905           (const_int 15))))]
11906   "TARGET_SHMEDIA"
11907   "mmulfxrp.w   %1, %2, %0"
11908   [(set_attr "type" "dmpy_media")
11909    (set_attr "highpart" "depend")])
11912 (define_expand "mmulhi_wl"
11913   [(match_operand:V2SI 0 "arith_reg_dest" "")
11914    (match_operand:V4HI 1 "arith_reg_operand" "")
11915    (match_operand:V4HI 2 "arith_reg_operand" "")]
11916   "TARGET_SHMEDIA"
11917   "
11919   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11920              (operands[0], operands[1], operands[2]));
11921   DONE;
11924 (define_expand "mmullo_wl"
11925   [(match_operand:V2SI 0 "arith_reg_dest" "")
11926    (match_operand:V4HI 1 "arith_reg_operand" "")
11927    (match_operand:V4HI 2 "arith_reg_operand" "")]
11928   "TARGET_SHMEDIA"
11929   "
11931   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11932              (operands[0], operands[1], operands[2]));
11933   DONE;
11936 (define_insn "mmul23_wl"
11937   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11938         (vec_select:V2SI
11939          (mult:V4SI
11940           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11941           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11942          (parallel [(const_int 2) (const_int 3)])))]
11943   "TARGET_SHMEDIA"
11944   "* return (TARGET_LITTLE_ENDIAN
11945              ? \"mmulhi.wl      %1, %2, %0\"
11946              : \"mmullo.wl      %1, %2, %0\");"
11947   [(set_attr "type" "dmpy_media")
11948    (set (attr "highpart")
11949         (cond [(eq_attr "endian" "big") (const_string "ignore")]
11950          (const_string "user")))])
11952 (define_insn "mmul01_wl"
11953   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11954         (vec_select:V2SI
11955          (mult:V4SI
11956           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11957           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11958          (parallel [(const_int 0) (const_int 1)])))]
11959   "TARGET_SHMEDIA"
11960   "* return (TARGET_LITTLE_ENDIAN
11961              ? \"mmullo.wl      %1, %2, %0\"
11962              : \"mmulhi.wl      %1, %2, %0\");"
11963   [(set_attr "type" "dmpy_media")
11964    (set (attr "highpart")
11965         (cond [(eq_attr "endian" "little") (const_string "ignore")]
11966          (const_string "user")))])
11969 (define_expand "mmulsum_wq"
11970   [(match_operand:DI 0 "arith_reg_dest" "")
11971    (match_operand:V4HI 1 "arith_reg_operand" "")
11972    (match_operand:V4HI 2 "arith_reg_operand" "")
11973    (match_operand:DI 3 "arith_reg_operand" "")]
11974   "TARGET_SHMEDIA"
11975   "
11977   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11978                                operands[1], operands[2]));
11979   DONE;
11982 (define_insn "mmulsum_wq_i"
11983   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11984         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11985          (plus:DI
11986           (plus:DI
11987            (vec_select:DI
11988             (mult:V4DI
11989              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11990              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11991             (parallel [(const_int 0)]))
11992            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11993                                      (sign_extend:V4DI (match_dup 3)))
11994                           (parallel [(const_int 1)])))
11995           (plus:DI
11996            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11997                                      (sign_extend:V4DI (match_dup 3)))
11998                           (parallel [(const_int 2)]))
11999            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12000                                      (sign_extend:V4DI (match_dup 3)))
12001                           (parallel [(const_int 3)]))))))]
12002   "TARGET_SHMEDIA"
12003   "mmulsum.wq   %2, %3, %0"
12004   [(set_attr "type" "mac_media")])
12006 (define_expand "mperm_w"
12007   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12008    (match_operand:V4HI 1 "arith_reg_operand" "r")
12009    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12010   "TARGET_SHMEDIA"
12011   "
12013   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12014              (operands[0], operands[1], operands[2]));
12015   DONE;
12018 ; This use of vec_select isn't exactly correct according to rtl.texi
12019 ; (because not constant), but it seems a straightforward extension.
12020 (define_insn "mperm_w_little"
12021   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12022         (vec_select:V4HI
12023          (match_operand:V4HI 1 "arith_reg_operand" "r")
12024          (parallel
12025           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12026                             (const_int 2) (const_int 0))
12027            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12028            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12029            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12030   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12031   "mperm.w      %1, %N2, %0"
12032   [(set_attr "type" "arith_media")])
12034 (define_insn "mperm_w_big"
12035   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12036         (vec_select:V4HI
12037          (match_operand:V4HI 1 "arith_reg_operand" "r")
12038          (parallel
12039           [(zero_extract:QI (not:QI (match_operand:QI 2
12040                                      "extend_reg_or_0_operand" "rZ"))
12041                             (const_int 2) (const_int 0))
12042            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12043            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12044            (zero_extract:QI (not:QI (match_dup 2))
12045                             (const_int 2) (const_int 6))])))]
12046   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12047   "mperm.w      %1, %N2, %0"
12048   [(set_attr "type" "arith_media")])
12050 (define_insn "mperm_w0"
12051   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12052         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12053                                           "trunc_hi_operand" "r"))))]
12054   "TARGET_SHMEDIA"
12055   "mperm.w      %1, r63, %0"
12056   [(set_attr "type" "arith_media")
12057    (set_attr "highpart" "ignore")])
12059 (define_expand "msad_ubq"
12060   [(match_operand:DI 0 "arith_reg_dest" "")
12061    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12062    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12063    (match_operand:DI 3 "arith_reg_operand" "")]
12064   "TARGET_SHMEDIA"
12065   "
12067   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12068                              operands[1], operands[2]));
12069   DONE;
12072 (define_insn "msad_ubq_i"
12073   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12074         (plus:DI
12075          (plus:DI
12076           (plus:DI
12077            (plus:DI
12078             (match_operand:DI 1 "arith_reg_operand" "0")
12079             (abs:DI (vec_select:DI
12080                      (minus:V8DI
12081                       (zero_extend:V8DI
12082                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12083                       (zero_extend:V8DI
12084                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12085                      (parallel [(const_int 0)]))))
12086            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12087                                               (zero_extend:V8DI (match_dup 3)))
12088                                   (parallel [(const_int 1)]))))
12089           (plus:DI
12090            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12091                                               (zero_extend:V8DI (match_dup 3)))
12092                                   (parallel [(const_int 2)])))
12093            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12094                                               (zero_extend:V8DI (match_dup 3)))
12095                                   (parallel [(const_int 3)])))))
12096          (plus:DI
12097           (plus:DI
12098            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12099                                               (zero_extend:V8DI (match_dup 3)))
12100                                   (parallel [(const_int 4)])))
12101            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12102                                               (zero_extend:V8DI (match_dup 3)))
12103                                   (parallel [(const_int 5)]))))
12104           (plus:DI
12105            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12106                                               (zero_extend:V8DI (match_dup 3)))
12107                                   (parallel [(const_int 6)])))
12108            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12109                                               (zero_extend:V8DI (match_dup 3)))
12110                                   (parallel [(const_int 7)])))))))]
12111   "TARGET_SHMEDIA"
12112   "msad.ubq     %N2, %N3, %0"
12113   [(set_attr "type" "mac_media")])
12115 (define_insn "mshalds_l"
12116   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12117         (ss_truncate:V2SI
12118          (ashift:V2DI
12119           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12120           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12121                   (const_int 31)))))]
12122   "TARGET_SHMEDIA"
12123   "mshalds.l    %1, %2, %0"
12124   [(set_attr "type" "mcmp_media")
12125    (set_attr "highpart" "depend")])
12127 (define_insn "mshalds_w"
12128   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12129         (ss_truncate:V4HI
12130          (ashift:V4SI
12131           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12132           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12133                   (const_int 15)))))]
12134   "TARGET_SHMEDIA"
12135   "mshalds.w    %1, %2, %0"
12136   [(set_attr "type" "mcmp_media")
12137    (set_attr "highpart" "depend")])
12139 (define_insn "ashrv2si3"
12140   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12141         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12142                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12143   "TARGET_SHMEDIA"
12144   "mshard.l     %1, %2, %0"
12145   [(set_attr "type" "arith_media")
12146    (set_attr "highpart" "depend")])
12148 (define_insn "ashrv4hi3"
12149   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12150         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12151                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12152   "TARGET_SHMEDIA"
12153   "mshard.w     %1, %2, %0"
12154   [(set_attr "type" "arith_media")
12155    (set_attr "highpart" "depend")])
12157 (define_insn "mshards_q"
12158   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12159         (ss_truncate:HI
12160          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12161                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12162   "TARGET_SHMEDIA"
12163   "mshards.q    %1, %N2, %0"
12164   [(set_attr "type" "mcmp_media")])
12166 (define_expand "mshfhi_b"
12167   [(match_operand:V8QI 0 "arith_reg_dest" "")
12168    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12169    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12170   "TARGET_SHMEDIA"
12171   "
12173   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12174              (operands[0], operands[1], operands[2]));
12175   DONE;
12178 (define_expand "mshflo_b"
12179   [(match_operand:V8QI 0 "arith_reg_dest" "")
12180    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12181    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12182   "TARGET_SHMEDIA"
12183   "
12185   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12186              (operands[0], operands[1], operands[2]));
12187   DONE;
12190 (define_insn "mshf4_b"
12191   [(set
12192     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12193     (vec_select:V8QI
12194      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12195                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12196      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12197                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12198   "TARGET_SHMEDIA"
12199   "* return (TARGET_LITTLE_ENDIAN
12200              ? \"mshfhi.b       %N1, %N2, %0\"
12201              : \"mshflo.b       %N1, %N2, %0\");"
12202   [(set_attr "type" "arith_media")
12203    (set (attr "highpart")
12204         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12205          (const_string "user")))])
12207 (define_insn "mshf0_b"
12208   [(set
12209     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12210     (vec_select:V8QI
12211      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12212                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12213      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12214                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12215   "TARGET_SHMEDIA"
12216   "* return (TARGET_LITTLE_ENDIAN
12217              ? \"mshflo.b       %N1, %N2, %0\"
12218              : \"mshfhi.b       %N1, %N2, %0\");"
12219   [(set_attr "type" "arith_media")
12220    (set (attr "highpart")
12221         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12222          (const_string "user")))])
12224 (define_expand "mshfhi_l"
12225   [(match_operand:V2SI 0 "arith_reg_dest" "")
12226    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12227    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12228   "TARGET_SHMEDIA"
12229   "
12231   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12232              (operands[0], operands[1], operands[2]));
12233   DONE;
12236 (define_expand "mshflo_l"
12237   [(match_operand:V2SI 0 "arith_reg_dest" "")
12238    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12239    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12240   "TARGET_SHMEDIA"
12241   "
12243   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12244              (operands[0], operands[1], operands[2]));
12245   DONE;
12248 (define_insn "mshf4_l"
12249   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12250         (vec_select:V2SI
12251          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12252                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12253          (parallel [(const_int 1) (const_int 3)])))]
12254   "TARGET_SHMEDIA"
12255   "* return (TARGET_LITTLE_ENDIAN
12256              ? \"mshfhi.l       %N1, %N2, %0\"
12257              : \"mshflo.l       %N1, %N2, %0\");"
12258   [(set_attr "type" "arith_media")
12259    (set (attr "highpart")
12260         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12261          (const_string "user")))])
12263 (define_insn "mshf0_l"
12264   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12265         (vec_select:V2SI
12266          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12267                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12268          (parallel [(const_int 0) (const_int 2)])))]
12269   "TARGET_SHMEDIA"
12270   "* return (TARGET_LITTLE_ENDIAN
12271              ? \"mshflo.l       %N1, %N2, %0\"
12272              : \"mshfhi.l       %N1, %N2, %0\");"
12273   [(set_attr "type" "arith_media")
12274    (set (attr "highpart")
12275         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12276          (const_string "user")))])
12278 (define_expand "mshfhi_w"
12279   [(match_operand:V4HI 0 "arith_reg_dest" "")
12280    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12281    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12282   "TARGET_SHMEDIA"
12283   "
12285   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12286              (operands[0], operands[1], operands[2]));
12287   DONE;
12290 (define_expand "mshflo_w"
12291   [(match_operand:V4HI 0 "arith_reg_dest" "")
12292    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12293    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12294   "TARGET_SHMEDIA"
12295   "
12297   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12298              (operands[0], operands[1], operands[2]));
12299   DONE;
12302 (define_insn "mshf4_w"
12303   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12304         (vec_select:V4HI
12305          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12306                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12307          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12308   "TARGET_SHMEDIA"
12309   "* return (TARGET_LITTLE_ENDIAN
12310              ? \"mshfhi.w       %N1, %N2, %0\"
12311              : \"mshflo.w       %N1, %N2, %0\");"
12312   [(set_attr "type" "arith_media")
12313    (set (attr "highpart")
12314         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12315          (const_string "user")))])
12317 (define_insn "mshf0_w"
12318   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12319         (vec_select:V4HI
12320          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12321                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12322          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12323   "TARGET_SHMEDIA"
12324   "* return (TARGET_LITTLE_ENDIAN
12325              ? \"mshflo.w       %N1, %N2, %0\"
12326              : \"mshfhi.w       %N1, %N2, %0\");"
12327   [(set_attr "type" "arith_media")
12328    (set (attr "highpart")
12329         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12330          (const_string "user")))])
12332 (define_insn "mshflo_w_x"
12333   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12334         (vec_select:V4HI
12335          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12336                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12337          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12338   "TARGET_SHMEDIA"
12339   "mshflo.w     %N1, %N2, %0"
12340   [(set_attr "type" "arith_media")
12341    (set_attr "highpart" "ignore")])
12343 /* These are useful to expand ANDs and as combiner patterns.  */
12344 (define_insn_and_split "mshfhi_l_di"
12345   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12346         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12347                              (const_int 32))
12348                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12349                         (const_int -4294967296))))]
12350   "TARGET_SHMEDIA"
12351   "@
12352         mshfhi.l        %N1, %N2, %0
12353         #"
12354   "TARGET_SHMEDIA && reload_completed
12355    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12356   [(set (match_dup 3) (match_dup 4))
12357    (set (match_dup 5) (match_dup 6))]
12358   "
12360   operands[3] = gen_lowpart (SImode, operands[0]);
12361   operands[4] = gen_highpart (SImode, operands[1]);
12362   operands[5] = gen_highpart (SImode, operands[0]);
12363   operands[6] = gen_highpart (SImode, operands[2]);
12365   [(set_attr "type" "arith_media")])
12367 (define_insn "*mshfhi_l_di_rev"
12368   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12369         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12370                         (const_int -4294967296))
12371                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12372                              (const_int 32))))]
12373   "TARGET_SHMEDIA"
12374   "mshfhi.l     %N2, %N1, %0"
12375   [(set_attr "type" "arith_media")])
12377 (define_split
12378   [(set (match_operand:DI 0 "arith_reg_dest" "")
12379         (ior:DI (zero_extend:DI (match_operand:SI 1
12380                                               "extend_reg_or_0_operand" ""))
12381                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12382                         (const_int -4294967296))))
12383    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12384   "TARGET_SHMEDIA"
12385   [(const_int 0)]
12386   "
12388   emit_insn (gen_ashldi3_media (operands[3],
12389                                 simplify_gen_subreg (DImode, operands[1],
12390                                                      SImode, 0),
12391                                 GEN_INT (32)));
12392   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12393   DONE;
12396 (define_insn "mshflo_l_di"
12397   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12398         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12399                         (const_int 4294967295))
12400                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12401                            (const_int 32))))]
12403   "TARGET_SHMEDIA"
12404   "mshflo.l     %N1, %N2, %0"
12405   [(set_attr "type" "arith_media")
12406    (set_attr "highpart" "ignore")])
12408 (define_insn "*mshflo_l_di_rev"
12409   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12410         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12411                            (const_int 32))
12412                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12413                         (const_int 4294967295))))]
12415   "TARGET_SHMEDIA"
12416   "mshflo.l     %N2, %N1, %0"
12417   [(set_attr "type" "arith_media")
12418    (set_attr "highpart" "ignore")])
12420 ;; Combiner pattern for trampoline initialization.
12421 (define_insn_and_split "*double_shori"
12422   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12423         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12424                            (const_int 32))
12425                 (match_operand:DI 2 "const_int_operand" "n")))]
12426   "TARGET_SHMEDIA
12427    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12428   "#"
12429   "rtx_equal_p (operands[0], operands[1])"
12430   [(const_int 0)]
12431   "
12433   HOST_WIDE_INT v = INTVAL (operands[2]);
12435   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12436   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12437   DONE;
12439   [(set_attr "highpart" "ignore")])
12442 (define_insn "*mshflo_l_di_x"
12443   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12444         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12445                                  "rZ"))
12446                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12447                            (const_int 32))))]
12449   "TARGET_SHMEDIA"
12450   "mshflo.l     %N1, %N2, %0"
12451   [(set_attr "type" "arith_media")
12452    (set_attr "highpart" "ignore")])
12454 (define_insn_and_split "concat_v2sf"
12455   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12456 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12457         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12458                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12460   "TARGET_SHMEDIA"
12461   "@
12462         mshflo.l        %N1, %N2, %0
12463         #
12464         #"
12465   "TARGET_SHMEDIA && reload_completed
12466    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12467   [(set (match_dup 3) (match_dup 1))
12468    (set (match_dup 4) (match_dup 2))]
12469   "
12471   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12472   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12474   [(set_attr "type" "arith_media")
12475    (set_attr "highpart" "ignore")])
12477 (define_insn "*mshflo_l_di_x_rev"
12478   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12479         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12480                            (const_int 32))
12481                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12483   "TARGET_SHMEDIA"
12484   "mshflo.l     %N2, %N1, %0"
12485   [(set_attr "type" "arith_media")
12486    (set_attr "highpart" "ignore")])
12488 (define_insn "ashlv2si3"
12489   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12490         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12491                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12492   "TARGET_SHMEDIA"
12493   "mshlld.l     %1, %2, %0"
12494   [(set_attr "type" "arith_media")
12495    (set_attr "highpart" "depend")])
12497 (define_split
12498   [(set (match_operand 0 "any_register_operand" "")
12499         (match_operator 3 "shift_operator"
12500           [(match_operand 1 "any_register_operand" "")
12501            (match_operand 2 "shift_count_reg_operand" "")]))]
12502   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12503   [(set (match_dup 0) (match_dup 3))]
12504   "
12506   rtx count = operands[2];
12507   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12509   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12510          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12511          || GET_CODE (count) == TRUNCATE)
12512     count = XEXP (count, 0);
12513   inner_mode = GET_MODE (count);
12514   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12515                                subreg_lowpart_offset (outer_mode, inner_mode));
12516   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12517                                 operands[1], count);
12520 (define_insn "ashlv4hi3"
12521   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12522         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12523                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12524   "TARGET_SHMEDIA"
12525   "mshlld.w     %1, %2, %0"
12526   [(set_attr "type" "arith_media")
12527    (set_attr "highpart" "depend")])
12529 (define_insn "lshrv2si3"
12530   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12531         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12532                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12533   "TARGET_SHMEDIA"
12534   "mshlrd.l     %1, %2, %0"
12535   [(set_attr "type" "arith_media")
12536    (set_attr "highpart" "depend")])
12538 (define_insn "lshrv4hi3"
12539   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12540         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12541                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12542   "TARGET_SHMEDIA"
12543   "mshlrd.w     %1, %2, %0"
12544   [(set_attr "type" "arith_media")
12545    (set_attr "highpart" "depend")])
12547 (define_insn "subv2si3"
12548   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12549         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12550                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12551   "TARGET_SHMEDIA"
12552   "msub.l       %N1, %2, %0"
12553   [(set_attr "type" "arith_media")
12554    (set_attr "highpart" "depend")])
12556 (define_insn "subv4hi3"
12557   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12558         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12559                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12560   "TARGET_SHMEDIA"
12561   "msub.w       %N1, %2, %0"
12562   [(set_attr "type" "arith_media")
12563    (set_attr "highpart" "depend")])
12565 (define_insn_and_split "subv2hi3"
12566   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12567         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12568                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12569   "TARGET_SHMEDIA"
12570   "#"
12571   "TARGET_SHMEDIA"
12572   [(const_int 0)]
12573   "
12575   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12576   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12577   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12578   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12579   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12581   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12582   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12583   DONE;
12585   [(set_attr "highpart" "must_split")])
12587 (define_insn "sssubv2si3"
12588   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12589         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12590                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12591   "TARGET_SHMEDIA"
12592   "msubs.l      %N1, %2, %0"
12593   [(set_attr "type" "mcmp_media")
12594    (set_attr "highpart" "depend")])
12596 (define_insn "ussubv8qi3"
12597   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12598         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12599                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12600   "TARGET_SHMEDIA"
12601   "msubs.ub     %N1, %2, %0"
12602   [(set_attr "type" "mcmp_media")
12603    (set_attr "highpart" "depend")])
12605 (define_insn "sssubv4hi3"
12606   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12607         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12608                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12609   "TARGET_SHMEDIA"
12610   "msubs.w      %N1, %2, %0"
12611   [(set_attr "type" "mcmp_media")
12612    (set_attr "highpart" "depend")])
12614 ;; Floating Point Intrinsics
12616 (define_insn "fcosa_s"
12617   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12618         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12619                    UNSPEC_FCOSA))]
12620   "TARGET_SHMEDIA"
12621   "fcosa.s      %1, %0"
12622   [(set_attr "type" "atrans_media")])
12624 (define_insn "fsina_s"
12625   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12626         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12627                    UNSPEC_FSINA))]
12628   "TARGET_SHMEDIA"
12629   "fsina.s      %1, %0"
12630   [(set_attr "type" "atrans_media")])
12632 (define_insn "fipr"
12633   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12634         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12635                                                     "fp_arith_reg_operand" "f")
12636                                                    (match_operand:V4SF 2
12637                                                     "fp_arith_reg_operand" "f"))
12638                                          (parallel [(const_int 0)]))
12639                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12640                                          (parallel [(const_int 1)])))
12641                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12642                                          (parallel [(const_int 2)]))
12643                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12644                                          (parallel [(const_int 3)])))))]
12645   "TARGET_SHMEDIA"
12646   "fipr.s       %1, %2, %0"
12647   [(set_attr "type" "fparith_media")])
12649 (define_insn "fsrra_s"
12650   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12651         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12652                    UNSPEC_FSRRA))]
12653   "TARGET_SHMEDIA"
12654   "fsrra.s      %1, %0"
12655   [(set_attr "type" "atrans_media")])
12657 (define_insn "ftrv"
12658   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12659         (plus:V4SF
12660          (plus:V4SF
12661           (mult:V4SF
12662            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12663                             (parallel [(const_int 0) (const_int 5)
12664                                        (const_int 10) (const_int 15)]))
12665            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12666           (mult:V4SF
12667            (vec_select:V4SF (match_dup 1)
12668                             (parallel [(const_int 4) (const_int 9)
12669                                        (const_int 14) (const_int 3)]))
12670            (vec_select:V4SF (match_dup 2)
12671                             (parallel [(const_int 1) (const_int 2)
12672                                        (const_int 3) (const_int 0)]))))
12673          (plus:V4SF
12674           (mult:V4SF
12675            (vec_select:V4SF (match_dup 1)
12676                             (parallel [(const_int 8) (const_int 13)
12677                                        (const_int 2) (const_int 7)]))
12678            (vec_select:V4SF (match_dup 2)
12679                             (parallel [(const_int 2) (const_int 3)
12680                                        (const_int 0) (const_int 1)])))
12681           (mult:V4SF
12682            (vec_select:V4SF (match_dup 1)
12683                             (parallel [(const_int 12) (const_int 1)
12684                                        (const_int 6) (const_int 11)]))
12685            (vec_select:V4SF (match_dup 2)
12686                             (parallel [(const_int 3) (const_int 0)
12687                                        (const_int 1) (const_int 2)]))))))]
12688   "TARGET_SHMEDIA"
12689   "ftrv.s %1, %2, %0"
12690   [(set_attr "type" "fparith_media")])
12692 (define_insn "ldhi_l"
12693   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12694         (zero_extract:SI
12695          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12696                                   (const_int 3))
12697                           (const_int -3)))
12698          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12699          (const_int 0)))]
12700   "TARGET_SHMEDIA32"
12701   "ldhi.l       %U1, %0"
12702   [(set_attr "type" "load_media")])
12704 (define_insn "ldhi_q"
12705   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12706         (zero_extract:DI
12707          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12708                                   (const_int 7))
12709                           (const_int -7)))
12710          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12711          (const_int 0)))]
12712   "TARGET_SHMEDIA32"
12713   "ldhi.q       %U1, %0"
12714   [(set_attr "type" "load_media")])
12716 (define_insn_and_split "*ldhi_q_comb0"
12717   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12718         (zero_extract:DI
12719          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12720                                             "register_operand" "r")
12721                                            (match_operand:SI 2
12722                                             "ua_offset" "I06"))
12723                                   (const_int 7))
12724                           (const_int -7)))
12725          (plus:SI (and:SI (match_dup 1) (const_int 7))
12726                   (const_int 1))
12727          (const_int 0)))]
12728   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12729   "#"
12730   ""
12731   [(pc)]
12732   "emit_insn (gen_ldhi_q (operands[0],
12733                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12734    DONE;")
12737 (define_insn_and_split "*ldhi_q_comb1"
12738   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12739         (zero_extract:DI
12740          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12741                                             "register_operand" "r")
12742                                            (match_operand:SI 2
12743                                             "ua_offset" "I06"))
12744                                   (const_int 7))
12745                           (const_int -7)))
12746          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12747                                                    "ua_offset" "I06"))
12748                           (const_int 7))
12749                   (const_int 1))
12750          (const_int 0)))]
12751   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12752    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12753   "#"
12754   ""
12755   [(pc)]
12756   "emit_insn (gen_ldhi_q (operands[0],
12757                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12758    DONE;")
12761 (define_insn "ldlo_l"
12762   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12763         (zero_extract:SI
12764          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12765                          (const_int -4)))
12766          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12767          (and:SI (match_dup 1) (const_int 3))))]
12768   "TARGET_SHMEDIA32"
12769   "ldlo.l       %U1, %0"
12770   [(set_attr "type" "load_media")])
12772 (define_insn "ldlo_q"
12773   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12774         (zero_extract:DI
12775          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12776                          (const_int -8)))
12777          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12778          (and:SI (match_dup 1) (const_int 7))))]
12779   "TARGET_SHMEDIA32"
12780   "ldlo.q       %U1, %0"
12781   [(set_attr "type" "load_media")])
12783 (define_insn_and_split "*ldlo_q_comb0"
12784   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12785         (zero_extract:DI
12786          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12787                                   (match_operand:SI 2 "ua_offset" "I06"))
12788                          (const_int -8)))
12789          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12790          (and:SI (match_dup 1) (const_int 7))))]
12791   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12792   "#"
12793   ""
12794   [(pc)]
12795   "emit_insn (gen_ldlo_q (operands[0],
12796                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12797    DONE;")
12799 (define_insn_and_split "*ldlo_q_comb1"
12800   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12801         (zero_extract:DI
12802          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12803                                   (match_operand:SI 2 "ua_offset" "I06"))
12804                          (const_int -8)))
12805          (minus:SI (const_int 8)
12806                    (and:SI (plus:SI (match_dup 1)
12807                                     (match_operand:SI 3 "ua_offset" "I06"))
12808                            (const_int 7)))
12809          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12810   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12811    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12812   "#"
12813   ""
12814   [(pc)]
12815   "emit_insn (gen_ldlo_q (operands[0],
12816                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12817    DONE;")
12819 (define_insn "sthi_l"
12820   [(set (zero_extract:SI
12821          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12822                                   (const_int 3))
12823                           (const_int -3)))
12824          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12825          (const_int 0))
12826         (match_operand:SI 1 "arith_reg_operand" "r"))]
12827   "TARGET_SHMEDIA32"
12828   "sthi.l       %U0, %1"
12829   [(set_attr "type" "ustore_media")])
12831 ;; All unaligned stores are considered to be 'narrow' because they typically
12832 ;; operate on less that a quadword, and when they operate on a full quadword,
12833 ;; the vanilla store high / store low sequence will cause a stall if not
12834 ;; scheduled apart.
12835 (define_insn "sthi_q"
12836   [(set (zero_extract:DI
12837          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12838                                   (const_int 7))
12839                           (const_int -7)))
12840          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12841          (const_int 0))
12842         (match_operand:DI 1 "arith_reg_operand" "r"))]
12843   "TARGET_SHMEDIA32"
12844   "sthi.q       %U0, %1"
12845   [(set_attr "type" "ustore_media")])
12847 (define_insn_and_split "*sthi_q_comb0"
12848   [(set (zero_extract:DI
12849          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12850                                             "register_operand" "r")
12851                                            (match_operand:SI 1 "ua_offset"
12852                                             "I06"))
12853                                   (const_int 7))
12854                           (const_int -7)))
12855          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12856          (const_int 0))
12857         (match_operand:DI 2 "arith_reg_operand" "r"))]
12858   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12859   "#"
12860   ""
12861   [(pc)]
12862   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12863                           operands[2]));
12864    DONE;")
12866 (define_insn_and_split "*sthi_q_comb1"
12867   [(set (zero_extract:DI
12868          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12869                                             "register_operand" "r")
12870                                            (match_operand:SI 1 "ua_offset"
12871                                             "I06"))
12872                                   (const_int 7))
12873                           (const_int -7)))
12874          (plus:SI (and:SI (plus:SI (match_dup 0)
12875                                    (match_operand:SI 2 "ua_offset" "I06"))
12876                           (const_int 7))
12877                   (const_int 1))
12878          (const_int 0))
12879         (match_operand:DI 3 "arith_reg_operand" "r"))]
12880   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12881    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12882   "#"
12883   ""
12884   [(pc)]
12885   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12886                           operands[3]));
12887    DONE;")
12889 ;; This is highpart user because the address is used as full 64 bit.
12890 (define_insn "stlo_l"
12891   [(set (zero_extract:SI
12892          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12893                          (const_int -4)))
12894          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12895          (and:SI (match_dup 0) (const_int 3)))
12896         (match_operand:SI 1 "arith_reg_operand" "r"))]
12897   "TARGET_SHMEDIA32"
12898   "stlo.l       %U0, %1"
12899   [(set_attr "type" "ustore_media")])
12901 (define_insn "stlo_q"
12902   [(set (zero_extract:DI
12903          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12904                          (const_int -8)))
12905          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12906          (and:SI (match_dup 0) (const_int 7)))
12907         (match_operand:DI 1 "arith_reg_operand" "r"))]
12908   "TARGET_SHMEDIA32"
12909   "stlo.q       %U0, %1"
12910   [(set_attr "type" "ustore_media")])
12912 (define_insn_and_split "*stlo_q_comb0"
12913   [(set (zero_extract:DI
12914          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12915                                   (match_operand:SI 1 "ua_offset" "I06"))
12916                          (const_int -8)))
12917          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12918          (and:SI (match_dup 0) (const_int 7)))
12919         (match_operand:DI 2 "arith_reg_operand" "r"))]
12920   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12921   "#"
12922   ""
12923   [(pc)]
12924   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12925                           operands[2]));
12926    DONE;")
12928 (define_insn_and_split "*stlo_q_comb1"
12929   [(set (zero_extract:DI
12930          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12931                                   (match_operand:SI 1 "ua_offset" "I06"))
12932                          (const_int -8)))
12933          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12934                                                   (match_operand:SI 2
12935                                                    "ua_offset" "I06"))
12936                                          (const_int 7)))
12937          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12938         (match_operand:DI 3 "arith_reg_operand" "r"))]
12939   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12940   "#"
12941   ""
12942   [(pc)]
12943   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12944                           operands[3]));
12945    DONE;")
12947 (define_insn "ldhi_l64"
12948   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12949         (zero_extract:SI
12950          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12951                                   (const_int 3))
12952                           (const_int -3)))
12953          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12954          (const_int 0)))]
12955   "TARGET_SHMEDIA64"
12956   "ldhi.l       %U1, %0"
12957   [(set_attr "type" "load_media")])
12959 (define_insn "ldhi_q64"
12960   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12961         (zero_extract:DI
12962          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12963                                   (const_int 7))
12964                           (const_int -7)))
12965          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12966          (const_int 0)))]
12967   "TARGET_SHMEDIA64"
12968   "ldhi.q       %U1, %0"
12969   [(set_attr "type" "load_media")])
12971 (define_insn "ldlo_l64"
12972   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12973         (zero_extract:SI
12974          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12975                          (const_int -4)))
12976          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12977          (and:DI (match_dup 1) (const_int 3))))]
12978   "TARGET_SHMEDIA64"
12979   "ldlo.l       %U1, %0"
12980   [(set_attr "type" "load_media")])
12982 (define_insn "ldlo_q64"
12983   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12984         (zero_extract:DI
12985          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12986                          (const_int -8)))
12987          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12988          (and:DI (match_dup 1) (const_int 7))))]
12989   "TARGET_SHMEDIA64"
12990   "ldlo.q       %U1, %0"
12991   [(set_attr "type" "load_media")])
12993 (define_insn "sthi_l64"
12994   [(set (zero_extract:SI
12995          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12996                                   (const_int 3))
12997                           (const_int -3)))
12998          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12999          (const_int 0))
13000         (match_operand:SI 1 "arith_reg_operand" "r"))]
13001   "TARGET_SHMEDIA64"
13002   "sthi.l       %U0, %1"
13003   [(set_attr "type" "ustore_media")])
13005 (define_insn "sthi_q64"
13006   [(set (zero_extract:DI
13007          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13008                                   (const_int 7))
13009                           (const_int -7)))
13010          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13011          (const_int 0))
13012         (match_operand:DI 1 "arith_reg_operand" "r"))]
13013   "TARGET_SHMEDIA64"
13014   "sthi.q       %U0, %1"
13015   [(set_attr "type" "ustore_media")])
13017 (define_insn "stlo_l64"
13018   [(set (zero_extract:SI
13019          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13020                          (const_int -4)))
13021          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13022          (and:DI (match_dup 0) (const_int 3)))
13023         (match_operand:SI 1 "arith_reg_operand" "r"))]
13024   "TARGET_SHMEDIA64"
13025   "stlo.l       %U0, %1"
13026   [(set_attr "type" "ustore_media")])
13028 (define_insn "stlo_q64"
13029   [(set (zero_extract:DI
13030          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13031                          (const_int -8)))
13032          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13033          (and:DI (match_dup 0) (const_int 7)))
13034         (match_operand:DI 1 "arith_reg_operand" "r"))]
13035   "TARGET_SHMEDIA64"
13036   "stlo.q       %U0, %1"
13037   [(set_attr "type" "ustore_media")])
13039 (define_insn "nsb"
13040   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13041         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13042                    UNSPEC_NSB))]
13043   "TARGET_SHMEDIA"
13044   "nsb  %1, %0"
13045   [(set_attr "type" "arith_media")])
13047 (define_insn "nsbsi"
13048   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13049         (zero_extend:SI
13050          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13051                     UNSPEC_NSB)))]
13052   "TARGET_SHMEDIA"
13053   "nsb  %1, %0"
13054   [(set_attr "type" "arith_media")])
13056 (define_insn "nsbdi"
13057   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13058         (zero_extend:DI
13059          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13060                     UNSPEC_NSB)))]
13061   "TARGET_SHMEDIA"
13062   "nsb  %1, %0"
13063   [(set_attr "type" "arith_media")])
13065 (define_expand "ffsdi2"
13066   [(set (match_operand:DI 0 "arith_reg_dest" "")
13067         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13068   "TARGET_SHMEDIA"
13069   "
13071   rtx scratch = gen_reg_rtx (DImode);
13072   rtx last;
13074   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13075   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13076   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13077   emit_insn (gen_nsbdi (scratch, scratch));
13078   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13079   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13080   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13081   REG_NOTES (last)
13082     = gen_rtx_EXPR_LIST (REG_EQUAL,
13083                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13084   DONE;
13087 (define_expand "ffssi2"
13088   [(set (match_operand:SI 0 "arith_reg_dest" "")
13089         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13090   "TARGET_SHMEDIA"
13091   "
13093   rtx scratch = gen_reg_rtx (SImode);
13094   rtx discratch = gen_reg_rtx (DImode);
13095   rtx last;
13097   emit_insn (gen_adddi3 (discratch,
13098                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13099                          constm1_rtx));
13100   emit_insn (gen_andcdi3 (discratch,
13101                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13102                           discratch));
13103   emit_insn (gen_nsbsi (scratch, discratch));
13104   last = emit_insn (gen_subsi3 (operands[0],
13105                                 force_reg (SImode, GEN_INT (63)), scratch));
13106   REG_NOTES (last)
13107     = gen_rtx_EXPR_LIST (REG_EQUAL,
13108                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13109   DONE;
13112 (define_insn "byterev"
13113   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13114         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13115                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13116                                     (const_int 4) (const_int 3) (const_int 2)
13117                                     (const_int 1) (const_int 0)])))]
13118   "TARGET_SHMEDIA"
13119   "byterev      %1, %0"
13120   [(set_attr "type" "arith_media")])
13122 (define_insn "*prefetch_media"
13123   [(prefetch (match_operand:QI 0 "address_operand" "p")
13124              (match_operand:SI 1 "const_int_operand" "n")
13125              (match_operand:SI 2 "const_int_operand" "n"))]
13126   "TARGET_SHMEDIA"
13127   "*
13129   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13130   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13131   return \"\";
13133   [(set_attr "type" "other")])
13135 (define_insn "*prefetch_i4"
13136   [(prefetch (match_operand:SI 0 "register_operand" "r")
13137              (match_operand:SI 1 "const_int_operand" "n")
13138              (match_operand:SI 2 "const_int_operand" "n"))]
13139   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13140   "*
13142   return \"pref @%0\";
13144   [(set_attr "type" "other")])
13146 (define_expand "prefetch"
13147   [(prefetch (match_operand 0 "address_operand" "p")
13148              (match_operand:SI 1 "const_int_operand" "n")
13149              (match_operand:SI 2 "const_int_operand" "n"))]
13150   "TARGET_HARD_SH4 || TARGET_SH5"
13151   "
13153   if (GET_MODE (operands[0]) != Pmode
13154       || GET_CODE (operands[1]) != CONST_INT
13155       || GET_CODE (operands[2]) != CONST_INT)
13156     FAIL;
13157   if (! TARGET_SHMEDIA)
13158     operands[0] = force_reg (Pmode, operands[0]);
13161 (define_insn "alloco_i"
13162   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13163         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13164   "TARGET_SHMEDIA32"
13165   "*
13167   rtx xops[2];
13169   if (GET_CODE (operands[0]) == PLUS)
13170     {
13171       xops[0] = XEXP (operands[0], 0);
13172       xops[1] = XEXP (operands[0], 1);
13173     }
13174   else
13175     {
13176       xops[0] = operands[0];
13177       xops[1] = const0_rtx;
13178     }
13179   output_asm_insn (\"alloco   %0, %1\", xops);
13180   return \"\";
13182   [(set_attr "type" "other")])
13184 (define_split
13185   [(set (match_operand 0 "any_register_operand" "")
13186         (match_operand 1 "" ""))]
13187   "TARGET_SHMEDIA && reload_completed"
13188   [(set (match_dup 0) (match_dup 1))]
13189   "
13191   int n_changes = 0;
13193   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13194   if (!n_changes)
13195     FAIL;
13198 ; Stack Protector Patterns
13200 (define_expand "stack_protect_set"
13201   [(set (match_operand 0 "memory_operand" "")
13202         (match_operand 1 "memory_operand" ""))]
13203   ""
13205   if (TARGET_SHMEDIA)
13206     {
13207       if (TARGET_SHMEDIA64)
13208         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13209       else
13210         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13211     }
13212   else
13213     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13215   DONE;
13218 (define_insn "stack_protect_set_si"
13219   [(set (match_operand:SI 0 "memory_operand" "=m")
13220         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13221    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13222   "!TARGET_SHMEDIA"
13223   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13224   [(set_attr "type" "other")
13225    (set_attr "length" "6")])
13227 (define_insn "stack_protect_set_si_media"
13228   [(set (match_operand:SI 0 "memory_operand" "=m")
13229         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13230    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13231   "TARGET_SHMEDIA"
13232   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13233   [(set_attr "type" "other")
13234    (set_attr "length" "12")])
13236 (define_insn "stack_protect_set_di_media"
13237   [(set (match_operand:DI 0 "memory_operand" "=m")
13238         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13239    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13240   "TARGET_SHMEDIA64"
13241   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13242   [(set_attr "type" "other")
13243    (set_attr "length" "12")])
13245 (define_expand "stack_protect_test"
13246   [(match_operand 0 "memory_operand" "")
13247    (match_operand 1 "memory_operand" "")
13248    (match_operand 2 "" "")]
13249   ""
13251   if (TARGET_SHMEDIA)
13252     {
13253       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13255       if (TARGET_SHMEDIA64)
13256         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13257                                                     operands[1]));
13258       else
13259         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13260                                                     operands[1]));
13262       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13263     }
13264   else
13265     {
13266       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13267       emit_jump_insn (gen_branch_true (operands[2]));
13268     }
13270   DONE;
13273 (define_insn "stack_protect_test_si"
13274   [(set (reg:SI T_REG)
13275         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13276                     (match_operand:SI 1 "memory_operand" "m")]
13277                    UNSPEC_SP_TEST))
13278   (set (match_scratch:SI 2 "=&r") (const_int 0))
13279   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13280   "!TARGET_SHMEDIA"
13281   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13282   [(set_attr "type" "other")
13283    (set_attr "length" "10")])
13285 (define_insn "stack_protect_test_si_media"
13286   [(set (match_operand:SI 0 "register_operand" "=&r")
13287         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13288                     (match_operand:SI 2 "memory_operand" "m")]
13289                    UNSPEC_SP_TEST))
13290   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13291   "TARGET_SHMEDIA"
13292   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13293   [(set_attr "type" "other")
13294    (set_attr "length" "16")])
13296 (define_insn "stack_protect_test_di_media"
13297   [(set (match_operand:DI 0 "register_operand" "=&r")
13298         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13299                     (match_operand:DI 2 "memory_operand" "m")]
13300                    UNSPEC_SP_TEST))
13301   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13302   "TARGET_SHMEDIA64"
13303   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13304   [(set_attr "type" "other")
13305    (set_attr "length" "16")])