Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / config / sh / sh.md
blobe367d602cc9fe4c2ef6e158d996d7aa15a07fc16
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004, 2005 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
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                 (cond [(eq_attr "braf_branch_p" "yes")
411                        (const_int 6)
412                        (eq (symbol_ref "flag_pic") (const_int 0))
413                        (const_int 10)
414                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
415                        (const_int 10)] (const_int 18))
416                 (eq_attr "braf_branch_p" "yes")
417                 (const_int 10)
418 ;; ??? using pc is not computed transitively.
419                 (ne (match_dup 0) (match_dup 0))
420                 (const_int 12)
421                 (ne (symbol_ref ("flag_pic")) (const_int 0))
422                 (const_int 22)
423                 ] (const_int 14))
424          (eq_attr "type" "pt_media")
425          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
426                        (const_int 20) (const_int 12))
427          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
428                          (const_int 4)
429                          (const_int 2))))
431 ;; DFA descriptions for the pipelines
433 (include "sh1.md")
434 (include "shmedia.md")
435 (include "sh4.md")
437 ;; Definitions for filling delay slots
439 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
441 ;; ??? This should be (nil) instead of (const_int 0)
442 (define_attr "hit_stack" "yes,no"
443         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
444                    (const_int 0))
445                (const_string "no")]
446               (const_string "yes")))
448 (define_attr "interrupt_function" "no,yes"
449   (const (symbol_ref "current_function_interrupt")))
451 (define_attr "in_delay_slot" "yes,no"
452   (cond [(eq_attr "type" "cbranch") (const_string "no")
453          (eq_attr "type" "pcload,pcload_si") (const_string "no")
454          (eq_attr "needs_delay_slot" "yes") (const_string "no")
455          (eq_attr "length" "2") (const_string "yes")
456          ] (const_string "no")))
458 (define_attr "cond_delay_slot" "yes,no"
459   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
460          ] (const_string "no")))
462 (define_attr "is_sfunc" ""
463   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
465 (define_attr "is_mac_media" ""
466   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
468 (define_attr "branch_zero" "yes,no"
469   (cond [(eq_attr "type" "!cbranch") (const_string "no")
470          (ne (symbol_ref "(next_active_insn (insn)\
471                            == (prev_active_insn\
472                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
473                           && get_attr_length (next_active_insn (insn)) == 2")
474              (const_int 0))
475          (const_string "yes")]
476         (const_string "no")))
478 ;; SH4 Double-precision computation with double-precision result -
479 ;; the two halves are ready at different times.
480 (define_attr "dfp_comp" "yes,no"
481   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
482         (const_string "no")))
484 ;; Insns for which the latency of a preceding fp insn is decreased by one.
485 (define_attr "late_fp_use" "yes,no" (const_string "no"))
486 ;; And feeding insns for which this relevant.
487 (define_attr "any_fp_comp" "yes,no"
488   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
489          (const_string "yes")]
490         (const_string "no")))
492 (define_attr "any_int_load" "yes,no"
493   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
494          (const_string "yes")]
495         (const_string "no")))
497 (define_delay
498   (eq_attr "needs_delay_slot" "yes")
499   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
501 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
502 ;; and thus we can't put a pop instruction in its delay slot.
503 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
504 ;; instruction can go in the delay slot.
506 ;; Since a normal return (rts) implicitly uses the PR register,
507 ;; we can't allow PR register loads in an rts delay slot.
509 (define_delay
510   (eq_attr "type" "return")
511   [(and (eq_attr "in_delay_slot" "yes")
512         (ior (and (eq_attr "interrupt_function" "no")
513                   (eq_attr "type" "!pload,prset"))
514              (and (eq_attr "interrupt_function" "yes")
515                   (ior
516                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
517                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
519 ;; Since a call implicitly uses the PR register, we can't allow
520 ;; a PR register store in a jsr delay slot.
522 (define_delay
523   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
524   [(and (eq_attr "in_delay_slot" "yes")
525         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
527 ;; Say that we have annulled true branches, since this gives smaller and
528 ;; faster code when branches are predicted as not taken.
530 ;; ??? The non-annulled condition should really be "in_delay_slot",
531 ;; but insns that can be filled in non-annulled get priority over insns
532 ;; that can only be filled in anulled.
534 (define_delay
535   (and (eq_attr "type" "cbranch")
536        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
537   ;; SH2e has a hardware bug that pretty much prohibits the use of
538   ;; annuled delay slots.
539   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
540                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
542 ;; -------------------------------------------------------------------------
543 ;; SImode signed integer comparisons
544 ;; -------------------------------------------------------------------------
546 (define_insn ""
547   [(set (reg:SI T_REG)
548         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
549                        (match_operand:SI 1 "arith_operand" "K08,r"))
550                (const_int 0)))]
551   "TARGET_SH1"
552   "tst  %1,%0"
553   [(set_attr "type" "mt_group")])
555 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
556 ;; That would still allow reload to create cmpi instructions, but would
557 ;; perhaps allow forcing the constant into a register when that is better.
558 ;; Probably should use r0 for mem/imm compares, but force constant into a
559 ;; register for pseudo/imm compares.
561 (define_insn "cmpeqsi_t"
562   [(set (reg:SI T_REG)
563         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
564                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
565   "TARGET_SH1"
566   "@
567         tst     %0,%0
568         cmp/eq  %1,%0
569         cmp/eq  %1,%0"
570    [(set_attr "type" "mt_group")])
572 (define_insn "cmpgtsi_t"
573   [(set (reg:SI T_REG)
574         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
575                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
576   "TARGET_SH1"
577   "@
578         cmp/gt  %1,%0
579         cmp/pl  %0"
580    [(set_attr "type" "mt_group")])
582 (define_insn "cmpgesi_t"
583   [(set (reg:SI T_REG)
584         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
585                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
586   "TARGET_SH1"
587   "@
588         cmp/ge  %1,%0
589         cmp/pz  %0"
590    [(set_attr "type" "mt_group")])
592 ;; -------------------------------------------------------------------------
593 ;; SImode unsigned integer comparisons
594 ;; -------------------------------------------------------------------------
596 (define_insn "cmpgeusi_t"
597   [(set (reg:SI T_REG)
598         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
599                 (match_operand:SI 1 "arith_reg_operand" "r")))]
600   "TARGET_SH1"
601   "cmp/hs       %1,%0"
602    [(set_attr "type" "mt_group")])
604 (define_insn "cmpgtusi_t"
605   [(set (reg:SI T_REG)
606         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
607                 (match_operand:SI 1 "arith_reg_operand" "r")))]
608   "TARGET_SH1"
609   "cmp/hi       %1,%0"
610    [(set_attr "type" "mt_group")])
612 ;; We save the compare operands in the cmpxx patterns and use them when
613 ;; we generate the branch.
615 (define_expand "cmpsi"
616   [(set (reg:SI T_REG)
617         (compare (match_operand:SI 0 "cmpsi_operand" "")
618                  (match_operand:SI 1 "arith_operand" "")))]
619   "TARGET_SH1"
620   "
622   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
623       && GET_CODE (operands[1]) != CONST_INT)
624     operands[0] = copy_to_mode_reg (SImode, operands[0]);
625   sh_compare_op0 = operands[0];
626   sh_compare_op1 = operands[1];
627   DONE;
630 ;; -------------------------------------------------------------------------
631 ;; DImode signed integer comparisons
632 ;; -------------------------------------------------------------------------
634 ;; ??? Could get better scheduling by splitting the initial test from the
635 ;; rest of the insn after reload.  However, the gain would hardly justify
636 ;; the sh.md size increase necessary to do that.
638 (define_insn ""
639   [(set (reg:SI T_REG)
640         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
641                        (match_operand:DI 1 "arith_operand" "r"))
642                (const_int 0)))]
643   "TARGET_SH1"
644   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
645                                  insn, operands);"
646   [(set_attr "length" "6")
647    (set_attr "type" "arith3b")])
649 (define_insn "cmpeqdi_t"
650   [(set (reg:SI T_REG)
651         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
652                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
653   "TARGET_SH1"
654   "@
655         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
656         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
657   [(set_attr "length" "6")
658    (set_attr "type" "arith3b")])
660 (define_split
661   [(set (reg:SI T_REG)
662         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
663                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
664 ;; If we applied this split when not optimizing, it would only be
665 ;; applied during the machine-dependent reorg, when no new basic blocks
666 ;; may be created.
667   "TARGET_SH1 && reload_completed && optimize"
668   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
669    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
670                            (label_ref (match_dup 6))
671                            (pc)))
672    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
673    (match_dup 6)]
674   "
676   operands[2]
677     = gen_rtx_REG (SImode,
678                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
679   operands[3]
680     = (operands[1] == const0_rtx
681        ? const0_rtx
682        : gen_rtx_REG (SImode,
683                       true_regnum (operands[1])
684                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
685   operands[4] = gen_lowpart (SImode, operands[0]);
686   operands[5] = gen_lowpart (SImode, operands[1]);
687   operands[6] = gen_label_rtx ();
690 (define_insn "cmpgtdi_t"
691   [(set (reg:SI T_REG)
692         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
693                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
694   "TARGET_SH2"
695   "@
696         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
697         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
698   [(set_attr "length" "8")
699    (set_attr "type" "arith3")])
701 (define_insn "cmpgedi_t"
702   [(set (reg:SI T_REG)
703         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
704                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
705   "TARGET_SH2"
706   "@
707         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
708         cmp/pz\\t%S0"
709   [(set_attr "length" "8,2")
710    (set_attr "type" "arith3,mt_group")])
712 ;; -------------------------------------------------------------------------
713 ;; DImode unsigned integer comparisons
714 ;; -------------------------------------------------------------------------
716 (define_insn "cmpgeudi_t"
717   [(set (reg:SI T_REG)
718         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
719                 (match_operand:DI 1 "arith_reg_operand" "r")))]
720   "TARGET_SH2"
721   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
722   [(set_attr "length" "8")
723    (set_attr "type" "arith3")])
725 (define_insn "cmpgtudi_t"
726   [(set (reg:SI T_REG)
727         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
728                 (match_operand:DI 1 "arith_reg_operand" "r")))]
729   "TARGET_SH2"
730   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
731   [(set_attr "length" "8")
732    (set_attr "type" "arith3")])
734 (define_insn "cmpeqdi_media"
735   [(set (match_operand:DI 0 "register_operand" "=r")
736         (eq:DI (match_operand:DI 1 "register_operand" "%r")
737                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
738   "TARGET_SHMEDIA"
739   "cmpeq        %1, %N2, %0"
740   [(set_attr "type" "cmp_media")])
742 (define_insn "cmpgtdi_media"
743   [(set (match_operand:DI 0 "register_operand" "=r")
744         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
745                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
746   "TARGET_SHMEDIA"
747   "cmpgt        %N1, %N2, %0"
748   [(set_attr "type" "cmp_media")])
750 (define_insn "cmpgtudi_media"
751   [(set (match_operand:DI 0 "register_operand" "=r")
752         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
753                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
754   "TARGET_SHMEDIA"
755   "cmpgtu       %N1, %N2, %0"
756   [(set_attr "type" "cmp_media")])
758 ;; We save the compare operands in the cmpxx patterns and use them when
759 ;; we generate the branch.
761 (define_expand "cmpdi"
762   [(set (reg:SI T_REG)
763         (compare (match_operand:DI 0 "arith_operand" "")
764                  (match_operand:DI 1 "arith_operand" "")))]
765   "TARGET_SH2 || TARGET_SHMEDIA"
766   "
768   sh_compare_op0 = operands[0];
769   sh_compare_op1 = operands[1];
770   DONE;
772 ;; -------------------------------------------------------------------------
773 ;; Conditional move instructions
774 ;; -------------------------------------------------------------------------
776 ;; The insn names may seem reversed, but note that cmveq performs the move
777 ;; if op1 == 0, and cmvne does it if op1 != 0.
779 (define_insn "movdicc_false"
780   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
781         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
782                              (const_int 0))
783          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
784          (match_operand:DI 3 "arith_reg_operand" "0")))]
785   "TARGET_SHMEDIA"
786   "cmveq        %1, %N2, %0"
787   [(set_attr "type" "arith_media")])
789 (define_insn "movdicc_true"
790   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
791         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
792                              (const_int 0))
793          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
794          (match_operand:DI 3 "arith_reg_operand" "0")))]
795   "TARGET_SHMEDIA"
796   "cmvne        %1, %N2, %0"
797   [(set_attr "type" "arith_media")])
799 (define_expand "movdicc"
800   [(set (match_operand:DI 0 "register_operand" "")
801         (if_then_else:DI (match_operand 1 "comparison_operator" "")
802                          (match_operand:DI 2 "register_operand" "")
803                          (match_operand:DI 3 "register_operand" "")))]
804   "TARGET_SHMEDIA"
805   "
807   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
808       && GET_MODE (sh_compare_op0) == DImode
809       && sh_compare_op1 == const0_rtx)
810     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
811                                   sh_compare_op0, sh_compare_op1);
812   else
813     {
814       rtx tmp;
816       if (no_new_pseudos)
817         FAIL;
819       tmp = gen_reg_rtx (DImode);
821       switch (GET_CODE (operands[1]))
822         {
823         case EQ:
824           emit_insn (gen_seq (tmp));
825           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
826           break;
828         case NE:
829           emit_insn (gen_seq (tmp));
830           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
831           break;
833         case GT:
834           emit_insn (gen_sgt (tmp));
835           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
836           break;
838         case LT:
839           emit_insn (gen_slt (tmp));
840           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
841           break;
843         case GE:
844           emit_insn (gen_slt (tmp));
845           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
846           break;
848         case LE:
849           emit_insn (gen_sgt (tmp));
850           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
851           break;
853         case GTU:
854           emit_insn (gen_sgtu (tmp));
855           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
856           break;
858         case LTU:
859           emit_insn (gen_sltu (tmp));
860           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
861           break;
863         case GEU:
864           emit_insn (gen_sltu (tmp));
865           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
866           break;
868         case LEU:
869           emit_insn (gen_sgtu (tmp));
870           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
871           break;
873         case UNORDERED:
874           emit_insn (gen_sunordered (tmp));
875           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
876           break;
878         case ORDERED:
879           emit_insn (gen_sunordered (tmp));
880           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
881           break;
883         case UNEQ:
884         case UNGE:
885         case UNGT:
886         case UNLE:
887         case UNLT:
888         case LTGT:
889           FAIL;
891         default:
892           abort ();
893         }
894     }
897 ;; -------------------------------------------------------------------------
898 ;; Addition instructions
899 ;; -------------------------------------------------------------------------
901 (define_expand "adddi3"
902   [(set (match_operand:DI 0 "arith_reg_operand" "")
903         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
904                  (match_operand:DI 2 "arith_operand" "")))]
905   ""
906   "
908   if (TARGET_SH1)
909     {
910       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
911         FAIL;
912       operands[2] = force_reg (DImode, operands[2]);
913       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
914       DONE;
915     }
918 (define_insn "*adddi3_media"
919   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
920         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
921                  (match_operand:DI 2 "arith_operand" "r,I10")))]
922   "TARGET_SHMEDIA"
923   "@
924         add     %1, %2, %0
925         addi    %1, %2, %0"
926   [(set_attr "type" "arith_media")])
928 (define_insn "adddi3z_media"
929   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
930         (zero_extend:DI
931          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
932                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
933   "TARGET_SHMEDIA"
934   "addz.l       %1, %N2, %0"
935   [(set_attr "type" "arith_media")])
937 (define_insn "adddi3_compact"
938   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
939         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
940                  (match_operand:DI 2 "arith_reg_operand" "r")))
941    (clobber (reg:SI T_REG))]
942   "TARGET_SH1"
943   "#"
944   [(set_attr "length" "6")])
946 (define_split
947   [(set (match_operand:DI 0 "arith_reg_operand" "")
948         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
949                  (match_operand:DI 2 "arith_reg_operand" "")))
950    (clobber (reg:SI T_REG))]
951   "TARGET_SH1 && reload_completed"
952   [(const_int 0)]
953   "
955   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
956   high0 = gen_rtx_REG (SImode,
957                        true_regnum (operands[0])
958                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
959   high2 = gen_rtx_REG (SImode,
960                        true_regnum (operands[2])
961                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
962   emit_insn (gen_clrt ());
963   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
964   emit_insn (gen_addc1 (high0, high0, high2));
965   DONE;
968 (define_insn "addc"
969   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
970         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
971                           (match_operand:SI 2 "arith_reg_operand" "r"))
972                  (reg:SI T_REG)))
973    (set (reg:SI T_REG)
974         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
975   "TARGET_SH1"
976   "addc %2,%0"
977   [(set_attr "type" "arith")])
979 (define_insn "addc1"
980   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
981         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
982                           (match_operand:SI 2 "arith_reg_operand" "r"))
983                  (reg:SI T_REG)))
984    (clobber (reg:SI T_REG))]
985   "TARGET_SH1"
986   "addc %2,%0"
987   [(set_attr "type" "arith")])
989 (define_expand "addsi3"
990   [(set (match_operand:SI 0 "arith_reg_operand" "")
991         (plus:SI (match_operand:SI 1 "arith_operand" "")
992                  (match_operand:SI 2 "arith_operand" "")))]
993   ""
994   "
996   if (TARGET_SHMEDIA)
997     operands[1] = force_reg (SImode, operands[1]);
1000 (define_insn "addsi3_media"
1001   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1002         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1003                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1004   "TARGET_SHMEDIA"
1005   "@
1006         add.l   %1, %2, %0
1007         addi.l  %1, %2, %0"
1008   [(set_attr "type" "arith_media")])
1010 (define_insn "*addsi3_compact"
1011   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1012         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1013                  (match_operand:SI 2 "arith_operand" "rI08")))]
1014   "TARGET_SH1"
1015   "add  %2,%0"
1016   [(set_attr "type" "arith")])
1018 ;; -------------------------------------------------------------------------
1019 ;; Subtraction instructions
1020 ;; -------------------------------------------------------------------------
1022 (define_expand "subdi3"
1023   [(set (match_operand:DI 0 "arith_reg_operand" "")
1024         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1025                   (match_operand:DI 2 "arith_reg_operand" "")))]
1026   ""
1027   "
1029   if (TARGET_SH1)
1030     {
1031       operands[1] = force_reg (DImode, operands[1]);
1032       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1033       DONE;
1034     }
1037 (define_insn "*subdi3_media"
1038   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1039         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1040                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1041   "TARGET_SHMEDIA"
1042   "sub  %N1, %2, %0"
1043   [(set_attr "type" "arith_media")])
1045 (define_insn "subdi3_compact"
1046   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1047         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1048                  (match_operand:DI 2 "arith_reg_operand" "r")))
1049    (clobber (reg:SI T_REG))]
1050   "TARGET_SH1"
1051   "#"
1052   [(set_attr "length" "6")])
1054 (define_split
1055   [(set (match_operand:DI 0 "arith_reg_operand" "")
1056         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1057                   (match_operand:DI 2 "arith_reg_operand" "")))
1058    (clobber (reg:SI T_REG))]
1059   "TARGET_SH1 && reload_completed"
1060   [(const_int 0)]
1061   "
1063   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1064   high0 = gen_rtx_REG (SImode,
1065                        true_regnum (operands[0])
1066                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1067   high2 = gen_rtx_REG (SImode,
1068                        true_regnum (operands[2])
1069                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1070   emit_insn (gen_clrt ());
1071   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1072   emit_insn (gen_subc1 (high0, high0, high2));
1073   DONE;
1076 (define_insn "subc"
1077   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1078         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1079                             (match_operand:SI 2 "arith_reg_operand" "r"))
1080                   (reg:SI T_REG)))
1081    (set (reg:SI T_REG)
1082         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1083                           (reg:SI T_REG))
1084                 (match_dup 1)))]
1085   "TARGET_SH1"
1086   "subc %2,%0"
1087   [(set_attr "type" "arith")])
1089 (define_insn "subc1"
1090   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1091         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1092                             (match_operand:SI 2 "arith_reg_operand" "r"))
1093                   (reg:SI T_REG)))
1094    (clobber (reg:SI T_REG))]
1095   "TARGET_SH1"
1096   "subc %2,%0"
1097   [(set_attr "type" "arith")])
1099 (define_insn "*subsi3_internal"
1100   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1101         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1102                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1103   "TARGET_SH1"
1104   "sub  %2,%0"
1105   [(set_attr "type" "arith")])
1107 (define_insn "*subsi3_media"
1108   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1109         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1110                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1111   "TARGET_SHMEDIA"
1112   "sub.l        %N1, %2, %0"
1113   [(set_attr "type" "arith_media")])
1115 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1116 ;; will sometimes save one instruction.  Otherwise we might get
1117 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1118 ;; are the same.
1120 (define_expand "subsi3"
1121   [(set (match_operand:SI 0 "arith_reg_operand" "")
1122         (minus:SI (match_operand:SI 1 "arith_operand" "")
1123                   (match_operand:SI 2 "arith_reg_operand" "")))]
1124   ""
1125   "
1127   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1128     {
1129       emit_insn (gen_negsi2 (operands[0], operands[2]));
1130       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1131       DONE;
1132     }
1133   if (TARGET_SHMEDIA)
1134     {
1135       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1136         FAIL;
1137       if (operands[1] != const0_rtx)
1138         operands[1] = force_reg (SImode, operands[1]);
1139     }
1142 ;; -------------------------------------------------------------------------
1143 ;; Division instructions
1144 ;; -------------------------------------------------------------------------
1146 ;; We take advantage of the library routines which don't clobber as many
1147 ;; registers as a normal function call would.
1149 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1150 ;; also has an effect on the register that holds the address of the sfunc.
1151 ;; To make this work, we have an extra dummy insn that shows the use
1152 ;; of this register for reorg.
1154 (define_insn "use_sfunc_addr"
1155   [(set (reg:SI PR_REG)
1156         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1157   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1158   ""
1159   [(set_attr "length" "0")])
1161 (define_insn "udivsi3_sh2a"
1162   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1163         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1164                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1165   "TARGET_SH2A"
1166   "divu %2,%1"
1167   [(set_attr "type" "arith")
1168    (set_attr "in_delay_slot" "no")])
1170 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1171 ;; hard register 0.  If we used hard register 0, then the next instruction
1172 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1173 ;; gets allocated to a stack slot that needs its address reloaded, then
1174 ;; there is nothing to prevent reload from using r0 to reload the address.
1175 ;; This reload would clobber the value in r0 we are trying to store.
1176 ;; If we let reload allocate r0, then this problem can never happen.
1178 (define_insn "udivsi3_i1"
1179   [(set (match_operand:SI 0 "register_operand" "=z")
1180         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1181    (clobber (reg:SI T_REG))
1182    (clobber (reg:SI PR_REG))
1183    (clobber (reg:SI R4_REG))
1184    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1185   "TARGET_SH1 && ! TARGET_SH4"
1186   "jsr  @%1%#"
1187   [(set_attr "type" "sfunc")
1188    (set_attr "needs_delay_slot" "yes")])
1190 ; Since shmedia-nofpu code could be linked against shcompact code, and
1191 ; the udivsi3 libcall has the same name, we must consider all registers
1192 ; clobbered that are in the union of the registers clobbered by the
1193 ; shmedia and the shcompact implementation.  Note, if the shcompact
1194 ; implementation actually used shcompact code, we'd need to clobber
1195 ; also r23 and fr23.
1196 (define_insn "udivsi3_i1_media"
1197   [(set (match_operand:SI 0 "register_operand" "=z")
1198         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1199    (clobber (reg:SI T_MEDIA_REG))
1200    (clobber (reg:SI PR_MEDIA_REG))
1201    (clobber (reg:SI R20_REG))
1202    (clobber (reg:SI R21_REG))
1203    (clobber (reg:SI R22_REG))
1204    (clobber (reg:DI TR0_REG))
1205    (clobber (reg:DI TR1_REG))
1206    (clobber (reg:DI TR2_REG))
1207    (use (match_operand:DI 1 "target_operand" "b"))]
1208   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1209   "blink        %1, r18"
1210   [(set_attr "type" "sfunc")
1211    (set_attr "needs_delay_slot" "yes")])
1213 (define_expand "udivsi3_i4_media"
1214   [(set (match_dup 3)
1215         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1216    (set (match_dup 4)
1217         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1218    (set (match_dup 5) (float:DF (match_dup 3)))
1219    (set (match_dup 6) (float:DF (match_dup 4)))
1220    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1221    (set (match_dup 8) (fix:DI (match_dup 7)))
1222    (set (match_operand:SI 0 "register_operand" "")
1223         (truncate:SI (match_dup 8)))]
1224   "TARGET_SHMEDIA_FPU"
1225   "
1227   operands[3] = gen_reg_rtx (DImode);
1228   operands[4] = gen_reg_rtx (DImode);
1229   operands[5] = gen_reg_rtx (DFmode);
1230   operands[6] = gen_reg_rtx (DFmode);
1231   operands[7] = gen_reg_rtx (DFmode);
1232   operands[8] = gen_reg_rtx (DImode);
1235 (define_insn "udivsi3_i4"
1236   [(set (match_operand:SI 0 "register_operand" "=y")
1237         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1238    (clobber (reg:SI T_REG))
1239    (clobber (reg:SI PR_REG))
1240    (clobber (reg:DF DR0_REG))
1241    (clobber (reg:DF DR2_REG))
1242    (clobber (reg:DF DR4_REG))
1243    (clobber (reg:SI R0_REG))
1244    (clobber (reg:SI R1_REG))
1245    (clobber (reg:SI R4_REG))
1246    (clobber (reg:SI R5_REG))
1247    (use (reg:PSI FPSCR_REG))
1248    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1249   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1250   "jsr  @%1%#"
1251   [(set_attr "type" "sfunc")
1252    (set_attr "fp_mode" "double")
1253    (set_attr "needs_delay_slot" "yes")])
1255 (define_insn "udivsi3_i4_single"
1256   [(set (match_operand:SI 0 "register_operand" "=y")
1257         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1258    (clobber (reg:SI T_REG))
1259    (clobber (reg:SI PR_REG))
1260    (clobber (reg:DF DR0_REG))
1261    (clobber (reg:DF DR2_REG))
1262    (clobber (reg:DF DR4_REG))
1263    (clobber (reg:SI R0_REG))
1264    (clobber (reg:SI R1_REG))
1265    (clobber (reg:SI R4_REG))
1266    (clobber (reg:SI R5_REG))
1267    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1268   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1269   "jsr  @%1%#"
1270   [(set_attr "type" "sfunc")
1271    (set_attr "needs_delay_slot" "yes")])
1273 (define_expand "udivsi3"
1274   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1275    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1276    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1277    (parallel [(set (match_operand:SI 0 "register_operand" "")
1278                    (udiv:SI (reg:SI R4_REG)
1279                             (reg:SI R5_REG)))
1280               (clobber (reg:SI T_REG))
1281               (clobber (reg:SI PR_REG))
1282               (clobber (reg:SI R4_REG))
1283               (use (match_dup 3))])]
1284   ""
1285   "
1287   rtx first, last;
1289   operands[3] = gen_reg_rtx (Pmode);
1290   /* Emit the move of the address to a pseudo outside of the libcall.  */
1291   if (TARGET_HARD_SH4 && TARGET_SH2E)
1292     {
1293       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1294       if (TARGET_FPU_SINGLE)
1295         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1296       else
1297         last = gen_udivsi3_i4 (operands[0], operands[3]);
1298     }
1299   else if (TARGET_SHMEDIA_FPU)
1300     {
1301       operands[1] = force_reg (SImode, operands[1]);
1302       operands[2] = force_reg (SImode, operands[2]);
1303       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1304       DONE;
1305     }
1306   else if (TARGET_SH2A)
1307     {
1308       operands[1] = force_reg (SImode, operands[1]);
1309       operands[2] = force_reg (SImode, operands[2]);
1310       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1311       DONE;
1312     }
1313   else if (TARGET_SH5)
1314     {
1315       emit_move_insn (operands[3],
1316                       function_symbol (TARGET_FPU_ANY
1317                                        ? \"__udivsi3_i4\"
1318                                        : \"__udivsi3\"));
1320       if (TARGET_SHMEDIA)
1321         last = gen_udivsi3_i1_media (operands[0],
1322                                      Pmode == DImode
1323                                      ? operands[3]
1324                                      : gen_rtx_SUBREG (DImode, operands[3],
1325                                                        0));
1326       else if (TARGET_FPU_ANY)
1327         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1328       else
1329         last = gen_udivsi3_i1 (operands[0], operands[3]);
1330     }
1331   else
1332     {
1333       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1334       last = gen_udivsi3_i1 (operands[0], operands[3]);
1335     }
1336   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1337   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1338   last = emit_insn (last);
1339   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1340      invariant code motion can move it.  */
1341   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1342   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1343   DONE;
1346 (define_insn "divsi3_sh2a"
1347   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1348         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1349                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1350   "TARGET_SH2A"
1351   "divs %2,%1"
1352   [(set_attr "type" "arith")
1353    (set_attr "in_delay_slot" "no")])
1355 (define_insn "divsi3_i1"
1356   [(set (match_operand:SI 0 "register_operand" "=z")
1357         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1358    (clobber (reg:SI T_REG))
1359    (clobber (reg:SI PR_REG))
1360    (clobber (reg:SI R1_REG))
1361    (clobber (reg:SI R2_REG))
1362    (clobber (reg:SI R3_REG))
1363    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1364   "TARGET_SH1 && ! TARGET_SH4"
1365   "jsr  @%1%#"
1366   [(set_attr "type" "sfunc")
1367    (set_attr "needs_delay_slot" "yes")])
1369 ; Since shmedia-nofpu code could be linked against shcompact code, and
1370 ; the sdivsi3 libcall has the same name, we must consider all registers
1371 ; clobbered that are in the union of the registers clobbered by the
1372 ; shmedia and the shcompact implementation.  Note, if the shcompact
1373 ; implementation actually used shcompact code, we'd need to clobber
1374 ; also r22, r23 and fr23.
1375 (define_insn "divsi3_i1_media"
1376   [(set (match_operand:SI 0 "register_operand" "=z")
1377         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1378    (clobber (reg:SI T_MEDIA_REG))
1379    (clobber (reg:SI PR_MEDIA_REG))
1380    (clobber (reg:SI R1_REG))
1381    (clobber (reg:SI R2_REG))
1382    (clobber (reg:SI R3_REG))
1383    (clobber (reg:SI R20_REG))
1384    (clobber (reg:SI R21_REG))
1385    (clobber (reg:DI TR0_REG))
1386    (clobber (reg:DI TR1_REG))
1387    (clobber (reg:DI TR2_REG))
1388    (use (match_operand:DI 1 "target_operand" "b"))]
1389   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1390   "blink        %1, r18"
1391   [(set_attr "type" "sfunc")])
1393 (define_expand "divsi3_i4_media"
1394   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1395    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1396    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1397    (set (match_operand:SI 0 "register_operand" "=r")
1398         (fix:SI (match_dup 5)))]
1399   "TARGET_SHMEDIA_FPU"
1400   "
1402   operands[3] = gen_reg_rtx (DFmode);
1403   operands[4] = gen_reg_rtx (DFmode);
1404   operands[5] = gen_reg_rtx (DFmode);
1407 (define_insn "divsi3_i4"
1408   [(set (match_operand:SI 0 "register_operand" "=y")
1409         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1410    (clobber (reg:SI PR_REG))
1411    (clobber (reg:DF DR0_REG))
1412    (clobber (reg:DF DR2_REG))
1413    (use (reg:PSI FPSCR_REG))
1414    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1415   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1416   "jsr  @%1%#"
1417   [(set_attr "type" "sfunc")
1418    (set_attr "fp_mode" "double")
1419    (set_attr "needs_delay_slot" "yes")])
1421 (define_insn "divsi3_i4_single"
1422   [(set (match_operand:SI 0 "register_operand" "=y")
1423         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1424    (clobber (reg:SI PR_REG))
1425    (clobber (reg:DF DR0_REG))
1426    (clobber (reg:DF DR2_REG))
1427    (clobber (reg:SI R2_REG))
1428    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1429   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1430   "jsr  @%1%#"
1431   [(set_attr "type" "sfunc")
1432    (set_attr "needs_delay_slot" "yes")])
1434 (define_expand "divsi3"
1435   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1436    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1437    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1438    (parallel [(set (match_operand:SI 0 "register_operand" "")
1439                    (div:SI (reg:SI R4_REG)
1440                            (reg:SI R5_REG)))
1441               (clobber (reg:SI T_REG))
1442               (clobber (reg:SI PR_REG))
1443               (clobber (reg:SI R1_REG))
1444               (clobber (reg:SI R2_REG))
1445               (clobber (reg:SI R3_REG))
1446               (use (match_dup 3))])]
1447   ""
1448   "
1450   rtx first, last;
1452   operands[3] = gen_reg_rtx (Pmode);
1453   /* Emit the move of the address to a pseudo outside of the libcall.  */
1454   if (TARGET_HARD_SH4 && TARGET_SH2E)
1455     {
1456       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1457       if (TARGET_FPU_SINGLE)
1458         last = gen_divsi3_i4_single (operands[0], operands[3]);
1459       else
1460         last = gen_divsi3_i4 (operands[0], operands[3]);
1461     }
1462   else if (TARGET_SH2A)
1463     {
1464       operands[1] = force_reg (SImode, operands[1]);
1465       operands[2] = force_reg (SImode, operands[2]);
1466       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1467       DONE;
1468     }
1469   else if (TARGET_SHMEDIA_FPU)
1470     {
1471       operands[1] = force_reg (SImode, operands[1]);
1472       operands[2] = force_reg (SImode, operands[2]);
1473       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1474       DONE;
1475     }
1476   else if (TARGET_SH5)
1477     {
1478       emit_move_insn (operands[3],
1479                       function_symbol (TARGET_FPU_ANY
1480                                        ? \"__sdivsi3_i4\"
1481                                        : \"__sdivsi3\"));
1483       if (TARGET_SHMEDIA)
1484         last = gen_divsi3_i1_media (operands[0],
1485                                     Pmode == DImode
1486                                     ? operands[3]
1487                                     : gen_rtx_SUBREG (DImode, operands[3],
1488                                                       0));
1489       else if (TARGET_FPU_ANY)
1490         last = gen_divsi3_i4_single (operands[0], operands[3]);
1491       else
1492         last = gen_divsi3_i1 (operands[0], operands[3]);
1493     }
1494   else
1495     {
1496       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1497       last = gen_divsi3_i1 (operands[0], operands[3]);
1498     }
1499   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1500   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1501   last = emit_insn (last);
1502   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1503      invariant code motion can move it.  */
1504   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1505   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1506   DONE;
1509 ;; -------------------------------------------------------------------------
1510 ;; Multiplication instructions
1511 ;; -------------------------------------------------------------------------
1513 (define_insn "umulhisi3_i"
1514   [(set (reg:SI MACL_REG)
1515         (mult:SI (zero_extend:SI
1516                   (match_operand:HI 0 "arith_reg_operand" "r"))
1517                  (zero_extend:SI
1518                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1519   "TARGET_SH1"
1520   "mulu.w       %1,%0"
1521   [(set_attr "type" "smpy")])
1523 (define_insn "mulhisi3_i"
1524   [(set (reg:SI MACL_REG)
1525         (mult:SI (sign_extend:SI
1526                   (match_operand:HI 0 "arith_reg_operand" "r"))
1527                  (sign_extend:SI
1528                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1529   "TARGET_SH1"
1530   "muls.w       %1,%0"
1531   [(set_attr "type" "smpy")])
1533 (define_expand "mulhisi3"
1534   [(set (reg:SI MACL_REG)
1535         (mult:SI (sign_extend:SI
1536                   (match_operand:HI 1 "arith_reg_operand" ""))
1537                  (sign_extend:SI
1538                   (match_operand:HI 2 "arith_reg_operand" ""))))
1539    (set (match_operand:SI 0 "arith_reg_operand" "")
1540         (reg:SI MACL_REG))]
1541   "TARGET_SH1"
1542   "
1544   rtx first, last;
1546   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1547   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1548   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1549      invariant code motion can move it.  */
1550   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1551   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1552   /* expand_binop can't find a suitable code in umul_widen_optab to
1553      make a REG_EQUAL note from, so make one here.
1554      See also smulsi3_highpart.
1555      ??? Alternatively, we could put this at the calling site of expand_binop,
1556      i.e. expand_expr.  */
1557   REG_NOTES (last)
1558     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1559                          REG_NOTES (last));
1560   DONE;
1563 (define_expand "umulhisi3"
1564   [(set (reg:SI MACL_REG)
1565         (mult:SI (zero_extend:SI
1566                   (match_operand:HI 1 "arith_reg_operand" ""))
1567                  (zero_extend:SI
1568                   (match_operand:HI 2 "arith_reg_operand" ""))))
1569    (set (match_operand:SI 0 "arith_reg_operand" "")
1570         (reg:SI MACL_REG))]
1571   "TARGET_SH1"
1572   "
1574   rtx first, last;
1576   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1577   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1578   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1579      invariant code motion can move it.  */
1580   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1581   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1582   /* expand_binop can't find a suitable code in umul_widen_optab to
1583      make a REG_EQUAL note from, so make one here.
1584      See also smulsi3_highpart.
1585      ??? Alternatively, we could put this at the calling site of expand_binop,
1586      i.e. expand_expr.  */
1587   REG_NOTES (last)
1588     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1589                          REG_NOTES (last));
1590   DONE;
1593 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1594 ;; a call to a routine which clobbers known registers.
1596 (define_insn ""
1597   [(set (match_operand:SI 1 "register_operand" "=z")
1598         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1599    (clobber (reg:SI MACL_REG))
1600    (clobber (reg:SI T_REG))
1601    (clobber (reg:SI PR_REG))
1602    (clobber (reg:SI R3_REG))
1603    (clobber (reg:SI R2_REG))
1604    (clobber (reg:SI R1_REG))
1605    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1606   "TARGET_SH1"
1607   "jsr  @%0%#"
1608   [(set_attr "type" "sfunc")
1609    (set_attr "needs_delay_slot" "yes")])
1611 (define_expand "mulsi3_call"
1612   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1613    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1614    (parallel[(set (match_operand:SI 0 "register_operand" "")
1615                   (mult:SI (reg:SI R4_REG)
1616                            (reg:SI R5_REG)))
1617              (clobber (reg:SI MACL_REG))
1618              (clobber (reg:SI T_REG))
1619              (clobber (reg:SI PR_REG))
1620              (clobber (reg:SI R3_REG))
1621              (clobber (reg:SI R2_REG))
1622              (clobber (reg:SI R1_REG))
1623              (use (match_operand:SI 3 "register_operand" ""))])]
1624   "TARGET_SH1"
1625   "")
1627 (define_insn "mul_r"
1628   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1629         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1630                  (match_operand:SI 2 "arith_reg_operand" "z")))]
1631   "TARGET_SH2A"
1632   "mulr %2,%0"
1633   [(set_attr "type" "dmpy")])
1635 (define_insn "mul_l"
1636   [(set (reg:SI MACL_REG)
1637         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1638                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1639   "TARGET_SH2"
1640   "mul.l        %1,%0"
1641   [(set_attr "type" "dmpy")])
1643 (define_expand "mulsi3"
1644   [(set (reg:SI MACL_REG)
1645         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1646                   (match_operand:SI 2 "arith_reg_operand" "")))
1647    (set (match_operand:SI 0 "arith_reg_operand" "")
1648         (reg:SI MACL_REG))]
1649   "TARGET_SH1"
1650   "
1652   rtx first, last;
1654   if (!TARGET_SH2)
1655     {
1656       /* The address must be set outside the libcall,
1657          since it goes into a pseudo.  */
1658       rtx sym = function_symbol (\"__mulsi3\");
1659       rtx addr = force_reg (SImode, sym);
1660       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1661                                    operands[2], addr);
1662       first = insns;
1663       last = emit_insn (insns);
1664     }
1665   else
1666     {
1667       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1669       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1670       /* consec_sets_giv can only recognize the first insn that sets a
1671          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1672          note.  */
1673       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1674     }
1675   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1676      invariant code motion can move it.  */
1677   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1678   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1679   DONE;
1682 (define_insn "mulsidi3_i"
1683   [(set (reg:SI MACH_REG)
1684         (truncate:SI
1685          (lshiftrt:DI
1686           (mult:DI
1687            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1688            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1689           (const_int 32))))
1690    (set (reg:SI MACL_REG)
1691         (mult:SI (match_dup 0)
1692                  (match_dup 1)))]
1693   "TARGET_SH2"
1694   "dmuls.l      %1,%0"
1695   [(set_attr "type" "dmpy")])
1697 (define_expand "mulsidi3"
1698   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1699         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1700                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1701   "TARGET_SH2 || TARGET_SHMEDIA"
1702   "
1704   if (TARGET_SH2)
1705     {
1706        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1707                                         operands[2]));
1708        DONE;
1709     }
1712 (define_insn "mulsidi3_media"
1713   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1714         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1715                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1716   "TARGET_SHMEDIA"
1717   "muls.l       %1, %2, %0"
1718   [(set_attr "type" "dmpy_media")])
1720 (define_insn "mulsidi3_compact"
1721   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1722         (mult:DI
1723          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1724          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1725    (clobber (reg:SI MACH_REG))
1726    (clobber (reg:SI MACL_REG))]
1727   "TARGET_SH2"
1728   "#")
1730 (define_split
1731   [(set (match_operand:DI 0 "arith_reg_operand" "")
1732         (mult:DI
1733          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1734          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1735    (clobber (reg:SI MACH_REG))
1736    (clobber (reg:SI MACL_REG))]
1737   "TARGET_SH2"
1738   [(const_int 0)]
1739   "
1741   rtx low_dst = gen_lowpart (SImode, operands[0]);
1742   rtx high_dst = gen_highpart (SImode, operands[0]);
1744   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1746   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1747   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1748   /* We need something to tag the possible REG_EQUAL notes on to.  */
1749   emit_move_insn (operands[0], operands[0]);
1750   DONE;
1753 (define_insn "umulsidi3_i"
1754   [(set (reg:SI MACH_REG)
1755         (truncate:SI
1756          (lshiftrt:DI
1757           (mult:DI
1758            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1759            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1760           (const_int 32))))
1761    (set (reg:SI MACL_REG)
1762         (mult:SI (match_dup 0)
1763                  (match_dup 1)))]
1764   "TARGET_SH2"
1765   "dmulu.l      %1,%0"
1766   [(set_attr "type" "dmpy")])
1768 (define_expand "umulsidi3"
1769   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1770         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1771                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1772   "TARGET_SH2 || TARGET_SHMEDIA"
1773   "
1775   if (TARGET_SH2)
1776     {
1777        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1778                                          operands[2]));
1779        DONE;
1780     }
1783 (define_insn "umulsidi3_media"
1784   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1785         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1786                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1787   "TARGET_SHMEDIA"
1788   "mulu.l       %1, %2, %0"
1789   [(set_attr "type" "dmpy_media")])
1791 (define_insn "umulsidi3_compact"
1792   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1793         (mult:DI
1794          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1795          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1796    (clobber (reg:SI MACH_REG))
1797    (clobber (reg:SI MACL_REG))]
1798   "TARGET_SH2"
1799   "#")
1801 (define_split
1802   [(set (match_operand:DI 0 "arith_reg_operand" "")
1803         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1804                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1805    (clobber (reg:SI MACH_REG))
1806    (clobber (reg:SI MACL_REG))]
1807   "TARGET_SH2"
1808   [(const_int 0)]
1809   "
1811   rtx low_dst = gen_lowpart (SImode, operands[0]);
1812   rtx high_dst = gen_highpart (SImode, operands[0]);
1814   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1816   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1817   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1818   /* We need something to tag the possible REG_EQUAL notes on to.  */
1819   emit_move_insn (operands[0], operands[0]);
1820   DONE;
1823 (define_insn "smulsi3_highpart_i"
1824   [(set (reg:SI MACH_REG)
1825         (truncate:SI
1826          (lshiftrt:DI
1827           (mult:DI
1828            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1829            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1830           (const_int 32))))
1831    (clobber (reg:SI MACL_REG))]
1832   "TARGET_SH2"
1833   "dmuls.l      %1,%0"
1834   [(set_attr "type" "dmpy")])
1836 (define_expand "smulsi3_highpart"
1837   [(parallel
1838     [(set (reg:SI MACH_REG)
1839           (truncate:SI
1840            (lshiftrt:DI
1841             (mult:DI
1842              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1843              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1844             (const_int 32))))
1845     (clobber (reg:SI MACL_REG))])
1846    (set (match_operand:SI 0 "arith_reg_operand" "")
1847         (reg:SI MACH_REG))]
1848   "TARGET_SH2"
1849   "
1851   rtx first, last;
1853   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1854   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1855   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1856      invariant code motion can move it.  */
1857   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1858   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1859   /* expand_binop can't find a suitable code in mul_highpart_optab to
1860      make a REG_EQUAL note from, so make one here.
1861      See also {,u}mulhisi.
1862      ??? Alternatively, we could put this at the calling site of expand_binop,
1863      i.e. expand_mult_highpart.  */
1864   REG_NOTES (last)
1865     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1866                          REG_NOTES (last));
1867   DONE;
1870 (define_insn "umulsi3_highpart_i"
1871   [(set (reg:SI MACH_REG)
1872         (truncate:SI
1873          (lshiftrt:DI
1874           (mult:DI
1875            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1876            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1877           (const_int 32))))
1878    (clobber (reg:SI MACL_REG))]
1879   "TARGET_SH2"
1880   "dmulu.l      %1,%0"
1881   [(set_attr "type" "dmpy")])
1883 (define_expand "umulsi3_highpart"
1884   [(parallel
1885     [(set (reg:SI MACH_REG)
1886           (truncate:SI
1887            (lshiftrt:DI
1888             (mult:DI
1889              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1890              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1891             (const_int 32))))
1892     (clobber (reg:SI MACL_REG))])
1893    (set (match_operand:SI 0 "arith_reg_operand" "")
1894         (reg:SI MACH_REG))]
1895   "TARGET_SH2"
1896   "
1898   rtx first, last;
1900   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1901   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1902   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1903      invariant code motion can move it.  */
1904   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1905   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1906   DONE;
1909 ;; -------------------------------------------------------------------------
1910 ;; Logical operations
1911 ;; -------------------------------------------------------------------------
1913 (define_insn "*andsi3_compact"
1914   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1915         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1916                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1917   "TARGET_SH1"
1918   "and  %2,%0"
1919   [(set_attr "type" "arith")])
1921 ;; If the constant is 255, then emit an extu.b instruction instead of an
1922 ;; and, since that will give better code.
1924 (define_expand "andsi3"
1925   [(set (match_operand:SI 0 "arith_reg_operand" "")
1926         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1927                 (match_operand:SI 2 "logical_operand" "")))]
1928   "TARGET_SH1"
1929   "
1931   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1932     {
1933       emit_insn (gen_zero_extendqisi2 (operands[0],
1934                                        gen_lowpart (QImode, operands[1])));
1935       DONE;
1936     }
1939 (define_insn_and_split "anddi3"
1940   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1941         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1942                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1943   "TARGET_SHMEDIA"
1944   "@
1945         and     %1, %2, %0
1946         andi    %1, %2, %0
1947         #"
1948   "reload_completed
1949    && ! logical_operand (operands[2], DImode)"
1950   [(const_int 0)]
1951   "
1953   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1954     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1955   else
1956     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1957   DONE;
1959   [(set_attr "type" "arith_media")])
1961 (define_insn "andcdi3"
1962   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1963         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1964                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1965   "TARGET_SHMEDIA"
1966   "andc %1,%2,%0"
1967   [(set_attr "type" "arith_media")])
1969 (define_insn "iorsi3"
1970   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1971         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1972                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1973   "TARGET_SH1"
1974   "or   %2,%0"
1975   [(set_attr "type" "arith")])
1977 (define_insn "iordi3"
1978   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1979         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1980                 (match_operand:DI 2 "logical_operand" "r,I10")))]
1981   "TARGET_SHMEDIA"
1982   "@
1983         or      %1, %2, %0
1984         ori     %1, %2, %0"
1985   [(set_attr "type" "arith_media")])
1987 (define_insn "xorsi3"
1988   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1989         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1990                 (match_operand:SI 2 "logical_operand" "K08,r")))]
1991   "TARGET_SH1"
1992   "xor  %2,%0"
1993   [(set_attr "type" "arith")])
1995 (define_insn "xordi3"
1996   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1997         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1998                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1999   "TARGET_SHMEDIA"
2000   "@
2001         xor     %1, %2, %0
2002         xori    %1, %2, %0"
2003   [(set_attr "type" "arith_media")])
2005 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2006 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2007 (define_split
2008   [(set (match_operand:DI 0 "arith_reg_operand" "")
2009         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2010                           [(match_operand 1 "any_register_operand" "")
2011                            (match_operand 2 "any_register_operand" "")])))]
2012   "TARGET_SHMEDIA"
2013   [(set (match_dup 5) (match_dup 4))
2014    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2017   enum machine_mode inmode = GET_MODE (operands[1]);
2018   int offset = 0;
2020   if (GET_CODE (operands[0]) == SUBREG)
2021     {
2022       offset = SUBREG_BYTE (operands[0]);
2023       operands[0] = SUBREG_REG (operands[0]);
2024     }
2025   if (GET_CODE (operands[0]) != REG)
2026     abort ();
2027   if (! TARGET_LITTLE_ENDIAN)
2028     offset += 8 - GET_MODE_SIZE (inmode);
2029   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2032 ;; -------------------------------------------------------------------------
2033 ;; Shifts and rotates
2034 ;; -------------------------------------------------------------------------
2036 (define_expand "rotldi3"
2037   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2038         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2039                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2040   "TARGET_SHMEDIA"
2041   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2043 (define_insn "rotldi3_mextr"
2044   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2045         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2046                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2047   "TARGET_SHMEDIA"
2048   "*
2050   static char templ[16];
2052   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2053            8 - (int) (INTVAL (operands[2]) >> 3));
2054   return templ;
2056   [(set_attr "type" "arith_media")])
2058 (define_expand "rotrdi3"
2059   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2060         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2061                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2062   "TARGET_SHMEDIA"
2063   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2065 (define_insn "rotrdi3_mextr"
2066   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2067         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2068                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2069   "TARGET_SHMEDIA"
2070   "*
2072   static char templ[16];
2074   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2075   return templ;
2077   [(set_attr "type" "arith_media")])
2079 (define_insn "rotlsi3_1"
2080   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2081         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2082                    (const_int 1)))
2083    (set (reg:SI T_REG)
2084         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2085   "TARGET_SH1"
2086   "rotl %0"
2087   [(set_attr "type" "arith")])
2089 (define_insn "rotlsi3_31"
2090   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2091         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2092                    (const_int 31)))
2093    (clobber (reg:SI T_REG))]
2094   "TARGET_SH1"
2095   "rotr %0"
2096   [(set_attr "type" "arith")])
2098 (define_insn "rotlsi3_16"
2099   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2100         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2101                    (const_int 16)))]
2102   "TARGET_SH1"
2103   "swap.w       %1,%0"
2104   [(set_attr "type" "arith")])
2106 (define_expand "rotlsi3"
2107   [(set (match_operand:SI 0 "arith_reg_operand" "")
2108         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2109                    (match_operand:SI 2 "immediate_operand" "")))]
2110   "TARGET_SH1"
2111   "
2113   static const char rot_tab[] = {
2114     000, 000, 000, 000, 000, 000, 010, 001,
2115     001, 001, 011, 013, 003, 003, 003, 003,
2116     003, 003, 003, 003, 003, 013, 012, 002,
2117     002, 002, 010, 000, 000, 000, 000, 000,
2118   };
2120   int count, choice;
2122   if (GET_CODE (operands[2]) != CONST_INT)
2123     FAIL;
2124   count = INTVAL (operands[2]);
2125   choice = rot_tab[count];
2126   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2127     FAIL;
2128   choice &= 7;
2129   switch (choice)
2130     {
2131     case 0:
2132       emit_move_insn (operands[0], operands[1]);
2133       count -= (count & 16) * 2;
2134       break;
2135     case 3:
2136      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2137      count -= 16;
2138      break;
2139     case 1:
2140     case 2:
2141       {
2142         rtx parts[2];
2143         parts[0] = gen_reg_rtx (SImode);
2144         parts[1] = gen_reg_rtx (SImode);
2145         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2146         emit_move_insn (parts[choice-1], operands[1]);
2147         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2148         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2149         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2150         count = (count & ~16) - 8;
2151       }
2152     }
2154   for (; count > 0; count--)
2155     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2156   for (; count < 0; count++)
2157     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2159   DONE;
2162 (define_insn "*rotlhi3_8"
2163   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2164         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2165                    (const_int 8)))]
2166   "TARGET_SH1"
2167   "swap.b       %1,%0"
2168   [(set_attr "type" "arith")])
2170 (define_expand "rotlhi3"
2171   [(set (match_operand:HI 0 "arith_reg_operand" "")
2172         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2173                    (match_operand:HI 2 "immediate_operand" "")))]
2174   "TARGET_SH1"
2175   "
2177   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2178     FAIL;
2182 ;; shift left
2184 (define_insn "ashlsi3_sh2a"
2185   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2186         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2187                    (match_operand:SI 2 "arith_reg_operand" "r")))]
2188   "TARGET_SH2A"
2189   "shad %2,%0"
2190   [(set_attr "type" "arith")
2191    (set_attr "length" "4")])
2193 ;; This pattern is used by init_expmed for computing the costs of shift
2194 ;; insns.
2196 (define_insn_and_split "ashlsi3_std"
2197   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2198         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2199                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2200    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2201   "TARGET_SH3
2202    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2203        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2204   "@
2205    shld %2,%0
2206    add  %0,%0
2207    shll%O2      %0
2208    #"
2209   "TARGET_SH3
2210    && reload_completed
2211    && GET_CODE (operands[2]) == CONST_INT
2212    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2213   [(set (match_dup 3) (match_dup 2))
2214    (parallel
2215     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2216      (clobber (match_dup 4))])]
2217   "operands[4] = gen_rtx_SCRATCH (SImode);"
2218   [(set_attr "length" "*,*,*,4")
2219    (set_attr "type" "dyn_shift,arith,arith,arith")])
2221 (define_insn "ashlhi3_k"
2222   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2223         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2224                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2225   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2226   "@
2227         add     %0,%0
2228         shll%O2 %0"
2229   [(set_attr "type" "arith")])
2231 (define_insn "ashlsi3_n"
2232   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2233         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2234                    (match_operand:SI 2 "const_int_operand" "n")))
2235    (clobber (reg:SI T_REG))]
2236   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2237   "#"
2238   [(set (attr "length")
2239         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2240                (const_string "2")
2241                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2242                (const_string "4")
2243                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2244                (const_string "6")]
2245               (const_string "8")))
2246    (set_attr "type" "arith")])
2248 (define_split
2249   [(set (match_operand:SI 0 "arith_reg_operand" "")
2250         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2251                    (match_operand:SI 2 "const_int_operand" "")))
2252    (clobber (reg:SI T_REG))]
2253   "TARGET_SH1 && reload_completed"
2254   [(use (reg:SI R0_REG))]
2255   "
2257   gen_shifty_op (ASHIFT, operands);
2258   DONE;
2261 (define_insn "ashlsi3_media"
2262   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2263         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2264                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2265   "TARGET_SHMEDIA"
2266   "@
2267         shlld.l %1, %2, %0
2268         shlli.l %1, %2, %0"
2269   [(set_attr "type" "arith_media")])
2271 (define_expand "ashlsi3"
2272   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2273                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2274                               (match_operand:SI 2 "nonmemory_operand" "")))
2275               (clobber (reg:SI T_REG))])]
2276   ""
2277   "
2279   if (TARGET_SHMEDIA)
2280     {
2281       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2282       DONE;
2283     }
2284   if (GET_CODE (operands[2]) == CONST_INT
2285       && sh_dynamicalize_shift_p (operands[2]))
2286     operands[2] = force_reg (SImode, operands[2]);
2287   if (TARGET_SH3)
2288     {
2289       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2290       DONE;
2291     }
2292   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2293     FAIL;
2296 (define_insn "ashlhi3"
2297   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2298         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2299                    (match_operand:HI 2 "const_int_operand" "n")))
2300    (clobber (reg:SI T_REG))]
2301   "TARGET_SH1"
2302   "#"
2303   [(set (attr "length")
2304         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2305                (const_string "2")
2306                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2307                (const_string "4")]
2308               (const_string "6")))
2309    (set_attr "type" "arith")])
2311 (define_split
2312   [(set (match_operand:HI 0 "arith_reg_operand" "")
2313         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2314                    (match_operand:HI 2 "const_int_operand" "")))
2315    (clobber (reg:SI T_REG))]
2316   "TARGET_SH1 && reload_completed"
2317   [(use (reg:SI R0_REG))]
2318   "
2320   gen_shifty_hi_op (ASHIFT, operands);
2321   DONE;
2325 ; arithmetic shift right
2328 (define_insn "ashrsi3_sh2a"
2329   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2330         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2331                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2332   "TARGET_SH2A"
2333   "shad %2,%0"
2334   [(set_attr "type" "dyn_shift")
2335    (set_attr "length" "4")])
2337 (define_insn "ashrsi3_k"
2338   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2339         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2340                      (match_operand:SI 2 "const_int_operand" "M")))
2341    (clobber (reg:SI T_REG))]
2342   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2343   "shar %0"
2344   [(set_attr "type" "arith")])
2346 ;; We can't do HImode right shifts correctly unless we start out with an
2347 ;; explicit zero / sign extension; doing that would result in worse overall
2348 ;; code, so just let the machine independent code widen the mode.
2349 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2352 ;; ??? This should be a define expand.
2354 (define_insn "ashrsi2_16"
2355   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2356         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2357                      (const_int 16)))]
2358   "TARGET_SH1"
2359   "#"
2360   [(set_attr "length" "4")])
2362 (define_split
2363   [(set (match_operand:SI 0 "arith_reg_operand" "")
2364         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2365                      (const_int 16)))]
2366   "TARGET_SH1"
2367   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2368    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2369   "operands[2] = gen_lowpart (HImode, operands[0]);")
2371 ;; ??? This should be a define expand.
2373 (define_insn "ashrsi2_31"
2374   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2375         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2376                      (const_int 31)))
2377    (clobber (reg:SI T_REG))]
2378   "TARGET_SH1"
2379   "#"
2380   [(set_attr "length" "4")])
2382 (define_split
2383   [(set (match_operand:SI 0 "arith_reg_operand" "")
2384         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2385                      (const_int 31)))
2386    (clobber (reg:SI T_REG))]
2387   "TARGET_SH1"
2388   [(const_int 0)]
2389   "
2391   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2392   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2393   DONE;
2396 (define_insn "ashlsi_c"
2397   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2398         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2399    (set (reg:SI T_REG)
2400         (lt:SI (match_dup 1) (const_int 0)))]
2401   "TARGET_SH1"
2402   "shll %0"
2403   [(set_attr "type" "arith")])
2405 (define_insn "ashrsi3_d"
2406   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2407         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2408                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2409   "TARGET_SH3"
2410   "shad %2,%0"
2411   [(set_attr "type" "dyn_shift")])
2413 (define_insn "ashrsi3_n"
2414   [(set (reg:SI R4_REG)
2415         (ashiftrt:SI (reg:SI R4_REG)
2416                      (match_operand:SI 0 "const_int_operand" "i")))
2417    (clobber (reg:SI T_REG))
2418    (clobber (reg:SI PR_REG))
2419    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2420   "TARGET_SH1"
2421   "jsr  @%1%#"
2422   [(set_attr "type" "sfunc")
2423    (set_attr "needs_delay_slot" "yes")])
2425 (define_insn "ashrsi3_media"
2426   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2427         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2428                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2429   "TARGET_SHMEDIA"
2430   "@
2431         shard.l %1, %2, %0
2432         shari.l %1, %2, %0"
2433   [(set_attr "type" "arith_media")])
2435 (define_expand "ashrsi3"
2436   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2437                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2438                                 (match_operand:SI 2 "nonmemory_operand" "")))
2439               (clobber (reg:SI T_REG))])]
2440   ""
2441   "
2443   if (TARGET_SHMEDIA)
2444     {
2445       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2446       DONE;
2447     }
2448   if (expand_ashiftrt (operands))
2449     DONE;
2450   else
2451     FAIL;
2454 ;; logical shift right
2456 (define_insn "lshrsi3_sh2a"
2457   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2458         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2459                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2460   "TARGET_SH2A"
2461   "shld %2,%0"
2462   [(set_attr "type" "dyn_shift")
2463    (set_attr "length" "4")])
2465 (define_insn "lshrsi3_d"
2466   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2467         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2468                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2469   "TARGET_SH3"
2470   "shld %2,%0"
2471   [(set_attr "type" "dyn_shift")])
2473 ;;  Only the single bit shift clobbers the T bit.
2475 (define_insn "lshrsi3_m"
2476   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2477         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2478                      (match_operand:SI 2 "const_int_operand" "M")))
2479    (clobber (reg:SI T_REG))]
2480   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2481   "shlr %0"
2482   [(set_attr "type" "arith")])
2484 (define_insn "lshrsi3_k"
2485   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2486         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2487                      (match_operand:SI 2 "const_int_operand" "P27")))]
2488   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2489    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2490   "shlr%O2      %0"
2491   [(set_attr "type" "arith")])
2493 (define_insn "lshrsi3_n"
2494   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2495         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2496                      (match_operand:SI 2 "const_int_operand" "n")))
2497    (clobber (reg:SI T_REG))]
2498   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2499   "#"
2500   [(set (attr "length")
2501         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2502                (const_string "2")
2503                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2504                (const_string "4")
2505                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2506                (const_string "6")]
2507               (const_string "8")))
2508    (set_attr "type" "arith")])
2510 (define_split
2511   [(set (match_operand:SI 0 "arith_reg_operand" "")
2512         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2513                      (match_operand:SI 2 "const_int_operand" "")))
2514    (clobber (reg:SI T_REG))]
2515   "TARGET_SH1 && reload_completed"
2516   [(use (reg:SI R0_REG))]
2517   "
2519   gen_shifty_op (LSHIFTRT, operands);
2520   DONE;
2523 (define_insn "lshrsi3_media"
2524   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2525         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2526                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2527   "TARGET_SHMEDIA"
2528   "@
2529         shlrd.l %1, %2, %0
2530         shlri.l %1, %2, %0"
2531   [(set_attr "type" "arith_media")])
2533 (define_expand "lshrsi3"
2534   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2535                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2536                                 (match_operand:SI 2 "nonmemory_operand" "")))
2537               (clobber (reg:SI T_REG))])]
2538   ""
2539   "
2541   if (TARGET_SHMEDIA)
2542     {
2543       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2544       DONE;
2545     }
2546   if (GET_CODE (operands[2]) == CONST_INT
2547       && sh_dynamicalize_shift_p (operands[2]))
2548     operands[2] = force_reg (SImode, operands[2]);
2549   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2550     {
2551       rtx count = copy_to_mode_reg (SImode, operands[2]);
2552       emit_insn (gen_negsi2 (count, count));
2553       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2554       DONE;
2555     }
2556   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2557     FAIL;
2560 ;; ??? This should be a define expand.
2562 (define_insn "ashldi3_k"
2563   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2564         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2565                    (const_int 1)))
2566    (clobber (reg:SI T_REG))]
2567   "TARGET_SH1"
2568   "shll %R0\;rotcl      %S0"
2569   [(set_attr "length" "4")
2570    (set_attr "type" "arith")])
2572 (define_insn "ashldi3_media"
2573   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2574         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2575                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2576   "TARGET_SHMEDIA"
2577   "@
2578         shlld   %1, %2, %0
2579         shlli   %1, %2, %0"
2580   [(set_attr "type" "arith_media")])
2582 (define_expand "ashldi3"
2583   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2584                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2585                               (match_operand:DI 2 "immediate_operand" "")))
2586               (clobber (reg:SI T_REG))])]
2587   ""
2588   "
2590   if (TARGET_SHMEDIA)
2591     {
2592       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2593       DONE;
2594     }
2595   if (GET_CODE (operands[2]) != CONST_INT
2596       || INTVAL (operands[2]) != 1)
2597     FAIL;
2600 ;; ??? This should be a define expand.
2602 (define_insn "lshrdi3_k"
2603   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2604         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2605                      (const_int 1)))
2606    (clobber (reg:SI T_REG))]
2607   "TARGET_SH1"
2608   "shlr %S0\;rotcr      %R0"
2609   [(set_attr "length" "4")
2610    (set_attr "type" "arith")])
2612 (define_insn "lshrdi3_media"
2613   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2614         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2615                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2616   "TARGET_SHMEDIA"
2617   "@
2618         shlrd   %1, %2, %0
2619         shlri   %1, %2, %0"
2620   [(set_attr "type" "arith_media")])
2622 (define_expand "lshrdi3"
2623   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2624                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2625                                (match_operand:DI 2 "immediate_operand" "")))
2626              (clobber (reg:SI T_REG))])]
2627   ""
2628   "
2630   if (TARGET_SHMEDIA)
2631     {
2632       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2633       DONE;
2634     }
2635   if (GET_CODE (operands[2]) != CONST_INT
2636       || INTVAL (operands[2]) != 1)
2637     FAIL;
2640 ;; ??? This should be a define expand.
2642 (define_insn "ashrdi3_k"
2643   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2644         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2645                      (const_int 1)))
2646    (clobber (reg:SI T_REG))]
2647   "TARGET_SH1"
2648   "shar %S0\;rotcr      %R0"
2649   [(set_attr "length" "4")
2650    (set_attr "type" "arith")])
2652 (define_insn "ashrdi3_media"
2653   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2654         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2655                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2656   "TARGET_SHMEDIA"
2657   "@
2658         shard   %1, %2, %0
2659         shari   %1, %2, %0"
2660   [(set_attr "type" "arith_media")])
2662 (define_expand "ashrdi3"
2663   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2664                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2665                                 (match_operand:DI 2 "immediate_operand" "")))
2666               (clobber (reg:SI T_REG))])]
2667   ""
2668   "
2670   if (TARGET_SHMEDIA)
2671     {
2672       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2673       DONE;
2674     }
2675   if (GET_CODE (operands[2]) != CONST_INT
2676       || INTVAL (operands[2]) != 1)
2677     FAIL;
2680 ;; combined left/right shift
2682 (define_split
2683   [(set (match_operand:SI 0 "register_operand" "")
2684         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2685                            (match_operand:SI 2 "const_int_operand" ""))
2686                 (match_operand:SI 3 "const_int_operand" "")))]
2687   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2688   [(use (reg:SI R0_REG))]
2689   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2690    DONE;")
2692 (define_split
2693   [(set (match_operand:SI 0 "register_operand" "")
2694         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2695                            (match_operand:SI 2 "const_int_operand" ""))
2696                 (match_operand:SI 3 "const_int_operand" "")))
2697    (clobber (reg:SI T_REG))]
2698   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2699   [(use (reg:SI R0_REG))]
2700   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2701    DONE;")
2703 (define_insn ""
2704   [(set (match_operand:SI 0 "register_operand" "=r")
2705         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2706                            (match_operand:SI 2 "const_int_operand" "n"))
2707                 (match_operand:SI 3 "const_int_operand" "n")))
2708    (clobber (reg:SI T_REG))]
2709   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2710  "#"
2711   [(set (attr "length")
2712         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2713                (const_string "4")
2714                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2715                (const_string "6")
2716                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2717                (const_string "8")
2718                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2719                (const_string "10")
2720                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2721                (const_string "12")
2722                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2723                (const_string "14")
2724                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2725                (const_string "16")]
2726               (const_string "18")))
2727    (set_attr "type" "arith")])
2729 (define_insn ""
2730   [(set (match_operand:SI 0 "register_operand" "=z")
2731         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2732                            (match_operand:SI 2 "const_int_operand" "n"))
2733                 (match_operand:SI 3 "const_int_operand" "n")))
2734    (clobber (reg:SI T_REG))]
2735   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2736  "#"
2737   [(set (attr "length")
2738         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2739                (const_string "4")
2740                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2741                (const_string "6")
2742                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2743                (const_string "8")]
2744               (const_string "10")))
2745    (set_attr "type" "arith")])
2747 ;; shift left / and combination with a scratch register: The combine pass
2748 ;; does not accept the individual instructions, even though they are
2749 ;; cheap.  But it needs a precise description so that it is usable after
2750 ;; reload.
2751 (define_insn "and_shl_scratch"
2752   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2753         (lshiftrt:SI
2754          (ashift:SI
2755           (and:SI
2756            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2757                         (match_operand:SI 2 "const_int_operand" "N,n"))
2758            (match_operand:SI 3 "" "0,r"))
2759           (match_operand:SI 4 "const_int_operand" "n,n"))
2760          (match_operand:SI 5 "const_int_operand" "n,n")))
2761    (clobber (reg:SI T_REG))]
2762   "TARGET_SH1"
2763   "#"
2764   [(set (attr "length")
2765         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2766                (const_string "4")
2767                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2768                (const_string "6")
2769                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2770                (const_string "8")
2771                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2772                (const_string "10")]
2773               (const_string "12")))
2774    (set_attr "type" "arith")])
2776 (define_split
2777   [(set (match_operand:SI 0 "register_operand" "")
2778         (lshiftrt:SI
2779          (ashift:SI
2780           (and:SI
2781            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2782                         (match_operand:SI 2 "const_int_operand" ""))
2783            (match_operand:SI 3 "register_operand" ""))
2784           (match_operand:SI 4 "const_int_operand" ""))
2785          (match_operand:SI 5 "const_int_operand" "")))
2786    (clobber (reg:SI T_REG))]
2787   "TARGET_SH1"
2788   [(use (reg:SI R0_REG))]
2789   "
2791   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2793   if (INTVAL (operands[2]))
2794     {
2795       gen_shifty_op (LSHIFTRT, operands);
2796     }
2797   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2798   operands[2] = operands[4];
2799   gen_shifty_op (ASHIFT, operands);
2800   if (INTVAL (operands[5]))
2801     {
2802       operands[2] = operands[5];
2803       gen_shifty_op (LSHIFTRT, operands);
2804     }
2805   DONE;
2808 ;; signed left/right shift combination.
2809 (define_split
2810   [(set (match_operand:SI 0 "register_operand" "")
2811         (sign_extract:SI
2812          (ashift:SI (match_operand:SI 1 "register_operand" "")
2813                     (match_operand:SI 2 "const_int_operand" ""))
2814          (match_operand:SI 3 "const_int_operand" "")
2815          (const_int 0)))
2816    (clobber (reg:SI T_REG))]
2817   "TARGET_SH1"
2818   [(use (reg:SI R0_REG))]
2819   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2820    DONE;")
2822 (define_insn "shl_sext_ext"
2823   [(set (match_operand:SI 0 "register_operand" "=r")
2824         (sign_extract:SI
2825          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2826                     (match_operand:SI 2 "const_int_operand" "n"))
2827          (match_operand:SI 3 "const_int_operand" "n")
2828          (const_int 0)))
2829    (clobber (reg:SI T_REG))]
2830   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2831   "#"
2832   [(set (attr "length")
2833         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2834                (const_string "2")
2835                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2836                (const_string "4")
2837                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2838                (const_string "6")
2839                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2840                (const_string "8")
2841                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2842                (const_string "10")
2843                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2844                (const_string "12")
2845                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2846                (const_string "14")
2847                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2848                (const_string "16")]
2849               (const_string "18")))
2850     (set_attr "type" "arith")])
2852 (define_insn "shl_sext_sub"
2853   [(set (match_operand:SI 0 "register_operand" "=z")
2854         (sign_extract:SI
2855          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2856                     (match_operand:SI 2 "const_int_operand" "n"))
2857          (match_operand:SI 3 "const_int_operand" "n")
2858          (const_int 0)))
2859    (clobber (reg:SI T_REG))]
2860   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2861   "#"
2862   [(set (attr "length")
2863         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2864                (const_string "6")
2865                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2866                (const_string "8")
2867                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2868                (const_string "10")
2869                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2870                (const_string "12")]
2871               (const_string "14")))
2872     (set_attr "type" "arith")])
2874 ;; These patterns are found in expansions of DImode shifts by 16, and
2875 ;; allow the xtrct instruction to be generated from C source.
2877 (define_insn "xtrct_left"
2878   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2879         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2880                            (const_int 16))
2881                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2882                              (const_int 16))))]
2883   "TARGET_SH1"
2884   "xtrct        %1,%0"
2885   [(set_attr "type" "arith")])
2887 (define_insn "xtrct_right"
2888   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2889         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2890                              (const_int 16))
2891                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2892                            (const_int 16))))]
2893   "TARGET_SH1"
2894   "xtrct        %2,%0"
2895   [(set_attr "type" "arith")])
2897 ;; -------------------------------------------------------------------------
2898 ;; Unary arithmetic
2899 ;; -------------------------------------------------------------------------
2901 (define_insn "negc"
2902   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2903         (neg:SI (plus:SI (reg:SI T_REG)
2904                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2905    (set (reg:SI T_REG)
2906         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2907                (const_int 0)))]
2908   "TARGET_SH1"
2909   "negc %1,%0"
2910   [(set_attr "type" "arith")])
2912 (define_insn "*negdi_media"
2913   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2914         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2915   "TARGET_SHMEDIA"
2916   "sub  r63, %1, %0"
2917   [(set_attr "type" "arith_media")])
2919 (define_expand "negdi2"
2920   [(set (match_operand:DI 0 "arith_reg_operand" "")
2921         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2922   ""
2923   "
2925   if (TARGET_SH1)
2926     {
2927       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2928       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2930       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2931       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2933       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2934       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2936       emit_insn (gen_clrt ());
2937       emit_insn (gen_negc (low_dst, low_src));
2938       emit_insn (gen_negc (high_dst, high_src));
2939       DONE;
2940     }
2943 (define_insn "negsi2"
2944   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2945         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2946   "TARGET_SH1"
2947   "neg  %1,%0"
2948   [(set_attr "type" "arith")])
2950 (define_insn "one_cmplsi2"
2951   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2952         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2953   "TARGET_SH1"
2954   "not  %1,%0"
2955   [(set_attr "type" "arith")])
2957 (define_expand "one_cmpldi2"
2958   [(set (match_operand:DI 0 "arith_reg_operand" "")
2959         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2960                 (const_int -1)))]
2961   "TARGET_SHMEDIA" "")
2963 ;; -------------------------------------------------------------------------
2964 ;; Zero extension instructions
2965 ;; -------------------------------------------------------------------------
2967 (define_insn "zero_extendsidi2"
2968   [(set (match_operand:DI 0 "register_operand" "=r")
2969         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2970   "TARGET_SHMEDIA"
2971   "addz.l       %1, r63, %0"
2972   [(set_attr "type" "arith_media")])
2974 (define_insn "zero_extendhidi2"
2975   [(set (match_operand:DI 0 "register_operand" "=r,r")
2976         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2977   "TARGET_SHMEDIA"
2978   "@
2979         #
2980         ld%M1.uw        %m1, %0"
2981   [(set_attr "type" "*,load_media")])
2983 (define_split
2984   [(set (match_operand:DI 0 "register_operand" "")
2985         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2986   "TARGET_SHMEDIA && reload_completed"
2987   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2988    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2989   "
2991   if (GET_CODE (operands[1]) == TRUNCATE)
2992     operands[1] = XEXP (operands[1], 0);
2995 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2996 ;; reload the entire truncate expression.
2997 (define_insn_and_split "*loaddi_trunc"
2998   [(set (match_operand 0 "int_gpr_dest" "=r")
2999         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3000   "TARGET_SHMEDIA && reload_completed"
3001   "#"
3002   "TARGET_SHMEDIA && reload_completed"
3003   [(set (match_dup 0) (match_dup 1))]
3004   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3006 (define_insn "zero_extendqidi2"
3007   [(set (match_operand:DI 0 "register_operand" "=r,r")
3008         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3009   "TARGET_SHMEDIA"
3010   "@
3011         andi    %1, 255, %0
3012         ld%M1.ub        %m1, %0"
3013   [(set_attr "type" "arith_media,load_media")])
3015 (define_expand "zero_extendhisi2"
3016   [(set (match_operand:SI 0 "arith_reg_operand" "")
3017         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3018   ""
3019   "
3021   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3022     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3025 (define_insn "*zero_extendhisi2_compact"
3026   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3027         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3028   "TARGET_SH1"
3029   "extu.w       %1,%0"
3030   [(set_attr "type" "arith")])
3032 (define_insn "*zero_extendhisi2_media"
3033   [(set (match_operand:SI 0 "register_operand" "=r,r")
3034         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3035   "TARGET_SHMEDIA"
3036   "@
3037         #
3038         ld%M1.uw        %m1, %0"
3039   [(set_attr "type" "arith_media,load_media")])
3041 (define_split
3042   [(set (match_operand:SI 0 "register_operand" "")
3043         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3044   "TARGET_SHMEDIA && reload_completed"
3045   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3046    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3047   "
3049   if (GET_CODE (operands[1]) == TRUNCATE)
3050     operands[1] = XEXP (operands[1], 0);
3053 (define_expand "zero_extendqisi2"
3054   [(set (match_operand:SI 0 "arith_reg_operand" "")
3055         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3056   ""
3057   "
3059   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3060     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3063 (define_insn "*zero_extendqisi2_compact"
3064   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3065         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3066   "TARGET_SH1"
3067   "extu.b       %1,%0"
3068   [(set_attr "type" "arith")])
3070 (define_insn "*zero_extendqisi2_media"
3071   [(set (match_operand:SI 0 "register_operand" "=r,r")
3072         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3073   "TARGET_SHMEDIA"
3074   "@
3075         andi    %1, 255, %0
3076         ld%M1.ub        %m1, %0"
3077   [(set_attr "type" "arith_media,load_media")])
3079 (define_insn "zero_extendqihi2"
3080   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3081         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3082   "TARGET_SH1"
3083   "extu.b       %1,%0"
3084   [(set_attr "type" "arith")])
3086 ;; -------------------------------------------------------------------------
3087 ;; Sign extension instructions
3088 ;; -------------------------------------------------------------------------
3090 ;; ??? This should be a define expand.
3091 ;; ??? Or perhaps it should be dropped?
3093 ;; convert_move generates good code for SH[1-4].
3094 (define_insn "extendsidi2"
3095   [(set (match_operand:DI 0 "register_operand" "=r,r")
3096         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3097   "TARGET_SHMEDIA"
3098   "@
3099         add.l   %1, r63, %0
3100         ld%M1.l %m1, %0"
3101   [(set_attr "type" "arith_media,load_media")])
3103 (define_insn "extendhidi2"
3104   [(set (match_operand:DI 0 "register_operand" "=r,r")
3105         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3106   "TARGET_SHMEDIA"
3107   "@
3108         #
3109         ld%M1.w %m1, %0"
3110   [(set_attr "type" "*,load_media")])
3112 (define_split
3113   [(set (match_operand:DI 0 "register_operand" "")
3114         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3115   "TARGET_SHMEDIA && reload_completed"
3116   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3117    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3118   "
3120   if (GET_CODE (operands[1]) == TRUNCATE)
3121     operands[1] = XEXP (operands[1], 0);
3124 (define_insn "extendqidi2"
3125   [(set (match_operand:DI 0 "register_operand" "=r,r")
3126         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3127   "TARGET_SHMEDIA"
3128   "@
3129         #
3130         ld%M1.b %m1, %0"
3131   [(set_attr "type" "*,load_media")])
3133 (define_split
3134   [(set (match_operand:DI 0 "register_operand" "")
3135         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3136   "TARGET_SHMEDIA && reload_completed"
3137   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3138    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3139   "
3141   if (GET_CODE (operands[1]) == TRUNCATE)
3142     operands[1] = XEXP (operands[1], 0);
3145 (define_expand "extendhisi2"
3146   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3147         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3148   ""
3149   "")
3151 (define_insn "*extendhisi2_compact"
3152   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3153         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3154   "TARGET_SH1"
3155   "@
3156         exts.w  %1,%0
3157         mov.w   %1,%0"
3158   [(set_attr "type" "arith,load")])
3160 (define_insn "*extendhisi2_media"
3161   [(set (match_operand:SI 0 "register_operand" "=r,r")
3162         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3163   "TARGET_SHMEDIA"
3164   "@
3165         #
3166         ld%M1.w %m1, %0"
3167   [(set_attr "type" "arith_media,load_media")])
3169 (define_split
3170   [(set (match_operand:SI 0 "register_operand" "")
3171         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3172   "TARGET_SHMEDIA && reload_completed"
3173   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3174    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3175   "
3177   if (GET_CODE (operands[1]) == TRUNCATE)
3178     operands[1] = XEXP (operands[1], 0);
3181 (define_expand "extendqisi2"
3182   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3183         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3184   ""
3185   "")
3187 (define_insn "*extendqisi2_compact"
3188   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3189         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3190   "TARGET_SH1"
3191   "@
3192         exts.b  %1,%0
3193         mov.b   %1,%0"
3194   [(set_attr "type" "arith,load")])
3196 (define_insn "*extendqisi2_media"
3197   [(set (match_operand:SI 0 "register_operand" "=r,r")
3198         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3199   "TARGET_SHMEDIA"
3200   "@
3201         #
3202         ld%M1.b %m1, %0"
3203   [(set_attr "type" "arith_media,load_media")])
3205 (define_split
3206   [(set (match_operand:SI 0 "register_operand" "")
3207         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3208   "TARGET_SHMEDIA && reload_completed"
3209   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3210    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3211    "
3213   if (GET_CODE (operands[1]) == TRUNCATE)
3214     operands[1] = XEXP (operands[1], 0);
3217 (define_insn "extendqihi2"
3218   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3219         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3220   "TARGET_SH1"
3221   "@
3222         exts.b  %1,%0
3223         mov.b   %1,%0"
3224   [(set_attr "type" "arith,load")])
3226 /* It would seem useful to combine the truncXi patterns into the movXi
3227    patterns, but unary operators are ignored when matching constraints,
3228    so we need separate patterns.  */
3229 (define_insn "truncdisi2"
3230   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3231         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3232   "TARGET_SHMEDIA"
3233   "@
3234         add.l   %1, r63, %0
3235         st%M0.l %m0, %1
3236         fst%M0.s        %m0, %T1
3237         fmov.ls %1, %0
3238         fmov.sl %T1, %0
3239         fmov.s  %T1, %0"
3240   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3243 (define_insn "truncdihi2"
3244   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3245         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3246   "TARGET_SHMEDIA"
3247   "@
3248         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3249         st%M0.w %m0, %1"
3250   [(set_attr "type"   "arith_media,store_media")
3251    (set_attr "length" "8,4")])
3253 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3254 ; Because we use zero extension, we can't provide signed QImode compares
3255 ; using a simple compare or conditional banch insn.
3256 (define_insn "truncdiqi2"
3257   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3258         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3259   "TARGET_SHMEDIA"
3260   "@
3261         andi    %1, 255, %0
3262         st%M0.b %m0, %1"
3263   [(set_attr "type"   "arith_media,store")])
3265 ;; -------------------------------------------------------------------------
3266 ;; Move instructions
3267 ;; -------------------------------------------------------------------------
3269 ;; define push and pop so it is easy for sh.c
3270 ;; We can't use push and pop on SHcompact because the stack must always
3271 ;; be 8-byte aligned.
3273 (define_expand "push"
3274   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3275         (match_operand:SI 0 "register_operand" "r,l,x"))]
3276   "TARGET_SH1 && ! TARGET_SH5"
3277   "")
3279 (define_expand "pop"
3280   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3281         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3282   "TARGET_SH1 && ! TARGET_SH5"
3283   "")
3285 (define_expand "push_e"
3286   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3287                    (match_operand:SF 0 "" ""))
3288               (use (reg:PSI FPSCR_REG))
3289               (clobber (scratch:SI))])]
3290   "TARGET_SH1 && ! TARGET_SH5"
3291   "")
3293 (define_insn "push_fpul"
3294   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3295   "TARGET_SH2E && ! TARGET_SH5"
3296   "sts.l        fpul,@-r15"
3297   [(set_attr "type" "store")
3298    (set_attr "late_fp_use" "yes")
3299    (set_attr "hit_stack" "yes")])
3301 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3302 ;; so use that.
3303 (define_expand "push_4"
3304   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3305                    (match_operand:DF 0 "" ""))
3306               (use (reg:PSI FPSCR_REG))
3307               (clobber (scratch:SI))])]
3308   "TARGET_SH1 && ! TARGET_SH5"
3309   "")
3311 (define_expand "pop_e"
3312   [(parallel [(set (match_operand:SF 0 "" "")
3313               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3314               (use (reg:PSI FPSCR_REG))
3315               (clobber (scratch:SI))])]
3316   "TARGET_SH1 && ! TARGET_SH5"
3317   "")
3319 (define_insn "pop_fpul"
3320   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3321   "TARGET_SH2E && ! TARGET_SH5"
3322   "lds.l        @r15+,fpul"
3323   [(set_attr "type" "load")
3324    (set_attr "hit_stack" "yes")])
3326 (define_expand "pop_4"
3327   [(parallel [(set (match_operand:DF 0 "" "")
3328                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3329               (use (reg:PSI FPSCR_REG))
3330               (clobber (scratch:SI))])]
3331   "TARGET_SH1 && ! TARGET_SH5"
3332   "")
3334 (define_expand "push_fpscr"
3335   [(const_int 0)]
3336   "TARGET_SH2E"
3337   "
3339   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3340                                                  gen_rtx_PRE_DEC (Pmode,
3341                                                           stack_pointer_rtx)),
3342                                         get_fpscr_rtx ()));
3343   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3344   DONE;
3347 (define_expand "pop_fpscr"
3348   [(const_int 0)]
3349   "TARGET_SH2E"
3350   "
3352   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3353                                         gen_rtx_MEM (PSImode,
3354                                                  gen_rtx_POST_INC (Pmode,
3355                                                           stack_pointer_rtx))));
3356   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3357   DONE;
3360 ;; These two patterns can happen as the result of optimization, when
3361 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3362 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3364 (define_insn "clrt"
3365   [(set (reg:SI T_REG) (const_int 0))]
3366   "TARGET_SH1"
3367   "clrt")
3369 (define_insn "sett"
3370   [(set (reg:SI T_REG) (const_int 1))]
3371   "TARGET_SH1"
3372   "sett")
3374 ;; t/r must come after r/r, lest reload will try to reload stuff like
3375 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3376 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3377 (define_insn "movsi_i"
3378   [(set (match_operand:SI 0 "general_movdst_operand"
3379             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3380         (match_operand:SI 1 "general_movsrc_operand"
3381          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3382   "TARGET_SH1
3383    && ! TARGET_SH2E
3384    && ! TARGET_SH2A
3385    && (register_operand (operands[0], SImode)
3386        || register_operand (operands[1], SImode))"
3387   "@
3388         mov.l   %1,%0
3389         mov     %1,%0
3390         cmp/pl  %1
3391         mov.l   %1,%0
3392         sts     %1,%0
3393         sts     %1,%0
3394         movt    %0
3395         mov.l   %1,%0
3396         sts.l   %1,%0
3397         sts.l   %1,%0
3398         lds     %1,%0
3399         lds     %1,%0
3400         lds.l   %1,%0
3401         lds.l   %1,%0
3402         fake    %1,%0"
3403   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3404    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3406 ;; t/r must come after r/r, lest reload will try to reload stuff like
3407 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3408 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3409 ;; will require a reload.
3410 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3411 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3412 (define_insn "movsi_ie"
3413   [(set (match_operand:SI 0 "general_movdst_operand"
3414             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3415         (match_operand:SI 1 "general_movsrc_operand"
3416          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3417   "(TARGET_SH2E || TARGET_SH2A)
3418    && (register_operand (operands[0], SImode)
3419        || register_operand (operands[1], SImode))"
3420   "@
3421         mov.l   %1,%0
3422         mov     %1,%0
3423         movi20  %1,%0
3424         cmp/pl  %1
3425         mov.l   %1,%0
3426         sts     %1,%0
3427         sts     %1,%0
3428         movt    %0
3429         mov.l   %1,%0
3430         sts.l   %1,%0
3431         sts.l   %1,%0
3432         lds     %1,%0
3433         lds     %1,%0
3434         lds.l   %1,%0
3435         lds.l   %1,%0
3436         lds.l   %1,%0
3437         sts.l   %1,%0
3438         fake    %1,%0
3439         lds     %1,%0
3440         sts     %1,%0
3441         fsts    fpul,%0
3442         flds    %1,fpul
3443         fmov    %1,%0
3444         ! move optimized away"
3445   [(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")
3446    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3447    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3449 (define_insn "movsi_i_lowpart"
3450   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3451         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3452    "TARGET_SH1
3453     && (register_operand (operands[0], SImode)
3454         || register_operand (operands[1], SImode))"
3455   "@
3456         mov.l   %1,%0
3457         mov     %1,%0
3458         mov.l   %1,%0
3459         sts     %1,%0
3460         sts     %1,%0
3461         movt    %0
3462         mov.l   %1,%0
3463         fake    %1,%0"
3464   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3466 (define_insn_and_split "load_ra"
3467   [(set (match_operand:SI 0 "general_movdst_operand" "")
3468         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3469   "TARGET_SH1"
3470   "#"
3471   "&& ! currently_expanding_to_rtl"
3472   [(set (match_dup 0) (match_dup 1))]
3473   "
3475   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3476     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3479 (define_insn "*movsi_media"
3480   [(set (match_operand:SI 0 "general_movdst_operand"
3481                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3482         (match_operand:SI 1 "general_movsrc_operand"
3483          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3484   "TARGET_SHMEDIA_FPU
3485    && (register_operand (operands[0], SImode)
3486        || sh_register_operand (operands[1], SImode))"
3487   "@
3488         add.l   %1, r63, %0
3489         movi    %1, %0
3490         #
3491         ld%M1.l %m1, %0
3492         st%M0.l %m0, %N1
3493         fld%M1.s        %m1, %0
3494         fst%M0.s        %m0, %1
3495         fmov.ls %N1, %0
3496         fmov.sl %1, %0
3497         fmov.s  %1, %0
3498         ptabs   %1, %0
3499         gettr   %1, %0
3500         pt      %1, %0"
3501   [(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")
3502    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3504 (define_insn "*movsi_media_nofpu"
3505   [(set (match_operand:SI 0 "general_movdst_operand"
3506                 "=r,r,r,r,m,*b,r,b")
3507         (match_operand:SI 1 "general_movsrc_operand"
3508          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3509   "TARGET_SHMEDIA
3510    && (register_operand (operands[0], SImode)
3511        || sh_register_operand (operands[1], SImode))"
3512   "@
3513         add.l   %1, r63, %0
3514         movi    %1, %0
3515         #
3516         ld%M1.l %m1, %0
3517         st%M0.l %m0, %N1
3518         ptabs   %1, %0
3519         gettr   %1, %0
3520         pt      %1, %0"
3521   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3522    (set_attr "length" "4,4,8,4,4,4,4,12")])
3524 (define_split
3525   [(set (match_operand:SI 0 "arith_reg_operand" "")
3526         (match_operand:SI 1 "immediate_operand" ""))]
3527   "TARGET_SHMEDIA && reload_completed
3528    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3529   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3530   "
3532   operands[2] = shallow_copy_rtx (operands[1]);
3533   PUT_MODE (operands[2], DImode);
3536 (define_split
3537   [(set (match_operand:SI 0 "register_operand" "")
3538         (match_operand:SI 1 "immediate_operand" ""))]
3539   "TARGET_SHMEDIA && reload_completed
3540    && ((GET_CODE (operands[1]) == CONST_INT
3541         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3542        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3543   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3545 (define_expand "movsi"
3546   [(set (match_operand:SI 0 "general_movdst_operand" "")
3547         (match_operand:SI 1 "general_movsrc_operand" ""))]
3548   ""
3549   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3551 (define_expand "ic_invalidate_line"
3552   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3553                                 (match_dup 1)] UNSPEC_ICACHE)
3554               (clobber (scratch:SI))])]
3555   "TARGET_HARD_SH4 || TARGET_SH5"
3556   "
3558   if (TARGET_SHMEDIA)
3559     {
3560       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3561       DONE;
3562     }
3563   else if (TARGET_SHCOMPACT)
3564     {
3565       operands[1] = function_symbol (\"__ic_invalidate\");
3566       operands[1] = force_reg (Pmode, operands[1]);
3567       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3568       DONE;
3569     }
3570   else if (TARGET_SH4A_ARCH)
3571     {
3572       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3573       DONE;
3574     }
3575   operands[0] = force_reg (Pmode, operands[0]);
3576   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3577                                                                Pmode)));
3580 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3581 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3582 ;; the requirement *1*00 for associative address writes.  The alignment of
3583 ;; %0 implies that its least significant bit is cleared,
3584 ;; thus we clear the V bit of a matching entry if there is one.
3585 (define_insn "ic_invalidate_line_i"
3586   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3587                      (match_operand:SI 1 "register_operand" "r")]
3588                      UNSPEC_ICACHE)
3589    (clobber (match_scratch:SI 2 "=&r"))]
3590   "TARGET_HARD_SH4"
3591   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3592   [(set_attr "length" "8")
3593    (set_attr "type" "cwb")])
3595 (define_insn "ic_invalidate_line_sh4a"
3596   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3597                     UNSPEC_ICACHE)]
3598   "TARGET_SH4A_ARCH"
3599   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3600   [(set_attr "length" "16")
3601    (set_attr "type" "cwb")])
3603 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3604 ;; an add in the code that calculates the address.
3605 (define_insn "ic_invalidate_line_media"
3606   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3607                     UNSPEC_ICACHE)]
3608   "TARGET_SHMEDIA"
3609   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3610   [(set_attr "length" "16")
3611    (set_attr "type" "invalidate_line_media")])
3613 (define_insn "ic_invalidate_line_compact"
3614   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3615                      (match_operand:SI 1 "register_operand" "r")]
3616                     UNSPEC_ICACHE)
3617    (clobber (reg:SI PR_REG))]
3618   "TARGET_SHCOMPACT"
3619   "jsr @%1%#"
3620   [(set_attr "type" "sfunc")
3621    (set_attr "needs_delay_slot" "yes")])
3623 (define_expand "initialize_trampoline"
3624   [(match_operand:SI 0 "" "")
3625    (match_operand:SI 1 "" "")
3626    (match_operand:SI 2 "" "")]
3627   "TARGET_SHCOMPACT"
3628   "
3630   rtx sfun, tramp;
3632   tramp = force_reg (Pmode, operands[0]);
3633   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3634   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3635   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3637   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3638   DONE;
3641 (define_insn "initialize_trampoline_compact"
3642   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3643                      (match_operand:SI 1 "register_operand" "r")
3644                      (reg:SI R2_REG) (reg:SI R3_REG)]
3645                     UNSPEC_INIT_TRAMP)
3647    (clobber (reg:SI PR_REG))]
3648   "TARGET_SHCOMPACT"
3649   "jsr @%1%#"
3650   [(set_attr "type" "sfunc")
3651    (set_attr "needs_delay_slot" "yes")])
3653 (define_insn "movqi_i"
3654   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3655         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3656   "TARGET_SH1
3657    && (arith_reg_operand (operands[0], QImode)
3658        || arith_reg_operand (operands[1], QImode))"
3659   "@
3660         mov     %1,%0
3661         mov.b   %1,%0
3662         mov.b   %1,%0
3663         movt    %0
3664         sts     %1,%0
3665         lds     %1,%0"
3666  [(set_attr "type" "move,load,store,move,move,move")])
3668 (define_insn "*movqi_media"
3669   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3670         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3671   "TARGET_SHMEDIA
3672    && (arith_reg_operand (operands[0], QImode)
3673        || arith_reg_or_0_operand (operands[1], QImode))"
3674   "@
3675         add.l   %1, r63, %0
3676         movi    %1, %0
3677         ld%M1.ub        %m1, %0
3678         st%M0.b %m0, %N1"
3679   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3681 (define_expand "movqi"
3682   [(set (match_operand:QI 0 "general_operand" "")
3683         (match_operand:QI 1 "general_operand"  ""))]
3684   ""
3685   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3687 (define_expand "reload_inqi"
3688   [(set (match_operand:SI 2 "" "=&r")
3689         (match_operand:QI 1 "inqhi_operand" ""))
3690    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3691         (truncate:QI (match_dup 3)))]
3692   "TARGET_SHMEDIA"
3693   "
3695   rtx inner = XEXP (operands[1], 0);
3696   int regno = REGNO (inner);
3698   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3699   operands[1] = gen_rtx_REG (SImode, regno);
3700   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3703 /* When storing r0, we have to avoid reg+reg addressing.  */
3704 (define_insn "movhi_i"
3705   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3706         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3707   "TARGET_SH1
3708    && (arith_reg_operand (operands[0], HImode)
3709        || arith_reg_operand (operands[1], HImode))
3710    && (GET_CODE (operands[0]) != MEM
3711        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3712        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3713        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3714   "@
3715         mov.w   %1,%0
3716         mov     %1,%0
3717         mov.w   %1,%0
3718         movt    %0
3719         mov.w   %1,%0
3720         sts     %1,%0
3721         lds     %1,%0
3722         fake    %1,%0"
3723   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3725 (define_insn "*movhi_media"
3726   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3727         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3728   "TARGET_SHMEDIA
3729    && (arith_reg_operand (operands[0], HImode)
3730        || arith_reg_or_0_operand (operands[1], HImode))"
3731   "@
3732         add.l   %1, r63, %0
3733         movi    %1, %0
3734         #
3735         ld%M1.w %m1, %0
3736         st%M0.w %m0, %N1"
3737   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3739 (define_split
3740   [(set (match_operand:HI 0 "register_operand" "")
3741         (match_operand:HI 1 "immediate_operand" ""))]
3742   "TARGET_SHMEDIA && reload_completed
3743    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3744   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3746 (define_expand "movhi"
3747   [(set (match_operand:HI 0 "general_movdst_operand" "")
3748         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3749   ""
3750   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3752 (define_expand "reload_inhi"
3753   [(set (match_operand:SI 2 "" "=&r")
3754         (match_operand:HI 1 "inqhi_operand" ""))
3755    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3756         (truncate:HI (match_dup 3)))]
3757   "TARGET_SHMEDIA"
3758   "
3760   rtx inner = XEXP (operands[1], 0);
3761   int regno = REGNO (inner);
3763   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3764   operands[1] = gen_rtx_REG (SImode, regno);
3765   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3768 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3769 ;; compiled with -m2 -ml -O3 -funroll-loops
3770 (define_insn "*movdi_i"
3771   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3772         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3773   "TARGET_SH1
3774    && (arith_reg_operand (operands[0], DImode)
3775        || arith_reg_operand (operands[1], DImode))"
3776   "* return output_movedouble (insn, operands, DImode);"
3777   [(set_attr "length" "4")
3778    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3780 ;; If the output is a register and the input is memory or a register, we have
3781 ;; to be careful and see which word needs to be loaded first.
3783 (define_split
3784   [(set (match_operand:DI 0 "general_movdst_operand" "")
3785         (match_operand:DI 1 "general_movsrc_operand" ""))]
3786   "TARGET_SH1 && reload_completed"
3787   [(set (match_dup 2) (match_dup 3))
3788    (set (match_dup 4) (match_dup 5))]
3789   "
3791   int regno;
3793   if ((GET_CODE (operands[0]) == MEM
3794        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3795       || (GET_CODE (operands[1]) == MEM
3796           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3797     FAIL;
3799   if (GET_CODE (operands[0]) == REG)
3800     regno = REGNO (operands[0]);
3801   else if (GET_CODE (operands[0]) == SUBREG)
3802     regno = subreg_regno (operands[0]);
3803   else if (GET_CODE (operands[0]) == MEM)
3804     regno = -1;
3805   else
3806     abort ();
3808   if (regno == -1
3809       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3810     {
3811       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3812       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3813       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3814       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3815     }
3816   else
3817     {
3818       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3819       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3820       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3821       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3822     }
3824   if (operands[2] == 0 || operands[3] == 0
3825       || operands[4] == 0 || operands[5] == 0)
3826     FAIL;
3829 (define_insn "*movdi_media"
3830   [(set (match_operand:DI 0 "general_movdst_operand"
3831                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3832         (match_operand:DI 1 "general_movsrc_operand"
3833          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3834   "TARGET_SHMEDIA_FPU
3835    && (register_operand (operands[0], DImode)
3836        || sh_register_operand (operands[1], DImode))"
3837   "@
3838         add     %1, r63, %0
3839         movi    %1, %0
3840         #
3841         ld%M1.q %m1, %0
3842         st%M0.q %m0, %N1
3843         fld%M1.d        %m1, %0
3844         fst%M0.d        %m0, %1
3845         fmov.qd %N1, %0
3846         fmov.dq %1, %0
3847         fmov.d  %1, %0
3848         ptabs   %1, %0
3849         gettr   %1, %0
3850         pt      %1, %0"
3851   [(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")
3852    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3854 (define_insn "*movdi_media_nofpu"
3855   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3856         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3857   "TARGET_SHMEDIA
3858    && (register_operand (operands[0], DImode)
3859        || sh_register_operand (operands[1], DImode))"
3860   "@
3861         add     %1, r63, %0
3862         movi    %1, %0
3863         #
3864         ld%M1.q %m1, %0
3865         st%M0.q %m0, %N1
3866         ptabs   %1, %0
3867         gettr   %1, %0
3868         pt      %1, %0"
3869   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3870    (set_attr "length" "4,4,16,4,4,4,4,*")])
3872 (define_split
3873   [(set (match_operand:DI 0 "arith_reg_operand" "")
3874         (match_operand:DI 1 "immediate_operand" ""))]
3875   "TARGET_SHMEDIA && reload_completed
3876    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3877   [(set (match_dup 0) (match_dup 1))]
3878   "
3880   rtx insn;
3882   if (TARGET_SHMEDIA64)
3883     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3884   else
3885     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3887   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3888                                         REG_NOTES (insn));
3890   DONE;
3893 (define_expand "movdi_const"
3894   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3895         (const:DI (sign_extend:DI
3896                    (truncate:HI
3897                     (ashiftrt:DI
3898                      (match_operand:DI 1 "immediate_operand" "s")
3899                      (const_int 48))))))
3900    (set (match_dup 0)
3901         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3902                 (zero_extend:DI
3903                  (truncate:HI
3904                   (const:DI
3905                    (sign_extend:DI
3906                     (truncate:HI
3907                      (ashiftrt:SI
3908                       (match_dup 1)
3909                       (const_int 32)))))))))
3910    (set (match_dup 0)
3911         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3912                 (zero_extend:DI
3913                  (truncate:HI
3914                   (const:DI
3915                    (sign_extend:DI
3916                     (truncate:HI
3917                      (ashiftrt:SI
3918                       (match_dup 1)
3919                       (const_int 16)))))))))
3920    (set (match_dup 0)
3921         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3922                 (zero_extend:DI
3923                  (truncate:HI
3924                   (const:DI
3925                    (sign_extend:DI
3926                     (truncate:HI
3927                      (match_dup 1))))))))]
3928   "TARGET_SHMEDIA64 && reload_completed
3929    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3930   "
3932   sh_mark_label (operands[1], 4);
3935 (define_expand "movdi_const_32bit"
3936   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3937         (const:DI (sign_extend:DI
3938                    (truncate:HI
3939                     (ashiftrt:DI
3940                      (match_operand:DI 1 "immediate_operand" "s")
3941                      (const_int 16))))))
3942    (set (match_dup 0)
3943         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3944                 (zero_extend:DI
3945                  (truncate:HI
3946                   (const:DI
3947                    (sign_extend:DI
3948                     (truncate:HI
3949                      (match_dup 1))))))))]
3950   "TARGET_SHMEDIA32 && reload_completed
3951    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3952   "
3954   sh_mark_label (operands[1], 2);
3957 (define_expand "movdi_const_16bit"
3958   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3959         (const:DI (sign_extend:DI
3960                    (truncate:HI
3961                     (match_operand:DI 1 "immediate_operand" "s")))))]
3962   "TARGET_SHMEDIA && flag_pic && reload_completed
3963    && GET_CODE (operands[1]) == SYMBOL_REF"
3964   "")
3966 (define_split
3967   [(set (match_operand:DI 0 "arith_reg_operand" "")
3968         (match_operand:DI 1 "immediate_operand" ""))]
3969   "TARGET_SHMEDIA && reload_completed
3970    && GET_CODE (operands[1]) == CONST_INT
3971    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3972   [(set (match_dup 0) (match_dup 2))
3973    (match_dup 1)]
3974   "
3976   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3977   unsigned HOST_WIDE_INT low = val;
3978   unsigned HOST_WIDE_INT high = val;
3979   unsigned HOST_WIDE_INT sign;
3980   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3982   /* Sign-extend the 16 least-significant bits.  */
3983   low &= 0xffff;
3984   low ^= 0x8000;
3985   low -= 0x8000;
3987   /* Arithmetic shift right the word by 16 bits.  */
3988   high >>= 16;
3989   sign = 1;
3990   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3991   high ^= sign;
3992   high -= sign;
3993   do
3994     {
3995       /* If we can't generate the constant with a two-insn movi / shori
3996          sequence, try some other strategies.  */
3997       if (! CONST_OK_FOR_I16 (high))
3998         {
3999           /* Try constant load / left shift.  We know VAL != 0.  */
4000           val2 = val ^ (val-1);
4001           if (val2 > 0x1ffff)
4002             {
4003               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4005               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4006                   || (! CONST_OK_FOR_I16 (high >> 16)
4007                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4008                 {
4009                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4010                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4011                                                    GEN_INT (trailing_zeroes));
4012                   break;
4013                 }
4014             }
4015           /* Try constant load / right shift.  */
4016           val2 = (val >> 15) + 1;
4017           if (val2 == (val2 & -val2))
4018             {
4019               int shift = 49 - exact_log2 (val2);
4021               val2 = trunc_int_for_mode (val << shift, DImode);
4022               if (CONST_OK_FOR_I16 (val2))
4023                 {
4024                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4025                                                    GEN_INT (shift));
4026                   break;
4027                 }
4028             }
4029           /* Try mperm.w .  */
4030           val2 = val & 0xffff;
4031           if ((val >> 16 & 0xffff) == val2
4032               && (val >> 32 & 0xffff) == val2
4033               && (val >> 48 & 0xffff) == val2)
4034             {
4035               val2 = (HOST_WIDE_INT) val >> 48;
4036               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4037               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4038               break;
4039             }
4040           /* Try movi / mshflo.l  */
4041           val2 = (HOST_WIDE_INT) val >> 32;
4042           if (val2 == ((unsigned HOST_WIDE_INT)
4043                         trunc_int_for_mode (val, SImode)))
4044             {
4045               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4046                                              operands[0]);
4047               break;
4048             }
4049           /* Try movi / mshflo.l w/ r63.  */
4050           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4051           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4052             {
4053               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4054                                              const0_rtx);
4055               break;
4056             }
4057         }
4058       val2 = high;
4059       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4060     }
4061   while (0);
4062   operands[2] = GEN_INT (val2);
4065 (define_split
4066   [(set (match_operand:DI 0 "arith_reg_operand" "")
4067         (match_operand:DI 1 "immediate_operand" ""))]
4068   "TARGET_SHMEDIA && reload_completed
4069    && GET_CODE (operands[1]) == CONST_DOUBLE"
4070   [(set (match_dup 0) (match_dup 2))
4071   (set (match_dup 0)
4072        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4073                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4074   "
4076   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4077   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4078   unsigned HOST_WIDE_INT val = low;
4079   unsigned HOST_WIDE_INT sign;
4081   /* Sign-extend the 16 least-significant bits.  */
4082   val &= 0xffff;
4083   val ^= 0x8000;
4084   val -= 0x8000;
4085   operands[1] = GEN_INT (val);
4087   /* Arithmetic shift right the double-word by 16 bits.  */
4088   low >>= 16;
4089   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4090   high >>= 16;
4091   sign = 1;
4092   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4093   high ^= sign;
4094   high -= sign;
4096   /* This will only be true if high is a sign-extension of low, i.e.,
4097      it must be either 0 or (unsigned)-1, and be zero iff the
4098      most-significant bit of low is set.  */
4099   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4100     operands[2] = GEN_INT (low);
4101   else
4102     operands[2] = immed_double_const (low, high, DImode);
4105 (define_insn "shori_media"
4106   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4107         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4108                            (const_int 16))
4109                 (zero_extend:DI
4110                  (truncate:HI
4111                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4112   "TARGET_SHMEDIA"
4113   "@
4114         shori   %u2, %0
4115         #"
4116   [(set_attr "type" "arith_media,*")])
4118 (define_expand "movdi"
4119   [(set (match_operand:DI 0 "general_movdst_operand" "")
4120         (match_operand:DI 1 "general_movsrc_operand" ""))]
4121   ""
4122   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4124 (define_insn "movdf_media"
4125   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4126         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4127   "TARGET_SHMEDIA_FPU
4128    && (register_operand (operands[0], DFmode)
4129        || sh_register_operand (operands[1], DFmode))"
4130   "@
4131         fmov.d  %1, %0
4132         fmov.qd %N1, %0
4133         fmov.dq %1, %0
4134         add     %1, r63, %0
4135         #
4136         fld%M1.d        %m1, %0
4137         fst%M0.d        %m0, %1
4138         ld%M1.q %m1, %0
4139         st%M0.q %m0, %N1"
4140   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4142 (define_insn "movdf_media_nofpu"
4143   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4144         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4145   "TARGET_SHMEDIA
4146    && (register_operand (operands[0], DFmode)
4147        || sh_register_operand (operands[1], DFmode))"
4148   "@
4149         add     %1, r63, %0
4150         #
4151         ld%M1.q %m1, %0
4152         st%M0.q %m0, %N1"
4153   [(set_attr "type" "arith_media,*,load_media,store_media")])
4155 (define_split
4156   [(set (match_operand:DF 0 "arith_reg_operand" "")
4157         (match_operand:DF 1 "immediate_operand" ""))]
4158   "TARGET_SHMEDIA && reload_completed"
4159   [(set (match_dup 3) (match_dup 2))]
4160   "
4162   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4163   long values[2];
4164   REAL_VALUE_TYPE value;
4166   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4167   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4169   if (HOST_BITS_PER_WIDE_INT >= 64)
4170     operands[2] = immed_double_const ((unsigned long) values[endian]
4171                                       | ((HOST_WIDE_INT) values[1 - endian]
4172                                          << 32), 0, DImode);
4173   else if (HOST_BITS_PER_WIDE_INT == 32)
4174     operands[2] = immed_double_const (values[endian], values[1 - endian],
4175                                       DImode);
4176   else
4177     abort ();
4179   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4182 ;; ??? This should be a define expand.
4184 (define_insn "movdf_k"
4185   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4186         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4187   "TARGET_SH1
4188    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
4189        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4190        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4191        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4192    && (arith_reg_operand (operands[0], DFmode)
4193        || arith_reg_operand (operands[1], DFmode))"
4194   "* return output_movedouble (insn, operands, DFmode);"
4195   [(set_attr "length" "4")
4196    (set_attr "type" "move,pcload,load,store")])
4198 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4199 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4200 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4201 ;; the d/m/c/X alternative, which is split later into single-precision
4202 ;; instructions.  And when not optimizing, no splits are done before fixing
4203 ;; up pcloads, so we need usable length information for that.
4204 (define_insn "movdf_i4"
4205   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4206         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4207    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4208    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4209   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4210    && (arith_reg_operand (operands[0], DFmode)
4211        || arith_reg_operand (operands[1], DFmode))"
4212   "@
4213         fmov    %1,%0
4214         #
4215         #
4216         fmov.d  %1,%0
4217         fmov.d  %1,%0
4218         #
4219         #
4220         #
4221         #
4222         #"
4223   [(set_attr_alternative "length"
4224      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4225       (const_int 4)
4226       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4227       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4228       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4229       (const_int 4)
4230       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4231       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4232       ;; increment or decrement r15 explicitly.
4233       (if_then_else
4234        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4235        (const_int 10) (const_int 8))
4236       (if_then_else
4237        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4238        (const_int 10) (const_int 8))])
4239    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4240    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4241    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4242                                            (const_string "double")
4243                                            (const_string "none")))])
4245 ;; Moving DFmode between fp/general registers through memory
4246 ;; (the top of the stack) is faster than moving through fpul even for
4247 ;; little endian.  Because the type of an instruction is important for its
4248 ;; scheduling,  it is beneficial to split these operations, rather than
4249 ;; emitting them in one single chunk, even if this will expose a stack
4250 ;; use that will prevent scheduling of other stack accesses beyond this
4251 ;; instruction.
4252 (define_split
4253   [(set (match_operand:DF 0 "register_operand" "")
4254         (match_operand:DF 1 "register_operand" ""))
4255    (use (match_operand:PSI 2 "fpscr_operand" ""))
4256    (clobber (match_scratch:SI 3 "=X"))]
4257   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
4258    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4259   [(const_int 0)]
4260   "
4262   rtx insn, tos;
4264   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4265     {
4266       emit_move_insn (stack_pointer_rtx,
4267                       plus_constant (stack_pointer_rtx, -8));
4268       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4269     }
4270   else
4271     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4272   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4273   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4274     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4275   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4276     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4277   else
4278     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4279   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4280   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4281     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4282   else
4283     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4284   DONE;
4287 ;; local-alloc sometimes allocates scratch registers even when not required,
4288 ;; so we must be prepared to handle these.
4290 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4291 (define_split
4292   [(set (match_operand:DF 0 "general_movdst_operand" "")
4293         (match_operand:DF 1 "general_movsrc_operand"  ""))
4294    (use (match_operand:PSI 2 "fpscr_operand" ""))
4295    (clobber (match_scratch:SI 3 ""))]
4296   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4297    && reload_completed
4298    && true_regnum (operands[0]) < 16
4299    && true_regnum (operands[1]) < 16"
4300   [(set (match_dup 0) (match_dup 1))]
4301   "
4303   /* If this was a reg <-> mem operation with base + index reg addressing,
4304      we have to handle this in a special way.  */
4305   rtx mem = operands[0];
4306   int store_p = 1;
4307   if (! memory_operand (mem, DFmode))
4308     {
4309       mem = operands[1];
4310       store_p = 0;
4311     }
4312   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4313     mem = SUBREG_REG (mem);
4314   if (GET_CODE (mem) == MEM)
4315     {
4316       rtx addr = XEXP (mem, 0);
4317       if (GET_CODE (addr) == PLUS
4318           && GET_CODE (XEXP (addr, 0)) == REG
4319           && GET_CODE (XEXP (addr, 1)) == REG)
4320         {
4321           int offset;
4322           rtx reg0 = gen_rtx_REG (Pmode, 0);
4323           rtx regop = operands[store_p], word0 ,word1;
4325           if (GET_CODE (regop) == SUBREG)
4326             alter_subreg (&regop);
4327           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4328             offset = 2;
4329           else
4330             offset = 4;
4331           mem = copy_rtx (mem);
4332           PUT_MODE (mem, SImode);
4333           word0 = gen_rtx_SUBREG (SImode, regop, 0);
4334           alter_subreg (&word0);
4335           word1 = gen_rtx_SUBREG (SImode, regop, 4);
4336           alter_subreg (&word1);
4337           if (store_p || ! refers_to_regno_p (REGNO (word0),
4338                                               REGNO (word0) + 1, addr, 0))
4339             {
4340               emit_insn (store_p
4341                          ? gen_movsi_ie (mem, word0)
4342                          : gen_movsi_ie (word0, mem));
4343               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4344               mem = copy_rtx (mem);
4345               emit_insn (store_p
4346                          ? gen_movsi_ie (mem, word1)
4347                          : gen_movsi_ie (word1, mem));
4348               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4349             }
4350           else
4351             {
4352               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4353               emit_insn (gen_movsi_ie (word1, mem));
4354               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4355               mem = copy_rtx (mem);
4356               emit_insn (gen_movsi_ie (word0, mem));
4357             }
4358           DONE;
4359         }
4360     }
4363 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4364 (define_split
4365   [(set (match_operand:DF 0 "register_operand" "")
4366         (match_operand:DF 1 "memory_operand"  ""))
4367    (use (match_operand:PSI 2 "fpscr_operand" ""))
4368    (clobber (reg:SI R0_REG))]
4369   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
4370   [(parallel [(set (match_dup 0) (match_dup 1))
4371               (use (match_dup 2))
4372               (clobber (scratch:SI))])]
4373   "")
4375 (define_expand "reload_indf"
4376   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4377                    (match_operand:DF 1 "immediate_operand" "FQ"))
4378               (use (reg:PSI FPSCR_REG))
4379               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4380   "TARGET_SH1"
4381   "")
4383 (define_expand "reload_outdf"
4384   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4385                    (match_operand:DF 1 "register_operand" "af,r"))
4386               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4387   "TARGET_SH1"
4388   "")
4390 ;; Simplify no-op moves.
4391 (define_split
4392   [(set (match_operand:SF 0 "register_operand" "")
4393         (match_operand:SF 1 "register_operand" ""))
4394    (use (match_operand:PSI 2 "fpscr_operand" ""))
4395    (clobber (match_scratch:SI 3 ""))]
4396   "TARGET_SH2E && reload_completed
4397    && true_regnum (operands[0]) == true_regnum (operands[1])"
4398   [(set (match_dup 0) (match_dup 0))]
4399   "")
4401 ;; fmovd substitute post-reload splits
4402 (define_split
4403   [(set (match_operand:DF 0 "register_operand" "")
4404         (match_operand:DF 1 "register_operand" ""))
4405    (use (match_operand:PSI 2 "fpscr_operand" ""))
4406    (clobber (match_scratch:SI 3 ""))]
4407   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4408    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4409    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4410   [(const_int 0)]
4411   "
4413   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4414   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4415                            gen_rtx_REG (SFmode, src), operands[2]));
4416   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4417                            gen_rtx_REG (SFmode, src + 1), operands[2]));
4418   DONE;
4421 (define_split
4422   [(set (match_operand:DF 0 "register_operand" "")
4423         (mem:DF (match_operand:SI 1 "register_operand" "")))
4424    (use (match_operand:PSI 2 "fpscr_operand" ""))
4425    (clobber (match_scratch:SI 3 ""))]
4426   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4427    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4428    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4429   [(const_int 0)]
4430   "
4432   int regno = true_regnum (operands[0]);
4433   rtx insn;
4434   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4436   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4437                                            regno + !! TARGET_LITTLE_ENDIAN),
4438                                   mem2, operands[2]));
4439   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4440   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4441                                            regno + ! TARGET_LITTLE_ENDIAN),
4442                                   gen_rtx_MEM (SFmode, operands[1]),
4443                                   operands[2]));
4444   DONE;
4447 (define_split
4448   [(set (match_operand:DF 0 "register_operand" "")
4449         (match_operand:DF 1 "memory_operand" ""))
4450    (use (match_operand:PSI 2 "fpscr_operand" ""))
4451    (clobber (match_scratch:SI 3 ""))]
4452   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4453    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4454   [(const_int 0)]
4455   "
4457   int regno = true_regnum (operands[0]);
4458   rtx addr, insn, adjust = NULL_RTX;
4459   rtx mem2 = copy_rtx (operands[1]);
4460   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4461   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4463   PUT_MODE (mem2, SFmode);
4464   operands[1] = copy_rtx (mem2);
4465   addr = XEXP (mem2, 0);
4466   if (GET_CODE (addr) != POST_INC)
4467     {
4468       /* If we have to modify the stack pointer, the value that we have
4469          read with post-increment might be modified by an interrupt,
4470          so write it back.  */
4471       if (REGNO (addr) == STACK_POINTER_REGNUM)
4472         adjust = gen_push_e (reg0);
4473       else
4474         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4475       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4476     }
4477   addr = XEXP (addr, 0);
4478   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4479   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4480   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4481   if (adjust)
4482     emit_insn (adjust);
4483   else
4484     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4485   DONE;
4488 (define_split
4489   [(set (match_operand:DF 0 "memory_operand" "")
4490         (match_operand:DF 1 "register_operand" ""))
4491    (use (match_operand:PSI 2 "fpscr_operand" ""))
4492    (clobber (match_scratch:SI 3 ""))]
4493   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4494    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4495   [(const_int 0)]
4496   "
4498   int regno = true_regnum (operands[1]);
4499   rtx insn, addr, adjust = NULL_RTX;
4501   operands[0] = copy_rtx (operands[0]);
4502   PUT_MODE (operands[0], SFmode);
4503   insn = emit_insn (gen_movsf_ie (operands[0],
4504                                   gen_rtx_REG (SFmode,
4505                                            regno + ! TARGET_LITTLE_ENDIAN),
4506                                   operands[2]));
4507   operands[0] = copy_rtx (operands[0]);
4508   addr = XEXP (operands[0], 0);
4509   if (GET_CODE (addr) != PRE_DEC)
4510     {
4511       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4512       emit_insn_before (adjust, insn);
4513       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4514     }
4515   addr = XEXP (addr, 0);
4516   if (! adjust)
4517     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4518   insn = emit_insn (gen_movsf_ie (operands[0],
4519                                   gen_rtx_REG (SFmode,
4520                                            regno + !! TARGET_LITTLE_ENDIAN),
4521                                   operands[2]));
4522   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4523   DONE;
4526 ;; If the output is a register and the input is memory or a register, we have
4527 ;; to be careful and see which word needs to be loaded first.
4529 (define_split
4530   [(set (match_operand:DF 0 "general_movdst_operand" "")
4531         (match_operand:DF 1 "general_movsrc_operand" ""))]
4532   "TARGET_SH1 && reload_completed"
4533   [(set (match_dup 2) (match_dup 3))
4534    (set (match_dup 4) (match_dup 5))]
4535   "
4537   int regno;
4539   if ((GET_CODE (operands[0]) == MEM
4540        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4541       || (GET_CODE (operands[1]) == MEM
4542           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4543     FAIL;
4545   if (GET_CODE (operands[0]) == REG)
4546     regno = REGNO (operands[0]);
4547   else if (GET_CODE (operands[0]) == SUBREG)
4548     regno = subreg_regno (operands[0]);
4549   else if (GET_CODE (operands[0]) == MEM)
4550     regno = -1;
4551   else
4552     abort ();
4554   if (regno == -1
4555       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4556     {
4557       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4558       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4559       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4560       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4561     }
4562   else
4563     {
4564       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4565       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4566       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4567       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4568     }
4570   if (operands[2] == 0 || operands[3] == 0
4571       || operands[4] == 0 || operands[5] == 0)
4572     FAIL;
4575 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4576 ;; used only once, let combine add in the index again.
4578 (define_split
4579   [(set (match_operand:SI 0 "register_operand" "")
4580         (match_operand:SI 1 "" ""))
4581    (clobber (match_operand 2 "register_operand" ""))]
4582   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4583   [(use (reg:SI R0_REG))]
4584   "
4586   rtx addr, reg, const_int;
4588   if (GET_CODE (operands[1]) != MEM)
4589     FAIL;
4590   addr = XEXP (operands[1], 0);
4591   if (GET_CODE (addr) != PLUS)
4592     FAIL;
4593   reg = XEXP (addr, 0);
4594   const_int = XEXP (addr, 1);
4595   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4596          && GET_CODE (const_int) == CONST_INT))
4597     FAIL;
4598   emit_move_insn (operands[2], const_int);
4599   emit_move_insn (operands[0],
4600                   change_address (operands[1], VOIDmode,
4601                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4602   DONE;
4605 (define_split
4606   [(set (match_operand:SI 1 "" "")
4607         (match_operand:SI 0 "register_operand" ""))
4608    (clobber (match_operand 2 "register_operand" ""))]
4609   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4610   [(use (reg:SI R0_REG))]
4611   "
4613   rtx addr, reg, const_int;
4615   if (GET_CODE (operands[1]) != MEM)
4616     FAIL;
4617   addr = XEXP (operands[1], 0);
4618   if (GET_CODE (addr) != PLUS)
4619     FAIL;
4620   reg = XEXP (addr, 0);
4621   const_int = XEXP (addr, 1);
4622   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4623          && GET_CODE (const_int) == CONST_INT))
4624     FAIL;
4625   emit_move_insn (operands[2], const_int);
4626   emit_move_insn (change_address (operands[1], VOIDmode,
4627                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4628                   operands[0]);
4629   DONE;
4632 (define_expand "movdf"
4633   [(set (match_operand:DF 0 "general_movdst_operand" "")
4634         (match_operand:DF 1 "general_movsrc_operand" ""))]
4635   ""
4636   "
4638   if (prepare_move_operands (operands, DFmode)) DONE;
4639   if (TARGET_SHMEDIA)
4640     {
4641       if (TARGET_SHMEDIA_FPU)
4642         emit_insn (gen_movdf_media (operands[0], operands[1]));
4643       else
4644         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4645       DONE;
4646     }
4647   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
4648     {
4649       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4650       DONE;
4651     }
4654 ;;This is incompatible with the way gcc uses subregs.
4655 ;;(define_insn "movv2sf_i"
4656 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4657 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4658 ;;  "TARGET_SHMEDIA_FPU
4659 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4660 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4661 ;;  "@
4662 ;;      #
4663 ;;      fld%M1.p        %m1, %0
4664 ;;      fst%M0.p        %m0, %1"
4665 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4667 (define_insn_and_split "movv2sf_i"
4668   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4669         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4670   "TARGET_SHMEDIA_FPU"
4671   "#"
4672   "TARGET_SHMEDIA_FPU && reload_completed"
4673   [(set (match_dup 0) (match_dup 1))]
4674   "
4676   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4677   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4680 (define_expand "movv2sf"
4681   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4682         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4683   "TARGET_SHMEDIA_FPU"
4684   "
4686   if (prepare_move_operands (operands, V2SFmode))
4687     DONE;
4690 (define_expand "addv2sf3"
4691   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4692    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4693    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4694   "TARGET_SHMEDIA_FPU"
4695   "
4697   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4698   DONE;
4701 (define_expand "subv2sf3"
4702   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4703    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4704    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4705   "TARGET_SHMEDIA_FPU"
4706   "
4708   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4709   DONE;
4712 (define_expand "mulv2sf3"
4713   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4714    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4715    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4716   "TARGET_SHMEDIA_FPU"
4717   "
4719   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4720   DONE;
4723 (define_expand "divv2sf3"
4724   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4725    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4726    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4727   "TARGET_SHMEDIA_FPU"
4728   "
4730   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4731   DONE;
4734 (define_insn_and_split "*movv4sf_i"
4735   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4736         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4737   "TARGET_SHMEDIA_FPU"
4738   "#"
4739   "&& reload_completed"
4740   [(const_int 0)]
4741   "
4743   int i;
4745   for (i = 0; i < 4/2; i++)
4746     {
4747       rtx x, y;
4749       if (GET_CODE (operands[0]) == MEM)
4750         x = gen_rtx_MEM (V2SFmode,
4751                          plus_constant (XEXP (operands[0], 0),
4752                                         i * GET_MODE_SIZE (V2SFmode)));
4753       else
4754         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4756       if (GET_CODE (operands[1]) == MEM)
4757         y = gen_rtx_MEM (V2SFmode,
4758                          plus_constant (XEXP (operands[1], 0),
4759                                         i * GET_MODE_SIZE (V2SFmode)));
4760       else
4761         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4763       emit_insn (gen_movv2sf_i (x, y));
4764     }
4766   DONE;
4768   [(set_attr "length" "8")])
4770 (define_expand "movv4sf"
4771   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4772         (match_operand:V4SF 1 "general_operand" ""))]
4773   "TARGET_SHMEDIA_FPU"
4774   "
4776   if (prepare_move_operands (operands, V4SFmode))
4777     DONE;
4780 (define_insn_and_split "*movv16sf_i"
4781   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4782         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4783   "TARGET_SHMEDIA_FPU"
4784   "#"
4785   "&& reload_completed"
4786   [(const_int 0)]
4787   "
4789   int i;
4791   for (i = 0; i < 16/2; i++)
4792     {
4793       rtx x,y;
4795       if (GET_CODE (operands[0]) == MEM)
4796         x = gen_rtx_MEM (V2SFmode,
4797                          plus_constant (XEXP (operands[0], 0),
4798                                         i * GET_MODE_SIZE (V2SFmode)));
4799       else
4800         {
4801           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4802           alter_subreg (&x);
4803         }
4805       if (GET_CODE (operands[1]) == MEM)
4806         y = gen_rtx_MEM (V2SFmode,
4807                          plus_constant (XEXP (operands[1], 0),
4808                                         i * GET_MODE_SIZE (V2SFmode)));
4809       else
4810         {
4811           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4812           alter_subreg (&y);
4813         }
4815       emit_insn (gen_movv2sf_i (x, y));
4816     }
4818   DONE;
4820   [(set_attr "length" "32")])
4822 (define_expand "movv16sf"
4823   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4824         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4825   "TARGET_SHMEDIA_FPU"
4826   "
4828   if (prepare_move_operands (operands, V16SFmode))
4829     DONE;
4832 (define_insn "movsf_media"
4833   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4834         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4835   "TARGET_SHMEDIA_FPU
4836    && (register_operand (operands[0], SFmode)
4837        || sh_register_operand (operands[1], SFmode))"
4838   "@
4839         fmov.s  %1, %0
4840         fmov.ls %N1, %0
4841         fmov.sl %1, %0
4842         add.l   %1, r63, %0
4843         #
4844         fld%M1.s        %m1, %0
4845         fst%M0.s        %m0, %1
4846         ld%M1.l %m1, %0
4847         st%M0.l %m0, %N1"
4848   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4850 (define_insn "movsf_media_nofpu"
4851   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4852         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4853   "TARGET_SHMEDIA
4854    && (register_operand (operands[0], SFmode)
4855        || sh_register_operand (operands[1], SFmode))"
4856   "@
4857         add.l   %1, r63, %0
4858         #
4859         ld%M1.l %m1, %0
4860         st%M0.l %m0, %N1"
4861   [(set_attr "type" "arith_media,*,load_media,store_media")])
4863 (define_split
4864   [(set (match_operand:SF 0 "arith_reg_operand" "")
4865         (match_operand:SF 1 "immediate_operand" ""))]
4866   "TARGET_SHMEDIA && reload_completed
4867    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4868   [(set (match_dup 3) (match_dup 2))]
4869   "
4871   long values;
4872   REAL_VALUE_TYPE value;
4874   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4875   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4876   operands[2] = GEN_INT (values);
4878   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4881 (define_insn "movsf_i"
4882   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4883         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4884   "TARGET_SH1
4885    && (! TARGET_SH2E
4886        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4887        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4888        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4889    && (arith_reg_operand (operands[0], SFmode)
4890        || arith_reg_operand (operands[1], SFmode))"
4891   "@
4892         mov     %1,%0
4893         mov     #0,%0
4894         mov.l   %1,%0
4895         mov.l   %1,%0
4896         mov.l   %1,%0
4897         lds     %1,%0
4898         sts     %1,%0"
4899   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4901 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4902 ;; update_flow_info would not know where to put REG_EQUAL notes
4903 ;; when the destination changes mode.
4904 (define_insn "movsf_ie"
4905   [(set (match_operand:SF 0 "general_movdst_operand"
4906          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4907         (match_operand:SF 1 "general_movsrc_operand"
4908           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4909    (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"))
4910    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4912   "TARGET_SH2E
4913    && (arith_reg_operand (operands[0], SFmode)
4914        || arith_reg_operand (operands[1], SFmode)
4915        || arith_reg_operand (operands[3], SImode)
4916        || (fpul_operand (operands[0], SFmode)
4917            && memory_operand (operands[1], SFmode)
4918            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4919        || (fpul_operand (operands[1], SFmode)
4920            && memory_operand (operands[0], SFmode)
4921            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4922   "@
4923         fmov    %1,%0
4924         mov     %1,%0
4925         fldi0   %0
4926         fldi1   %0
4927         #
4928         fmov.s  %1,%0
4929         fmov.s  %1,%0
4930         mov.l   %1,%0
4931         mov.l   %1,%0
4932         mov.l   %1,%0
4933         fsts    fpul,%0
4934         flds    %1,fpul
4935         lds.l   %1,%0
4936         #
4937         sts     %1,%0
4938         lds     %1,%0
4939         sts.l   %1,%0
4940         lds.l   %1,%0
4941         ! move optimized away"
4942   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4943    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4944    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
4945    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4946                                            (const_string "single")
4947                                            (const_string "none")))])
4949 (define_split
4950   [(set (match_operand:SF 0 "register_operand" "")
4951         (match_operand:SF 1 "register_operand" ""))
4952    (use (match_operand:PSI 2 "fpscr_operand" ""))
4953    (clobber (reg:SI FPUL_REG))]
4954   "TARGET_SH1"
4955   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4956               (use (match_dup 2))
4957               (clobber (scratch:SI))])
4958    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4959               (use (match_dup 2))
4960               (clobber (scratch:SI))])]
4961   "")
4963 (define_expand "movsf"
4964   [(set (match_operand:SF 0 "general_movdst_operand" "")
4965         (match_operand:SF 1 "general_movsrc_operand" ""))]
4966   ""
4967   "
4969   if (prepare_move_operands (operands, SFmode))
4970     DONE;
4971   if (TARGET_SHMEDIA)
4972     {
4973       if (TARGET_SHMEDIA_FPU)
4974         emit_insn (gen_movsf_media (operands[0], operands[1]));
4975       else
4976         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4977       DONE;
4978     }
4979   if (TARGET_SH2E)
4980     {
4981       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4982       DONE;
4983     }
4986 (define_insn "mov_nop"
4987   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4988   "TARGET_SH2E"
4989   ""
4990   [(set_attr "length" "0")
4991    (set_attr "type" "nil")])
4993 (define_expand "reload_insf"
4994   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4995                    (match_operand:SF 1 "immediate_operand" "FQ"))
4996               (use (reg:PSI FPSCR_REG))
4997               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4998   "TARGET_SH1"
4999   "")
5001 (define_expand "reload_insi"
5002   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5003                    (match_operand:SF 1 "immediate_operand" "FQ"))
5004               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5005   "TARGET_SH1"
5006   "")
5008 (define_insn "*movsi_y"
5009   [(set (match_operand:SI 0 "register_operand" "=y,y")
5010         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5011    (clobber (match_scratch:SI 2 "=&z,r"))]
5012   "TARGET_SH2E
5013    && (reload_in_progress || reload_completed)"
5014   "#"
5015   [(set_attr "length" "4")
5016    (set_attr "type" "pcload,move")])
5018 (define_split
5019   [(set (match_operand:SI 0 "register_operand" "")
5020         (match_operand:SI 1 "immediate_operand" ""))
5021    (clobber (match_operand:SI 2 "register_operand" ""))]
5022   "TARGET_SH1"
5023   [(set (match_dup 2) (match_dup 1))
5024    (set (match_dup 0) (match_dup 2))]
5025   "")
5027 (define_split
5028   [(set (match_operand:SI 0 "register_operand" "")
5029         (match_operand:SI 1 "memory_operand" ""))
5030    (clobber (reg:SI R0_REG))]
5031   "TARGET_SH1"
5032   [(set (match_dup 0) (match_dup 1))]
5033   "")
5035 ;; ------------------------------------------------------------------------
5036 ;; Define the real conditional branch instructions.
5037 ;; ------------------------------------------------------------------------
5039 (define_insn "branch_true"
5040   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5041                            (label_ref (match_operand 0 "" ""))
5042                            (pc)))]
5043   "TARGET_SH1"
5044   "* return output_branch (1, insn, operands);"
5045   [(set_attr "type" "cbranch")])
5047 (define_insn "branch_false"
5048   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5049                            (label_ref (match_operand 0 "" ""))
5050                            (pc)))]
5051   "TARGET_SH1"
5052   "* return output_branch (0, insn, operands);"
5053   [(set_attr "type" "cbranch")])
5055 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5056 ;; which destination is too far away.
5057 ;; The const_int_operand is distinct for each branch target; it avoids
5058 ;; unwanted matches with redundant_insn.
5059 (define_insn "block_branch_redirect"
5060   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5061   "TARGET_SH1"
5062   ""
5063   [(set_attr "length" "0")])
5065 ;; This one has the additional purpose to record a possible scratch register
5066 ;; for the following branch.
5067 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5068 ;; because the insn then might be deemed dead and deleted.  And we can't
5069 ;; make the use in the jump insn explicit because that would disable
5070 ;; delay slot scheduling from the target.
5071 (define_insn "indirect_jump_scratch"
5072   [(set (match_operand:SI 0 "register_operand" "=r")
5073         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5074    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5075   "TARGET_SH1"
5076   ""
5077   [(set_attr "length" "0")])
5079 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5080 ;; being pulled into the delay slot of a condbranch that has been made to
5081 ;; jump around the unconditional jump because it was out of range.
5082 (define_insn "stuff_delay_slot"
5083   [(set (pc)
5084         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5085    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5086   "TARGET_SH1"
5087   ""
5088   [(set_attr "length" "0")
5089    (set_attr "cond_delay_slot" "yes")])
5091 ;; Conditional branch insns
5093 (define_expand "beq_media"
5094   [(set (pc)
5095         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5096                           (match_operand:DI 2 "arith_operand" "r,I06"))
5097                       (label_ref:DI (match_operand 0 "" ""))
5098                       (pc)))]
5099   "TARGET_SHMEDIA"
5100   "")
5102 (define_insn "*beq_media_i"
5103   [(set (pc)
5104         (if_then_else (match_operator 3 "equality_comparison_operator"
5105                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5106                          (match_operand:DI 2 "arith_operand" "r,I06")])
5107                       (match_operand:DI 0 "target_operand" "b,b")
5108                       (pc)))]
5109   "TARGET_SHMEDIA"
5110   "@
5111         b%o3%'  %1, %2, %0
5112         b%o3i%' %1, %2, %0"
5113   [(set_attr "type" "cbranch_media")])
5115 (define_expand "bne_media"
5116   [(set (pc)
5117         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5118                           (match_operand:DI 2 "arith_operand" "r,I06"))
5119                       (label_ref:DI (match_operand 0 "" ""))
5120                       (pc)))]
5121   "TARGET_SHMEDIA"
5122   "")
5124 (define_expand "bgt_media"
5125   [(set (pc)
5126         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5127                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5128                       (label_ref:DI (match_operand 0 "" ""))
5129                       (pc)))]
5130   "TARGET_SHMEDIA"
5131   "")
5133 (define_expand "bge_media"
5134   [(set (pc)
5135         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5136                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5137                       (label_ref:DI (match_operand 0 "" ""))
5138                       (pc)))]
5139   "TARGET_SHMEDIA"
5140   "")
5142 (define_expand "bgtu_media"
5143   [(set (pc)
5144         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5145                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5146                       (label_ref:DI (match_operand 0 "" ""))
5147                       (pc)))]
5148   "TARGET_SHMEDIA"
5149   "")
5151 (define_expand "bgeu_media"
5152   [(set (pc)
5153         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5154                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5155                       (label_ref:DI (match_operand 0 "" ""))
5156                       (pc)))]
5157   "TARGET_SHMEDIA"
5158   "")
5160 (define_insn "*bgt_media_i"
5161   [(set (pc)
5162         (if_then_else (match_operator 3 "greater_comparison_operator"
5163                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5164                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5165                       (match_operand:DI 0 "target_operand" "b")
5166                       (pc)))]
5167   "TARGET_SHMEDIA"
5168   "b%o3%'       %N1, %N2, %0"
5169   [(set_attr "type" "cbranch_media")])
5171 ;; These are only needed to make invert_jump() happy.
5172 (define_insn "*blt_media_i"
5173   [(set (pc)
5174         (if_then_else (match_operator 3 "less_comparison_operator"
5175                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5176                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5177                       (match_operand:DI 0 "target_operand" "b")
5178                       (pc)))]
5179   "TARGET_SHMEDIA"
5180   "b%o3%'       %N2, %N1, %0"
5181   [(set_attr "type" "cbranch_media")])
5183 (define_expand "beq"
5184   [(set (pc)
5185         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5186                       (label_ref (match_operand 0 "" ""))
5187                       (pc)))]
5188   ""
5189   "
5191   if (TARGET_SHMEDIA)
5192     {
5193       if (GET_MODE (sh_compare_op0) != DImode)
5194         {
5195           rtx tmp = gen_reg_rtx (DImode);
5197           emit_insn (gen_seq (tmp));
5198           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5199           DONE;
5200         }
5202       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5203       emit_jump_insn (gen_beq_media (operands[0],
5204                                      sh_compare_op0, sh_compare_op1));
5205       DONE;
5206     }
5208   from_compare (operands, EQ);
5211 (define_expand "bne"
5212   [(set (pc)
5213         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5214                       (label_ref (match_operand 0 "" ""))
5215                       (pc)))]
5216   ""
5217   "
5219   if (TARGET_SHMEDIA)
5220     {
5221       if (GET_MODE (sh_compare_op0) != DImode)
5222         {
5223           rtx tmp = gen_reg_rtx (DImode);
5225           emit_insn (gen_seq (tmp));
5226           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5227           DONE;
5228         }
5230       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5231       emit_jump_insn (gen_bne_media (operands[0],
5232                                      sh_compare_op0, sh_compare_op1));
5233       DONE;
5234     }
5236   from_compare (operands, EQ);
5239 (define_expand "bgt"
5240   [(set (pc)
5241         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5242                       (label_ref (match_operand 0 "" ""))
5243                       (pc)))]
5244   ""
5245   "
5247   if (TARGET_SHMEDIA)
5248     {
5249       if (GET_MODE (sh_compare_op0) != DImode)
5250         {
5251           rtx tmp = gen_reg_rtx (DImode);
5253           emit_insn (gen_sgt (tmp));
5254           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5255           DONE;
5256         }
5258       if (sh_compare_op0 != const0_rtx)
5259         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5260       if (sh_compare_op1 != const0_rtx)
5261         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5262       emit_jump_insn (gen_bgt_media (operands[0],
5263                                      sh_compare_op0, sh_compare_op1));
5264       DONE;
5265     }
5267   from_compare (operands, GT);
5270 (define_expand "blt"
5271   [(set (pc)
5272         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5273                       (label_ref (match_operand 0 "" ""))
5274                       (pc)))]
5275   ""
5276   "
5278   if (TARGET_SHMEDIA)
5279     {
5280       if (GET_MODE (sh_compare_op0) != DImode)
5281         {
5282           rtx tmp = gen_reg_rtx (DImode);
5284           emit_insn (gen_slt (tmp));
5285           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5286           DONE;
5287         }
5289       if (sh_compare_op0 != const0_rtx)
5290         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5291       if (sh_compare_op1 != const0_rtx)
5292         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5293       emit_jump_insn (gen_bgt_media (operands[0],
5294                                      sh_compare_op1, sh_compare_op0));
5295       DONE;
5296     }
5298   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5299     {
5300       rtx tmp = sh_compare_op0;
5301       sh_compare_op0 = sh_compare_op1;
5302       sh_compare_op1 = tmp;
5303       emit_insn (gen_bgt (operands[0]));
5304       DONE;
5305     }
5306   from_compare (operands, GE);
5309 (define_expand "ble"
5310   [(set (pc)
5311         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5312                       (label_ref (match_operand 0 "" ""))
5313                       (pc)))]
5314   ""
5315   "
5317   if (TARGET_SHMEDIA)
5318     {
5319       if (GET_MODE (sh_compare_op0) != DImode)
5320         {
5321           rtx tmp = gen_reg_rtx (DImode);
5323           emit_insn (gen_sle (tmp));
5324           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5325           DONE;
5326         }
5328       if (sh_compare_op0 != const0_rtx)
5329         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5330       if (sh_compare_op1 != const0_rtx)
5331         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5332       emit_jump_insn (gen_bge_media (operands[0],
5333                                      sh_compare_op1, sh_compare_op0));
5334       DONE;
5335     }
5337   if (TARGET_SH2E
5338       && TARGET_IEEE
5339       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5340     {
5341       rtx tmp = sh_compare_op0;
5342       sh_compare_op0 = sh_compare_op1;
5343       sh_compare_op1 = tmp;
5344       emit_insn (gen_bge (operands[0]));
5345       DONE;
5346     }
5347   from_compare (operands, GT);
5350 (define_expand "bge"
5351   [(set (pc)
5352         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5353                       (label_ref (match_operand 0 "" ""))
5354                       (pc)))]
5355   ""
5356   "
5358   if (TARGET_SHMEDIA)
5359     {
5360       if (GET_MODE (sh_compare_op0) != DImode)
5361         {
5362           rtx tmp = gen_reg_rtx (DImode);
5364           emit_insn (gen_sge (tmp));
5365           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5366           DONE;
5367         }
5369       if (sh_compare_op0 != const0_rtx)
5370         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5371       if (sh_compare_op1 != const0_rtx)
5372         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5373       emit_jump_insn (gen_bge_media (operands[0],
5374                                      sh_compare_op0, sh_compare_op1));
5375       DONE;
5376     }
5378   if (TARGET_SH2E
5379       && ! TARGET_IEEE
5380       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5381     {
5382       rtx tmp = sh_compare_op0;
5383       sh_compare_op0 = sh_compare_op1;
5384       sh_compare_op1 = tmp;
5385       emit_insn (gen_ble (operands[0]));
5386       DONE;
5387     }
5388   from_compare (operands, GE);
5391 (define_expand "bgtu"
5392   [(set (pc)
5393         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5394                       (label_ref (match_operand 0 "" ""))
5395                       (pc)))]
5396   ""
5397   "
5399   if (TARGET_SHMEDIA)
5400     {
5401       if (sh_compare_op0 != const0_rtx)
5402         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5403       if (sh_compare_op1 != const0_rtx)
5404         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5405       emit_jump_insn (gen_bgtu_media (operands[0],
5406                                       sh_compare_op0, sh_compare_op1));
5407       DONE;
5408     }
5410   from_compare (operands, GTU);
5413 (define_expand "bltu"
5414   [(set (pc)
5415         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5416                       (label_ref (match_operand 0 "" ""))
5417                       (pc)))]
5418   ""
5419   "
5421   if (TARGET_SHMEDIA)
5422     {
5423       if (sh_compare_op0 != const0_rtx)
5424         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5425       if (sh_compare_op1 != const0_rtx)
5426         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5427       emit_jump_insn (gen_bgtu_media (operands[0],
5428                                       sh_compare_op1, sh_compare_op0));
5429       DONE;
5430     }
5432   from_compare (operands, GEU);
5435 (define_expand "bgeu"
5436   [(set (pc)
5437         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5438                       (label_ref (match_operand 0 "" ""))
5439                       (pc)))]
5440   ""
5441   "
5443   if (TARGET_SHMEDIA)
5444     {
5445       if (sh_compare_op0 != const0_rtx)
5446         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5447       if (sh_compare_op1 != const0_rtx)
5448         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5449       emit_jump_insn (gen_bgeu_media (operands[0],
5450                                       sh_compare_op0, sh_compare_op1));
5451       DONE;
5452     }
5454   from_compare (operands, GEU);
5457 (define_expand "bleu"
5458   [(set (pc)
5459         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5460                       (label_ref (match_operand 0 "" ""))
5461                       (pc)))]
5462   ""
5463   "
5465   if (TARGET_SHMEDIA)
5466     {
5467       if (sh_compare_op0 != const0_rtx)
5468         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5469       if (sh_compare_op1 != const0_rtx)
5470         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5471       emit_jump_insn (gen_bgeu_media (operands[0],
5472                                       sh_compare_op1, sh_compare_op0));
5473       DONE;
5474     }
5476   from_compare (operands, GTU);
5479 (define_expand "bunordered"
5480   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5481    (set (pc)
5482         (if_then_else (ne (match_dup 1) (const_int 0))
5483                       (label_ref:DI (match_operand 0 "" ""))
5484                       (pc)))]
5485   "TARGET_SHMEDIA"
5486   "
5488   operands[1] = gen_reg_rtx (DImode);
5489   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5490   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5493 ;; ------------------------------------------------------------------------
5494 ;; Jump and linkage insns
5495 ;; ------------------------------------------------------------------------
5497 (define_insn "jump_compact"
5498   [(set (pc)
5499         (label_ref (match_operand 0 "" "")))]
5500   "TARGET_SH1"
5501   "*
5503   /* The length is 16 if the delay slot is unfilled.  */
5504   if (get_attr_length(insn) > 4)
5505     return output_far_jump(insn, operands[0]);
5506   else
5507     return   \"bra      %l0%#\";
5509   [(set_attr "type" "jump")
5510    (set_attr "needs_delay_slot" "yes")])
5512 ;; ??? It would be much saner to explicitly use the scratch register
5513 ;; in the jump insn, and have indirect_jump_scratch only set it,
5514 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5515 ;; from the target then, as it uses simplejump_p.
5516 ;;(define_insn "jump_compact_far"
5517 ;;  [(set (pc)
5518 ;;      (label_ref (match_operand 0 "" "")))
5519 ;;   (use (match_operand 1 "register_operand" "r")]
5520 ;;  "TARGET_SH1"
5521 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5522 ;;  [(set_attr "type" "jump")
5523 ;;   (set_attr "needs_delay_slot" "yes")])
5525 (define_insn "jump_media"
5526   [(set (pc)
5527         (match_operand:DI 0 "target_operand" "b"))]
5528   "TARGET_SHMEDIA"
5529   "blink        %0, r63"
5530   [(set_attr "type" "jump_media")])
5532 (define_expand "jump"
5533   [(set (pc)
5534         (label_ref (match_operand 0 "" "")))]
5535   ""
5536   "
5538   if (TARGET_SH1)
5539     emit_jump_insn (gen_jump_compact (operands[0]));
5540   else if (TARGET_SHMEDIA)
5541     {
5542       if (reload_in_progress || reload_completed)
5543         FAIL;
5544       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5545                                                          operands[0])));
5546     }
5547   DONE;
5550 (define_insn "force_mode_for_call"
5551   [(use (reg:PSI FPSCR_REG))]
5552   "TARGET_SHCOMPACT"
5553   ""
5554   [(set_attr "length" "0")
5555    (set (attr "fp_mode")
5556         (if_then_else (eq_attr "fpu_single" "yes")
5557                       (const_string "single") (const_string "double")))])
5559 (define_insn "calli"
5560   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5561          (match_operand 1 "" ""))
5562    (use (reg:PSI FPSCR_REG))
5563    (clobber (reg:SI PR_REG))]
5564   "TARGET_SH1"
5565   "jsr  @%0%#"
5566   [(set_attr "type" "call")
5567    (set (attr "fp_mode")
5568         (if_then_else (eq_attr "fpu_single" "yes")
5569                       (const_string "single") (const_string "double")))
5570    (set_attr "needs_delay_slot" "yes")
5571    (set_attr "fp_set" "unknown")])
5573 ;; This is a pc-rel call, using bsrf, for use with PIC.
5575 (define_insn "calli_pcrel"
5576   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5577          (match_operand 1 "" ""))
5578    (use (reg:PSI FPSCR_REG))
5579    (use (reg:SI PIC_REG))
5580    (use (match_operand 2 "" ""))
5581    (clobber (reg:SI PR_REG))]
5582   "TARGET_SH2"
5583   "bsrf %0\\n%O2:%#"
5584   [(set_attr "type" "call")
5585    (set (attr "fp_mode")
5586         (if_then_else (eq_attr "fpu_single" "yes")
5587                       (const_string "single") (const_string "double")))
5588    (set_attr "needs_delay_slot" "yes")
5589    (set_attr "fp_set" "unknown")])
5591 (define_insn_and_split "call_pcrel"
5592   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5593          (match_operand 1 "" ""))
5594    (use (reg:PSI FPSCR_REG))
5595    (use (reg:SI PIC_REG))
5596    (clobber (reg:SI PR_REG))
5597    (clobber (match_scratch:SI 2 "=r"))]
5598   "TARGET_SH2"
5599   "#"
5600   "reload_completed"
5601   [(const_int 0)]
5602   "
5604   rtx lab = PATTERN (gen_call_site ());
5606   if (SYMBOL_REF_LOCAL_P (operands[0]))
5607     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5608   else
5609     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5610   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5611   DONE;
5613   [(set_attr "type" "call")
5614    (set (attr "fp_mode")
5615         (if_then_else (eq_attr "fpu_single" "yes")
5616                       (const_string "single") (const_string "double")))
5617    (set_attr "needs_delay_slot" "yes")
5618    (set_attr "fp_set" "unknown")])
5620 (define_insn "call_compact"
5621   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5622          (match_operand 1 "" ""))
5623    (match_operand 2 "immediate_operand" "n")
5624    (use (reg:SI R0_REG))
5625    (use (reg:SI R1_REG))
5626    (use (reg:PSI FPSCR_REG))
5627    (clobber (reg:SI PR_REG))]
5628   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5629   "jsr  @%0%#"
5630   [(set_attr "type" "call")
5631    (set (attr "fp_mode")
5632         (if_then_else (eq_attr "fpu_single" "yes")
5633                       (const_string "single") (const_string "double")))
5634    (set_attr "needs_delay_slot" "yes")])
5636 (define_insn "call_compact_rettramp"
5637   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5638          (match_operand 1 "" ""))
5639    (match_operand 2 "immediate_operand" "n")
5640    (use (reg:SI R0_REG))
5641    (use (reg:SI R1_REG))
5642    (use (reg:PSI FPSCR_REG))
5643    (clobber (reg:SI R10_REG))
5644    (clobber (reg:SI PR_REG))]
5645   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5646   "jsr  @%0%#"
5647   [(set_attr "type" "call")
5648    (set (attr "fp_mode")
5649         (if_then_else (eq_attr "fpu_single" "yes")
5650                       (const_string "single") (const_string "double")))
5651    (set_attr "needs_delay_slot" "yes")])
5653 (define_insn "call_media"
5654   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5655          (match_operand 1 "" ""))
5656    (clobber (reg:DI PR_MEDIA_REG))]
5657   "TARGET_SHMEDIA"
5658   "blink        %0, r18"
5659   [(set_attr "type" "jump_media")])
5661 (define_insn "call_valuei"
5662   [(set (match_operand 0 "" "=rf")
5663         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5664               (match_operand 2 "" "")))
5665    (use (reg:PSI FPSCR_REG))
5666    (clobber (reg:SI PR_REG))]
5667   "TARGET_SH1"
5668   "jsr  @%1%#"
5669   [(set_attr "type" "call")
5670    (set (attr "fp_mode")
5671         (if_then_else (eq_attr "fpu_single" "yes")
5672                       (const_string "single") (const_string "double")))
5673    (set_attr "needs_delay_slot" "yes")
5674    (set_attr "fp_set" "unknown")])
5676 (define_insn "call_valuei_pcrel"
5677   [(set (match_operand 0 "" "=rf")
5678         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5679               (match_operand 2 "" "")))
5680    (use (reg:PSI FPSCR_REG))
5681    (use (reg:SI PIC_REG))
5682    (use (match_operand 3 "" ""))
5683    (clobber (reg:SI PR_REG))]
5684   "TARGET_SH2"
5685   "bsrf %1\\n%O3:%#"
5686   [(set_attr "type" "call")
5687    (set (attr "fp_mode")
5688         (if_then_else (eq_attr "fpu_single" "yes")
5689                       (const_string "single") (const_string "double")))
5690    (set_attr "needs_delay_slot" "yes")
5691    (set_attr "fp_set" "unknown")])
5693 (define_insn_and_split "call_value_pcrel"
5694   [(set (match_operand 0 "" "=rf")
5695         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5696               (match_operand 2 "" "")))
5697    (use (reg:PSI FPSCR_REG))
5698    (use (reg:SI PIC_REG))
5699    (clobber (reg:SI PR_REG))
5700    (clobber (match_scratch:SI 3 "=r"))]
5701   "TARGET_SH2"
5702   "#"
5703   "reload_completed"
5704   [(const_int 0)]
5705   "
5707   rtx lab = PATTERN (gen_call_site ());
5709   if (SYMBOL_REF_LOCAL_P (operands[1]))
5710     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5711   else
5712     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5713   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5714                                          operands[2], lab));
5715   DONE;
5717   [(set_attr "type" "call")
5718    (set (attr "fp_mode")
5719         (if_then_else (eq_attr "fpu_single" "yes")
5720                       (const_string "single") (const_string "double")))
5721    (set_attr "needs_delay_slot" "yes")
5722    (set_attr "fp_set" "unknown")])
5724 (define_insn "call_value_compact"
5725   [(set (match_operand 0 "" "=rf")
5726         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5727               (match_operand 2 "" "")))
5728    (match_operand 3 "immediate_operand" "n")
5729    (use (reg:SI R0_REG))
5730    (use (reg:SI R1_REG))
5731    (use (reg:PSI FPSCR_REG))
5732    (clobber (reg:SI PR_REG))]
5733   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5734   "jsr  @%1%#"
5735   [(set_attr "type" "call")
5736    (set (attr "fp_mode")
5737         (if_then_else (eq_attr "fpu_single" "yes")
5738                       (const_string "single") (const_string "double")))
5739    (set_attr "needs_delay_slot" "yes")])
5741 (define_insn "call_value_compact_rettramp"
5742   [(set (match_operand 0 "" "=rf")
5743         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5744               (match_operand 2 "" "")))
5745    (match_operand 3 "immediate_operand" "n")
5746    (use (reg:SI R0_REG))
5747    (use (reg:SI R1_REG))
5748    (use (reg:PSI FPSCR_REG))
5749    (clobber (reg:SI R10_REG))
5750    (clobber (reg:SI PR_REG))]
5751   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5752   "jsr  @%1%#"
5753   [(set_attr "type" "call")
5754    (set (attr "fp_mode")
5755         (if_then_else (eq_attr "fpu_single" "yes")
5756                       (const_string "single") (const_string "double")))
5757    (set_attr "needs_delay_slot" "yes")])
5759 (define_insn "call_value_media"
5760   [(set (match_operand 0 "" "=rf")
5761         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5762               (match_operand 2 "" "")))
5763    (clobber (reg:DI PR_MEDIA_REG))]
5764   "TARGET_SHMEDIA"
5765   "blink        %1, r18"
5766   [(set_attr "type" "jump_media")])
5768 (define_expand "call"
5769   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5770                             (match_operand 1 "" ""))
5771               (match_operand 2 "" "")
5772               (use (reg:PSI FPSCR_REG))
5773               (clobber (reg:SI PR_REG))])]
5774   ""
5775   "
5777   if (TARGET_SHMEDIA)
5778     {
5779       operands[0] = XEXP (operands[0], 0);
5780       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5781         {
5782           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5783             {
5784               rtx reg = gen_reg_rtx (Pmode);
5786               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5787               operands[0] = reg;
5788             }
5789           else
5790             {
5791               operands[0] = gen_sym2PIC (operands[0]);
5792               PUT_MODE (operands[0], Pmode);
5793             }
5794         }
5795       if (GET_MODE (operands[0]) == SImode)
5796         {
5797           if (GET_CODE (operands[0]) == REG)
5798             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5799           else if (GET_CODE (operands[0]) == SUBREG)
5800             {
5801               operands[0] = SUBREG_REG (operands[0]);
5802               if (GET_MODE (operands[0]) != DImode)
5803                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5804             }
5805           else if (TARGET_SHMEDIA64)
5806             {
5807               operands[0] = shallow_copy_rtx (operands[0]);
5808               PUT_MODE (operands[0], DImode);
5809             }
5810           else
5811             {
5812               rtx reg = gen_reg_rtx (DImode);
5814               operands[0] = copy_to_mode_reg (SImode, operands[0]);
5815               emit_insn (gen_extendsidi2 (reg, operands[0]));
5816               operands[0] = reg;
5817             }
5818         }
5819       if (! target_reg_operand (operands[0], DImode))
5820         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5821       emit_call_insn (gen_call_media (operands[0], operands[1]));
5822       DONE;
5823     }
5824   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5825     {
5826       rtx cookie_rtx = operands[2];
5827       long cookie = INTVAL (cookie_rtx);
5828       rtx func = XEXP (operands[0], 0);
5829       rtx r0, r1;
5831       if (flag_pic)
5832         {
5833           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5834             {
5835               rtx reg = gen_reg_rtx (Pmode);
5837               emit_insn (gen_symGOTPLT2reg (reg, func));
5838               func = reg;
5839             }
5840           else
5841             func = legitimize_pic_address (func, Pmode, 0);
5842         }
5844       r0 = gen_rtx_REG (SImode, R0_REG);
5845       r1 = gen_rtx_REG (SImode, R1_REG);
5847       /* Since such a call function may use all call-clobbered
5848          registers, we force a mode switch earlier, so that we don't
5849          run out of registers when adjusting fpscr for the call.  */
5850       emit_insn (gen_force_mode_for_call ());
5852       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5853       if (flag_pic)
5854         {
5855           rtx reg = gen_reg_rtx (Pmode);
5857           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5858           operands[0] = reg;
5859         }
5860       operands[0] = force_reg (SImode, operands[0]);
5862       emit_move_insn (r0, func);
5863       emit_move_insn (r1, cookie_rtx);
5865       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5866         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5867                                                    operands[2]));
5868       else
5869         emit_call_insn (gen_call_compact (operands[0], operands[1],
5870                                           operands[2]));
5872       DONE;
5873     }
5874   else if (TARGET_SHCOMPACT && flag_pic
5875            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5876            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5877     {
5878       rtx reg = gen_reg_rtx (Pmode);
5880       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5881       XEXP (operands[0], 0) = reg;
5882     }
5883   if (flag_pic && TARGET_SH2
5884       && GET_CODE (operands[0]) == MEM
5885       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5886     {
5887       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5888       DONE;
5889     }
5890   else
5891   {
5892     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5893     operands[1] = operands[2];
5894   }
5896   emit_call_insn (gen_calli (operands[0], operands[1]));
5897   DONE;
5900 (define_insn "call_pop_compact"
5901   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5902          (match_operand 1 "" ""))
5903    (match_operand 2 "immediate_operand" "n")
5904    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5905                                  (match_operand 3 "immediate_operand" "n")))
5906    (use (reg:SI R0_REG))
5907    (use (reg:SI R1_REG))
5908    (use (reg:PSI FPSCR_REG))
5909    (clobber (reg:SI PR_REG))]
5910   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5911   "jsr  @%0%#"
5912   [(set_attr "type" "call")
5913    (set (attr "fp_mode")
5914         (if_then_else (eq_attr "fpu_single" "yes")
5915                       (const_string "single") (const_string "double")))
5916    (set_attr "needs_delay_slot" "yes")])
5918 (define_insn "call_pop_compact_rettramp"
5919   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5920          (match_operand 1 "" ""))
5921    (match_operand 2 "immediate_operand" "n")
5922    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5923                                  (match_operand 3 "immediate_operand" "n")))
5924    (use (reg:SI R0_REG))
5925    (use (reg:SI R1_REG))
5926    (use (reg:PSI FPSCR_REG))
5927    (clobber (reg:SI R10_REG))
5928    (clobber (reg:SI PR_REG))]
5929   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5930   "jsr  @%0%#"
5931   [(set_attr "type" "call")
5932    (set (attr "fp_mode")
5933         (if_then_else (eq_attr "fpu_single" "yes")
5934                       (const_string "single") (const_string "double")))
5935    (set_attr "needs_delay_slot" "yes")])
5937 (define_expand "call_pop"
5938   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5939                     (match_operand 1 "" ""))
5940              (match_operand 2 "" "")
5941              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5942                                            (match_operand 3 "" "")))])]
5943   "TARGET_SHCOMPACT"
5944   "
5946   if (operands[2] && INTVAL (operands[2]))
5947     {
5948       rtx cookie_rtx = operands[2];
5949       long cookie = INTVAL (cookie_rtx);
5950       rtx func = XEXP (operands[0], 0);
5951       rtx r0, r1;
5953       if (flag_pic)
5954         {
5955           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5956             {
5957               rtx reg = gen_reg_rtx (Pmode);
5959               emit_insn (gen_symGOTPLT2reg (reg, func));
5960               func = reg;
5961             }
5962           else
5963             func = legitimize_pic_address (func, Pmode, 0);
5964         }
5966       r0 = gen_rtx_REG (SImode, R0_REG);
5967       r1 = gen_rtx_REG (SImode, R1_REG);
5969       /* Since such a call function may use all call-clobbered
5970          registers, we force a mode switch earlier, so that we don't
5971          run out of registers when adjusting fpscr for the call.  */
5972       emit_insn (gen_force_mode_for_call ());
5974       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5975       if (flag_pic)
5976         {
5977           rtx reg = gen_reg_rtx (Pmode);
5979           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5980           operands[0] = reg;
5981         }
5982       operands[0] = force_reg (SImode, operands[0]);
5984       emit_move_insn (r0, func);
5985       emit_move_insn (r1, cookie_rtx);
5987       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5988         emit_call_insn (gen_call_pop_compact_rettramp
5989                         (operands[0], operands[1], operands[2], operands[3]));
5990       else
5991         emit_call_insn (gen_call_pop_compact
5992                         (operands[0], operands[1], operands[2], operands[3]));
5994       DONE;
5995     }
5997   abort ();
6000 (define_expand "call_value"
6001   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6002                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6003                                  (match_operand 2 "" "")))
6004               (match_operand 3 "" "")
6005               (use (reg:PSI FPSCR_REG))
6006               (clobber (reg:SI PR_REG))])]
6007   ""
6008   "
6010   if (TARGET_SHMEDIA)
6011     {
6012       operands[1] = XEXP (operands[1], 0);
6013       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6014         {
6015           if (! SYMBOL_REF_LOCAL_P (operands[1]))
6016             {
6017               rtx reg = gen_reg_rtx (Pmode);
6019               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6020               operands[1] = reg;
6021             }
6022           else
6023             {
6024               operands[1] = gen_sym2PIC (operands[1]);
6025               PUT_MODE (operands[1], Pmode);
6026             }
6027         }
6028       if (GET_MODE (operands[1]) == SImode)
6029         {
6030           if (GET_CODE (operands[1]) == REG)
6031             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6032           else if (GET_CODE (operands[1]) == SUBREG)
6033             {
6034               operands[1] = SUBREG_REG (operands[1]);
6035               if (GET_MODE (operands[1]) != DImode)
6036                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6037             }
6038           else if (TARGET_SHMEDIA64)
6039             {
6040               operands[1] = shallow_copy_rtx (operands[1]);
6041               PUT_MODE (operands[1], DImode);
6042             }
6043           else
6044             {
6045               rtx reg = gen_reg_rtx (DImode);
6047               operands[1] = copy_to_mode_reg (SImode, operands[1]);
6048               emit_insn (gen_extendsidi2 (reg, operands[1]));
6049               operands[1] = reg;
6050             }
6051         }
6052       if (! target_reg_operand (operands[1], DImode))
6053         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6054       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6055                                             operands[2]));
6056       DONE;
6057     }
6058   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6059     {
6060       rtx cookie_rtx = operands[3];
6061       long cookie = INTVAL (cookie_rtx);
6062       rtx func = XEXP (operands[1], 0);
6063       rtx r0, r1;
6065       if (flag_pic)
6066         {
6067           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6068             {
6069               rtx reg = gen_reg_rtx (Pmode);
6071               emit_insn (gen_symGOTPLT2reg (reg, func));
6072               func = reg;
6073             }
6074           else
6075             func = legitimize_pic_address (func, Pmode, 0);
6076         }
6078       r0 = gen_rtx_REG (SImode, R0_REG);
6079       r1 = gen_rtx_REG (SImode, R1_REG);
6081       /* Since such a call function may use all call-clobbered
6082          registers, we force a mode switch earlier, so that we don't
6083          run out of registers when adjusting fpscr for the call.  */
6084       emit_insn (gen_force_mode_for_call ());
6086       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6087       if (flag_pic)
6088         {
6089           rtx reg = gen_reg_rtx (Pmode);
6091           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6092           operands[1] = reg;
6093         }
6094       operands[1] = force_reg (SImode, operands[1]);
6096       emit_move_insn (r0, func);
6097       emit_move_insn (r1, cookie_rtx);
6099       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6100         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6101                                                          operands[1],
6102                                                          operands[2],
6103                                                          operands[3]));
6104       else
6105         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6106                                                 operands[2], operands[3]));
6108       DONE;
6109     }
6110   else if (TARGET_SHCOMPACT && flag_pic
6111            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6112            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6113     {
6114       rtx reg = gen_reg_rtx (Pmode);
6116       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6117       XEXP (operands[1], 0) = reg;
6118     }
6119   if (flag_pic && TARGET_SH2
6120       && GET_CODE (operands[1]) == MEM
6121       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6122     {
6123       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6124                                             operands[2]));
6125       DONE;
6126     }
6127   else
6128     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6130   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6131   DONE;
6134 (define_insn "sibcalli"
6135   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6136          (match_operand 1 "" ""))
6137    (use (reg:PSI FPSCR_REG))
6138    (return)]
6139   "TARGET_SH1"
6140   "jmp  @%0%#"
6141   [(set_attr "needs_delay_slot" "yes")
6142    (set (attr "fp_mode")
6143         (if_then_else (eq_attr "fpu_single" "yes")
6144                       (const_string "single") (const_string "double")))
6145    (set_attr "type" "jump_ind")])
6147 (define_insn "sibcalli_pcrel"
6148   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6149          (match_operand 1 "" ""))
6150    (use (match_operand 2 "" ""))
6151    (use (reg:PSI FPSCR_REG))
6152    (return)]
6153   "TARGET_SH2"
6154   "braf %0\\n%O2:%#"
6155   [(set_attr "needs_delay_slot" "yes")
6156    (set (attr "fp_mode")
6157         (if_then_else (eq_attr "fpu_single" "yes")
6158                       (const_string "single") (const_string "double")))
6159    (set_attr "type" "jump_ind")])
6161 (define_insn_and_split "sibcall_pcrel"
6162   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6163          (match_operand 1 "" ""))
6164    (use (reg:PSI FPSCR_REG))
6165    (clobber (match_scratch:SI 2 "=k"))
6166    (return)]
6167   "TARGET_SH2"
6168   "#"
6169   "reload_completed"
6170   [(const_int 0)]
6171   "
6173   rtx lab = PATTERN (gen_call_site ());
6174   rtx call_insn;
6176   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6177   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6178                                                   lab));
6179   SIBLING_CALL_P (call_insn) = 1;
6180   DONE;
6182   [(set_attr "needs_delay_slot" "yes")
6183    (set (attr "fp_mode")
6184         (if_then_else (eq_attr "fpu_single" "yes")
6185                       (const_string "single") (const_string "double")))
6186    (set_attr "type" "jump_ind")])
6188 (define_insn "sibcall_compact"
6189   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6190          (match_operand 1 "" ""))
6191    (return)
6192    (use (match_operand:SI 2 "register_operand" "z,x"))
6193    (use (reg:SI R1_REG))
6194    (use (reg:PSI FPSCR_REG))
6195    ;; We want to make sure the `x' above will only match MACH_REG
6196    ;; because sibcall_epilogue may clobber MACL_REG.
6197    (clobber (reg:SI MACL_REG))]
6198   "TARGET_SHCOMPACT"
6199   "@
6200         jmp     @%0%#
6201         jmp     @%0\\n  sts     %2, r0"
6202   [(set_attr "needs_delay_slot" "yes,no")
6203    (set_attr "length" "2,4")
6204    (set (attr "fp_mode") (const_string "single"))
6205    (set_attr "type" "jump_ind")])
6207 (define_insn "sibcall_media"
6208   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6209          (match_operand 1 "" ""))
6210    (use (reg:SI PR_MEDIA_REG))
6211    (return)]
6212   "TARGET_SHMEDIA"
6213   "blink        %0, r63"
6214   [(set_attr "type" "jump_media")])
6216 (define_expand "sibcall"
6217   [(parallel
6218     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6219            (match_operand 1 "" ""))
6220      (match_operand 2 "" "")
6221      (use (reg:PSI FPSCR_REG))
6222      (return)])]
6223   ""
6224   "
6226   if (TARGET_SHMEDIA)
6227     {
6228       operands[0] = XEXP (operands[0], 0);
6229       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6230         {
6231           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6232             {
6233               rtx reg = gen_reg_rtx (Pmode);
6235               /* We must not use GOTPLT for sibcalls, because PIC_REG
6236                  must be restored before the PLT code gets to run.  */
6237               emit_insn (gen_symGOT2reg (reg, operands[0]));
6238               operands[0] = reg;
6239             }
6240           else
6241             {
6242               operands[0] = gen_sym2PIC (operands[0]);
6243               PUT_MODE (operands[0], Pmode);
6244             }
6245         }
6246       if (GET_MODE (operands[0]) == SImode)
6247         {
6248           if (GET_CODE (operands[0]) == REG)
6249             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6250           else if (GET_CODE (operands[0]) == SUBREG)
6251             {
6252               operands[0] = SUBREG_REG (operands[0]);
6253               if (GET_MODE (operands[0]) != DImode)
6254                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6255             }
6256           else
6257             {
6258               operands[0] = shallow_copy_rtx (operands[0]);
6259               PUT_MODE (operands[0], DImode);
6260             }
6261         }
6262       if (! target_reg_operand (operands[0], DImode))
6263         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6264       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6265       DONE;
6266     }
6267   else if (TARGET_SHCOMPACT && operands[2]
6268            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6269     {
6270       rtx cookie_rtx = operands[2];
6271       long cookie = INTVAL (cookie_rtx);
6272       rtx func = XEXP (operands[0], 0);
6273       rtx mach, r1;
6275       if (flag_pic)
6276         {
6277           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6278             {
6279               rtx reg = gen_reg_rtx (Pmode);
6281               emit_insn (gen_symGOT2reg (reg, func));
6282               func = reg;
6283             }
6284           else
6285             func = legitimize_pic_address (func, Pmode, 0);
6286         }
6288       /* FIXME: if we could tell whether all argument registers are
6289          already taken, we could decide whether to force the use of
6290          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6291          simple way to tell.  We could use the CALL_COOKIE, but we
6292          can't currently tell a register used for regular argument
6293          passing from one that is unused.  If we leave it up to reload
6294          to decide which register to use, it seems to always choose
6295          R0_REG, which leaves no available registers in SIBCALL_REGS
6296          to hold the address of the trampoline.  */
6297       mach = gen_rtx_REG (SImode, MACH_REG);
6298       r1 = gen_rtx_REG (SImode, R1_REG);
6300       /* Since such a call function may use all call-clobbered
6301          registers, we force a mode switch earlier, so that we don't
6302          run out of registers when adjusting fpscr for the call.  */
6303       emit_insn (gen_force_mode_for_call ());
6305       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6306       if (flag_pic)
6307         {
6308           rtx reg = gen_reg_rtx (Pmode);
6310           emit_insn (gen_symGOT2reg (reg, operands[0]));
6311           operands[0] = reg;
6312         }
6313       operands[0] = force_reg (SImode, operands[0]);
6315       /* We don't need a return trampoline, since the callee will
6316          return directly to the upper caller.  */
6317       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6318         {
6319           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6320           cookie_rtx = GEN_INT (cookie);
6321         }
6323       emit_move_insn (mach, func);
6324       emit_move_insn (r1, cookie_rtx);
6326       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6327       DONE;
6328     }
6329   else if (TARGET_SHCOMPACT && flag_pic
6330            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6331            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6332     {
6333       rtx reg = gen_reg_rtx (Pmode);
6335       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6336       XEXP (operands[0], 0) = reg;
6337     }
6338   if (flag_pic && TARGET_SH2
6339       && GET_CODE (operands[0]) == MEM
6340       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6341       /* The PLT needs the PIC register, but the epilogue would have
6342          to restore it, so we can only use PC-relative PIC calls for
6343          static functions.  */
6344       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6345     {
6346       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6347       DONE;
6348     }
6349   else
6350     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6352   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6353   DONE;
6356 (define_expand "sibcall_value"
6357   [(set (match_operand 0 "" "")
6358         (call (match_operand 1 "" "")
6359               (match_operand 2 "" "")))
6360    (match_operand 3 "" "")]
6361   ""
6362   "
6364   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6365   DONE;
6368 (define_insn "call_value_pop_compact"
6369   [(set (match_operand 0 "" "=rf")
6370         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6371               (match_operand 2 "" "")))
6372    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6373                                  (match_operand 4 "immediate_operand" "n")))
6374    (match_operand 3 "immediate_operand" "n")
6375    (use (reg:SI R0_REG))
6376    (use (reg:SI R1_REG))
6377    (use (reg:PSI FPSCR_REG))
6378    (clobber (reg:SI PR_REG))]
6379   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6380   "jsr  @%1%#"
6381   [(set_attr "type" "call")
6382    (set (attr "fp_mode")
6383         (if_then_else (eq_attr "fpu_single" "yes")
6384                       (const_string "single") (const_string "double")))
6385    (set_attr "needs_delay_slot" "yes")])
6387 (define_insn "call_value_pop_compact_rettramp"
6388   [(set (match_operand 0 "" "=rf")
6389         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6390               (match_operand 2 "" "")))
6391    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6392                                  (match_operand 4 "immediate_operand" "n")))
6393    (match_operand 3 "immediate_operand" "n")
6394    (use (reg:SI R0_REG))
6395    (use (reg:SI R1_REG))
6396    (use (reg:PSI FPSCR_REG))
6397    (clobber (reg:SI R10_REG))
6398    (clobber (reg:SI PR_REG))]
6399   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6400   "jsr  @%1%#"
6401   [(set_attr "type" "call")
6402    (set (attr "fp_mode")
6403         (if_then_else (eq_attr "fpu_single" "yes")
6404                       (const_string "single") (const_string "double")))
6405    (set_attr "needs_delay_slot" "yes")])
6407 (define_expand "call_value_pop"
6408   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6409                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6410                                  (match_operand 2 "" "")))
6411               (match_operand 3 "" "")
6412               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6413                                             (match_operand 4 "" "")))])]
6414   "TARGET_SHCOMPACT"
6415   "
6417   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6418     {
6419       rtx cookie_rtx = operands[3];
6420       long cookie = INTVAL (cookie_rtx);
6421       rtx func = XEXP (operands[1], 0);
6422       rtx r0, r1;
6424       if (flag_pic)
6425         {
6426           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6427             {
6428               rtx reg = gen_reg_rtx (Pmode);
6430               emit_insn (gen_symGOTPLT2reg (reg, func));
6431               func = reg;
6432             }
6433           else
6434             func = legitimize_pic_address (func, Pmode, 0);
6435         }
6437       r0 = gen_rtx_REG (SImode, R0_REG);
6438       r1 = gen_rtx_REG (SImode, R1_REG);
6440       /* Since such a call function may use all call-clobbered
6441          registers, we force a mode switch earlier, so that we don't
6442          run out of registers when adjusting fpscr for the call.  */
6443       emit_insn (gen_force_mode_for_call ());
6445       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6446       if (flag_pic)
6447         {
6448           rtx reg = gen_reg_rtx (Pmode);
6450           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6451           operands[1] = reg;
6452         }
6453       operands[1] = force_reg (SImode, operands[1]);
6455       emit_move_insn (r0, func);
6456       emit_move_insn (r1, cookie_rtx);
6458       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6459         emit_call_insn (gen_call_value_pop_compact_rettramp
6460                         (operands[0], operands[1], operands[2],
6461                          operands[3], operands[4]));
6462       else
6463         emit_call_insn (gen_call_value_pop_compact
6464                         (operands[0], operands[1], operands[2],
6465                          operands[3], operands[4]));
6467       DONE;
6468     }
6470   abort ();
6473 (define_expand "sibcall_epilogue"
6474   [(return)]
6475   ""
6476   "
6478   sh_expand_epilogue (1);
6479   if (TARGET_SHCOMPACT)
6480     {
6481       rtx insn, set;
6483       /* If epilogue clobbers r0, preserve it in macl.  */
6484       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6485         if ((set = single_set (insn))
6486             && GET_CODE (SET_DEST (set)) == REG
6487             && REGNO (SET_DEST (set)) == R0_REG)
6488           {
6489             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6490             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6491             rtx i;
6493             /* We can't tell at this point whether the sibcall is a
6494                sibcall_compact and, if it is, whether it uses r0 or
6495                mach as operand 2, so let the instructions that
6496                preserve r0 be optimized away if r0 turns out to be
6497                dead.  */
6498             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6499             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6500                                                REG_NOTES (i));
6501             i = emit_move_insn (r0, tmp);
6502             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6503                                                REG_NOTES (i));
6504             break;
6505           }
6506     }
6507   DONE;
6510 (define_insn "indirect_jump_compact"
6511   [(set (pc)
6512         (match_operand:SI 0 "arith_reg_operand" "r"))]
6513   "TARGET_SH1"
6514   "jmp  @%0%#"
6515   [(set_attr "needs_delay_slot" "yes")
6516    (set_attr "type" "jump_ind")])
6518 (define_expand "indirect_jump"
6519   [(set (pc)
6520         (match_operand 0 "register_operand" ""))]
6521   ""
6522   "
6524   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6525     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6528 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6529 ;; which can be present in structured code from indirect jumps which can not
6530 ;; be present in structured code.  This allows -fprofile-arcs to work.
6532 ;; For SH1 processors.
6533 (define_insn "casesi_jump_1"
6534   [(set (pc)
6535         (match_operand:SI 0 "register_operand" "r"))
6536    (use (label_ref (match_operand 1 "" "")))]
6537   "TARGET_SH1"
6538   "jmp  @%0%#"
6539   [(set_attr "needs_delay_slot" "yes")
6540    (set_attr "type" "jump_ind")])
6542 ;; For all later processors.
6543 (define_insn "casesi_jump_2"
6544   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6545                       (label_ref (match_operand 1 "" ""))))
6546    (use (label_ref (match_operand 2 "" "")))]
6547   "TARGET_SH2
6548    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6549   "braf %0%#"
6550   [(set_attr "needs_delay_slot" "yes")
6551    (set_attr "type" "jump_ind")])
6553 (define_insn "casesi_jump_media"
6554   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6555    (use (label_ref (match_operand 1 "" "")))]
6556   "TARGET_SHMEDIA"
6557   "blink        %0, r63"
6558   [(set_attr "type" "jump_media")])
6560 ;; Call subroutine returning any type.
6561 ;; ??? This probably doesn't work.
6563 (define_expand "untyped_call"
6564   [(parallel [(call (match_operand 0 "" "")
6565                     (const_int 0))
6566               (match_operand 1 "" "")
6567               (match_operand 2 "" "")])]
6568   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
6569   "
6571   int i;
6573   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6575   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6576     {
6577       rtx set = XVECEXP (operands[2], 0, i);
6578       emit_move_insn (SET_DEST (set), SET_SRC (set));
6579     }
6581   /* The optimizer does not know that the call sets the function value
6582      registers we stored in the result block.  We avoid problems by
6583      claiming that all hard registers are used and clobbered at this
6584      point.  */
6585   emit_insn (gen_blockage ());
6587   DONE;
6590 ;; ------------------------------------------------------------------------
6591 ;; Misc insns
6592 ;; ------------------------------------------------------------------------
6594 (define_insn "dect"
6595   [(set (reg:SI T_REG)
6596         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6597    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6598   "TARGET_SH2"
6599   "dt   %0"
6600   [(set_attr "type" "arith")])
6602 (define_insn "nop"
6603   [(const_int 0)]
6604   ""
6605   "nop")
6607 ;; Load address of a label. This is only generated by the casesi expand,
6608 ;; and by machine_dependent_reorg (fixing up fp moves).
6609 ;; This must use unspec, because this only works for labels that are
6610 ;; within range,
6612 (define_insn "mova"
6613   [(set (reg:SI R0_REG)
6614         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6615   "TARGET_SH1"
6616   "mova %O0,r0"
6617   [(set_attr "in_delay_slot" "no")
6618    (set_attr "type" "arith")])
6620 ;; machine_dependent_reorg will make this a `mova'.
6621 (define_insn "mova_const"
6622   [(set (reg:SI R0_REG)
6623         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6624   "TARGET_SH1"
6625   "#"
6626   [(set_attr "in_delay_slot" "no")
6627    (set_attr "type" "arith")])
6629 (define_expand "GOTaddr2picreg"
6630   [(set (reg:SI R0_REG)
6631         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6632                    UNSPEC_MOVA))
6633    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6634    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6635   "" "
6637   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6638   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6640   if (TARGET_SH5)
6641     operands[1] = gen_datalabel_ref (operands[1]);
6643   if (TARGET_SHMEDIA)
6644     {
6645       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6646       rtx dipic = operands[0];
6647       rtx lab = PATTERN (gen_call_site ());
6648       rtx insn, equiv;
6650       equiv = operands[1];
6651       operands[1] = gen_rtx_MINUS (DImode,
6652                                    operands[1],
6653                                    gen_rtx_CONST
6654                                    (DImode,
6655                                     gen_rtx_MINUS (DImode,
6656                                                    gen_rtx_CONST (DImode,
6657                                                                   lab),
6658                                                    pc_rtx)));
6659       operands[1] = gen_sym2PIC (operands[1]);
6660       PUT_MODE (operands[1], DImode);
6662       if (GET_MODE (dipic) != DImode)
6663         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6665       if (TARGET_SHMEDIA64)
6666         emit_insn (gen_movdi_const (dipic, operands[1]));
6667       else
6668         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6670       emit_insn (gen_ptrel (tr, dipic, lab));
6672       if (GET_MODE (operands[0]) != GET_MODE (tr))
6673         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6675       insn = emit_move_insn (operands[0], tr);
6677       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6678                                             REG_NOTES (insn));
6680       DONE;
6681     }
6685 (define_insn "*ptb"
6686   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6687         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6688                              UNSPEC_DATALABEL)))]
6689   "TARGET_SHMEDIA && flag_pic
6690    && EXTRA_CONSTRAINT_Csy (operands[1])"
6691   "ptb/u        datalabel %1, %0"
6692   [(set_attr "type" "pt_media")
6693    (set_attr "length" "*")])
6695 (define_insn "ptrel"
6696   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6697         (plus:DI (match_operand:DI 1 "register_operand" "r")
6698               (pc)))
6699    (match_operand:DI 2 "" "")]
6700   "TARGET_SHMEDIA"
6701   "%O2: ptrel/u %1, %0"
6702   [(set_attr "type" "ptabs_media")])
6704 (define_expand "builtin_setjmp_receiver"
6705   [(match_operand 0 "" "")]
6706   "flag_pic"
6707   "
6709   emit_insn (gen_GOTaddr2picreg ());
6710   DONE;
6713 (define_expand "call_site"
6714   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6715   "TARGET_SH1"
6716   "
6718   static HOST_WIDE_INT i = 0;
6719   operands[0] = GEN_INT (i);
6720   i++;
6723 (define_expand "sym_label2reg"
6724   [(set (match_operand:SI 0 "" "")
6725         (const:SI (minus:SI
6726                    (const:SI
6727                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6728                    (const:SI
6729                     (plus:SI
6730                      (match_operand:SI 2 "" "")
6731                      (const_int 2))))))]
6732   "TARGET_SH1" "")
6734 (define_expand "symGOT_load"
6735   [(set (match_dup 2) (match_operand 1 "" ""))
6736    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6737    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6738   ""
6739   "
6741   rtx insn;
6743   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6744   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6746   if (TARGET_SHMEDIA)
6747     {
6748       rtx reg = operands[2];
6750       if (GET_MODE (reg) != DImode)
6751         reg = gen_rtx_SUBREG (DImode, reg, 0);
6753       if (flag_pic > 1)
6754         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6755       else
6756         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6757     }
6758   else
6759     emit_move_insn (operands[2], operands[1]);
6761   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6762                                              operands[2],
6763                                              gen_rtx_REG (Pmode, PIC_REG)));
6765   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6767   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6768                                                                   0), 0, 0),
6769                                         REG_NOTES (insn));
6771   DONE;
6774 (define_expand "sym2GOT"
6775   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6776   ""
6777   "")
6779 (define_expand "symGOT2reg"
6780   [(match_operand 0 "" "") (match_operand 1 "" "")]
6781   ""
6782   "
6784   rtx gotsym, insn;
6786   gotsym = gen_sym2GOT (operands[1]);
6787   PUT_MODE (gotsym, Pmode);
6788   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6790   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
6792   DONE;
6795 (define_expand "sym2GOTPLT"
6796   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6797   ""
6798   "")
6800 (define_expand "symGOTPLT2reg"
6801   [(match_operand 0 "" "") (match_operand 1 "" "")]
6802   ""
6803   "
6805   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6806   DONE;
6809 (define_expand "sym2GOTOFF"
6810   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6811   ""
6812   "")
6814 (define_expand "symGOTOFF2reg"
6815   [(match_operand 0 "" "") (match_operand 1 "" "")]
6816   ""
6817   "
6819   rtx gotoffsym, insn;
6820   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6822   gotoffsym = gen_sym2GOTOFF (operands[1]);
6823   PUT_MODE (gotoffsym, Pmode);
6824   emit_move_insn (t, gotoffsym);
6825   insn = emit_move_insn (operands[0],
6826                          gen_rtx_PLUS (Pmode, t,
6827                                        gen_rtx_REG (Pmode, PIC_REG)));
6829   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6830                                         REG_NOTES (insn));
6832   DONE;
6835 (define_expand "symPLT_label2reg"
6836   [(set (match_operand:SI 0 "" "")
6837         (const:SI (minus:SI
6838                    (const:SI
6839                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6840                    (const:SI
6841                     (minus:SI
6842                      (const:SI (plus:SI
6843                                 (match_operand:SI 2 "" "")
6844                                 (const_int 2)))
6845                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6846    ;; Even though the PIC register is not really used by the call
6847    ;; sequence in which this is expanded, the PLT code assumes the PIC
6848    ;; register is set, so we must not skip its initialization.  Since
6849    ;; we only use this expand as part of calling sequences, and never
6850    ;; to take the address of a function, this is the best point to
6851    ;; insert the (use).  Using the PLT to take the address of a
6852    ;; function would be wrong, not only because the PLT entry could
6853    ;; then be called from a function that doesn't initialize the PIC
6854    ;; register to the proper GOT, but also because pointers to the
6855    ;; same function might not compare equal, should they be set by
6856    ;; different shared libraries.
6857    (use (reg:SI PIC_REG))]
6858   "TARGET_SH1"
6859   "")
6861 (define_expand "sym2PIC"
6862   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6863   ""
6864   "")
6866 ;; TLS code generation.
6867 ;; ??? this should be a define_insn_and_split
6868 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6869 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6870 ;; for details.
6872 (define_insn "tls_global_dynamic"
6873   [(set (match_operand:SI 0 "register_operand" "=&z")
6874         (call (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
6875                                   UNSPEC_TLSGD))
6876               (const_int 0)))
6877    (use (reg:PSI FPSCR_REG))
6878    (use (reg:SI PIC_REG))
6879    (clobber (reg:SI PR_REG))
6880    (clobber (scratch:SI))]
6881   "TARGET_SH1"
6882   "*
6884   return \"\\
6885 mov.l\\t1f,r4\\n\\
6886 \\tmova\\t2f,r0\\n\\
6887 \\tmov.l\\t2f,r1\\n\\
6888 \\tadd\\tr0,r1\\n\\
6889 \\tjsr\\t@r1\\n\\
6890 \\tadd\\tr12,r4\\n\\
6891 \\tbra\\t3f\\n\\
6892 \\tnop\\n\\
6893 \\t.align\\t2\\n\\
6894 1:\\t.long\\t%a1@TLSGD\\n\\
6895 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6896 3:\";
6898   [(set_attr "type" "tls_load")
6899    (set_attr "length" "26")])
6901 (define_insn "tls_local_dynamic"
6902   [(set (match_operand:SI 0 "register_operand" "=&z")
6903         (call (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
6904                                   UNSPEC_TLSLDM))
6905               (const_int 0)))
6906    (use (reg:PSI FPSCR_REG))
6907    (use (reg:SI PIC_REG))
6908    (clobber (reg:SI PR_REG))
6909    (clobber (scratch:SI))]
6910   "TARGET_SH1"
6911   "*
6913   return \"\\
6914 mov.l\\t1f,r4\\n\\
6915 \\tmova\\t2f,r0\\n\\
6916 \\tmov.l\\t2f,r1\\n\\
6917 \\tadd\\tr0,r1\\n\\
6918 \\tjsr\\t@r1\\n\\
6919 \\tadd\\tr12,r4\\n\\
6920 \\tbra\\t3f\\n\\
6921 \\tnop\\n\\
6922 \\t.align\\t2\\n\\
6923 1:\\t.long\\t%a1@TLSLDM\\n\\
6924 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6925 3:\";
6927   [(set_attr "type" "tls_load")
6928    (set_attr "length" "26")])
6930 (define_expand "sym2DTPOFF"
6931   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6932   ""
6933   "")
6935 (define_expand "symDTPOFF2reg"
6936   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6937   ""
6938   "
6940   rtx dtpoffsym, insn;
6941   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6943   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6944   PUT_MODE (dtpoffsym, Pmode);
6945   emit_move_insn (t, dtpoffsym);
6946   insn = emit_move_insn (operands[0],
6947                          gen_rtx_PLUS (Pmode, t, operands[2]));
6948   DONE;
6951 (define_expand "sym2GOTTPOFF"
6952   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6953   ""
6954   "")
6956 (define_insn "tls_initial_exec"
6957   [(set (match_operand:SI 0 "register_operand" "=&r")
6958         (unspec:SI [(match_operand:SI 1 "" "")]
6959                     UNSPEC_TLSIE))
6960    (use (reg:SI GBR_REG))
6961    (use (reg:SI PIC_REG))
6962    (clobber (reg:SI R0_REG))]
6963   ""
6964   "*
6966   return \"\\
6967 mov.l\\t1f,r0\\n\\
6968 \\tstc\\tgbr,%0\\n\\
6969 \\tmov.l\\t@(r0,r12),r0\\n\\
6970 \\tbra\\t2f\\n\\
6971 \\tadd\\tr0,%0\\n\\
6972 \\t.align\\t2\\n\\
6973 1:\\t.long\\t%a1\\n\\
6974 2:\";
6976   [(set_attr "type" "tls_load")
6977    (set_attr "length" "16")])
6979 (define_expand "sym2TPOFF"
6980   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6981   ""
6982   "")
6984 (define_expand "symTPOFF2reg"
6985   [(match_operand 0 "" "") (match_operand 1 "" "")]
6986   ""
6987   "
6989   rtx tpoffsym, insn;
6991   tpoffsym = gen_sym2TPOFF (operands[1]);
6992   PUT_MODE (tpoffsym, Pmode);
6993   insn = emit_move_insn (operands[0], tpoffsym);
6994   DONE;
6997 (define_insn "load_gbr"
6998   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6999    (use (reg:SI GBR_REG))]
7000   ""
7001   "stc  gbr,%0"
7002   [(set_attr "type" "tls_load")])
7004 ;; case instruction for switch statements.
7006 ;; Operand 0 is index
7007 ;; operand 1 is the minimum bound
7008 ;; operand 2 is the maximum bound - minimum bound + 1
7009 ;; operand 3 is CODE_LABEL for the table;
7010 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7012 (define_expand "casesi"
7013   [(match_operand:SI 0 "arith_reg_operand" "")
7014    (match_operand:SI 1 "arith_reg_operand" "")
7015    (match_operand:SI 2 "arith_reg_operand" "")
7016    (match_operand 3 "" "") (match_operand 4 "" "")]
7017   ""
7018   "
7020   rtx reg = gen_reg_rtx (SImode);
7021   rtx reg2 = gen_reg_rtx (SImode);
7022   if (TARGET_SHMEDIA)
7023     {
7024       rtx reg = gen_reg_rtx (DImode);
7025       rtx reg2 = gen_reg_rtx (DImode);
7026       rtx reg3 = gen_reg_rtx (DImode);
7027       rtx reg4 = gen_reg_rtx (DImode);
7028       rtx reg5 = gen_reg_rtx (DImode);
7030       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7031       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7032       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7034       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7035       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7036       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7037       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7038       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7039                                                (DImode, operands[3])));
7040       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7041       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7042       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7043       emit_barrier ();
7044       DONE;
7045     }
7046   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7047   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7048   /* If optimizing, casesi_worker depends on the mode of the instruction
7049      before label it 'uses' - operands[3].  */
7050   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7051                            reg));
7052   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7053   if (TARGET_SH2)
7054     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7055   else
7056     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7057   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7058      operands[3], but to lab.  We will fix this up in
7059      machine_dependent_reorg.  */
7060   emit_barrier ();
7061   DONE;
7064 (define_expand "casesi_0"
7065   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7066    (set (match_dup 4) (minus:SI (match_dup 4)
7067                                 (match_operand:SI 1 "arith_operand" "")))
7068    (set (reg:SI T_REG)
7069         (gtu:SI (match_dup 4)
7070                 (match_operand:SI 2 "arith_reg_operand" "")))
7071    (set (pc)
7072         (if_then_else (ne (reg:SI T_REG)
7073                           (const_int 0))
7074                       (label_ref (match_operand 3 "" ""))
7075                       (pc)))]
7076   "TARGET_SH1"
7077   "")
7079 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7080 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7081 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7083 (define_insn "casesi_worker_0"
7084   [(set (match_operand:SI 0 "register_operand" "=r,r")
7085         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7086                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7087    (clobber (match_scratch:SI 3 "=X,1"))
7088    (clobber (match_scratch:SI 4 "=&z,z"))]
7089   "TARGET_SH1"
7090   "#")
7092 (define_split
7093   [(set (match_operand:SI 0 "register_operand" "")
7094         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7095                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7096    (clobber (match_scratch:SI 3 ""))
7097    (clobber (match_scratch:SI 4 ""))]
7098   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7099   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7100    (parallel [(set (match_dup 0)
7101               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7102                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7103               (clobber (match_dup 3))])
7104    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7105   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7107 (define_split
7108   [(set (match_operand:SI 0 "register_operand" "")
7109         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7110                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7111    (clobber (match_scratch:SI 3 ""))
7112    (clobber (match_scratch:SI 4 ""))]
7113   "TARGET_SH2 && reload_completed"
7114   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7115    (parallel [(set (match_dup 0)
7116               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7117                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7118               (clobber (match_dup 3))])]
7119   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7121 (define_insn "casesi_worker_1"
7122   [(set (match_operand:SI 0 "register_operand" "=r,r")
7123         (unspec:SI [(reg:SI R0_REG)
7124                     (match_operand:SI 1 "register_operand" "0,r")
7125                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7126    (clobber (match_scratch:SI 3 "=X,1"))]
7127   "TARGET_SH1"
7128   "*
7130   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7132   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7133     abort ();
7135   switch (GET_MODE (diff_vec))
7136     {
7137     case SImode:
7138       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7139     case HImode:
7140       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7141     case QImode:
7142       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7143         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7144       return \"mov.b    @(r0,%1),%0\";
7145     default:
7146       abort ();
7147     }
7149   [(set_attr "length" "4")])
7151 (define_insn "casesi_worker_2"
7152   [(set (match_operand:SI 0 "register_operand" "=r,r")
7153         (unspec:SI [(reg:SI R0_REG)
7154                     (match_operand:SI 1 "register_operand" "0,r")
7155                     (label_ref (match_operand 2 "" ""))
7156                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7157    (clobber (match_operand:SI 4 "" "=X,1"))]
7158   "TARGET_SH2 && reload_completed && flag_pic"
7159   "*
7161   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7162   const char *load;
7164   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7165     abort ();
7167   switch (GET_MODE (diff_vec))
7168     {
7169     case SImode:
7170       output_asm_insn (\"shll2    %1\", operands);
7171       load = \"mov.l    @(r0,%1),%0\"; break;
7172     case HImode:
7173       output_asm_insn (\"add    %1,%1\", operands);
7174       load = \"mov.w    @(r0,%1),%0\"; break;
7175     case QImode:
7176       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7177         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7178       else
7179         load = \"mov.b  @(r0,%1),%0\";
7180       break;
7181     default:
7182       abort ();
7183     }
7184   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7185   return load;
7187   [(set_attr "length" "8")])
7189 (define_insn "casesi_shift_media"
7190   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7191         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7192                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7193                     UNSPEC_CASESI)))]
7194   "TARGET_SHMEDIA"
7195   "*
7197   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7199   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7200     abort ();
7202   switch (GET_MODE (diff_vec))
7203     {
7204     case SImode:
7205       return \"shlli    %1, 2, %0\";
7206     case HImode:
7207       return \"shlli    %1, 1, %0\";
7208     case QImode:
7209       if (rtx_equal_p (operands[0], operands[1]))
7210         return \"\";
7211       return \"add      %1, r63, %0\";
7212     default:
7213       abort ();
7214     }
7216   [(set_attr "type" "arith_media")])
7218 (define_insn "casesi_load_media"
7219   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7220         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7221                          (match_operand 2 "arith_reg_operand" "r")
7222                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7223   "TARGET_SHMEDIA"
7224   "*
7226   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7228   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7229     abort ();
7231   switch (GET_MODE (diff_vec))
7232     {
7233     case SImode:
7234       return \"ldx.l    %1, %2, %0\";
7235     case HImode:
7236 #if 0
7237       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7238         return \"ldx.uw %1, %2, %0\";
7239 #endif
7240       return \"ldx.w    %1, %2, %0\";
7241     case QImode:
7242       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7243         return \"ldx.ub %1, %2, %0\";
7244       return \"ldx.b    %1, %2, %0\";
7245     default:
7246       abort ();
7247     }
7249   [(set_attr "type" "load_media")])
7251 (define_expand "return"
7252   [(return)]
7253   "reload_completed && ! sh_need_epilogue ()"
7254   "
7256   if (TARGET_SHMEDIA)
7257     {
7258       emit_jump_insn (gen_return_media ());
7259       DONE;
7260     }
7262   if (TARGET_SHCOMPACT
7263       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7264     {
7265       emit_jump_insn (gen_shcompact_return_tramp ());
7266       DONE;
7267     }
7270 (define_insn "*return_i"
7271   [(return)]
7272   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7273                     && (current_function_args_info.call_cookie
7274                         & CALL_COOKIE_RET_TRAMP (1)))
7275    && reload_completed"
7276   "%@   %#"
7277   [(set_attr "type" "return")
7278    (set_attr "needs_delay_slot" "yes")])
7280 (define_expand "shcompact_return_tramp"
7281   [(return)]
7282   "TARGET_SHCOMPACT
7283    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7284   "
7286   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7287   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7289   if (flag_pic)
7290     emit_insn (gen_symGOTPLT2reg (reg, sym));
7291   else
7292     emit_move_insn (reg, sym);
7294   emit_jump_insn (gen_shcompact_return_tramp_i ());
7295   DONE;
7298 (define_insn "shcompact_return_tramp_i"
7299   [(parallel [(return) (use (reg:SI R0_REG))])]
7300   "TARGET_SHCOMPACT
7301    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7302   "jmp  @r0%#"
7303   [(set_attr "type" "jump_ind")
7304    (set_attr "needs_delay_slot" "yes")])
7306 (define_insn "return_media_i"
7307   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7308   "TARGET_SHMEDIA && reload_completed"
7309   "blink        %0, r63"
7310   [(set_attr "type" "jump_media")])
7312 (define_insn "return_media_rte"
7313   [(return)]
7314   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7315   "rte"
7316   [(set_attr "type" "jump_media")])
7318 (define_expand "return_media"
7319   [(return)]
7320   "TARGET_SHMEDIA && reload_completed"
7321   "
7323   int tr_regno = sh_media_register_for_return ();
7324   rtx tr;
7326   if (current_function_interrupt)
7327     {
7328       emit_jump_insn (gen_return_media_rte ());
7329       DONE;
7330     }
7331   if (tr_regno < 0)
7332     {
7333       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7335       if (! call_really_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7336         abort ();
7337       tr_regno = TR0_REG;
7338       tr = gen_rtx_REG (DImode, tr_regno);
7339       emit_move_insn (tr, r18);
7340     }
7341   else
7342     tr = gen_rtx_REG (DImode, tr_regno);
7344   emit_jump_insn (gen_return_media_i (tr));
7345   DONE;
7348 (define_insn "shcompact_preserve_incoming_args"
7349   [(set (match_operand:SI 0 "register_operand" "+r")
7350         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7351   "TARGET_SHCOMPACT"
7352   ""
7353   [(set_attr "length" "0")])
7355 (define_insn "shcompact_incoming_args"
7356   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7357    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7358    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7359    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7360    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7361    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7362    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7363    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7364    (set (mem:BLK (reg:SI MACL_REG))
7365         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7366    (use (reg:SI R0_REG))
7367    (clobber (reg:SI R0_REG))
7368    (clobber (reg:SI MACL_REG))
7369    (clobber (reg:SI MACH_REG))
7370    (clobber (reg:SI PR_REG))]
7371   "TARGET_SHCOMPACT"
7372   "jsr  @r0%#"
7373   [(set_attr "needs_delay_slot" "yes")])
7375 (define_insn "shmedia_save_restore_regs_compact"
7376   [(set (reg:SI SP_REG)
7377         (plus:SI (reg:SI SP_REG)
7378                  (match_operand:SI 0 "immediate_operand" "i")))
7379    (use (reg:SI R0_REG))
7380    (clobber (reg:SI PR_REG))]
7381   "TARGET_SHCOMPACT
7382    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7383        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7384   "jsr @r0%#"
7385   [(set_attr "needs_delay_slot" "yes")])
7387 (define_expand "prologue"
7388   [(const_int 0)]
7389   ""
7390   "sh_expand_prologue (); DONE;")
7392 (define_expand "epilogue"
7393   [(return)]
7394   ""
7395   "
7397   sh_expand_epilogue (0);
7398   emit_jump_insn (gen_return ());
7399   DONE;
7402 (define_expand "eh_return"
7403   [(use (match_operand 0 "register_operand" ""))]
7404   ""
7406   rtx ra = operands[0];
7408   if (TARGET_SHMEDIA64)
7409     emit_insn (gen_eh_set_ra_di (ra));
7410   else
7411     emit_insn (gen_eh_set_ra_si (ra));
7413   DONE;
7416 ;; Clobber the return address on the stack.  We can't expand this
7417 ;; until we know where it will be put in the stack frame.
7419 (define_insn "eh_set_ra_si"
7420   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7421    (clobber (match_scratch:SI 1 "=&r"))]
7422   "! TARGET_SHMEDIA64"
7423   "#")
7425 (define_insn "eh_set_ra_di"
7426   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7427    (clobber (match_scratch:DI 1 "=&r"))]
7428   "TARGET_SHMEDIA64"
7429   "#")
7431 (define_split
7432   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7433    (clobber (match_scratch 1 ""))]
7434   "reload_completed"
7435   [(const_int 0)]
7436   "
7438   sh_set_return_address (operands[0], operands[1]);
7439   DONE;
7442 (define_insn "blockage"
7443   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7444   ""
7445   ""
7446   [(set_attr "length" "0")])
7448 ;; ------------------------------------------------------------------------
7449 ;; Scc instructions
7450 ;; ------------------------------------------------------------------------
7452 (define_insn "movt"
7453   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7454         (eq:SI (reg:SI T_REG) (const_int 1)))]
7455   "TARGET_SH1"
7456   "movt %0"
7457   [(set_attr "type" "arith")])
7459 (define_expand "seq"
7460   [(set (match_operand:SI 0 "arith_reg_operand" "")
7461         (match_dup 1))]
7462   ""
7463   "
7465   if (TARGET_SHMEDIA)
7466     {
7467       if (GET_MODE (operands[0]) != DImode)
7468         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7469       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7470       if (sh_compare_op1 != const0_rtx)
7471         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7472                                     ? GET_MODE (sh_compare_op0)
7473                                     : GET_MODE (sh_compare_op1),
7474                                     sh_compare_op1);
7476       switch (GET_MODE (sh_compare_op0))
7477         {
7478         case DImode:
7479           emit_insn (gen_cmpeqdi_media (operands[0],
7480                                         sh_compare_op0, sh_compare_op1));
7481           break;
7483         case SFmode:
7484           if (! TARGET_SHMEDIA_FPU)
7485             FAIL;
7486           emit_insn (gen_cmpeqsf_media (operands[0],
7487                                         sh_compare_op0, sh_compare_op1));
7488           break;
7490         case DFmode:
7491           if (! TARGET_SHMEDIA_FPU)
7492             FAIL;
7493           emit_insn (gen_cmpeqdf_media (operands[0],
7494                                         sh_compare_op0, sh_compare_op1));
7495           break;
7497         default:
7498           FAIL;
7499         }
7500       DONE;
7501     }
7502   if (sh_expand_t_scc (EQ, operands[0]))
7503     DONE;
7504   if (! currently_expanding_to_rtl)
7505     FAIL;
7506   operands[1] = prepare_scc_operands (EQ);
7509 (define_expand "slt"
7510   [(set (match_operand:SI 0 "arith_reg_operand" "")
7511         (match_dup 1))]
7512   ""
7513   "
7515   if (TARGET_SHMEDIA)
7516     {
7517       if (GET_MODE (operands[0]) != DImode)
7518         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7519       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7520       if (sh_compare_op1 != const0_rtx)
7521         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7522                                     ? GET_MODE (sh_compare_op0)
7523                                     : GET_MODE (sh_compare_op1),
7524                                     sh_compare_op1);
7526       switch (GET_MODE (sh_compare_op0))
7527         {
7528         case DImode:
7529           emit_insn (gen_cmpgtdi_media (operands[0],
7530                                         sh_compare_op1, sh_compare_op0));
7531           break;
7533         case SFmode:
7534           if (! TARGET_SHMEDIA_FPU)
7535             FAIL;
7536           emit_insn (gen_cmpgtsf_media (operands[0],
7537                                         sh_compare_op1, sh_compare_op0));
7538           break;
7540         case DFmode:
7541           if (! TARGET_SHMEDIA_FPU)
7542             FAIL;
7543           emit_insn (gen_cmpgtdf_media (operands[0],
7544                                         sh_compare_op1, sh_compare_op0));
7545           break;
7547         default:
7548           FAIL;
7549         }
7550       DONE;
7551     }
7552   if (! currently_expanding_to_rtl)
7553     FAIL;
7554   operands[1] = prepare_scc_operands (LT);
7557 (define_expand "sle"
7558   [(match_operand:SI 0 "arith_reg_operand" "")]
7559   ""
7560   "
7562   rtx tmp = sh_compare_op0;
7564   if (TARGET_SHMEDIA)
7565     {
7566       if (GET_MODE (operands[0]) != DImode)
7567         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7568       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7569       if (sh_compare_op1 != const0_rtx)
7570         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7571                                     ? GET_MODE (sh_compare_op0)
7572                                     : GET_MODE (sh_compare_op1),
7573                                     sh_compare_op1);
7575       switch (GET_MODE (sh_compare_op0))
7576         {
7577         case DImode:
7578           {
7579             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7581             emit_insn (gen_cmpgtdi_media (tmp,
7582                                           sh_compare_op0, sh_compare_op1));
7583             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7584             break;
7585           }
7587         case SFmode:
7588           if (! TARGET_SHMEDIA_FPU)
7589             FAIL;
7590           emit_insn (gen_cmpgesf_media (operands[0],
7591                                         sh_compare_op1, sh_compare_op0));
7592           break;
7594         case DFmode:
7595           if (! TARGET_SHMEDIA_FPU)
7596             FAIL;
7597           emit_insn (gen_cmpgedf_media (operands[0],
7598                                         sh_compare_op1, sh_compare_op0));
7599           break;
7601         default:
7602           FAIL;
7603         }
7604       DONE;
7605     }
7607   sh_compare_op0 = sh_compare_op1;
7608   sh_compare_op1 = tmp;
7609   emit_insn (gen_sge (operands[0]));
7610   DONE;
7613 (define_expand "sgt"
7614   [(set (match_operand:SI 0 "arith_reg_operand" "")
7615         (match_dup 1))]
7616   ""
7617   "
7619   if (TARGET_SHMEDIA)
7620     {
7621       if (GET_MODE (operands[0]) != DImode)
7622         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7623       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7624       if (sh_compare_op1 != const0_rtx)
7625         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7626                                     ? GET_MODE (sh_compare_op0)
7627                                     : GET_MODE (sh_compare_op1),
7628                                     sh_compare_op1);
7630       switch (GET_MODE (sh_compare_op0))
7631         {
7632         case DImode:
7633           emit_insn (gen_cmpgtdi_media (operands[0],
7634                                         sh_compare_op0, sh_compare_op1));
7635           break;
7637         case SFmode:
7638           if (! TARGET_SHMEDIA_FPU)
7639             FAIL;
7640           emit_insn (gen_cmpgtsf_media (operands[0],
7641                                         sh_compare_op0, sh_compare_op1));
7642           break;
7644         case DFmode:
7645           if (! TARGET_SHMEDIA_FPU)
7646             FAIL;
7647           emit_insn (gen_cmpgtdf_media (operands[0],
7648                                         sh_compare_op0, sh_compare_op1));
7649           break;
7651         default:
7652           FAIL;
7653         }
7654       DONE;
7655     }
7656   if (! currently_expanding_to_rtl)
7657     FAIL;
7658   operands[1] = prepare_scc_operands (GT);
7661 (define_expand "sge"
7662   [(set (match_operand:SI 0 "arith_reg_operand" "")
7663         (match_dup 1))]
7664   ""
7665   "
7667   if (TARGET_SHMEDIA)
7668     {
7669       if (GET_MODE (operands[0]) != DImode)
7670         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7671       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7672       if (sh_compare_op1 != const0_rtx)
7673         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7674                                     ? GET_MODE (sh_compare_op0)
7675                                     : GET_MODE (sh_compare_op1),
7676                                     sh_compare_op1);
7678       switch (GET_MODE (sh_compare_op0))
7679         {
7680         case DImode:
7681           {
7682             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7684             emit_insn (gen_cmpgtdi_media (tmp,
7685                                           sh_compare_op1, sh_compare_op0));
7686             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7687             break;
7688           }
7690         case SFmode:
7691           if (! TARGET_SHMEDIA_FPU)
7692             FAIL;
7693           emit_insn (gen_cmpgesf_media (operands[0],
7694                                         sh_compare_op0, sh_compare_op1));
7695           break;
7697         case DFmode:
7698           if (! TARGET_SHMEDIA_FPU)
7699             FAIL;
7700           emit_insn (gen_cmpgedf_media (operands[0],
7701                                         sh_compare_op0, sh_compare_op1));
7702           break;
7704         default:
7705           FAIL;
7706         }
7707       DONE;
7708     }
7710   if (! currently_expanding_to_rtl)
7711     FAIL;
7712   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7713     {
7714       if (TARGET_IEEE)
7715         {
7716           rtx lab = gen_label_rtx ();
7717           prepare_scc_operands (EQ);
7718           emit_jump_insn (gen_branch_true (lab));
7719           prepare_scc_operands (GT);
7720           emit_label (lab);
7721           emit_insn (gen_movt (operands[0]));
7722         }
7723       else
7724         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7725       DONE;
7726     }
7727   operands[1] = prepare_scc_operands (GE);
7730 (define_expand "sgtu"
7731   [(set (match_operand:SI 0 "arith_reg_operand" "")
7732         (match_dup 1))]
7733   ""
7734   "
7736   if (TARGET_SHMEDIA)
7737     {
7738       if (GET_MODE (operands[0]) != DImode)
7739         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7740       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7741       if (sh_compare_op1 != const0_rtx)
7742         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7743                                     ? GET_MODE (sh_compare_op0)
7744                                     : GET_MODE (sh_compare_op1),
7745                                     sh_compare_op1);
7747       emit_insn (gen_cmpgtudi_media (operands[0],
7748                                      sh_compare_op0, sh_compare_op1));
7749       DONE;
7750     }
7751   if (! currently_expanding_to_rtl)
7752     FAIL;
7753   operands[1] = prepare_scc_operands (GTU);
7756 (define_expand "sltu"
7757   [(set (match_operand:SI 0 "arith_reg_operand" "")
7758         (match_dup 1))]
7759   ""
7760   "
7762   if (TARGET_SHMEDIA)
7763     {
7764       if (GET_MODE (operands[0]) != DImode)
7765         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7766       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7767       if (sh_compare_op1 != const0_rtx)
7768         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7769                                     ? GET_MODE (sh_compare_op0)
7770                                     : GET_MODE (sh_compare_op1),
7771                                     sh_compare_op1);
7773       emit_insn (gen_cmpgtudi_media (operands[0],
7774                                      sh_compare_op1, sh_compare_op0));
7775       DONE;
7776     }
7777   if (! currently_expanding_to_rtl)
7778     FAIL;
7779   operands[1] = prepare_scc_operands (LTU);
7782 (define_expand "sleu"
7783   [(set (match_operand:SI 0 "arith_reg_operand" "")
7784         (match_dup 1))]
7785   ""
7786   "
7788   if (TARGET_SHMEDIA)
7789     {
7790       rtx tmp;
7792       if (GET_MODE (operands[0]) != DImode)
7793         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7794       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7795       if (sh_compare_op1 != const0_rtx)
7796         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7797                                     ? GET_MODE (sh_compare_op0)
7798                                     : GET_MODE (sh_compare_op1),
7799                                     sh_compare_op1);
7801       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7803       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7804       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7806       DONE;
7807     }
7808   if (! currently_expanding_to_rtl)
7809     FAIL;
7810   operands[1] = prepare_scc_operands (LEU);
7813 (define_expand "sgeu"
7814   [(set (match_operand:SI 0 "arith_reg_operand" "")
7815         (match_dup 1))]
7816   ""
7817   "
7819   if (TARGET_SHMEDIA)
7820     {
7821       rtx tmp;
7823       if (GET_MODE (operands[0]) != DImode)
7824         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7825       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7826       if (sh_compare_op1 != const0_rtx)
7827         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7828                                     ? GET_MODE (sh_compare_op0)
7829                                     : GET_MODE (sh_compare_op1),
7830                                     sh_compare_op1);
7832       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7834       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7835       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7837       DONE;
7838     }
7840   if (! currently_expanding_to_rtl)
7841     FAIL;
7842   operands[1] = prepare_scc_operands (GEU);
7845 ;; sne moves the complement of the T reg to DEST like this:
7846 ;;      cmp/eq ...
7847 ;;      mov    #-1,temp
7848 ;;      negc   temp,dest
7849 ;;   This is better than xoring compare result with 1 because it does
7850 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7851 ;;   loop.
7853 (define_expand "sne"
7854   [(set (match_dup 2) (const_int -1))
7855    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7856                    (neg:SI (plus:SI (match_dup 1)
7857                                     (match_dup 2))))
7858               (set (reg:SI T_REG)
7859                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7860                           (const_int 0)))])]
7861   ""
7862   "
7864   if (TARGET_SHMEDIA)
7865     {
7866       rtx tmp;
7868       if (GET_MODE (operands[0]) != DImode)
7869         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7871       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7872         FAIL;
7874       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7875       if (sh_compare_op1 != const0_rtx)
7876         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7877                                     ? GET_MODE (sh_compare_op0)
7878                                     : GET_MODE (sh_compare_op1),
7879                                     sh_compare_op1);
7881       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7883       emit_insn (gen_seq (tmp));
7884       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7886       DONE;
7887     }
7889   if (sh_expand_t_scc (NE, operands[0]))
7890     DONE;
7891   if (! currently_expanding_to_rtl)
7892     FAIL;
7893   operands[1] = prepare_scc_operands (EQ);
7894   operands[2] = gen_reg_rtx (SImode);
7897 (define_expand "sunordered"
7898   [(set (match_operand:DI 0 "arith_reg_operand" "")
7899         (unordered:DI (match_dup 1) (match_dup 2)))]
7900   "TARGET_SHMEDIA_FPU"
7901   "
7903   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7904   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7907 ;; Use the same trick for FP sle / sge
7908 (define_expand "movnegt"
7909   [(set (match_dup 2) (const_int -1))
7910    (parallel [(set (match_operand 0 "" "")
7911                    (neg:SI (plus:SI (match_dup 1)
7912                                     (match_dup 2))))
7913               (set (reg:SI T_REG)
7914                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7915                           (const_int 0)))])]
7916   "TARGET_SH1"
7917   "operands[2] = gen_reg_rtx (SImode);")
7919 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7920 ;; This prevents a regression that occurred when we switched from xor to
7921 ;; mov/neg for sne.
7923 (define_split
7924   [(set (match_operand:SI 0 "arith_reg_operand" "")
7925         (plus:SI (reg:SI T_REG)
7926                  (const_int -1)))]
7927   "TARGET_SH1"
7928   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7929    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7930   "")
7932 ;; -------------------------------------------------------------------------
7933 ;; Instructions to cope with inline literal tables
7934 ;; -------------------------------------------------------------------------
7936 ; 2 byte integer in line
7938 (define_insn "consttable_2"
7939  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7940                     (match_operand 1 "" "")]
7941                    UNSPECV_CONST2)]
7942  ""
7943  "*
7945   if (operands[1] != const0_rtx)
7946     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7947   return \"\";
7949  [(set_attr "length" "2")
7950  (set_attr "in_delay_slot" "no")])
7952 ; 4 byte integer in line
7954 (define_insn "consttable_4"
7955  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7956                     (match_operand 1 "" "")]
7957                    UNSPECV_CONST4)]
7958  ""
7959  "*
7961   if (operands[1] != const0_rtx)
7962     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7963   return \"\";
7965  [(set_attr "length" "4")
7966   (set_attr "in_delay_slot" "no")])
7968 ; 8 byte integer in line
7970 (define_insn "consttable_8"
7971  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7972                     (match_operand 1 "" "")]
7973                    UNSPECV_CONST8)]
7974  ""
7975  "*
7977   if (operands[1] != const0_rtx)
7978     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7979   return \"\";
7981  [(set_attr "length" "8")
7982   (set_attr "in_delay_slot" "no")])
7984 ; 4 byte floating point
7986 (define_insn "consttable_sf"
7987  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7988                     (match_operand 1 "" "")]
7989                    UNSPECV_CONST4)]
7990  ""
7991  "*
7993   if (operands[1] != const0_rtx)
7994     {
7995       REAL_VALUE_TYPE d;
7996       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7997       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7998     }
7999   return \"\";
8001  [(set_attr "length" "4")
8002   (set_attr "in_delay_slot" "no")])
8004 ; 8 byte floating point
8006 (define_insn "consttable_df"
8007  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
8008                     (match_operand 1 "" "")]
8009                    UNSPECV_CONST8)]
8010  ""
8011  "*
8013   if (operands[1] != const0_rtx)
8014     {
8015       REAL_VALUE_TYPE d;
8016       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8017       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
8018     }
8019   return \"\";
8021  [(set_attr "length" "8")
8022   (set_attr "in_delay_slot" "no")])
8024 ;; Alignment is needed for some constant tables; it may also be added for
8025 ;; Instructions at the start of loops, or after unconditional branches.
8026 ;; ??? We would get more accurate lengths if we did instruction
8027 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8028 ;; here is too conservative.
8030 ; align to a two byte boundary
8032 (define_expand "align_2"
8033  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8034  ""
8035  "")
8037 ; align to a four byte boundary
8038 ;; align_4 and align_log are instructions for the starts of loops, or
8039 ;; after unconditional branches, which may take up extra room.
8041 (define_expand "align_4"
8042  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8043  ""
8044  "")
8046 ; align to a cache line boundary
8048 (define_insn "align_log"
8049  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8050  ""
8051  ""
8052  [(set_attr "length" "0")
8053   (set_attr "in_delay_slot" "no")])
8055 ; emitted at the end of the literal table, used to emit the
8056 ; 32bit branch labels if needed.
8058 (define_insn "consttable_end"
8059   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8060   ""
8061   "* return output_jump_label_table ();"
8062   [(set_attr "in_delay_slot" "no")])
8064 ; emitted at the end of the window in the literal table.
8066 (define_insn "consttable_window_end"
8067   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8068   ""
8069   ""
8070   [(set_attr "length" "0")
8071    (set_attr "in_delay_slot" "no")])
8073 ;; -------------------------------------------------------------------------
8074 ;; Misc
8075 ;; -------------------------------------------------------------------------
8077 ;; String/block move insn.
8079 (define_expand "movmemsi"
8080   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8081                    (mem:BLK (match_operand:BLK 1 "" "")))
8082               (use (match_operand:SI 2 "nonmemory_operand" ""))
8083               (use (match_operand:SI 3 "immediate_operand" ""))
8084               (clobber (reg:SI PR_REG))
8085               (clobber (reg:SI R4_REG))
8086               (clobber (reg:SI R5_REG))
8087               (clobber (reg:SI R0_REG))])]
8088   "TARGET_SH1 && ! TARGET_SH5"
8089   "
8091   if(expand_block_move (operands))
8092      DONE;
8093   else FAIL;
8096 (define_insn "block_move_real"
8097   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8098                    (mem:BLK (reg:SI R5_REG)))
8099               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8100               (clobber (reg:SI PR_REG))
8101               (clobber (reg:SI R0_REG))])]
8102   "TARGET_SH1 && ! TARGET_HARD_SH4"
8103   "jsr  @%0%#"
8104   [(set_attr "type" "sfunc")
8105    (set_attr "needs_delay_slot" "yes")])
8107 (define_insn "block_lump_real"
8108   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8109                    (mem:BLK (reg:SI R5_REG)))
8110               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8111               (use (reg:SI R6_REG))
8112               (clobber (reg:SI PR_REG))
8113               (clobber (reg:SI T_REG))
8114               (clobber (reg:SI R4_REG))
8115               (clobber (reg:SI R5_REG))
8116               (clobber (reg:SI R6_REG))
8117               (clobber (reg:SI R0_REG))])]
8118   "TARGET_SH1 && ! TARGET_HARD_SH4"
8119   "jsr  @%0%#"
8120   [(set_attr "type" "sfunc")
8121    (set_attr "needs_delay_slot" "yes")])
8123 (define_insn "block_move_real_i4"
8124   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8125                    (mem:BLK (reg:SI R5_REG)))
8126               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8127               (clobber (reg:SI PR_REG))
8128               (clobber (reg:SI R0_REG))
8129               (clobber (reg:SI R1_REG))
8130               (clobber (reg:SI R2_REG))])]
8131   "TARGET_HARD_SH4"
8132   "jsr  @%0%#"
8133   [(set_attr "type" "sfunc")
8134    (set_attr "needs_delay_slot" "yes")])
8136 (define_insn "block_lump_real_i4"
8137   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8138                    (mem:BLK (reg:SI R5_REG)))
8139               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8140               (use (reg:SI R6_REG))
8141               (clobber (reg:SI PR_REG))
8142               (clobber (reg:SI T_REG))
8143               (clobber (reg:SI R4_REG))
8144               (clobber (reg:SI R5_REG))
8145               (clobber (reg:SI R6_REG))
8146               (clobber (reg:SI R0_REG))
8147               (clobber (reg:SI R1_REG))
8148               (clobber (reg:SI R2_REG))
8149               (clobber (reg:SI R3_REG))])]
8150   "TARGET_HARD_SH4"
8151   "jsr  @%0%#"
8152   [(set_attr "type" "sfunc")
8153    (set_attr "needs_delay_slot" "yes")])
8155 ;; -------------------------------------------------------------------------
8156 ;; Floating point instructions.
8157 ;; -------------------------------------------------------------------------
8159 ;; ??? All patterns should have a type attribute.
8161 (define_expand "fpu_switch0"
8162   [(set (match_operand:SI 0 "" "") (match_dup 2))
8163    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8164   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8165   "
8167   operands[1] = get_fpscr_rtx ();
8168   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8169   if (flag_pic)
8170     operands[2] = legitimize_pic_address (operands[2], SImode,
8171                                           no_new_pseudos ? operands[0] : 0);
8174 (define_expand "fpu_switch1"
8175   [(set (match_operand:SI 0 "" "") (match_dup 2))
8176    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8177    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8178   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8179   "
8181   operands[1] = get_fpscr_rtx ();
8182   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8183   if (flag_pic)
8184     operands[2] = legitimize_pic_address (operands[2], SImode,
8185                                           no_new_pseudos ? operands[0] : 0);
8186   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8189 (define_expand "movpsi"
8190   [(set (match_operand:PSI 0 "register_operand" "")
8191         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8192   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8193   "")
8195 ;; The c / m alternative is a fake to guide reload to load directly into
8196 ;; fpscr, since reload doesn't know how to use post-increment.
8197 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8198 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8199 ;; predicate after reload.
8200 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8201 ;; like a mac -> gpr move.
8202 (define_insn "fpu_switch"
8203   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8204         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8205   "TARGET_SH2E
8206    && (! reload_completed
8207        || true_regnum (operands[0]) != FPSCR_REG
8208        || GET_CODE (operands[1]) != MEM
8209        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8210   "@
8211         ! precision stays the same
8212         lds.l   %1,fpscr
8213         mov.l   %1,%0
8214         #
8215         lds     %1,fpscr
8216         mov     %1,%0
8217         mov.l   %1,%0
8218         sts     fpscr,%0
8219         sts.l   fpscr,%0"
8220   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8221    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8223 (define_split
8224   [(set (reg:PSI FPSCR_REG)
8225         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8226   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8227   [(set (match_dup 0) (match_dup 0))]
8228   "
8230   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8231                                         gen_rtx_MEM (PSImode,
8232                                                  gen_rtx_POST_INC (Pmode,
8233                                                           operands[0]))));
8234   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8237 (define_split
8238   [(set (reg:PSI FPSCR_REG)
8239         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8240   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8241   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8242   "
8244   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8245                                         gen_rtx_MEM (PSImode,
8246                                                  gen_rtx_POST_INC (Pmode,
8247                                                           operands[0]))));
8248   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8251 ;; ??? This uses the fp unit, but has no type indicating that.
8252 ;; If we did that, this would either give a bogus latency or introduce
8253 ;; a bogus FIFO constraint.
8254 ;; Since this insn is currently only used for prologues/epilogues,
8255 ;; it is probably best to claim no function unit, which matches the
8256 ;; current setting.
8257 (define_insn "toggle_sz"
8258   [(set (reg:PSI FPSCR_REG)
8259         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8260   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8261   "fschg"
8262   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8264 ;; There's no way we can use it today, since optimize mode switching
8265 ;; doesn't enable us to know from which mode we're switching to the
8266 ;; mode it requests, to tell whether we can use a relative mode switch
8267 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8268 ;; memory).
8269 (define_insn "toggle_pr"
8270   [(set (reg:PSI FPSCR_REG)
8271         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8272   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8273   "fpchg"
8274   [(set_attr "type" "fp")])
8276 (define_expand "addsf3"
8277   [(set (match_operand:SF 0 "arith_reg_operand" "")
8278         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8279                  (match_operand:SF 2 "arith_reg_operand" "")))]
8280   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8281   "
8283   if (TARGET_SH2E)
8284     {
8285       expand_sf_binop (&gen_addsf3_i, operands);
8286       DONE;
8287     }
8290 (define_insn "*addsf3_media"
8291   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8292         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8293                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8294   "TARGET_SHMEDIA_FPU"
8295   "fadd.s       %1, %2, %0"
8296   [(set_attr "type" "fparith_media")])
8298 (define_insn_and_split "unary_sf_op"
8299   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8300         (vec_select:V2SF
8301          (vec_concat:V2SF
8302           (vec_select:SF
8303            (match_dup 0)
8304            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8305           (match_operator:SF 2 "unary_float_operator"
8306             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8307                             (parallel [(match_operand 4
8308                                         "const_int_operand" "n")]))]))
8309          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8310   "TARGET_SHMEDIA_FPU"
8311   "#"
8312   "TARGET_SHMEDIA_FPU && reload_completed"
8313   [(set (match_dup 5) (match_dup 6))]
8314   "
8316   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8317   rtx op1 = gen_rtx_REG (SFmode,
8318                          (true_regnum (operands[1])
8319                           + (INTVAL (operands[4]) ^ endian)));
8321   operands[7] = gen_rtx_REG (SFmode,
8322                              (true_regnum (operands[0])
8323                               + (INTVAL (operands[3]) ^ endian)));
8324   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8326   [(set_attr "type" "fparith_media")])
8328 (define_insn_and_split "binary_sf_op"
8329   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8330         (vec_select:V2SF
8331          (vec_concat:V2SF
8332           (vec_select:SF
8333            (match_dup 0)
8334            (parallel [(match_operand 7 "const_int_operand" "n")]))
8335           (match_operator:SF 3 "binary_float_operator"
8336             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8337                             (parallel [(match_operand 5
8338                                         "const_int_operand" "n")]))
8339              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8340                             (parallel [(match_operand 6
8341                                         "const_int_operand" "n")]))]))
8342          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8343   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8344   "#"
8345   "&& reload_completed"
8346   [(set (match_dup 8) (match_dup 9))]
8347   "
8349   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8350   rtx op1 = gen_rtx_REG (SFmode,
8351                          (true_regnum (operands[1])
8352                           + (INTVAL (operands[5]) ^ endian)));
8353   rtx op2 = gen_rtx_REG (SFmode,
8354                          (true_regnum (operands[2])
8355                           + (INTVAL (operands[6]) ^ endian)));
8357   operands[8] = gen_rtx_REG (SFmode,
8358                              (true_regnum (operands[0])
8359                               + (INTVAL (operands[4]) ^ endian)));
8360   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8362   [(set_attr "type" "fparith_media")])
8364 (define_insn "addsf3_i"
8365   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8366         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8367                  (match_operand:SF 2 "arith_reg_operand" "f")))
8368    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8369   "TARGET_SH2E"
8370   "fadd %2,%0"
8371   [(set_attr "type" "fp")
8372    (set_attr "fp_mode" "single")])
8374 (define_expand "subsf3"
8375   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8376         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8377                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8378   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8379   "
8381   if (TARGET_SH2E)
8382     {
8383       expand_sf_binop (&gen_subsf3_i, operands);
8384       DONE;
8385     }
8388 (define_insn "*subsf3_media"
8389   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8390         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8391                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8392   "TARGET_SHMEDIA_FPU"
8393   "fsub.s       %1, %2, %0"
8394   [(set_attr "type" "fparith_media")])
8396 (define_insn "subsf3_i"
8397   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8398         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8399                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8400    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8401   "TARGET_SH2E"
8402   "fsub %2,%0"
8403   [(set_attr "type" "fp")
8404    (set_attr "fp_mode" "single")])
8406 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8407 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8408 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8409 ;; SH3E, we use a separate insn for SH3E mulsf3.
8411 (define_expand "mulsf3"
8412   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8413         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8414                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8415   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8416   "
8418   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8419     expand_sf_binop (&gen_mulsf3_i4, operands);
8420   else if (TARGET_SH2E)
8421     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8422   if (! TARGET_SHMEDIA)
8423     DONE;
8426 (define_insn "*mulsf3_media"
8427   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8428         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8429                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8430   "TARGET_SHMEDIA_FPU"
8431   "fmul.s       %1, %2, %0"
8432   [(set_attr "type" "fparith_media")])
8434 (define_insn "mulsf3_i4"
8435   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8436         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8437                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8438    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8439   "TARGET_SH2E"
8440   "fmul %2,%0"
8441   [(set_attr "type" "fp")
8442    (set_attr "fp_mode" "single")])
8444 (define_insn "mulsf3_ie"
8445   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8446         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8447                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8448   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8449   "fmul %2,%0"
8450   [(set_attr "type" "fp")])
8452 (define_insn "*mac_media"
8453   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8454         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8455                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8456                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8457   "TARGET_SHMEDIA_FPU"
8458   "fmac.s %1, %2, %0"
8459   [(set_attr "type" "fparith_media")])
8461 (define_insn "*macsf3"
8462   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8463         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8464                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8465                  (match_operand:SF 3 "arith_reg_operand" "0")))
8466    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8467   "TARGET_SH2E && ! TARGET_SH4"
8468   "fmac fr0,%2,%0"
8469   [(set_attr "type" "fp")
8470    (set_attr "fp_mode" "single")])
8472 (define_expand "divsf3"
8473   [(set (match_operand:SF 0 "arith_reg_operand" "")
8474         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8475                 (match_operand:SF 2 "arith_reg_operand" "")))]
8476   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8477   "
8479   if (TARGET_SH2E)
8480     {
8481       expand_sf_binop (&gen_divsf3_i, operands);
8482       DONE;
8483     }
8486 (define_insn "*divsf3_media"
8487   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8488         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8489                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8490   "TARGET_SHMEDIA_FPU"
8491   "fdiv.s       %1, %2, %0"
8492   [(set_attr "type" "fdiv_media")])
8494 (define_insn "divsf3_i"
8495   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8496         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8497                  (match_operand:SF 2 "arith_reg_operand" "f")))
8498    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8499   "TARGET_SH2E"
8500   "fdiv %2,%0"
8501   [(set_attr "type" "fdiv")
8502    (set_attr "fp_mode" "single")])
8504 (define_insn "floatdisf2"
8505   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8506         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8507   "TARGET_SHMEDIA_FPU"
8508   "float.qs %1, %0"
8509   [(set_attr "type" "fpconv_media")])
8511 (define_expand "floatsisf2"
8512   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8513         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8514   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8515   "
8517   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8518     {
8519       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8520       DONE;
8521     }
8524 (define_insn "*floatsisf2_media"
8525   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8526         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8527   "TARGET_SHMEDIA_FPU"
8528   "float.ls     %1, %0"
8529   [(set_attr "type" "fpconv_media")])
8531 (define_insn "floatsisf2_i4"
8532   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8533         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8534    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8535   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8536   "float        %1,%0"
8537   [(set_attr "type" "fp")
8538    (set_attr "fp_mode" "single")])
8540 (define_insn "*floatsisf2_ie"
8541   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8542         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8543   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8544   "float        %1,%0"
8545   [(set_attr "type" "fp")])
8547 (define_insn "fix_truncsfdi2"
8548   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8549         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8550   "TARGET_SHMEDIA_FPU"
8551   "ftrc.sq %1, %0"
8552   [(set_attr "type" "fpconv_media")])
8554 (define_expand "fix_truncsfsi2"
8555   [(set (match_operand:SI 0 "fpul_operand" "=y")
8556         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8557   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8558   "
8560   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8561     {
8562       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8563       DONE;
8564     }
8567 (define_insn "*fix_truncsfsi2_media"
8568   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8569         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8570   "TARGET_SHMEDIA_FPU"
8571   "ftrc.sl      %1, %0"
8572   [(set_attr "type" "fpconv_media")])
8574 (define_insn "fix_truncsfsi2_i4"
8575   [(set (match_operand:SI 0 "fpul_operand" "=y")
8576         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8577    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8578   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8579   "ftrc %1,%0"
8580   [(set_attr "type" "ftrc_s")
8581    (set_attr "fp_mode" "single")])
8583 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8584 ;; fix_truncsfsi2_i4.
8585 ;; (define_insn "fix_truncsfsi2_i4_2"
8586 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8587 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8588 ;;   (use (reg:PSI FPSCR_REG))
8589 ;;   (clobber (reg:SI FPUL_REG))]
8590 ;;  "TARGET_SH4"
8591 ;;  "#"
8592 ;;  [(set_attr "length" "4")
8593 ;;   (set_attr "fp_mode" "single")])
8595 ;;(define_split
8596 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8597 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8598 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8599 ;;   (clobber (reg:SI FPUL_REG))]
8600 ;;  "TARGET_SH4"
8601 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8602 ;;            (use (match_dup 2))])
8603 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8605 (define_insn "*fixsfsi"
8606   [(set (match_operand:SI 0 "fpul_operand" "=y")
8607         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8608   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8609   "ftrc %1,%0"
8610   [(set_attr "type" "fp")])
8612 (define_insn "cmpgtsf_t"
8613   [(set (reg:SI T_REG)
8614         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8615                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8616   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8617   "fcmp/gt      %1,%0"
8618   [(set_attr "type" "fp")
8619    (set_attr "fp_mode" "single")])
8621 (define_insn "cmpeqsf_t"
8622   [(set (reg:SI T_REG)
8623         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8624                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8625   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8626   "fcmp/eq      %1,%0"
8627   [(set_attr "type" "fp")
8628    (set_attr "fp_mode" "single")])
8630 (define_insn "ieee_ccmpeqsf_t"
8631   [(set (reg:SI T_REG)
8632         (ior:SI (reg:SI T_REG)
8633                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8634                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8635   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8636   "* return output_ieee_ccmpeq (insn, operands);"
8637   [(set_attr "length" "4")])
8640 (define_insn "cmpgtsf_t_i4"
8641   [(set (reg:SI T_REG)
8642         (gt: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_SH4 || TARGET_SH2A_SINGLE)"
8646   "fcmp/gt      %1,%0"
8647   [(set_attr "type" "fp")
8648    (set_attr "fp_mode" "single")])
8650 (define_insn "cmpeqsf_t_i4"
8651   [(set (reg:SI T_REG)
8652         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8653                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8654    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8655   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8656   "fcmp/eq      %1,%0"
8657   [(set_attr "type" "fp")
8658    (set_attr "fp_mode" "single")])
8660 (define_insn "*ieee_ccmpeqsf_t_4"
8661   [(set (reg:SI T_REG)
8662         (ior:SI (reg:SI T_REG)
8663                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8664                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8665    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8666   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8667   "* return output_ieee_ccmpeq (insn, operands);"
8668   [(set_attr "length" "4")
8669    (set_attr "fp_mode" "single")])
8671 (define_insn "cmpeqsf_media"
8672   [(set (match_operand:DI 0 "register_operand" "=r")
8673         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8674                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8675   "TARGET_SHMEDIA_FPU"
8676   "fcmpeq.s     %1, %2, %0"
8677   [(set_attr "type" "fcmp_media")])
8679 (define_insn "cmpgtsf_media"
8680   [(set (match_operand:DI 0 "register_operand" "=r")
8681         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8682                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8683   "TARGET_SHMEDIA_FPU"
8684   "fcmpgt.s     %1, %2, %0"
8685   [(set_attr "type" "fcmp_media")])
8687 (define_insn "cmpgesf_media"
8688   [(set (match_operand:DI 0 "register_operand" "=r")
8689         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8690                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8691   "TARGET_SHMEDIA_FPU"
8692   "fcmpge.s     %1, %2, %0"
8693   [(set_attr "type" "fcmp_media")])
8695 (define_insn "cmpunsf_media"
8696   [(set (match_operand:DI 0 "register_operand" "=r")
8697         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8698                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8699   "TARGET_SHMEDIA_FPU"
8700   "fcmpun.s     %1, %2, %0"
8701   [(set_attr "type" "fcmp_media")])
8703 (define_expand "cmpsf"
8704   [(set (reg:SI T_REG)
8705         (compare (match_operand:SF 0 "arith_operand" "")
8706                  (match_operand:SF 1 "arith_operand" "")))]
8707   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8708   "
8710   sh_compare_op0 = operands[0];
8711   sh_compare_op1 = operands[1];
8712   DONE;
8715 (define_expand "negsf2"
8716   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8717         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8718   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8719   "
8721   if (TARGET_SH2E)
8722     {
8723       expand_sf_unop (&gen_negsf2_i, operands);
8724       DONE;
8725     }
8728 (define_insn "*negsf2_media"
8729   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8730         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8731   "TARGET_SHMEDIA_FPU"
8732   "fneg.s       %1, %0"
8733   [(set_attr "type" "fmove_media")])
8735 (define_insn "negsf2_i"
8736   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8737         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8738    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8739   "TARGET_SH2E"
8740   "fneg %0"
8741   [(set_attr "type" "fmove")
8742    (set_attr "fp_mode" "single")])
8744 (define_expand "sqrtsf2"
8745   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8746         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8747   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8748   "
8750   if (TARGET_SH3E)
8751     {
8752       expand_sf_unop (&gen_sqrtsf2_i, operands);
8753       DONE;
8754     }
8757 (define_insn "*sqrtsf2_media"
8758   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8759         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8760   "TARGET_SHMEDIA_FPU"
8761   "fsqrt.s      %1, %0"
8762   [(set_attr "type" "fdiv_media")])
8764 (define_insn "sqrtsf2_i"
8765   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8766         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8767    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8768   "TARGET_SH3E"
8769   "fsqrt        %0"
8770   [(set_attr "type" "fdiv")
8771    (set_attr "fp_mode" "single")])
8773 (define_insn "rsqrtsf2"
8774   [(set (match_operand:SF 0 "register_operand" "=f")
8775         (div:SF (match_operand:SF 1 "immediate_operand" "i")
8776                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8777    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8778   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8779    && operands[1] == CONST1_RTX (SFmode)"
8780   "fsrra        %0"
8781   [(set_attr "type" "fsrra")
8782    (set_attr "fp_mode" "single")])
8784 (define_insn "fsca"
8785   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8786         (vec_concat:V2SF
8787          (unspec:SF [(mult:SF
8788                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8789                       (match_operand:SF 2 "immediate_operand" "i"))
8790                     ] UNSPEC_FSINA)
8791          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8792                     ] UNSPEC_FCOSA)))
8793    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8794   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8795    && operands[2] == sh_fsca_int2sf ()"
8796   "fsca fpul,%d0"
8797   [(set_attr "type" "fsca")
8798    (set_attr "fp_mode" "single")])
8800 (define_expand "sinsf2"
8801   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8802         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8803                    UNSPEC_FSINA))]
8804   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8805   "
8807   rtx scaled = gen_reg_rtx (SFmode);
8808   rtx truncated = gen_reg_rtx (SImode);
8809   rtx fsca = gen_reg_rtx (V2SFmode);
8810   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8812   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8813   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8814   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8815                           get_fpscr_rtx ()));
8816   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8817   DONE;
8820 (define_expand "cossf2"
8821   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8822         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8823                    UNSPEC_FCOSA))]
8824   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8825   "
8827   rtx scaled = gen_reg_rtx (SFmode);
8828   rtx truncated = gen_reg_rtx (SImode);
8829   rtx fsca = gen_reg_rtx (V2SFmode);
8830   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8832   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8833   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8834   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8835                           get_fpscr_rtx ()));
8836   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8837   DONE;
8840 (define_expand "sindf2"
8841   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8842         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8843                    UNSPEC_FSINA))]
8844   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8845   "
8847   rtx scaled = gen_reg_rtx (DFmode);
8848   rtx truncated = gen_reg_rtx (SImode);
8849   rtx fsca = gen_reg_rtx (V2SFmode);
8850   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8851   rtx sfresult = gen_reg_rtx (SFmode);
8853   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8854   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8855   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8856                           get_fpscr_rtx ()));
8857   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8858   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8859   DONE;
8862 (define_expand "cosdf2"
8863   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8864         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8865                    UNSPEC_FCOSA))]
8866   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8867   "
8869   rtx scaled = gen_reg_rtx (DFmode);
8870   rtx truncated = gen_reg_rtx (SImode);
8871   rtx fsca = gen_reg_rtx (V2SFmode);
8872   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8873   rtx sfresult = gen_reg_rtx (SFmode);
8875   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8876   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8877   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8878                           get_fpscr_rtx ()));
8879   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8880   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8881   DONE;
8884 (define_expand "abssf2"
8885   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8886         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8887   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8888   "
8890   if (TARGET_SH2E)
8891     {
8892       expand_sf_unop (&gen_abssf2_i, operands);
8893       DONE;
8894     }
8897 (define_insn "*abssf2_media"
8898   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8899         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8900   "TARGET_SHMEDIA_FPU"
8901   "fabs.s       %1, %0"
8902   [(set_attr "type" "fmove_media")])
8904 (define_insn "abssf2_i"
8905   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8906         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8907    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8908   "TARGET_SH2E"
8909   "fabs %0"
8910   [(set_attr "type" "fmove")
8911    (set_attr "fp_mode" "single")])
8913 (define_expand "adddf3"
8914   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8915         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8916                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8917   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8918   "
8920   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8921     {
8922       expand_df_binop (&gen_adddf3_i, operands);
8923       DONE;
8924     }
8927 (define_insn "*adddf3_media"
8928   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8929         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8930                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8931   "TARGET_SHMEDIA_FPU"
8932   "fadd.d       %1, %2, %0"
8933   [(set_attr "type" "dfparith_media")])
8935 (define_insn "adddf3_i"
8936   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8937         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8938                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8939    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8940   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8941   "fadd %2,%0"
8942   [(set_attr "type" "dfp_arith")
8943    (set_attr "fp_mode" "double")])
8945 (define_expand "subdf3"
8946   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8947         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8948                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8949   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8950   "
8952   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8953     {
8954       expand_df_binop (&gen_subdf3_i, operands);
8955       DONE;
8956     }
8959 (define_insn "*subdf3_media"
8960   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8961         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8962                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8963   "TARGET_SHMEDIA_FPU"
8964   "fsub.d       %1, %2, %0"
8965   [(set_attr "type" "dfparith_media")])
8967 (define_insn "subdf3_i"
8968   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8969         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8970                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8971    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8972   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8973   "fsub %2,%0"
8974   [(set_attr "type" "dfp_arith")
8975    (set_attr "fp_mode" "double")])
8977 (define_expand "muldf3"
8978   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8979         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8980                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8981   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8982   "
8984   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8985     {
8986       expand_df_binop (&gen_muldf3_i, operands);
8987       DONE;
8988     }
8991 (define_insn "*muldf3_media"
8992   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8993         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8994                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8995   "TARGET_SHMEDIA_FPU"
8996   "fmul.d       %1, %2, %0"
8997   [(set_attr "type" "dfmul_media")])
8999 (define_insn "muldf3_i"
9000   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9001         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
9002                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9003    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9004   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9005   "fmul %2,%0"
9006   [(set_attr "type" "dfp_arith")
9007    (set_attr "fp_mode" "double")])
9009 (define_expand "divdf3"
9010   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9011         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
9012                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
9013   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9014   "
9016   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9017     {
9018       expand_df_binop (&gen_divdf3_i, operands);
9019       DONE;
9020     }
9023 (define_insn "*divdf3_media"
9024   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9025         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
9026                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9027   "TARGET_SHMEDIA_FPU"
9028   "fdiv.d       %1, %2, %0"
9029   [(set_attr "type" "dfdiv_media")])
9031 (define_insn "divdf3_i"
9032   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9033         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
9034                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9035    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9036   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9037   "fdiv %2,%0"
9038   [(set_attr "type" "dfdiv")
9039    (set_attr "fp_mode" "double")])
9041 (define_insn "floatdidf2"
9042   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9043         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
9044   "TARGET_SHMEDIA_FPU"
9045   "float.qd     %1, %0"
9046   [(set_attr "type" "dfpconv_media")])
9048 (define_expand "floatsidf2"
9049   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9050         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
9051   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9052   "
9054   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9055     {
9056       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
9057                                       get_fpscr_rtx ()));
9058       DONE;
9059     }
9062 (define_insn "*floatsidf2_media"
9063   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9064         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
9065   "TARGET_SHMEDIA_FPU"
9066   "float.ld     %1, %0"
9067   [(set_attr "type" "dfpconv_media")])
9069 (define_insn "floatsidf2_i"
9070   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9071         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
9072    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9073   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9074   "float        %1,%0"
9075   [(set_attr "type" "dfp_conv")
9076    (set_attr "fp_mode" "double")])
9078 (define_insn "fix_truncdfdi2"
9079   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
9080         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9081   "TARGET_SHMEDIA_FPU"
9082   "ftrc.dq      %1, %0"
9083   [(set_attr "type" "dfpconv_media")])
9085 (define_expand "fix_truncdfsi2"
9086   [(set (match_operand:SI 0 "fpul_operand" "")
9087         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9088   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9089   "
9091   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9092     {
9093       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9094                                           get_fpscr_rtx ()));
9095       DONE;
9096     }
9099 (define_insn "*fix_truncdfsi2_media"
9100   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9101         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9102   "TARGET_SHMEDIA_FPU"
9103   "ftrc.dl      %1, %0"
9104   [(set_attr "type" "dfpconv_media")])
9106 (define_insn "fix_truncdfsi2_i"
9107   [(set (match_operand:SI 0 "fpul_operand" "=y")
9108         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9109    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9110   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9111   "ftrc %1,%0"
9112   [(set_attr "type" "dfp_conv")
9113    (set_attr "dfp_comp" "no")
9114    (set_attr "fp_mode" "double")])
9116 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
9117 ;; fix_truncdfsi2_i.
9118 ;; (define_insn "fix_truncdfsi2_i4"
9119 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9120 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9121 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9122 ;;    (clobber (reg:SI FPUL_REG))]
9123 ;;   "TARGET_SH4"
9124 ;;   "#"
9125 ;;   [(set_attr "length" "4")
9126 ;;    (set_attr "fp_mode" "double")])
9128 ;; (define_split
9129 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9130 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9131 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9132 ;;    (clobber (reg:SI FPUL_REG))]
9133 ;;   "TARGET_SH4"
9134 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9135 ;;            (use (match_dup 2))])
9136 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
9138 (define_insn "cmpgtdf_t"
9139   [(set (reg:SI T_REG)
9140         (gt: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_SH4 || TARGET_SH2A_DOUBLE)"
9144   "fcmp/gt      %1,%0"
9145   [(set_attr "type" "dfp_cmp")
9146    (set_attr "fp_mode" "double")])
9148 (define_insn "cmpeqdf_t"
9149   [(set (reg:SI T_REG)
9150         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9151                (match_operand:DF 1 "arith_reg_operand" "f")))
9152    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9153   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9154   "fcmp/eq      %1,%0"
9155   [(set_attr "type" "dfp_cmp")
9156    (set_attr "fp_mode" "double")])
9158 (define_insn "*ieee_ccmpeqdf_t"
9159   [(set (reg:SI T_REG)
9160         (ior:SI (reg:SI T_REG)
9161                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9162                        (match_operand:DF 1 "arith_reg_operand" "f"))))
9163    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9164   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9165   "* return output_ieee_ccmpeq (insn, operands);"
9166   [(set_attr "length" "4")
9167    (set_attr "fp_mode" "double")])
9169 (define_insn "cmpeqdf_media"
9170   [(set (match_operand:DI 0 "register_operand" "=r")
9171         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9172                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9173   "TARGET_SHMEDIA_FPU"
9174   "fcmpeq.d     %1,%2,%0"
9175   [(set_attr "type" "fcmp_media")])
9177 (define_insn "cmpgtdf_media"
9178   [(set (match_operand:DI 0 "register_operand" "=r")
9179         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9180                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9181   "TARGET_SHMEDIA_FPU"
9182   "fcmpgt.d     %1,%2,%0"
9183   [(set_attr "type" "fcmp_media")])
9185 (define_insn "cmpgedf_media"
9186   [(set (match_operand:DI 0 "register_operand" "=r")
9187         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9188                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9189   "TARGET_SHMEDIA_FPU"
9190   "fcmpge.d     %1,%2,%0"
9191   [(set_attr "type" "fcmp_media")])
9193 (define_insn "cmpundf_media"
9194   [(set (match_operand:DI 0 "register_operand" "=r")
9195         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9196                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9197   "TARGET_SHMEDIA_FPU"
9198   "fcmpun.d     %1,%2,%0"
9199   [(set_attr "type" "fcmp_media")])
9201 (define_expand "cmpdf"
9202   [(set (reg:SI T_REG)
9203         (compare (match_operand:DF 0 "arith_operand" "")
9204                  (match_operand:DF 1 "arith_operand" "")))]
9205   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9206   "
9208   sh_compare_op0 = operands[0];
9209   sh_compare_op1 = operands[1];
9210   DONE;
9213 (define_expand "negdf2"
9214   [(set (match_operand:DF 0 "arith_reg_operand" "")
9215         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9216   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9217   "
9219   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9220     {
9221       expand_df_unop (&gen_negdf2_i, operands);
9222       DONE;
9223     }
9226 (define_insn "*negdf2_media"
9227   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9228         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9229   "TARGET_SHMEDIA_FPU"
9230   "fneg.d       %1, %0"
9231   [(set_attr "type" "fmove_media")])
9233 (define_insn "negdf2_i"
9234   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9235         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9236    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9237   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9238   "fneg %0"
9239   [(set_attr "type" "fmove")
9240    (set_attr "fp_mode" "double")])
9242 (define_expand "sqrtdf2"
9243   [(set (match_operand:DF 0 "arith_reg_operand" "")
9244         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9245   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9246   "
9248   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9249     {
9250       expand_df_unop (&gen_sqrtdf2_i, operands);
9251       DONE;
9252     }
9255 (define_insn "*sqrtdf2_media"
9256   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9257         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9258   "TARGET_SHMEDIA_FPU"
9259   "fsqrt.d      %1, %0"
9260   [(set_attr "type" "dfdiv_media")])
9262 (define_insn "sqrtdf2_i"
9263   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9264         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9265    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9266   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9267   "fsqrt        %0"
9268   [(set_attr "type" "dfdiv")
9269    (set_attr "fp_mode" "double")])
9271 (define_expand "absdf2"
9272   [(set (match_operand:DF 0 "arith_reg_operand" "")
9273         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9274   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9275   "
9277   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9278     {
9279       expand_df_unop (&gen_absdf2_i, operands);
9280       DONE;
9281     }
9284 (define_insn "*absdf2_media"
9285   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9286         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9287   "TARGET_SHMEDIA_FPU"
9288   "fabs.d       %1, %0"
9289   [(set_attr "type" "fmove_media")])
9291 (define_insn "absdf2_i"
9292   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9293         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9294    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9295   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9296   "fabs %0"
9297   [(set_attr "type" "fmove")
9298    (set_attr "fp_mode" "double")])
9300 (define_expand "extendsfdf2"
9301   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9302         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9303   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9304   "
9306   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9307     {
9308       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9309                                         get_fpscr_rtx ()));
9310       DONE;
9311     }
9314 (define_insn "*extendsfdf2_media"
9315   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9316         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9317   "TARGET_SHMEDIA_FPU"
9318   "fcnv.sd      %1, %0"
9319   [(set_attr "type" "dfpconv_media")])
9321 (define_insn "extendsfdf2_i4"
9322   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9323         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9324    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9325   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9326   "fcnvsd  %1,%0"
9327   [(set_attr "type" "fp")
9328    (set_attr "fp_mode" "double")])
9330 (define_expand "truncdfsf2"
9331   [(set (match_operand:SF 0 "fpul_operand" "")
9332         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9333   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9334   "
9336   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9337     {
9338       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9339                                        get_fpscr_rtx ()));
9340       DONE;
9341     }
9344 (define_insn "*truncdfsf2_media"
9345   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9346         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9347   "TARGET_SHMEDIA_FPU"
9348   "fcnv.ds      %1, %0"
9349   [(set_attr "type" "dfpconv_media")])
9351 (define_insn "truncdfsf2_i4"
9352   [(set (match_operand:SF 0 "fpul_operand" "=y")
9353         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9354    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9355   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9356   "fcnvds  %1,%0"
9357   [(set_attr "type" "fp")
9358    (set_attr "fp_mode" "double")])
9360 ;; Bit field extract patterns.  These give better code for packed bitfields,
9361 ;; because they allow auto-increment addresses to be generated.
9363 (define_expand "insv"
9364   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9365                          (match_operand:SI 1 "immediate_operand" "")
9366                          (match_operand:SI 2 "immediate_operand" ""))
9367         (match_operand:SI 3 "general_operand" ""))]
9368   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9369   "
9371   rtx addr_target, orig_address, shift_reg, qi_val;
9372   HOST_WIDE_INT bitsize, size, v = 0;
9373   rtx x = operands[3];
9375   /* ??? expmed doesn't care for non-register predicates.  */
9376   if (! memory_operand (operands[0], VOIDmode)
9377       || ! immediate_operand (operands[1], VOIDmode)
9378       || ! immediate_operand (operands[2], VOIDmode)
9379       || ! general_operand (x, VOIDmode))
9380     FAIL;
9381   /* If this isn't a 16 / 24 / 32 bit field, or if
9382      it doesn't start on a byte boundary, then fail.  */
9383   bitsize = INTVAL (operands[1]);
9384   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9385       || (INTVAL (operands[2]) % 8) != 0)
9386     FAIL;
9388   size = bitsize / 8;
9389   orig_address = XEXP (operands[0], 0);
9390   shift_reg = gen_reg_rtx (SImode);
9391   if (GET_CODE (x) == CONST_INT)
9392     {
9393       v = INTVAL (x);
9394       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9395     }
9396   else
9397     {
9398       emit_insn (gen_movsi (shift_reg, operands[3]));
9399       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9400     }
9401   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9403   operands[0] = replace_equiv_address (operands[0], addr_target);
9404   emit_insn (gen_movqi (operands[0], qi_val));
9406   while (size -= 1)
9407     {
9408       if (GET_CODE (x) == CONST_INT)
9409         qi_val
9410           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9411       else
9412         {
9413           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9414           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9415         }
9416       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9417       emit_insn (gen_movqi (operands[0], qi_val));
9418     }
9420   DONE;
9423 (define_insn "movua"
9424   [(set (match_operand:SI 0 "register_operand" "=z")
9425         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9426                          (const_int 32) (const_int 0)))]
9427   "TARGET_SH4A_ARCH"
9428   "movua.l      %1,%0"
9429   [(set_attr "type" "movua")])
9431 ;; We shouldn't need this, but cse replaces increments with references
9432 ;; to other regs before flow has a chance to create post_inc
9433 ;; addressing modes, and only postreload's cse_move2add brings the
9434 ;; increments back to a usable form.
9435 (define_peephole2
9436   [(set (match_operand:SI 0 "register_operand" "")
9437         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9438                          (const_int 32) (const_int 0)))
9439    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9440   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9441   [(set (match_operand:SI 0 "register_operand" "")
9442         (sign_extract:SI (mem:SI (post_inc:SI
9443                                   (match_operand:SI 1 "register_operand" "")))
9444                          (const_int 32) (const_int 0)))]
9445   "")
9447 (define_expand "extv"
9448   [(set (match_operand:SI 0 "register_operand" "")
9449         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9450                          (match_operand 2 "const_int_operand" "")
9451                          (match_operand 3 "const_int_operand" "")))]
9452   "TARGET_SH4A_ARCH"
9454   if (TARGET_SH4A_ARCH
9455       && INTVAL (operands[2]) == 32
9456       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9457       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9458     {
9459       emit_insn (gen_movua (operands[0],
9460                             adjust_address (operands[1], SImode, 0)));
9461       DONE;
9462     }
9464   FAIL;
9467 (define_expand "extzv"
9468   [(set (match_operand:SI 0 "register_operand" "")
9469         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9470                          (match_operand 2 "const_int_operand" "")
9471                          (match_operand 3 "const_int_operand" "")))]
9472   "TARGET_SH4A_ARCH"
9474   if (TARGET_SH4A_ARCH
9475       && INTVAL (operands[2]) == 32
9476       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9477       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9478     {
9479       emit_insn (gen_movua (operands[0],
9480                             adjust_address (operands[1], SImode, 0)));
9481       DONE;
9482     }
9484   FAIL;
9488 ;; -------------------------------------------------------------------------
9489 ;; Peepholes
9490 ;; -------------------------------------------------------------------------
9492 ;; This matches cases where a stack pointer increment at the start of the
9493 ;; epilogue combines with a stack slot read loading the return value.
9495 (define_peephole
9496   [(set (match_operand:SI 0 "arith_reg_operand" "")
9497         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9498    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9499   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9500   "mov.l        @%1+,%0")
9502 ;; See the comment on the dt combiner pattern above.
9504 (define_peephole
9505   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9506         (plus:SI (match_dup 0)
9507                  (const_int -1)))
9508    (set (reg:SI T_REG)
9509         (eq:SI (match_dup 0)
9510                (const_int 0)))]
9511   "TARGET_SH2"
9512   "dt   %0")
9514 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9515 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9516 ;; reload when the constant is too large for a reg+offset address.
9518 ;; ??? We would get much better code if this was done in reload.  This would
9519 ;; require modifying find_reloads_address to recognize that if the constant
9520 ;; is out-of-range for an immediate add, then we get better code by reloading
9521 ;; the constant into a register than by reloading the sum into a register,
9522 ;; since the former is one instruction shorter if the address does not need
9523 ;; to be offsettable.  Unfortunately this does not work, because there is
9524 ;; only one register, r0, that can be used as an index register.  This register
9525 ;; is also the function return value register.  So, if we try to force reload
9526 ;; to use double-reg addresses, then we end up with some instructions that
9527 ;; need to use r0 twice.  The only way to fix this is to change the calling
9528 ;; convention so that r0 is not used to return values.
9530 (define_peephole
9531   [(set (match_operand:SI 0 "register_operand" "=r")
9532         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9533    (set (mem:SI (match_dup 0))
9534         (match_operand:SI 2 "general_movsrc_operand" ""))]
9535   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9536   "mov.l        %2,@(%0,%1)")
9538 (define_peephole
9539   [(set (match_operand:SI 0 "register_operand" "=r")
9540         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9541    (set (match_operand:SI 2 "general_movdst_operand" "")
9542         (mem:SI (match_dup 0)))]
9543   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9544   "mov.l        @(%0,%1),%2")
9546 (define_peephole
9547   [(set (match_operand:SI 0 "register_operand" "=r")
9548         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9549    (set (mem:HI (match_dup 0))
9550         (match_operand:HI 2 "general_movsrc_operand" ""))]
9551   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9552   "mov.w        %2,@(%0,%1)")
9554 (define_peephole
9555   [(set (match_operand:SI 0 "register_operand" "=r")
9556         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9557    (set (match_operand:HI 2 "general_movdst_operand" "")
9558         (mem:HI (match_dup 0)))]
9559   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9560   "mov.w        @(%0,%1),%2")
9562 (define_peephole
9563   [(set (match_operand:SI 0 "register_operand" "=r")
9564         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9565    (set (mem:QI (match_dup 0))
9566         (match_operand:QI 2 "general_movsrc_operand" ""))]
9567   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9568   "mov.b        %2,@(%0,%1)")
9570 (define_peephole
9571   [(set (match_operand:SI 0 "register_operand" "=r")
9572         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9573    (set (match_operand:QI 2 "general_movdst_operand" "")
9574         (mem:QI (match_dup 0)))]
9575   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9576   "mov.b        @(%0,%1),%2")
9578 (define_peephole
9579   [(set (match_operand:SI 0 "register_operand" "=r")
9580         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9581    (set (mem:SF (match_dup 0))
9582         (match_operand:SF 2 "general_movsrc_operand" ""))]
9583   "TARGET_SH1 && REGNO (operands[0]) == 0
9584    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9585        || (GET_CODE (operands[2]) == SUBREG
9586            && REGNO (SUBREG_REG (operands[2])) < 16))
9587    && reg_unused_after (operands[0], insn)"
9588   "mov.l        %2,@(%0,%1)")
9590 (define_peephole
9591   [(set (match_operand:SI 0 "register_operand" "=r")
9592         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9593    (set (match_operand:SF 2 "general_movdst_operand" "")
9595         (mem:SF (match_dup 0)))]
9596   "TARGET_SH1 && REGNO (operands[0]) == 0
9597    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9598        || (GET_CODE (operands[2]) == SUBREG
9599            && REGNO (SUBREG_REG (operands[2])) < 16))
9600    && reg_unused_after (operands[0], insn)"
9601   "mov.l        @(%0,%1),%2")
9603 (define_peephole
9604   [(set (match_operand:SI 0 "register_operand" "=r")
9605         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9606    (set (mem:SF (match_dup 0))
9607         (match_operand:SF 2 "general_movsrc_operand" ""))]
9608   "TARGET_SH2E && REGNO (operands[0]) == 0
9609    && ((GET_CODE (operands[2]) == REG
9610         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9611        || (GET_CODE (operands[2]) == SUBREG
9612            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9613    && reg_unused_after (operands[0], insn)"
9614   "fmov{.s|}    %2,@(%0,%1)")
9616 (define_peephole
9617   [(set (match_operand:SI 0 "register_operand" "=r")
9618         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9619    (set (match_operand:SF 2 "general_movdst_operand" "")
9621         (mem:SF (match_dup 0)))]
9622   "TARGET_SH2E && REGNO (operands[0]) == 0
9623    && ((GET_CODE (operands[2]) == REG
9624         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9625        || (GET_CODE (operands[2]) == SUBREG
9626            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9627    && reg_unused_after (operands[0], insn)"
9628   "fmov{.s|}    @(%0,%1),%2")
9630 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9631 (define_insn "sp_switch_1"
9632   [(const_int 1)]
9633   "TARGET_SH1"
9634   "*
9636   rtx xoperands[1];
9638   xoperands[0] = sp_switch;
9639   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9640   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9641   return \"mov r0,r15\";
9643   [(set_attr "length" "10")])
9645 ;; Switch back to the original stack for interrupt functions with the
9646 ;; sp_switch attribute.  */
9647 (define_insn "sp_switch_2"
9648   [(const_int 2)]
9649   "TARGET_SH1"
9650   "mov.l @r15+,r15\;mov.l @r15+,r0"
9651   [(set_attr "length" "4")])
9653 ;; Integer vector moves
9655 (define_expand "movv8qi"
9656   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9657         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9658   "TARGET_SHMEDIA"
9659   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9661 (define_insn "movv8qi_i"
9662   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9663         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9664   "TARGET_SHMEDIA
9665    && (register_operand (operands[0], V8QImode)
9666        || sh_register_operand (operands[1], V8QImode))"
9667   "@
9668         add     %1, r63, %0
9669         movi    %1, %0
9670         #
9671         ld%M1.q %m1, %0
9672         st%M0.q %m0, %N1"
9673   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9674    (set_attr "length" "4,4,16,4,4")])
9676 (define_split
9677   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9678         (subreg:V8QI (const_int 0) 0))]
9679   "TARGET_SHMEDIA"
9680   [(set (match_dup 0)
9681         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9682                             (const_int 0) (const_int 0) (const_int 0)
9683                             (const_int 0) (const_int 0)]))])
9685 (define_split
9686   [(set (match_operand 0 "arith_reg_dest" "")
9687         (match_operand 1 "sh_rep_vec" ""))]
9688   "TARGET_SHMEDIA && reload_completed
9689    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9690    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9691    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9692    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9693        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9694    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9695        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9696   [(set (match_dup 0) (match_dup 1))
9697    (match_dup 2)]
9698   "
9700   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9701   rtx elt1 = XVECEXP (operands[1], 0, 1);
9703   if (unit_size > 2)
9704     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9705   else
9706     {
9707       if (unit_size < 2)
9708         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9709       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9710     }
9711   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9712   operands[1] = XVECEXP (operands[1], 0, 0);
9713   if (unit_size < 2)
9714     {
9715       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9716         operands[1]
9717           = GEN_INT (TARGET_LITTLE_ENDIAN
9718                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9719                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9720       else
9721         {
9722           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9723           operands[1]
9724             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9725         }
9726     }
9729 (define_split
9730   [(set (match_operand 0 "arith_reg_dest" "")
9731         (match_operand 1 "sh_const_vec" ""))]
9732   "TARGET_SHMEDIA && reload_completed
9733    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9734    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9735    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9736   [(set (match_dup 0) (match_dup 1))]
9737   "
9739   rtx v = operands[1];
9740   enum machine_mode new_mode
9741     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9743   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9744   operands[1]
9745     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9748 (define_expand "movv2hi"
9749   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9750         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9751   "TARGET_SHMEDIA"
9752   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9754 (define_insn "movv2hi_i"
9755   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9756         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9757   "TARGET_SHMEDIA
9758    && (register_operand (operands[0], V2HImode)
9759        || sh_register_operand (operands[1], V2HImode))"
9760   "@
9761         addz.l  %1, r63, %0
9762         movi    %1, %0
9763         #
9764         ld%M1.l %m1, %0
9765         st%M0.l %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 "movv4hi"
9770   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9771         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9772   "TARGET_SHMEDIA"
9773   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9775 (define_insn "movv4hi_i"
9776   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9777         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9778   "TARGET_SHMEDIA
9779    && (register_operand (operands[0], V4HImode)
9780        || sh_register_operand (operands[1], V4HImode))"
9781   "@
9782         add     %1, r63, %0
9783         movi    %1, %0
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 (define_expand "movv2si"
9791   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9792         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9793   "TARGET_SHMEDIA"
9794   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9796 (define_insn "movv2si_i"
9797   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9798         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9799   "TARGET_SHMEDIA
9800    && (register_operand (operands[0], V2SImode)
9801        || sh_register_operand (operands[1], V2SImode))"
9802   "@
9803         add     %1, r63, %0
9804         #
9805         #
9806         ld%M1.q %m1, %0
9807         st%M0.q %m0, %N1"
9808   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9809    (set_attr "length" "4,4,16,4,4")])
9811 ;; Multimedia Intrinsics
9813 (define_insn "absv2si2"
9814   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9815         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9816   "TARGET_SHMEDIA"
9817   "mabs.l       %1, %0"
9818   [(set_attr "type" "mcmp_media")])
9820 (define_insn "absv4hi2"
9821   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9822         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9823   "TARGET_SHMEDIA"
9824   "mabs.w       %1, %0"
9825   [(set_attr "type" "mcmp_media")])
9827 (define_insn "addv2si3"
9828   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9829         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9830                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9831   "TARGET_SHMEDIA"
9832   "madd.l       %1, %2, %0"
9833   [(set_attr "type" "arith_media")])
9835 (define_insn "addv4hi3"
9836   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9837         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9838                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9839   "TARGET_SHMEDIA"
9840   "madd.w       %1, %2, %0"
9841   [(set_attr "type" "arith_media")])
9843 (define_insn "ssaddv2si3"
9844   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9845         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9846                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9847   "TARGET_SHMEDIA"
9848   "madds.l      %1, %2, %0"
9849   [(set_attr "type" "mcmp_media")])
9851 (define_insn "usaddv8qi3"
9852   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9853         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9854                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9855   "TARGET_SHMEDIA"
9856   "madds.ub     %1, %2, %0"
9857   [(set_attr "type" "mcmp_media")])
9859 (define_insn "ssaddv4hi3"
9860   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9861         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9862                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9863   "TARGET_SHMEDIA"
9864   "madds.w      %1, %2, %0"
9865   [(set_attr "type" "mcmp_media")])
9867 (define_insn "negcmpeqv8qi"
9868   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9869         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9870                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9871   "TARGET_SHMEDIA"
9872   "mcmpeq.b     %N1, %N2, %0"
9873   [(set_attr "type" "mcmp_media")])
9875 (define_insn "negcmpeqv2si"
9876   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9877         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9878                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9879   "TARGET_SHMEDIA"
9880   "mcmpeq.l     %N1, %N2, %0"
9881   [(set_attr "type" "mcmp_media")])
9883 (define_insn "negcmpeqv4hi"
9884   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9885         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9886                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9887   "TARGET_SHMEDIA"
9888   "mcmpeq.w     %N1, %N2, %0"
9889   [(set_attr "type" "mcmp_media")])
9891 (define_insn "negcmpgtuv8qi"
9892   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9893         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9894                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9895   "TARGET_SHMEDIA"
9896   "mcmpgt.ub    %N1, %N2, %0"
9897   [(set_attr "type" "mcmp_media")])
9899 (define_insn "negcmpgtv2si"
9900   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9901         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9902                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9903   "TARGET_SHMEDIA"
9904   "mcmpgt.l     %N1, %N2, %0"
9905   [(set_attr "type" "mcmp_media")])
9907 (define_insn "negcmpgtv4hi"
9908   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9909         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9910                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9911   "TARGET_SHMEDIA"
9912   "mcmpgt.w     %N1, %N2, %0"
9913   [(set_attr "type" "mcmp_media")])
9915 (define_insn "mcmv"
9916   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9917         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9918                         (match_operand:DI 2 "arith_reg_operand" "r"))
9919                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9920                         (not:DI (match_dup 2)))))]
9921   "TARGET_SHMEDIA"
9922   "mcmv %N1, %2, %0"
9923   [(set_attr "type" "arith_media")])
9925 (define_insn "mcnvs_lw"
9926   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9927         (vec_concat:V4HI
9928          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9929          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9930   "TARGET_SHMEDIA"
9931   "mcnvs.lw     %N1, %N2, %0"
9932   [(set_attr "type" "mcmp_media")])
9934 (define_insn "mcnvs_wb"
9935   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9936         (vec_concat:V8QI
9937          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9938          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9939   "TARGET_SHMEDIA"
9940   "mcnvs.wb     %N1, %N2, %0"
9941   [(set_attr "type" "mcmp_media")])
9943 (define_insn "mcnvs_wub"
9944   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9945         (vec_concat:V8QI
9946          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9947          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9948   "TARGET_SHMEDIA"
9949   "mcnvs.wub    %N1, %N2, %0"
9950   [(set_attr "type" "mcmp_media")])
9952 (define_insn "mextr_rl"
9953   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9954         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9955                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9956                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9957                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9958   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9959   "*
9961   static char templ[16];
9963   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9964            (int) INTVAL (operands[3]) >> 3);
9965   return templ;
9967   [(set_attr "type" "arith_media")])
9969 (define_insn "*mextr_lr"
9970   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9971         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9972                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9973                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9974                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9975   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9976   "*
9978   static char templ[16];
9980   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9981            (int) INTVAL (operands[4]) >> 3);
9982   return templ;
9984   [(set_attr "type" "arith_media")])
9986 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9987 ; vector then varies depending on endianness.
9988 (define_expand "mextr1"
9989   [(match_operand:DI 0 "arith_reg_dest" "")
9990    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9991    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9992   "TARGET_SHMEDIA"
9993   "
9995   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9996                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9997   DONE;
10000 (define_expand "mextr2"
10001   [(match_operand:DI 0 "arith_reg_dest" "")
10002    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10003    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10004   "TARGET_SHMEDIA"
10005   "
10007   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10008                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
10009   DONE;
10012 (define_expand "mextr3"
10013   [(match_operand:DI 0 "arith_reg_dest" "")
10014    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10015    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10016   "TARGET_SHMEDIA"
10017   "
10019   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10020                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
10021   DONE;
10024 (define_expand "mextr4"
10025   [(match_operand:DI 0 "arith_reg_dest" "")
10026    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10027    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10028   "TARGET_SHMEDIA"
10029   "
10031   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10032                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
10033   DONE;
10036 (define_expand "mextr5"
10037   [(match_operand:DI 0 "arith_reg_dest" "")
10038    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10039    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10040   "TARGET_SHMEDIA"
10041   "
10043   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10044                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
10045   DONE;
10048 (define_expand "mextr6"
10049   [(match_operand:DI 0 "arith_reg_dest" "")
10050    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10051    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10052   "TARGET_SHMEDIA"
10053   "
10055   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10056                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
10057   DONE;
10060 (define_expand "mextr7"
10061   [(match_operand:DI 0 "arith_reg_dest" "")
10062    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10063    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10064   "TARGET_SHMEDIA"
10065   "
10067   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10068                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
10069   DONE;
10072 (define_expand "mmacfx_wl"
10073   [(match_operand:V2SI 0 "arith_reg_dest" "")
10074    (match_operand:V2HI 1 "extend_reg_operand" "")
10075    (match_operand:V2HI 2 "extend_reg_operand" "")
10076    (match_operand:V2SI 3 "arith_reg_operand" "")]
10077   "TARGET_SHMEDIA"
10078   "
10080   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
10081                               operands[1], operands[2]));
10082   DONE;
10085 (define_insn "mmacfx_wl_i"
10086   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10087         (ss_plus:V2SI
10088          (match_operand:V2SI 1 "arith_reg_operand" "0")
10089          (ss_truncate:V2SI
10090           (ashift:V2DI
10091            (sign_extend:V2DI
10092             (mult:V2SI
10093              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10094              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10095            (const_int 1)))))]
10096   "TARGET_SHMEDIA"
10097   "mmacfx.wl    %2, %3, %0"
10098   [(set_attr "type" "mac_media")])
10100 (define_expand "mmacnfx_wl"
10101   [(match_operand:V2SI 0 "arith_reg_dest" "")
10102    (match_operand:V2HI 1 "extend_reg_operand" "")
10103    (match_operand:V2HI 2 "extend_reg_operand" "")
10104    (match_operand:V2SI 3 "arith_reg_operand" "")]
10105   "TARGET_SHMEDIA"
10106   "
10108   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10109                                operands[1], operands[2]));
10110   DONE;
10113 (define_insn "mmacnfx_wl_i"
10114   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10115         (ss_minus:V2SI
10116          (match_operand:V2SI 1 "arith_reg_operand" "0")
10117          (ss_truncate:V2SI
10118           (ashift:V2DI
10119            (sign_extend:V2DI
10120             (mult:V2SI
10121              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10122              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10123            (const_int 1)))))]
10124   "TARGET_SHMEDIA"
10125   "mmacnfx.wl   %2, %3, %0"
10126   [(set_attr "type" "mac_media")])
10128 (define_insn "mulv2si3"
10129   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10130         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10131                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10132   "TARGET_SHMEDIA"
10133   "mmul.l       %1, %2, %0"
10134   [(set_attr "type" "d2mpy_media")])
10136 (define_insn "mulv4hi3"
10137   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10138         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10139                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10140   "TARGET_SHMEDIA"
10141   "mmul.w       %1, %2, %0"
10142   [(set_attr "type" "dmpy_media")])
10144 (define_insn "mmulfx_l"
10145   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10146         (ss_truncate:V2SI
10147          (ashiftrt:V2DI
10148           (mult:V2DI
10149            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10150            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10151           (const_int 31))))]
10152   "TARGET_SHMEDIA"
10153   "mmulfx.l     %1, %2, %0"
10154   [(set_attr "type" "d2mpy_media")])
10156 (define_insn "mmulfx_w"
10157   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10158         (ss_truncate:V4HI
10159          (ashiftrt:V4SI
10160           (mult:V4SI
10161            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10162            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10163           (const_int 15))))]
10164   "TARGET_SHMEDIA"
10165   "mmulfx.w     %1, %2, %0"
10166   [(set_attr "type" "dmpy_media")])
10168 (define_insn "mmulfxrp_w"
10169   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10170         (ss_truncate:V4HI
10171          (ashiftrt:V4SI
10172           (plus:V4SI
10173            (mult:V4SI
10174             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10175             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10176            (const_int 16384))
10177           (const_int 15))))]
10178   "TARGET_SHMEDIA"
10179   "mmulfxrp.w   %1, %2, %0"
10180   [(set_attr "type" "dmpy_media")])
10182 (define_expand "mmulhi_wl"
10183   [(match_operand:V2SI 0 "arith_reg_dest" "")
10184    (match_operand:V4HI 1 "arith_reg_operand" "")
10185    (match_operand:V4HI 2 "arith_reg_operand" "")]
10186   "TARGET_SHMEDIA"
10187   "
10189   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10190              (operands[0], operands[1], operands[2]));
10191   DONE;
10194 (define_expand "mmullo_wl"
10195   [(match_operand:V2SI 0 "arith_reg_dest" "")
10196    (match_operand:V4HI 1 "arith_reg_operand" "")
10197    (match_operand:V4HI 2 "arith_reg_operand" "")]
10198   "TARGET_SHMEDIA"
10199   "
10201   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10202              (operands[0], operands[1], operands[2]));
10203   DONE;
10206 (define_insn "mmul23_wl"
10207   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10208         (vec_select:V2SI
10209          (mult:V4SI
10210           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10211           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10212          (parallel [(const_int 2) (const_int 3)])))]
10213   "TARGET_SHMEDIA"
10214   "* return (TARGET_LITTLE_ENDIAN
10215              ? \"mmulhi.wl      %1, %2, %0\"
10216              : \"mmullo.wl      %1, %2, %0\");"
10217   [(set_attr "type" "dmpy_media")])
10219 (define_insn "mmul01_wl"
10220   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10221         (vec_select:V2SI
10222          (mult:V4SI
10223           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10224           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10225          (parallel [(const_int 0) (const_int 1)])))]
10226   "TARGET_SHMEDIA"
10227   "* return (TARGET_LITTLE_ENDIAN
10228              ? \"mmullo.wl      %1, %2, %0\"
10229              : \"mmulhi.wl      %1, %2, %0\");"
10230   [(set_attr "type" "dmpy_media")])
10232 (define_expand "mmulsum_wq"
10233   [(match_operand:DI 0 "arith_reg_dest" "")
10234    (match_operand:V4HI 1 "arith_reg_operand" "")
10235    (match_operand:V4HI 2 "arith_reg_operand" "")
10236    (match_operand:DI 3 "arith_reg_operand" "")]
10237   "TARGET_SHMEDIA"
10238   "
10240   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10241                                operands[1], operands[2]));
10242   DONE;
10245 (define_insn "mmulsum_wq_i"
10246   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10247         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10248          (plus:DI
10249           (plus:DI
10250            (vec_select:DI
10251             (mult:V4DI
10252              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10253              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10254             (parallel [(const_int 0)]))
10255            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10256                                      (sign_extend:V4DI (match_dup 3)))
10257                           (parallel [(const_int 1)])))
10258           (plus:DI
10259            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10260                                      (sign_extend:V4DI (match_dup 3)))
10261                           (parallel [(const_int 2)]))
10262            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10263                                      (sign_extend:V4DI (match_dup 3)))
10264                           (parallel [(const_int 3)]))))))]
10265   "TARGET_SHMEDIA"
10266   "mmulsum.wq   %2, %3, %0"
10267   [(set_attr "type" "mac_media")])
10269 (define_expand "mperm_w"
10270   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10271    (match_operand:V4HI 1 "arith_reg_operand" "r")
10272    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10273   "TARGET_SHMEDIA"
10274   "
10276   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10277              (operands[0], operands[1], operands[2]));
10278   DONE;
10281 ; This use of vec_select isn't exactly correct according to rtl.texi
10282 ; (because not constant), but it seems a straightforward extension.
10283 (define_insn "mperm_w_little"
10284   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10285         (vec_select:V4HI
10286          (match_operand:V4HI 1 "arith_reg_operand" "r")
10287          (parallel
10288           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10289                             (const_int 2) (const_int 0))
10290            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10291            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10292            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10293   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10294   "mperm.w      %1, %N2, %0"
10295   [(set_attr "type" "arith_media")])
10297 (define_insn "mperm_w_big"
10298   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10299         (vec_select:V4HI
10300          (match_operand:V4HI 1 "arith_reg_operand" "r")
10301          (parallel
10302           [(zero_extract:QI (not:QI (match_operand:QI 2
10303                                      "extend_reg_or_0_operand" "rZ"))
10304                             (const_int 2) (const_int 0))
10305            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10306            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10307            (zero_extract:QI (not:QI (match_dup 2))
10308                             (const_int 2) (const_int 6))])))]
10309   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10310   "mperm.w      %1, %N2, %0"
10311   [(set_attr "type" "arith_media")])
10313 (define_insn "mperm_w0"
10314   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10315         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10316                                           "trunc_hi_operand" "r"))))]
10317   "TARGET_SHMEDIA"
10318   "mperm.w      %1, r63, %0"
10319   [(set_attr "type" "arith_media")])
10321 (define_expand "msad_ubq"
10322   [(match_operand:DI 0 "arith_reg_dest" "")
10323    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10324    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10325    (match_operand:DI 3 "arith_reg_operand" "")]
10326   "TARGET_SHMEDIA"
10327   "
10329   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10330                              operands[1], operands[2]));
10331   DONE;
10334 (define_insn "msad_ubq_i"
10335   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10336         (plus:DI
10337          (plus:DI
10338           (plus:DI
10339            (plus:DI
10340             (match_operand:DI 1 "arith_reg_operand" "0")
10341             (abs:DI (vec_select:DI
10342                      (minus:V8DI
10343                       (zero_extend:V8DI
10344                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10345                       (zero_extend:V8DI
10346                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10347                      (parallel [(const_int 0)]))))
10348            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10349                                               (zero_extend:V8DI (match_dup 3)))
10350                                   (parallel [(const_int 1)]))))
10351           (plus:DI
10352            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10353                                               (zero_extend:V8DI (match_dup 3)))
10354                                   (parallel [(const_int 2)])))
10355            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10356                                               (zero_extend:V8DI (match_dup 3)))
10357                                   (parallel [(const_int 3)])))))
10358          (plus:DI
10359           (plus:DI
10360            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10361                                               (zero_extend:V8DI (match_dup 3)))
10362                                   (parallel [(const_int 4)])))
10363            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10364                                               (zero_extend:V8DI (match_dup 3)))
10365                                   (parallel [(const_int 5)]))))
10366           (plus:DI
10367            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10368                                               (zero_extend:V8DI (match_dup 3)))
10369                                   (parallel [(const_int 6)])))
10370            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10371                                               (zero_extend:V8DI (match_dup 3)))
10372                                   (parallel [(const_int 7)])))))))]
10373   "TARGET_SHMEDIA"
10374   "msad.ubq     %N2, %N3, %0"
10375   [(set_attr "type" "mac_media")])
10377 (define_insn "mshalds_l"
10378   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10379         (ss_truncate:V2SI
10380          (ashift:V2DI
10381           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10382           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10383                   (const_int 31)))))]
10384   "TARGET_SHMEDIA"
10385   "mshalds.l    %1, %2, %0"
10386   [(set_attr "type" "mcmp_media")])
10388 (define_insn "mshalds_w"
10389   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10390         (ss_truncate:V4HI
10391          (ashift:V4SI
10392           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10393           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10394                   (const_int 15)))))]
10395   "TARGET_SHMEDIA"
10396   "mshalds.w    %1, %2, %0"
10397   [(set_attr "type" "mcmp_media")])
10399 (define_insn "ashrv2si3"
10400   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10401         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10402                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10403   "TARGET_SHMEDIA"
10404   "mshard.l     %1, %2, %0"
10405   [(set_attr "type" "arith_media")])
10407 (define_insn "ashrv4hi3"
10408   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10409         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10410                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10411   "TARGET_SHMEDIA"
10412   "mshard.w     %1, %2, %0"
10413   [(set_attr "type" "arith_media")])
10415 (define_insn "mshards_q"
10416   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10417         (ss_truncate:HI
10418          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10419                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10420   "TARGET_SHMEDIA"
10421   "mshards.q    %1, %N2, %0"
10422   [(set_attr "type" "mcmp_media")])
10424 (define_expand "mshfhi_b"
10425   [(match_operand:V8QI 0 "arith_reg_dest" "")
10426    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10427    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10428   "TARGET_SHMEDIA"
10429   "
10431   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10432              (operands[0], operands[1], operands[2]));
10433   DONE;
10436 (define_expand "mshflo_b"
10437   [(match_operand:V8QI 0 "arith_reg_dest" "")
10438    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10439    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10440   "TARGET_SHMEDIA"
10441   "
10443   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10444              (operands[0], operands[1], operands[2]));
10445   DONE;
10448 (define_insn "mshf4_b"
10449   [(set
10450     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10451     (vec_select:V8QI
10452      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10453                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10454      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10455                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10456   "TARGET_SHMEDIA"
10457   "* return (TARGET_LITTLE_ENDIAN
10458              ? \"mshfhi.b       %N1, %N2, %0\"
10459              : \"mshflo.b       %N1, %N2, %0\");"
10460   [(set_attr "type" "arith_media")])
10462 (define_insn "mshf0_b"
10463   [(set
10464     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10465     (vec_select:V8QI
10466      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10467                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10468      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10469                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10470   "TARGET_SHMEDIA"
10471   "* return (TARGET_LITTLE_ENDIAN
10472              ? \"mshflo.b       %N1, %N2, %0\"
10473              : \"mshfhi.b       %N1, %N2, %0\");"
10474   [(set_attr "type" "arith_media")])
10476 (define_expand "mshfhi_l"
10477   [(match_operand:V2SI 0 "arith_reg_dest" "")
10478    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10479    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10480   "TARGET_SHMEDIA"
10481   "
10483   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10484              (operands[0], operands[1], operands[2]));
10485   DONE;
10488 (define_expand "mshflo_l"
10489   [(match_operand:V2SI 0 "arith_reg_dest" "")
10490    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10491    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10492   "TARGET_SHMEDIA"
10493   "
10495   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10496              (operands[0], operands[1], operands[2]));
10497   DONE;
10500 (define_insn "mshf4_l"
10501   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10502         (vec_select:V2SI
10503          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10504                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10505          (parallel [(const_int 1) (const_int 3)])))]
10506   "TARGET_SHMEDIA"
10507   "* return (TARGET_LITTLE_ENDIAN
10508              ? \"mshfhi.l       %N1, %N2, %0\"
10509              : \"mshflo.l       %N1, %N2, %0\");"
10510   [(set_attr "type" "arith_media")])
10512 (define_insn "mshf0_l"
10513   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10514         (vec_select:V2SI
10515          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10516                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10517          (parallel [(const_int 0) (const_int 2)])))]
10518   "TARGET_SHMEDIA"
10519   "* return (TARGET_LITTLE_ENDIAN
10520              ? \"mshflo.l       %N1, %N2, %0\"
10521              : \"mshfhi.l       %N1, %N2, %0\");"
10522   [(set_attr "type" "arith_media")])
10524 (define_expand "mshfhi_w"
10525   [(match_operand:V4HI 0 "arith_reg_dest" "")
10526    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10527    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10528   "TARGET_SHMEDIA"
10529   "
10531   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10532              (operands[0], operands[1], operands[2]));
10533   DONE;
10536 (define_expand "mshflo_w"
10537   [(match_operand:V4HI 0 "arith_reg_dest" "")
10538    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10539    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10540   "TARGET_SHMEDIA"
10541   "
10543   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10544              (operands[0], operands[1], operands[2]));
10545   DONE;
10548 (define_insn "mshf4_w"
10549   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10550         (vec_select:V4HI
10551          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10552                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10553          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10554   "TARGET_SHMEDIA"
10555   "* return (TARGET_LITTLE_ENDIAN
10556              ? \"mshfhi.w       %N1, %N2, %0\"
10557              : \"mshflo.w       %N1, %N2, %0\");"
10558   [(set_attr "type" "arith_media")])
10560 (define_insn "mshf0_w"
10561   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10562         (vec_select:V4HI
10563          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10564                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10565          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10566   "TARGET_SHMEDIA"
10567   "* return (TARGET_LITTLE_ENDIAN
10568              ? \"mshflo.w       %N1, %N2, %0\"
10569              : \"mshfhi.w       %N1, %N2, %0\");"
10570   [(set_attr "type" "arith_media")])
10572 (define_insn "mshflo_w_x"
10573   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10574         (vec_select:V4HI
10575          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10576                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10577          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10578   "TARGET_SHMEDIA"
10579   "mshflo.w     %N1, %N2, %0"
10580   [(set_attr "type" "arith_media")])
10582 /* These are useful to expand ANDs and as combiner patterns.  */
10583 (define_insn_and_split "mshfhi_l_di"
10584   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10585         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10586                              (const_int 32))
10587                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10588                         (const_int -4294967296))))]
10589   "TARGET_SHMEDIA"
10590   "@
10591         mshfhi.l        %N1, %N2, %0
10592         #"
10593   "TARGET_SHMEDIA && reload_completed
10594    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10595   [(set (match_dup 3) (match_dup 4))
10596    (set (match_dup 5) (match_dup 6))]
10597   "
10599   operands[3] = gen_lowpart (SImode, operands[0]);
10600   operands[4] = gen_highpart (SImode, operands[1]);
10601   operands[5] = gen_highpart (SImode, operands[0]);
10602   operands[6] = gen_highpart (SImode, operands[2]);
10604   [(set_attr "type" "arith_media")])
10606 (define_insn "*mshfhi_l_di_rev"
10607   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10608         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10609                         (const_int -4294967296))
10610                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10611                              (const_int 32))))]
10612   "TARGET_SHMEDIA"
10613   "mshfhi.l     %N2, %N1, %0"
10614   [(set_attr "type" "arith_media")])
10616 (define_split
10617   [(set (match_operand:DI 0 "arith_reg_dest" "")
10618         (ior:DI (zero_extend:DI (match_operand:SI 1
10619                                               "extend_reg_or_0_operand" ""))
10620                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10621                         (const_int -4294967296))))
10622    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10623   "TARGET_SHMEDIA"
10624   [(const_int 0)]
10625   "
10627   emit_insn (gen_ashldi3_media (operands[3],
10628                                 simplify_gen_subreg (DImode, operands[1],
10629                                                      SImode, 0),
10630                                 GEN_INT (32)));
10631   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10632   DONE;
10635 (define_insn "mshflo_l_di"
10636   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10637         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10638                         (const_int 4294967295))
10639                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10640                            (const_int 32))))]
10642   "TARGET_SHMEDIA"
10643   "mshflo.l     %N1, %N2, %0"
10644   [(set_attr "type" "arith_media")])
10646 (define_insn "*mshflo_l_di_rev"
10647   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10648         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10649                            (const_int 32))
10650                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10651                         (const_int 4294967295))))]
10653   "TARGET_SHMEDIA"
10654   "mshflo.l     %N2, %N1, %0"
10655   [(set_attr "type" "arith_media")])
10657 ;; Combiner pattern for trampoline initialization.
10658 (define_insn_and_split "*double_shori"
10659   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10660         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10661                            (const_int 32))
10662                 (match_operand:DI 2 "const_int_operand" "n")))]
10663   "TARGET_SHMEDIA
10664    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10665   "#"
10666   "rtx_equal_p (operands[0], operands[1])"
10667   [(const_int 0)]
10668   "
10670   HOST_WIDE_INT v = INTVAL (operands[2]);
10672   emit_insn (gen_shori_media (operands[0], operands[0],
10673              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10674   emit_insn (gen_shori_media (operands[0], operands[0],
10675                               gen_int_mode (v, HImode)));
10676   DONE;
10680 (define_insn "*mshflo_l_di_x"
10681   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10682         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10683                                  "rZ"))
10684                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10685                            (const_int 32))))]
10687   "TARGET_SHMEDIA"
10688   "mshflo.l     %N1, %N2, %0"
10689   [(set_attr "type" "arith_media")])
10691 (define_insn_and_split "concat_v2sf"
10692   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10693 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10694         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10695                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10697   "TARGET_SHMEDIA"
10698   "@
10699         mshflo.l        %N1, %N2, %0
10700         #
10701         #"
10702   "TARGET_SHMEDIA && reload_completed
10703    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10704   [(set (match_dup 3) (match_dup 1))
10705    (set (match_dup 4) (match_dup 2))]
10706   "
10708   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10709   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10711   [(set_attr "type" "arith_media")])
10713 (define_insn "*mshflo_l_di_x_rev"
10714   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10715         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10716                            (const_int 32))
10717                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10719   "TARGET_SHMEDIA"
10720   "mshflo.l     %N2, %N1, %0"
10721   [(set_attr "type" "arith_media")])
10723 (define_insn "ashlv2si3"
10724   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10725         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10726                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10727   "TARGET_SHMEDIA"
10728   "mshlld.l     %1, %2, %0"
10729   [(set_attr "type" "arith_media")])
10731 (define_insn "ashlv4hi3"
10732   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10733         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10734                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10735   "TARGET_SHMEDIA"
10736   "mshlld.w     %1, %2, %0"
10737   [(set_attr "type" "arith_media")])
10739 (define_insn "lshrv2si3"
10740   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10741         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10742                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10743   "TARGET_SHMEDIA"
10744   "mshlrd.l     %1, %2, %0"
10745   [(set_attr "type" "arith_media")])
10747 (define_insn "lshrv4hi3"
10748   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10749         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10750                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10751   "TARGET_SHMEDIA"
10752   "mshlrd.w     %1, %2, %0"
10753   [(set_attr "type" "arith_media")])
10755 (define_insn "subv2si3"
10756   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10757         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10758                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10759   "TARGET_SHMEDIA"
10760   "msub.l       %N1, %2, %0"
10761   [(set_attr "type" "arith_media")])
10763 (define_insn "subv4hi3"
10764   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10765         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10766                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10767   "TARGET_SHMEDIA"
10768   "msub.w       %N1, %2, %0"
10769   [(set_attr "type" "arith_media")])
10771 (define_insn "sssubv2si3"
10772   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10773         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10774                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10775   "TARGET_SHMEDIA"
10776   "msubs.l      %N1, %2, %0"
10777   [(set_attr "type" "mcmp_media")])
10779 (define_insn "ussubv8qi3"
10780   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10781         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10782                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10783   "TARGET_SHMEDIA"
10784   "msubs.ub     %1, %2, %0"
10785   [(set_attr "type" "mcmp_media")])
10787 (define_insn "sssubv4hi3"
10788   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10789         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10790                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10791   "TARGET_SHMEDIA"
10792   "msubs.w      %N1, %2, %0"
10793   [(set_attr "type" "mcmp_media")])
10795 ;; Floating Point Intrinsics
10797 (define_insn "fcosa_s"
10798   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10799         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10800                    UNSPEC_FCOSA))]
10801   "TARGET_SHMEDIA"
10802   "fcosa.s      %1, %0"
10803   [(set_attr "type" "atrans_media")])
10805 (define_insn "fsina_s"
10806   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10807         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10808                    UNSPEC_FSINA))]
10809   "TARGET_SHMEDIA"
10810   "fsina.s      %1, %0"
10811   [(set_attr "type" "atrans_media")])
10813 (define_insn "fipr"
10814   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10815         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10816                                                     "fp_arith_reg_operand" "f")
10817                                                    (match_operand:V4SF 2
10818                                                     "fp_arith_reg_operand" "f"))
10819                                          (parallel [(const_int 0)]))
10820                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10821                                          (parallel [(const_int 1)])))
10822                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10823                                          (parallel [(const_int 2)]))
10824                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10825                                          (parallel [(const_int 3)])))))]
10826   "TARGET_SHMEDIA"
10827   "fipr.s       %1, %2, %0"
10828   [(set_attr "type" "fparith_media")])
10830 (define_insn "fsrra_s"
10831   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10832         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10833                    UNSPEC_FSRRA))]
10834   "TARGET_SHMEDIA"
10835   "fsrra.s      %1, %0"
10836   [(set_attr "type" "atrans_media")])
10838 (define_insn "ftrv"
10839   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10840         (plus:V4SF
10841          (plus:V4SF
10842           (mult:V4SF
10843            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10844                             (parallel [(const_int 0) (const_int 5)
10845                                        (const_int 10) (const_int 15)]))
10846            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10847           (mult:V4SF
10848            (vec_select:V4SF (match_dup 1)
10849                             (parallel [(const_int 4) (const_int 9)
10850                                        (const_int 14) (const_int 3)]))
10851            (vec_select:V4SF (match_dup 2)
10852                             (parallel [(const_int 1) (const_int 2)
10853                                        (const_int 3) (const_int 0)]))))
10854          (plus:V4SF
10855           (mult:V4SF
10856            (vec_select:V4SF (match_dup 1)
10857                             (parallel [(const_int 8) (const_int 13)
10858                                        (const_int 2) (const_int 7)]))
10859            (vec_select:V4SF (match_dup 2)
10860                             (parallel [(const_int 2) (const_int 3)
10861                                        (const_int 0) (const_int 1)])))
10862           (mult:V4SF
10863            (vec_select:V4SF (match_dup 1)
10864                             (parallel [(const_int 12) (const_int 1)
10865                                        (const_int 6) (const_int 11)]))
10866            (vec_select:V4SF (match_dup 2)
10867                             (parallel [(const_int 3) (const_int 0)
10868                                        (const_int 1) (const_int 2)]))))))]
10869   "TARGET_SHMEDIA"
10870   "ftrv.s %1, %2, %0"
10871   [(set_attr "type" "fparith_media")])
10873 (define_insn "nsb"
10874   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10875         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10876                    UNSPEC_NSB))]
10877   "TARGET_SHMEDIA"
10878   "nsb  %1, %0"
10879   [(set_attr "type" "arith_media")])
10881 (define_insn "nsbsi"
10882   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10883         (zero_extend:SI
10884          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10885                     UNSPEC_NSB)))]
10886   "TARGET_SHMEDIA"
10887   "nsb  %1, %0"
10888   [(set_attr "type" "arith_media")])
10890 (define_insn "nsbdi"
10891   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10892         (zero_extend:DI
10893          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10894                     UNSPEC_NSB)))]
10895   "TARGET_SHMEDIA"
10896   "nsb  %1, %0"
10897   [(set_attr "type" "arith_media")])
10899 (define_expand "ffsdi2"
10900   [(set (match_operand:DI 0 "arith_reg_dest" "")
10901         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10902   "TARGET_SHMEDIA"
10903   "
10905   rtx scratch = gen_reg_rtx (DImode);
10906   rtx last;
10908   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10909   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10910   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10911   emit_insn (gen_nsbdi (scratch, scratch));
10912   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10913   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10914   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10915   REG_NOTES (last)
10916     = gen_rtx_EXPR_LIST (REG_EQUAL,
10917                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10918   DONE;
10921 (define_expand "ffssi2"
10922   [(set (match_operand:SI 0 "arith_reg_dest" "")
10923         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10924   "TARGET_SHMEDIA"
10925   "
10927   rtx scratch = gen_reg_rtx (SImode);
10928   rtx discratch = gen_reg_rtx (DImode);
10929   rtx last;
10931   emit_insn (gen_adddi3 (discratch,
10932                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10933                          constm1_rtx));
10934   emit_insn (gen_andcdi3 (discratch,
10935                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10936                           discratch));
10937   emit_insn (gen_nsbsi (scratch, discratch));
10938   last = emit_insn (gen_subsi3 (operands[0],
10939                                 force_reg (SImode, GEN_INT (63)), scratch));
10940   REG_NOTES (last)
10941     = gen_rtx_EXPR_LIST (REG_EQUAL,
10942                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10943   DONE;
10946 (define_insn "byterev"
10947   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10948         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10949                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10950                                     (const_int 4) (const_int 3) (const_int 2)
10951                                     (const_int 1) (const_int 0)])))]
10952   "TARGET_SHMEDIA"
10953   "byterev      %1, %0"
10954   [(set_attr "type" "arith_media")])
10956 (define_insn "prefetch_media"
10957   [(prefetch (match_operand:QI 0 "address_operand" "p")
10958              (match_operand:SI 1 "const_int_operand" "n")
10959              (match_operand:SI 2 "const_int_operand" "n"))]
10960   "TARGET_SHMEDIA"
10961   "*
10963   operands[0] = gen_rtx_MEM (QImode, operands[0]);
10964   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
10965   return \"\";
10967   [(set_attr "type" "other")])
10969 (define_insn "prefetch_i4"
10970   [(prefetch (match_operand:SI 0 "register_operand" "r")
10971              (match_operand:SI 1 "const_int_operand" "n")
10972              (match_operand:SI 2 "const_int_operand" "n"))]
10973   "TARGET_HARD_SH4"
10974   "*
10976   return \"pref @%0\";
10978   [(set_attr "type" "other")])
10980 (define_expand "prefetch"
10981   [(prefetch (match_operand:QI 0 "address_operand" "p")
10982              (match_operand:SI 1 "const_int_operand" "n")
10983              (match_operand:SI 2 "const_int_operand" "n"))]
10984   "TARGET_SHMEDIA || TARGET_HARD_SH4"
10985   "
10987   if (TARGET_HARD_SH4 && ! register_operand (operands[0], SImode))
10988     {
10989       rtx reg = gen_reg_rtx (SImode);
10990       emit_move_insn (reg, operands[0]);
10991       operands[0] = reg;
10992     }
10994   emit_insn ((TARGET_SHMEDIA ? gen_prefetch_media : gen_prefetch_i4)
10995              (operands[0], operands[1], operands[2]));
10996   DONE;