2004-08-23 Eric Christopher <echristo@redhat.com>
[official-gcc.git] / gcc / config / sh / sh.md
bloba21a2a4b869790a21fde415e4dddd61e8bc9fc70
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004 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, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, 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)
147   ;; These are used with unspec_volatile.
148   (UNSPECV_BLOCKAGE     0)
149   (UNSPECV_ALIGN        1)
150   (UNSPECV_CONST2       2)
151   (UNSPECV_CONST4       4)
152   (UNSPECV_CONST8       6)
153   (UNSPECV_WINDOW_END   10)
154   (UNSPECV_CONST_END    11)
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
161 ;; Target CPU.
163 (define_attr "cpu"
164  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
165   (const (symbol_ref "sh_cpu_attr")))
167 (define_attr "endian" "big,little"
168  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169                       (const_string "little") (const_string "big"))))
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174                          (const_string "yes") (const_string "no"))))
176 (define_attr "fmovd" "yes,no"
177   (const (if_then_else (symbol_ref "TARGET_FMOVD")
178                        (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181   (const
182    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184          (const_string "sh1"))))
186 ;; cbranch      conditional branch instructions
187 ;; jump         unconditional jumps
188 ;; arith        ordinary arithmetic
189 ;; arith3       a compound insn that behaves similarly to a sequence of
190 ;;              three insns of type arith
191 ;; arith3b      like above, but might end with a redirected branch
192 ;; load         from memory
193 ;; load_si      Likewise, SImode variant for general register.
194 ;; fload        Likewise, but load to fp register.
195 ;; store        to memory
196 ;; move         general purpose register to register
197 ;; mt_group     other sh4 mt instructions
198 ;; fmove        register to register, floating point
199 ;; smpy         word precision integer multiply
200 ;; dmpy         longword or doublelongword precision integer multiply
201 ;; return       rts
202 ;; pload        load of pr reg, which can't be put into delay slot of rts
203 ;; prset        copy register to pr reg, ditto
204 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
205 ;; prget        copy pr to register, ditto
206 ;; pcload       pc relative load of constant value
207 ;; pcfload      Likewise, but load to fp register.
208 ;; pcload_si    Likewise, SImode variant for general register.
209 ;; rte          return from exception
210 ;; sfunc        special function call with known used registers
211 ;; call         function call
212 ;; fp           floating point
213 ;; fdiv         floating point divide (or square root)
214 ;; gp_fpul      move from general purpose register to fpul
215 ;; fpul_gp      move from fpul to general purpose register
216 ;; mac_gp       move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s       fix_truncsfsi2_i4
219 ;; dfdiv        double precision floating point divide (or square root)
220 ;; cwb          ic_invalidate_line_i
221 ;; movua        SH4a unaligned load
222 ;; fsrra        square root reciprocal approximate
223 ;; fsca         sine and cosine approximate
224 ;; tls_load     load TLS related address
225 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media    SHmedia compare instructions
228 ;; dfdiv_media  SHmedia double precision divide and square root
229 ;; dfmul_media  SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media   SHmedia longword multiply
233 ;; fcmp_media   SHmedia floating point compare instructions
234 ;; fdiv_media   SHmedia single precision divide and square root
235 ;; fload_media  SHmedia floating point register load instructions
236 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media  SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media   SHmedia unconditional branch instructions
243 ;; load_media   SHmedia general register load instructions
244 ;; pt_media     SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media  SHmedia ptabs instruction
246 ;; store_media  SHmedia general register store instructions
247 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media    SHmedia mac-style fixed point operations
249 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
250 ;; atrans       SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil          no-op move, will be deleted.
254 (define_attr "type"
255  "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"
256   (const_string "other"))
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
261 ;; mt_group      SH4 "mt" group instructions.
263 ;; ex_group      SH4 "ex" group instructions.
265 ;; ls_group      SH4 "ls" group instructions.
268 (define_attr "insn_class"
269   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273          (eq_attr "type" "cbranch,jump") (const_string "br_group")
274          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275            (const_string "fe_group")
276          (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")]
277         (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
289 ;; state.
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long.  Something in the
296 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
299 ; 2 bytes.
301 ;; The maximum range used for SImode constant pool entries is 1018.  A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table.  That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
318 ;; inside an le.
319 (define_attr "short_cbranch_p" "no,yes"
320   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
321          (const_string "no")
322          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
323          (const_string "yes")
324          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
325          (const_string "no")
326          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
327          (const_string "yes")
328          ] (const_string "no")))
330 (define_attr "med_branch_p" "no,yes"
331   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
332               (const_int 1988))
333          (const_string "yes")
334          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335          (const_string "no")
336          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
337               (const_int 8186))
338          (const_string "yes")
339          ] (const_string "no")))
341 (define_attr "med_cbranch_p" "no,yes"
342   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
343               (const_int 1986))
344          (const_string "yes")
345          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
346          (const_string "no")
347          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
348                (const_int 8184))
349          (const_string "yes")
350          ] (const_string "no")))
352 (define_attr "braf_branch_p" "no,yes"
353   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
356               (const_int 20660))
357          (const_string "yes")
358          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
359          (const_string "no")
360          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
361               (const_int 65530))
362          (const_string "yes")
363          ] (const_string "no")))
365 (define_attr "braf_cbranch_p" "no,yes"
366   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
367          (const_string "no")
368          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
369               (const_int 20658))
370          (const_string "yes")
371          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
372          (const_string "no")
373          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
374               (const_int 65528))
375          (const_string "yes")
376          ] (const_string "no")))
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
385 ; All other instructions are two bytes long by default.
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390   (cond [(eq_attr "type" "cbranch")
391          (cond [(eq_attr "short_cbranch_p" "yes")
392                 (const_int 2)
393                 (eq_attr "med_cbranch_p" "yes")
394                 (const_int 6)
395                 (eq_attr "braf_cbranch_p" "yes")
396                 (const_int 12)
397 ;; ??? using pc is not computed transitively.
398                 (ne (match_dup 0) (match_dup 0))
399                 (const_int 14)
400                 (ne (symbol_ref ("flag_pic")) (const_int 0))
401                 (const_int 24)
402                 ] (const_int 16))
403          (eq_attr "type" "jump")
404          (cond [(eq_attr "med_branch_p" "yes")
405                 (const_int 2)
406                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
407                          (symbol_ref "INSN"))
408                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409                          (symbol_ref "code_for_indirect_jump_scratch")))
410                 (if_then_else (eq_attr "braf_branch_p" "yes")
411                               (const_int 6)
412                               (const_int 10))
413                 (eq_attr "braf_branch_p" "yes")
414                 (const_int 10)
415 ;; ??? using pc is not computed transitively.
416                 (ne (match_dup 0) (match_dup 0))
417                 (const_int 12)
418                 (ne (symbol_ref ("flag_pic")) (const_int 0))
419                 (const_int 22)
420                 ] (const_int 14))
421          (eq_attr "type" "pt_media")
422          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
423                        (const_int 20) (const_int 12))
424          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
425                          (const_int 4)
426                          (const_int 2))))
428 ;; DFA descriptions for the pipelines
430 (include "sh1.md")
431 (include "shmedia.md")
432 (include "sh4.md")
434 ;; Definitions for filling delay slots
436 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
438 ;; ??? This should be (nil) instead of (const_int 0)
439 (define_attr "hit_stack" "yes,no"
440         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
441                    (const_int 0))
442                (const_string "no")]
443               (const_string "yes")))
445 (define_attr "interrupt_function" "no,yes"
446   (const (symbol_ref "current_function_interrupt")))
448 (define_attr "in_delay_slot" "yes,no"
449   (cond [(eq_attr "type" "cbranch") (const_string "no")
450          (eq_attr "type" "pcload,pcload_si") (const_string "no")
451          (eq_attr "needs_delay_slot" "yes") (const_string "no")
452          (eq_attr "length" "2") (const_string "yes")
453          ] (const_string "no")))
455 (define_attr "cond_delay_slot" "yes,no"
456   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
457          ] (const_string "no")))
459 (define_attr "is_sfunc" ""
460   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
462 (define_attr "is_mac_media" ""
463   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
465 (define_attr "branch_zero" "yes,no"
466   (cond [(eq_attr "type" "!cbranch") (const_string "no")
467          (ne (symbol_ref "(next_active_insn (insn)\
468                            == (prev_active_insn\
469                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
470                           && get_attr_length (next_active_insn (insn)) == 2")
471              (const_int 0))
472          (const_string "yes")]
473         (const_string "no")))
475 ;; SH4 Double-precision computation with double-precision result -
476 ;; the two halves are ready at different times.
477 (define_attr "dfp_comp" "yes,no"
478   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
479         (const_string "no")))
481 ;; Insns for which the latency of a preceding fp insn is decreased by one.
482 (define_attr "late_fp_use" "yes,no" (const_string "no"))
483 ;; And feeding insns for which this relevant.
484 (define_attr "any_fp_comp" "yes,no"
485   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
486          (const_string "yes")]
487         (const_string "no")))
489 (define_attr "any_int_load" "yes,no"
490   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
491          (const_string "yes")]
492         (const_string "no")))
494 (define_delay
495   (eq_attr "needs_delay_slot" "yes")
496   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
498 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
499 ;; and thus we can't put a pop instruction in its delay slot.
500 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
501 ;; instruction can go in the delay slot.
503 ;; Since a normal return (rts) implicitly uses the PR register,
504 ;; we can't allow PR register loads in an rts delay slot.
506 (define_delay
507   (eq_attr "type" "return")
508   [(and (eq_attr "in_delay_slot" "yes")
509         (ior (and (eq_attr "interrupt_function" "no")
510                   (eq_attr "type" "!pload,prset"))
511              (and (eq_attr "interrupt_function" "yes")
512                   (ior
513                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
514                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
516 ;; Since a call implicitly uses the PR register, we can't allow
517 ;; a PR register store in a jsr delay slot.
519 (define_delay
520   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
521   [(and (eq_attr "in_delay_slot" "yes")
522         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
524 ;; Say that we have annulled true branches, since this gives smaller and
525 ;; faster code when branches are predicted as not taken.
527 ;; ??? The non-annulled condition should really be "in_delay_slot",
528 ;; but insns that can be filled in non-annulled get priority over insns
529 ;; that can only be filled in anulled.
531 (define_delay
532   (and (eq_attr "type" "cbranch")
533        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
534   ;; SH2e has a hardware bug that pretty much prohibits the use of
535   ;; annuled delay slots.
536   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
537                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
539 ;; -------------------------------------------------------------------------
540 ;; SImode signed integer comparisons
541 ;; -------------------------------------------------------------------------
543 (define_insn ""
544   [(set (reg:SI T_REG)
545         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
546                        (match_operand:SI 1 "arith_operand" "K08,r"))
547                (const_int 0)))]
548   "TARGET_SH1"
549   "tst  %1,%0"
550   [(set_attr "type" "mt_group")])
552 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
553 ;; That would still allow reload to create cmpi instructions, but would
554 ;; perhaps allow forcing the constant into a register when that is better.
555 ;; Probably should use r0 for mem/imm compares, but force constant into a
556 ;; register for pseudo/imm compares.
558 (define_insn "cmpeqsi_t"
559   [(set (reg:SI T_REG)
560         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
561                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
562   "TARGET_SH1"
563   "@
564         tst     %0,%0
565         cmp/eq  %1,%0
566         cmp/eq  %1,%0"
567    [(set_attr "type" "mt_group")])
569 (define_insn "cmpgtsi_t"
570   [(set (reg:SI T_REG)
571         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
572                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
573   "TARGET_SH1"
574   "@
575         cmp/gt  %1,%0
576         cmp/pl  %0"
577    [(set_attr "type" "mt_group")])
579 (define_insn "cmpgesi_t"
580   [(set (reg:SI T_REG)
581         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
582                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
583   "TARGET_SH1"
584   "@
585         cmp/ge  %1,%0
586         cmp/pz  %0"
587    [(set_attr "type" "mt_group")])
589 ;; -------------------------------------------------------------------------
590 ;; SImode unsigned integer comparisons
591 ;; -------------------------------------------------------------------------
593 (define_insn "cmpgeusi_t"
594   [(set (reg:SI T_REG)
595         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
596                 (match_operand:SI 1 "arith_reg_operand" "r")))]
597   "TARGET_SH1"
598   "cmp/hs       %1,%0"
599    [(set_attr "type" "mt_group")])
601 (define_insn "cmpgtusi_t"
602   [(set (reg:SI T_REG)
603         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
604                 (match_operand:SI 1 "arith_reg_operand" "r")))]
605   "TARGET_SH1"
606   "cmp/hi       %1,%0"
607    [(set_attr "type" "mt_group")])
609 ;; We save the compare operands in the cmpxx patterns and use them when
610 ;; we generate the branch.
612 (define_expand "cmpsi"
613   [(set (reg:SI T_REG)
614         (compare (match_operand:SI 0 "cmpsi_operand" "")
615                  (match_operand:SI 1 "arith_operand" "")))]
616   "TARGET_SH1"
617   "
619   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
620       && GET_CODE (operands[1]) != CONST_INT)
621     operands[0] = copy_to_mode_reg (SImode, operands[0]);
622   sh_compare_op0 = operands[0];
623   sh_compare_op1 = operands[1];
624   DONE;
627 ;; -------------------------------------------------------------------------
628 ;; DImode signed integer comparisons
629 ;; -------------------------------------------------------------------------
631 ;; ??? Could get better scheduling by splitting the initial test from the
632 ;; rest of the insn after reload.  However, the gain would hardly justify
633 ;; the sh.md size increase necessary to do that.
635 (define_insn ""
636   [(set (reg:SI T_REG)
637         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
638                        (match_operand:DI 1 "arith_operand" "r"))
639                (const_int 0)))]
640   "TARGET_SH1"
641   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
642                                  insn, operands);"
643   [(set_attr "length" "6")
644    (set_attr "type" "arith3b")])
646 (define_insn "cmpeqdi_t"
647   [(set (reg:SI T_REG)
648         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
649                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
650   "TARGET_SH1"
651   "@
652         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
653         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
654   [(set_attr "length" "6")
655    (set_attr "type" "arith3b")])
657 (define_split
658   [(set (reg:SI T_REG)
659         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
660                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
661 ;; If we applied this split when not optimizing, it would only be
662 ;; applied during the machine-dependent reorg, when no new basic blocks
663 ;; may be created.
664   "TARGET_SH1 && reload_completed && optimize"
665   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
666    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
667                            (label_ref (match_dup 6))
668                            (pc)))
669    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
670    (match_dup 6)]
671   "
673   operands[2]
674     = gen_rtx_REG (SImode,
675                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
676   operands[3]
677     = (operands[1] == const0_rtx
678        ? const0_rtx
679        : gen_rtx_REG (SImode,
680                       true_regnum (operands[1])
681                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
682   operands[4] = gen_lowpart (SImode, operands[0]);
683   operands[5] = gen_lowpart (SImode, operands[1]);
684   operands[6] = gen_label_rtx ();
687 (define_insn "cmpgtdi_t"
688   [(set (reg:SI T_REG)
689         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
690                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
691   "TARGET_SH2"
692   "@
693         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
694         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
695   [(set_attr "length" "8")
696    (set_attr "type" "arith3")])
698 (define_insn "cmpgedi_t"
699   [(set (reg:SI T_REG)
700         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
701                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
702   "TARGET_SH2"
703   "@
704         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
705         cmp/pz\\t%S0"
706   [(set_attr "length" "8,2")
707    (set_attr "type" "arith3,mt_group")])
709 ;; -------------------------------------------------------------------------
710 ;; DImode unsigned integer comparisons
711 ;; -------------------------------------------------------------------------
713 (define_insn "cmpgeudi_t"
714   [(set (reg:SI T_REG)
715         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
716                 (match_operand:DI 1 "arith_reg_operand" "r")))]
717   "TARGET_SH2"
718   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
719   [(set_attr "length" "8")
720    (set_attr "type" "arith3")])
722 (define_insn "cmpgtudi_t"
723   [(set (reg:SI T_REG)
724         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
725                 (match_operand:DI 1 "arith_reg_operand" "r")))]
726   "TARGET_SH2"
727   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
728   [(set_attr "length" "8")
729    (set_attr "type" "arith3")])
731 (define_insn "cmpeqdi_media"
732   [(set (match_operand:DI 0 "register_operand" "=r")
733         (eq:DI (match_operand:DI 1 "register_operand" "%r")
734                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
735   "TARGET_SHMEDIA"
736   "cmpeq        %1, %N2, %0"
737   [(set_attr "type" "cmp_media")])
739 (define_insn "cmpgtdi_media"
740   [(set (match_operand:DI 0 "register_operand" "=r")
741         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
742                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
743   "TARGET_SHMEDIA"
744   "cmpgt        %N1, %N2, %0"
745   [(set_attr "type" "cmp_media")])
747 (define_insn "cmpgtudi_media"
748   [(set (match_operand:DI 0 "register_operand" "=r")
749         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
750                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
751   "TARGET_SHMEDIA"
752   "cmpgtu       %N1, %N2, %0"
753   [(set_attr "type" "cmp_media")])
755 ;; We save the compare operands in the cmpxx patterns and use them when
756 ;; we generate the branch.
758 (define_expand "cmpdi"
759   [(set (reg:SI T_REG)
760         (compare (match_operand:DI 0 "arith_operand" "")
761                  (match_operand:DI 1 "arith_operand" "")))]
762   "TARGET_SH2 || TARGET_SHMEDIA"
763   "
765   sh_compare_op0 = operands[0];
766   sh_compare_op1 = operands[1];
767   DONE;
769 ;; -------------------------------------------------------------------------
770 ;; Conditional move instructions
771 ;; -------------------------------------------------------------------------
773 ;; The insn names may seem reversed, but note that cmveq performs the move
774 ;; if op1 == 0, and cmvne does it if op1 != 0.
776 (define_insn "movdicc_false"
777   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
778         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
779                              (const_int 0))
780          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
781          (match_operand:DI 3 "arith_reg_operand" "0")))]
782   "TARGET_SHMEDIA"
783   "cmveq        %1, %N2, %0"
784   [(set_attr "type" "arith_media")])
786 (define_insn "movdicc_true"
787   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
788         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
789                              (const_int 0))
790          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
791          (match_operand:DI 3 "arith_reg_operand" "0")))]
792   "TARGET_SHMEDIA"
793   "cmvne        %1, %N2, %0"
794   [(set_attr "type" "arith_media")])
796 (define_expand "movdicc"
797   [(set (match_operand:DI 0 "register_operand" "")
798         (if_then_else:DI (match_operand 1 "comparison_operator" "")
799                          (match_operand:DI 2 "register_operand" "")
800                          (match_operand:DI 3 "register_operand" "")))]
801   "TARGET_SHMEDIA"
802   "
804   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
805       && GET_MODE (sh_compare_op0) == DImode
806       && sh_compare_op1 == const0_rtx)
807     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
808                                   sh_compare_op0, sh_compare_op1);
809   else
810     {
811       rtx tmp;
813       if (no_new_pseudos)
814         FAIL;
816       tmp = gen_reg_rtx (DImode);
818       switch (GET_CODE (operands[1]))
819         {
820         case EQ:
821           emit_insn (gen_seq (tmp));
822           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
823           break;
825         case NE:
826           emit_insn (gen_seq (tmp));
827           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
828           break;
830         case GT:
831           emit_insn (gen_sgt (tmp));
832           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
833           break;
835         case LT:
836           emit_insn (gen_slt (tmp));
837           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
838           break;
840         case GE:
841           emit_insn (gen_slt (tmp));
842           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
843           break;
845         case LE:
846           emit_insn (gen_sgt (tmp));
847           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
848           break;
850         case GTU:
851           emit_insn (gen_sgtu (tmp));
852           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
853           break;
855         case LTU:
856           emit_insn (gen_sltu (tmp));
857           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
858           break;
860         case GEU:
861           emit_insn (gen_sltu (tmp));
862           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
863           break;
865         case LEU:
866           emit_insn (gen_sgtu (tmp));
867           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
868           break;
870         case UNORDERED:
871           emit_insn (gen_sunordered (tmp));
872           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
873           break;
875         case ORDERED:
876           emit_insn (gen_sunordered (tmp));
877           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
878           break;
880         case UNEQ:
881         case UNGE:
882         case UNGT:
883         case UNLE:
884         case UNLT:
885         case LTGT:
886           FAIL;
888         default:
889           abort ();
890         }
891     }
894 ;; -------------------------------------------------------------------------
895 ;; Addition instructions
896 ;; -------------------------------------------------------------------------
898 (define_expand "adddi3"
899   [(set (match_operand:DI 0 "arith_reg_operand" "")
900         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
901                  (match_operand:DI 2 "arith_operand" "")))]
902   ""
903   "
905   if (TARGET_SH1)
906     {
907       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
908         FAIL;
909       operands[2] = force_reg (DImode, operands[2]);
910       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
911       DONE;
912     }
915 (define_insn "*adddi3_media"
916   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
917         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
918                  (match_operand:DI 2 "arith_operand" "r,I10")))]
919   "TARGET_SHMEDIA"
920   "@
921         add     %1, %2, %0
922         addi    %1, %2, %0"
923   [(set_attr "type" "arith_media")])
925 (define_insn "adddi3z_media"
926   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
927         (zero_extend:DI
928          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
929                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
930   "TARGET_SHMEDIA"
931   "addz.l       %1, %N2, %0"
932   [(set_attr "type" "arith_media")])
934 (define_insn "adddi3_compact"
935   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
936         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
937                  (match_operand:DI 2 "arith_reg_operand" "r")))
938    (clobber (reg:SI T_REG))]
939   "TARGET_SH1"
940   "#"
941   [(set_attr "length" "6")])
943 (define_split
944   [(set (match_operand:DI 0 "arith_reg_operand" "")
945         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
946                  (match_operand:DI 2 "arith_reg_operand" "")))
947    (clobber (reg:SI T_REG))]
948   "TARGET_SH1 && reload_completed"
949   [(const_int 0)]
950   "
952   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
953   high0 = gen_rtx_REG (SImode,
954                        true_regnum (operands[0])
955                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
956   high2 = gen_rtx_REG (SImode,
957                        true_regnum (operands[2])
958                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
959   emit_insn (gen_clrt ());
960   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
961   emit_insn (gen_addc1 (high0, high0, high2));
962   DONE;
965 (define_insn "addc"
966   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
967         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
968                           (match_operand:SI 2 "arith_reg_operand" "r"))
969                  (reg:SI T_REG)))
970    (set (reg:SI T_REG)
971         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
972   "TARGET_SH1"
973   "addc %2,%0"
974   [(set_attr "type" "arith")])
976 (define_insn "addc1"
977   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
978         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
979                           (match_operand:SI 2 "arith_reg_operand" "r"))
980                  (reg:SI T_REG)))
981    (clobber (reg:SI T_REG))]
982   "TARGET_SH1"
983   "addc %2,%0"
984   [(set_attr "type" "arith")])
986 (define_expand "addsi3"
987   [(set (match_operand:SI 0 "arith_reg_operand" "")
988         (plus:SI (match_operand:SI 1 "arith_operand" "")
989                  (match_operand:SI 2 "arith_operand" "")))]
990   ""
991   "
993   if (TARGET_SHMEDIA)
994     operands[1] = force_reg (SImode, operands[1]);
997 (define_insn "addsi3_media"
998   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
999         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1000                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1001   "TARGET_SHMEDIA"
1002   "@
1003         add.l   %1, %2, %0
1004         addi.l  %1, %2, %0"
1005   [(set_attr "type" "arith_media")])
1007 (define_insn "*addsi3_compact"
1008   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1009         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1010                  (match_operand:SI 2 "arith_operand" "rI08")))]
1011   "TARGET_SH1"
1012   "add  %2,%0"
1013   [(set_attr "type" "arith")])
1015 ;; -------------------------------------------------------------------------
1016 ;; Subtraction instructions
1017 ;; -------------------------------------------------------------------------
1019 (define_expand "subdi3"
1020   [(set (match_operand:DI 0 "arith_reg_operand" "")
1021         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1022                   (match_operand:DI 2 "arith_reg_operand" "")))]
1023   ""
1024   "
1026   if (TARGET_SH1)
1027     {
1028       operands[1] = force_reg (DImode, operands[1]);
1029       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1030       DONE;
1031     }
1034 (define_insn "*subdi3_media"
1035   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1036         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1037                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1038   "TARGET_SHMEDIA"
1039   "sub  %N1, %2, %0"
1040   [(set_attr "type" "arith_media")])
1042 (define_insn "subdi3_compact"
1043   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1044         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1045                  (match_operand:DI 2 "arith_reg_operand" "r")))
1046    (clobber (reg:SI T_REG))]
1047   "TARGET_SH1"
1048   "#"
1049   [(set_attr "length" "6")])
1051 (define_split
1052   [(set (match_operand:DI 0 "arith_reg_operand" "")
1053         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1054                   (match_operand:DI 2 "arith_reg_operand" "")))
1055    (clobber (reg:SI T_REG))]
1056   "TARGET_SH1 && reload_completed"
1057   [(const_int 0)]
1058   "
1060   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1061   high0 = gen_rtx_REG (SImode,
1062                        true_regnum (operands[0])
1063                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1064   high2 = gen_rtx_REG (SImode,
1065                        true_regnum (operands[2])
1066                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1067   emit_insn (gen_clrt ());
1068   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1069   emit_insn (gen_subc1 (high0, high0, high2));
1070   DONE;
1073 (define_insn "subc"
1074   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1075         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1076                             (match_operand:SI 2 "arith_reg_operand" "r"))
1077                   (reg:SI T_REG)))
1078    (set (reg:SI T_REG)
1079         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1080                           (reg:SI T_REG))
1081                 (match_dup 1)))]
1082   "TARGET_SH1"
1083   "subc %2,%0"
1084   [(set_attr "type" "arith")])
1086 (define_insn "subc1"
1087   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1088         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1089                             (match_operand:SI 2 "arith_reg_operand" "r"))
1090                   (reg:SI T_REG)))
1091    (clobber (reg:SI T_REG))]
1092   "TARGET_SH1"
1093   "subc %2,%0"
1094   [(set_attr "type" "arith")])
1096 (define_insn "*subsi3_internal"
1097   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1098         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1099                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1100   "TARGET_SH1"
1101   "sub  %2,%0"
1102   [(set_attr "type" "arith")])
1104 (define_insn "*subsi3_media"
1105   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1106         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1107                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1108   "TARGET_SHMEDIA"
1109   "sub.l        %N1, %2, %0"
1110   [(set_attr "type" "arith_media")])
1112 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1113 ;; will sometimes save one instruction.  Otherwise we might get
1114 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1115 ;; are the same.
1117 (define_expand "subsi3"
1118   [(set (match_operand:SI 0 "arith_reg_operand" "")
1119         (minus:SI (match_operand:SI 1 "arith_operand" "")
1120                   (match_operand:SI 2 "arith_reg_operand" "")))]
1121   ""
1122   "
1124   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1125     {
1126       emit_insn (gen_negsi2 (operands[0], operands[2]));
1127       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1128       DONE;
1129     }
1130   if (TARGET_SHMEDIA)
1131     {
1132       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1133         FAIL;
1134       if (operands[1] != const0_rtx)
1135         operands[1] = force_reg (SImode, operands[1]);
1136     }
1139 ;; -------------------------------------------------------------------------
1140 ;; Division instructions
1141 ;; -------------------------------------------------------------------------
1143 ;; We take advantage of the library routines which don't clobber as many
1144 ;; registers as a normal function call would.
1146 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1147 ;; also has an effect on the register that holds the address of the sfunc.
1148 ;; To make this work, we have an extra dummy insn that shows the use
1149 ;; of this register for reorg.
1151 (define_insn "use_sfunc_addr"
1152   [(set (reg:SI PR_REG)
1153         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1154   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1155   ""
1156   [(set_attr "length" "0")])
1158 (define_insn "udivsi3_sh2a"
1159   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1160         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1161                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1162   "TARGET_SH2A"
1163   "divu %2,%1"
1164   [(set_attr "type" "arith")])
1166 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1167 ;; hard register 0.  If we used hard register 0, then the next instruction
1168 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1169 ;; gets allocated to a stack slot that needs its address reloaded, then
1170 ;; there is nothing to prevent reload from using r0 to reload the address.
1171 ;; This reload would clobber the value in r0 we are trying to store.
1172 ;; If we let reload allocate r0, then this problem can never happen.
1174 (define_insn "udivsi3_i1"
1175   [(set (match_operand:SI 0 "register_operand" "=z")
1176         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1177    (clobber (reg:SI T_REG))
1178    (clobber (reg:SI PR_REG))
1179    (clobber (reg:SI R4_REG))
1180    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1181   "TARGET_SH1 && ! TARGET_SH4"
1182   "jsr  @%1%#"
1183   [(set_attr "type" "sfunc")
1184    (set_attr "needs_delay_slot" "yes")])
1186 ; Since shmedia-nofpu code could be linked against shcompact code, and
1187 ; the udivsi3 libcall has the same name, we must consider all registers
1188 ; clobbered that are in the union of the registers clobbered by the
1189 ; shmedia and the shcompact implementation.  Note, if the shcompact
1190 ; implementation actually used shcompact code, we'd need to clobber
1191 ; also r23 and fr23.
1192 (define_insn "udivsi3_i1_media"
1193   [(set (match_operand:SI 0 "register_operand" "=z")
1194         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1195    (clobber (reg:SI T_MEDIA_REG))
1196    (clobber (reg:SI PR_MEDIA_REG))
1197    (clobber (reg:SI R20_REG))
1198    (clobber (reg:SI R21_REG))
1199    (clobber (reg:SI R22_REG))
1200    (clobber (reg:DI TR0_REG))
1201    (clobber (reg:DI TR1_REG))
1202    (clobber (reg:DI TR2_REG))
1203    (use (match_operand:DI 1 "target_operand" "b"))]
1204   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1205   "blink        %1, r18"
1206   [(set_attr "type" "sfunc")
1207    (set_attr "needs_delay_slot" "yes")])
1209 (define_expand "udivsi3_i4_media"
1210   [(set (match_dup 3)
1211         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1212    (set (match_dup 4)
1213         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1214    (set (match_dup 5) (float:DF (match_dup 3)))
1215    (set (match_dup 6) (float:DF (match_dup 4)))
1216    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1217    (set (match_dup 8) (fix:DI (match_dup 7)))
1218    (set (match_operand:SI 0 "register_operand" "")
1219         (truncate:SI (match_dup 8)))]
1220   "TARGET_SHMEDIA_FPU"
1221   "
1223   operands[3] = gen_reg_rtx (DImode);
1224   operands[4] = gen_reg_rtx (DImode);
1225   operands[5] = gen_reg_rtx (DFmode);
1226   operands[6] = gen_reg_rtx (DFmode);
1227   operands[7] = gen_reg_rtx (DFmode);
1228   operands[8] = gen_reg_rtx (DImode);
1231 (define_insn "udivsi3_i4"
1232   [(set (match_operand:SI 0 "register_operand" "=y")
1233         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1234    (clobber (reg:SI T_REG))
1235    (clobber (reg:SI PR_REG))
1236    (clobber (reg:DF DR0_REG))
1237    (clobber (reg:DF DR2_REG))
1238    (clobber (reg:DF DR4_REG))
1239    (clobber (reg:SI R0_REG))
1240    (clobber (reg:SI R1_REG))
1241    (clobber (reg:SI R4_REG))
1242    (clobber (reg:SI R5_REG))
1243    (use (reg:PSI FPSCR_REG))
1244    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1245   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1246   "jsr  @%1%#"
1247   [(set_attr "type" "sfunc")
1248    (set_attr "fp_mode" "double")
1249    (set_attr "needs_delay_slot" "yes")])
1251 (define_insn "udivsi3_i4_single"
1252   [(set (match_operand:SI 0 "register_operand" "=y")
1253         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1254    (clobber (reg:SI T_REG))
1255    (clobber (reg:SI PR_REG))
1256    (clobber (reg:DF DR0_REG))
1257    (clobber (reg:DF DR2_REG))
1258    (clobber (reg:DF DR4_REG))
1259    (clobber (reg:SI R0_REG))
1260    (clobber (reg:SI R1_REG))
1261    (clobber (reg:SI R4_REG))
1262    (clobber (reg:SI R5_REG))
1263    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1264   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1265   "jsr  @%1%#"
1266   [(set_attr "type" "sfunc")
1267    (set_attr "needs_delay_slot" "yes")])
1269 (define_expand "udivsi3"
1270   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1271    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1272    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1273    (parallel [(set (match_operand:SI 0 "register_operand" "")
1274                    (udiv:SI (reg:SI R4_REG)
1275                             (reg:SI R5_REG)))
1276               (clobber (reg:SI T_REG))
1277               (clobber (reg:SI PR_REG))
1278               (clobber (reg:SI R4_REG))
1279               (use (match_dup 3))])]
1280   ""
1281   "
1283   rtx first, last;
1285   operands[3] = gen_reg_rtx (Pmode);
1286   /* Emit the move of the address to a pseudo outside of the libcall.  */
1287   if (TARGET_HARD_SH4 && TARGET_SH2E)
1288     {
1289       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1290       if (TARGET_FPU_SINGLE)
1291         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1292       else
1293         last = gen_udivsi3_i4 (operands[0], operands[3]);
1294     }
1295   else if (TARGET_SHMEDIA_FPU)
1296     {
1297       operands[1] = force_reg (SImode, operands[1]);
1298       operands[2] = force_reg (SImode, operands[2]);
1299       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1300       DONE;
1301     }
1302   else if (TARGET_SH2A)
1303     {
1304       operands[1] = force_reg (SImode, operands[1]);
1305       operands[2] = force_reg (SImode, operands[2]);
1306       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1307       DONE;
1308     }
1309   else if (TARGET_SH5)
1310     {
1311       emit_move_insn (operands[3],
1312                       function_symbol (TARGET_FPU_ANY
1313                                        ? \"__udivsi3_i4\"
1314                                        : \"__udivsi3\"));
1316       if (TARGET_SHMEDIA)
1317         last = gen_udivsi3_i1_media (operands[0],
1318                                      Pmode == DImode
1319                                      ? operands[3]
1320                                      : gen_rtx_SUBREG (DImode, operands[3],
1321                                                        0));
1322       else if (TARGET_FPU_ANY)
1323         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1324       else
1325         last = gen_udivsi3_i1 (operands[0], operands[3]);
1326     }
1327   else
1328     {
1329       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1330       last = gen_udivsi3_i1 (operands[0], operands[3]);
1331     }
1332   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1333   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1334   last = emit_insn (last);
1335   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1336      invariant code motion can move it.  */
1337   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1338   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1339   DONE;
1342 (define_insn "divsi3_sh2a"
1343   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1344         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1345                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1346   "TARGET_SH2A"
1347   "divs %2,%1"
1348   [(set_attr "type" "arith")])
1350 (define_insn "divsi3_i1"
1351   [(set (match_operand:SI 0 "register_operand" "=z")
1352         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1353    (clobber (reg:SI T_REG))
1354    (clobber (reg:SI PR_REG))
1355    (clobber (reg:SI R1_REG))
1356    (clobber (reg:SI R2_REG))
1357    (clobber (reg:SI R3_REG))
1358    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1359   "TARGET_SH1 && ! TARGET_SH4"
1360   "jsr  @%1%#"
1361   [(set_attr "type" "sfunc")
1362    (set_attr "needs_delay_slot" "yes")])
1364 ; Since shmedia-nofpu code could be linked against shcompact code, and
1365 ; the sdivsi3 libcall has the same name, we must consider all registers
1366 ; clobbered that are in the union of the registers clobbered by the
1367 ; shmedia and the shcompact implementation.  Note, if the shcompact
1368 ; implementation actually used shcompact code, we'd need to clobber
1369 ; also r22, r23 and fr23.
1370 (define_insn "divsi3_i1_media"
1371   [(set (match_operand:SI 0 "register_operand" "=z")
1372         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1373    (clobber (reg:SI T_MEDIA_REG))
1374    (clobber (reg:SI PR_MEDIA_REG))
1375    (clobber (reg:SI R1_REG))
1376    (clobber (reg:SI R2_REG))
1377    (clobber (reg:SI R3_REG))
1378    (clobber (reg:SI R20_REG))
1379    (clobber (reg:SI R21_REG))
1380    (clobber (reg:DI TR0_REG))
1381    (clobber (reg:DI TR1_REG))
1382    (clobber (reg:DI TR2_REG))
1383    (use (match_operand:DI 1 "target_operand" "b"))]
1384   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1385   "blink        %1, r18"
1386   [(set_attr "type" "sfunc")])
1388 (define_expand "divsi3_i4_media"
1389   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1390    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1391    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1392    (set (match_operand:SI 0 "register_operand" "=r")
1393         (fix:SI (match_dup 5)))]
1394   "TARGET_SHMEDIA_FPU"
1395   "
1397   operands[3] = gen_reg_rtx (DFmode);
1398   operands[4] = gen_reg_rtx (DFmode);
1399   operands[5] = gen_reg_rtx (DFmode);
1402 (define_insn "divsi3_i4"
1403   [(set (match_operand:SI 0 "register_operand" "=y")
1404         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1405    (clobber (reg:SI PR_REG))
1406    (clobber (reg:DF DR0_REG))
1407    (clobber (reg:DF DR2_REG))
1408    (use (reg:PSI FPSCR_REG))
1409    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1410   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1411   "jsr  @%1%#"
1412   [(set_attr "type" "sfunc")
1413    (set_attr "fp_mode" "double")
1414    (set_attr "needs_delay_slot" "yes")])
1416 (define_insn "divsi3_i4_single"
1417   [(set (match_operand:SI 0 "register_operand" "=y")
1418         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1419    (clobber (reg:SI PR_REG))
1420    (clobber (reg:DF DR0_REG))
1421    (clobber (reg:DF DR2_REG))
1422    (clobber (reg:SI R2_REG))
1423    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1424   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1425   "jsr  @%1%#"
1426   [(set_attr "type" "sfunc")
1427    (set_attr "needs_delay_slot" "yes")])
1429 (define_expand "divsi3"
1430   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1431    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1432    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1433    (parallel [(set (match_operand:SI 0 "register_operand" "")
1434                    (div:SI (reg:SI R4_REG)
1435                            (reg:SI R5_REG)))
1436               (clobber (reg:SI T_REG))
1437               (clobber (reg:SI PR_REG))
1438               (clobber (reg:SI R1_REG))
1439               (clobber (reg:SI R2_REG))
1440               (clobber (reg:SI R3_REG))
1441               (use (match_dup 3))])]
1442   ""
1443   "
1445   rtx first, last;
1447   operands[3] = gen_reg_rtx (Pmode);
1448   /* Emit the move of the address to a pseudo outside of the libcall.  */
1449   if (TARGET_HARD_SH4 && TARGET_SH2E)
1450     {
1451       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1452       if (TARGET_FPU_SINGLE)
1453         last = gen_divsi3_i4_single (operands[0], operands[3]);
1454       else
1455         last = gen_divsi3_i4 (operands[0], operands[3]);
1456     }
1457   else if (TARGET_SH2A)
1458     {
1459       operands[1] = force_reg (SImode, operands[1]);
1460       operands[2] = force_reg (SImode, operands[2]);
1461       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1462       DONE;
1463     }
1464   else if (TARGET_SHMEDIA_FPU)
1465     {
1466       operands[1] = force_reg (SImode, operands[1]);
1467       operands[2] = force_reg (SImode, operands[2]);
1468       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1469       DONE;
1470     }
1471   else if (TARGET_SH5)
1472     {
1473       emit_move_insn (operands[3],
1474                       function_symbol (TARGET_FPU_ANY
1475                                        ? \"__sdivsi3_i4\"
1476                                        : \"__sdivsi3\"));
1478       if (TARGET_SHMEDIA)
1479         last = gen_divsi3_i1_media (operands[0],
1480                                     Pmode == DImode
1481                                     ? operands[3]
1482                                     : gen_rtx_SUBREG (DImode, operands[3],
1483                                                       0));
1484       else if (TARGET_FPU_ANY)
1485         last = gen_divsi3_i4_single (operands[0], operands[3]);
1486       else
1487         last = gen_divsi3_i1 (operands[0], operands[3]);
1488     }
1489   else
1490     {
1491       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1492       last = gen_divsi3_i1 (operands[0], operands[3]);
1493     }
1494   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1495   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1496   last = emit_insn (last);
1497   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1498      invariant code motion can move it.  */
1499   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1500   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1501   DONE;
1504 ;; -------------------------------------------------------------------------
1505 ;; Multiplication instructions
1506 ;; -------------------------------------------------------------------------
1508 (define_insn "umulhisi3_i"
1509   [(set (reg:SI MACL_REG)
1510         (mult:SI (zero_extend:SI
1511                   (match_operand:HI 0 "arith_reg_operand" "r"))
1512                  (zero_extend:SI
1513                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1514   "TARGET_SH1"
1515   "mulu.w       %1,%0"
1516   [(set_attr "type" "smpy")])
1518 (define_insn "mulhisi3_i"
1519   [(set (reg:SI MACL_REG)
1520         (mult:SI (sign_extend:SI
1521                   (match_operand:HI 0 "arith_reg_operand" "r"))
1522                  (sign_extend:SI
1523                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1524   "TARGET_SH1"
1525   "muls.w       %1,%0"
1526   [(set_attr "type" "smpy")])
1528 (define_expand "mulhisi3"
1529   [(set (reg:SI MACL_REG)
1530         (mult:SI (sign_extend:SI
1531                   (match_operand:HI 1 "arith_reg_operand" ""))
1532                  (sign_extend:SI
1533                   (match_operand:HI 2 "arith_reg_operand" ""))))
1534    (set (match_operand:SI 0 "arith_reg_operand" "")
1535         (reg:SI MACL_REG))]
1536   "TARGET_SH1"
1537   "
1539   rtx first, last;
1541   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1542   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1543   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1544      invariant code motion can move it.  */
1545   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1546   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1547   /* expand_binop can't find a suitable code in umul_widen_optab to
1548      make a REG_EQUAL note from, so make one here.
1549      See also smulsi3_highpart.
1550      ??? Alternatively, we could put this at the calling site of expand_binop,
1551      i.e. expand_expr.  */
1552   REG_NOTES (last)
1553     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1554                          REG_NOTES (last));
1555   DONE;
1558 (define_expand "umulhisi3"
1559   [(set (reg:SI MACL_REG)
1560         (mult:SI (zero_extend:SI
1561                   (match_operand:HI 1 "arith_reg_operand" ""))
1562                  (zero_extend:SI
1563                   (match_operand:HI 2 "arith_reg_operand" ""))))
1564    (set (match_operand:SI 0 "arith_reg_operand" "")
1565         (reg:SI MACL_REG))]
1566   "TARGET_SH1"
1567   "
1569   rtx first, last;
1571   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1572   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1573   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1574      invariant code motion can move it.  */
1575   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1576   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1577   /* expand_binop can't find a suitable code in umul_widen_optab to
1578      make a REG_EQUAL note from, so make one here.
1579      See also smulsi3_highpart.
1580      ??? Alternatively, we could put this at the calling site of expand_binop,
1581      i.e. expand_expr.  */
1582   REG_NOTES (last)
1583     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1584                          REG_NOTES (last));
1585   DONE;
1588 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1589 ;; a call to a routine which clobbers known registers.
1591 (define_insn ""
1592   [(set (match_operand:SI 1 "register_operand" "=z")
1593         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1594    (clobber (reg:SI MACL_REG))
1595    (clobber (reg:SI T_REG))
1596    (clobber (reg:SI PR_REG))
1597    (clobber (reg:SI R3_REG))
1598    (clobber (reg:SI R2_REG))
1599    (clobber (reg:SI R1_REG))
1600    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1601   "TARGET_SH1"
1602   "jsr  @%0%#"
1603   [(set_attr "type" "sfunc")
1604    (set_attr "needs_delay_slot" "yes")])
1606 (define_expand "mulsi3_call"
1607   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1608    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1609    (parallel[(set (match_operand:SI 0 "register_operand" "")
1610                   (mult:SI (reg:SI R4_REG)
1611                            (reg:SI R5_REG)))
1612              (clobber (reg:SI MACL_REG))
1613              (clobber (reg:SI T_REG))
1614              (clobber (reg:SI PR_REG))
1615              (clobber (reg:SI R3_REG))
1616              (clobber (reg:SI R2_REG))
1617              (clobber (reg:SI R1_REG))
1618              (use (match_operand:SI 3 "register_operand" ""))])]
1619   "TARGET_SH1"
1620   "")
1622 (define_insn "mul_r"
1623   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1624         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1625                  (match_operand:SI 2 "arith_reg_operand" "z")))]
1626   "TARGET_SH2A"
1627   "mulr %2,%0"
1628   [(set_attr "type" "dmpy")])
1630 (define_insn "mul_l"
1631   [(set (reg:SI MACL_REG)
1632         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1633                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1634   "TARGET_SH2"
1635   "mul.l        %1,%0"
1636   [(set_attr "type" "dmpy")])
1638 (define_expand "mulsi3"
1639   [(set (reg:SI MACL_REG)
1640         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1641                   (match_operand:SI 2 "arith_reg_operand" "")))
1642    (set (match_operand:SI 0 "arith_reg_operand" "")
1643         (reg:SI MACL_REG))]
1644   "TARGET_SH1"
1645   "
1647   rtx first, last;
1649   if (!TARGET_SH2)
1650     {
1651       /* The address must be set outside the libcall,
1652          since it goes into a pseudo.  */
1653       rtx sym = function_symbol (\"__mulsi3\");
1654       rtx addr = force_reg (SImode, sym);
1655       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1656                                    operands[2], addr);
1657       first = insns;
1658       last = emit_insn (insns);
1659     }
1660   else
1661     {
1662       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1664       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1665       /* consec_sets_giv can only recognize the first insn that sets a
1666          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1667          note.  */
1668       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1669     }
1670   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1671      invariant code motion can move it.  */
1672   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1673   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1674   DONE;
1677 (define_insn "mulsidi3_i"
1678   [(set (reg:SI MACH_REG)
1679         (truncate:SI
1680          (lshiftrt:DI
1681           (mult:DI
1682            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1683            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1684           (const_int 32))))
1685    (set (reg:SI MACL_REG)
1686         (mult:SI (match_dup 0)
1687                  (match_dup 1)))]
1688   "TARGET_SH2"
1689   "dmuls.l      %1,%0"
1690   [(set_attr "type" "dmpy")])
1692 (define_expand "mulsidi3"
1693   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1694         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1695                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1696   "TARGET_SH2 || TARGET_SHMEDIA"
1697   "
1699   if (TARGET_SH2)
1700     {
1701        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1702                                         operands[2]));
1703        DONE;
1704     }
1707 (define_insn "mulsidi3_media"
1708   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1709         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1710                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1711   "TARGET_SHMEDIA"
1712   "muls.l       %1, %2, %0"
1713   [(set_attr "type" "dmpy_media")])
1715 (define_insn "mulsidi3_compact"
1716   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1717         (mult:DI
1718          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1719          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1720    (clobber (reg:SI MACH_REG))
1721    (clobber (reg:SI MACL_REG))]
1722   "TARGET_SH2"
1723   "#")
1725 (define_split
1726   [(set (match_operand:DI 0 "arith_reg_operand" "")
1727         (mult:DI
1728          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1729          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1730    (clobber (reg:SI MACH_REG))
1731    (clobber (reg:SI MACL_REG))]
1732   "TARGET_SH2"
1733   [(const_int 0)]
1734   "
1736   rtx low_dst = gen_lowpart (SImode, operands[0]);
1737   rtx high_dst = gen_highpart (SImode, operands[0]);
1739   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1741   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1742   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1743   /* We need something to tag the possible REG_EQUAL notes on to.  */
1744   emit_move_insn (operands[0], operands[0]);
1745   DONE;
1748 (define_insn "umulsidi3_i"
1749   [(set (reg:SI MACH_REG)
1750         (truncate:SI
1751          (lshiftrt:DI
1752           (mult:DI
1753            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1754            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1755           (const_int 32))))
1756    (set (reg:SI MACL_REG)
1757         (mult:SI (match_dup 0)
1758                  (match_dup 1)))]
1759   "TARGET_SH2"
1760   "dmulu.l      %1,%0"
1761   [(set_attr "type" "dmpy")])
1763 (define_expand "umulsidi3"
1764   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1765         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1766                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1767   "TARGET_SH2 || TARGET_SHMEDIA"
1768   "
1770   if (TARGET_SH2)
1771     {
1772        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1773                                          operands[2]));
1774        DONE;
1775     }
1778 (define_insn "umulsidi3_media"
1779   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1780         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1781                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1782   "TARGET_SHMEDIA"
1783   "mulu.l       %1, %2, %0"
1784   [(set_attr "type" "dmpy_media")])
1786 (define_insn "umulsidi3_compact"
1787   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1788         (mult:DI
1789          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1790          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1791    (clobber (reg:SI MACH_REG))
1792    (clobber (reg:SI MACL_REG))]
1793   "TARGET_SH2"
1794   "#")
1796 (define_split
1797   [(set (match_operand:DI 0 "arith_reg_operand" "")
1798         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1799                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1800    (clobber (reg:SI MACH_REG))
1801    (clobber (reg:SI MACL_REG))]
1802   "TARGET_SH2"
1803   [(const_int 0)]
1804   "
1806   rtx low_dst = gen_lowpart (SImode, operands[0]);
1807   rtx high_dst = gen_highpart (SImode, operands[0]);
1809   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1811   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1812   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1813   /* We need something to tag the possible REG_EQUAL notes on to.  */
1814   emit_move_insn (operands[0], operands[0]);
1815   DONE;
1818 (define_insn "smulsi3_highpart_i"
1819   [(set (reg:SI MACH_REG)
1820         (truncate:SI
1821          (lshiftrt:DI
1822           (mult:DI
1823            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1824            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1825           (const_int 32))))
1826    (clobber (reg:SI MACL_REG))]
1827   "TARGET_SH2"
1828   "dmuls.l      %1,%0"
1829   [(set_attr "type" "dmpy")])
1831 (define_expand "smulsi3_highpart"
1832   [(parallel
1833     [(set (reg:SI MACH_REG)
1834           (truncate:SI
1835            (lshiftrt:DI
1836             (mult:DI
1837              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1838              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1839             (const_int 32))))
1840     (clobber (reg:SI MACL_REG))])
1841    (set (match_operand:SI 0 "arith_reg_operand" "")
1842         (reg:SI MACH_REG))]
1843   "TARGET_SH2"
1844   "
1846   rtx first, last;
1848   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1849   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1850   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1851      invariant code motion can move it.  */
1852   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1853   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1854   /* expand_binop can't find a suitable code in mul_highpart_optab to
1855      make a REG_EQUAL note from, so make one here.
1856      See also {,u}mulhisi.
1857      ??? Alternatively, we could put this at the calling site of expand_binop,
1858      i.e. expand_mult_highpart.  */
1859   REG_NOTES (last)
1860     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1861                          REG_NOTES (last));
1862   DONE;
1865 (define_insn "umulsi3_highpart_i"
1866   [(set (reg:SI MACH_REG)
1867         (truncate:SI
1868          (lshiftrt:DI
1869           (mult:DI
1870            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1871            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1872           (const_int 32))))
1873    (clobber (reg:SI MACL_REG))]
1874   "TARGET_SH2"
1875   "dmulu.l      %1,%0"
1876   [(set_attr "type" "dmpy")])
1878 (define_expand "umulsi3_highpart"
1879   [(parallel
1880     [(set (reg:SI MACH_REG)
1881           (truncate:SI
1882            (lshiftrt:DI
1883             (mult:DI
1884              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1885              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1886             (const_int 32))))
1887     (clobber (reg:SI MACL_REG))])
1888    (set (match_operand:SI 0 "arith_reg_operand" "")
1889         (reg:SI MACH_REG))]
1890   "TARGET_SH2"
1891   "
1893   rtx first, last;
1895   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1896   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1897   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1898      invariant code motion can move it.  */
1899   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1900   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1901   DONE;
1904 ;; -------------------------------------------------------------------------
1905 ;; Logical operations
1906 ;; -------------------------------------------------------------------------
1908 (define_insn "*andsi3_compact"
1909   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1910         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1911                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1912   "TARGET_SH1"
1913   "and  %2,%0"
1914   [(set_attr "type" "arith")])
1916 ;; If the constant is 255, then emit an extu.b instruction instead of an
1917 ;; and, since that will give better code.
1919 (define_expand "andsi3"
1920   [(set (match_operand:SI 0 "arith_reg_operand" "")
1921         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1922                 (match_operand:SI 2 "logical_operand" "")))]
1923   "TARGET_SH1"
1924   "
1926   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1927     {
1928       emit_insn (gen_zero_extendqisi2 (operands[0],
1929                                        gen_lowpart (QImode, operands[1])));
1930       DONE;
1931     }
1934 (define_insn_and_split "anddi3"
1935   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1936         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1937                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1938   "TARGET_SHMEDIA"
1939   "@
1940         and     %1, %2, %0
1941         andi    %1, %2, %0
1942         #"
1943   "reload_completed
1944    && ! logical_operand (operands[2], DImode)"
1945   [(const_int 0)]
1946   "
1948   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1949     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1950   else
1951     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1952   DONE;
1954   [(set_attr "type" "arith_media")])
1956 (define_insn "andcdi3"
1957   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1958         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1959                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1960   "TARGET_SHMEDIA"
1961   "andc %1,%2,%0"
1962   [(set_attr "type" "arith_media")])
1964 (define_insn "iorsi3"
1965   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1966         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1967                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1968   "TARGET_SH1"
1969   "or   %2,%0"
1970   [(set_attr "type" "arith")])
1972 (define_insn "iordi3"
1973   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1974         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1975                 (match_operand:DI 2 "logical_operand" "r,I10")))]
1976   "TARGET_SHMEDIA"
1977   "@
1978         or      %1, %2, %0
1979         ori     %1, %2, %0"
1980   [(set_attr "type" "arith_media")])
1982 (define_insn "xorsi3"
1983   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1984         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1985                 (match_operand:SI 2 "logical_operand" "K08,r")))]
1986   "TARGET_SH1"
1987   "xor  %2,%0"
1988   [(set_attr "type" "arith")])
1990 (define_insn "xordi3"
1991   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1992         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1993                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1994   "TARGET_SHMEDIA"
1995   "@
1996         xor     %1, %2, %0
1997         xori    %1, %2, %0"
1998   [(set_attr "type" "arith_media")])
2000 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2001 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2002 (define_split
2003   [(set (match_operand:DI 0 "arith_reg_operand" "")
2004         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2005                           [(match_operand 1 "any_register_operand" "")
2006                            (match_operand 2 "any_register_operand" "")])))]
2007   "TARGET_SHMEDIA"
2008   [(set (match_dup 5) (match_dup 4))
2009    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2012   enum machine_mode inmode = GET_MODE (operands[1]);
2013   int offset = 0;
2015   if (GET_CODE (operands[0]) == SUBREG)
2016     {
2017       offset = SUBREG_BYTE (operands[0]);
2018       operands[0] = SUBREG_REG (operands[0]);
2019     }
2020   if (GET_CODE (operands[0]) != REG)
2021     abort ();
2022   if (! TARGET_LITTLE_ENDIAN)
2023     offset += 8 - GET_MODE_SIZE (inmode);
2024   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2027 ;; -------------------------------------------------------------------------
2028 ;; Shifts and rotates
2029 ;; -------------------------------------------------------------------------
2031 (define_expand "rotldi3"
2032   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2033         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2034                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2035   "TARGET_SHMEDIA"
2036   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2038 (define_insn "rotldi3_mextr"
2039   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2040         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2041                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2042   "TARGET_SHMEDIA"
2043   "*
2045   static char templ[16];
2047   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2048            8 - (int) (INTVAL (operands[2]) >> 3));
2049   return templ;
2051   [(set_attr "type" "arith_media")])
2053 (define_expand "rotrdi3"
2054   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2055         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2056                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2057   "TARGET_SHMEDIA"
2058   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2060 (define_insn "rotrdi3_mextr"
2061   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2062         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2063                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2064   "TARGET_SHMEDIA"
2065   "*
2067   static char templ[16];
2069   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2070   return templ;
2072   [(set_attr "type" "arith_media")])
2074 (define_insn "rotlsi3_1"
2075   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2076         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2077                    (const_int 1)))
2078    (set (reg:SI T_REG)
2079         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2080   "TARGET_SH1"
2081   "rotl %0"
2082   [(set_attr "type" "arith")])
2084 (define_insn "rotlsi3_31"
2085   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2086         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2087                    (const_int 31)))
2088    (clobber (reg:SI T_REG))]
2089   "TARGET_SH1"
2090   "rotr %0"
2091   [(set_attr "type" "arith")])
2093 (define_insn "rotlsi3_16"
2094   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2095         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2096                    (const_int 16)))]
2097   "TARGET_SH1"
2098   "swap.w       %1,%0"
2099   [(set_attr "type" "arith")])
2101 (define_expand "rotlsi3"
2102   [(set (match_operand:SI 0 "arith_reg_operand" "")
2103         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2104                    (match_operand:SI 2 "immediate_operand" "")))]
2105   "TARGET_SH1"
2106   "
2108   static const char rot_tab[] = {
2109     000, 000, 000, 000, 000, 000, 010, 001,
2110     001, 001, 011, 013, 003, 003, 003, 003,
2111     003, 003, 003, 003, 003, 013, 012, 002,
2112     002, 002, 010, 000, 000, 000, 000, 000,
2113   };
2115   int count, choice;
2117   if (GET_CODE (operands[2]) != CONST_INT)
2118     FAIL;
2119   count = INTVAL (operands[2]);
2120   choice = rot_tab[count];
2121   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2122     FAIL;
2123   choice &= 7;
2124   switch (choice)
2125     {
2126     case 0:
2127       emit_move_insn (operands[0], operands[1]);
2128       count -= (count & 16) * 2;
2129       break;
2130     case 3:
2131      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2132      count -= 16;
2133      break;
2134     case 1:
2135     case 2:
2136       {
2137         rtx parts[2];
2138         parts[0] = gen_reg_rtx (SImode);
2139         parts[1] = gen_reg_rtx (SImode);
2140         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2141         emit_move_insn (parts[choice-1], operands[1]);
2142         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2143         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2144         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2145         count = (count & ~16) - 8;
2146       }
2147     }
2149   for (; count > 0; count--)
2150     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2151   for (; count < 0; count++)
2152     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2154   DONE;
2157 (define_insn "*rotlhi3_8"
2158   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2159         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2160                    (const_int 8)))]
2161   "TARGET_SH1"
2162   "swap.b       %1,%0"
2163   [(set_attr "type" "arith")])
2165 (define_expand "rotlhi3"
2166   [(set (match_operand:HI 0 "arith_reg_operand" "")
2167         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2168                    (match_operand:HI 2 "immediate_operand" "")))]
2169   "TARGET_SH1"
2170   "
2172   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2173     FAIL;
2177 ;; shift left
2179 (define_insn "ashlsi3_sh2a"
2180   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2181         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2182                    (match_operand:SI 2 "arith_reg_operand" "r")))]
2183   "TARGET_SH2A"
2184   "shad %2,%0"
2185   [(set_attr "type" "arith")
2186    (set_attr "length" "4")])
2188 ;; This pattern is used by init_expmed for computing the costs of shift
2189 ;; insns.
2191 (define_insn_and_split "ashlsi3_std"
2192   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2193         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2194                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2195    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2196   "TARGET_SH3
2197    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2198        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2199   "@
2200    shld %2,%0
2201    add  %0,%0
2202    shll%O2      %0
2203    #"
2204   "TARGET_SH3
2205    && reload_completed
2206    && GET_CODE (operands[2]) == CONST_INT
2207    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2208   [(set (match_dup 3) (match_dup 2))
2209    (parallel
2210     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2211      (clobber (match_dup 4))])]
2212   "operands[4] = gen_rtx_SCRATCH (SImode);"
2213   [(set_attr "length" "*,*,*,4")
2214    (set_attr "type" "dyn_shift,arith,arith,arith")])
2216 (define_insn "ashlhi3_k"
2217   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2218         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2219                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2220   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2221   "@
2222         add     %0,%0
2223         shll%O2 %0"
2224   [(set_attr "type" "arith")])
2226 (define_insn "ashlsi3_n"
2227   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2228         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2229                    (match_operand:SI 2 "const_int_operand" "n")))
2230    (clobber (reg:SI T_REG))]
2231   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2232   "#"
2233   [(set (attr "length")
2234         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2235                (const_string "2")
2236                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2237                (const_string "4")
2238                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2239                (const_string "6")]
2240               (const_string "8")))
2241    (set_attr "type" "arith")])
2243 (define_split
2244   [(set (match_operand:SI 0 "arith_reg_operand" "")
2245         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2246                    (match_operand:SI 2 "const_int_operand" "")))
2247    (clobber (reg:SI T_REG))]
2248   "TARGET_SH1 && reload_completed"
2249   [(use (reg:SI R0_REG))]
2250   "
2252   gen_shifty_op (ASHIFT, operands);
2253   DONE;
2256 (define_insn "ashlsi3_media"
2257   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2258         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2259                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2260   "TARGET_SHMEDIA"
2261   "@
2262         shlld.l %1, %2, %0
2263         shlli.l %1, %2, %0"
2264   [(set_attr "type" "arith_media")])
2266 (define_expand "ashlsi3"
2267   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2268                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2269                               (match_operand:SI 2 "nonmemory_operand" "")))
2270               (clobber (reg:SI T_REG))])]
2271   ""
2272   "
2274   if (TARGET_SHMEDIA)
2275     {
2276       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2277       DONE;
2278     }
2279   if (GET_CODE (operands[2]) == CONST_INT
2280       && sh_dynamicalize_shift_p (operands[2]))
2281     operands[2] = force_reg (SImode, operands[2]);
2282   if (TARGET_SH3)
2283     {
2284       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2285       DONE;
2286     }
2287   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2288     FAIL;
2291 (define_insn "ashlhi3"
2292   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2293         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2294                    (match_operand:HI 2 "const_int_operand" "n")))
2295    (clobber (reg:SI T_REG))]
2296   "TARGET_SH1"
2297   "#"
2298   [(set (attr "length")
2299         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2300                (const_string "2")
2301                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2302                (const_string "4")]
2303               (const_string "6")))
2304    (set_attr "type" "arith")])
2306 (define_split
2307   [(set (match_operand:HI 0 "arith_reg_operand" "")
2308         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2309                    (match_operand:HI 2 "const_int_operand" "")))
2310    (clobber (reg:SI T_REG))]
2311   "TARGET_SH1 && reload_completed"
2312   [(use (reg:SI R0_REG))]
2313   "
2315   gen_shifty_hi_op (ASHIFT, operands);
2316   DONE;
2320 ; arithmetic shift right
2323 (define_insn "ashrsi3_sh2a"
2324   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2325         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2326                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2327   "TARGET_SH2A"
2328   "shad %2,%0"
2329   [(set_attr "type" "dyn_shift")
2330    (set_attr "length" "4")])
2332 (define_insn "ashrsi3_k"
2333   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2334         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2335                      (match_operand:SI 2 "const_int_operand" "M")))
2336    (clobber (reg:SI T_REG))]
2337   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2338   "shar %0"
2339   [(set_attr "type" "arith")])
2341 ;; We can't do HImode right shifts correctly unless we start out with an
2342 ;; explicit zero / sign extension; doing that would result in worse overall
2343 ;; code, so just let the machine independent code widen the mode.
2344 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2347 ;; ??? This should be a define expand.
2349 (define_insn "ashrsi2_16"
2350   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2351         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2352                      (const_int 16)))]
2353   "TARGET_SH1"
2354   "#"
2355   [(set_attr "length" "4")])
2357 (define_split
2358   [(set (match_operand:SI 0 "arith_reg_operand" "")
2359         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2360                      (const_int 16)))]
2361   "TARGET_SH1"
2362   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2363    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2364   "operands[2] = gen_lowpart (HImode, operands[0]);")
2366 ;; ??? This should be a define expand.
2368 (define_insn "ashrsi2_31"
2369   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2370         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2371                      (const_int 31)))
2372    (clobber (reg:SI T_REG))]
2373   "TARGET_SH1"
2374   "#"
2375   [(set_attr "length" "4")])
2377 (define_split
2378   [(set (match_operand:SI 0 "arith_reg_operand" "")
2379         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2380                      (const_int 31)))
2381    (clobber (reg:SI T_REG))]
2382   "TARGET_SH1"
2383   [(const_int 0)]
2384   "
2386   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2387   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2388   DONE;
2391 (define_insn "ashlsi_c"
2392   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2393         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2394    (set (reg:SI T_REG)
2395         (lt:SI (match_dup 1) (const_int 0)))]
2396   "TARGET_SH1"
2397   "shll %0"
2398   [(set_attr "type" "arith")])
2400 (define_insn "ashrsi3_d"
2401   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2402         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2403                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2404   "TARGET_SH3"
2405   "shad %2,%0"
2406   [(set_attr "type" "dyn_shift")])
2408 (define_insn "ashrsi3_n"
2409   [(set (reg:SI R4_REG)
2410         (ashiftrt:SI (reg:SI R4_REG)
2411                      (match_operand:SI 0 "const_int_operand" "i")))
2412    (clobber (reg:SI T_REG))
2413    (clobber (reg:SI PR_REG))
2414    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2415   "TARGET_SH1"
2416   "jsr  @%1%#"
2417   [(set_attr "type" "sfunc")
2418    (set_attr "needs_delay_slot" "yes")])
2420 (define_insn "ashrsi3_media"
2421   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2422         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2423                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2424   "TARGET_SHMEDIA"
2425   "@
2426         shard.l %1, %2, %0
2427         shari.l %1, %2, %0"
2428   [(set_attr "type" "arith_media")])
2430 (define_expand "ashrsi3"
2431   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2432                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2433                                 (match_operand:SI 2 "nonmemory_operand" "")))
2434               (clobber (reg:SI T_REG))])]
2435   ""
2436   "
2438   if (TARGET_SHMEDIA)
2439     {
2440       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2441       DONE;
2442     }
2443   if (expand_ashiftrt (operands))
2444     DONE;
2445   else
2446     FAIL;
2449 ;; logical shift right
2451 (define_insn "lshrsi3_sh2a"
2452   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2453         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2454                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2455   "TARGET_SH2A"
2456   "shld %2,%0"
2457   [(set_attr "type" "dyn_shift")
2458    (set_attr "length" "4")])
2460 (define_insn "lshrsi3_d"
2461   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2462         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2463                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2464   "TARGET_SH3"
2465   "shld %2,%0"
2466   [(set_attr "type" "dyn_shift")])
2468 ;;  Only the single bit shift clobbers the T bit.
2470 (define_insn "lshrsi3_m"
2471   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2472         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2473                      (match_operand:SI 2 "const_int_operand" "M")))
2474    (clobber (reg:SI T_REG))]
2475   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2476   "shlr %0"
2477   [(set_attr "type" "arith")])
2479 (define_insn "lshrsi3_k"
2480   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2481         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2482                      (match_operand:SI 2 "const_int_operand" "P27")))]
2483   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2484    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2485   "shlr%O2      %0"
2486   [(set_attr "type" "arith")])
2488 (define_insn "lshrsi3_n"
2489   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2490         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2491                      (match_operand:SI 2 "const_int_operand" "n")))
2492    (clobber (reg:SI T_REG))]
2493   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2494   "#"
2495   [(set (attr "length")
2496         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2497                (const_string "2")
2498                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2499                (const_string "4")
2500                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2501                (const_string "6")]
2502               (const_string "8")))
2503    (set_attr "type" "arith")])
2505 (define_split
2506   [(set (match_operand:SI 0 "arith_reg_operand" "")
2507         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2508                      (match_operand:SI 2 "const_int_operand" "")))
2509    (clobber (reg:SI T_REG))]
2510   "TARGET_SH1 && reload_completed"
2511   [(use (reg:SI R0_REG))]
2512   "
2514   gen_shifty_op (LSHIFTRT, operands);
2515   DONE;
2518 (define_insn "lshrsi3_media"
2519   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2520         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2521                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2522   "TARGET_SHMEDIA"
2523   "@
2524         shlrd.l %1, %2, %0
2525         shlri.l %1, %2, %0"
2526   [(set_attr "type" "arith_media")])
2528 (define_expand "lshrsi3"
2529   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2530                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2531                                 (match_operand:SI 2 "nonmemory_operand" "")))
2532               (clobber (reg:SI T_REG))])]
2533   ""
2534   "
2536   if (TARGET_SHMEDIA)
2537     {
2538       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2539       DONE;
2540     }
2541   if (GET_CODE (operands[2]) == CONST_INT
2542       && sh_dynamicalize_shift_p (operands[2]))
2543     operands[2] = force_reg (SImode, operands[2]);
2544   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2545     {
2546       rtx count = copy_to_mode_reg (SImode, operands[2]);
2547       emit_insn (gen_negsi2 (count, count));
2548       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2549       DONE;
2550     }
2551   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2552     FAIL;
2555 ;; ??? This should be a define expand.
2557 (define_insn "ashldi3_k"
2558   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2559         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2560                    (const_int 1)))
2561    (clobber (reg:SI T_REG))]
2562   "TARGET_SH1"
2563   "shll %R0\;rotcl      %S0"
2564   [(set_attr "length" "4")
2565    (set_attr "type" "arith")])
2567 (define_insn "ashldi3_media"
2568   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2569         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2570                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2571   "TARGET_SHMEDIA"
2572   "@
2573         shlld   %1, %2, %0
2574         shlli   %1, %2, %0"
2575   [(set_attr "type" "arith_media")])
2577 (define_expand "ashldi3"
2578   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2579                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2580                               (match_operand:DI 2 "immediate_operand" "")))
2581               (clobber (reg:SI T_REG))])]
2582   ""
2583   "
2585   if (TARGET_SHMEDIA)
2586     {
2587       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2588       DONE;
2589     }
2590   if (GET_CODE (operands[2]) != CONST_INT
2591       || INTVAL (operands[2]) != 1)
2592     FAIL;
2595 ;; ??? This should be a define expand.
2597 (define_insn "lshrdi3_k"
2598   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2599         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2600                      (const_int 1)))
2601    (clobber (reg:SI T_REG))]
2602   "TARGET_SH1"
2603   "shlr %S0\;rotcr      %R0"
2604   [(set_attr "length" "4")
2605    (set_attr "type" "arith")])
2607 (define_insn "lshrdi3_media"
2608   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2609         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2610                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2611   "TARGET_SHMEDIA"
2612   "@
2613         shlrd   %1, %2, %0
2614         shlri   %1, %2, %0"
2615   [(set_attr "type" "arith_media")])
2617 (define_expand "lshrdi3"
2618   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2619                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2620                                (match_operand:DI 2 "immediate_operand" "")))
2621              (clobber (reg:SI T_REG))])]
2622   ""
2623   "
2625   if (TARGET_SHMEDIA)
2626     {
2627       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2628       DONE;
2629     }
2630   if (GET_CODE (operands[2]) != CONST_INT
2631       || INTVAL (operands[2]) != 1)
2632     FAIL;
2635 ;; ??? This should be a define expand.
2637 (define_insn "ashrdi3_k"
2638   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2639         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2640                      (const_int 1)))
2641    (clobber (reg:SI T_REG))]
2642   "TARGET_SH1"
2643   "shar %S0\;rotcr      %R0"
2644   [(set_attr "length" "4")
2645    (set_attr "type" "arith")])
2647 (define_insn "ashrdi3_media"
2648   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2649         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2650                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2651   "TARGET_SHMEDIA"
2652   "@
2653         shard   %1, %2, %0
2654         shari   %1, %2, %0"
2655   [(set_attr "type" "arith_media")])
2657 (define_expand "ashrdi3"
2658   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2659                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2660                                 (match_operand:DI 2 "immediate_operand" "")))
2661               (clobber (reg:SI T_REG))])]
2662   ""
2663   "
2665   if (TARGET_SHMEDIA)
2666     {
2667       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2668       DONE;
2669     }
2670   if (GET_CODE (operands[2]) != CONST_INT
2671       || INTVAL (operands[2]) != 1)
2672     FAIL;
2675 ;; combined left/right shift
2677 (define_split
2678   [(set (match_operand:SI 0 "register_operand" "")
2679         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2680                            (match_operand:SI 2 "const_int_operand" ""))
2681                 (match_operand:SI 3 "const_int_operand" "")))]
2682   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2683   [(use (reg:SI R0_REG))]
2684   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2685    DONE;")
2687 (define_split
2688   [(set (match_operand:SI 0 "register_operand" "")
2689         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2690                            (match_operand:SI 2 "const_int_operand" ""))
2691                 (match_operand:SI 3 "const_int_operand" "")))
2692    (clobber (reg:SI T_REG))]
2693   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2694   [(use (reg:SI R0_REG))]
2695   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2696    DONE;")
2698 (define_insn ""
2699   [(set (match_operand:SI 0 "register_operand" "=r")
2700         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2701                            (match_operand:SI 2 "const_int_operand" "n"))
2702                 (match_operand:SI 3 "const_int_operand" "n")))
2703    (clobber (reg:SI T_REG))]
2704   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2705  "#"
2706   [(set (attr "length")
2707         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2708                (const_string "4")
2709                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2710                (const_string "6")
2711                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2712                (const_string "8")
2713                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2714                (const_string "10")
2715                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2716                (const_string "12")
2717                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2718                (const_string "14")
2719                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2720                (const_string "16")]
2721               (const_string "18")))
2722    (set_attr "type" "arith")])
2724 (define_insn ""
2725   [(set (match_operand:SI 0 "register_operand" "=z")
2726         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2727                            (match_operand:SI 2 "const_int_operand" "n"))
2728                 (match_operand:SI 3 "const_int_operand" "n")))
2729    (clobber (reg:SI T_REG))]
2730   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2731  "#"
2732   [(set (attr "length")
2733         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2734                (const_string "4")
2735                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2736                (const_string "6")
2737                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2738                (const_string "8")]
2739               (const_string "10")))
2740    (set_attr "type" "arith")])
2742 ;; shift left / and combination with a scratch register: The combine pass
2743 ;; does not accept the individual instructions, even though they are
2744 ;; cheap.  But it needs a precise description so that it is usable after
2745 ;; reload.
2746 (define_insn "and_shl_scratch"
2747   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2748         (lshiftrt:SI
2749          (ashift:SI
2750           (and:SI
2751            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2752                         (match_operand:SI 2 "const_int_operand" "N,n"))
2753            (match_operand:SI 3 "" "0,r"))
2754           (match_operand:SI 4 "const_int_operand" "n,n"))
2755          (match_operand:SI 5 "const_int_operand" "n,n")))
2756    (clobber (reg:SI T_REG))]
2757   "TARGET_SH1"
2758   "#"
2759   [(set (attr "length")
2760         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2761                (const_string "4")
2762                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2763                (const_string "6")
2764                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2765                (const_string "8")
2766                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2767                (const_string "10")]
2768               (const_string "12")))
2769    (set_attr "type" "arith")])
2771 (define_split
2772   [(set (match_operand:SI 0 "register_operand" "")
2773         (lshiftrt:SI
2774          (ashift:SI
2775           (and:SI
2776            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2777                         (match_operand:SI 2 "const_int_operand" ""))
2778            (match_operand:SI 3 "register_operand" ""))
2779           (match_operand:SI 4 "const_int_operand" ""))
2780          (match_operand:SI 5 "const_int_operand" "")))
2781    (clobber (reg:SI T_REG))]
2782   "TARGET_SH1"
2783   [(use (reg:SI R0_REG))]
2784   "
2786   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2788   if (INTVAL (operands[2]))
2789     {
2790       gen_shifty_op (LSHIFTRT, operands);
2791     }
2792   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2793   operands[2] = operands[4];
2794   gen_shifty_op (ASHIFT, operands);
2795   if (INTVAL (operands[5]))
2796     {
2797       operands[2] = operands[5];
2798       gen_shifty_op (LSHIFTRT, operands);
2799     }
2800   DONE;
2803 ;; signed left/right shift combination.
2804 (define_split
2805   [(set (match_operand:SI 0 "register_operand" "")
2806         (sign_extract:SI
2807          (ashift:SI (match_operand:SI 1 "register_operand" "")
2808                     (match_operand:SI 2 "const_int_operand" ""))
2809          (match_operand:SI 3 "const_int_operand" "")
2810          (const_int 0)))
2811    (clobber (reg:SI T_REG))]
2812   "TARGET_SH1"
2813   [(use (reg:SI R0_REG))]
2814   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2815    DONE;")
2817 (define_insn "shl_sext_ext"
2818   [(set (match_operand:SI 0 "register_operand" "=r")
2819         (sign_extract:SI
2820          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2821                     (match_operand:SI 2 "const_int_operand" "n"))
2822          (match_operand:SI 3 "const_int_operand" "n")
2823          (const_int 0)))
2824    (clobber (reg:SI T_REG))]
2825   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2826   "#"
2827   [(set (attr "length")
2828         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2829                (const_string "2")
2830                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2831                (const_string "4")
2832                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2833                (const_string "6")
2834                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2835                (const_string "8")
2836                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2837                (const_string "10")
2838                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2839                (const_string "12")
2840                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2841                (const_string "14")
2842                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2843                (const_string "16")]
2844               (const_string "18")))
2845     (set_attr "type" "arith")])
2847 (define_insn "shl_sext_sub"
2848   [(set (match_operand:SI 0 "register_operand" "=z")
2849         (sign_extract:SI
2850          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2851                     (match_operand:SI 2 "const_int_operand" "n"))
2852          (match_operand:SI 3 "const_int_operand" "n")
2853          (const_int 0)))
2854    (clobber (reg:SI T_REG))]
2855   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2856   "#"
2857   [(set (attr "length")
2858         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2859                (const_string "6")
2860                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2861                (const_string "8")
2862                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2863                (const_string "10")
2864                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2865                (const_string "12")]
2866               (const_string "14")))
2867     (set_attr "type" "arith")])
2869 ;; These patterns are found in expansions of DImode shifts by 16, and
2870 ;; allow the xtrct instruction to be generated from C source.
2872 (define_insn "xtrct_left"
2873   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2874         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2875                            (const_int 16))
2876                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2877                              (const_int 16))))]
2878   "TARGET_SH1"
2879   "xtrct        %1,%0"
2880   [(set_attr "type" "arith")])
2882 (define_insn "xtrct_right"
2883   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2884         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2885                              (const_int 16))
2886                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2887                            (const_int 16))))]
2888   "TARGET_SH1"
2889   "xtrct        %2,%0"
2890   [(set_attr "type" "arith")])
2892 ;; -------------------------------------------------------------------------
2893 ;; Unary arithmetic
2894 ;; -------------------------------------------------------------------------
2896 (define_insn "negc"
2897   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2898         (neg:SI (plus:SI (reg:SI T_REG)
2899                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2900    (set (reg:SI T_REG)
2901         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2902                (const_int 0)))]
2903   "TARGET_SH1"
2904   "negc %1,%0"
2905   [(set_attr "type" "arith")])
2907 (define_insn "*negdi_media"
2908   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2909         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2910   "TARGET_SHMEDIA"
2911   "sub  r63, %1, %0"
2912   [(set_attr "type" "arith_media")])
2914 (define_expand "negdi2"
2915   [(set (match_operand:DI 0 "arith_reg_operand" "")
2916         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2917   ""
2918   "
2920   if (TARGET_SH1)
2921     {
2922       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2923       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2925       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2926       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2928       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2929       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2931       emit_insn (gen_clrt ());
2932       emit_insn (gen_negc (low_dst, low_src));
2933       emit_insn (gen_negc (high_dst, high_src));
2934       DONE;
2935     }
2938 (define_insn "negsi2"
2939   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2940         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2941   "TARGET_SH1"
2942   "neg  %1,%0"
2943   [(set_attr "type" "arith")])
2945 (define_insn "one_cmplsi2"
2946   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2947         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2948   "TARGET_SH1"
2949   "not  %1,%0"
2950   [(set_attr "type" "arith")])
2952 (define_expand "one_cmpldi2"
2953   [(set (match_operand:DI 0 "arith_reg_operand" "")
2954         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2955                 (const_int -1)))]
2956   "TARGET_SHMEDIA" "")
2958 ;; -------------------------------------------------------------------------
2959 ;; Zero extension instructions
2960 ;; -------------------------------------------------------------------------
2962 (define_insn "zero_extendsidi2"
2963   [(set (match_operand:DI 0 "register_operand" "=r")
2964         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2965   "TARGET_SHMEDIA"
2966   "addz.l       %1, r63, %0"
2967   [(set_attr "type" "arith_media")])
2969 (define_insn "zero_extendhidi2"
2970   [(set (match_operand:DI 0 "register_operand" "=r,r")
2971         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2972   "TARGET_SHMEDIA"
2973   "@
2974         #
2975         ld%M1.uw        %m1, %0"
2976   [(set_attr "type" "*,load_media")])
2978 (define_split
2979   [(set (match_operand:DI 0 "register_operand" "")
2980         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2981   "TARGET_SHMEDIA && reload_completed"
2982   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2983    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2984   "
2986   if (GET_CODE (operands[1]) == TRUNCATE)
2987     operands[1] = XEXP (operands[1], 0);
2990 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2991 ;; reload the entire truncate expression.
2992 (define_insn_and_split "*loaddi_trunc"
2993   [(set (match_operand 0 "int_gpr_dest" "=r")
2994         (truncate (match_operand:DI 1 "memory_operand" "m")))]
2995   "TARGET_SHMEDIA && reload_completed"
2996   "#"
2997   "TARGET_SHMEDIA && reload_completed"
2998   [(set (match_dup 0) (match_dup 1))]
2999   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3001 (define_insn "zero_extendqidi2"
3002   [(set (match_operand:DI 0 "register_operand" "=r,r")
3003         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3004   "TARGET_SHMEDIA"
3005   "@
3006         andi    %1, 255, %0
3007         ld%M1.ub        %m1, %0"
3008   [(set_attr "type" "arith_media,load_media")])
3010 (define_expand "zero_extendhisi2"
3011   [(set (match_operand:SI 0 "arith_reg_operand" "")
3012         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3013   ""
3014   "
3016   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3017     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3020 (define_insn "*zero_extendhisi2_compact"
3021   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3022         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3023   "TARGET_SH1"
3024   "extu.w       %1,%0"
3025   [(set_attr "type" "arith")])
3027 (define_insn "*zero_extendhisi2_media"
3028   [(set (match_operand:SI 0 "register_operand" "=r,r")
3029         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3030   "TARGET_SHMEDIA"
3031   "@
3032         #
3033         ld%M1.uw        %m1, %0"
3034   [(set_attr "type" "arith_media,load_media")])
3036 (define_split
3037   [(set (match_operand:SI 0 "register_operand" "")
3038         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3039   "TARGET_SHMEDIA && reload_completed"
3040   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3041    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3042   "
3044   if (GET_CODE (operands[1]) == TRUNCATE)
3045     operands[1] = XEXP (operands[1], 0);
3048 (define_expand "zero_extendqisi2"
3049   [(set (match_operand:SI 0 "arith_reg_operand" "")
3050         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3051   ""
3052   "
3054   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3055     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3058 (define_insn "*zero_extendqisi2_compact"
3059   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3060         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3061   "TARGET_SH1"
3062   "extu.b       %1,%0"
3063   [(set_attr "type" "arith")])
3065 (define_insn "*zero_extendqisi2_media"
3066   [(set (match_operand:SI 0 "register_operand" "=r,r")
3067         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3068   "TARGET_SHMEDIA"
3069   "@
3070         andi    %1, 255, %0
3071         ld%M1.ub        %m1, %0"
3072   [(set_attr "type" "arith_media,load_media")])
3074 (define_insn "zero_extendqihi2"
3075   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3076         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3077   "TARGET_SH1"
3078   "extu.b       %1,%0"
3079   [(set_attr "type" "arith")])
3081 ;; -------------------------------------------------------------------------
3082 ;; Sign extension instructions
3083 ;; -------------------------------------------------------------------------
3085 ;; ??? This should be a define expand.
3086 ;; ??? Or perhaps it should be dropped?
3088 ;; convert_move generates good code for SH[1-4].
3089 (define_insn "extendsidi2"
3090   [(set (match_operand:DI 0 "register_operand" "=r,r")
3091         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3092   "TARGET_SHMEDIA"
3093   "@
3094         add.l   %1, r63, %0
3095         ld%M1.l %m1, %0"
3096   [(set_attr "type" "arith_media,load_media")])
3098 (define_insn "extendhidi2"
3099   [(set (match_operand:DI 0 "register_operand" "=r,r")
3100         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3101   "TARGET_SHMEDIA"
3102   "@
3103         #
3104         ld%M1.w %m1, %0"
3105   [(set_attr "type" "*,load_media")])
3107 (define_split
3108   [(set (match_operand:DI 0 "register_operand" "")
3109         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3110   "TARGET_SHMEDIA && reload_completed"
3111   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3112    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3113   "
3115   if (GET_CODE (operands[1]) == TRUNCATE)
3116     operands[1] = XEXP (operands[1], 0);
3119 (define_insn "extendqidi2"
3120   [(set (match_operand:DI 0 "register_operand" "=r,r")
3121         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3122   "TARGET_SHMEDIA"
3123   "@
3124         #
3125         ld%M1.b %m1, %0"
3126   [(set_attr "type" "*,load_media")])
3128 (define_split
3129   [(set (match_operand:DI 0 "register_operand" "")
3130         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3131   "TARGET_SHMEDIA && reload_completed"
3132   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3133    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3134   "
3136   if (GET_CODE (operands[1]) == TRUNCATE)
3137     operands[1] = XEXP (operands[1], 0);
3140 (define_expand "extendhisi2"
3141   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3142         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3143   ""
3144   "")
3146 (define_insn "*extendhisi2_compact"
3147   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3148         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3149   "TARGET_SH1"
3150   "@
3151         exts.w  %1,%0
3152         mov.w   %1,%0"
3153   [(set_attr "type" "arith,load")])
3155 (define_insn "*extendhisi2_media"
3156   [(set (match_operand:SI 0 "register_operand" "=r,r")
3157         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3158   "TARGET_SHMEDIA"
3159   "@
3160         #
3161         ld%M1.w %m1, %0"
3162   [(set_attr "type" "arith_media,load_media")])
3164 (define_split
3165   [(set (match_operand:SI 0 "register_operand" "")
3166         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3167   "TARGET_SHMEDIA && reload_completed"
3168   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3169    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3170   "
3172   if (GET_CODE (operands[1]) == TRUNCATE)
3173     operands[1] = XEXP (operands[1], 0);
3176 (define_expand "extendqisi2"
3177   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3178         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3179   ""
3180   "")
3182 (define_insn "*extendqisi2_compact"
3183   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3184         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3185   "TARGET_SH1"
3186   "@
3187         exts.b  %1,%0
3188         mov.b   %1,%0"
3189   [(set_attr "type" "arith,load")])
3191 (define_insn "*extendqisi2_media"
3192   [(set (match_operand:SI 0 "register_operand" "=r,r")
3193         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3194   "TARGET_SHMEDIA"
3195   "@
3196         #
3197         ld%M1.b %m1, %0"
3198   [(set_attr "type" "arith_media,load_media")])
3200 (define_split
3201   [(set (match_operand:SI 0 "register_operand" "")
3202         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3203   "TARGET_SHMEDIA && reload_completed"
3204   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3205    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3206    "
3208   if (GET_CODE (operands[1]) == TRUNCATE)
3209     operands[1] = XEXP (operands[1], 0);
3212 (define_insn "extendqihi2"
3213   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3214         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3215   "TARGET_SH1"
3216   "@
3217         exts.b  %1,%0
3218         mov.b   %1,%0"
3219   [(set_attr "type" "arith,load")])
3221 /* It would seem useful to combine the truncXi patterns into the movXi
3222    patterns, but unary operators are ignored when matching constraints,
3223    so we need separate patterns.  */
3224 (define_insn "truncdisi2"
3225   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3226         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3227   "TARGET_SHMEDIA"
3228   "@
3229         add.l   %1, r63, %0
3230         st%M0.l %m0, %1
3231         fst%M0.s        %m0, %T1
3232         fmov.ls %1, %0
3233         fmov.sl %T1, %0
3234         fmov.s  %T1, %0"
3235   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3238 (define_insn "truncdihi2"
3239   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3240         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3241   "TARGET_SHMEDIA"
3242   "@
3243         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3244         st%M0.w %m0, %1"
3245   [(set_attr "type"   "arith_media,store_media")
3246    (set_attr "length" "8,4")])
3248 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3249 ; Because we use zero extension, we can't provide signed QImode compares
3250 ; using a simple compare or conditional banch insn.
3251 (define_insn "truncdiqi2"
3252   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3253         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3254   "TARGET_SHMEDIA"
3255   "@
3256         andi    %1, 255, %0
3257         st%M0.b %m0, %1"
3258   [(set_attr "type"   "arith_media,store")])
3260 ;; -------------------------------------------------------------------------
3261 ;; Move instructions
3262 ;; -------------------------------------------------------------------------
3264 ;; define push and pop so it is easy for sh.c
3265 ;; We can't use push and pop on SHcompact because the stack must always
3266 ;; be 8-byte aligned.
3268 (define_expand "push"
3269   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3270         (match_operand:SI 0 "register_operand" "r,l,x"))]
3271   "TARGET_SH1 && ! TARGET_SH5"
3272   "")
3274 (define_expand "pop"
3275   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3276         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3277   "TARGET_SH1 && ! TARGET_SH5"
3278   "")
3280 (define_expand "push_e"
3281   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3282                    (match_operand:SF 0 "" ""))
3283               (use (reg:PSI FPSCR_REG))
3284               (clobber (scratch:SI))])]
3285   "TARGET_SH1 && ! TARGET_SH5"
3286   "")
3288 (define_insn "push_fpul"
3289   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3290   "TARGET_SH2E && ! TARGET_SH5"
3291   "sts.l        fpul,@-r15"
3292   [(set_attr "type" "store")
3293    (set_attr "late_fp_use" "yes")
3294    (set_attr "hit_stack" "yes")])
3296 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3297 ;; so use that.
3298 (define_expand "push_4"
3299   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3300                    (match_operand:DF 0 "" ""))
3301               (use (reg:PSI FPSCR_REG))
3302               (clobber (scratch:SI))])]
3303   "TARGET_SH1 && ! TARGET_SH5"
3304   "")
3306 (define_expand "pop_e"
3307   [(parallel [(set (match_operand:SF 0 "" "")
3308               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3309               (use (reg:PSI FPSCR_REG))
3310               (clobber (scratch:SI))])]
3311   "TARGET_SH1 && ! TARGET_SH5"
3312   "")
3314 (define_insn "pop_fpul"
3315   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3316   "TARGET_SH2E && ! TARGET_SH5"
3317   "lds.l        @r15+,fpul"
3318   [(set_attr "type" "load")
3319    (set_attr "hit_stack" "yes")])
3321 (define_expand "pop_4"
3322   [(parallel [(set (match_operand:DF 0 "" "")
3323                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3324               (use (reg:PSI FPSCR_REG))
3325               (clobber (scratch:SI))])]
3326   "TARGET_SH1 && ! TARGET_SH5"
3327   "")
3329 (define_expand "push_fpscr"
3330   [(const_int 0)]
3331   "TARGET_SH2E"
3332   "
3334   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3335                                                  gen_rtx_PRE_DEC (Pmode,
3336                                                           stack_pointer_rtx)),
3337                                         get_fpscr_rtx ()));
3338   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3339   DONE;
3342 (define_expand "pop_fpscr"
3343   [(const_int 0)]
3344   "TARGET_SH2E"
3345   "
3347   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3348                                         gen_rtx_MEM (PSImode,
3349                                                  gen_rtx_POST_INC (Pmode,
3350                                                           stack_pointer_rtx))));
3351   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3352   DONE;
3355 ;; These two patterns can happen as the result of optimization, when
3356 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3357 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3359 (define_insn "clrt"
3360   [(set (reg:SI T_REG) (const_int 0))]
3361   "TARGET_SH1"
3362   "clrt")
3364 (define_insn "sett"
3365   [(set (reg:SI T_REG) (const_int 1))]
3366   "TARGET_SH1"
3367   "sett")
3369 ;; t/r must come after r/r, lest reload will try to reload stuff like
3370 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3371 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3372 (define_insn "movsi_i"
3373   [(set (match_operand:SI 0 "general_movdst_operand"
3374             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3375         (match_operand:SI 1 "general_movsrc_operand"
3376          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3377   "TARGET_SH1
3378    && ! TARGET_SH2E
3379    && ! TARGET_SH2A
3380    && (register_operand (operands[0], SImode)
3381        || register_operand (operands[1], SImode))"
3382   "@
3383         mov.l   %1,%0
3384         mov     %1,%0
3385         cmp/pl  %1
3386         mov.l   %1,%0
3387         sts     %1,%0
3388         sts     %1,%0
3389         movt    %0
3390         mov.l   %1,%0
3391         sts.l   %1,%0
3392         sts.l   %1,%0
3393         lds     %1,%0
3394         lds     %1,%0
3395         lds.l   %1,%0
3396         lds.l   %1,%0
3397         fake    %1,%0"
3398   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3399    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3401 ;; t/r must come after r/r, lest reload will try to reload stuff like
3402 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3403 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3404 ;; will require a reload.
3405 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3406 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3407 (define_insn "movsi_ie"
3408   [(set (match_operand:SI 0 "general_movdst_operand"
3409             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3410         (match_operand:SI 1 "general_movsrc_operand"
3411          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3412   "(TARGET_SH2E || TARGET_SH2A)
3413    && (register_operand (operands[0], SImode)
3414        || register_operand (operands[1], SImode))"
3415   "@
3416         mov.l   %1,%0
3417         mov     %1,%0
3418         movi20  %1,%0
3419         cmp/pl  %1
3420         mov.l   %1,%0
3421         sts     %1,%0
3422         sts     %1,%0
3423         movt    %0
3424         mov.l   %1,%0
3425         sts.l   %1,%0
3426         sts.l   %1,%0
3427         lds     %1,%0
3428         lds     %1,%0
3429         lds.l   %1,%0
3430         lds.l   %1,%0
3431         lds.l   %1,%0
3432         sts.l   %1,%0
3433         fake    %1,%0
3434         lds     %1,%0
3435         sts     %1,%0
3436         fsts    fpul,%0
3437         flds    %1,fpul
3438         fmov    %1,%0
3439         ! move optimized away"
3440   [(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")
3441    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3442    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3444 (define_insn "movsi_i_lowpart"
3445   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3446         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3447    "TARGET_SH1
3448     && (register_operand (operands[0], SImode)
3449         || register_operand (operands[1], SImode))"
3450   "@
3451         mov.l   %1,%0
3452         mov     %1,%0
3453         mov.l   %1,%0
3454         sts     %1,%0
3455         sts     %1,%0
3456         movt    %0
3457         mov.l   %1,%0
3458         fake    %1,%0"
3459   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3461 (define_insn_and_split "load_ra"
3462   [(set (match_operand:SI 0 "general_movdst_operand" "")
3463         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3464   "TARGET_SH1"
3465   "#"
3466   "&& ! currently_expanding_to_rtl"
3467   [(set (match_dup 0) (match_dup 1))]
3468   "
3470   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3471     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3474 (define_insn "*movsi_media"
3475   [(set (match_operand:SI 0 "general_movdst_operand"
3476                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3477         (match_operand:SI 1 "general_movsrc_operand"
3478          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3479   "TARGET_SHMEDIA_FPU
3480    && (register_operand (operands[0], SImode)
3481        || sh_register_operand (operands[1], SImode))"
3482   "@
3483         add.l   %1, r63, %0
3484         movi    %1, %0
3485         #
3486         ld%M1.l %m1, %0
3487         st%M0.l %m0, %N1
3488         fld%M1.s        %m1, %0
3489         fst%M0.s        %m0, %1
3490         fmov.ls %N1, %0
3491         fmov.sl %1, %0
3492         fmov.s  %1, %0
3493         ptabs   %1, %0
3494         gettr   %1, %0
3495         pt      %1, %0"
3496   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,fpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
3497    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3499 (define_insn "*movsi_media_nofpu"
3500   [(set (match_operand:SI 0 "general_movdst_operand"
3501                 "=r,r,r,r,m,*b,r,b")
3502         (match_operand:SI 1 "general_movsrc_operand"
3503          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3504   "TARGET_SHMEDIA
3505    && (register_operand (operands[0], SImode)
3506        || sh_register_operand (operands[1], SImode))"
3507   "@
3508         add.l   %1, r63, %0
3509         movi    %1, %0
3510         #
3511         ld%M1.l %m1, %0
3512         st%M0.l %m0, %N1
3513         ptabs   %1, %0
3514         gettr   %1, %0
3515         pt      %1, %0"
3516   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3517    (set_attr "length" "4,4,8,4,4,4,4,12")])
3519 (define_split
3520   [(set (match_operand:SI 0 "arith_reg_operand" "")
3521         (match_operand:SI 1 "immediate_operand" ""))]
3522   "TARGET_SHMEDIA && reload_completed
3523    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3524   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3525   "
3527   operands[2] = shallow_copy_rtx (operands[1]);
3528   PUT_MODE (operands[2], DImode);
3531 (define_split
3532   [(set (match_operand:SI 0 "register_operand" "")
3533         (match_operand:SI 1 "immediate_operand" ""))]
3534   "TARGET_SHMEDIA && reload_completed
3535    && ((GET_CODE (operands[1]) == CONST_INT
3536         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3537        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3538   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3540 (define_expand "movsi"
3541   [(set (match_operand:SI 0 "general_movdst_operand" "")
3542         (match_operand:SI 1 "general_movsrc_operand" ""))]
3543   ""
3544   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3546 (define_expand "ic_invalidate_line"
3547   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3548                                 (match_dup 1)] UNSPEC_ICACHE)
3549               (clobber (scratch:SI))])]
3550   "TARGET_HARD_SH4 || TARGET_SH5"
3551   "
3553   if (TARGET_SHMEDIA)
3554     {
3555       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3556       DONE;
3557     }
3558   else if (TARGET_SHCOMPACT)
3559     {
3560       operands[1] = function_symbol (\"__ic_invalidate\");
3561       operands[1] = force_reg (Pmode, operands[1]);
3562       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3563       DONE;
3564     }
3565   else if (TARGET_SH4A_ARCH)
3566     {
3567       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3568       DONE;
3569     }
3570   operands[0] = force_reg (Pmode, operands[0]);
3571   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3572                                                                Pmode)));
3575 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3576 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3577 ;; the requirement *1*00 for associative address writes.  The alignment of
3578 ;; %0 implies that its least significant bit is cleared,
3579 ;; thus we clear the V bit of a matching entry if there is one.
3580 (define_insn "ic_invalidate_line_i"
3581   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3582                      (match_operand:SI 1 "register_operand" "r")]
3583                      UNSPEC_ICACHE)
3584    (clobber (match_scratch:SI 2 "=&r"))]
3585   "TARGET_HARD_SH4"
3586   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3587   [(set_attr "length" "8")
3588    (set_attr "type" "cwb")])
3590 (define_insn "ic_invalidate_line_sh4a"
3591   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3592                     UNSPEC_ICACHE)]
3593   "TARGET_SH4A_ARCH"
3594   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3595   [(set_attr "length" "16")
3596    (set_attr "type" "cwb")])
3598 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3599 ;; an add in the code that calculates the address.
3600 (define_insn "ic_invalidate_line_media"
3601   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3602                     UNSPEC_ICACHE)]
3603   "TARGET_SHMEDIA"
3604   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3605   [(set_attr "length" "16")
3606    (set_attr "type" "invalidate_line_media")])
3608 (define_insn "ic_invalidate_line_compact"
3609   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3610                      (match_operand:SI 1 "register_operand" "r")]
3611                     UNSPEC_ICACHE)
3612    (clobber (reg:SI PR_REG))]
3613   "TARGET_SHCOMPACT"
3614   "jsr @%1%#"
3615   [(set_attr "type" "sfunc")
3616    (set_attr "needs_delay_slot" "yes")])
3618 (define_expand "initialize_trampoline"
3619   [(match_operand:SI 0 "" "")
3620    (match_operand:SI 1 "" "")
3621    (match_operand:SI 2 "" "")]
3622   "TARGET_SHCOMPACT"
3623   "
3625   rtx sfun, tramp;
3627   tramp = force_reg (Pmode, operands[0]);
3628   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3629   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3630   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3632   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3633   DONE;
3636 (define_insn "initialize_trampoline_compact"
3637   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3638                      (match_operand:SI 1 "register_operand" "r")
3639                      (reg:SI R2_REG) (reg:SI R3_REG)]
3640                     UNSPEC_INIT_TRAMP)
3642    (clobber (reg:SI PR_REG))]
3643   "TARGET_SHCOMPACT"
3644   "jsr @%1%#"
3645   [(set_attr "type" "sfunc")
3646    (set_attr "needs_delay_slot" "yes")])
3648 (define_insn "movqi_i"
3649   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3650         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3651   "TARGET_SH1
3652    && (arith_reg_operand (operands[0], QImode)
3653        || arith_reg_operand (operands[1], QImode))"
3654   "@
3655         mov     %1,%0
3656         mov.b   %1,%0
3657         mov.b   %1,%0
3658         movt    %0
3659         sts     %1,%0
3660         lds     %1,%0"
3661  [(set_attr "type" "move,load,store,move,move,move")])
3663 (define_insn "*movqi_media"
3664   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3665         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3666   "TARGET_SHMEDIA
3667    && (arith_reg_operand (operands[0], QImode)
3668        || arith_reg_or_0_operand (operands[1], QImode))"
3669   "@
3670         add.l   %1, r63, %0
3671         movi    %1, %0
3672         ld%M1.ub        %m1, %0
3673         st%M0.b %m0, %N1"
3674   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3676 (define_expand "movqi"
3677   [(set (match_operand:QI 0 "general_operand" "")
3678         (match_operand:QI 1 "general_operand"  ""))]
3679   ""
3680   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3682 (define_expand "reload_inqi"
3683   [(set (match_operand:SI 2 "" "=&r")
3684         (match_operand:QI 1 "inqhi_operand" ""))
3685    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3686         (truncate:QI (match_dup 3)))]
3687   "TARGET_SHMEDIA"
3688   "
3690   rtx inner = XEXP (operands[1], 0);
3691   int regno = REGNO (inner);
3693   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3694   operands[1] = gen_rtx_REG (SImode, regno);
3695   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3698 /* When storing r0, we have to avoid reg+reg addressing.  */
3699 (define_insn "movhi_i"
3700   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3701         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3702   "TARGET_SH1
3703    && (arith_reg_operand (operands[0], HImode)
3704        || arith_reg_operand (operands[1], HImode))
3705    && (GET_CODE (operands[0]) != MEM
3706        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3707        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3708        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3709   "@
3710         mov.w   %1,%0
3711         mov     %1,%0
3712         mov.w   %1,%0
3713         movt    %0
3714         mov.w   %1,%0
3715         sts     %1,%0
3716         lds     %1,%0
3717         fake    %1,%0"
3718   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3720 (define_insn "*movhi_media"
3721   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3722         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3723   "TARGET_SHMEDIA
3724    && (arith_reg_operand (operands[0], HImode)
3725        || arith_reg_or_0_operand (operands[1], HImode))"
3726   "@
3727         add.l   %1, r63, %0
3728         movi    %1, %0
3729         #
3730         ld%M1.w %m1, %0
3731         st%M0.w %m0, %N1"
3732   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3734 (define_split
3735   [(set (match_operand:HI 0 "register_operand" "")
3736         (match_operand:HI 1 "immediate_operand" ""))]
3737   "TARGET_SHMEDIA && reload_completed
3738    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3739   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3741 (define_expand "movhi"
3742   [(set (match_operand:HI 0 "general_movdst_operand" "")
3743         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3744   ""
3745   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3747 (define_expand "reload_inhi"
3748   [(set (match_operand:SI 2 "" "=&r")
3749         (match_operand:HI 1 "inqhi_operand" ""))
3750    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3751         (truncate:HI (match_dup 3)))]
3752   "TARGET_SHMEDIA"
3753   "
3755   rtx inner = XEXP (operands[1], 0);
3756   int regno = REGNO (inner);
3758   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3759   operands[1] = gen_rtx_REG (SImode, regno);
3760   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3763 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3764 ;; compiled with -m2 -ml -O3 -funroll-loops
3765 (define_insn "*movdi_i"
3766   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3767         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3768   "TARGET_SH1
3769    && (arith_reg_operand (operands[0], DImode)
3770        || arith_reg_operand (operands[1], DImode))"
3771   "* return output_movedouble (insn, operands, DImode);"
3772   [(set_attr "length" "4")
3773    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3775 ;; If the output is a register and the input is memory or a register, we have
3776 ;; to be careful and see which word needs to be loaded first.
3778 (define_split
3779   [(set (match_operand:DI 0 "general_movdst_operand" "")
3780         (match_operand:DI 1 "general_movsrc_operand" ""))]
3781   "TARGET_SH1 && reload_completed"
3782   [(set (match_dup 2) (match_dup 3))
3783    (set (match_dup 4) (match_dup 5))]
3784   "
3786   int regno;
3788   if ((GET_CODE (operands[0]) == MEM
3789        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3790       || (GET_CODE (operands[1]) == MEM
3791           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3792     FAIL;
3794   if (GET_CODE (operands[0]) == REG)
3795     regno = REGNO (operands[0]);
3796   else if (GET_CODE (operands[0]) == SUBREG)
3797     regno = subreg_regno (operands[0]);
3798   else if (GET_CODE (operands[0]) == MEM)
3799     regno = -1;
3800   else
3801     abort ();
3803   if (regno == -1
3804       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3805     {
3806       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3807       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3808       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3809       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3810     }
3811   else
3812     {
3813       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3814       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3815       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3816       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3817     }
3819   if (operands[2] == 0 || operands[3] == 0
3820       || operands[4] == 0 || operands[5] == 0)
3821     FAIL;
3824 (define_insn "*movdi_media"
3825   [(set (match_operand:DI 0 "general_movdst_operand"
3826                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3827         (match_operand:DI 1 "general_movsrc_operand"
3828          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3829   "TARGET_SHMEDIA_FPU
3830    && (register_operand (operands[0], DImode)
3831        || sh_register_operand (operands[1], DImode))"
3832   "@
3833         add     %1, r63, %0
3834         movi    %1, %0
3835         #
3836         ld%M1.q %m1, %0
3837         st%M0.q %m0, %N1
3838         fld%M1.d        %m1, %0
3839         fst%M0.d        %m0, %1
3840         fmov.qd %N1, %0
3841         fmov.dq %1, %0
3842         fmov.d  %1, %0
3843         ptabs   %1, %0
3844         gettr   %1, %0
3845         pt      %1, %0"
3846   [(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")
3847    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3849 (define_insn "*movdi_media_nofpu"
3850   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3851         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3852   "TARGET_SHMEDIA
3853    && (register_operand (operands[0], DImode)
3854        || sh_register_operand (operands[1], DImode))"
3855   "@
3856         add     %1, r63, %0
3857         movi    %1, %0
3858         #
3859         ld%M1.q %m1, %0
3860         st%M0.q %m0, %N1
3861         ptabs   %1, %0
3862         gettr   %1, %0
3863         pt      %1, %0"
3864   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3865    (set_attr "length" "4,4,16,4,4,4,4,*")])
3867 (define_split
3868   [(set (match_operand:DI 0 "arith_reg_operand" "")
3869         (match_operand:DI 1 "immediate_operand" ""))]
3870   "TARGET_SHMEDIA && reload_completed
3871    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3872   [(set (match_dup 0) (match_dup 1))]
3873   "
3875   rtx insn;
3877   if (TARGET_SHMEDIA64)
3878     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3879   else
3880     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3882   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3883                                         REG_NOTES (insn));
3885   DONE;
3888 (define_expand "movdi_const"
3889   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3890         (const:DI (sign_extend:DI
3891                    (truncate:HI
3892                     (ashiftrt:DI
3893                      (match_operand:DI 1 "immediate_operand" "s")
3894                      (const_int 48))))))
3895    (set (match_dup 0)
3896         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3897                 (zero_extend:DI
3898                  (truncate:HI
3899                   (const:DI
3900                    (sign_extend:DI
3901                     (truncate:HI
3902                      (ashiftrt:SI
3903                       (match_dup 1)
3904                       (const_int 32)))))))))
3905    (set (match_dup 0)
3906         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3907                 (zero_extend:DI
3908                  (truncate:HI
3909                   (const:DI
3910                    (sign_extend:DI
3911                     (truncate:HI
3912                      (ashiftrt:SI
3913                       (match_dup 1)
3914                       (const_int 16)))))))))
3915    (set (match_dup 0)
3916         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3917                 (zero_extend:DI
3918                  (truncate:HI
3919                   (const:DI
3920                    (sign_extend:DI
3921                     (truncate:HI
3922                      (match_dup 1))))))))]
3923   "TARGET_SHMEDIA64 && reload_completed
3924    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3925   "
3927   sh_mark_label (operands[1], 4);
3930 (define_expand "movdi_const_32bit"
3931   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3932         (const:DI (sign_extend:DI
3933                    (truncate:HI
3934                     (ashiftrt:DI
3935                      (match_operand:DI 1 "immediate_operand" "s")
3936                      (const_int 16))))))
3937    (set (match_dup 0)
3938         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3939                 (zero_extend:DI
3940                  (truncate:HI
3941                   (const:DI
3942                    (sign_extend:DI
3943                     (truncate:HI
3944                      (match_dup 1))))))))]
3945   "TARGET_SHMEDIA32 && reload_completed
3946    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3947   "
3949   sh_mark_label (operands[1], 2);
3952 (define_expand "movdi_const_16bit"
3953   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3954         (const:DI (sign_extend:DI
3955                    (truncate:HI
3956                     (match_operand:DI 1 "immediate_operand" "s")))))]
3957   "TARGET_SHMEDIA && flag_pic && reload_completed
3958    && GET_CODE (operands[1]) == SYMBOL_REF"
3959   "")
3961 (define_split
3962   [(set (match_operand:DI 0 "arith_reg_operand" "")
3963         (match_operand:DI 1 "immediate_operand" ""))]
3964   "TARGET_SHMEDIA && reload_completed
3965    && GET_CODE (operands[1]) == CONST_INT
3966    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3967   [(set (match_dup 0) (match_dup 2))
3968    (match_dup 1)]
3969   "
3971   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3972   unsigned HOST_WIDE_INT low = val;
3973   unsigned HOST_WIDE_INT high = val;
3974   unsigned HOST_WIDE_INT sign;
3975   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3977   /* Sign-extend the 16 least-significant bits.  */
3978   low &= 0xffff;
3979   low ^= 0x8000;
3980   low -= 0x8000;
3982   /* Arithmetic shift right the word by 16 bits.  */
3983   high >>= 16;
3984   sign = 1;
3985   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3986   high ^= sign;
3987   high -= sign;
3988   do
3989     {
3990       /* If we can't generate the constant with a two-insn movi / shori
3991          sequence, try some other strategies.  */
3992       if (! CONST_OK_FOR_I16 (high))
3993         {
3994           /* Try constant load / left shift.  We know VAL != 0.  */
3995           val2 = val ^ (val-1);
3996           if (val2 > 0x1ffff)
3997             {
3998               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4000               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4001                   || (! CONST_OK_FOR_I16 (high >> 16)
4002                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4003                 {
4004                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4005                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4006                                                    GEN_INT (trailing_zeroes));
4007                   break;
4008                 }
4009             }
4010           /* Try constant load / right shift.  */
4011           val2 = (val >> 15) + 1;
4012           if (val2 == (val2 & -val2))
4013             {
4014               int shift = 49 - exact_log2 (val2);
4016               val2 = trunc_int_for_mode (val << shift, DImode);
4017               if (CONST_OK_FOR_I16 (val2))
4018                 {
4019                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4020                                                    GEN_INT (shift));
4021                   break;
4022                 }
4023             }
4024           /* Try mperm.w .  */
4025           val2 = val & 0xffff;
4026           if ((val >> 16 & 0xffff) == val2
4027               && (val >> 32 & 0xffff) == val2
4028               && (val >> 48 & 0xffff) == val2)
4029             {
4030               val2 = (HOST_WIDE_INT) val >> 48;
4031               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4032               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4033               break;
4034             }
4035           /* Try movi / mshflo.l  */
4036           val2 = (HOST_WIDE_INT) val >> 32;
4037           if (val2 == ((unsigned HOST_WIDE_INT)
4038                         trunc_int_for_mode (val, SImode)))
4039             {
4040               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4041                                              operands[0]);
4042               break;
4043             }
4044           /* Try movi / mshflo.l w/ r63.  */
4045           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4046           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4047             {
4048               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4049                                              const0_rtx);
4050               break;
4051             }
4052         }
4053       val2 = high;
4054       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4055     }
4056   while (0);
4057   operands[2] = GEN_INT (val2);
4060 (define_split
4061   [(set (match_operand:DI 0 "arith_reg_operand" "")
4062         (match_operand:DI 1 "immediate_operand" ""))]
4063   "TARGET_SHMEDIA && reload_completed
4064    && GET_CODE (operands[1]) == CONST_DOUBLE"
4065   [(set (match_dup 0) (match_dup 2))
4066   (set (match_dup 0)
4067        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4068                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4069   "
4071   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4072   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4073   unsigned HOST_WIDE_INT val = low;
4074   unsigned HOST_WIDE_INT sign;
4076   /* Sign-extend the 16 least-significant bits.  */
4077   val &= 0xffff;
4078   val ^= 0x8000;
4079   val -= 0x8000;
4080   operands[1] = GEN_INT (val);
4082   /* Arithmetic shift right the double-word by 16 bits.  */
4083   low >>= 16;
4084   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4085   high >>= 16;
4086   sign = 1;
4087   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4088   high ^= sign;
4089   high -= sign;
4091   /* This will only be true if high is a sign-extension of low, i.e.,
4092      it must be either 0 or (unsigned)-1, and be zero iff the
4093      most-significant bit of low is set.  */
4094   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4095     operands[2] = GEN_INT (low);
4096   else
4097     operands[2] = immed_double_const (low, high, DImode);
4100 (define_insn "shori_media"
4101   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4102         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4103                            (const_int 16))
4104                 (zero_extend:DI
4105                  (truncate:HI
4106                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4107   "TARGET_SHMEDIA"
4108   "@
4109         shori   %u2, %0
4110         #"
4111   [(set_attr "type" "arith_media,*")])
4113 (define_expand "movdi"
4114   [(set (match_operand:DI 0 "general_movdst_operand" "")
4115         (match_operand:DI 1 "general_movsrc_operand" ""))]
4116   ""
4117   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4119 (define_insn "movdf_media"
4120   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4121         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4122   "TARGET_SHMEDIA_FPU
4123    && (register_operand (operands[0], DFmode)
4124        || sh_register_operand (operands[1], DFmode))"
4125   "@
4126         fmov.d  %1, %0
4127         fmov.qd %N1, %0
4128         fmov.dq %1, %0
4129         add     %1, r63, %0
4130         #
4131         fld%M1.d        %m1, %0
4132         fst%M0.d        %m0, %1
4133         ld%M1.q %m1, %0
4134         st%M0.q %m0, %N1"
4135   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4137 (define_insn "movdf_media_nofpu"
4138   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4139         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4140   "TARGET_SHMEDIA
4141    && (register_operand (operands[0], DFmode)
4142        || sh_register_operand (operands[1], DFmode))"
4143   "@
4144         add     %1, r63, %0
4145         #
4146         ld%M1.q %m1, %0
4147         st%M0.q %m0, %N1"
4148   [(set_attr "type" "arith_media,*,load_media,store_media")])
4150 (define_split
4151   [(set (match_operand:DF 0 "arith_reg_operand" "")
4152         (match_operand:DF 1 "immediate_operand" ""))]
4153   "TARGET_SHMEDIA && reload_completed"
4154   [(set (match_dup 3) (match_dup 2))]
4155   "
4157   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4158   long values[2];
4159   REAL_VALUE_TYPE value;
4161   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4162   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4164   if (HOST_BITS_PER_WIDE_INT >= 64)
4165     operands[2] = immed_double_const ((unsigned long) values[endian]
4166                                       | ((HOST_WIDE_INT) values[1 - endian]
4167                                          << 32), 0, DImode);
4168   else if (HOST_BITS_PER_WIDE_INT == 32)
4169     operands[2] = immed_double_const (values[endian], values[1 - endian],
4170                                       DImode);
4171   else
4172     abort ();
4174   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4177 ;; ??? This should be a define expand.
4179 (define_insn "movdf_k"
4180   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4181         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4182   "TARGET_SH1
4183    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
4184        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4185        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4186        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4187    && (arith_reg_operand (operands[0], DFmode)
4188        || arith_reg_operand (operands[1], DFmode))"
4189   "* return output_movedouble (insn, operands, DFmode);"
4190   [(set_attr "length" "4")
4191    (set_attr "type" "move,pcload,load,store")])
4193 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4194 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4195 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4196 ;; the d/m/c/X alternative, which is split later into single-precision
4197 ;; instructions.  And when not optimizing, no splits are done before fixing
4198 ;; up pcloads, so we need usable length information for that.
4199 (define_insn "movdf_i4"
4200   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4201         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4202    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4203    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4204   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4205    && (arith_reg_operand (operands[0], DFmode)
4206        || arith_reg_operand (operands[1], DFmode))"
4207   "@
4208         fmov    %1,%0
4209         #
4210         #
4211         fmov.d  %1,%0
4212         fmov.d  %1,%0
4213         #
4214         #
4215         #
4216         #
4217         #"
4218   [(set_attr_alternative "length"
4219      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4220       (const_int 4)
4221       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4222       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4223       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4224       (const_int 4)
4225       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4226       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4227       ;; increment or decrement r15 explicitly.
4228       (if_then_else
4229        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4230        (const_int 10) (const_int 8))
4231       (if_then_else
4232        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4233        (const_int 10) (const_int 8))])
4234    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4235    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4236    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4237                                            (const_string "double")
4238                                            (const_string "none")))])
4240 ;; Moving DFmode between fp/general registers through memory
4241 ;; (the top of the stack) is faster than moving through fpul even for
4242 ;; little endian.  Because the type of an instruction is important for its
4243 ;; scheduling,  it is beneficial to split these operations, rather than
4244 ;; emitting them in one single chunk, even if this will expose a stack
4245 ;; use that will prevent scheduling of other stack accesses beyond this
4246 ;; instruction.
4247 (define_split
4248   [(set (match_operand:DF 0 "register_operand" "")
4249         (match_operand:DF 1 "register_operand" ""))
4250    (use (match_operand:PSI 2 "fpscr_operand" ""))
4251    (clobber (match_scratch:SI 3 "=X"))]
4252   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
4253    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4254   [(const_int 0)]
4255   "
4257   rtx insn, tos;
4259   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4260     {
4261       emit_move_insn (stack_pointer_rtx,
4262                       plus_constant (stack_pointer_rtx, -8));
4263       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4264     }
4265   else
4266     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4267   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4268   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4269     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4270   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4271     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4272   else
4273     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4274   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4275   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4276     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4277   else
4278     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4279   DONE;
4282 ;; local-alloc sometimes allocates scratch registers even when not required,
4283 ;; so we must be prepared to handle these.
4285 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4286 (define_split
4287   [(set (match_operand:DF 0 "general_movdst_operand" "")
4288         (match_operand:DF 1 "general_movsrc_operand"  ""))
4289    (use (match_operand:PSI 2 "fpscr_operand" ""))
4290    (clobber (match_scratch:SI 3 ""))]
4291   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4292    && reload_completed
4293    && true_regnum (operands[0]) < 16
4294    && true_regnum (operands[1]) < 16"
4295   [(set (match_dup 0) (match_dup 1))]
4296   "
4298   /* If this was a reg <-> mem operation with base + index reg addressing,
4299      we have to handle this in a special way.  */
4300   rtx mem = operands[0];
4301   int store_p = 1;
4302   if (! memory_operand (mem, DFmode))
4303     {
4304       mem = operands[1];
4305       store_p = 0;
4306     }
4307   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4308     mem = SUBREG_REG (mem);
4309   if (GET_CODE (mem) == MEM)
4310     {
4311       rtx addr = XEXP (mem, 0);
4312       if (GET_CODE (addr) == PLUS
4313           && GET_CODE (XEXP (addr, 0)) == REG
4314           && GET_CODE (XEXP (addr, 1)) == REG)
4315         {
4316           int offset;
4317           rtx reg0 = gen_rtx_REG (Pmode, 0);
4318           rtx regop = operands[store_p], word0 ,word1;
4320           if (GET_CODE (regop) == SUBREG)
4321             alter_subreg (&regop);
4322           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4323             offset = 2;
4324           else
4325             offset = 4;
4326           mem = copy_rtx (mem);
4327           PUT_MODE (mem, SImode);
4328           word0 = gen_rtx_SUBREG (SImode, regop, 0);
4329           alter_subreg (&word0);
4330           word1 = gen_rtx_SUBREG (SImode, regop, 4);
4331           alter_subreg (&word1);
4332           if (store_p || ! refers_to_regno_p (REGNO (word0),
4333                                               REGNO (word0) + 1, addr, 0))
4334             {
4335               emit_insn (store_p
4336                          ? gen_movsi_ie (mem, word0)
4337                          : gen_movsi_ie (word0, mem));
4338               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4339               mem = copy_rtx (mem);
4340               emit_insn (store_p
4341                          ? gen_movsi_ie (mem, word1)
4342                          : gen_movsi_ie (word1, mem));
4343               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4344             }
4345           else
4346             {
4347               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4348               emit_insn (gen_movsi_ie (word1, mem));
4349               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4350               mem = copy_rtx (mem);
4351               emit_insn (gen_movsi_ie (word0, mem));
4352             }
4353           DONE;
4354         }
4355     }
4358 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4359 (define_split
4360   [(set (match_operand:DF 0 "register_operand" "")
4361         (match_operand:DF 1 "memory_operand"  ""))
4362    (use (match_operand:PSI 2 "fpscr_operand" ""))
4363    (clobber (reg:SI R0_REG))]
4364   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
4365   [(parallel [(set (match_dup 0) (match_dup 1))
4366               (use (match_dup 2))
4367               (clobber (scratch:SI))])]
4368   "")
4370 (define_expand "reload_indf"
4371   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4372                    (match_operand:DF 1 "immediate_operand" "FQ"))
4373               (use (reg:PSI FPSCR_REG))
4374               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4375   "TARGET_SH1"
4376   "")
4378 (define_expand "reload_outdf"
4379   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4380                    (match_operand:DF 1 "register_operand" "af,r"))
4381               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4382   "TARGET_SH1"
4383   "")
4385 ;; Simplify no-op moves.
4386 (define_split
4387   [(set (match_operand:SF 0 "register_operand" "")
4388         (match_operand:SF 1 "register_operand" ""))
4389    (use (match_operand:PSI 2 "fpscr_operand" ""))
4390    (clobber (match_scratch:SI 3 ""))]
4391   "TARGET_SH2E && reload_completed
4392    && true_regnum (operands[0]) == true_regnum (operands[1])"
4393   [(set (match_dup 0) (match_dup 0))]
4394   "")
4396 ;; fmovd substitute post-reload splits
4397 (define_split
4398   [(set (match_operand:DF 0 "register_operand" "")
4399         (match_operand:DF 1 "register_operand" ""))
4400    (use (match_operand:PSI 2 "fpscr_operand" ""))
4401    (clobber (match_scratch:SI 3 ""))]
4402   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4403    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4404    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4405   [(const_int 0)]
4406   "
4408   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4409   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4410                            gen_rtx_REG (SFmode, src), operands[2]));
4411   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4412                            gen_rtx_REG (SFmode, src + 1), operands[2]));
4413   DONE;
4416 (define_split
4417   [(set (match_operand:DF 0 "register_operand" "")
4418         (mem:DF (match_operand:SI 1 "register_operand" "")))
4419    (use (match_operand:PSI 2 "fpscr_operand" ""))
4420    (clobber (match_scratch:SI 3 ""))]
4421   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4422    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4423    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4424   [(const_int 0)]
4425   "
4427   int regno = true_regnum (operands[0]);
4428   rtx insn;
4429   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4431   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4432                                            regno + !! TARGET_LITTLE_ENDIAN),
4433                                   mem2, operands[2]));
4434   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4435   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4436                                            regno + ! TARGET_LITTLE_ENDIAN),
4437                                   gen_rtx_MEM (SFmode, operands[1]),
4438                                   operands[2]));
4439   DONE;
4442 (define_split
4443   [(set (match_operand:DF 0 "register_operand" "")
4444         (match_operand:DF 1 "memory_operand" ""))
4445    (use (match_operand:PSI 2 "fpscr_operand" ""))
4446    (clobber (match_scratch:SI 3 ""))]
4447   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4448    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4449   [(const_int 0)]
4450   "
4452   int regno = true_regnum (operands[0]);
4453   rtx addr, insn, adjust = NULL_RTX;
4454   rtx mem2 = copy_rtx (operands[1]);
4455   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4456   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4458   PUT_MODE (mem2, SFmode);
4459   operands[1] = copy_rtx (mem2);
4460   addr = XEXP (mem2, 0);
4461   if (GET_CODE (addr) != POST_INC)
4462     {
4463       /* If we have to modify the stack pointer, the value that we have
4464          read with post-increment might be modified by an interrupt,
4465          so write it back.  */
4466       if (REGNO (addr) == STACK_POINTER_REGNUM)
4467         adjust = gen_push_e (reg0);
4468       else
4469         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4470       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4471     }
4472   addr = XEXP (addr, 0);
4473   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4474   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4475   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4476   if (adjust)
4477     emit_insn (adjust);
4478   else
4479     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4480   DONE;
4483 (define_split
4484   [(set (match_operand:DF 0 "memory_operand" "")
4485         (match_operand:DF 1 "register_operand" ""))
4486    (use (match_operand:PSI 2 "fpscr_operand" ""))
4487    (clobber (match_scratch:SI 3 ""))]
4488   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4489    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4490   [(const_int 0)]
4491   "
4493   int regno = true_regnum (operands[1]);
4494   rtx insn, addr, adjust = NULL_RTX;
4496   operands[0] = copy_rtx (operands[0]);
4497   PUT_MODE (operands[0], SFmode);
4498   insn = emit_insn (gen_movsf_ie (operands[0],
4499                                   gen_rtx_REG (SFmode,
4500                                            regno + ! TARGET_LITTLE_ENDIAN),
4501                                   operands[2]));
4502   operands[0] = copy_rtx (operands[0]);
4503   addr = XEXP (operands[0], 0);
4504   if (GET_CODE (addr) != PRE_DEC)
4505     {
4506       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4507       emit_insn_before (adjust, insn);
4508       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4509     }
4510   addr = XEXP (addr, 0);
4511   if (! adjust)
4512     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4513   insn = emit_insn (gen_movsf_ie (operands[0],
4514                                   gen_rtx_REG (SFmode,
4515                                            regno + !! TARGET_LITTLE_ENDIAN),
4516                                   operands[2]));
4517   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4518   DONE;
4521 ;; If the output is a register and the input is memory or a register, we have
4522 ;; to be careful and see which word needs to be loaded first.
4524 (define_split
4525   [(set (match_operand:DF 0 "general_movdst_operand" "")
4526         (match_operand:DF 1 "general_movsrc_operand" ""))]
4527   "TARGET_SH1 && reload_completed"
4528   [(set (match_dup 2) (match_dup 3))
4529    (set (match_dup 4) (match_dup 5))]
4530   "
4532   int regno;
4534   if ((GET_CODE (operands[0]) == MEM
4535        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4536       || (GET_CODE (operands[1]) == MEM
4537           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4538     FAIL;
4540   if (GET_CODE (operands[0]) == REG)
4541     regno = REGNO (operands[0]);
4542   else if (GET_CODE (operands[0]) == SUBREG)
4543     regno = subreg_regno (operands[0]);
4544   else if (GET_CODE (operands[0]) == MEM)
4545     regno = -1;
4546   else
4547     abort ();
4549   if (regno == -1
4550       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4551     {
4552       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4553       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4554       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4555       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4556     }
4557   else
4558     {
4559       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4560       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4561       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4562       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4563     }
4565   if (operands[2] == 0 || operands[3] == 0
4566       || operands[4] == 0 || operands[5] == 0)
4567     FAIL;
4570 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4571 ;; used only once, let combine add in the index again.
4573 (define_split
4574   [(set (match_operand:SI 0 "register_operand" "")
4575         (match_operand:SI 1 "" ""))
4576    (clobber (match_operand 2 "register_operand" ""))]
4577   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4578   [(use (reg:SI R0_REG))]
4579   "
4581   rtx addr, reg, const_int;
4583   if (GET_CODE (operands[1]) != MEM)
4584     FAIL;
4585   addr = XEXP (operands[1], 0);
4586   if (GET_CODE (addr) != PLUS)
4587     FAIL;
4588   reg = XEXP (addr, 0);
4589   const_int = XEXP (addr, 1);
4590   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4591          && GET_CODE (const_int) == CONST_INT))
4592     FAIL;
4593   emit_move_insn (operands[2], const_int);
4594   emit_move_insn (operands[0],
4595                   change_address (operands[1], VOIDmode,
4596                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4597   DONE;
4600 (define_split
4601   [(set (match_operand:SI 1 "" "")
4602         (match_operand:SI 0 "register_operand" ""))
4603    (clobber (match_operand 2 "register_operand" ""))]
4604   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4605   [(use (reg:SI R0_REG))]
4606   "
4608   rtx addr, reg, const_int;
4610   if (GET_CODE (operands[1]) != MEM)
4611     FAIL;
4612   addr = XEXP (operands[1], 0);
4613   if (GET_CODE (addr) != PLUS)
4614     FAIL;
4615   reg = XEXP (addr, 0);
4616   const_int = XEXP (addr, 1);
4617   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4618          && GET_CODE (const_int) == CONST_INT))
4619     FAIL;
4620   emit_move_insn (operands[2], const_int);
4621   emit_move_insn (change_address (operands[1], VOIDmode,
4622                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4623                   operands[0]);
4624   DONE;
4627 (define_expand "movdf"
4628   [(set (match_operand:DF 0 "general_movdst_operand" "")
4629         (match_operand:DF 1 "general_movsrc_operand" ""))]
4630   ""
4631   "
4633   if (prepare_move_operands (operands, DFmode)) DONE;
4634   if (TARGET_SHMEDIA)
4635     {
4636       if (TARGET_SHMEDIA_FPU)
4637         emit_insn (gen_movdf_media (operands[0], operands[1]));
4638       else
4639         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4640       DONE;
4641     }
4642   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
4643     {
4644       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4645       DONE;
4646     }
4649 ;;This is incompatible with the way gcc uses subregs.
4650 ;;(define_insn "movv2sf_i"
4651 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4652 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4653 ;;  "TARGET_SHMEDIA_FPU
4654 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4655 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4656 ;;  "@
4657 ;;      #
4658 ;;      fld%M1.p        %m1, %0
4659 ;;      fst%M0.p        %m0, %1"
4660 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4662 (define_insn_and_split "movv2sf_i"
4663   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4664         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4665   "TARGET_SHMEDIA_FPU"
4666   "#"
4667   "TARGET_SHMEDIA_FPU && reload_completed"
4668   [(set (match_dup 0) (match_dup 1))]
4669   "
4671   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4672   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4675 (define_expand "movv2sf"
4676   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4677         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4678   "TARGET_SHMEDIA_FPU"
4679   "
4681   if (prepare_move_operands (operands, V2SFmode))
4682     DONE;
4685 (define_expand "addv2sf3"
4686   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4687    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4688    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4689   "TARGET_SHMEDIA_FPU"
4690   "
4692   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4693   DONE;
4696 (define_expand "subv2sf3"
4697   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4698    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4699    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4700   "TARGET_SHMEDIA_FPU"
4701   "
4703   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4704   DONE;
4707 (define_expand "mulv2sf3"
4708   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4709    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4710    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4711   "TARGET_SHMEDIA_FPU"
4712   "
4714   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4715   DONE;
4718 (define_expand "divv2sf3"
4719   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4720    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4721    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4722   "TARGET_SHMEDIA_FPU"
4723   "
4725   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4726   DONE;
4729 (define_insn_and_split "*movv4sf_i"
4730   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4731         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4732   "TARGET_SHMEDIA_FPU"
4733   "#"
4734   "&& reload_completed"
4735   [(const_int 0)]
4736   "
4738   int i;
4740   for (i = 0; i < 4/2; i++)
4741     {
4742       rtx x, y;
4744       if (GET_CODE (operands[0]) == MEM)
4745         x = gen_rtx_MEM (V2SFmode,
4746                          plus_constant (XEXP (operands[0], 0),
4747                                         i * GET_MODE_SIZE (V2SFmode)));
4748       else
4749         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4751       if (GET_CODE (operands[1]) == MEM)
4752         y = gen_rtx_MEM (V2SFmode,
4753                          plus_constant (XEXP (operands[1], 0),
4754                                         i * GET_MODE_SIZE (V2SFmode)));
4755       else
4756         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4758       emit_insn (gen_movv2sf_i (x, y));
4759     }
4761   DONE;
4763   [(set_attr "length" "8")])
4765 (define_expand "movv4sf"
4766   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4767         (match_operand:V4SF 1 "general_operand" ""))]
4768   "TARGET_SHMEDIA_FPU"
4769   "
4771   if (prepare_move_operands (operands, V4SFmode))
4772     DONE;
4775 (define_insn_and_split "*movv16sf_i"
4776   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4777         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4778   "TARGET_SHMEDIA_FPU"
4779   "#"
4780   "&& reload_completed"
4781   [(const_int 0)]
4782   "
4784   int i;
4786   for (i = 0; i < 16/2; i++)
4787     {
4788       rtx x,y;
4790       if (GET_CODE (operands[0]) == MEM)
4791         x = gen_rtx_MEM (V2SFmode,
4792                          plus_constant (XEXP (operands[0], 0),
4793                                         i * GET_MODE_SIZE (V2SFmode)));
4794       else
4795         {
4796           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4797           alter_subreg (&x);
4798         }
4800       if (GET_CODE (operands[1]) == MEM)
4801         y = gen_rtx_MEM (V2SFmode,
4802                          plus_constant (XEXP (operands[1], 0),
4803                                         i * GET_MODE_SIZE (V2SFmode)));
4804       else
4805         {
4806           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4807           alter_subreg (&y);
4808         }
4810       emit_insn (gen_movv2sf_i (x, y));
4811     }
4813   DONE;
4815   [(set_attr "length" "32")])
4817 (define_expand "movv16sf"
4818   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4819         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4820   "TARGET_SHMEDIA_FPU"
4821   "
4823   if (prepare_move_operands (operands, V16SFmode))
4824     DONE;
4827 (define_insn "movsf_media"
4828   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4829         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4830   "TARGET_SHMEDIA_FPU
4831    && (register_operand (operands[0], SFmode)
4832        || sh_register_operand (operands[1], SFmode))"
4833   "@
4834         fmov.s  %1, %0
4835         fmov.ls %N1, %0
4836         fmov.sl %1, %0
4837         add.l   %1, r63, %0
4838         #
4839         fld%M1.s        %m1, %0
4840         fst%M0.s        %m0, %1
4841         ld%M1.l %m1, %0
4842         st%M0.l %m0, %N1"
4843   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4845 (define_insn "movsf_media_nofpu"
4846   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4847         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4848   "TARGET_SHMEDIA
4849    && (register_operand (operands[0], SFmode)
4850        || sh_register_operand (operands[1], SFmode))"
4851   "@
4852         add.l   %1, r63, %0
4853         #
4854         ld%M1.l %m1, %0
4855         st%M0.l %m0, %N1"
4856   [(set_attr "type" "arith_media,*,load_media,store_media")])
4858 (define_split
4859   [(set (match_operand:SF 0 "arith_reg_operand" "")
4860         (match_operand:SF 1 "immediate_operand" ""))]
4861   "TARGET_SHMEDIA && reload_completed
4862    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4863   [(set (match_dup 3) (match_dup 2))]
4864   "
4866   long values;
4867   REAL_VALUE_TYPE value;
4869   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4870   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4871   operands[2] = GEN_INT (values);
4873   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4876 (define_insn "movsf_i"
4877   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4878         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4879   "TARGET_SH1
4880    && (! TARGET_SH2E
4881        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4882        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4883        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4884    && (arith_reg_operand (operands[0], SFmode)
4885        || arith_reg_operand (operands[1], SFmode))"
4886   "@
4887         mov     %1,%0
4888         mov     #0,%0
4889         mov.l   %1,%0
4890         mov.l   %1,%0
4891         mov.l   %1,%0
4892         lds     %1,%0
4893         sts     %1,%0"
4894   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4896 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4897 ;; update_flow_info would not know where to put REG_EQUAL notes
4898 ;; when the destination changes mode.
4899 (define_insn "movsf_ie"
4900   [(set (match_operand:SF 0 "general_movdst_operand"
4901          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4902         (match_operand:SF 1 "general_movsrc_operand"
4903           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4904    (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"))
4905    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4907   "TARGET_SH2E
4908    && (arith_reg_operand (operands[0], SFmode)
4909        || arith_reg_operand (operands[1], SFmode)
4910        || arith_reg_operand (operands[3], SImode)
4911        || (fpul_operand (operands[0], SFmode)
4912            && memory_operand (operands[1], SFmode)
4913            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4914        || (fpul_operand (operands[1], SFmode)
4915            && memory_operand (operands[0], SFmode)
4916            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4917   "@
4918         fmov    %1,%0
4919         mov     %1,%0
4920         fldi0   %0
4921         fldi1   %0
4922         #
4923         fmov.s  %1,%0
4924         fmov.s  %1,%0
4925         mov.l   %1,%0
4926         mov.l   %1,%0
4927         mov.l   %1,%0
4928         fsts    fpul,%0
4929         flds    %1,fpul
4930         lds.l   %1,%0
4931         #
4932         sts     %1,%0
4933         lds     %1,%0
4934         sts.l   %1,%0
4935         lds.l   %1,%0
4936         ! move optimized away"
4937   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4938    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4939    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
4940    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4941                                            (const_string "single")
4942                                            (const_string "none")))])
4944 (define_split
4945   [(set (match_operand:SF 0 "register_operand" "")
4946         (match_operand:SF 1 "register_operand" ""))
4947    (use (match_operand:PSI 2 "fpscr_operand" ""))
4948    (clobber (reg:SI FPUL_REG))]
4949   "TARGET_SH1"
4950   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4951               (use (match_dup 2))
4952               (clobber (scratch:SI))])
4953    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4954               (use (match_dup 2))
4955               (clobber (scratch:SI))])]
4956   "")
4958 (define_expand "movsf"
4959   [(set (match_operand:SF 0 "general_movdst_operand" "")
4960         (match_operand:SF 1 "general_movsrc_operand" ""))]
4961   ""
4962   "
4964   if (prepare_move_operands (operands, SFmode))
4965     DONE;
4966   if (TARGET_SHMEDIA)
4967     {
4968       if (TARGET_SHMEDIA_FPU)
4969         emit_insn (gen_movsf_media (operands[0], operands[1]));
4970       else
4971         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4972       DONE;
4973     }
4974   if (TARGET_SH2E)
4975     {
4976       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4977       DONE;
4978     }
4981 (define_insn "mov_nop"
4982   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4983   "TARGET_SH2E"
4984   ""
4985   [(set_attr "length" "0")
4986    (set_attr "type" "nil")])
4988 (define_expand "reload_insf"
4989   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4990                    (match_operand:SF 1 "immediate_operand" "FQ"))
4991               (use (reg:PSI FPSCR_REG))
4992               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4993   "TARGET_SH1"
4994   "")
4996 (define_expand "reload_insi"
4997   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4998                    (match_operand:SF 1 "immediate_operand" "FQ"))
4999               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5000   "TARGET_SH1"
5001   "")
5003 (define_insn "*movsi_y"
5004   [(set (match_operand:SI 0 "register_operand" "=y,y")
5005         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5006    (clobber (match_scratch:SI 2 "=&z,r"))]
5007   "TARGET_SH2E
5008    && (reload_in_progress || reload_completed)"
5009   "#"
5010   [(set_attr "length" "4")
5011    (set_attr "type" "pcload,move")])
5013 (define_split
5014   [(set (match_operand:SI 0 "register_operand" "")
5015         (match_operand:SI 1 "immediate_operand" ""))
5016    (clobber (match_operand:SI 2 "register_operand" ""))]
5017   "TARGET_SH1"
5018   [(set (match_dup 2) (match_dup 1))
5019    (set (match_dup 0) (match_dup 2))]
5020   "")
5022 (define_split
5023   [(set (match_operand:SI 0 "register_operand" "")
5024         (match_operand:SI 1 "memory_operand" ""))
5025    (clobber (reg:SI R0_REG))]
5026   "TARGET_SH1"
5027   [(set (match_dup 0) (match_dup 1))]
5028   "")
5030 ;; ------------------------------------------------------------------------
5031 ;; Define the real conditional branch instructions.
5032 ;; ------------------------------------------------------------------------
5034 (define_insn "branch_true"
5035   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5036                            (label_ref (match_operand 0 "" ""))
5037                            (pc)))]
5038   "TARGET_SH1"
5039   "* return output_branch (1, insn, operands);"
5040   [(set_attr "type" "cbranch")])
5042 (define_insn "branch_false"
5043   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5044                            (label_ref (match_operand 0 "" ""))
5045                            (pc)))]
5046   "TARGET_SH1"
5047   "* return output_branch (0, insn, operands);"
5048   [(set_attr "type" "cbranch")])
5050 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5051 ;; which destination is too far away.
5052 ;; The const_int_operand is distinct for each branch target; it avoids
5053 ;; unwanted matches with redundant_insn.
5054 (define_insn "block_branch_redirect"
5055   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5056   "TARGET_SH1"
5057   ""
5058   [(set_attr "length" "0")])
5060 ;; This one has the additional purpose to record a possible scratch register
5061 ;; for the following branch.
5062 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5063 ;; because the insn then might be deemed dead and deleted.  And we can't
5064 ;; make the use in the jump insn explicit because that would disable
5065 ;; delay slot scheduling from the target.
5066 (define_insn "indirect_jump_scratch"
5067   [(set (match_operand:SI 0 "register_operand" "=r")
5068         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5069    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5070   "TARGET_SH1"
5071   ""
5072   [(set_attr "length" "0")])
5074 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5075 ;; being pulled into the delay slot of a condbranch that has been made to
5076 ;; jump around the unconditional jump because it was out of range.
5077 (define_insn "stuff_delay_slot"
5078   [(set (pc)
5079         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5080    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5081   "TARGET_SH1"
5082   ""
5083   [(set_attr "length" "0")
5084    (set_attr "cond_delay_slot" "yes")])
5086 ;; Conditional branch insns
5088 (define_expand "beq_media"
5089   [(set (pc)
5090         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5091                           (match_operand:DI 2 "arith_operand" "r,I06"))
5092                       (label_ref:DI (match_operand 0 "" ""))
5093                       (pc)))]
5094   "TARGET_SHMEDIA"
5095   "")
5097 (define_insn "*beq_media_i"
5098   [(set (pc)
5099         (if_then_else (match_operator 3 "equality_comparison_operator"
5100                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5101                          (match_operand:DI 2 "arith_operand" "r,I06")])
5102                       (match_operand:DI 0 "target_operand" "b,b")
5103                       (pc)))]
5104   "TARGET_SHMEDIA"
5105   "@
5106         b%o3%'  %1, %2, %0
5107         b%o3i%' %1, %2, %0"
5108   [(set_attr "type" "cbranch_media")])
5110 (define_expand "bne_media"
5111   [(set (pc)
5112         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5113                           (match_operand:DI 2 "arith_operand" "r,I06"))
5114                       (label_ref:DI (match_operand 0 "" ""))
5115                       (pc)))]
5116   "TARGET_SHMEDIA"
5117   "")
5119 (define_expand "bgt_media"
5120   [(set (pc)
5121         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5122                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5123                       (label_ref:DI (match_operand 0 "" ""))
5124                       (pc)))]
5125   "TARGET_SHMEDIA"
5126   "")
5128 (define_expand "bge_media"
5129   [(set (pc)
5130         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5131                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5132                       (label_ref:DI (match_operand 0 "" ""))
5133                       (pc)))]
5134   "TARGET_SHMEDIA"
5135   "")
5137 (define_expand "bgtu_media"
5138   [(set (pc)
5139         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5140                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5141                       (label_ref:DI (match_operand 0 "" ""))
5142                       (pc)))]
5143   "TARGET_SHMEDIA"
5144   "")
5146 (define_expand "bgeu_media"
5147   [(set (pc)
5148         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5149                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5150                       (label_ref:DI (match_operand 0 "" ""))
5151                       (pc)))]
5152   "TARGET_SHMEDIA"
5153   "")
5155 (define_insn "*bgt_media_i"
5156   [(set (pc)
5157         (if_then_else (match_operator 3 "greater_comparison_operator"
5158                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5159                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5160                       (match_operand:DI 0 "target_operand" "b")
5161                       (pc)))]
5162   "TARGET_SHMEDIA"
5163   "b%o3%'       %N1, %N2, %0"
5164   [(set_attr "type" "cbranch_media")])
5166 ;; These are only needed to make invert_jump() happy.
5167 (define_insn "*blt_media_i"
5168   [(set (pc)
5169         (if_then_else (match_operator 3 "less_comparison_operator"
5170                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5171                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5172                       (match_operand:DI 0 "target_operand" "b")
5173                       (pc)))]
5174   "TARGET_SHMEDIA"
5175   "b%o3%'       %N2, %N1, %0"
5176   [(set_attr "type" "cbranch_media")])
5178 (define_expand "beq"
5179   [(set (pc)
5180         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5181                       (label_ref (match_operand 0 "" ""))
5182                       (pc)))]
5183   ""
5184   "
5186   if (TARGET_SHMEDIA)
5187     {
5188       if (GET_MODE (sh_compare_op0) != DImode)
5189         {
5190           rtx tmp = gen_reg_rtx (DImode);
5192           emit_insn (gen_seq (tmp));
5193           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5194           DONE;
5195         }
5197       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5198       emit_jump_insn (gen_beq_media (operands[0],
5199                                      sh_compare_op0, sh_compare_op1));
5200       DONE;
5201     }
5203   from_compare (operands, EQ);
5206 (define_expand "bne"
5207   [(set (pc)
5208         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5209                       (label_ref (match_operand 0 "" ""))
5210                       (pc)))]
5211   ""
5212   "
5214   if (TARGET_SHMEDIA)
5215     {
5216       if (GET_MODE (sh_compare_op0) != DImode)
5217         {
5218           rtx tmp = gen_reg_rtx (DImode);
5220           emit_insn (gen_seq (tmp));
5221           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5222           DONE;
5223         }
5225       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5226       emit_jump_insn (gen_bne_media (operands[0],
5227                                      sh_compare_op0, sh_compare_op1));
5228       DONE;
5229     }
5231   from_compare (operands, EQ);
5234 (define_expand "bgt"
5235   [(set (pc)
5236         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5237                       (label_ref (match_operand 0 "" ""))
5238                       (pc)))]
5239   ""
5240   "
5242   if (TARGET_SHMEDIA)
5243     {
5244       if (GET_MODE (sh_compare_op0) != DImode)
5245         {
5246           rtx tmp = gen_reg_rtx (DImode);
5248           emit_insn (gen_sgt (tmp));
5249           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5250           DONE;
5251         }
5253       if (sh_compare_op0 != const0_rtx)
5254         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5255       if (sh_compare_op1 != const0_rtx)
5256         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5257       emit_jump_insn (gen_bgt_media (operands[0],
5258                                      sh_compare_op0, sh_compare_op1));
5259       DONE;
5260     }
5262   from_compare (operands, GT);
5265 (define_expand "blt"
5266   [(set (pc)
5267         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5268                       (label_ref (match_operand 0 "" ""))
5269                       (pc)))]
5270   ""
5271   "
5273   if (TARGET_SHMEDIA)
5274     {
5275       if (GET_MODE (sh_compare_op0) != DImode)
5276         {
5277           rtx tmp = gen_reg_rtx (DImode);
5279           emit_insn (gen_slt (tmp));
5280           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5281           DONE;
5282         }
5284       if (sh_compare_op0 != const0_rtx)
5285         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5286       if (sh_compare_op1 != const0_rtx)
5287         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5288       emit_jump_insn (gen_bgt_media (operands[0],
5289                                      sh_compare_op1, sh_compare_op0));
5290       DONE;
5291     }
5293   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5294     {
5295       rtx tmp = sh_compare_op0;
5296       sh_compare_op0 = sh_compare_op1;
5297       sh_compare_op1 = tmp;
5298       emit_insn (gen_bgt (operands[0]));
5299       DONE;
5300     }
5301   from_compare (operands, GE);
5304 (define_expand "ble"
5305   [(set (pc)
5306         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5307                       (label_ref (match_operand 0 "" ""))
5308                       (pc)))]
5309   ""
5310   "
5312   if (TARGET_SHMEDIA)
5313     {
5314       if (GET_MODE (sh_compare_op0) != DImode)
5315         {
5316           rtx tmp = gen_reg_rtx (DImode);
5318           emit_insn (gen_sle (tmp));
5319           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5320           DONE;
5321         }
5323       if (sh_compare_op0 != const0_rtx)
5324         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5325       if (sh_compare_op1 != const0_rtx)
5326         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5327       emit_jump_insn (gen_bge_media (operands[0],
5328                                      sh_compare_op1, sh_compare_op0));
5329       DONE;
5330     }
5332   if (TARGET_SH2E
5333       && TARGET_IEEE
5334       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5335     {
5336       rtx tmp = sh_compare_op0;
5337       sh_compare_op0 = sh_compare_op1;
5338       sh_compare_op1 = tmp;
5339       emit_insn (gen_bge (operands[0]));
5340       DONE;
5341     }
5342   from_compare (operands, GT);
5345 (define_expand "bge"
5346   [(set (pc)
5347         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5348                       (label_ref (match_operand 0 "" ""))
5349                       (pc)))]
5350   ""
5351   "
5353   if (TARGET_SHMEDIA)
5354     {
5355       if (GET_MODE (sh_compare_op0) != DImode)
5356         {
5357           rtx tmp = gen_reg_rtx (DImode);
5359           emit_insn (gen_sge (tmp));
5360           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5361           DONE;
5362         }
5364       if (sh_compare_op0 != const0_rtx)
5365         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5366       if (sh_compare_op1 != const0_rtx)
5367         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5368       emit_jump_insn (gen_bge_media (operands[0],
5369                                      sh_compare_op0, sh_compare_op1));
5370       DONE;
5371     }
5373   if (TARGET_SH2E
5374       && ! TARGET_IEEE
5375       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5376     {
5377       rtx tmp = sh_compare_op0;
5378       sh_compare_op0 = sh_compare_op1;
5379       sh_compare_op1 = tmp;
5380       emit_insn (gen_ble (operands[0]));
5381       DONE;
5382     }
5383   from_compare (operands, GE);
5386 (define_expand "bgtu"
5387   [(set (pc)
5388         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5389                       (label_ref (match_operand 0 "" ""))
5390                       (pc)))]
5391   ""
5392   "
5394   if (TARGET_SHMEDIA)
5395     {
5396       if (sh_compare_op0 != const0_rtx)
5397         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5398       if (sh_compare_op1 != const0_rtx)
5399         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5400       emit_jump_insn (gen_bgtu_media (operands[0],
5401                                       sh_compare_op0, sh_compare_op1));
5402       DONE;
5403     }
5405   from_compare (operands, GTU);
5408 (define_expand "bltu"
5409   [(set (pc)
5410         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5411                       (label_ref (match_operand 0 "" ""))
5412                       (pc)))]
5413   ""
5414   "
5416   if (TARGET_SHMEDIA)
5417     {
5418       if (sh_compare_op0 != const0_rtx)
5419         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5420       if (sh_compare_op1 != const0_rtx)
5421         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5422       emit_jump_insn (gen_bgtu_media (operands[0],
5423                                       sh_compare_op1, sh_compare_op0));
5424       DONE;
5425     }
5427   from_compare (operands, GEU);
5430 (define_expand "bgeu"
5431   [(set (pc)
5432         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5433                       (label_ref (match_operand 0 "" ""))
5434                       (pc)))]
5435   ""
5436   "
5438   if (TARGET_SHMEDIA)
5439     {
5440       if (sh_compare_op0 != const0_rtx)
5441         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5442       if (sh_compare_op1 != const0_rtx)
5443         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5444       emit_jump_insn (gen_bgeu_media (operands[0],
5445                                       sh_compare_op0, sh_compare_op1));
5446       DONE;
5447     }
5449   from_compare (operands, GEU);
5452 (define_expand "bleu"
5453   [(set (pc)
5454         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5455                       (label_ref (match_operand 0 "" ""))
5456                       (pc)))]
5457   ""
5458   "
5460   if (TARGET_SHMEDIA)
5461     {
5462       if (sh_compare_op0 != const0_rtx)
5463         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5464       if (sh_compare_op1 != const0_rtx)
5465         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5466       emit_jump_insn (gen_bgeu_media (operands[0],
5467                                       sh_compare_op1, sh_compare_op0));
5468       DONE;
5469     }
5471   from_compare (operands, GTU);
5474 (define_expand "bunordered"
5475   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5476    (set (pc)
5477         (if_then_else (ne (match_dup 1) (const_int 0))
5478                       (label_ref:DI (match_operand 0 "" ""))
5479                       (pc)))]
5480   "TARGET_SHMEDIA"
5481   "
5483   operands[1] = gen_reg_rtx (DImode);
5484   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5485   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5488 ;; ------------------------------------------------------------------------
5489 ;; Jump and linkage insns
5490 ;; ------------------------------------------------------------------------
5492 (define_insn "jump_compact"
5493   [(set (pc)
5494         (label_ref (match_operand 0 "" "")))]
5495   "TARGET_SH1"
5496   "*
5498   /* The length is 16 if the delay slot is unfilled.  */
5499   if (get_attr_length(insn) > 4)
5500     return output_far_jump(insn, operands[0]);
5501   else
5502     return   \"bra      %l0%#\";
5504   [(set_attr "type" "jump")
5505    (set_attr "needs_delay_slot" "yes")])
5507 ;; ??? It would be much saner to explicitly use the scratch register
5508 ;; in the jump insn, and have indirect_jump_scratch only set it,
5509 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5510 ;; from the target then, as it uses simplejump_p.
5511 ;;(define_insn "jump_compact_far"
5512 ;;  [(set (pc)
5513 ;;      (label_ref (match_operand 0 "" "")))
5514 ;;   (use (match_operand 1 "register_operand" "r")]
5515 ;;  "TARGET_SH1"
5516 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5517 ;;  [(set_attr "type" "jump")
5518 ;;   (set_attr "needs_delay_slot" "yes")])
5520 (define_insn "jump_media"
5521   [(set (pc)
5522         (match_operand:DI 0 "target_operand" "b"))]
5523   "TARGET_SHMEDIA"
5524   "blink        %0, r63"
5525   [(set_attr "type" "jump_media")])
5527 (define_expand "jump"
5528   [(set (pc)
5529         (label_ref (match_operand 0 "" "")))]
5530   ""
5531   "
5533   if (TARGET_SH1)
5534     emit_jump_insn (gen_jump_compact (operands[0]));
5535   else if (TARGET_SHMEDIA)
5536     {
5537       if (reload_in_progress || reload_completed)
5538         FAIL;
5539       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5540                                                          operands[0])));
5541     }
5542   DONE;
5545 (define_insn "force_mode_for_call"
5546   [(use (reg:PSI FPSCR_REG))]
5547   "TARGET_SHCOMPACT"
5548   ""
5549   [(set_attr "length" "0")
5550    (set (attr "fp_mode")
5551         (if_then_else (eq_attr "fpu_single" "yes")
5552                       (const_string "single") (const_string "double")))])
5554 (define_insn "calli"
5555   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5556          (match_operand 1 "" ""))
5557    (use (reg:PSI FPSCR_REG))
5558    (clobber (reg:SI PR_REG))]
5559   "TARGET_SH1"
5560   "jsr  @%0%#"
5561   [(set_attr "type" "call")
5562    (set (attr "fp_mode")
5563         (if_then_else (eq_attr "fpu_single" "yes")
5564                       (const_string "single") (const_string "double")))
5565    (set_attr "needs_delay_slot" "yes")
5566    (set_attr "fp_set" "unknown")])
5568 ;; This is a pc-rel call, using bsrf, for use with PIC.
5570 (define_insn "calli_pcrel"
5571   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5572          (match_operand 1 "" ""))
5573    (use (reg:PSI FPSCR_REG))
5574    (use (reg:SI PIC_REG))
5575    (use (match_operand 2 "" ""))
5576    (clobber (reg:SI PR_REG))]
5577   "TARGET_SH2"
5578   "bsrf %0\\n%O2:%#"
5579   [(set_attr "type" "call")
5580    (set (attr "fp_mode")
5581         (if_then_else (eq_attr "fpu_single" "yes")
5582                       (const_string "single") (const_string "double")))
5583    (set_attr "needs_delay_slot" "yes")
5584    (set_attr "fp_set" "unknown")])
5586 (define_insn_and_split "call_pcrel"
5587   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5588          (match_operand 1 "" ""))
5589    (use (reg:PSI FPSCR_REG))
5590    (use (reg:SI PIC_REG))
5591    (clobber (reg:SI PR_REG))
5592    (clobber (match_scratch:SI 2 "=r"))]
5593   "TARGET_SH2"
5594   "#"
5595   "reload_completed"
5596   [(const_int 0)]
5597   "
5599   rtx lab = PATTERN (gen_call_site ());
5601   if (SYMBOL_REF_LOCAL_P (operands[0]))
5602     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5603   else
5604     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5605   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5606   DONE;
5608   [(set_attr "type" "call")
5609    (set (attr "fp_mode")
5610         (if_then_else (eq_attr "fpu_single" "yes")
5611                       (const_string "single") (const_string "double")))
5612    (set_attr "needs_delay_slot" "yes")
5613    (set_attr "fp_set" "unknown")])
5615 (define_insn "call_compact"
5616   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5617          (match_operand 1 "" ""))
5618    (match_operand 2 "immediate_operand" "n")
5619    (use (reg:SI R0_REG))
5620    (use (reg:SI R1_REG))
5621    (use (reg:PSI FPSCR_REG))
5622    (clobber (reg:SI PR_REG))]
5623   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5624   "jsr  @%0%#"
5625   [(set_attr "type" "call")
5626    (set (attr "fp_mode")
5627         (if_then_else (eq_attr "fpu_single" "yes")
5628                       (const_string "single") (const_string "double")))
5629    (set_attr "needs_delay_slot" "yes")])
5631 (define_insn "call_compact_rettramp"
5632   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5633          (match_operand 1 "" ""))
5634    (match_operand 2 "immediate_operand" "n")
5635    (use (reg:SI R0_REG))
5636    (use (reg:SI R1_REG))
5637    (use (reg:PSI FPSCR_REG))
5638    (clobber (reg:SI R10_REG))
5639    (clobber (reg:SI PR_REG))]
5640   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5641   "jsr  @%0%#"
5642   [(set_attr "type" "call")
5643    (set (attr "fp_mode")
5644         (if_then_else (eq_attr "fpu_single" "yes")
5645                       (const_string "single") (const_string "double")))
5646    (set_attr "needs_delay_slot" "yes")])
5648 (define_insn "call_media"
5649   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5650          (match_operand 1 "" ""))
5651    (clobber (reg:DI PR_MEDIA_REG))]
5652   "TARGET_SHMEDIA"
5653   "blink        %0, r18"
5654   [(set_attr "type" "jump_media")])
5656 (define_insn "call_valuei"
5657   [(set (match_operand 0 "" "=rf")
5658         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5659               (match_operand 2 "" "")))
5660    (use (reg:PSI FPSCR_REG))
5661    (clobber (reg:SI PR_REG))]
5662   "TARGET_SH1"
5663   "jsr  @%1%#"
5664   [(set_attr "type" "call")
5665    (set (attr "fp_mode")
5666         (if_then_else (eq_attr "fpu_single" "yes")
5667                       (const_string "single") (const_string "double")))
5668    (set_attr "needs_delay_slot" "yes")
5669    (set_attr "fp_set" "unknown")])
5671 (define_insn "call_valuei_pcrel"
5672   [(set (match_operand 0 "" "=rf")
5673         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5674               (match_operand 2 "" "")))
5675    (use (reg:PSI FPSCR_REG))
5676    (use (reg:SI PIC_REG))
5677    (use (match_operand 3 "" ""))
5678    (clobber (reg:SI PR_REG))]
5679   "TARGET_SH2"
5680   "bsrf %1\\n%O3:%#"
5681   [(set_attr "type" "call")
5682    (set (attr "fp_mode")
5683         (if_then_else (eq_attr "fpu_single" "yes")
5684                       (const_string "single") (const_string "double")))
5685    (set_attr "needs_delay_slot" "yes")
5686    (set_attr "fp_set" "unknown")])
5688 (define_insn_and_split "call_value_pcrel"
5689   [(set (match_operand 0 "" "=rf")
5690         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5691               (match_operand 2 "" "")))
5692    (use (reg:PSI FPSCR_REG))
5693    (use (reg:SI PIC_REG))
5694    (clobber (reg:SI PR_REG))
5695    (clobber (match_scratch:SI 3 "=r"))]
5696   "TARGET_SH2"
5697   "#"
5698   "reload_completed"
5699   [(const_int 0)]
5700   "
5702   rtx lab = PATTERN (gen_call_site ());
5704   if (SYMBOL_REF_LOCAL_P (operands[1]))
5705     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5706   else
5707     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5708   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5709                                          operands[2], lab));
5710   DONE;
5712   [(set_attr "type" "call")
5713    (set (attr "fp_mode")
5714         (if_then_else (eq_attr "fpu_single" "yes")
5715                       (const_string "single") (const_string "double")))
5716    (set_attr "needs_delay_slot" "yes")
5717    (set_attr "fp_set" "unknown")])
5719 (define_insn "call_value_compact"
5720   [(set (match_operand 0 "" "=rf")
5721         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5722               (match_operand 2 "" "")))
5723    (match_operand 3 "immediate_operand" "n")
5724    (use (reg:SI R0_REG))
5725    (use (reg:SI R1_REG))
5726    (use (reg:PSI FPSCR_REG))
5727    (clobber (reg:SI PR_REG))]
5728   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5729   "jsr  @%1%#"
5730   [(set_attr "type" "call")
5731    (set (attr "fp_mode")
5732         (if_then_else (eq_attr "fpu_single" "yes")
5733                       (const_string "single") (const_string "double")))
5734    (set_attr "needs_delay_slot" "yes")])
5736 (define_insn "call_value_compact_rettramp"
5737   [(set (match_operand 0 "" "=rf")
5738         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5739               (match_operand 2 "" "")))
5740    (match_operand 3 "immediate_operand" "n")
5741    (use (reg:SI R0_REG))
5742    (use (reg:SI R1_REG))
5743    (use (reg:PSI FPSCR_REG))
5744    (clobber (reg:SI R10_REG))
5745    (clobber (reg:SI PR_REG))]
5746   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5747   "jsr  @%1%#"
5748   [(set_attr "type" "call")
5749    (set (attr "fp_mode")
5750         (if_then_else (eq_attr "fpu_single" "yes")
5751                       (const_string "single") (const_string "double")))
5752    (set_attr "needs_delay_slot" "yes")])
5754 (define_insn "call_value_media"
5755   [(set (match_operand 0 "" "=rf")
5756         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5757               (match_operand 2 "" "")))
5758    (clobber (reg:DI PR_MEDIA_REG))]
5759   "TARGET_SHMEDIA"
5760   "blink        %1, r18"
5761   [(set_attr "type" "jump_media")])
5763 (define_expand "call"
5764   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5765                             (match_operand 1 "" ""))
5766               (match_operand 2 "" "")
5767               (use (reg:PSI FPSCR_REG))
5768               (clobber (reg:SI PR_REG))])]
5769   ""
5770   "
5772   if (TARGET_SHMEDIA)
5773     {
5774       operands[0] = XEXP (operands[0], 0);
5775       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5776         {
5777           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5778             {
5779               rtx reg = gen_reg_rtx (Pmode);
5781               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5782               operands[0] = reg;
5783             }
5784           else
5785             {
5786               operands[0] = gen_sym2PIC (operands[0]);
5787               PUT_MODE (operands[0], Pmode);
5788             }
5789         }
5790       if (GET_MODE (operands[0]) == SImode)
5791         {
5792           if (GET_CODE (operands[0]) == REG)
5793             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5794           else if (GET_CODE (operands[0]) == SUBREG)
5795             {
5796               operands[0] = SUBREG_REG (operands[0]);
5797               if (GET_MODE (operands[0]) != DImode)
5798                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5799             }
5800           else
5801             {
5802               operands[0] = shallow_copy_rtx (operands[0]);
5803               PUT_MODE (operands[0], DImode);
5804             }
5805         }
5806       if (! target_reg_operand (operands[0], DImode))
5807         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5808       emit_call_insn (gen_call_media (operands[0], operands[1]));
5809       DONE;
5810     }
5811   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5812     {
5813       rtx cookie_rtx = operands[2];
5814       long cookie = INTVAL (cookie_rtx);
5815       rtx func = XEXP (operands[0], 0);
5816       rtx r0, r1;
5818       if (flag_pic)
5819         {
5820           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5821             {
5822               rtx reg = gen_reg_rtx (Pmode);
5824               emit_insn (gen_symGOTPLT2reg (reg, func));
5825               func = reg;
5826             }
5827           else
5828             func = legitimize_pic_address (func, Pmode, 0);
5829         }
5831       r0 = gen_rtx_REG (SImode, R0_REG);
5832       r1 = gen_rtx_REG (SImode, R1_REG);
5834       /* Since such a call function may use all call-clobbered
5835          registers, we force a mode switch earlier, so that we don't
5836          run out of registers when adjusting fpscr for the call.  */
5837       emit_insn (gen_force_mode_for_call ());
5839       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5840       if (flag_pic)
5841         {
5842           rtx reg = gen_reg_rtx (Pmode);
5844           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5845           operands[0] = reg;
5846         }
5847       operands[0] = force_reg (SImode, operands[0]);
5849       emit_move_insn (r0, func);
5850       emit_move_insn (r1, cookie_rtx);
5852       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5853         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5854                                                    operands[2]));
5855       else
5856         emit_call_insn (gen_call_compact (operands[0], operands[1],
5857                                           operands[2]));
5859       DONE;
5860     }
5861   else if (TARGET_SHCOMPACT && flag_pic
5862            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5863            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5864     {
5865       rtx reg = gen_reg_rtx (Pmode);
5867       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5868       XEXP (operands[0], 0) = reg;
5869     }
5870   if (flag_pic && TARGET_SH2
5871       && GET_CODE (operands[0]) == MEM
5872       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5873     {
5874       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5875       DONE;
5876     }
5877   else
5878   {
5879     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5880     operands[1] = operands[2];
5881   }
5883   emit_call_insn (gen_calli (operands[0], operands[1]));
5884   DONE;
5887 (define_insn "call_pop_compact"
5888   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5889          (match_operand 1 "" ""))
5890    (match_operand 2 "immediate_operand" "n")
5891    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5892                                  (match_operand 3 "immediate_operand" "n")))
5893    (use (reg:SI R0_REG))
5894    (use (reg:SI R1_REG))
5895    (use (reg:PSI FPSCR_REG))
5896    (clobber (reg:SI PR_REG))]
5897   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5898   "jsr  @%0%#"
5899   [(set_attr "type" "call")
5900    (set (attr "fp_mode")
5901         (if_then_else (eq_attr "fpu_single" "yes")
5902                       (const_string "single") (const_string "double")))
5903    (set_attr "needs_delay_slot" "yes")])
5905 (define_insn "call_pop_compact_rettramp"
5906   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5907          (match_operand 1 "" ""))
5908    (match_operand 2 "immediate_operand" "n")
5909    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5910                                  (match_operand 3 "immediate_operand" "n")))
5911    (use (reg:SI R0_REG))
5912    (use (reg:SI R1_REG))
5913    (use (reg:PSI FPSCR_REG))
5914    (clobber (reg:SI R10_REG))
5915    (clobber (reg:SI PR_REG))]
5916   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5917   "jsr  @%0%#"
5918   [(set_attr "type" "call")
5919    (set (attr "fp_mode")
5920         (if_then_else (eq_attr "fpu_single" "yes")
5921                       (const_string "single") (const_string "double")))
5922    (set_attr "needs_delay_slot" "yes")])
5924 (define_expand "call_pop"
5925   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5926                     (match_operand 1 "" ""))
5927              (match_operand 2 "" "")
5928              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5929                                            (match_operand 3 "" "")))])]
5930   "TARGET_SHCOMPACT"
5931   "
5933   if (operands[2] && INTVAL (operands[2]))
5934     {
5935       rtx cookie_rtx = operands[2];
5936       long cookie = INTVAL (cookie_rtx);
5937       rtx func = XEXP (operands[0], 0);
5938       rtx r0, r1;
5940       if (flag_pic)
5941         {
5942           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5943             {
5944               rtx reg = gen_reg_rtx (Pmode);
5946               emit_insn (gen_symGOTPLT2reg (reg, func));
5947               func = reg;
5948             }
5949           else
5950             func = legitimize_pic_address (func, Pmode, 0);
5951         }
5953       r0 = gen_rtx_REG (SImode, R0_REG);
5954       r1 = gen_rtx_REG (SImode, R1_REG);
5956       /* Since such a call function may use all call-clobbered
5957          registers, we force a mode switch earlier, so that we don't
5958          run out of registers when adjusting fpscr for the call.  */
5959       emit_insn (gen_force_mode_for_call ());
5961       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5962       if (flag_pic)
5963         {
5964           rtx reg = gen_reg_rtx (Pmode);
5966           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5967           operands[0] = reg;
5968         }
5969       operands[0] = force_reg (SImode, operands[0]);
5971       emit_move_insn (r0, func);
5972       emit_move_insn (r1, cookie_rtx);
5974       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5975         emit_call_insn (gen_call_pop_compact_rettramp
5976                         (operands[0], operands[1], operands[2], operands[3]));
5977       else
5978         emit_call_insn (gen_call_pop_compact
5979                         (operands[0], operands[1], operands[2], operands[3]));
5981       DONE;
5982     }
5984   abort ();
5987 (define_expand "call_value"
5988   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5989                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5990                                  (match_operand 2 "" "")))
5991               (match_operand 3 "" "")
5992               (use (reg:PSI FPSCR_REG))
5993               (clobber (reg:SI PR_REG))])]
5994   ""
5995   "
5997   if (TARGET_SHMEDIA)
5998     {
5999       operands[1] = XEXP (operands[1], 0);
6000       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6001         {
6002           if (! SYMBOL_REF_LOCAL_P (operands[1]))
6003             {
6004               rtx reg = gen_reg_rtx (Pmode);
6006               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6007               operands[1] = reg;
6008             }
6009           else
6010             {
6011               operands[1] = gen_sym2PIC (operands[1]);
6012               PUT_MODE (operands[1], Pmode);
6013             }
6014         }
6015       if (GET_MODE (operands[1]) == SImode)
6016         {
6017           if (GET_CODE (operands[1]) == REG)
6018             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6019           else if (GET_CODE (operands[1]) == SUBREG)
6020             {
6021               operands[1] = SUBREG_REG (operands[1]);
6022               if (GET_MODE (operands[1]) != DImode)
6023                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6024             }
6025           else
6026             {
6027               operands[1] = shallow_copy_rtx (operands[1]);
6028               PUT_MODE (operands[1], DImode);
6029             }
6030         }
6031       if (! target_reg_operand (operands[1], DImode))
6032         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6033       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6034                                             operands[2]));
6035       DONE;
6036     }
6037   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6038     {
6039       rtx cookie_rtx = operands[3];
6040       long cookie = INTVAL (cookie_rtx);
6041       rtx func = XEXP (operands[1], 0);
6042       rtx r0, r1;
6044       if (flag_pic)
6045         {
6046           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6047             {
6048               rtx reg = gen_reg_rtx (Pmode);
6050               emit_insn (gen_symGOTPLT2reg (reg, func));
6051               func = reg;
6052             }
6053           else
6054             func = legitimize_pic_address (func, Pmode, 0);
6055         }
6057       r0 = gen_rtx_REG (SImode, R0_REG);
6058       r1 = gen_rtx_REG (SImode, R1_REG);
6060       /* Since such a call function may use all call-clobbered
6061          registers, we force a mode switch earlier, so that we don't
6062          run out of registers when adjusting fpscr for the call.  */
6063       emit_insn (gen_force_mode_for_call ());
6065       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6066       if (flag_pic)
6067         {
6068           rtx reg = gen_reg_rtx (Pmode);
6070           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6071           operands[1] = reg;
6072         }
6073       operands[1] = force_reg (SImode, operands[1]);
6075       emit_move_insn (r0, func);
6076       emit_move_insn (r1, cookie_rtx);
6078       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6079         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6080                                                          operands[1],
6081                                                          operands[2],
6082                                                          operands[3]));
6083       else
6084         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6085                                                 operands[2], operands[3]));
6087       DONE;
6088     }
6089   else if (TARGET_SHCOMPACT && flag_pic
6090            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6091            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6092     {
6093       rtx reg = gen_reg_rtx (Pmode);
6095       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6096       XEXP (operands[1], 0) = reg;
6097     }
6098   if (flag_pic && TARGET_SH2
6099       && GET_CODE (operands[1]) == MEM
6100       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6101     {
6102       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6103                                             operands[2]));
6104       DONE;
6105     }
6106   else
6107     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6109   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6110   DONE;
6113 (define_insn "sibcalli"
6114   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6115          (match_operand 1 "" ""))
6116    (use (reg:PSI FPSCR_REG))
6117    (return)]
6118   "TARGET_SH1"
6119   "jmp  @%0%#"
6120   [(set_attr "needs_delay_slot" "yes")
6121    (set (attr "fp_mode")
6122         (if_then_else (eq_attr "fpu_single" "yes")
6123                       (const_string "single") (const_string "double")))
6124    (set_attr "type" "jump_ind")])
6126 (define_insn "sibcalli_pcrel"
6127   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6128          (match_operand 1 "" ""))
6129    (use (match_operand 2 "" ""))
6130    (use (reg:PSI FPSCR_REG))
6131    (return)]
6132   "TARGET_SH2"
6133   "braf %0\\n%O2:%#"
6134   [(set_attr "needs_delay_slot" "yes")
6135    (set (attr "fp_mode")
6136         (if_then_else (eq_attr "fpu_single" "yes")
6137                       (const_string "single") (const_string "double")))
6138    (set_attr "type" "jump_ind")])
6140 (define_insn_and_split "sibcall_pcrel"
6141   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6142          (match_operand 1 "" ""))
6143    (use (reg:PSI FPSCR_REG))
6144    (clobber (match_scratch:SI 2 "=k"))
6145    (return)]
6146   "TARGET_SH2"
6147   "#"
6148   "reload_completed"
6149   [(const_int 0)]
6150   "
6152   rtx lab = PATTERN (gen_call_site ());
6153   rtx call_insn;
6155   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6156   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6157                                                   lab));
6158   SIBLING_CALL_P (call_insn) = 1;
6159   DONE;
6161   [(set_attr "needs_delay_slot" "yes")
6162    (set (attr "fp_mode")
6163         (if_then_else (eq_attr "fpu_single" "yes")
6164                       (const_string "single") (const_string "double")))
6165    (set_attr "type" "jump_ind")])
6167 (define_insn "sibcall_compact"
6168   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6169          (match_operand 1 "" ""))
6170    (return)
6171    (use (match_operand:SI 2 "register_operand" "z,x"))
6172    (use (reg:SI R1_REG))
6173    (use (reg:PSI FPSCR_REG))
6174    ;; We want to make sure the `x' above will only match MACH_REG
6175    ;; because sibcall_epilogue may clobber MACL_REG.
6176    (clobber (reg:SI MACL_REG))]
6177   "TARGET_SHCOMPACT"
6178   "@
6179         jmp     @%0%#
6180         jmp     @%0\\n  sts     %2, r0"
6181   [(set_attr "needs_delay_slot" "yes,no")
6182    (set_attr "length" "2,4")
6183    (set (attr "fp_mode") (const_string "single"))
6184    (set_attr "type" "jump_ind")])
6186 (define_insn "sibcall_media"
6187   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6188          (match_operand 1 "" ""))
6189    (use (reg:SI PR_MEDIA_REG))
6190    (return)]
6191   "TARGET_SHMEDIA"
6192   "blink        %0, r63"
6193   [(set_attr "type" "jump_media")])
6195 (define_expand "sibcall"
6196   [(parallel
6197     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6198            (match_operand 1 "" ""))
6199      (match_operand 2 "" "")
6200      (use (reg:PSI FPSCR_REG))
6201      (return)])]
6202   ""
6203   "
6205   if (TARGET_SHMEDIA)
6206     {
6207       operands[0] = XEXP (operands[0], 0);
6208       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6209         {
6210           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6211             {
6212               rtx reg = gen_reg_rtx (Pmode);
6214               /* We must not use GOTPLT for sibcalls, because PIC_REG
6215                  must be restored before the PLT code gets to run.  */
6216               emit_insn (gen_symGOT2reg (reg, operands[0]));
6217               operands[0] = reg;
6218             }
6219           else
6220             {
6221               operands[0] = gen_sym2PIC (operands[0]);
6222               PUT_MODE (operands[0], Pmode);
6223             }
6224         }
6225       if (GET_MODE (operands[0]) == SImode)
6226         {
6227           if (GET_CODE (operands[0]) == REG)
6228             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6229           else if (GET_CODE (operands[0]) == SUBREG)
6230             {
6231               operands[0] = SUBREG_REG (operands[0]);
6232               if (GET_MODE (operands[0]) != DImode)
6233                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6234             }
6235           else
6236             {
6237               operands[0] = shallow_copy_rtx (operands[0]);
6238               PUT_MODE (operands[0], DImode);
6239             }
6240         }
6241       if (! target_reg_operand (operands[0], DImode))
6242         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6243       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6244       DONE;
6245     }
6246   else if (TARGET_SHCOMPACT && operands[2]
6247            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6248     {
6249       rtx cookie_rtx = operands[2];
6250       long cookie = INTVAL (cookie_rtx);
6251       rtx func = XEXP (operands[0], 0);
6252       rtx mach, r1;
6254       if (flag_pic)
6255         {
6256           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6257             {
6258               rtx reg = gen_reg_rtx (Pmode);
6260               emit_insn (gen_symGOT2reg (reg, func));
6261               func = reg;
6262             }
6263           else
6264             func = legitimize_pic_address (func, Pmode, 0);
6265         }
6267       /* FIXME: if we could tell whether all argument registers are
6268          already taken, we could decide whether to force the use of
6269          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6270          simple way to tell.  We could use the CALL_COOKIE, but we
6271          can't currently tell a register used for regular argument
6272          passing from one that is unused.  If we leave it up to reload
6273          to decide which register to use, it seems to always choose
6274          R0_REG, which leaves no available registers in SIBCALL_REGS
6275          to hold the address of the trampoline.  */
6276       mach = gen_rtx_REG (SImode, MACH_REG);
6277       r1 = gen_rtx_REG (SImode, R1_REG);
6279       /* Since such a call function may use all call-clobbered
6280          registers, we force a mode switch earlier, so that we don't
6281          run out of registers when adjusting fpscr for the call.  */
6282       emit_insn (gen_force_mode_for_call ());
6284       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6285       if (flag_pic)
6286         {
6287           rtx reg = gen_reg_rtx (Pmode);
6289           emit_insn (gen_symGOT2reg (reg, operands[0]));
6290           operands[0] = reg;
6291         }
6292       operands[0] = force_reg (SImode, operands[0]);
6294       /* We don't need a return trampoline, since the callee will
6295          return directly to the upper caller.  */
6296       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6297         {
6298           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6299           cookie_rtx = GEN_INT (cookie);
6300         }
6302       emit_move_insn (mach, func);
6303       emit_move_insn (r1, cookie_rtx);
6305       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6306       DONE;
6307     }
6308   else if (TARGET_SHCOMPACT && flag_pic
6309            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6310            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6311     {
6312       rtx reg = gen_reg_rtx (Pmode);
6314       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6315       XEXP (operands[0], 0) = reg;
6316     }
6317   if (flag_pic && TARGET_SH2
6318       && GET_CODE (operands[0]) == MEM
6319       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6320       /* The PLT needs the PIC register, but the epilogue would have
6321          to restore it, so we can only use PC-relative PIC calls for
6322          static functions.  */
6323       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6324     {
6325       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6326       DONE;
6327     }
6328   else
6329     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6331   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6332   DONE;
6335 (define_expand "sibcall_value"
6336   [(set (match_operand 0 "" "")
6337         (call (match_operand 1 "" "")
6338               (match_operand 2 "" "")))
6339    (match_operand 3 "" "")]
6340   ""
6341   "
6343   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6344   DONE;
6347 (define_insn "call_value_pop_compact"
6348   [(set (match_operand 0 "" "=rf")
6349         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6350               (match_operand 2 "" "")))
6351    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6352                                  (match_operand 4 "immediate_operand" "n")))
6353    (match_operand 3 "immediate_operand" "n")
6354    (use (reg:SI R0_REG))
6355    (use (reg:SI R1_REG))
6356    (use (reg:PSI FPSCR_REG))
6357    (clobber (reg:SI PR_REG))]
6358   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6359   "jsr  @%1%#"
6360   [(set_attr "type" "call")
6361    (set (attr "fp_mode")
6362         (if_then_else (eq_attr "fpu_single" "yes")
6363                       (const_string "single") (const_string "double")))
6364    (set_attr "needs_delay_slot" "yes")])
6366 (define_insn "call_value_pop_compact_rettramp"
6367   [(set (match_operand 0 "" "=rf")
6368         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6369               (match_operand 2 "" "")))
6370    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6371                                  (match_operand 4 "immediate_operand" "n")))
6372    (match_operand 3 "immediate_operand" "n")
6373    (use (reg:SI R0_REG))
6374    (use (reg:SI R1_REG))
6375    (use (reg:PSI FPSCR_REG))
6376    (clobber (reg:SI R10_REG))
6377    (clobber (reg:SI PR_REG))]
6378   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6379   "jsr  @%1%#"
6380   [(set_attr "type" "call")
6381    (set (attr "fp_mode")
6382         (if_then_else (eq_attr "fpu_single" "yes")
6383                       (const_string "single") (const_string "double")))
6384    (set_attr "needs_delay_slot" "yes")])
6386 (define_expand "call_value_pop"
6387   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6388                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6389                                  (match_operand 2 "" "")))
6390               (match_operand 3 "" "")
6391               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6392                                             (match_operand 4 "" "")))])]
6393   "TARGET_SHCOMPACT"
6394   "
6396   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6397     {
6398       rtx cookie_rtx = operands[3];
6399       long cookie = INTVAL (cookie_rtx);
6400       rtx func = XEXP (operands[1], 0);
6401       rtx r0, r1;
6403       if (flag_pic)
6404         {
6405           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6406             {
6407               rtx reg = gen_reg_rtx (Pmode);
6409               emit_insn (gen_symGOTPLT2reg (reg, func));
6410               func = reg;
6411             }
6412           else
6413             func = legitimize_pic_address (func, Pmode, 0);
6414         }
6416       r0 = gen_rtx_REG (SImode, R0_REG);
6417       r1 = gen_rtx_REG (SImode, R1_REG);
6419       /* Since such a call function may use all call-clobbered
6420          registers, we force a mode switch earlier, so that we don't
6421          run out of registers when adjusting fpscr for the call.  */
6422       emit_insn (gen_force_mode_for_call ());
6424       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6425       if (flag_pic)
6426         {
6427           rtx reg = gen_reg_rtx (Pmode);
6429           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6430           operands[1] = reg;
6431         }
6432       operands[1] = force_reg (SImode, operands[1]);
6434       emit_move_insn (r0, func);
6435       emit_move_insn (r1, cookie_rtx);
6437       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6438         emit_call_insn (gen_call_value_pop_compact_rettramp
6439                         (operands[0], operands[1], operands[2],
6440                          operands[3], operands[4]));
6441       else
6442         emit_call_insn (gen_call_value_pop_compact
6443                         (operands[0], operands[1], operands[2],
6444                          operands[3], operands[4]));
6446       DONE;
6447     }
6449   abort ();
6452 (define_expand "sibcall_epilogue"
6453   [(return)]
6454   ""
6455   "
6457   sh_expand_epilogue (1);
6458   if (TARGET_SHCOMPACT)
6459     {
6460       rtx insn, set;
6462       /* If epilogue clobbers r0, preserve it in macl.  */
6463       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6464         if ((set = single_set (insn))
6465             && GET_CODE (SET_DEST (set)) == REG
6466             && REGNO (SET_DEST (set)) == R0_REG)
6467           {
6468             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6469             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6470             rtx i;
6472             /* We can't tell at this point whether the sibcall is a
6473                sibcall_compact and, if it is, whether it uses r0 or
6474                mach as operand 2, so let the instructions that
6475                preserve r0 be optimized away if r0 turns out to be
6476                dead.  */
6477             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6478             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6479                                                REG_NOTES (i));
6480             i = emit_move_insn (r0, tmp);
6481             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6482                                                REG_NOTES (i));
6483             break;
6484           }
6485     }
6486   DONE;
6489 (define_insn "indirect_jump_compact"
6490   [(set (pc)
6491         (match_operand:SI 0 "arith_reg_operand" "r"))]
6492   "TARGET_SH1"
6493   "jmp  @%0%#"
6494   [(set_attr "needs_delay_slot" "yes")
6495    (set_attr "type" "jump_ind")])
6497 (define_expand "indirect_jump"
6498   [(set (pc)
6499         (match_operand 0 "register_operand" ""))]
6500   ""
6501   "
6503   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6504     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6507 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6508 ;; which can be present in structured code from indirect jumps which can not
6509 ;; be present in structured code.  This allows -fprofile-arcs to work.
6511 ;; For SH1 processors.
6512 (define_insn "casesi_jump_1"
6513   [(set (pc)
6514         (match_operand:SI 0 "register_operand" "r"))
6515    (use (label_ref (match_operand 1 "" "")))]
6516   "TARGET_SH1"
6517   "jmp  @%0%#"
6518   [(set_attr "needs_delay_slot" "yes")
6519    (set_attr "type" "jump_ind")])
6521 ;; For all later processors.
6522 (define_insn "casesi_jump_2"
6523   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6524                       (label_ref (match_operand 1 "" ""))))
6525    (use (label_ref (match_operand 2 "" "")))]
6526   "TARGET_SH2
6527    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6528   "braf %0%#"
6529   [(set_attr "needs_delay_slot" "yes")
6530    (set_attr "type" "jump_ind")])
6532 (define_insn "casesi_jump_media"
6533   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6534    (use (label_ref (match_operand 1 "" "")))]
6535   "TARGET_SHMEDIA"
6536   "blink        %0, r63"
6537   [(set_attr "type" "jump_media")])
6539 ;; Call subroutine returning any type.
6540 ;; ??? This probably doesn't work.
6542 (define_expand "untyped_call"
6543   [(parallel [(call (match_operand 0 "" "")
6544                     (const_int 0))
6545               (match_operand 1 "" "")
6546               (match_operand 2 "" "")])]
6547   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
6548   "
6550   int i;
6552   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6554   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6555     {
6556       rtx set = XVECEXP (operands[2], 0, i);
6557       emit_move_insn (SET_DEST (set), SET_SRC (set));
6558     }
6560   /* The optimizer does not know that the call sets the function value
6561      registers we stored in the result block.  We avoid problems by
6562      claiming that all hard registers are used and clobbered at this
6563      point.  */
6564   emit_insn (gen_blockage ());
6566   DONE;
6569 ;; ------------------------------------------------------------------------
6570 ;; Misc insns
6571 ;; ------------------------------------------------------------------------
6573 (define_insn "dect"
6574   [(set (reg:SI T_REG)
6575         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6576    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6577   "TARGET_SH2"
6578   "dt   %0"
6579   [(set_attr "type" "arith")])
6581 (define_insn "nop"
6582   [(const_int 0)]
6583   ""
6584   "nop")
6586 ;; Load address of a label. This is only generated by the casesi expand,
6587 ;; and by machine_dependent_reorg (fixing up fp moves).
6588 ;; This must use unspec, because this only works for labels that are
6589 ;; within range,
6591 (define_insn "mova"
6592   [(set (reg:SI R0_REG)
6593         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6594   "TARGET_SH1"
6595   "mova %O0,r0"
6596   [(set_attr "in_delay_slot" "no")
6597    (set_attr "type" "arith")])
6599 ;; machine_dependent_reorg will make this a `mova'.
6600 (define_insn "mova_const"
6601   [(set (reg:SI R0_REG)
6602         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6603   "TARGET_SH1"
6604   "#"
6605   [(set_attr "in_delay_slot" "no")
6606    (set_attr "type" "arith")])
6608 (define_expand "GOTaddr2picreg"
6609   [(set (reg:SI R0_REG)
6610         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6611                    UNSPEC_MOVA))
6612    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6613    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6614   "" "
6616   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6617   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6619   if (TARGET_SH5)
6620     operands[1] = gen_datalabel_ref (operands[1]);
6622   if (TARGET_SHMEDIA)
6623     {
6624       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6625       rtx dipic = operands[0];
6626       rtx lab = PATTERN (gen_call_site ());
6627       rtx insn, equiv;
6629       equiv = operands[1];
6630       operands[1] = gen_rtx_MINUS (DImode,
6631                                    operands[1],
6632                                    gen_rtx_CONST
6633                                    (DImode,
6634                                     gen_rtx_MINUS (DImode,
6635                                                    gen_rtx_CONST (DImode,
6636                                                                   lab),
6637                                                    pc_rtx)));
6638       operands[1] = gen_sym2PIC (operands[1]);
6639       PUT_MODE (operands[1], DImode);
6641       if (GET_MODE (dipic) != DImode)
6642         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6644       if (TARGET_SHMEDIA64)
6645         emit_insn (gen_movdi_const (dipic, operands[1]));
6646       else
6647         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6649       emit_insn (gen_ptrel (tr, dipic, lab));
6651       if (GET_MODE (operands[0]) != GET_MODE (tr))
6652         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6654       insn = emit_move_insn (operands[0], tr);
6656       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6657                                             REG_NOTES (insn));
6659       DONE;
6660     }
6664 (define_insn "*ptb"
6665   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6666         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6667                              UNSPEC_DATALABEL)))]
6668   "TARGET_SHMEDIA && flag_pic
6669    && EXTRA_CONSTRAINT_Csy (operands[1])"
6670   "ptb/u        datalabel %1, %0"
6671   [(set_attr "type" "pt_media")
6672    (set_attr "length" "*")])
6674 (define_insn "ptrel"
6675   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6676         (plus:DI (match_operand:DI 1 "register_operand" "r")
6677               (pc)))
6678    (match_operand:DI 2 "" "")]
6679   "TARGET_SHMEDIA"
6680   "%O2: ptrel/u %1, %0"
6681   [(set_attr "type" "ptabs_media")])
6683 (define_expand "builtin_setjmp_receiver"
6684   [(match_operand 0 "" "")]
6685   "flag_pic"
6686   "
6688   emit_insn (gen_GOTaddr2picreg ());
6689   DONE;
6692 (define_expand "call_site"
6693   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6694   "TARGET_SH1"
6695   "
6697   static HOST_WIDE_INT i = 0;
6698   operands[0] = GEN_INT (i);
6699   i++;
6702 (define_expand "sym_label2reg"
6703   [(set (match_operand:SI 0 "" "")
6704         (const:SI (minus:SI
6705                    (const:SI
6706                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6707                    (const:SI
6708                     (plus:SI
6709                      (match_operand:SI 2 "" "")
6710                      (const_int 2))))))]
6711   "TARGET_SH1" "")
6713 (define_expand "symGOT_load"
6714   [(set (match_dup 2) (match_operand 1 "" ""))
6715    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6716    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6717   ""
6718   "
6720   rtx insn;
6722   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6723   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6725   if (TARGET_SHMEDIA)
6726     {
6727       rtx reg = operands[2];
6729       if (GET_MODE (reg) != DImode)
6730         reg = gen_rtx_SUBREG (DImode, reg, 0);
6732       if (flag_pic > 1)
6733         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6734       else
6735         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6736     }
6737   else
6738     emit_move_insn (operands[2], operands[1]);
6740   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6741                                              operands[2],
6742                                              gen_rtx_REG (Pmode, PIC_REG)));
6744   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6746   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6747                                                                   0), 0, 0),
6748                                         REG_NOTES (insn));
6750   DONE;
6753 (define_expand "sym2GOT"
6754   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6755   ""
6756   "")
6758 (define_expand "symGOT2reg"
6759   [(match_operand 0 "" "") (match_operand 1 "" "")]
6760   ""
6761   "
6763   rtx gotsym, insn;
6765   gotsym = gen_sym2GOT (operands[1]);
6766   PUT_MODE (gotsym, Pmode);
6767   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6769   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
6771   DONE;
6774 (define_expand "sym2GOTPLT"
6775   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6776   ""
6777   "")
6779 (define_expand "symGOTPLT2reg"
6780   [(match_operand 0 "" "") (match_operand 1 "" "")]
6781   ""
6782   "
6784   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6785   DONE;
6788 (define_expand "sym2GOTOFF"
6789   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6790   ""
6791   "")
6793 (define_expand "symGOTOFF2reg"
6794   [(match_operand 0 "" "") (match_operand 1 "" "")]
6795   ""
6796   "
6798   rtx gotoffsym, insn;
6799   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6801   gotoffsym = gen_sym2GOTOFF (operands[1]);
6802   PUT_MODE (gotoffsym, Pmode);
6803   emit_move_insn (t, gotoffsym);
6804   insn = emit_move_insn (operands[0],
6805                          gen_rtx_PLUS (Pmode, t,
6806                                        gen_rtx_REG (Pmode, PIC_REG)));
6808   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6809                                         REG_NOTES (insn));
6811   DONE;
6814 (define_expand "symPLT_label2reg"
6815   [(set (match_operand:SI 0 "" "")
6816         (const:SI (minus:SI
6817                    (const:SI
6818                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6819                    (const:SI
6820                     (minus:SI
6821                      (const:SI (plus:SI
6822                                 (match_operand:SI 2 "" "")
6823                                 (const_int 2)))
6824                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6825    ;; Even though the PIC register is not really used by the call
6826    ;; sequence in which this is expanded, the PLT code assumes the PIC
6827    ;; register is set, so we must not skip its initialization.  Since
6828    ;; we only use this expand as part of calling sequences, and never
6829    ;; to take the address of a function, this is the best point to
6830    ;; insert the (use).  Using the PLT to take the address of a
6831    ;; function would be wrong, not only because the PLT entry could
6832    ;; then be called from a function that doesn't initialize the PIC
6833    ;; register to the proper GOT, but also because pointers to the
6834    ;; same function might not compare equal, should they be set by
6835    ;; different shared libraries.
6836    (use (reg:SI PIC_REG))]
6837   "TARGET_SH1"
6838   "")
6840 (define_expand "sym2PIC"
6841   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6842   ""
6843   "")
6845 ;; TLS code generation.
6846 ;; ??? this should be a define_insn_and_split
6847 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6848 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6849 ;; for details.
6851 (define_insn "tls_global_dynamic"
6852   [(set (match_operand:SI 0 "register_operand" "=&z")
6853         (call (unspec:SI [(match_operand:SI 1 "" "")]
6854                           UNSPEC_TLSGD)
6855               (const_int 0)))
6856    (use (reg:PSI FPSCR_REG))
6857    (use (reg:SI PIC_REG))
6858    (clobber (reg:SI PR_REG))
6859    (clobber (scratch:SI))]
6860   "TARGET_SH1"
6861   "*
6863   return \"\\
6864 mov.l\\t1f,r4\\n\\
6865 \\tmova\\t2f,r0\\n\\
6866 \\tmov.l\\t2f,r1\\n\\
6867 \\tadd\\tr0,r1\\n\\
6868 \\tjsr\\t@r1\\n\\
6869 \\tadd\\tr12,r4\\n\\
6870 \\tbra\\t3f\\n\\
6871 \\tnop\\n\\
6872 \\t.align\\t2\\n\\
6873 1:\\t.long\\t%a1@TLSGD\\n\\
6874 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6875 3:\";
6877   [(set_attr "type" "tls_load")
6878    (set_attr "length" "26")])
6880 (define_insn "tls_local_dynamic"
6881   [(set (match_operand:SI 0 "register_operand" "=&z")
6882         (call (unspec:SI [(match_operand:SI 1 "" "")]
6883                           UNSPEC_TLSLDM)
6884               (const_int 0)))
6885    (use (reg:PSI FPSCR_REG))
6886    (use (reg:SI PIC_REG))
6887    (clobber (reg:SI PR_REG))
6888    (clobber (scratch:SI))]
6889   "TARGET_SH1"
6890   "*
6892   return \"\\
6893 mov.l\\t1f,r4\\n\\
6894 \\tmova\\t2f,r0\\n\\
6895 \\tmov.l\\t2f,r1\\n\\
6896 \\tadd\\tr0,r1\\n\\
6897 \\tjsr\\t@r1\\n\\
6898 \\tadd\\tr12,r4\\n\\
6899 \\tbra\\t3f\\n\\
6900 \\tnop\\n\\
6901 \\t.align\\t2\\n\\
6902 1:\\t.long\\t%a1@TLSLDM\\n\\
6903 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6904 3:\";
6906   [(set_attr "type" "tls_load")
6907    (set_attr "length" "26")])
6909 (define_expand "sym2DTPOFF"
6910   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6911   ""
6912   "")
6914 (define_expand "symDTPOFF2reg"
6915   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6916   ""
6917   "
6919   rtx dtpoffsym, insn;
6920   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6922   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6923   PUT_MODE (dtpoffsym, Pmode);
6924   emit_move_insn (t, dtpoffsym);
6925   insn = emit_move_insn (operands[0],
6926                          gen_rtx_PLUS (Pmode, t, operands[2]));
6927   DONE;
6930 (define_expand "sym2GOTTPOFF"
6931   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6932   ""
6933   "")
6935 (define_insn "tls_initial_exec"
6936   [(set (match_operand:SI 0 "register_operand" "=&r")
6937         (unspec:SI [(match_operand:SI 1 "" "")]
6938                     UNSPEC_TLSIE))
6939    (use (reg:SI GBR_REG))
6940    (use (reg:SI PIC_REG))
6941    (clobber (reg:SI R0_REG))]
6942   ""
6943   "*
6945   return \"\\
6946 mov.l\\t1f,r0\\n\\
6947 \\tstc\\tgbr,%0\\n\\
6948 \\tmov.l\\t@(r0,r12),r0\\n\\
6949 \\tbra\\t2f\\n\\
6950 \\tadd\\tr0,%0\\n\\
6951 \\t.align\\t2\\n\\
6952 1:\\t.long\\t%a1\\n\\
6953 2:\";
6955   [(set_attr "type" "tls_load")
6956    (set_attr "length" "16")])
6958 (define_expand "sym2TPOFF"
6959   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6960   ""
6961   "")
6963 (define_expand "symTPOFF2reg"
6964   [(match_operand 0 "" "") (match_operand 1 "" "")]
6965   ""
6966   "
6968   rtx tpoffsym, insn;
6970   tpoffsym = gen_sym2TPOFF (operands[1]);
6971   PUT_MODE (tpoffsym, Pmode);
6972   insn = emit_move_insn (operands[0], tpoffsym);
6973   DONE;
6976 (define_insn "load_gbr"
6977   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6978    (use (reg:SI GBR_REG))]
6979   ""
6980   "stc  gbr,%0"
6981   [(set_attr "type" "tls_load")])
6983 ;; case instruction for switch statements.
6985 ;; Operand 0 is index
6986 ;; operand 1 is the minimum bound
6987 ;; operand 2 is the maximum bound - minimum bound + 1
6988 ;; operand 3 is CODE_LABEL for the table;
6989 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6991 (define_expand "casesi"
6992   [(match_operand:SI 0 "arith_reg_operand" "")
6993    (match_operand:SI 1 "arith_reg_operand" "")
6994    (match_operand:SI 2 "arith_reg_operand" "")
6995    (match_operand 3 "" "") (match_operand 4 "" "")]
6996   ""
6997   "
6999   rtx reg = gen_reg_rtx (SImode);
7000   rtx reg2 = gen_reg_rtx (SImode);
7001   if (TARGET_SHMEDIA)
7002     {
7003       rtx reg = gen_reg_rtx (DImode);
7004       rtx reg2 = gen_reg_rtx (DImode);
7005       rtx reg3 = gen_reg_rtx (DImode);
7006       rtx reg4 = gen_reg_rtx (DImode);
7007       rtx reg5 = gen_reg_rtx (DImode);
7009       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7010       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7011       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7013       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7014       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7015       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7016       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7017       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7018                                                (DImode, operands[3])));
7019       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7020       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7021       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7022       emit_barrier ();
7023       DONE;
7024     }
7025   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7026   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7027   /* If optimizing, casesi_worker depends on the mode of the instruction
7028      before label it 'uses' - operands[3].  */
7029   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7030                            reg));
7031   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7032   if (TARGET_SH2)
7033     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7034   else
7035     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7036   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7037      operands[3], but to lab.  We will fix this up in
7038      machine_dependent_reorg.  */
7039   emit_barrier ();
7040   DONE;
7043 (define_expand "casesi_0"
7044   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7045    (set (match_dup 4) (minus:SI (match_dup 4)
7046                                 (match_operand:SI 1 "arith_operand" "")))
7047    (set (reg:SI T_REG)
7048         (gtu:SI (match_dup 4)
7049                 (match_operand:SI 2 "arith_reg_operand" "")))
7050    (set (pc)
7051         (if_then_else (ne (reg:SI T_REG)
7052                           (const_int 0))
7053                       (label_ref (match_operand 3 "" ""))
7054                       (pc)))]
7055   "TARGET_SH1"
7056   "")
7058 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7059 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7060 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7062 (define_insn "casesi_worker_0"
7063   [(set (match_operand:SI 0 "register_operand" "=r,r")
7064         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7065                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7066    (clobber (match_scratch:SI 3 "=X,1"))
7067    (clobber (match_scratch:SI 4 "=&z,z"))]
7068   "TARGET_SH1"
7069   "#")
7071 (define_split
7072   [(set (match_operand:SI 0 "register_operand" "")
7073         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7074                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7075    (clobber (match_scratch:SI 3 ""))
7076    (clobber (match_scratch:SI 4 ""))]
7077   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7078   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7079    (parallel [(set (match_dup 0)
7080               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7081                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7082               (clobber (match_dup 3))])
7083    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7084   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7086 (define_split
7087   [(set (match_operand:SI 0 "register_operand" "")
7088         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7089                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7090    (clobber (match_scratch:SI 3 ""))
7091    (clobber (match_scratch:SI 4 ""))]
7092   "TARGET_SH2 && reload_completed"
7093   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7094    (parallel [(set (match_dup 0)
7095               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7096                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7097               (clobber (match_dup 3))])]
7098   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7100 (define_insn "casesi_worker_1"
7101   [(set (match_operand:SI 0 "register_operand" "=r,r")
7102         (unspec:SI [(reg:SI R0_REG)
7103                     (match_operand:SI 1 "register_operand" "0,r")
7104                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7105    (clobber (match_scratch:SI 3 "=X,1"))]
7106   "TARGET_SH1"
7107   "*
7109   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7111   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7112     abort ();
7114   switch (GET_MODE (diff_vec))
7115     {
7116     case SImode:
7117       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7118     case HImode:
7119       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7120     case QImode:
7121       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7122         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7123       return \"mov.b    @(r0,%1),%0\";
7124     default:
7125       abort ();
7126     }
7128   [(set_attr "length" "4")])
7130 (define_insn "casesi_worker_2"
7131   [(set (match_operand:SI 0 "register_operand" "=r,r")
7132         (unspec:SI [(reg:SI R0_REG)
7133                     (match_operand:SI 1 "register_operand" "0,r")
7134                     (label_ref (match_operand 2 "" ""))
7135                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7136    (clobber (match_operand:SI 4 "" "=X,1"))]
7137   "TARGET_SH2 && reload_completed && flag_pic"
7138   "*
7140   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7141   const char *load;
7143   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7144     abort ();
7146   switch (GET_MODE (diff_vec))
7147     {
7148     case SImode:
7149       output_asm_insn (\"shll2    %1\", operands);
7150       load = \"mov.l    @(r0,%1),%0\"; break;
7151     case HImode:
7152       output_asm_insn (\"add    %1,%1\", operands);
7153       load = \"mov.w    @(r0,%1),%0\"; break;
7154     case QImode:
7155       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7156         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7157       else
7158         load = \"mov.b  @(r0,%1),%0\";
7159       break;
7160     default:
7161       abort ();
7162     }
7163   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7164   return load;
7166   [(set_attr "length" "8")])
7168 (define_insn "casesi_shift_media"
7169   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7170         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7171                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7172                     UNSPEC_CASESI)))]
7173   "TARGET_SHMEDIA"
7174   "*
7176   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7178   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7179     abort ();
7181   switch (GET_MODE (diff_vec))
7182     {
7183     case SImode:
7184       return \"shlli    %1, 2, %0\";
7185     case HImode:
7186       return \"shlli    %1, 1, %0\";
7187     case QImode:
7188       if (rtx_equal_p (operands[0], operands[1]))
7189         return \"\";
7190       return \"add      %1, r63, %0\";
7191     default:
7192       abort ();
7193     }
7195   [(set_attr "type" "arith_media")])
7197 (define_insn "casesi_load_media"
7198   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7199         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7200                          (match_operand 2 "arith_reg_operand" "r")
7201                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7202   "TARGET_SHMEDIA"
7203   "*
7205   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7207   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7208     abort ();
7210   switch (GET_MODE (diff_vec))
7211     {
7212     case SImode:
7213       return \"ldx.l    %1, %2, %0\";
7214     case HImode:
7215 #if 0
7216       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7217         return \"ldx.uw %1, %2, %0\";
7218 #endif
7219       return \"ldx.w    %1, %2, %0\";
7220     case QImode:
7221       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7222         return \"ldx.ub %1, %2, %0\";
7223       return \"ldx.b    %1, %2, %0\";
7224     default:
7225       abort ();
7226     }
7228   [(set_attr "type" "load_media")])
7230 (define_expand "return"
7231   [(return)]
7232   "reload_completed && ! sh_need_epilogue ()"
7233   "
7235   if (TARGET_SHMEDIA)
7236     {
7237       emit_jump_insn (gen_return_media ());
7238       DONE;
7239     }
7241   if (TARGET_SHCOMPACT
7242       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7243     {
7244       emit_jump_insn (gen_shcompact_return_tramp ());
7245       DONE;
7246     }
7249 (define_insn "*return_i"
7250   [(return)]
7251   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7252                     && (current_function_args_info.call_cookie
7253                         & CALL_COOKIE_RET_TRAMP (1)))
7254    && reload_completed"
7255   "%@   %#"
7256   [(set_attr "type" "return")
7257    (set_attr "needs_delay_slot" "yes")])
7259 (define_expand "shcompact_return_tramp"
7260   [(return)]
7261   "TARGET_SHCOMPACT
7262    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7263   "
7265   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7266   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7268   if (flag_pic)
7269     emit_insn (gen_symGOTPLT2reg (reg, sym));
7270   else
7271     emit_move_insn (reg, sym);
7273   emit_jump_insn (gen_shcompact_return_tramp_i ());
7274   DONE;
7277 (define_insn "shcompact_return_tramp_i"
7278   [(parallel [(return) (use (reg:SI R0_REG))])]
7279   "TARGET_SHCOMPACT
7280    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7281   "jmp  @r0%#"
7282   [(set_attr "type" "jump_ind")
7283    (set_attr "needs_delay_slot" "yes")])
7285 (define_insn "return_media_i"
7286   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7287   "TARGET_SHMEDIA && reload_completed"
7288   "blink        %0, r63"
7289   [(set_attr "type" "jump_media")])
7291 (define_insn "return_media_rte"
7292   [(return)]
7293   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7294   "rte"
7295   [(set_attr "type" "jump_media")])
7297 (define_expand "return_media"
7298   [(return)]
7299   "TARGET_SHMEDIA && reload_completed"
7300   "
7302   int tr_regno = sh_media_register_for_return ();
7303   rtx tr;
7305   if (current_function_interrupt)
7306     {
7307       emit_jump_insn (gen_return_media_rte ());
7308       DONE;
7309     }
7310   if (tr_regno < 0)
7311     {
7312       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7314       if (! call_really_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7315         abort ();
7316       tr_regno = TR0_REG;
7317       tr = gen_rtx_REG (DImode, tr_regno);
7318       emit_move_insn (tr, r18);
7319     }
7320   else
7321     tr = gen_rtx_REG (DImode, tr_regno);
7323   emit_jump_insn (gen_return_media_i (tr));
7324   DONE;
7327 (define_insn "shcompact_preserve_incoming_args"
7328   [(set (match_operand:SI 0 "register_operand" "+r")
7329         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7330   "TARGET_SHCOMPACT"
7331   ""
7332   [(set_attr "length" "0")])
7334 (define_insn "shcompact_incoming_args"
7335   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7336    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7337    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7338    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7339    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7340    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7341    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7342    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7343    (set (mem:BLK (reg:SI MACL_REG))
7344         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7345    (use (reg:SI R0_REG))
7346    (clobber (reg:SI R0_REG))
7347    (clobber (reg:SI MACL_REG))
7348    (clobber (reg:SI MACH_REG))
7349    (clobber (reg:SI PR_REG))]
7350   "TARGET_SHCOMPACT"
7351   "jsr  @r0%#"
7352   [(set_attr "needs_delay_slot" "yes")])
7354 (define_insn "shmedia_save_restore_regs_compact"
7355   [(set (reg:SI SP_REG)
7356         (plus:SI (reg:SI SP_REG)
7357                  (match_operand:SI 0 "immediate_operand" "i")))
7358    (use (reg:SI R0_REG))
7359    (clobber (reg:SI PR_REG))]
7360   "TARGET_SHCOMPACT
7361    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7362        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7363   "jsr @r0%#"
7364   [(set_attr "needs_delay_slot" "yes")])
7366 (define_expand "prologue"
7367   [(const_int 0)]
7368   ""
7369   "sh_expand_prologue (); DONE;")
7371 (define_expand "epilogue"
7372   [(return)]
7373   ""
7374   "
7376   sh_expand_epilogue (0);
7377   emit_jump_insn (gen_return ());
7378   DONE;
7381 (define_expand "eh_return"
7382   [(use (match_operand 0 "register_operand" ""))]
7383   ""
7385   rtx ra = operands[0];
7387   if (TARGET_SHMEDIA64)
7388     emit_insn (gen_eh_set_ra_di (ra));
7389   else
7390     emit_insn (gen_eh_set_ra_si (ra));
7392   DONE;
7395 ;; Clobber the return address on the stack.  We can't expand this
7396 ;; until we know where it will be put in the stack frame.
7398 (define_insn "eh_set_ra_si"
7399   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7400    (clobber (match_scratch:SI 1 "=&r"))]
7401   "! TARGET_SHMEDIA64"
7402   "#")
7404 (define_insn "eh_set_ra_di"
7405   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7406    (clobber (match_scratch:DI 1 "=&r"))]
7407   "TARGET_SHMEDIA64"
7408   "#")
7410 (define_split
7411   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7412    (clobber (match_scratch 1 ""))]
7413   "reload_completed"
7414   [(const_int 0)]
7415   "
7417   sh_set_return_address (operands[0], operands[1]);
7418   DONE;
7421 (define_insn "blockage"
7422   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7423   ""
7424   ""
7425   [(set_attr "length" "0")])
7427 ;; ------------------------------------------------------------------------
7428 ;; Scc instructions
7429 ;; ------------------------------------------------------------------------
7431 (define_insn "movt"
7432   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7433         (eq:SI (reg:SI T_REG) (const_int 1)))]
7434   "TARGET_SH1"
7435   "movt %0"
7436   [(set_attr "type" "arith")])
7438 (define_expand "seq"
7439   [(set (match_operand:SI 0 "arith_reg_operand" "")
7440         (match_dup 1))]
7441   ""
7442   "
7444   if (TARGET_SHMEDIA)
7445     {
7446       if (GET_MODE (operands[0]) != DImode)
7447         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7448       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7449       if (sh_compare_op1 != const0_rtx)
7450         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7451                                     ? GET_MODE (sh_compare_op0)
7452                                     : GET_MODE (sh_compare_op1),
7453                                     sh_compare_op1);
7455       switch (GET_MODE (sh_compare_op0))
7456         {
7457         case DImode:
7458           emit_insn (gen_cmpeqdi_media (operands[0],
7459                                         sh_compare_op0, sh_compare_op1));
7460           break;
7462         case SFmode:
7463           if (! TARGET_SHMEDIA_FPU)
7464             FAIL;
7465           emit_insn (gen_cmpeqsf_media (operands[0],
7466                                         sh_compare_op0, sh_compare_op1));
7467           break;
7469         case DFmode:
7470           if (! TARGET_SHMEDIA_FPU)
7471             FAIL;
7472           emit_insn (gen_cmpeqdf_media (operands[0],
7473                                         sh_compare_op0, sh_compare_op1));
7474           break;
7476         default:
7477           FAIL;
7478         }
7479       DONE;
7480     }
7481   if (sh_expand_t_scc (EQ, operands[0]))
7482     DONE;
7483   if (! currently_expanding_to_rtl)
7484     FAIL;
7485   operands[1] = prepare_scc_operands (EQ);
7488 (define_expand "slt"
7489   [(set (match_operand:SI 0 "arith_reg_operand" "")
7490         (match_dup 1))]
7491   ""
7492   "
7494   if (TARGET_SHMEDIA)
7495     {
7496       if (GET_MODE (operands[0]) != DImode)
7497         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7498       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7499       if (sh_compare_op1 != const0_rtx)
7500         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7501                                     ? GET_MODE (sh_compare_op0)
7502                                     : GET_MODE (sh_compare_op1),
7503                                     sh_compare_op1);
7505       switch (GET_MODE (sh_compare_op0))
7506         {
7507         case DImode:
7508           emit_insn (gen_cmpgtdi_media (operands[0],
7509                                         sh_compare_op1, sh_compare_op0));
7510           break;
7512         case SFmode:
7513           if (! TARGET_SHMEDIA_FPU)
7514             FAIL;
7515           emit_insn (gen_cmpgtsf_media (operands[0],
7516                                         sh_compare_op1, sh_compare_op0));
7517           break;
7519         case DFmode:
7520           if (! TARGET_SHMEDIA_FPU)
7521             FAIL;
7522           emit_insn (gen_cmpgtdf_media (operands[0],
7523                                         sh_compare_op1, sh_compare_op0));
7524           break;
7526         default:
7527           FAIL;
7528         }
7529       DONE;
7530     }
7531   if (! currently_expanding_to_rtl)
7532     FAIL;
7533   operands[1] = prepare_scc_operands (LT);
7536 (define_expand "sle"
7537   [(match_operand:SI 0 "arith_reg_operand" "")]
7538   ""
7539   "
7541   rtx tmp = sh_compare_op0;
7543   if (TARGET_SHMEDIA)
7544     {
7545       if (GET_MODE (operands[0]) != DImode)
7546         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7547       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7548       if (sh_compare_op1 != const0_rtx)
7549         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7550                                     ? GET_MODE (sh_compare_op0)
7551                                     : GET_MODE (sh_compare_op1),
7552                                     sh_compare_op1);
7554       switch (GET_MODE (sh_compare_op0))
7555         {
7556         case DImode:
7557           {
7558             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7560             emit_insn (gen_cmpgtdi_media (tmp,
7561                                           sh_compare_op0, sh_compare_op1));
7562             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7563             break;
7564           }
7566         case SFmode:
7567           if (! TARGET_SHMEDIA_FPU)
7568             FAIL;
7569           emit_insn (gen_cmpgesf_media (operands[0],
7570                                         sh_compare_op1, sh_compare_op0));
7571           break;
7573         case DFmode:
7574           if (! TARGET_SHMEDIA_FPU)
7575             FAIL;
7576           emit_insn (gen_cmpgedf_media (operands[0],
7577                                         sh_compare_op1, sh_compare_op0));
7578           break;
7580         default:
7581           FAIL;
7582         }
7583       DONE;
7584     }
7586   sh_compare_op0 = sh_compare_op1;
7587   sh_compare_op1 = tmp;
7588   emit_insn (gen_sge (operands[0]));
7589   DONE;
7592 (define_expand "sgt"
7593   [(set (match_operand:SI 0 "arith_reg_operand" "")
7594         (match_dup 1))]
7595   ""
7596   "
7598   if (TARGET_SHMEDIA)
7599     {
7600       if (GET_MODE (operands[0]) != DImode)
7601         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7602       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7603       if (sh_compare_op1 != const0_rtx)
7604         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7605                                     ? GET_MODE (sh_compare_op0)
7606                                     : GET_MODE (sh_compare_op1),
7607                                     sh_compare_op1);
7609       switch (GET_MODE (sh_compare_op0))
7610         {
7611         case DImode:
7612           emit_insn (gen_cmpgtdi_media (operands[0],
7613                                         sh_compare_op0, sh_compare_op1));
7614           break;
7616         case SFmode:
7617           if (! TARGET_SHMEDIA_FPU)
7618             FAIL;
7619           emit_insn (gen_cmpgtsf_media (operands[0],
7620                                         sh_compare_op0, sh_compare_op1));
7621           break;
7623         case DFmode:
7624           if (! TARGET_SHMEDIA_FPU)
7625             FAIL;
7626           emit_insn (gen_cmpgtdf_media (operands[0],
7627                                         sh_compare_op0, sh_compare_op1));
7628           break;
7630         default:
7631           FAIL;
7632         }
7633       DONE;
7634     }
7635   if (! currently_expanding_to_rtl)
7636     FAIL;
7637   operands[1] = prepare_scc_operands (GT);
7640 (define_expand "sge"
7641   [(set (match_operand:SI 0 "arith_reg_operand" "")
7642         (match_dup 1))]
7643   ""
7644   "
7646   if (TARGET_SHMEDIA)
7647     {
7648       if (GET_MODE (operands[0]) != DImode)
7649         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7650       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7651       if (sh_compare_op1 != const0_rtx)
7652         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7653                                     ? GET_MODE (sh_compare_op0)
7654                                     : GET_MODE (sh_compare_op1),
7655                                     sh_compare_op1);
7657       switch (GET_MODE (sh_compare_op0))
7658         {
7659         case DImode:
7660           {
7661             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7663             emit_insn (gen_cmpgtdi_media (tmp,
7664                                           sh_compare_op1, sh_compare_op0));
7665             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7666             break;
7667           }
7669         case SFmode:
7670           if (! TARGET_SHMEDIA_FPU)
7671             FAIL;
7672           emit_insn (gen_cmpgesf_media (operands[0],
7673                                         sh_compare_op0, sh_compare_op1));
7674           break;
7676         case DFmode:
7677           if (! TARGET_SHMEDIA_FPU)
7678             FAIL;
7679           emit_insn (gen_cmpgedf_media (operands[0],
7680                                         sh_compare_op0, sh_compare_op1));
7681           break;
7683         default:
7684           FAIL;
7685         }
7686       DONE;
7687     }
7689   if (! currently_expanding_to_rtl)
7690     FAIL;
7691   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7692     {
7693       if (TARGET_IEEE)
7694         {
7695           rtx lab = gen_label_rtx ();
7696           prepare_scc_operands (EQ);
7697           emit_jump_insn (gen_branch_true (lab));
7698           prepare_scc_operands (GT);
7699           emit_label (lab);
7700           emit_insn (gen_movt (operands[0]));
7701         }
7702       else
7703         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7704       DONE;
7705     }
7706   operands[1] = prepare_scc_operands (GE);
7709 (define_expand "sgtu"
7710   [(set (match_operand:SI 0 "arith_reg_operand" "")
7711         (match_dup 1))]
7712   ""
7713   "
7715   if (TARGET_SHMEDIA)
7716     {
7717       if (GET_MODE (operands[0]) != DImode)
7718         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7719       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7720       if (sh_compare_op1 != const0_rtx)
7721         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7722                                     ? GET_MODE (sh_compare_op0)
7723                                     : GET_MODE (sh_compare_op1),
7724                                     sh_compare_op1);
7726       emit_insn (gen_cmpgtudi_media (operands[0],
7727                                      sh_compare_op0, sh_compare_op1));
7728       DONE;
7729     }
7730   if (! currently_expanding_to_rtl)
7731     FAIL;
7732   operands[1] = prepare_scc_operands (GTU);
7735 (define_expand "sltu"
7736   [(set (match_operand:SI 0 "arith_reg_operand" "")
7737         (match_dup 1))]
7738   ""
7739   "
7741   if (TARGET_SHMEDIA)
7742     {
7743       if (GET_MODE (operands[0]) != DImode)
7744         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7745       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7746       if (sh_compare_op1 != const0_rtx)
7747         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7748                                     ? GET_MODE (sh_compare_op0)
7749                                     : GET_MODE (sh_compare_op1),
7750                                     sh_compare_op1);
7752       emit_insn (gen_cmpgtudi_media (operands[0],
7753                                      sh_compare_op1, sh_compare_op0));
7754       DONE;
7755     }
7756   if (! currently_expanding_to_rtl)
7757     FAIL;
7758   operands[1] = prepare_scc_operands (LTU);
7761 (define_expand "sleu"
7762   [(set (match_operand:SI 0 "arith_reg_operand" "")
7763         (match_dup 1))]
7764   ""
7765   "
7767   if (TARGET_SHMEDIA)
7768     {
7769       rtx tmp;
7771       if (GET_MODE (operands[0]) != DImode)
7772         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7773       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7774       if (sh_compare_op1 != const0_rtx)
7775         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7776                                     ? GET_MODE (sh_compare_op0)
7777                                     : GET_MODE (sh_compare_op1),
7778                                     sh_compare_op1);
7780       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7782       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7783       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7785       DONE;
7786     }
7787   if (! currently_expanding_to_rtl)
7788     FAIL;
7789   operands[1] = prepare_scc_operands (LEU);
7792 (define_expand "sgeu"
7793   [(set (match_operand:SI 0 "arith_reg_operand" "")
7794         (match_dup 1))]
7795   ""
7796   "
7798   if (TARGET_SHMEDIA)
7799     {
7800       rtx tmp;
7802       if (GET_MODE (operands[0]) != DImode)
7803         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7804       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7805       if (sh_compare_op1 != const0_rtx)
7806         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7807                                     ? GET_MODE (sh_compare_op0)
7808                                     : GET_MODE (sh_compare_op1),
7809                                     sh_compare_op1);
7811       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7813       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7814       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7816       DONE;
7817     }
7819   if (! currently_expanding_to_rtl)
7820     FAIL;
7821   operands[1] = prepare_scc_operands (GEU);
7824 ;; sne moves the complement of the T reg to DEST like this:
7825 ;;      cmp/eq ...
7826 ;;      mov    #-1,temp
7827 ;;      negc   temp,dest
7828 ;;   This is better than xoring compare result with 1 because it does
7829 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7830 ;;   loop.
7832 (define_expand "sne"
7833   [(set (match_dup 2) (const_int -1))
7834    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7835                    (neg:SI (plus:SI (match_dup 1)
7836                                     (match_dup 2))))
7837               (set (reg:SI T_REG)
7838                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7839                           (const_int 0)))])]
7840   ""
7841   "
7843   if (TARGET_SHMEDIA)
7844     {
7845       rtx tmp;
7847       if (GET_MODE (operands[0]) != DImode)
7848         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7850       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7851         FAIL;
7853       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7854       if (sh_compare_op1 != const0_rtx)
7855         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7856                                     ? GET_MODE (sh_compare_op0)
7857                                     : GET_MODE (sh_compare_op1),
7858                                     sh_compare_op1);
7860       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7862       emit_insn (gen_seq (tmp));
7863       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7865       DONE;
7866     }
7868   if (sh_expand_t_scc (NE, operands[0]))
7869     DONE;
7870   if (! currently_expanding_to_rtl)
7871     FAIL;
7872   operands[1] = prepare_scc_operands (EQ);
7873   operands[2] = gen_reg_rtx (SImode);
7876 (define_expand "sunordered"
7877   [(set (match_operand:DI 0 "arith_reg_operand" "")
7878         (unordered:DI (match_dup 1) (match_dup 2)))]
7879   "TARGET_SHMEDIA_FPU"
7880   "
7882   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7883   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7886 ;; Use the same trick for FP sle / sge
7887 (define_expand "movnegt"
7888   [(set (match_dup 2) (const_int -1))
7889    (parallel [(set (match_operand 0 "" "")
7890                    (neg:SI (plus:SI (match_dup 1)
7891                                     (match_dup 2))))
7892               (set (reg:SI T_REG)
7893                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7894                           (const_int 0)))])]
7895   "TARGET_SH1"
7896   "operands[2] = gen_reg_rtx (SImode);")
7898 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7899 ;; This prevents a regression that occurred when we switched from xor to
7900 ;; mov/neg for sne.
7902 (define_split
7903   [(set (match_operand:SI 0 "arith_reg_operand" "")
7904         (plus:SI (reg:SI T_REG)
7905                  (const_int -1)))]
7906   "TARGET_SH1"
7907   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7908    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7909   "")
7911 ;; -------------------------------------------------------------------------
7912 ;; Instructions to cope with inline literal tables
7913 ;; -------------------------------------------------------------------------
7915 ; 2 byte integer in line
7917 (define_insn "consttable_2"
7918  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7919                     (match_operand 1 "" "")]
7920                    UNSPECV_CONST2)]
7921  ""
7922  "*
7924   if (operands[1] != const0_rtx)
7925     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7926   return \"\";
7928  [(set_attr "length" "2")
7929  (set_attr "in_delay_slot" "no")])
7931 ; 4 byte integer in line
7933 (define_insn "consttable_4"
7934  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7935                     (match_operand 1 "" "")]
7936                    UNSPECV_CONST4)]
7937  ""
7938  "*
7940   if (operands[1] != const0_rtx)
7941     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7942   return \"\";
7944  [(set_attr "length" "4")
7945   (set_attr "in_delay_slot" "no")])
7947 ; 8 byte integer in line
7949 (define_insn "consttable_8"
7950  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7951                     (match_operand 1 "" "")]
7952                    UNSPECV_CONST8)]
7953  ""
7954  "*
7956   if (operands[1] != const0_rtx)
7957     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7958   return \"\";
7960  [(set_attr "length" "8")
7961   (set_attr "in_delay_slot" "no")])
7963 ; 4 byte floating point
7965 (define_insn "consttable_sf"
7966  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7967                     (match_operand 1 "" "")]
7968                    UNSPECV_CONST4)]
7969  ""
7970  "*
7972   if (operands[1] != const0_rtx)
7973     {
7974       REAL_VALUE_TYPE d;
7975       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7976       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7977     }
7978   return \"\";
7980  [(set_attr "length" "4")
7981   (set_attr "in_delay_slot" "no")])
7983 ; 8 byte floating point
7985 (define_insn "consttable_df"
7986  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7987                     (match_operand 1 "" "")]
7988                    UNSPECV_CONST8)]
7989  ""
7990  "*
7992   if (operands[1] != const0_rtx)
7993     {
7994       REAL_VALUE_TYPE d;
7995       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7996       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7997     }
7998   return \"\";
8000  [(set_attr "length" "8")
8001   (set_attr "in_delay_slot" "no")])
8003 ;; Alignment is needed for some constant tables; it may also be added for
8004 ;; Instructions at the start of loops, or after unconditional branches.
8005 ;; ??? We would get more accurate lengths if we did instruction
8006 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8007 ;; here is too conservative.
8009 ; align to a two byte boundary
8011 (define_expand "align_2"
8012  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8013  ""
8014  "")
8016 ; align to a four byte boundary
8017 ;; align_4 and align_log are instructions for the starts of loops, or
8018 ;; after unconditional branches, which may take up extra room.
8020 (define_expand "align_4"
8021  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8022  ""
8023  "")
8025 ; align to a cache line boundary
8027 (define_insn "align_log"
8028  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8029  ""
8030  ""
8031  [(set_attr "length" "0")
8032   (set_attr "in_delay_slot" "no")])
8034 ; emitted at the end of the literal table, used to emit the
8035 ; 32bit branch labels if needed.
8037 (define_insn "consttable_end"
8038   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8039   ""
8040   "* return output_jump_label_table ();"
8041   [(set_attr "in_delay_slot" "no")])
8043 ; emitted at the end of the window in the literal table.
8045 (define_insn "consttable_window_end"
8046   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8047   ""
8048   ""
8049   [(set_attr "length" "0")
8050    (set_attr "in_delay_slot" "no")])
8052 ;; -------------------------------------------------------------------------
8053 ;; Misc
8054 ;; -------------------------------------------------------------------------
8056 ;; String/block move insn.
8058 (define_expand "movmemsi"
8059   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8060                    (mem:BLK (match_operand:BLK 1 "" "")))
8061               (use (match_operand:SI 2 "nonmemory_operand" ""))
8062               (use (match_operand:SI 3 "immediate_operand" ""))
8063               (clobber (reg:SI PR_REG))
8064               (clobber (reg:SI R4_REG))
8065               (clobber (reg:SI R5_REG))
8066               (clobber (reg:SI R0_REG))])]
8067   "TARGET_SH1 && ! TARGET_SH5"
8068   "
8070   if(expand_block_move (operands))
8071      DONE;
8072   else FAIL;
8075 (define_insn "block_move_real"
8076   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8077                    (mem:BLK (reg:SI R5_REG)))
8078               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8079               (clobber (reg:SI PR_REG))
8080               (clobber (reg:SI R0_REG))])]
8081   "TARGET_SH1 && ! TARGET_HARD_SH4"
8082   "jsr  @%0%#"
8083   [(set_attr "type" "sfunc")
8084    (set_attr "needs_delay_slot" "yes")])
8086 (define_insn "block_lump_real"
8087   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8088                    (mem:BLK (reg:SI R5_REG)))
8089               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8090               (use (reg:SI R6_REG))
8091               (clobber (reg:SI PR_REG))
8092               (clobber (reg:SI T_REG))
8093               (clobber (reg:SI R4_REG))
8094               (clobber (reg:SI R5_REG))
8095               (clobber (reg:SI R6_REG))
8096               (clobber (reg:SI R0_REG))])]
8097   "TARGET_SH1 && ! TARGET_HARD_SH4"
8098   "jsr  @%0%#"
8099   [(set_attr "type" "sfunc")
8100    (set_attr "needs_delay_slot" "yes")])
8102 (define_insn "block_move_real_i4"
8103   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8104                    (mem:BLK (reg:SI R5_REG)))
8105               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8106               (clobber (reg:SI PR_REG))
8107               (clobber (reg:SI R0_REG))
8108               (clobber (reg:SI R1_REG))
8109               (clobber (reg:SI R2_REG))])]
8110   "TARGET_HARD_SH4"
8111   "jsr  @%0%#"
8112   [(set_attr "type" "sfunc")
8113    (set_attr "needs_delay_slot" "yes")])
8115 (define_insn "block_lump_real_i4"
8116   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8117                    (mem:BLK (reg:SI R5_REG)))
8118               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8119               (use (reg:SI R6_REG))
8120               (clobber (reg:SI PR_REG))
8121               (clobber (reg:SI T_REG))
8122               (clobber (reg:SI R4_REG))
8123               (clobber (reg:SI R5_REG))
8124               (clobber (reg:SI R6_REG))
8125               (clobber (reg:SI R0_REG))
8126               (clobber (reg:SI R1_REG))
8127               (clobber (reg:SI R2_REG))
8128               (clobber (reg:SI R3_REG))])]
8129   "TARGET_HARD_SH4"
8130   "jsr  @%0%#"
8131   [(set_attr "type" "sfunc")
8132    (set_attr "needs_delay_slot" "yes")])
8134 ;; -------------------------------------------------------------------------
8135 ;; Floating point instructions.
8136 ;; -------------------------------------------------------------------------
8138 ;; ??? All patterns should have a type attribute.
8140 (define_expand "fpu_switch0"
8141   [(set (match_operand:SI 0 "" "") (match_dup 2))
8142    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8143   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8144   "
8146   operands[1] = get_fpscr_rtx ();
8147   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8148   if (flag_pic)
8149     operands[2] = legitimize_pic_address (operands[2], SImode,
8150                                           no_new_pseudos ? operands[0] : 0);
8153 (define_expand "fpu_switch1"
8154   [(set (match_operand:SI 0 "" "") (match_dup 2))
8155    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8156    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8157   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8158   "
8160   operands[1] = get_fpscr_rtx ();
8161   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8162   if (flag_pic)
8163     operands[2] = legitimize_pic_address (operands[2], SImode,
8164                                           no_new_pseudos ? operands[0] : 0);
8165   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8168 (define_expand "movpsi"
8169   [(set (match_operand:PSI 0 "register_operand" "")
8170         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8171   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8172   "")
8174 ;; The c / m alternative is a fake to guide reload to load directly into
8175 ;; fpscr, since reload doesn't know how to use post-increment.
8176 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8177 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8178 ;; predicate after reload.
8179 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8180 ;; like a mac -> gpr move.
8181 (define_insn "fpu_switch"
8182   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8183         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8184   "TARGET_SH2E
8185    && (! reload_completed
8186        || true_regnum (operands[0]) != FPSCR_REG
8187        || GET_CODE (operands[1]) != MEM
8188        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8189   "@
8190         ! precision stays the same
8191         lds.l   %1,fpscr
8192         mov.l   %1,%0
8193         #
8194         lds     %1,fpscr
8195         mov     %1,%0
8196         mov.l   %1,%0
8197         sts     fpscr,%0
8198         sts.l   fpscr,%0"
8199   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8200    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8202 (define_split
8203   [(set (reg:PSI FPSCR_REG)
8204         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8205   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8206   [(set (match_dup 0) (match_dup 0))]
8207   "
8209   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8210                                         gen_rtx_MEM (PSImode,
8211                                                  gen_rtx_POST_INC (Pmode,
8212                                                           operands[0]))));
8213   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8216 (define_split
8217   [(set (reg:PSI FPSCR_REG)
8218         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8219   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8220   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8221   "
8223   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8224                                         gen_rtx_MEM (PSImode,
8225                                                  gen_rtx_POST_INC (Pmode,
8226                                                           operands[0]))));
8227   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8230 ;; ??? This uses the fp unit, but has no type indicating that.
8231 ;; If we did that, this would either give a bogus latency or introduce
8232 ;; a bogus FIFO constraint.
8233 ;; Since this insn is currently only used for prologues/epilogues,
8234 ;; it is probably best to claim no function unit, which matches the
8235 ;; current setting.
8236 (define_insn "toggle_sz"
8237   [(set (reg:PSI FPSCR_REG)
8238         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8239   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8240   "fschg"
8241   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8243 ;; There's no way we can use it today, since optimize mode switching
8244 ;; doesn't enable us to know from which mode we're switching to the
8245 ;; mode it requests, to tell whether we can use a relative mode switch
8246 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8247 ;; memory).
8248 (define_insn "toggle_pr"
8249   [(set (reg:PSI FPSCR_REG)
8250         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8251   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8252   "fpchg"
8253   [(set_attr "type" "fp")])
8255 (define_expand "addsf3"
8256   [(set (match_operand:SF 0 "arith_reg_operand" "")
8257         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8258                  (match_operand:SF 2 "arith_reg_operand" "")))]
8259   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8260   "
8262   if (TARGET_SH2E)
8263     {
8264       expand_sf_binop (&gen_addsf3_i, operands);
8265       DONE;
8266     }
8269 (define_insn "*addsf3_media"
8270   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8271         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8272                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8273   "TARGET_SHMEDIA_FPU"
8274   "fadd.s       %1, %2, %0"
8275   [(set_attr "type" "fparith_media")])
8277 (define_insn_and_split "unary_sf_op"
8278   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8279         (vec_select:V2SF
8280          (vec_concat:V2SF
8281           (vec_select:SF
8282            (match_dup 0)
8283            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8284           (match_operator:SF 2 "unary_float_operator"
8285             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8286                             (parallel [(match_operand 4
8287                                         "const_int_operand" "n")]))]))
8288          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8289   "TARGET_SHMEDIA_FPU"
8290   "#"
8291   "TARGET_SHMEDIA_FPU && reload_completed"
8292   [(set (match_dup 5) (match_dup 6))]
8293   "
8295   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8296   rtx op1 = gen_rtx_REG (SFmode,
8297                          (true_regnum (operands[1])
8298                           + (INTVAL (operands[4]) ^ endian)));
8300   operands[7] = gen_rtx_REG (SFmode,
8301                              (true_regnum (operands[0])
8302                               + (INTVAL (operands[3]) ^ endian)));
8303   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8305   [(set_attr "type" "fparith_media")])
8307 (define_insn_and_split "binary_sf_op"
8308   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8309         (vec_select:V2SF
8310          (vec_concat:V2SF
8311           (vec_select:SF
8312            (match_dup 0)
8313            (parallel [(match_operand 7 "const_int_operand" "n")]))
8314           (match_operator:SF 3 "binary_float_operator"
8315             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8316                             (parallel [(match_operand 5
8317                                         "const_int_operand" "n")]))
8318              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8319                             (parallel [(match_operand 6
8320                                         "const_int_operand" "n")]))]))
8321          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8322   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8323   "#"
8324   "&& reload_completed"
8325   [(set (match_dup 8) (match_dup 9))]
8326   "
8328   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8329   rtx op1 = gen_rtx_REG (SFmode,
8330                          (true_regnum (operands[1])
8331                           + (INTVAL (operands[5]) ^ endian)));
8332   rtx op2 = gen_rtx_REG (SFmode,
8333                          (true_regnum (operands[2])
8334                           + (INTVAL (operands[6]) ^ endian)));
8336   operands[8] = gen_rtx_REG (SFmode,
8337                              (true_regnum (operands[0])
8338                               + (INTVAL (operands[4]) ^ endian)));
8339   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8341   [(set_attr "type" "fparith_media")])
8343 (define_insn "addsf3_i"
8344   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8345         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8346                  (match_operand:SF 2 "arith_reg_operand" "f")))
8347    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8348   "TARGET_SH2E"
8349   "fadd %2,%0"
8350   [(set_attr "type" "fp")
8351    (set_attr "fp_mode" "single")])
8353 (define_expand "subsf3"
8354   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8355         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8356                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8357   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8358   "
8360   if (TARGET_SH2E)
8361     {
8362       expand_sf_binop (&gen_subsf3_i, operands);
8363       DONE;
8364     }
8367 (define_insn "*subsf3_media"
8368   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8369         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8370                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8371   "TARGET_SHMEDIA_FPU"
8372   "fsub.s       %1, %2, %0"
8373   [(set_attr "type" "fparith_media")])
8375 (define_insn "subsf3_i"
8376   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8377         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8378                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8379    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8380   "TARGET_SH2E"
8381   "fsub %2,%0"
8382   [(set_attr "type" "fp")
8383    (set_attr "fp_mode" "single")])
8385 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8386 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8387 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8388 ;; SH3E, we use a separate insn for SH3E mulsf3.
8390 (define_expand "mulsf3"
8391   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8392         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8393                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8394   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8395   "
8397   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8398     expand_sf_binop (&gen_mulsf3_i4, operands);
8399   else if (TARGET_SH2E)
8400     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8401   if (! TARGET_SHMEDIA)
8402     DONE;
8405 (define_insn "*mulsf3_media"
8406   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8407         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8408                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8409   "TARGET_SHMEDIA_FPU"
8410   "fmul.s       %1, %2, %0"
8411   [(set_attr "type" "fparith_media")])
8413 (define_insn "mulsf3_i4"
8414   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8415         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8416                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8417    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8418   "TARGET_SH2E"
8419   "fmul %2,%0"
8420   [(set_attr "type" "fp")
8421    (set_attr "fp_mode" "single")])
8423 (define_insn "mulsf3_ie"
8424   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8425         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8426                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8427   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8428   "fmul %2,%0"
8429   [(set_attr "type" "fp")])
8431 (define_insn "*mac_media"
8432   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8433         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8434                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8435                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8436   "TARGET_SHMEDIA_FPU"
8437   "fmac.s %1, %2, %0"
8438   [(set_attr "type" "fparith_media")])
8440 (define_insn "*macsf3"
8441   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8442         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8443                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8444                  (match_operand:SF 3 "arith_reg_operand" "0")))
8445    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8446   "TARGET_SH2E && ! TARGET_SH4"
8447   "fmac fr0,%2,%0"
8448   [(set_attr "type" "fp")
8449    (set_attr "fp_mode" "single")])
8451 (define_expand "divsf3"
8452   [(set (match_operand:SF 0 "arith_reg_operand" "")
8453         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8454                 (match_operand:SF 2 "arith_reg_operand" "")))]
8455   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8456   "
8458   if (TARGET_SH2E)
8459     {
8460       expand_sf_binop (&gen_divsf3_i, operands);
8461       DONE;
8462     }
8465 (define_insn "*divsf3_media"
8466   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8467         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8468                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8469   "TARGET_SHMEDIA_FPU"
8470   "fdiv.s       %1, %2, %0"
8471   [(set_attr "type" "fdiv_media")])
8473 (define_insn "divsf3_i"
8474   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8475         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8476                  (match_operand:SF 2 "arith_reg_operand" "f")))
8477    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8478   "TARGET_SH2E"
8479   "fdiv %2,%0"
8480   [(set_attr "type" "fdiv")
8481    (set_attr "fp_mode" "single")])
8483 (define_insn "floatdisf2"
8484   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8485         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8486   "TARGET_SHMEDIA_FPU"
8487   "float.qs %1, %0"
8488   [(set_attr "type" "fpconv_media")])
8490 (define_expand "floatsisf2"
8491   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8492         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8493   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8494   "
8496   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8497     {
8498       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8499       DONE;
8500     }
8503 (define_insn "*floatsisf2_media"
8504   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8505         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8506   "TARGET_SHMEDIA_FPU"
8507   "float.ls     %1, %0"
8508   [(set_attr "type" "fpconv_media")])
8510 (define_insn "floatsisf2_i4"
8511   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8512         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8513    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8514   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8515   "float        %1,%0"
8516   [(set_attr "type" "fp")
8517    (set_attr "fp_mode" "single")])
8519 (define_insn "*floatsisf2_ie"
8520   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8521         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8522   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8523   "float        %1,%0"
8524   [(set_attr "type" "fp")])
8526 (define_insn "fix_truncsfdi2"
8527   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8528         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8529   "TARGET_SHMEDIA_FPU"
8530   "ftrc.sq %1, %0"
8531   [(set_attr "type" "fpconv_media")])
8533 (define_expand "fix_truncsfsi2"
8534   [(set (match_operand:SI 0 "fpul_operand" "=y")
8535         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8536   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8537   "
8539   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8540     {
8541       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8542       DONE;
8543     }
8546 (define_insn "*fix_truncsfsi2_media"
8547   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8548         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8549   "TARGET_SHMEDIA_FPU"
8550   "ftrc.sl      %1, %0"
8551   [(set_attr "type" "fpconv_media")])
8553 (define_insn "fix_truncsfsi2_i4"
8554   [(set (match_operand:SI 0 "fpul_operand" "=y")
8555         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8556    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8557   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8558   "ftrc %1,%0"
8559   [(set_attr "type" "ftrc_s")
8560    (set_attr "fp_mode" "single")])
8562 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8563 ;; fix_truncsfsi2_i4.
8564 ;; (define_insn "fix_truncsfsi2_i4_2"
8565 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8566 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8567 ;;   (use (reg:PSI FPSCR_REG))
8568 ;;   (clobber (reg:SI FPUL_REG))]
8569 ;;  "TARGET_SH4"
8570 ;;  "#"
8571 ;;  [(set_attr "length" "4")
8572 ;;   (set_attr "fp_mode" "single")])
8574 ;;(define_split
8575 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8576 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8577 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8578 ;;   (clobber (reg:SI FPUL_REG))]
8579 ;;  "TARGET_SH4"
8580 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8581 ;;            (use (match_dup 2))])
8582 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8584 (define_insn "*fixsfsi"
8585   [(set (match_operand:SI 0 "fpul_operand" "=y")
8586         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8587   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8588   "ftrc %1,%0"
8589   [(set_attr "type" "fp")])
8591 (define_insn "cmpgtsf_t"
8592   [(set (reg:SI T_REG)
8593         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8594                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8595   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8596   "fcmp/gt      %1,%0"
8597   [(set_attr "type" "fp")
8598    (set_attr "fp_mode" "single")])
8600 (define_insn "cmpeqsf_t"
8601   [(set (reg:SI T_REG)
8602         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8603                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8604   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8605   "fcmp/eq      %1,%0"
8606   [(set_attr "type" "fp")
8607    (set_attr "fp_mode" "single")])
8609 (define_insn "ieee_ccmpeqsf_t"
8610   [(set (reg:SI T_REG)
8611         (ior:SI (reg:SI T_REG)
8612                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8613                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8614   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8615   "* return output_ieee_ccmpeq (insn, operands);"
8616   [(set_attr "length" "4")])
8619 (define_insn "cmpgtsf_t_i4"
8620   [(set (reg:SI T_REG)
8621         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8622                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8623    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8624   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8625   "fcmp/gt      %1,%0"
8626   [(set_attr "type" "fp")
8627    (set_attr "fp_mode" "single")])
8629 (define_insn "cmpeqsf_t_i4"
8630   [(set (reg:SI T_REG)
8631         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8632                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8633    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8634   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8635   "fcmp/eq      %1,%0"
8636   [(set_attr "type" "fp")
8637    (set_attr "fp_mode" "single")])
8639 (define_insn "*ieee_ccmpeqsf_t_4"
8640   [(set (reg:SI T_REG)
8641         (ior:SI (reg:SI T_REG)
8642                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8643                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8644    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8645   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8646   "* return output_ieee_ccmpeq (insn, operands);"
8647   [(set_attr "length" "4")
8648    (set_attr "fp_mode" "single")])
8650 (define_insn "cmpeqsf_media"
8651   [(set (match_operand:DI 0 "register_operand" "=r")
8652         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8653                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8654   "TARGET_SHMEDIA_FPU"
8655   "fcmpeq.s     %1, %2, %0"
8656   [(set_attr "type" "fcmp_media")])
8658 (define_insn "cmpgtsf_media"
8659   [(set (match_operand:DI 0 "register_operand" "=r")
8660         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8661                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8662   "TARGET_SHMEDIA_FPU"
8663   "fcmpgt.s     %1, %2, %0"
8664   [(set_attr "type" "fcmp_media")])
8666 (define_insn "cmpgesf_media"
8667   [(set (match_operand:DI 0 "register_operand" "=r")
8668         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8669                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8670   "TARGET_SHMEDIA_FPU"
8671   "fcmpge.s     %1, %2, %0"
8672   [(set_attr "type" "fcmp_media")])
8674 (define_insn "cmpunsf_media"
8675   [(set (match_operand:DI 0 "register_operand" "=r")
8676         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8677                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8678   "TARGET_SHMEDIA_FPU"
8679   "fcmpun.s     %1, %2, %0"
8680   [(set_attr "type" "fcmp_media")])
8682 (define_expand "cmpsf"
8683   [(set (reg:SI T_REG)
8684         (compare (match_operand:SF 0 "arith_operand" "")
8685                  (match_operand:SF 1 "arith_operand" "")))]
8686   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8687   "
8689   sh_compare_op0 = operands[0];
8690   sh_compare_op1 = operands[1];
8691   DONE;
8694 (define_expand "negsf2"
8695   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8696         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8697   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8698   "
8700   if (TARGET_SH2E)
8701     {
8702       expand_sf_unop (&gen_negsf2_i, operands);
8703       DONE;
8704     }
8707 (define_insn "*negsf2_media"
8708   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8709         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8710   "TARGET_SHMEDIA_FPU"
8711   "fneg.s       %1, %0"
8712   [(set_attr "type" "fmove_media")])
8714 (define_insn "negsf2_i"
8715   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8716         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8717    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8718   "TARGET_SH2E"
8719   "fneg %0"
8720   [(set_attr "type" "fmove")
8721    (set_attr "fp_mode" "single")])
8723 (define_expand "sqrtsf2"
8724   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8725         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8726   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8727   "
8729   if (TARGET_SH3E)
8730     {
8731       expand_sf_unop (&gen_sqrtsf2_i, operands);
8732       DONE;
8733     }
8736 (define_insn "*sqrtsf2_media"
8737   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8738         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8739   "TARGET_SHMEDIA_FPU"
8740   "fsqrt.s      %1, %0"
8741   [(set_attr "type" "fdiv_media")])
8743 (define_insn "sqrtsf2_i"
8744   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8745         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8746    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8747   "TARGET_SH3E"
8748   "fsqrt        %0"
8749   [(set_attr "type" "fdiv")
8750    (set_attr "fp_mode" "single")])
8752 (define_insn "rsqrtsf2"
8753   [(set (match_operand:SF 0 "register_operand" "=f")
8754         (div:SF (match_operand:SF 1 "immediate_operand" "i")
8755                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8756    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8757   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8758    && operands[1] == CONST1_RTX (SFmode)"
8759   "fsrra        %0"
8760   [(set_attr "type" "fsrra")
8761    (set_attr "fp_mode" "single")])
8763 (define_insn "fsca"
8764   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8765         (vec_concat:V2SF
8766          (unspec:SF [(mult:SF
8767                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8768                       (match_operand:SF 2 "immediate_operand" "i"))
8769                     ] UNSPEC_FSINA)
8770          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8771                     ] UNSPEC_FCOSA)))
8772    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8773   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8774    && operands[2] == sh_fsca_int2sf ()"
8775   "fsca fpul,%d0"
8776   [(set_attr "type" "fsca")
8777    (set_attr "fp_mode" "single")])
8779 (define_expand "sinsf2"
8780   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8781         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8782                    UNSPEC_FSINA))]
8783   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8784   "
8786   rtx scaled = gen_reg_rtx (SFmode);
8787   rtx truncated = gen_reg_rtx (SImode);
8788   rtx fsca = gen_reg_rtx (V2SFmode);
8789   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8791   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8792   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8793   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8794                           get_fpscr_rtx ()));
8795   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8796   DONE;
8799 (define_expand "cossf2"
8800   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8801         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8802                    UNSPEC_FCOSA))]
8803   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8804   "
8806   rtx scaled = gen_reg_rtx (SFmode);
8807   rtx truncated = gen_reg_rtx (SImode);
8808   rtx fsca = gen_reg_rtx (V2SFmode);
8809   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8811   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8812   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8813   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8814                           get_fpscr_rtx ()));
8815   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8816   DONE;
8819 (define_expand "sindf2"
8820   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8821         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8822                    UNSPEC_FSINA))]
8823   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8824   "
8826   rtx scaled = gen_reg_rtx (DFmode);
8827   rtx truncated = gen_reg_rtx (SImode);
8828   rtx fsca = gen_reg_rtx (V2SFmode);
8829   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8830   rtx sfresult = gen_reg_rtx (SFmode);
8832   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8833   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8834   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8835                           get_fpscr_rtx ()));
8836   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8837   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8838   DONE;
8841 (define_expand "cosdf2"
8842   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8843         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8844                    UNSPEC_FCOSA))]
8845   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8846   "
8848   rtx scaled = gen_reg_rtx (DFmode);
8849   rtx truncated = gen_reg_rtx (SImode);
8850   rtx fsca = gen_reg_rtx (V2SFmode);
8851   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8852   rtx sfresult = gen_reg_rtx (SFmode);
8854   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8855   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8856   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8857                           get_fpscr_rtx ()));
8858   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8859   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8860   DONE;
8863 (define_expand "abssf2"
8864   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8865         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8866   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8867   "
8869   if (TARGET_SH2E)
8870     {
8871       expand_sf_unop (&gen_abssf2_i, operands);
8872       DONE;
8873     }
8876 (define_insn "*abssf2_media"
8877   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8878         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8879   "TARGET_SHMEDIA_FPU"
8880   "fabs.s       %1, %0"
8881   [(set_attr "type" "fmove_media")])
8883 (define_insn "abssf2_i"
8884   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8885         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8886    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8887   "TARGET_SH2E"
8888   "fabs %0"
8889   [(set_attr "type" "fmove")
8890    (set_attr "fp_mode" "single")])
8892 (define_expand "adddf3"
8893   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8894         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8895                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8896   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8897   "
8899   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8900     {
8901       expand_df_binop (&gen_adddf3_i, operands);
8902       DONE;
8903     }
8906 (define_insn "*adddf3_media"
8907   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8908         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8909                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8910   "TARGET_SHMEDIA_FPU"
8911   "fadd.d       %1, %2, %0"
8912   [(set_attr "type" "dfparith_media")])
8914 (define_insn "adddf3_i"
8915   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8916         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8917                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8918    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8919   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8920   "fadd %2,%0"
8921   [(set_attr "type" "dfp_arith")
8922    (set_attr "fp_mode" "double")])
8924 (define_expand "subdf3"
8925   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8926         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8927                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8928   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8929   "
8931   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8932     {
8933       expand_df_binop (&gen_subdf3_i, operands);
8934       DONE;
8935     }
8938 (define_insn "*subdf3_media"
8939   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8940         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8941                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8942   "TARGET_SHMEDIA_FPU"
8943   "fsub.d       %1, %2, %0"
8944   [(set_attr "type" "dfparith_media")])
8946 (define_insn "subdf3_i"
8947   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8948         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8949                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8950    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8951   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8952   "fsub %2,%0"
8953   [(set_attr "type" "dfp_arith")
8954    (set_attr "fp_mode" "double")])
8956 (define_expand "muldf3"
8957   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8958         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8959                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8960   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8961   "
8963   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8964     {
8965       expand_df_binop (&gen_muldf3_i, operands);
8966       DONE;
8967     }
8970 (define_insn "*muldf3_media"
8971   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8972         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8973                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8974   "TARGET_SHMEDIA_FPU"
8975   "fmul.d       %1, %2, %0"
8976   [(set_attr "type" "dfmul_media")])
8978 (define_insn "muldf3_i"
8979   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8980         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8981                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8982    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8983   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8984   "fmul %2,%0"
8985   [(set_attr "type" "dfp_arith")
8986    (set_attr "fp_mode" "double")])
8988 (define_expand "divdf3"
8989   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8990         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8991                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8992   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8993   "
8995   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8996     {
8997       expand_df_binop (&gen_divdf3_i, operands);
8998       DONE;
8999     }
9002 (define_insn "*divdf3_media"
9003   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9004         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
9005                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9006   "TARGET_SHMEDIA_FPU"
9007   "fdiv.d       %1, %2, %0"
9008   [(set_attr "type" "dfdiv_media")])
9010 (define_insn "divdf3_i"
9011   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9012         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
9013                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9014    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9015   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9016   "fdiv %2,%0"
9017   [(set_attr "type" "dfdiv")
9018    (set_attr "fp_mode" "double")])
9020 (define_insn "floatdidf2"
9021   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9022         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
9023   "TARGET_SHMEDIA_FPU"
9024   "float.qd     %1, %0"
9025   [(set_attr "type" "dfpconv_media")])
9027 (define_expand "floatsidf2"
9028   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9029         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
9030   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9031   "
9033   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9034     {
9035       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
9036                                       get_fpscr_rtx ()));
9037       DONE;
9038     }
9041 (define_insn "*floatsidf2_media"
9042   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9043         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
9044   "TARGET_SHMEDIA_FPU"
9045   "float.ld     %1, %0"
9046   [(set_attr "type" "dfpconv_media")])
9048 (define_insn "floatsidf2_i"
9049   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9050         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
9051    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9052   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9053   "float        %1,%0"
9054   [(set_attr "type" "dfp_conv")
9055    (set_attr "fp_mode" "double")])
9057 (define_insn "fix_truncdfdi2"
9058   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
9059         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9060   "TARGET_SHMEDIA_FPU"
9061   "ftrc.dq      %1, %0"
9062   [(set_attr "type" "dfpconv_media")])
9064 (define_expand "fix_truncdfsi2"
9065   [(set (match_operand:SI 0 "fpul_operand" "")
9066         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9067   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9068   "
9070   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9071     {
9072       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9073                                           get_fpscr_rtx ()));
9074       DONE;
9075     }
9078 (define_insn "*fix_truncdfsi2_media"
9079   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9080         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9081   "TARGET_SHMEDIA_FPU"
9082   "ftrc.dl      %1, %0"
9083   [(set_attr "type" "dfpconv_media")])
9085 (define_insn "fix_truncdfsi2_i"
9086   [(set (match_operand:SI 0 "fpul_operand" "=y")
9087         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9088    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9089   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9090   "ftrc %1,%0"
9091   [(set_attr "type" "dfp_conv")
9092    (set_attr "dfp_comp" "no")
9093    (set_attr "fp_mode" "double")])
9095 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
9096 ;; fix_truncdfsi2_i.
9097 ;; (define_insn "fix_truncdfsi2_i4"
9098 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9099 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9100 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9101 ;;    (clobber (reg:SI FPUL_REG))]
9102 ;;   "TARGET_SH4"
9103 ;;   "#"
9104 ;;   [(set_attr "length" "4")
9105 ;;    (set_attr "fp_mode" "double")])
9107 ;; (define_split
9108 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9109 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9110 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9111 ;;    (clobber (reg:SI FPUL_REG))]
9112 ;;   "TARGET_SH4"
9113 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9114 ;;            (use (match_dup 2))])
9115 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
9117 (define_insn "cmpgtdf_t"
9118   [(set (reg:SI T_REG)
9119         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9120                (match_operand:DF 1 "arith_reg_operand" "f")))
9121    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9122   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9123   "fcmp/gt      %1,%0"
9124   [(set_attr "type" "dfp_cmp")
9125    (set_attr "fp_mode" "double")])
9127 (define_insn "cmpeqdf_t"
9128   [(set (reg:SI T_REG)
9129         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9130                (match_operand:DF 1 "arith_reg_operand" "f")))
9131    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9132   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9133   "fcmp/eq      %1,%0"
9134   [(set_attr "type" "dfp_cmp")
9135    (set_attr "fp_mode" "double")])
9137 (define_insn "*ieee_ccmpeqdf_t"
9138   [(set (reg:SI T_REG)
9139         (ior:SI (reg:SI T_REG)
9140                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9141                        (match_operand:DF 1 "arith_reg_operand" "f"))))
9142    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9143   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9144   "* return output_ieee_ccmpeq (insn, operands);"
9145   [(set_attr "length" "4")
9146    (set_attr "fp_mode" "double")])
9148 (define_insn "cmpeqdf_media"
9149   [(set (match_operand:DI 0 "register_operand" "=r")
9150         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9151                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9152   "TARGET_SHMEDIA_FPU"
9153   "fcmpeq.d     %1,%2,%0"
9154   [(set_attr "type" "fcmp_media")])
9156 (define_insn "cmpgtdf_media"
9157   [(set (match_operand:DI 0 "register_operand" "=r")
9158         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9159                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9160   "TARGET_SHMEDIA_FPU"
9161   "fcmpgt.d     %1,%2,%0"
9162   [(set_attr "type" "fcmp_media")])
9164 (define_insn "cmpgedf_media"
9165   [(set (match_operand:DI 0 "register_operand" "=r")
9166         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9167                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9168   "TARGET_SHMEDIA_FPU"
9169   "fcmpge.d     %1,%2,%0"
9170   [(set_attr "type" "fcmp_media")])
9172 (define_insn "cmpundf_media"
9173   [(set (match_operand:DI 0 "register_operand" "=r")
9174         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9175                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9176   "TARGET_SHMEDIA_FPU"
9177   "fcmpun.d     %1,%2,%0"
9178   [(set_attr "type" "fcmp_media")])
9180 (define_expand "cmpdf"
9181   [(set (reg:SI T_REG)
9182         (compare (match_operand:DF 0 "arith_operand" "")
9183                  (match_operand:DF 1 "arith_operand" "")))]
9184   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9185   "
9187   sh_compare_op0 = operands[0];
9188   sh_compare_op1 = operands[1];
9189   DONE;
9192 (define_expand "negdf2"
9193   [(set (match_operand:DF 0 "arith_reg_operand" "")
9194         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9195   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9196   "
9198   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9199     {
9200       expand_df_unop (&gen_negdf2_i, operands);
9201       DONE;
9202     }
9205 (define_insn "*negdf2_media"
9206   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9207         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9208   "TARGET_SHMEDIA_FPU"
9209   "fneg.d       %1, %0"
9210   [(set_attr "type" "fmove_media")])
9212 (define_insn "negdf2_i"
9213   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9214         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9215    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9216   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9217   "fneg %0"
9218   [(set_attr "type" "fmove")
9219    (set_attr "fp_mode" "double")])
9221 (define_expand "sqrtdf2"
9222   [(set (match_operand:DF 0 "arith_reg_operand" "")
9223         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9224   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9225   "
9227   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9228     {
9229       expand_df_unop (&gen_sqrtdf2_i, operands);
9230       DONE;
9231     }
9234 (define_insn "*sqrtdf2_media"
9235   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9236         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9237   "TARGET_SHMEDIA_FPU"
9238   "fsqrt.d      %1, %0"
9239   [(set_attr "type" "dfdiv_media")])
9241 (define_insn "sqrtdf2_i"
9242   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9243         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9244    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9245   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9246   "fsqrt        %0"
9247   [(set_attr "type" "dfdiv")
9248    (set_attr "fp_mode" "double")])
9250 (define_expand "absdf2"
9251   [(set (match_operand:DF 0 "arith_reg_operand" "")
9252         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9253   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9254   "
9256   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9257     {
9258       expand_df_unop (&gen_absdf2_i, operands);
9259       DONE;
9260     }
9263 (define_insn "*absdf2_media"
9264   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9265         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9266   "TARGET_SHMEDIA_FPU"
9267   "fabs.d       %1, %0"
9268   [(set_attr "type" "fmove_media")])
9270 (define_insn "absdf2_i"
9271   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9272         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9273    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9274   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9275   "fabs %0"
9276   [(set_attr "type" "fmove")
9277    (set_attr "fp_mode" "double")])
9279 (define_expand "extendsfdf2"
9280   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9281         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9282   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9283   "
9285   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9286     {
9287       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9288                                         get_fpscr_rtx ()));
9289       DONE;
9290     }
9293 (define_insn "*extendsfdf2_media"
9294   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9295         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9296   "TARGET_SHMEDIA_FPU"
9297   "fcnv.sd      %1, %0"
9298   [(set_attr "type" "dfpconv_media")])
9300 (define_insn "extendsfdf2_i4"
9301   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9302         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9303    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9304   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9305   "fcnvsd  %1,%0"
9306   [(set_attr "type" "fp")
9307    (set_attr "fp_mode" "double")])
9309 (define_expand "truncdfsf2"
9310   [(set (match_operand:SF 0 "fpul_operand" "")
9311         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9312   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9313   "
9315   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9316     {
9317       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9318                                        get_fpscr_rtx ()));
9319       DONE;
9320     }
9323 (define_insn "*truncdfsf2_media"
9324   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9325         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9326   "TARGET_SHMEDIA_FPU"
9327   "fcnv.ds      %1, %0"
9328   [(set_attr "type" "dfpconv_media")])
9330 (define_insn "truncdfsf2_i4"
9331   [(set (match_operand:SF 0 "fpul_operand" "=y")
9332         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9333    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9334   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9335   "fcnvds  %1,%0"
9336   [(set_attr "type" "fp")
9337    (set_attr "fp_mode" "double")])
9339 ;; Bit field extract patterns.  These give better code for packed bitfields,
9340 ;; because they allow auto-increment addresses to be generated.
9342 (define_expand "insv"
9343   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9344                          (match_operand:SI 1 "immediate_operand" "")
9345                          (match_operand:SI 2 "immediate_operand" ""))
9346         (match_operand:SI 3 "general_operand" ""))]
9347   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9348   "
9350   rtx addr_target, orig_address, shift_reg, qi_val;
9351   HOST_WIDE_INT bitsize, size, v = 0;
9352   rtx x = operands[3];
9354   /* ??? expmed doesn't care for non-register predicates.  */
9355   if (! memory_operand (operands[0], VOIDmode)
9356       || ! immediate_operand (operands[1], VOIDmode)
9357       || ! immediate_operand (operands[2], VOIDmode)
9358       || ! general_operand (x, VOIDmode))
9359     FAIL;
9360   /* If this isn't a 16 / 24 / 32 bit field, or if
9361      it doesn't start on a byte boundary, then fail.  */
9362   bitsize = INTVAL (operands[1]);
9363   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9364       || (INTVAL (operands[2]) % 8) != 0)
9365     FAIL;
9367   size = bitsize / 8;
9368   orig_address = XEXP (operands[0], 0);
9369   shift_reg = gen_reg_rtx (SImode);
9370   if (GET_CODE (x) == CONST_INT)
9371     {
9372       v = INTVAL (x);
9373       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9374     }
9375   else
9376     {
9377       emit_insn (gen_movsi (shift_reg, operands[3]));
9378       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9379     }
9380   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9382   operands[0] = replace_equiv_address (operands[0], addr_target);
9383   emit_insn (gen_movqi (operands[0], qi_val));
9385   while (size -= 1)
9386     {
9387       if (GET_CODE (x) == CONST_INT)
9388         qi_val
9389           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9390       else
9391         {
9392           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9393           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9394         }
9395       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9396       emit_insn (gen_movqi (operands[0], qi_val));
9397     }
9399   DONE;
9402 (define_insn "movua"
9403   [(set (match_operand:SI 0 "register_operand" "=z")
9404         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9405                          (const_int 32) (const_int 0)))]
9406   "TARGET_SH4A_ARCH"
9407   "movua.l      %1,%0"
9408   [(set_attr "type" "movua")])
9410 ;; We shouldn't need this, but cse replaces increments with references
9411 ;; to other regs before flow has a chance to create post_inc
9412 ;; addressing modes, and only postreload's cse_move2add brings the
9413 ;; increments back to a usable form.
9414 (define_peephole2
9415   [(set (match_operand:SI 0 "register_operand" "")
9416         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9417                          (const_int 32) (const_int 0)))
9418    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9419   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9420   [(set (match_operand:SI 0 "register_operand" "")
9421         (sign_extract:SI (mem:SI (post_inc:SI
9422                                   (match_operand:SI 1 "register_operand" "")))
9423                          (const_int 32) (const_int 0)))]
9424   "")
9426 (define_expand "extv"
9427   [(set (match_operand:SI 0 "register_operand" "")
9428         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9429                          (match_operand 2 "const_int_operand" "")
9430                          (match_operand 3 "const_int_operand" "")))]
9431   ""
9433   if (TARGET_SH4A_ARCH
9434       && INTVAL (operands[2]) == 32
9435       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9436       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9437     {
9438       emit_insn (gen_movua (operands[0],
9439                             adjust_address (operands[1], SImode, 0)));
9440       DONE;
9441     }
9443   FAIL;
9446 (define_expand "extzv"
9447   [(set (match_operand:SI 0 "register_operand" "")
9448         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9449                          (match_operand 2 "const_int_operand" "")
9450                          (match_operand 3 "const_int_operand" "")))]
9451   ""
9453   if (TARGET_SH4A_ARCH
9454       && INTVAL (operands[2]) == 32
9455       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9456       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9457     {
9458       emit_insn (gen_movua (operands[0],
9459                             adjust_address (operands[1], SImode, 0)));
9460       DONE;
9461     }
9463   FAIL;
9467 ;; -------------------------------------------------------------------------
9468 ;; Peepholes
9469 ;; -------------------------------------------------------------------------
9471 ;; This matches cases where a stack pointer increment at the start of the
9472 ;; epilogue combines with a stack slot read loading the return value.
9474 (define_peephole
9475   [(set (match_operand:SI 0 "arith_reg_operand" "")
9476         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9477    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9478   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9479   "mov.l        @%1+,%0")
9481 ;; See the comment on the dt combiner pattern above.
9483 (define_peephole
9484   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9485         (plus:SI (match_dup 0)
9486                  (const_int -1)))
9487    (set (reg:SI T_REG)
9488         (eq:SI (match_dup 0)
9489                (const_int 0)))]
9490   "TARGET_SH2"
9491   "dt   %0")
9493 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9494 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9495 ;; reload when the constant is too large for a reg+offset address.
9497 ;; ??? We would get much better code if this was done in reload.  This would
9498 ;; require modifying find_reloads_address to recognize that if the constant
9499 ;; is out-of-range for an immediate add, then we get better code by reloading
9500 ;; the constant into a register than by reloading the sum into a register,
9501 ;; since the former is one instruction shorter if the address does not need
9502 ;; to be offsettable.  Unfortunately this does not work, because there is
9503 ;; only one register, r0, that can be used as an index register.  This register
9504 ;; is also the function return value register.  So, if we try to force reload
9505 ;; to use double-reg addresses, then we end up with some instructions that
9506 ;; need to use r0 twice.  The only way to fix this is to change the calling
9507 ;; convention so that r0 is not used to return values.
9509 (define_peephole
9510   [(set (match_operand:SI 0 "register_operand" "=r")
9511         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9512    (set (mem:SI (match_dup 0))
9513         (match_operand:SI 2 "general_movsrc_operand" ""))]
9514   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9515   "mov.l        %2,@(%0,%1)")
9517 (define_peephole
9518   [(set (match_operand:SI 0 "register_operand" "=r")
9519         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9520    (set (match_operand:SI 2 "general_movdst_operand" "")
9521         (mem:SI (match_dup 0)))]
9522   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9523   "mov.l        @(%0,%1),%2")
9525 (define_peephole
9526   [(set (match_operand:SI 0 "register_operand" "=r")
9527         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9528    (set (mem:HI (match_dup 0))
9529         (match_operand:HI 2 "general_movsrc_operand" ""))]
9530   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9531   "mov.w        %2,@(%0,%1)")
9533 (define_peephole
9534   [(set (match_operand:SI 0 "register_operand" "=r")
9535         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9536    (set (match_operand:HI 2 "general_movdst_operand" "")
9537         (mem:HI (match_dup 0)))]
9538   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9539   "mov.w        @(%0,%1),%2")
9541 (define_peephole
9542   [(set (match_operand:SI 0 "register_operand" "=r")
9543         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9544    (set (mem:QI (match_dup 0))
9545         (match_operand:QI 2 "general_movsrc_operand" ""))]
9546   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9547   "mov.b        %2,@(%0,%1)")
9549 (define_peephole
9550   [(set (match_operand:SI 0 "register_operand" "=r")
9551         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9552    (set (match_operand:QI 2 "general_movdst_operand" "")
9553         (mem:QI (match_dup 0)))]
9554   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9555   "mov.b        @(%0,%1),%2")
9557 (define_peephole
9558   [(set (match_operand:SI 0 "register_operand" "=r")
9559         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9560    (set (mem:SF (match_dup 0))
9561         (match_operand:SF 2 "general_movsrc_operand" ""))]
9562   "TARGET_SH1 && REGNO (operands[0]) == 0
9563    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9564        || (GET_CODE (operands[2]) == SUBREG
9565            && REGNO (SUBREG_REG (operands[2])) < 16))
9566    && reg_unused_after (operands[0], insn)"
9567   "mov.l        %2,@(%0,%1)")
9569 (define_peephole
9570   [(set (match_operand:SI 0 "register_operand" "=r")
9571         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9572    (set (match_operand:SF 2 "general_movdst_operand" "")
9574         (mem:SF (match_dup 0)))]
9575   "TARGET_SH1 && REGNO (operands[0]) == 0
9576    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9577        || (GET_CODE (operands[2]) == SUBREG
9578            && REGNO (SUBREG_REG (operands[2])) < 16))
9579    && reg_unused_after (operands[0], insn)"
9580   "mov.l        @(%0,%1),%2")
9582 (define_peephole
9583   [(set (match_operand:SI 0 "register_operand" "=r")
9584         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9585    (set (mem:SF (match_dup 0))
9586         (match_operand:SF 2 "general_movsrc_operand" ""))]
9587   "TARGET_SH2E && REGNO (operands[0]) == 0
9588    && ((GET_CODE (operands[2]) == REG
9589         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9590        || (GET_CODE (operands[2]) == SUBREG
9591            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9592    && reg_unused_after (operands[0], insn)"
9593   "fmov{.s|}    %2,@(%0,%1)")
9595 (define_peephole
9596   [(set (match_operand:SI 0 "register_operand" "=r")
9597         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9598    (set (match_operand:SF 2 "general_movdst_operand" "")
9600         (mem:SF (match_dup 0)))]
9601   "TARGET_SH2E && REGNO (operands[0]) == 0
9602    && ((GET_CODE (operands[2]) == REG
9603         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9604        || (GET_CODE (operands[2]) == SUBREG
9605            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9606    && reg_unused_after (operands[0], insn)"
9607   "fmov{.s|}    @(%0,%1),%2")
9609 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9610 (define_insn "sp_switch_1"
9611   [(const_int 1)]
9612   "TARGET_SH1"
9613   "*
9615   rtx xoperands[1];
9617   xoperands[0] = sp_switch;
9618   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9619   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9620   return \"mov r0,r15\";
9622   [(set_attr "length" "10")])
9624 ;; Switch back to the original stack for interrupt functions with the
9625 ;; sp_switch attribute.  */
9626 (define_insn "sp_switch_2"
9627   [(const_int 2)]
9628   "TARGET_SH1"
9629   "mov.l @r15+,r15\;mov.l @r15+,r0"
9630   [(set_attr "length" "4")])
9632 ;; Integer vector moves
9634 (define_expand "movv8qi"
9635   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9636         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9637   "TARGET_SHMEDIA"
9638   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9640 (define_insn "movv8qi_i"
9641   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9642         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9643   "TARGET_SHMEDIA
9644    && (register_operand (operands[0], V8QImode)
9645        || sh_register_operand (operands[1], V8QImode))"
9646   "@
9647         add     %1, r63, %0
9648         movi    %1, %0
9649         #
9650         ld%M1.q %m1, %0
9651         st%M0.q %m0, %N1"
9652   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9653    (set_attr "length" "4,4,16,4,4")])
9655 (define_split
9656   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9657         (subreg:V8QI (const_int 0) 0))]
9658   "TARGET_SHMEDIA"
9659   [(set (match_dup 0)
9660         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9661                             (const_int 0) (const_int 0) (const_int 0)
9662                             (const_int 0) (const_int 0)]))])
9664 (define_split
9665   [(set (match_operand 0 "arith_reg_dest" "")
9666         (match_operand 1 "sh_rep_vec" ""))]
9667   "TARGET_SHMEDIA && reload_completed
9668    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9669    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9670    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9671    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9672        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9673    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9674        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9675   [(set (match_dup 0) (match_dup 1))
9676    (match_dup 2)]
9677   "
9679   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9680   rtx elt1 = XVECEXP (operands[1], 0, 1);
9682   if (unit_size > 2)
9683     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9684   else
9685     {
9686       if (unit_size < 2)
9687         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9688       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9689     }
9690   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9691   operands[1] = XVECEXP (operands[1], 0, 0);
9692   if (unit_size < 2)
9693     {
9694       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9695         operands[1]
9696           = GEN_INT (TARGET_LITTLE_ENDIAN
9697                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9698                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9699       else
9700         {
9701           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9702           operands[1]
9703             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9704         }
9705     }
9708 (define_split
9709   [(set (match_operand 0 "arith_reg_dest" "")
9710         (match_operand 1 "sh_const_vec" ""))]
9711   "TARGET_SHMEDIA && reload_completed
9712    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9713    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9714    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9715   [(set (match_dup 0) (match_dup 1))]
9716   "
9718   rtx v = operands[1];
9719   enum machine_mode new_mode
9720     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9722   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9723   operands[1]
9724     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9727 (define_expand "movv2hi"
9728   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9729         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9730   "TARGET_SHMEDIA"
9731   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9733 (define_insn "movv2hi_i"
9734   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9735         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9736   "TARGET_SHMEDIA
9737    && (register_operand (operands[0], V2HImode)
9738        || sh_register_operand (operands[1], V2HImode))"
9739   "@
9740         addz.l  %1, r63, %0
9741         movi    %1, %0
9742         #
9743         ld%M1.l %m1, %0
9744         st%M0.l %m0, %N1"
9745   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9746    (set_attr "length" "4,4,16,4,4")])
9748 (define_expand "movv4hi"
9749   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9750         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9751   "TARGET_SHMEDIA"
9752   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9754 (define_insn "movv4hi_i"
9755   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9756         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9757   "TARGET_SHMEDIA
9758    && (register_operand (operands[0], V4HImode)
9759        || sh_register_operand (operands[1], V4HImode))"
9760   "@
9761         add     %1, r63, %0
9762         movi    %1, %0
9763         #
9764         ld%M1.q %m1, %0
9765         st%M0.q %m0, %N1"
9766   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9767    (set_attr "length" "4,4,16,4,4")])
9769 (define_expand "movv2si"
9770   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9771         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9772   "TARGET_SHMEDIA"
9773   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9775 (define_insn "movv2si_i"
9776   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9777         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9778   "TARGET_SHMEDIA
9779    && (register_operand (operands[0], V2SImode)
9780        || sh_register_operand (operands[1], V2SImode))"
9781   "@
9782         add     %1, r63, %0
9783         #
9784         #
9785         ld%M1.q %m1, %0
9786         st%M0.q %m0, %N1"
9787   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9788    (set_attr "length" "4,4,16,4,4")])
9790 ;; Multimedia Intrinsics
9792 (define_insn "absv2si2"
9793   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9794         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9795   "TARGET_SHMEDIA"
9796   "mabs.l       %1, %0"
9797   [(set_attr "type" "mcmp_media")])
9799 (define_insn "absv4hi2"
9800   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9801         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9802   "TARGET_SHMEDIA"
9803   "mabs.w       %1, %0"
9804   [(set_attr "type" "mcmp_media")])
9806 (define_insn "addv2si3"
9807   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9808         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9809                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9810   "TARGET_SHMEDIA"
9811   "madd.l       %1, %2, %0"
9812   [(set_attr "type" "arith_media")])
9814 (define_insn "addv4hi3"
9815   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9816         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9817                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9818   "TARGET_SHMEDIA"
9819   "madd.w       %1, %2, %0"
9820   [(set_attr "type" "arith_media")])
9822 (define_insn "ssaddv2si3"
9823   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9824         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9825                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9826   "TARGET_SHMEDIA"
9827   "madds.l      %1, %2, %0"
9828   [(set_attr "type" "mcmp_media")])
9830 (define_insn "usaddv8qi3"
9831   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9832         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9833                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9834   "TARGET_SHMEDIA"
9835   "madds.ub     %1, %2, %0"
9836   [(set_attr "type" "mcmp_media")])
9838 (define_insn "ssaddv4hi3"
9839   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9840         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9841                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9842   "TARGET_SHMEDIA"
9843   "madds.w      %1, %2, %0"
9844   [(set_attr "type" "mcmp_media")])
9846 (define_insn "negcmpeqv8qi"
9847   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9848         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9849                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9850   "TARGET_SHMEDIA"
9851   "mcmpeq.b     %N1, %N2, %0"
9852   [(set_attr "type" "mcmp_media")])
9854 (define_insn "negcmpeqv2si"
9855   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9856         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9857                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9858   "TARGET_SHMEDIA"
9859   "mcmpeq.l     %N1, %N2, %0"
9860   [(set_attr "type" "mcmp_media")])
9862 (define_insn "negcmpeqv4hi"
9863   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9864         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9865                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9866   "TARGET_SHMEDIA"
9867   "mcmpeq.w     %N1, %N2, %0"
9868   [(set_attr "type" "mcmp_media")])
9870 (define_insn "negcmpgtuv8qi"
9871   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9872         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9873                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9874   "TARGET_SHMEDIA"
9875   "mcmpgt.ub    %N1, %N2, %0"
9876   [(set_attr "type" "mcmp_media")])
9878 (define_insn "negcmpgtv2si"
9879   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9880         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9881                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9882   "TARGET_SHMEDIA"
9883   "mcmpgt.l     %N1, %N2, %0"
9884   [(set_attr "type" "mcmp_media")])
9886 (define_insn "negcmpgtv4hi"
9887   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9888         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9889                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9890   "TARGET_SHMEDIA"
9891   "mcmpgt.w     %N1, %N2, %0"
9892   [(set_attr "type" "mcmp_media")])
9894 (define_insn "mcmv"
9895   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9896         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9897                         (match_operand:DI 2 "arith_reg_operand" "r"))
9898                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9899                         (not:DI (match_dup 2)))))]
9900   "TARGET_SHMEDIA"
9901   "mcmv %N1, %2, %0"
9902   [(set_attr "type" "arith_media")])
9904 (define_insn "mcnvs_lw"
9905   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9906         (vec_concat:V4HI
9907          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9908          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9909   "TARGET_SHMEDIA"
9910   "mcnvs.lw     %N1, %N2, %0"
9911   [(set_attr "type" "mcmp_media")])
9913 (define_insn "mcnvs_wb"
9914   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9915         (vec_concat:V8QI
9916          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9917          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9918   "TARGET_SHMEDIA"
9919   "mcnvs.wb     %N1, %N2, %0"
9920   [(set_attr "type" "mcmp_media")])
9922 (define_insn "mcnvs_wub"
9923   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9924         (vec_concat:V8QI
9925          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9926          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9927   "TARGET_SHMEDIA"
9928   "mcnvs.wub    %N1, %N2, %0"
9929   [(set_attr "type" "mcmp_media")])
9931 (define_insn "mextr_rl"
9932   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9933         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9934                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9935                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9936                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9937   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9938   "*
9940   static char templ[16];
9942   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9943            (int) INTVAL (operands[3]) >> 3);
9944   return templ;
9946   [(set_attr "type" "arith_media")])
9948 (define_insn "*mextr_lr"
9949   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9950         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9951                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9952                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9953                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9954   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9955   "*
9957   static char templ[16];
9959   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9960            (int) INTVAL (operands[4]) >> 3);
9961   return templ;
9963   [(set_attr "type" "arith_media")])
9965 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9966 ; vector then varies depending on endianness.
9967 (define_expand "mextr1"
9968   [(match_operand:DI 0 "arith_reg_dest" "")
9969    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9970    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9971   "TARGET_SHMEDIA"
9972   "
9974   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9975                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9976   DONE;
9979 (define_expand "mextr2"
9980   [(match_operand:DI 0 "arith_reg_dest" "")
9981    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9982    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9983   "TARGET_SHMEDIA"
9984   "
9986   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9987                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9988   DONE;
9991 (define_expand "mextr3"
9992   [(match_operand:DI 0 "arith_reg_dest" "")
9993    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9994    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9995   "TARGET_SHMEDIA"
9996   "
9998   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9999                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
10000   DONE;
10003 (define_expand "mextr4"
10004   [(match_operand:DI 0 "arith_reg_dest" "")
10005    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10006    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10007   "TARGET_SHMEDIA"
10008   "
10010   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10011                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
10012   DONE;
10015 (define_expand "mextr5"
10016   [(match_operand:DI 0 "arith_reg_dest" "")
10017    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10018    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10019   "TARGET_SHMEDIA"
10020   "
10022   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10023                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
10024   DONE;
10027 (define_expand "mextr6"
10028   [(match_operand:DI 0 "arith_reg_dest" "")
10029    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10030    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10031   "TARGET_SHMEDIA"
10032   "
10034   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10035                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
10036   DONE;
10039 (define_expand "mextr7"
10040   [(match_operand:DI 0 "arith_reg_dest" "")
10041    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10042    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10043   "TARGET_SHMEDIA"
10044   "
10046   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10047                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
10048   DONE;
10051 (define_expand "mmacfx_wl"
10052   [(match_operand:V2SI 0 "arith_reg_dest" "")
10053    (match_operand:V2HI 1 "extend_reg_operand" "")
10054    (match_operand:V2HI 2 "extend_reg_operand" "")
10055    (match_operand:V2SI 3 "arith_reg_operand" "")]
10056   "TARGET_SHMEDIA"
10057   "
10059   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
10060                               operands[1], operands[2]));
10061   DONE;
10064 (define_insn "mmacfx_wl_i"
10065   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10066         (ss_plus:V2SI
10067          (match_operand:V2SI 1 "arith_reg_operand" "0")
10068          (ss_truncate:V2SI
10069           (ashift:V2DI
10070            (sign_extend:V2DI
10071             (mult:V2SI
10072              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10073              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10074            (const_int 1)))))]
10075   "TARGET_SHMEDIA"
10076   "mmacfx.wl    %2, %3, %0"
10077   [(set_attr "type" "mac_media")])
10079 (define_expand "mmacnfx_wl"
10080   [(match_operand:V2SI 0 "arith_reg_dest" "")
10081    (match_operand:V2HI 1 "extend_reg_operand" "")
10082    (match_operand:V2HI 2 "extend_reg_operand" "")
10083    (match_operand:V2SI 3 "arith_reg_operand" "")]
10084   "TARGET_SHMEDIA"
10085   "
10087   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10088                                operands[1], operands[2]));
10089   DONE;
10092 (define_insn "mmacnfx_wl_i"
10093   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10094         (ss_minus:V2SI
10095          (match_operand:V2SI 1 "arith_reg_operand" "0")
10096          (ss_truncate:V2SI
10097           (ashift:V2DI
10098            (sign_extend:V2DI
10099             (mult:V2SI
10100              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10101              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10102            (const_int 1)))))]
10103   "TARGET_SHMEDIA"
10104   "mmacnfx.wl   %2, %3, %0"
10105   [(set_attr "type" "mac_media")])
10107 (define_insn "mulv2si3"
10108   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10109         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10110                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10111   "TARGET_SHMEDIA"
10112   "mmul.l       %1, %2, %0"
10113   [(set_attr "type" "d2mpy_media")])
10115 (define_insn "mulv4hi3"
10116   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10117         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10118                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10119   "TARGET_SHMEDIA"
10120   "mmul.w       %1, %2, %0"
10121   [(set_attr "type" "dmpy_media")])
10123 (define_insn "mmulfx_l"
10124   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10125         (ss_truncate:V2SI
10126          (ashiftrt:V2DI
10127           (mult:V2DI
10128            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10129            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10130           (const_int 31))))]
10131   "TARGET_SHMEDIA"
10132   "mmulfx.l     %1, %2, %0"
10133   [(set_attr "type" "d2mpy_media")])
10135 (define_insn "mmulfx_w"
10136   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10137         (ss_truncate:V4HI
10138          (ashiftrt:V4SI
10139           (mult:V4SI
10140            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10141            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10142           (const_int 15))))]
10143   "TARGET_SHMEDIA"
10144   "mmulfx.w     %1, %2, %0"
10145   [(set_attr "type" "dmpy_media")])
10147 (define_insn "mmulfxrp_w"
10148   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10149         (ss_truncate:V4HI
10150          (ashiftrt:V4SI
10151           (plus:V4SI
10152            (mult:V4SI
10153             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10154             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10155            (const_int 16384))
10156           (const_int 15))))]
10157   "TARGET_SHMEDIA"
10158   "mmulfxrp.w   %1, %2, %0"
10159   [(set_attr "type" "dmpy_media")])
10161 (define_expand "mmulhi_wl"
10162   [(match_operand:V2SI 0 "arith_reg_dest" "")
10163    (match_operand:V4HI 1 "arith_reg_operand" "")
10164    (match_operand:V4HI 2 "arith_reg_operand" "")]
10165   "TARGET_SHMEDIA"
10166   "
10168   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10169              (operands[0], operands[1], operands[2]));
10170   DONE;
10173 (define_expand "mmullo_wl"
10174   [(match_operand:V2SI 0 "arith_reg_dest" "")
10175    (match_operand:V4HI 1 "arith_reg_operand" "")
10176    (match_operand:V4HI 2 "arith_reg_operand" "")]
10177   "TARGET_SHMEDIA"
10178   "
10180   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10181              (operands[0], operands[1], operands[2]));
10182   DONE;
10185 (define_insn "mmul23_wl"
10186   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10187         (vec_select:V2SI
10188          (mult:V4SI
10189           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10190           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10191          (parallel [(const_int 2) (const_int 3)])))]
10192   "TARGET_SHMEDIA"
10193   "* return (TARGET_LITTLE_ENDIAN
10194              ? \"mmulhi.wl      %1, %2, %0\"
10195              : \"mmullo.wl      %1, %2, %0\");"
10196   [(set_attr "type" "dmpy_media")])
10198 (define_insn "mmul01_wl"
10199   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10200         (vec_select:V2SI
10201          (mult:V4SI
10202           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10203           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10204          (parallel [(const_int 0) (const_int 1)])))]
10205   "TARGET_SHMEDIA"
10206   "* return (TARGET_LITTLE_ENDIAN
10207              ? \"mmullo.wl      %1, %2, %0\"
10208              : \"mmulhi.wl      %1, %2, %0\");"
10209   [(set_attr "type" "dmpy_media")])
10211 (define_expand "mmulsum_wq"
10212   [(match_operand:DI 0 "arith_reg_dest" "")
10213    (match_operand:V4HI 1 "arith_reg_operand" "")
10214    (match_operand:V4HI 2 "arith_reg_operand" "")
10215    (match_operand:DI 3 "arith_reg_operand" "")]
10216   "TARGET_SHMEDIA"
10217   "
10219   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10220                                operands[1], operands[2]));
10221   DONE;
10224 (define_insn "mmulsum_wq_i"
10225   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10226         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10227          (plus:DI
10228           (plus:DI
10229            (vec_select:DI
10230             (mult:V4DI
10231              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10232              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10233             (parallel [(const_int 0)]))
10234            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10235                                      (sign_extend:V4DI (match_dup 3)))
10236                           (parallel [(const_int 1)])))
10237           (plus:DI
10238            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10239                                      (sign_extend:V4DI (match_dup 3)))
10240                           (parallel [(const_int 2)]))
10241            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10242                                      (sign_extend:V4DI (match_dup 3)))
10243                           (parallel [(const_int 3)]))))))]
10244   "TARGET_SHMEDIA"
10245   "mmulsum.wq   %2, %3, %0"
10246   [(set_attr "type" "mac_media")])
10248 (define_expand "mperm_w"
10249   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10250    (match_operand:V4HI 1 "arith_reg_operand" "r")
10251    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10252   "TARGET_SHMEDIA"
10253   "
10255   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10256              (operands[0], operands[1], operands[2]));
10257   DONE;
10260 ; This use of vec_select isn't exactly correct according to rtl.texi
10261 ; (because not constant), but it seems a straightforward extension.
10262 (define_insn "mperm_w_little"
10263   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10264         (vec_select:V4HI
10265          (match_operand:V4HI 1 "arith_reg_operand" "r")
10266          (parallel
10267           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10268                             (const_int 2) (const_int 0))
10269            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10270            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10271            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10272   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10273   "mperm.w      %1, %N2, %0"
10274   [(set_attr "type" "arith_media")])
10276 (define_insn "mperm_w_big"
10277   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10278         (vec_select:V4HI
10279          (match_operand:V4HI 1 "arith_reg_operand" "r")
10280          (parallel
10281           [(zero_extract:QI (not:QI (match_operand:QI 2
10282                                      "extend_reg_or_0_operand" "rZ"))
10283                             (const_int 2) (const_int 0))
10284            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10285            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10286            (zero_extract:QI (not:QI (match_dup 2))
10287                             (const_int 2) (const_int 6))])))]
10288   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10289   "mperm.w      %1, %N2, %0"
10290   [(set_attr "type" "arith_media")])
10292 (define_insn "mperm_w0"
10293   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10294         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10295                                           "trunc_hi_operand" "r"))))]
10296   "TARGET_SHMEDIA"
10297   "mperm.w      %1, r63, %0"
10298   [(set_attr "type" "arith_media")])
10300 (define_expand "msad_ubq"
10301   [(match_operand:DI 0 "arith_reg_dest" "")
10302    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10303    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10304    (match_operand:DI 3 "arith_reg_operand" "")]
10305   "TARGET_SHMEDIA"
10306   "
10308   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10309                              operands[1], operands[2]));
10310   DONE;
10313 (define_insn "msad_ubq_i"
10314   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10315         (plus:DI
10316          (plus:DI
10317           (plus:DI
10318            (plus:DI
10319             (match_operand:DI 1 "arith_reg_operand" "0")
10320             (abs:DI (vec_select:DI
10321                      (minus:V8DI
10322                       (zero_extend:V8DI
10323                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10324                       (zero_extend:V8DI
10325                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10326                      (parallel [(const_int 0)]))))
10327            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10328                                               (zero_extend:V8DI (match_dup 3)))
10329                                   (parallel [(const_int 1)]))))
10330           (plus:DI
10331            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10332                                               (zero_extend:V8DI (match_dup 3)))
10333                                   (parallel [(const_int 2)])))
10334            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10335                                               (zero_extend:V8DI (match_dup 3)))
10336                                   (parallel [(const_int 3)])))))
10337          (plus:DI
10338           (plus:DI
10339            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10340                                               (zero_extend:V8DI (match_dup 3)))
10341                                   (parallel [(const_int 4)])))
10342            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10343                                               (zero_extend:V8DI (match_dup 3)))
10344                                   (parallel [(const_int 5)]))))
10345           (plus:DI
10346            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10347                                               (zero_extend:V8DI (match_dup 3)))
10348                                   (parallel [(const_int 6)])))
10349            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10350                                               (zero_extend:V8DI (match_dup 3)))
10351                                   (parallel [(const_int 7)])))))))]
10352   "TARGET_SHMEDIA"
10353   "msad.ubq     %N2, %N3, %0"
10354   [(set_attr "type" "mac_media")])
10356 (define_insn "mshalds_l"
10357   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10358         (ss_truncate:V2SI
10359          (ashift:V2DI
10360           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10361           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10362                   (const_int 31)))))]
10363   "TARGET_SHMEDIA"
10364   "mshalds.l    %1, %2, %0"
10365   [(set_attr "type" "mcmp_media")])
10367 (define_insn "mshalds_w"
10368   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10369         (ss_truncate:V4HI
10370          (ashift:V4SI
10371           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10372           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10373                   (const_int 15)))))]
10374   "TARGET_SHMEDIA"
10375   "mshalds.w    %1, %2, %0"
10376   [(set_attr "type" "mcmp_media")])
10378 (define_insn "ashrv2si3"
10379   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10380         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10381                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10382   "TARGET_SHMEDIA"
10383   "mshard.l     %1, %2, %0"
10384   [(set_attr "type" "arith_media")])
10386 (define_insn "ashrv4hi3"
10387   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10388         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10389                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10390   "TARGET_SHMEDIA"
10391   "mshard.w     %1, %2, %0"
10392   [(set_attr "type" "arith_media")])
10394 (define_insn "mshards_q"
10395   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10396         (ss_truncate:HI
10397          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10398                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10399   "TARGET_SHMEDIA"
10400   "mshards.q    %1, %N2, %0"
10401   [(set_attr "type" "mcmp_media")])
10403 (define_expand "mshfhi_b"
10404   [(match_operand:V8QI 0 "arith_reg_dest" "")
10405    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10406    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10407   "TARGET_SHMEDIA"
10408   "
10410   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10411              (operands[0], operands[1], operands[2]));
10412   DONE;
10415 (define_expand "mshflo_b"
10416   [(match_operand:V8QI 0 "arith_reg_dest" "")
10417    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10418    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10419   "TARGET_SHMEDIA"
10420   "
10422   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10423              (operands[0], operands[1], operands[2]));
10424   DONE;
10427 (define_insn "mshf4_b"
10428   [(set
10429     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10430     (vec_select:V8QI
10431      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10432                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10433      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10434                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10435   "TARGET_SHMEDIA"
10436   "* return (TARGET_LITTLE_ENDIAN
10437              ? \"mshfhi.b       %N1, %N2, %0\"
10438              : \"mshflo.b       %N1, %N2, %0\");"
10439   [(set_attr "type" "arith_media")])
10441 (define_insn "mshf0_b"
10442   [(set
10443     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10444     (vec_select:V8QI
10445      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10446                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10447      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10448                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10449   "TARGET_SHMEDIA"
10450   "* return (TARGET_LITTLE_ENDIAN
10451              ? \"mshflo.b       %N1, %N2, %0\"
10452              : \"mshfhi.b       %N1, %N2, %0\");"
10453   [(set_attr "type" "arith_media")])
10455 (define_expand "mshfhi_l"
10456   [(match_operand:V2SI 0 "arith_reg_dest" "")
10457    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10458    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10459   "TARGET_SHMEDIA"
10460   "
10462   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10463              (operands[0], operands[1], operands[2]));
10464   DONE;
10467 (define_expand "mshflo_l"
10468   [(match_operand:V2SI 0 "arith_reg_dest" "")
10469    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10470    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10471   "TARGET_SHMEDIA"
10472   "
10474   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10475              (operands[0], operands[1], operands[2]));
10476   DONE;
10479 (define_insn "mshf4_l"
10480   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10481         (vec_select:V2SI
10482          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10483                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10484          (parallel [(const_int 1) (const_int 3)])))]
10485   "TARGET_SHMEDIA"
10486   "* return (TARGET_LITTLE_ENDIAN
10487              ? \"mshfhi.l       %N1, %N2, %0\"
10488              : \"mshflo.l       %N1, %N2, %0\");"
10489   [(set_attr "type" "arith_media")])
10491 (define_insn "mshf0_l"
10492   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10493         (vec_select:V2SI
10494          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10495                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10496          (parallel [(const_int 0) (const_int 2)])))]
10497   "TARGET_SHMEDIA"
10498   "* return (TARGET_LITTLE_ENDIAN
10499              ? \"mshflo.l       %N1, %N2, %0\"
10500              : \"mshfhi.l       %N1, %N2, %0\");"
10501   [(set_attr "type" "arith_media")])
10503 (define_expand "mshfhi_w"
10504   [(match_operand:V4HI 0 "arith_reg_dest" "")
10505    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10506    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10507   "TARGET_SHMEDIA"
10508   "
10510   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10511              (operands[0], operands[1], operands[2]));
10512   DONE;
10515 (define_expand "mshflo_w"
10516   [(match_operand:V4HI 0 "arith_reg_dest" "")
10517    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10518    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10519   "TARGET_SHMEDIA"
10520   "
10522   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10523              (operands[0], operands[1], operands[2]));
10524   DONE;
10527 (define_insn "mshf4_w"
10528   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10529         (vec_select:V4HI
10530          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10531                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10532          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10533   "TARGET_SHMEDIA"
10534   "* return (TARGET_LITTLE_ENDIAN
10535              ? \"mshfhi.w       %N1, %N2, %0\"
10536              : \"mshflo.w       %N1, %N2, %0\");"
10537   [(set_attr "type" "arith_media")])
10539 (define_insn "mshf0_w"
10540   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10541         (vec_select:V4HI
10542          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10543                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10544          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10545   "TARGET_SHMEDIA"
10546   "* return (TARGET_LITTLE_ENDIAN
10547              ? \"mshflo.w       %N1, %N2, %0\"
10548              : \"mshfhi.w       %N1, %N2, %0\");"
10549   [(set_attr "type" "arith_media")])
10551 (define_insn "mshflo_w_x"
10552   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10553         (vec_select:V4HI
10554          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10555                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10556          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10557   "TARGET_SHMEDIA"
10558   "mshflo.w     %N1, %N2, %0"
10559   [(set_attr "type" "arith_media")])
10561 /* These are useful to expand ANDs and as combiner patterns.  */
10562 (define_insn_and_split "mshfhi_l_di"
10563   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10564         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10565                              (const_int 32))
10566                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10567                         (const_int -4294967296))))]
10568   "TARGET_SHMEDIA"
10569   "@
10570         mshfhi.l        %N1, %N2, %0
10571         #"
10572   "TARGET_SHMEDIA && reload_completed
10573    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10574   [(set (match_dup 3) (match_dup 4))
10575    (set (match_dup 5) (match_dup 6))]
10576   "
10578   operands[3] = gen_lowpart (SImode, operands[0]);
10579   operands[4] = gen_highpart (SImode, operands[1]);
10580   operands[5] = gen_highpart (SImode, operands[0]);
10581   operands[6] = gen_highpart (SImode, operands[2]);
10583   [(set_attr "type" "arith_media")])
10585 (define_insn "*mshfhi_l_di_rev"
10586   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10587         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10588                         (const_int -4294967296))
10589                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10590                              (const_int 32))))]
10591   "TARGET_SHMEDIA"
10592   "mshfhi.l     %N2, %N1, %0"
10593   [(set_attr "type" "arith_media")])
10595 (define_split
10596   [(set (match_operand:DI 0 "arith_reg_dest" "")
10597         (ior:DI (zero_extend:DI (match_operand:SI 1
10598                                               "extend_reg_or_0_operand" ""))
10599                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10600                         (const_int -4294967296))))
10601    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10602   "TARGET_SHMEDIA"
10603   [(const_int 0)]
10604   "
10606   emit_insn (gen_ashldi3_media (operands[3],
10607                                 simplify_gen_subreg (DImode, operands[1],
10608                                                      SImode, 0),
10609                                 GEN_INT (32)));
10610   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10611   DONE;
10614 (define_insn "mshflo_l_di"
10615   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10616         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10617                         (const_int 4294967295))
10618                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10619                            (const_int 32))))]
10621   "TARGET_SHMEDIA"
10622   "mshflo.l     %N1, %N2, %0"
10623   [(set_attr "type" "arith_media")])
10625 (define_insn "*mshflo_l_di_rev"
10626   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10627         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10628                            (const_int 32))
10629                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10630                         (const_int 4294967295))))]
10632   "TARGET_SHMEDIA"
10633   "mshflo.l     %N2, %N1, %0"
10634   [(set_attr "type" "arith_media")])
10636 ;; Combiner pattern for trampoline initialization.
10637 (define_insn_and_split "*double_shori"
10638   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10639         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10640                            (const_int 32))
10641                 (match_operand:DI 2 "const_int_operand" "n")))]
10642   "TARGET_SHMEDIA
10643    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10644   "#"
10645   "rtx_equal_p (operands[0], operands[1])"
10646   [(const_int 0)]
10647   "
10649   HOST_WIDE_INT v = INTVAL (operands[2]);
10651   emit_insn (gen_shori_media (operands[0], operands[0],
10652              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10653   emit_insn (gen_shori_media (operands[0], operands[0],
10654                               gen_int_mode (v, HImode)));
10655   DONE;
10659 (define_insn "*mshflo_l_di_x"
10660   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10661         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10662                                  "rZ"))
10663                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10664                            (const_int 32))))]
10666   "TARGET_SHMEDIA"
10667   "mshflo.l     %N1, %N2, %0"
10668   [(set_attr "type" "arith_media")])
10670 (define_insn_and_split "concat_v2sf"
10671   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10672 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10673         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10674                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10676   "TARGET_SHMEDIA"
10677   "@
10678         mshflo.l        %N1, %N2, %0
10679         #
10680         #"
10681   "TARGET_SHMEDIA && reload_completed
10682    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10683   [(set (match_dup 3) (match_dup 1))
10684    (set (match_dup 4) (match_dup 2))]
10685   "
10687   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10688   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10690   [(set_attr "type" "arith_media")])
10692 (define_insn "*mshflo_l_di_x_rev"
10693   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10694         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10695                            (const_int 32))
10696                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10698   "TARGET_SHMEDIA"
10699   "mshflo.l     %N2, %N1, %0"
10700   [(set_attr "type" "arith_media")])
10702 (define_insn "ashlv2si3"
10703   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10704         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10705                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10706   "TARGET_SHMEDIA"
10707   "mshlld.l     %1, %2, %0"
10708   [(set_attr "type" "arith_media")])
10710 (define_insn "ashlv4hi3"
10711   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10712         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10713                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10714   "TARGET_SHMEDIA"
10715   "mshlld.w     %1, %2, %0"
10716   [(set_attr "type" "arith_media")])
10718 (define_insn "lshrv2si3"
10719   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10720         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10721                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10722   "TARGET_SHMEDIA"
10723   "mshlrd.l     %1, %2, %0"
10724   [(set_attr "type" "arith_media")])
10726 (define_insn "lshrv4hi3"
10727   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10728         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10729                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10730   "TARGET_SHMEDIA"
10731   "mshlrd.w     %1, %2, %0"
10732   [(set_attr "type" "arith_media")])
10734 (define_insn "subv2si3"
10735   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10736         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10737                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10738   "TARGET_SHMEDIA"
10739   "msub.l       %N1, %2, %0"
10740   [(set_attr "type" "arith_media")])
10742 (define_insn "subv4hi3"
10743   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10744         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10745                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10746   "TARGET_SHMEDIA"
10747   "msub.w       %N1, %2, %0"
10748   [(set_attr "type" "arith_media")])
10750 (define_insn "sssubv2si3"
10751   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10752         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10753                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10754   "TARGET_SHMEDIA"
10755   "msubs.l      %N1, %2, %0"
10756   [(set_attr "type" "mcmp_media")])
10758 (define_insn "ussubv8qi3"
10759   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10760         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10761                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10762   "TARGET_SHMEDIA"
10763   "msubs.ub     %1, %2, %0"
10764   [(set_attr "type" "mcmp_media")])
10766 (define_insn "sssubv4hi3"
10767   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10768         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10769                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10770   "TARGET_SHMEDIA"
10771   "msubs.w      %N1, %2, %0"
10772   [(set_attr "type" "mcmp_media")])
10774 ;; Floating Point Intrinsics
10776 (define_insn "fcosa_s"
10777   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10778         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10779                    UNSPEC_FCOSA))]
10780   "TARGET_SHMEDIA"
10781   "fcosa.s      %1, %0"
10782   [(set_attr "type" "atrans_media")])
10784 (define_insn "fsina_s"
10785   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10786         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10787                    UNSPEC_FSINA))]
10788   "TARGET_SHMEDIA"
10789   "fsina.s      %1, %0"
10790   [(set_attr "type" "atrans_media")])
10792 (define_insn "fipr"
10793   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10794         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10795                                                     "fp_arith_reg_operand" "f")
10796                                                    (match_operand:V4SF 2
10797                                                     "fp_arith_reg_operand" "f"))
10798                                          (parallel [(const_int 0)]))
10799                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10800                                          (parallel [(const_int 1)])))
10801                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10802                                          (parallel [(const_int 2)]))
10803                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10804                                          (parallel [(const_int 3)])))))]
10805   "TARGET_SHMEDIA"
10806   "fipr.s       %1, %2, %0"
10807   [(set_attr "type" "fparith_media")])
10809 (define_insn "fsrra_s"
10810   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10811         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10812                    UNSPEC_FSRRA))]
10813   "TARGET_SHMEDIA"
10814   "fsrra.s      %1, %0"
10815   [(set_attr "type" "atrans_media")])
10817 (define_insn "ftrv"
10818   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10819         (plus:V4SF
10820          (plus:V4SF
10821           (mult:V4SF
10822            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10823                             (parallel [(const_int 0) (const_int 5)
10824                                        (const_int 10) (const_int 15)]))
10825            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10826           (mult:V4SF
10827            (vec_select:V4SF (match_dup 1)
10828                             (parallel [(const_int 4) (const_int 9)
10829                                        (const_int 14) (const_int 3)]))
10830            (vec_select:V4SF (match_dup 2)
10831                             (parallel [(const_int 1) (const_int 2)
10832                                        (const_int 3) (const_int 0)]))))
10833          (plus:V4SF
10834           (mult:V4SF
10835            (vec_select:V4SF (match_dup 1)
10836                             (parallel [(const_int 8) (const_int 13)
10837                                        (const_int 2) (const_int 7)]))
10838            (vec_select:V4SF (match_dup 2)
10839                             (parallel [(const_int 2) (const_int 3)
10840                                        (const_int 0) (const_int 1)])))
10841           (mult:V4SF
10842            (vec_select:V4SF (match_dup 1)
10843                             (parallel [(const_int 12) (const_int 1)
10844                                        (const_int 6) (const_int 11)]))
10845            (vec_select:V4SF (match_dup 2)
10846                             (parallel [(const_int 3) (const_int 0)
10847                                        (const_int 1) (const_int 2)]))))))]
10848   "TARGET_SHMEDIA"
10849   "ftrv.s %1, %2, %0"
10850   [(set_attr "type" "fparith_media")])
10852 (define_insn "nsb"
10853   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10854         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10855                    UNSPEC_NSB))]
10856   "TARGET_SHMEDIA"
10857   "nsb  %1, %0"
10858   [(set_attr "type" "arith_media")])
10860 (define_insn "nsbsi"
10861   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10862         (zero_extend:SI
10863          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10864                     UNSPEC_NSB)))]
10865   "TARGET_SHMEDIA"
10866   "nsb  %1, %0"
10867   [(set_attr "type" "arith_media")])
10869 (define_insn "nsbdi"
10870   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10871         (zero_extend:DI
10872          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10873                     UNSPEC_NSB)))]
10874   "TARGET_SHMEDIA"
10875   "nsb  %1, %0"
10876   [(set_attr "type" "arith_media")])
10878 (define_expand "ffsdi2"
10879   [(set (match_operand:DI 0 "arith_reg_dest" "")
10880         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10881   "TARGET_SHMEDIA"
10882   "
10884   rtx scratch = gen_reg_rtx (DImode);
10885   rtx last;
10887   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10888   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10889   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10890   emit_insn (gen_nsbdi (scratch, scratch));
10891   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10892   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10893   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10894   REG_NOTES (last)
10895     = gen_rtx_EXPR_LIST (REG_EQUAL,
10896                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10897   DONE;
10900 (define_expand "ffssi2"
10901   [(set (match_operand:SI 0 "arith_reg_dest" "")
10902         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10903   "TARGET_SHMEDIA"
10904   "
10906   rtx scratch = gen_reg_rtx (SImode);
10907   rtx discratch = gen_reg_rtx (DImode);
10908   rtx last;
10910   emit_insn (gen_adddi3 (discratch,
10911                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10912                          constm1_rtx));
10913   emit_insn (gen_andcdi3 (discratch,
10914                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10915                           discratch));
10916   emit_insn (gen_nsbsi (scratch, discratch));
10917   last = emit_insn (gen_subsi3 (operands[0],
10918                                 force_reg (SImode, GEN_INT (63)), scratch));
10919   REG_NOTES (last)
10920     = gen_rtx_EXPR_LIST (REG_EQUAL,
10921                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10922   DONE;
10925 (define_insn "byterev"
10926   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10927         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10928                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10929                                     (const_int 4) (const_int 3) (const_int 2)
10930                                     (const_int 1) (const_int 0)])))]
10931   "TARGET_SHMEDIA"
10932   "byterev      %1, %0"
10933   [(set_attr "type" "arith_media")])
10935 (define_insn "prefetch"
10936   [(prefetch (match_operand:QI 0 "address_operand" "p")
10937              (match_operand:SI 1 "const_int_operand" "n")
10938              (match_operand:SI 2 "const_int_operand" "n"))]
10939   "TARGET_SHMEDIA || TARGET_HARD_SH4"
10940   "*
10942   if (TARGET_HARD_SH4)
10943     return \"pref @%0\";
10944   operands[0] = gen_rtx_MEM (QImode, operands[0]);
10945   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
10946   return \"\";
10948   [(set_attr "type" "other")])