config/sh/sh.md ("length"): Increase branch length when SH1 pic code to 18:
[official-gcc.git] / gcc / config / sh / sh.md
blob31e05a2fead98988a10e3e5c850d66de9069fcab
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
50 ;; Special formats used for outputting SH instructions:
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
60 ;; Special predicates:
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
82   (FPSCR_REG    151)
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
116   (XD0_REG      136)
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
147   ;; These are used with unspec_volatile.
148   (UNSPECV_BLOCKAGE     0)
149   (UNSPECV_ALIGN        1)
150   (UNSPECV_CONST2       2)
151   (UNSPECV_CONST4       4)
152   (UNSPECV_CONST8       6)
153   (UNSPECV_WINDOW_END   10)
154   (UNSPECV_CONST_END    11)
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
161 ;; Target CPU.
163 (define_attr "cpu"
164  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
165   (const (symbol_ref "sh_cpu_attr")))
167 (define_attr "endian" "big,little"
168  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169                       (const_string "little") (const_string "big"))))
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174                          (const_string "yes") (const_string "no"))))
176 (define_attr "fmovd" "yes,no"
177   (const (if_then_else (symbol_ref "TARGET_FMOVD")
178                        (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181   (const
182    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184          (const_string "sh1"))))
186 ;; cbranch      conditional branch instructions
187 ;; jump         unconditional jumps
188 ;; arith        ordinary arithmetic
189 ;; arith3       a compound insn that behaves similarly to a sequence of
190 ;;              three insns of type arith
191 ;; arith3b      like above, but might end with a redirected branch
192 ;; load         from memory
193 ;; load_si      Likewise, SImode variant for general register.
194 ;; fload        Likewise, but load to fp register.
195 ;; store        to memory
196 ;; move         general purpose register to register
197 ;; mt_group     other sh4 mt instructions
198 ;; fmove        register to register, floating point
199 ;; smpy         word precision integer multiply
200 ;; dmpy         longword or doublelongword precision integer multiply
201 ;; return       rts
202 ;; pload        load of pr reg, which can't be put into delay slot of rts
203 ;; prset        copy register to pr reg, ditto
204 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
205 ;; prget        copy pr to register, ditto
206 ;; pcload       pc relative load of constant value
207 ;; pcfload      Likewise, but load to fp register.
208 ;; pcload_si    Likewise, SImode variant for general register.
209 ;; rte          return from exception
210 ;; sfunc        special function call with known used registers
211 ;; call         function call
212 ;; fp           floating point
213 ;; fdiv         floating point divide (or square root)
214 ;; gp_fpul      move from general purpose register to fpul
215 ;; fpul_gp      move from fpul to general purpose register
216 ;; mac_gp       move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s       fix_truncsfsi2_i4
219 ;; dfdiv        double precision floating point divide (or square root)
220 ;; cwb          ic_invalidate_line_i
221 ;; movua        SH4a unaligned load
222 ;; fsrra        square root reciprocal approximate
223 ;; fsca         sine and cosine approximate
224 ;; tls_load     load TLS related address
225 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media    SHmedia compare instructions
228 ;; dfdiv_media  SHmedia double precision divide and square root
229 ;; dfmul_media  SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media   SHmedia longword multiply
233 ;; fcmp_media   SHmedia floating point compare instructions
234 ;; fdiv_media   SHmedia single precision divide and square root
235 ;; fload_media  SHmedia floating point register load instructions
236 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media  SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media   SHmedia unconditional branch instructions
243 ;; load_media   SHmedia general register load instructions
244 ;; pt_media     SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media  SHmedia ptabs instruction
246 ;; store_media  SHmedia general register store instructions
247 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media    SHmedia mac-style fixed point operations
249 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
250 ;; atrans       SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil          no-op move, will be deleted.
254 (define_attr "type"
255  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
256   (const_string "other"))
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
261 ;; mt_group      SH4 "mt" group instructions.
263 ;; ex_group      SH4 "ex" group instructions.
265 ;; ls_group      SH4 "ls" group instructions.
268 (define_attr "insn_class"
269   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273          (eq_attr "type" "cbranch,jump") (const_string "br_group")
274          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275            (const_string "fe_group")
276          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
277         (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
289 ;; state.
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long.  Something in the
296 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
299 ; 2 bytes.
301 ;; The maximum range used for SImode constant pool entries is 1018.  A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table.  That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
318 ;; inside an le.
319 (define_attr "short_cbranch_p" "no,yes"
320   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
321          (const_string "no")
322          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
323          (const_string "yes")
324          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
325          (const_string "no")
326          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
327          (const_string "yes")
328          ] (const_string "no")))
330 (define_attr "med_branch_p" "no,yes"
331   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
332               (const_int 1988))
333          (const_string "yes")
334          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335          (const_string "no")
336          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
337               (const_int 8186))
338          (const_string "yes")
339          ] (const_string "no")))
341 (define_attr "med_cbranch_p" "no,yes"
342   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
343               (const_int 1986))
344          (const_string "yes")
345          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
346          (const_string "no")
347          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
348                (const_int 8184))
349          (const_string "yes")
350          ] (const_string "no")))
352 (define_attr "braf_branch_p" "no,yes"
353   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
356               (const_int 20660))
357          (const_string "yes")
358          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
359          (const_string "no")
360          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
361               (const_int 65530))
362          (const_string "yes")
363          ] (const_string "no")))
365 (define_attr "braf_cbranch_p" "no,yes"
366   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
367          (const_string "no")
368          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
369               (const_int 20658))
370          (const_string "yes")
371          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
372          (const_string "no")
373          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
374               (const_int 65528))
375          (const_string "yes")
376          ] (const_string "no")))
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
385 ; All other instructions are two bytes long by default.
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390   (cond [(eq_attr "type" "cbranch")
391          (cond [(eq_attr "short_cbranch_p" "yes")
392                 (const_int 2)
393                 (eq_attr "med_cbranch_p" "yes")
394                 (const_int 6)
395                 (eq_attr "braf_cbranch_p" "yes")
396                 (const_int 12)
397 ;; ??? using pc is not computed transitively.
398                 (ne (match_dup 0) (match_dup 0))
399                 (const_int 14)
400                 (ne (symbol_ref ("flag_pic")) (const_int 0))
401                 (const_int 24)
402                 ] (const_int 16))
403          (eq_attr "type" "jump")
404          (cond [(eq_attr "med_branch_p" "yes")
405                 (const_int 2)
406                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
407                          (symbol_ref "INSN"))
408                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409                          (symbol_ref "code_for_indirect_jump_scratch")))
410                 (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")])
1169 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1170 ;; hard register 0.  If we used hard register 0, then the next instruction
1171 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1172 ;; gets allocated to a stack slot that needs its address reloaded, then
1173 ;; there is nothing to prevent reload from using r0 to reload the address.
1174 ;; This reload would clobber the value in r0 we are trying to store.
1175 ;; If we let reload allocate r0, then this problem can never happen.
1177 (define_insn "udivsi3_i1"
1178   [(set (match_operand:SI 0 "register_operand" "=z")
1179         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1180    (clobber (reg:SI T_REG))
1181    (clobber (reg:SI PR_REG))
1182    (clobber (reg:SI R4_REG))
1183    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1184   "TARGET_SH1 && ! TARGET_SH4"
1185   "jsr  @%1%#"
1186   [(set_attr "type" "sfunc")
1187    (set_attr "needs_delay_slot" "yes")])
1189 ; Since shmedia-nofpu code could be linked against shcompact code, and
1190 ; the udivsi3 libcall has the same name, we must consider all registers
1191 ; clobbered that are in the union of the registers clobbered by the
1192 ; shmedia and the shcompact implementation.  Note, if the shcompact
1193 ; implementation actually used shcompact code, we'd need to clobber
1194 ; also r23 and fr23.
1195 (define_insn "udivsi3_i1_media"
1196   [(set (match_operand:SI 0 "register_operand" "=z")
1197         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1198    (clobber (reg:SI T_MEDIA_REG))
1199    (clobber (reg:SI PR_MEDIA_REG))
1200    (clobber (reg:SI R20_REG))
1201    (clobber (reg:SI R21_REG))
1202    (clobber (reg:SI R22_REG))
1203    (clobber (reg:DI TR0_REG))
1204    (clobber (reg:DI TR1_REG))
1205    (clobber (reg:DI TR2_REG))
1206    (use (match_operand:DI 1 "target_operand" "b"))]
1207   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1208   "blink        %1, r18"
1209   [(set_attr "type" "sfunc")
1210    (set_attr "needs_delay_slot" "yes")])
1212 (define_expand "udivsi3_i4_media"
1213   [(set (match_dup 3)
1214         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1215    (set (match_dup 4)
1216         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1217    (set (match_dup 5) (float:DF (match_dup 3)))
1218    (set (match_dup 6) (float:DF (match_dup 4)))
1219    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1220    (set (match_dup 8) (fix:DI (match_dup 7)))
1221    (set (match_operand:SI 0 "register_operand" "")
1222         (truncate:SI (match_dup 8)))]
1223   "TARGET_SHMEDIA_FPU"
1224   "
1226   operands[3] = gen_reg_rtx (DImode);
1227   operands[4] = gen_reg_rtx (DImode);
1228   operands[5] = gen_reg_rtx (DFmode);
1229   operands[6] = gen_reg_rtx (DFmode);
1230   operands[7] = gen_reg_rtx (DFmode);
1231   operands[8] = gen_reg_rtx (DImode);
1234 (define_insn "udivsi3_i4"
1235   [(set (match_operand:SI 0 "register_operand" "=y")
1236         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1237    (clobber (reg:SI T_REG))
1238    (clobber (reg:SI PR_REG))
1239    (clobber (reg:DF DR0_REG))
1240    (clobber (reg:DF DR2_REG))
1241    (clobber (reg:DF DR4_REG))
1242    (clobber (reg:SI R0_REG))
1243    (clobber (reg:SI R1_REG))
1244    (clobber (reg:SI R4_REG))
1245    (clobber (reg:SI R5_REG))
1246    (use (reg:PSI FPSCR_REG))
1247    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1248   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1249   "jsr  @%1%#"
1250   [(set_attr "type" "sfunc")
1251    (set_attr "fp_mode" "double")
1252    (set_attr "needs_delay_slot" "yes")])
1254 (define_insn "udivsi3_i4_single"
1255   [(set (match_operand:SI 0 "register_operand" "=y")
1256         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1257    (clobber (reg:SI T_REG))
1258    (clobber (reg:SI PR_REG))
1259    (clobber (reg:DF DR0_REG))
1260    (clobber (reg:DF DR2_REG))
1261    (clobber (reg:DF DR4_REG))
1262    (clobber (reg:SI R0_REG))
1263    (clobber (reg:SI R1_REG))
1264    (clobber (reg:SI R4_REG))
1265    (clobber (reg:SI R5_REG))
1266    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1267   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1268   "jsr  @%1%#"
1269   [(set_attr "type" "sfunc")
1270    (set_attr "needs_delay_slot" "yes")])
1272 (define_expand "udivsi3"
1273   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1274    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1275    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1276    (parallel [(set (match_operand:SI 0 "register_operand" "")
1277                    (udiv:SI (reg:SI R4_REG)
1278                             (reg:SI R5_REG)))
1279               (clobber (reg:SI T_REG))
1280               (clobber (reg:SI PR_REG))
1281               (clobber (reg:SI R4_REG))
1282               (use (match_dup 3))])]
1283   ""
1284   "
1286   rtx first, last;
1288   operands[3] = gen_reg_rtx (Pmode);
1289   /* Emit the move of the address to a pseudo outside of the libcall.  */
1290   if (TARGET_HARD_SH4 && TARGET_SH2E)
1291     {
1292       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1293       if (TARGET_FPU_SINGLE)
1294         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1295       else
1296         last = gen_udivsi3_i4 (operands[0], operands[3]);
1297     }
1298   else if (TARGET_SHMEDIA_FPU)
1299     {
1300       operands[1] = force_reg (SImode, operands[1]);
1301       operands[2] = force_reg (SImode, operands[2]);
1302       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1303       DONE;
1304     }
1305   else if (TARGET_SH2A)
1306     {
1307       operands[1] = force_reg (SImode, operands[1]);
1308       operands[2] = force_reg (SImode, operands[2]);
1309       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1310       DONE;
1311     }
1312   else if (TARGET_SH5)
1313     {
1314       emit_move_insn (operands[3],
1315                       function_symbol (TARGET_FPU_ANY
1316                                        ? \"__udivsi3_i4\"
1317                                        : \"__udivsi3\"));
1319       if (TARGET_SHMEDIA)
1320         last = gen_udivsi3_i1_media (operands[0],
1321                                      Pmode == DImode
1322                                      ? operands[3]
1323                                      : gen_rtx_SUBREG (DImode, operands[3],
1324                                                        0));
1325       else if (TARGET_FPU_ANY)
1326         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1327       else
1328         last = gen_udivsi3_i1 (operands[0], operands[3]);
1329     }
1330   else
1331     {
1332       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1333       last = gen_udivsi3_i1 (operands[0], operands[3]);
1334     }
1335   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1336   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1337   last = emit_insn (last);
1338   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1339      invariant code motion can move it.  */
1340   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1341   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1342   DONE;
1345 (define_insn "divsi3_sh2a"
1346   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1347         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1348                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1349   "TARGET_SH2A"
1350   "divs %2,%1"
1351   [(set_attr "type" "arith")])
1353 (define_insn "divsi3_i1"
1354   [(set (match_operand:SI 0 "register_operand" "=z")
1355         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1356    (clobber (reg:SI T_REG))
1357    (clobber (reg:SI PR_REG))
1358    (clobber (reg:SI R1_REG))
1359    (clobber (reg:SI R2_REG))
1360    (clobber (reg:SI R3_REG))
1361    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1362   "TARGET_SH1 && ! TARGET_SH4"
1363   "jsr  @%1%#"
1364   [(set_attr "type" "sfunc")
1365    (set_attr "needs_delay_slot" "yes")])
1367 ; Since shmedia-nofpu code could be linked against shcompact code, and
1368 ; the sdivsi3 libcall has the same name, we must consider all registers
1369 ; clobbered that are in the union of the registers clobbered by the
1370 ; shmedia and the shcompact implementation.  Note, if the shcompact
1371 ; implementation actually used shcompact code, we'd need to clobber
1372 ; also r22, r23 and fr23.
1373 (define_insn "divsi3_i1_media"
1374   [(set (match_operand:SI 0 "register_operand" "=z")
1375         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1376    (clobber (reg:SI T_MEDIA_REG))
1377    (clobber (reg:SI PR_MEDIA_REG))
1378    (clobber (reg:SI R1_REG))
1379    (clobber (reg:SI R2_REG))
1380    (clobber (reg:SI R3_REG))
1381    (clobber (reg:SI R20_REG))
1382    (clobber (reg:SI R21_REG))
1383    (clobber (reg:DI TR0_REG))
1384    (clobber (reg:DI TR1_REG))
1385    (clobber (reg:DI TR2_REG))
1386    (use (match_operand:DI 1 "target_operand" "b"))]
1387   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1388   "blink        %1, r18"
1389   [(set_attr "type" "sfunc")])
1391 (define_expand "divsi3_i4_media"
1392   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1393    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1394    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1395    (set (match_operand:SI 0 "register_operand" "=r")
1396         (fix:SI (match_dup 5)))]
1397   "TARGET_SHMEDIA_FPU"
1398   "
1400   operands[3] = gen_reg_rtx (DFmode);
1401   operands[4] = gen_reg_rtx (DFmode);
1402   operands[5] = gen_reg_rtx (DFmode);
1405 (define_insn "divsi3_i4"
1406   [(set (match_operand:SI 0 "register_operand" "=y")
1407         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1408    (clobber (reg:SI PR_REG))
1409    (clobber (reg:DF DR0_REG))
1410    (clobber (reg:DF DR2_REG))
1411    (use (reg:PSI FPSCR_REG))
1412    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1413   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1414   "jsr  @%1%#"
1415   [(set_attr "type" "sfunc")
1416    (set_attr "fp_mode" "double")
1417    (set_attr "needs_delay_slot" "yes")])
1419 (define_insn "divsi3_i4_single"
1420   [(set (match_operand:SI 0 "register_operand" "=y")
1421         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1422    (clobber (reg:SI PR_REG))
1423    (clobber (reg:DF DR0_REG))
1424    (clobber (reg:DF DR2_REG))
1425    (clobber (reg:SI R2_REG))
1426    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1427   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1428   "jsr  @%1%#"
1429   [(set_attr "type" "sfunc")
1430    (set_attr "needs_delay_slot" "yes")])
1432 (define_expand "divsi3"
1433   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1434    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1435    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1436    (parallel [(set (match_operand:SI 0 "register_operand" "")
1437                    (div:SI (reg:SI R4_REG)
1438                            (reg:SI R5_REG)))
1439               (clobber (reg:SI T_REG))
1440               (clobber (reg:SI PR_REG))
1441               (clobber (reg:SI R1_REG))
1442               (clobber (reg:SI R2_REG))
1443               (clobber (reg:SI R3_REG))
1444               (use (match_dup 3))])]
1445   ""
1446   "
1448   rtx first, last;
1450   operands[3] = gen_reg_rtx (Pmode);
1451   /* Emit the move of the address to a pseudo outside of the libcall.  */
1452   if (TARGET_HARD_SH4 && TARGET_SH2E)
1453     {
1454       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1455       if (TARGET_FPU_SINGLE)
1456         last = gen_divsi3_i4_single (operands[0], operands[3]);
1457       else
1458         last = gen_divsi3_i4 (operands[0], operands[3]);
1459     }
1460   else if (TARGET_SH2A)
1461     {
1462       operands[1] = force_reg (SImode, operands[1]);
1463       operands[2] = force_reg (SImode, operands[2]);
1464       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
1465       DONE;
1466     }
1467   else if (TARGET_SHMEDIA_FPU)
1468     {
1469       operands[1] = force_reg (SImode, operands[1]);
1470       operands[2] = force_reg (SImode, operands[2]);
1471       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1472       DONE;
1473     }
1474   else if (TARGET_SH5)
1475     {
1476       emit_move_insn (operands[3],
1477                       function_symbol (TARGET_FPU_ANY
1478                                        ? \"__sdivsi3_i4\"
1479                                        : \"__sdivsi3\"));
1481       if (TARGET_SHMEDIA)
1482         last = gen_divsi3_i1_media (operands[0],
1483                                     Pmode == DImode
1484                                     ? operands[3]
1485                                     : gen_rtx_SUBREG (DImode, operands[3],
1486                                                       0));
1487       else if (TARGET_FPU_ANY)
1488         last = gen_divsi3_i4_single (operands[0], operands[3]);
1489       else
1490         last = gen_divsi3_i1 (operands[0], operands[3]);
1491     }
1492   else
1493     {
1494       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1495       last = gen_divsi3_i1 (operands[0], operands[3]);
1496     }
1497   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1498   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1499   last = emit_insn (last);
1500   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1501      invariant code motion can move it.  */
1502   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1503   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1504   DONE;
1507 ;; -------------------------------------------------------------------------
1508 ;; Multiplication instructions
1509 ;; -------------------------------------------------------------------------
1511 (define_insn "umulhisi3_i"
1512   [(set (reg:SI MACL_REG)
1513         (mult:SI (zero_extend:SI
1514                   (match_operand:HI 0 "arith_reg_operand" "r"))
1515                  (zero_extend:SI
1516                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1517   "TARGET_SH1"
1518   "mulu.w       %1,%0"
1519   [(set_attr "type" "smpy")])
1521 (define_insn "mulhisi3_i"
1522   [(set (reg:SI MACL_REG)
1523         (mult:SI (sign_extend:SI
1524                   (match_operand:HI 0 "arith_reg_operand" "r"))
1525                  (sign_extend:SI
1526                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1527   "TARGET_SH1"
1528   "muls.w       %1,%0"
1529   [(set_attr "type" "smpy")])
1531 (define_expand "mulhisi3"
1532   [(set (reg:SI MACL_REG)
1533         (mult:SI (sign_extend:SI
1534                   (match_operand:HI 1 "arith_reg_operand" ""))
1535                  (sign_extend:SI
1536                   (match_operand:HI 2 "arith_reg_operand" ""))))
1537    (set (match_operand:SI 0 "arith_reg_operand" "")
1538         (reg:SI MACL_REG))]
1539   "TARGET_SH1"
1540   "
1542   rtx first, last;
1544   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1545   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1546   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1547      invariant code motion can move it.  */
1548   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1549   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1550   /* expand_binop can't find a suitable code in umul_widen_optab to
1551      make a REG_EQUAL note from, so make one here.
1552      See also smulsi3_highpart.
1553      ??? Alternatively, we could put this at the calling site of expand_binop,
1554      i.e. expand_expr.  */
1555   REG_NOTES (last)
1556     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1557                          REG_NOTES (last));
1558   DONE;
1561 (define_expand "umulhisi3"
1562   [(set (reg:SI MACL_REG)
1563         (mult:SI (zero_extend:SI
1564                   (match_operand:HI 1 "arith_reg_operand" ""))
1565                  (zero_extend:SI
1566                   (match_operand:HI 2 "arith_reg_operand" ""))))
1567    (set (match_operand:SI 0 "arith_reg_operand" "")
1568         (reg:SI MACL_REG))]
1569   "TARGET_SH1"
1570   "
1572   rtx first, last;
1574   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1575   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1576   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1577      invariant code motion can move it.  */
1578   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1579   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1580   /* expand_binop can't find a suitable code in umul_widen_optab to
1581      make a REG_EQUAL note from, so make one here.
1582      See also smulsi3_highpart.
1583      ??? Alternatively, we could put this at the calling site of expand_binop,
1584      i.e. expand_expr.  */
1585   REG_NOTES (last)
1586     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1587                          REG_NOTES (last));
1588   DONE;
1591 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1592 ;; a call to a routine which clobbers known registers.
1594 (define_insn ""
1595   [(set (match_operand:SI 1 "register_operand" "=z")
1596         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1597    (clobber (reg:SI MACL_REG))
1598    (clobber (reg:SI T_REG))
1599    (clobber (reg:SI PR_REG))
1600    (clobber (reg:SI R3_REG))
1601    (clobber (reg:SI R2_REG))
1602    (clobber (reg:SI R1_REG))
1603    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1604   "TARGET_SH1"
1605   "jsr  @%0%#"
1606   [(set_attr "type" "sfunc")
1607    (set_attr "needs_delay_slot" "yes")])
1609 (define_expand "mulsi3_call"
1610   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1611    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1612    (parallel[(set (match_operand:SI 0 "register_operand" "")
1613                   (mult:SI (reg:SI R4_REG)
1614                            (reg:SI R5_REG)))
1615              (clobber (reg:SI MACL_REG))
1616              (clobber (reg:SI T_REG))
1617              (clobber (reg:SI PR_REG))
1618              (clobber (reg:SI R3_REG))
1619              (clobber (reg:SI R2_REG))
1620              (clobber (reg:SI R1_REG))
1621              (use (match_operand:SI 3 "register_operand" ""))])]
1622   "TARGET_SH1"
1623   "")
1625 (define_insn "mul_r"
1626   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1627         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
1628                  (match_operand:SI 2 "arith_reg_operand" "z")))]
1629   "TARGET_SH2A"
1630   "mulr %2,%0"
1631   [(set_attr "type" "dmpy")])
1633 (define_insn "mul_l"
1634   [(set (reg:SI MACL_REG)
1635         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1636                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1637   "TARGET_SH2"
1638   "mul.l        %1,%0"
1639   [(set_attr "type" "dmpy")])
1641 (define_expand "mulsi3"
1642   [(set (reg:SI MACL_REG)
1643         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1644                   (match_operand:SI 2 "arith_reg_operand" "")))
1645    (set (match_operand:SI 0 "arith_reg_operand" "")
1646         (reg:SI MACL_REG))]
1647   "TARGET_SH1"
1648   "
1650   rtx first, last;
1652   if (!TARGET_SH2)
1653     {
1654       /* The address must be set outside the libcall,
1655          since it goes into a pseudo.  */
1656       rtx sym = function_symbol (\"__mulsi3\");
1657       rtx addr = force_reg (SImode, sym);
1658       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1659                                    operands[2], addr);
1660       first = insns;
1661       last = emit_insn (insns);
1662     }
1663   else
1664     {
1665       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1667       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1668       /* consec_sets_giv can only recognize the first insn that sets a
1669          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1670          note.  */
1671       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1672     }
1673   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1674      invariant code motion can move it.  */
1675   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1676   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1677   DONE;
1680 (define_insn "mulsidi3_i"
1681   [(set (reg:SI MACH_REG)
1682         (truncate:SI
1683          (lshiftrt:DI
1684           (mult:DI
1685            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1686            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1687           (const_int 32))))
1688    (set (reg:SI MACL_REG)
1689         (mult:SI (match_dup 0)
1690                  (match_dup 1)))]
1691   "TARGET_SH2"
1692   "dmuls.l      %1,%0"
1693   [(set_attr "type" "dmpy")])
1695 (define_expand "mulsidi3"
1696   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1697         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1698                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1699   "TARGET_SH2 || TARGET_SHMEDIA"
1700   "
1702   if (TARGET_SH2)
1703     {
1704        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1705                                         operands[2]));
1706        DONE;
1707     }
1710 (define_insn "mulsidi3_media"
1711   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1712         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1713                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1714   "TARGET_SHMEDIA"
1715   "muls.l       %1, %2, %0"
1716   [(set_attr "type" "dmpy_media")])
1718 (define_insn "mulsidi3_compact"
1719   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1720         (mult:DI
1721          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1722          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1723    (clobber (reg:SI MACH_REG))
1724    (clobber (reg:SI MACL_REG))]
1725   "TARGET_SH2"
1726   "#")
1728 (define_split
1729   [(set (match_operand:DI 0 "arith_reg_operand" "")
1730         (mult:DI
1731          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1732          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1733    (clobber (reg:SI MACH_REG))
1734    (clobber (reg:SI MACL_REG))]
1735   "TARGET_SH2"
1736   [(const_int 0)]
1737   "
1739   rtx low_dst = gen_lowpart (SImode, operands[0]);
1740   rtx high_dst = gen_highpart (SImode, operands[0]);
1742   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1744   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1745   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1746   /* We need something to tag the possible REG_EQUAL notes on to.  */
1747   emit_move_insn (operands[0], operands[0]);
1748   DONE;
1751 (define_insn "umulsidi3_i"
1752   [(set (reg:SI MACH_REG)
1753         (truncate:SI
1754          (lshiftrt:DI
1755           (mult:DI
1756            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1757            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1758           (const_int 32))))
1759    (set (reg:SI MACL_REG)
1760         (mult:SI (match_dup 0)
1761                  (match_dup 1)))]
1762   "TARGET_SH2"
1763   "dmulu.l      %1,%0"
1764   [(set_attr "type" "dmpy")])
1766 (define_expand "umulsidi3"
1767   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1768         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1769                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1770   "TARGET_SH2 || TARGET_SHMEDIA"
1771   "
1773   if (TARGET_SH2)
1774     {
1775        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1776                                          operands[2]));
1777        DONE;
1778     }
1781 (define_insn "umulsidi3_media"
1782   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1783         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1784                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1785   "TARGET_SHMEDIA"
1786   "mulu.l       %1, %2, %0"
1787   [(set_attr "type" "dmpy_media")])
1789 (define_insn "umulsidi3_compact"
1790   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1791         (mult:DI
1792          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1793          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1794    (clobber (reg:SI MACH_REG))
1795    (clobber (reg:SI MACL_REG))]
1796   "TARGET_SH2"
1797   "#")
1799 (define_split
1800   [(set (match_operand:DI 0 "arith_reg_operand" "")
1801         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1802                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1803    (clobber (reg:SI MACH_REG))
1804    (clobber (reg:SI MACL_REG))]
1805   "TARGET_SH2"
1806   [(const_int 0)]
1807   "
1809   rtx low_dst = gen_lowpart (SImode, operands[0]);
1810   rtx high_dst = gen_highpart (SImode, operands[0]);
1812   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1814   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1815   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1816   /* We need something to tag the possible REG_EQUAL notes on to.  */
1817   emit_move_insn (operands[0], operands[0]);
1818   DONE;
1821 (define_insn "smulsi3_highpart_i"
1822   [(set (reg:SI MACH_REG)
1823         (truncate:SI
1824          (lshiftrt:DI
1825           (mult:DI
1826            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1827            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1828           (const_int 32))))
1829    (clobber (reg:SI MACL_REG))]
1830   "TARGET_SH2"
1831   "dmuls.l      %1,%0"
1832   [(set_attr "type" "dmpy")])
1834 (define_expand "smulsi3_highpart"
1835   [(parallel
1836     [(set (reg:SI MACH_REG)
1837           (truncate:SI
1838            (lshiftrt:DI
1839             (mult:DI
1840              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1841              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1842             (const_int 32))))
1843     (clobber (reg:SI MACL_REG))])
1844    (set (match_operand:SI 0 "arith_reg_operand" "")
1845         (reg:SI MACH_REG))]
1846   "TARGET_SH2"
1847   "
1849   rtx first, last;
1851   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1852   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1853   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1854      invariant code motion can move it.  */
1855   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1856   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1857   /* expand_binop can't find a suitable code in mul_highpart_optab to
1858      make a REG_EQUAL note from, so make one here.
1859      See also {,u}mulhisi.
1860      ??? Alternatively, we could put this at the calling site of expand_binop,
1861      i.e. expand_mult_highpart.  */
1862   REG_NOTES (last)
1863     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1864                          REG_NOTES (last));
1865   DONE;
1868 (define_insn "umulsi3_highpart_i"
1869   [(set (reg:SI MACH_REG)
1870         (truncate:SI
1871          (lshiftrt:DI
1872           (mult:DI
1873            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1874            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1875           (const_int 32))))
1876    (clobber (reg:SI MACL_REG))]
1877   "TARGET_SH2"
1878   "dmulu.l      %1,%0"
1879   [(set_attr "type" "dmpy")])
1881 (define_expand "umulsi3_highpart"
1882   [(parallel
1883     [(set (reg:SI MACH_REG)
1884           (truncate:SI
1885            (lshiftrt:DI
1886             (mult:DI
1887              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1888              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1889             (const_int 32))))
1890     (clobber (reg:SI MACL_REG))])
1891    (set (match_operand:SI 0 "arith_reg_operand" "")
1892         (reg:SI MACH_REG))]
1893   "TARGET_SH2"
1894   "
1896   rtx first, last;
1898   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1899   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1900   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1901      invariant code motion can move it.  */
1902   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1903   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1904   DONE;
1907 ;; -------------------------------------------------------------------------
1908 ;; Logical operations
1909 ;; -------------------------------------------------------------------------
1911 (define_insn "*andsi3_compact"
1912   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1913         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1914                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1915   "TARGET_SH1"
1916   "and  %2,%0"
1917   [(set_attr "type" "arith")])
1919 ;; If the constant is 255, then emit an extu.b instruction instead of an
1920 ;; and, since that will give better code.
1922 (define_expand "andsi3"
1923   [(set (match_operand:SI 0 "arith_reg_operand" "")
1924         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1925                 (match_operand:SI 2 "logical_operand" "")))]
1926   "TARGET_SH1"
1927   "
1929   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1930     {
1931       emit_insn (gen_zero_extendqisi2 (operands[0],
1932                                        gen_lowpart (QImode, operands[1])));
1933       DONE;
1934     }
1937 (define_insn_and_split "anddi3"
1938   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1939         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1940                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1941   "TARGET_SHMEDIA"
1942   "@
1943         and     %1, %2, %0
1944         andi    %1, %2, %0
1945         #"
1946   "reload_completed
1947    && ! logical_operand (operands[2], DImode)"
1948   [(const_int 0)]
1949   "
1951   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1952     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1953   else
1954     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1955   DONE;
1957   [(set_attr "type" "arith_media")])
1959 (define_insn "andcdi3"
1960   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1961         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1962                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1963   "TARGET_SHMEDIA"
1964   "andc %1,%2,%0"
1965   [(set_attr "type" "arith_media")])
1967 (define_insn "iorsi3"
1968   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1969         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1970                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1971   "TARGET_SH1"
1972   "or   %2,%0"
1973   [(set_attr "type" "arith")])
1975 (define_insn "iordi3"
1976   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1977         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1978                 (match_operand:DI 2 "logical_operand" "r,I10")))]
1979   "TARGET_SHMEDIA"
1980   "@
1981         or      %1, %2, %0
1982         ori     %1, %2, %0"
1983   [(set_attr "type" "arith_media")])
1985 (define_insn "xorsi3"
1986   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1987         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1988                 (match_operand:SI 2 "logical_operand" "K08,r")))]
1989   "TARGET_SH1"
1990   "xor  %2,%0"
1991   [(set_attr "type" "arith")])
1993 (define_insn "xordi3"
1994   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1995         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1996                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1997   "TARGET_SHMEDIA"
1998   "@
1999         xor     %1, %2, %0
2000         xori    %1, %2, %0"
2001   [(set_attr "type" "arith_media")])
2003 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2004 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2005 (define_split
2006   [(set (match_operand:DI 0 "arith_reg_operand" "")
2007         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2008                           [(match_operand 1 "any_register_operand" "")
2009                            (match_operand 2 "any_register_operand" "")])))]
2010   "TARGET_SHMEDIA"
2011   [(set (match_dup 5) (match_dup 4))
2012    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2015   enum machine_mode inmode = GET_MODE (operands[1]);
2016   int offset = 0;
2018   if (GET_CODE (operands[0]) == SUBREG)
2019     {
2020       offset = SUBREG_BYTE (operands[0]);
2021       operands[0] = SUBREG_REG (operands[0]);
2022     }
2023   if (GET_CODE (operands[0]) != REG)
2024     abort ();
2025   if (! TARGET_LITTLE_ENDIAN)
2026     offset += 8 - GET_MODE_SIZE (inmode);
2027   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2030 ;; -------------------------------------------------------------------------
2031 ;; Shifts and rotates
2032 ;; -------------------------------------------------------------------------
2034 (define_expand "rotldi3"
2035   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2036         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2037                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2038   "TARGET_SHMEDIA"
2039   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2041 (define_insn "rotldi3_mextr"
2042   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2043         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2044                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2045   "TARGET_SHMEDIA"
2046   "*
2048   static char templ[16];
2050   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2051            8 - (int) (INTVAL (operands[2]) >> 3));
2052   return templ;
2054   [(set_attr "type" "arith_media")])
2056 (define_expand "rotrdi3"
2057   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2058         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2059                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2060   "TARGET_SHMEDIA"
2061   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2063 (define_insn "rotrdi3_mextr"
2064   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2065         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2066                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2067   "TARGET_SHMEDIA"
2068   "*
2070   static char templ[16];
2072   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2073   return templ;
2075   [(set_attr "type" "arith_media")])
2077 (define_insn "rotlsi3_1"
2078   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2079         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2080                    (const_int 1)))
2081    (set (reg:SI T_REG)
2082         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2083   "TARGET_SH1"
2084   "rotl %0"
2085   [(set_attr "type" "arith")])
2087 (define_insn "rotlsi3_31"
2088   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2089         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2090                    (const_int 31)))
2091    (clobber (reg:SI T_REG))]
2092   "TARGET_SH1"
2093   "rotr %0"
2094   [(set_attr "type" "arith")])
2096 (define_insn "rotlsi3_16"
2097   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2098         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2099                    (const_int 16)))]
2100   "TARGET_SH1"
2101   "swap.w       %1,%0"
2102   [(set_attr "type" "arith")])
2104 (define_expand "rotlsi3"
2105   [(set (match_operand:SI 0 "arith_reg_operand" "")
2106         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2107                    (match_operand:SI 2 "immediate_operand" "")))]
2108   "TARGET_SH1"
2109   "
2111   static const char rot_tab[] = {
2112     000, 000, 000, 000, 000, 000, 010, 001,
2113     001, 001, 011, 013, 003, 003, 003, 003,
2114     003, 003, 003, 003, 003, 013, 012, 002,
2115     002, 002, 010, 000, 000, 000, 000, 000,
2116   };
2118   int count, choice;
2120   if (GET_CODE (operands[2]) != CONST_INT)
2121     FAIL;
2122   count = INTVAL (operands[2]);
2123   choice = rot_tab[count];
2124   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2125     FAIL;
2126   choice &= 7;
2127   switch (choice)
2128     {
2129     case 0:
2130       emit_move_insn (operands[0], operands[1]);
2131       count -= (count & 16) * 2;
2132       break;
2133     case 3:
2134      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2135      count -= 16;
2136      break;
2137     case 1:
2138     case 2:
2139       {
2140         rtx parts[2];
2141         parts[0] = gen_reg_rtx (SImode);
2142         parts[1] = gen_reg_rtx (SImode);
2143         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2144         emit_move_insn (parts[choice-1], operands[1]);
2145         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2146         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2147         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2148         count = (count & ~16) - 8;
2149       }
2150     }
2152   for (; count > 0; count--)
2153     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2154   for (; count < 0; count++)
2155     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2157   DONE;
2160 (define_insn "*rotlhi3_8"
2161   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2162         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2163                    (const_int 8)))]
2164   "TARGET_SH1"
2165   "swap.b       %1,%0"
2166   [(set_attr "type" "arith")])
2168 (define_expand "rotlhi3"
2169   [(set (match_operand:HI 0 "arith_reg_operand" "")
2170         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2171                    (match_operand:HI 2 "immediate_operand" "")))]
2172   "TARGET_SH1"
2173   "
2175   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2176     FAIL;
2180 ;; shift left
2182 (define_insn "ashlsi3_sh2a"
2183   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2184         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2185                    (match_operand:SI 2 "arith_reg_operand" "r")))]
2186   "TARGET_SH2A"
2187   "shad %2,%0"
2188   [(set_attr "type" "arith")
2189    (set_attr "length" "4")])
2191 ;; This pattern is used by init_expmed for computing the costs of shift
2192 ;; insns.
2194 (define_insn_and_split "ashlsi3_std"
2195   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2196         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2197                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2198    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2199   "TARGET_SH3
2200    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2201        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2202   "@
2203    shld %2,%0
2204    add  %0,%0
2205    shll%O2      %0
2206    #"
2207   "TARGET_SH3
2208    && reload_completed
2209    && GET_CODE (operands[2]) == CONST_INT
2210    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2211   [(set (match_dup 3) (match_dup 2))
2212    (parallel
2213     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2214      (clobber (match_dup 4))])]
2215   "operands[4] = gen_rtx_SCRATCH (SImode);"
2216   [(set_attr "length" "*,*,*,4")
2217    (set_attr "type" "dyn_shift,arith,arith,arith")])
2219 (define_insn "ashlhi3_k"
2220   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2221         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2222                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2223   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2224   "@
2225         add     %0,%0
2226         shll%O2 %0"
2227   [(set_attr "type" "arith")])
2229 (define_insn "ashlsi3_n"
2230   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2231         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2232                    (match_operand:SI 2 "const_int_operand" "n")))
2233    (clobber (reg:SI T_REG))]
2234   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2235   "#"
2236   [(set (attr "length")
2237         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2238                (const_string "2")
2239                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2240                (const_string "4")
2241                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2242                (const_string "6")]
2243               (const_string "8")))
2244    (set_attr "type" "arith")])
2246 (define_split
2247   [(set (match_operand:SI 0 "arith_reg_operand" "")
2248         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2249                    (match_operand:SI 2 "const_int_operand" "")))
2250    (clobber (reg:SI T_REG))]
2251   "TARGET_SH1 && reload_completed"
2252   [(use (reg:SI R0_REG))]
2253   "
2255   gen_shifty_op (ASHIFT, operands);
2256   DONE;
2259 (define_insn "ashlsi3_media"
2260   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2261         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2262                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2263   "TARGET_SHMEDIA"
2264   "@
2265         shlld.l %1, %2, %0
2266         shlli.l %1, %2, %0"
2267   [(set_attr "type" "arith_media")])
2269 (define_expand "ashlsi3"
2270   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2271                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2272                               (match_operand:SI 2 "nonmemory_operand" "")))
2273               (clobber (reg:SI T_REG))])]
2274   ""
2275   "
2277   if (TARGET_SHMEDIA)
2278     {
2279       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2280       DONE;
2281     }
2282   if (GET_CODE (operands[2]) == CONST_INT
2283       && sh_dynamicalize_shift_p (operands[2]))
2284     operands[2] = force_reg (SImode, operands[2]);
2285   if (TARGET_SH3)
2286     {
2287       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2288       DONE;
2289     }
2290   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2291     FAIL;
2294 (define_insn "ashlhi3"
2295   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2296         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2297                    (match_operand:HI 2 "const_int_operand" "n")))
2298    (clobber (reg:SI T_REG))]
2299   "TARGET_SH1"
2300   "#"
2301   [(set (attr "length")
2302         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2303                (const_string "2")
2304                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2305                (const_string "4")]
2306               (const_string "6")))
2307    (set_attr "type" "arith")])
2309 (define_split
2310   [(set (match_operand:HI 0 "arith_reg_operand" "")
2311         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2312                    (match_operand:HI 2 "const_int_operand" "")))
2313    (clobber (reg:SI T_REG))]
2314   "TARGET_SH1 && reload_completed"
2315   [(use (reg:SI R0_REG))]
2316   "
2318   gen_shifty_hi_op (ASHIFT, operands);
2319   DONE;
2323 ; arithmetic shift right
2326 (define_insn "ashrsi3_sh2a"
2327   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2328         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2329                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2330   "TARGET_SH2A"
2331   "shad %2,%0"
2332   [(set_attr "type" "dyn_shift")
2333    (set_attr "length" "4")])
2335 (define_insn "ashrsi3_k"
2336   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2337         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2338                      (match_operand:SI 2 "const_int_operand" "M")))
2339    (clobber (reg:SI T_REG))]
2340   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2341   "shar %0"
2342   [(set_attr "type" "arith")])
2344 ;; We can't do HImode right shifts correctly unless we start out with an
2345 ;; explicit zero / sign extension; doing that would result in worse overall
2346 ;; code, so just let the machine independent code widen the mode.
2347 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2350 ;; ??? This should be a define expand.
2352 (define_insn "ashrsi2_16"
2353   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2354         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2355                      (const_int 16)))]
2356   "TARGET_SH1"
2357   "#"
2358   [(set_attr "length" "4")])
2360 (define_split
2361   [(set (match_operand:SI 0 "arith_reg_operand" "")
2362         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2363                      (const_int 16)))]
2364   "TARGET_SH1"
2365   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2366    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2367   "operands[2] = gen_lowpart (HImode, operands[0]);")
2369 ;; ??? This should be a define expand.
2371 (define_insn "ashrsi2_31"
2372   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2373         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2374                      (const_int 31)))
2375    (clobber (reg:SI T_REG))]
2376   "TARGET_SH1"
2377   "#"
2378   [(set_attr "length" "4")])
2380 (define_split
2381   [(set (match_operand:SI 0 "arith_reg_operand" "")
2382         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2383                      (const_int 31)))
2384    (clobber (reg:SI T_REG))]
2385   "TARGET_SH1"
2386   [(const_int 0)]
2387   "
2389   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2390   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2391   DONE;
2394 (define_insn "ashlsi_c"
2395   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2396         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2397    (set (reg:SI T_REG)
2398         (lt:SI (match_dup 1) (const_int 0)))]
2399   "TARGET_SH1"
2400   "shll %0"
2401   [(set_attr "type" "arith")])
2403 (define_insn "ashrsi3_d"
2404   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2405         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2406                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2407   "TARGET_SH3"
2408   "shad %2,%0"
2409   [(set_attr "type" "dyn_shift")])
2411 (define_insn "ashrsi3_n"
2412   [(set (reg:SI R4_REG)
2413         (ashiftrt:SI (reg:SI R4_REG)
2414                      (match_operand:SI 0 "const_int_operand" "i")))
2415    (clobber (reg:SI T_REG))
2416    (clobber (reg:SI PR_REG))
2417    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2418   "TARGET_SH1"
2419   "jsr  @%1%#"
2420   [(set_attr "type" "sfunc")
2421    (set_attr "needs_delay_slot" "yes")])
2423 (define_insn "ashrsi3_media"
2424   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2425         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2426                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2427   "TARGET_SHMEDIA"
2428   "@
2429         shard.l %1, %2, %0
2430         shari.l %1, %2, %0"
2431   [(set_attr "type" "arith_media")])
2433 (define_expand "ashrsi3"
2434   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2435                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2436                                 (match_operand:SI 2 "nonmemory_operand" "")))
2437               (clobber (reg:SI T_REG))])]
2438   ""
2439   "
2441   if (TARGET_SHMEDIA)
2442     {
2443       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2444       DONE;
2445     }
2446   if (expand_ashiftrt (operands))
2447     DONE;
2448   else
2449     FAIL;
2452 ;; logical shift right
2454 (define_insn "lshrsi3_sh2a"
2455   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2456         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2457                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2458   "TARGET_SH2A"
2459   "shld %2,%0"
2460   [(set_attr "type" "dyn_shift")
2461    (set_attr "length" "4")])
2463 (define_insn "lshrsi3_d"
2464   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2465         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2466                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2467   "TARGET_SH3"
2468   "shld %2,%0"
2469   [(set_attr "type" "dyn_shift")])
2471 ;;  Only the single bit shift clobbers the T bit.
2473 (define_insn "lshrsi3_m"
2474   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2475         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2476                      (match_operand:SI 2 "const_int_operand" "M")))
2477    (clobber (reg:SI T_REG))]
2478   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2479   "shlr %0"
2480   [(set_attr "type" "arith")])
2482 (define_insn "lshrsi3_k"
2483   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2484         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2485                      (match_operand:SI 2 "const_int_operand" "P27")))]
2486   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2487    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2488   "shlr%O2      %0"
2489   [(set_attr "type" "arith")])
2491 (define_insn "lshrsi3_n"
2492   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2493         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2494                      (match_operand:SI 2 "const_int_operand" "n")))
2495    (clobber (reg:SI T_REG))]
2496   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2497   "#"
2498   [(set (attr "length")
2499         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2500                (const_string "2")
2501                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2502                (const_string "4")
2503                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2504                (const_string "6")]
2505               (const_string "8")))
2506    (set_attr "type" "arith")])
2508 (define_split
2509   [(set (match_operand:SI 0 "arith_reg_operand" "")
2510         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2511                      (match_operand:SI 2 "const_int_operand" "")))
2512    (clobber (reg:SI T_REG))]
2513   "TARGET_SH1 && reload_completed"
2514   [(use (reg:SI R0_REG))]
2515   "
2517   gen_shifty_op (LSHIFTRT, operands);
2518   DONE;
2521 (define_insn "lshrsi3_media"
2522   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2523         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2524                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2525   "TARGET_SHMEDIA"
2526   "@
2527         shlrd.l %1, %2, %0
2528         shlri.l %1, %2, %0"
2529   [(set_attr "type" "arith_media")])
2531 (define_expand "lshrsi3"
2532   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2533                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2534                                 (match_operand:SI 2 "nonmemory_operand" "")))
2535               (clobber (reg:SI T_REG))])]
2536   ""
2537   "
2539   if (TARGET_SHMEDIA)
2540     {
2541       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2542       DONE;
2543     }
2544   if (GET_CODE (operands[2]) == CONST_INT
2545       && sh_dynamicalize_shift_p (operands[2]))
2546     operands[2] = force_reg (SImode, operands[2]);
2547   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2548     {
2549       rtx count = copy_to_mode_reg (SImode, operands[2]);
2550       emit_insn (gen_negsi2 (count, count));
2551       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2552       DONE;
2553     }
2554   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2555     FAIL;
2558 ;; ??? This should be a define expand.
2560 (define_insn "ashldi3_k"
2561   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2562         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2563                    (const_int 1)))
2564    (clobber (reg:SI T_REG))]
2565   "TARGET_SH1"
2566   "shll %R0\;rotcl      %S0"
2567   [(set_attr "length" "4")
2568    (set_attr "type" "arith")])
2570 (define_insn "ashldi3_media"
2571   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2572         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2573                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2574   "TARGET_SHMEDIA"
2575   "@
2576         shlld   %1, %2, %0
2577         shlli   %1, %2, %0"
2578   [(set_attr "type" "arith_media")])
2580 (define_expand "ashldi3"
2581   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2582                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2583                               (match_operand:DI 2 "immediate_operand" "")))
2584               (clobber (reg:SI T_REG))])]
2585   ""
2586   "
2588   if (TARGET_SHMEDIA)
2589     {
2590       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2591       DONE;
2592     }
2593   if (GET_CODE (operands[2]) != CONST_INT
2594       || INTVAL (operands[2]) != 1)
2595     FAIL;
2598 ;; ??? This should be a define expand.
2600 (define_insn "lshrdi3_k"
2601   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2602         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2603                      (const_int 1)))
2604    (clobber (reg:SI T_REG))]
2605   "TARGET_SH1"
2606   "shlr %S0\;rotcr      %R0"
2607   [(set_attr "length" "4")
2608    (set_attr "type" "arith")])
2610 (define_insn "lshrdi3_media"
2611   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2612         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2613                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2614   "TARGET_SHMEDIA"
2615   "@
2616         shlrd   %1, %2, %0
2617         shlri   %1, %2, %0"
2618   [(set_attr "type" "arith_media")])
2620 (define_expand "lshrdi3"
2621   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2622                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2623                                (match_operand:DI 2 "immediate_operand" "")))
2624              (clobber (reg:SI T_REG))])]
2625   ""
2626   "
2628   if (TARGET_SHMEDIA)
2629     {
2630       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2631       DONE;
2632     }
2633   if (GET_CODE (operands[2]) != CONST_INT
2634       || INTVAL (operands[2]) != 1)
2635     FAIL;
2638 ;; ??? This should be a define expand.
2640 (define_insn "ashrdi3_k"
2641   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2642         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2643                      (const_int 1)))
2644    (clobber (reg:SI T_REG))]
2645   "TARGET_SH1"
2646   "shar %S0\;rotcr      %R0"
2647   [(set_attr "length" "4")
2648    (set_attr "type" "arith")])
2650 (define_insn "ashrdi3_media"
2651   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2652         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2653                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2654   "TARGET_SHMEDIA"
2655   "@
2656         shard   %1, %2, %0
2657         shari   %1, %2, %0"
2658   [(set_attr "type" "arith_media")])
2660 (define_expand "ashrdi3"
2661   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2662                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2663                                 (match_operand:DI 2 "immediate_operand" "")))
2664               (clobber (reg:SI T_REG))])]
2665   ""
2666   "
2668   if (TARGET_SHMEDIA)
2669     {
2670       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2671       DONE;
2672     }
2673   if (GET_CODE (operands[2]) != CONST_INT
2674       || INTVAL (operands[2]) != 1)
2675     FAIL;
2678 ;; combined left/right shift
2680 (define_split
2681   [(set (match_operand:SI 0 "register_operand" "")
2682         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2683                            (match_operand:SI 2 "const_int_operand" ""))
2684                 (match_operand:SI 3 "const_int_operand" "")))]
2685   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2686   [(use (reg:SI R0_REG))]
2687   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2688    DONE;")
2690 (define_split
2691   [(set (match_operand:SI 0 "register_operand" "")
2692         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2693                            (match_operand:SI 2 "const_int_operand" ""))
2694                 (match_operand:SI 3 "const_int_operand" "")))
2695    (clobber (reg:SI T_REG))]
2696   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2697   [(use (reg:SI R0_REG))]
2698   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2699    DONE;")
2701 (define_insn ""
2702   [(set (match_operand:SI 0 "register_operand" "=r")
2703         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2704                            (match_operand:SI 2 "const_int_operand" "n"))
2705                 (match_operand:SI 3 "const_int_operand" "n")))
2706    (clobber (reg:SI T_REG))]
2707   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2708  "#"
2709   [(set (attr "length")
2710         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2711                (const_string "4")
2712                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2713                (const_string "6")
2714                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2715                (const_string "8")
2716                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2717                (const_string "10")
2718                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2719                (const_string "12")
2720                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2721                (const_string "14")
2722                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2723                (const_string "16")]
2724               (const_string "18")))
2725    (set_attr "type" "arith")])
2727 (define_insn ""
2728   [(set (match_operand:SI 0 "register_operand" "=z")
2729         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2730                            (match_operand:SI 2 "const_int_operand" "n"))
2731                 (match_operand:SI 3 "const_int_operand" "n")))
2732    (clobber (reg:SI T_REG))]
2733   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2734  "#"
2735   [(set (attr "length")
2736         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2737                (const_string "4")
2738                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2739                (const_string "6")
2740                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2741                (const_string "8")]
2742               (const_string "10")))
2743    (set_attr "type" "arith")])
2745 ;; shift left / and combination with a scratch register: The combine pass
2746 ;; does not accept the individual instructions, even though they are
2747 ;; cheap.  But it needs a precise description so that it is usable after
2748 ;; reload.
2749 (define_insn "and_shl_scratch"
2750   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2751         (lshiftrt:SI
2752          (ashift:SI
2753           (and:SI
2754            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2755                         (match_operand:SI 2 "const_int_operand" "N,n"))
2756            (match_operand:SI 3 "" "0,r"))
2757           (match_operand:SI 4 "const_int_operand" "n,n"))
2758          (match_operand:SI 5 "const_int_operand" "n,n")))
2759    (clobber (reg:SI T_REG))]
2760   "TARGET_SH1"
2761   "#"
2762   [(set (attr "length")
2763         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2764                (const_string "4")
2765                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2766                (const_string "6")
2767                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2768                (const_string "8")
2769                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2770                (const_string "10")]
2771               (const_string "12")))
2772    (set_attr "type" "arith")])
2774 (define_split
2775   [(set (match_operand:SI 0 "register_operand" "")
2776         (lshiftrt:SI
2777          (ashift:SI
2778           (and:SI
2779            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2780                         (match_operand:SI 2 "const_int_operand" ""))
2781            (match_operand:SI 3 "register_operand" ""))
2782           (match_operand:SI 4 "const_int_operand" ""))
2783          (match_operand:SI 5 "const_int_operand" "")))
2784    (clobber (reg:SI T_REG))]
2785   "TARGET_SH1"
2786   [(use (reg:SI R0_REG))]
2787   "
2789   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2791   if (INTVAL (operands[2]))
2792     {
2793       gen_shifty_op (LSHIFTRT, operands);
2794     }
2795   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2796   operands[2] = operands[4];
2797   gen_shifty_op (ASHIFT, operands);
2798   if (INTVAL (operands[5]))
2799     {
2800       operands[2] = operands[5];
2801       gen_shifty_op (LSHIFTRT, operands);
2802     }
2803   DONE;
2806 ;; signed left/right shift combination.
2807 (define_split
2808   [(set (match_operand:SI 0 "register_operand" "")
2809         (sign_extract:SI
2810          (ashift:SI (match_operand:SI 1 "register_operand" "")
2811                     (match_operand:SI 2 "const_int_operand" ""))
2812          (match_operand:SI 3 "const_int_operand" "")
2813          (const_int 0)))
2814    (clobber (reg:SI T_REG))]
2815   "TARGET_SH1"
2816   [(use (reg:SI R0_REG))]
2817   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2818    DONE;")
2820 (define_insn "shl_sext_ext"
2821   [(set (match_operand:SI 0 "register_operand" "=r")
2822         (sign_extract:SI
2823          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2824                     (match_operand:SI 2 "const_int_operand" "n"))
2825          (match_operand:SI 3 "const_int_operand" "n")
2826          (const_int 0)))
2827    (clobber (reg:SI T_REG))]
2828   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2829   "#"
2830   [(set (attr "length")
2831         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2832                (const_string "2")
2833                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2834                (const_string "4")
2835                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2836                (const_string "6")
2837                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2838                (const_string "8")
2839                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2840                (const_string "10")
2841                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2842                (const_string "12")
2843                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2844                (const_string "14")
2845                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2846                (const_string "16")]
2847               (const_string "18")))
2848     (set_attr "type" "arith")])
2850 (define_insn "shl_sext_sub"
2851   [(set (match_operand:SI 0 "register_operand" "=z")
2852         (sign_extract:SI
2853          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2854                     (match_operand:SI 2 "const_int_operand" "n"))
2855          (match_operand:SI 3 "const_int_operand" "n")
2856          (const_int 0)))
2857    (clobber (reg:SI T_REG))]
2858   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2859   "#"
2860   [(set (attr "length")
2861         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2862                (const_string "6")
2863                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2864                (const_string "8")
2865                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2866                (const_string "10")
2867                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2868                (const_string "12")]
2869               (const_string "14")))
2870     (set_attr "type" "arith")])
2872 ;; These patterns are found in expansions of DImode shifts by 16, and
2873 ;; allow the xtrct instruction to be generated from C source.
2875 (define_insn "xtrct_left"
2876   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2877         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2878                            (const_int 16))
2879                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2880                              (const_int 16))))]
2881   "TARGET_SH1"
2882   "xtrct        %1,%0"
2883   [(set_attr "type" "arith")])
2885 (define_insn "xtrct_right"
2886   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2887         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2888                              (const_int 16))
2889                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2890                            (const_int 16))))]
2891   "TARGET_SH1"
2892   "xtrct        %2,%0"
2893   [(set_attr "type" "arith")])
2895 ;; -------------------------------------------------------------------------
2896 ;; Unary arithmetic
2897 ;; -------------------------------------------------------------------------
2899 (define_insn "negc"
2900   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2901         (neg:SI (plus:SI (reg:SI T_REG)
2902                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2903    (set (reg:SI T_REG)
2904         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2905                (const_int 0)))]
2906   "TARGET_SH1"
2907   "negc %1,%0"
2908   [(set_attr "type" "arith")])
2910 (define_insn "*negdi_media"
2911   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2912         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2913   "TARGET_SHMEDIA"
2914   "sub  r63, %1, %0"
2915   [(set_attr "type" "arith_media")])
2917 (define_expand "negdi2"
2918   [(set (match_operand:DI 0 "arith_reg_operand" "")
2919         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2920   ""
2921   "
2923   if (TARGET_SH1)
2924     {
2925       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2926       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2928       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2929       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2931       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2932       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2934       emit_insn (gen_clrt ());
2935       emit_insn (gen_negc (low_dst, low_src));
2936       emit_insn (gen_negc (high_dst, high_src));
2937       DONE;
2938     }
2941 (define_insn "negsi2"
2942   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2943         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2944   "TARGET_SH1"
2945   "neg  %1,%0"
2946   [(set_attr "type" "arith")])
2948 (define_insn "one_cmplsi2"
2949   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2950         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2951   "TARGET_SH1"
2952   "not  %1,%0"
2953   [(set_attr "type" "arith")])
2955 (define_expand "one_cmpldi2"
2956   [(set (match_operand:DI 0 "arith_reg_operand" "")
2957         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2958                 (const_int -1)))]
2959   "TARGET_SHMEDIA" "")
2961 ;; -------------------------------------------------------------------------
2962 ;; Zero extension instructions
2963 ;; -------------------------------------------------------------------------
2965 (define_insn "zero_extendsidi2"
2966   [(set (match_operand:DI 0 "register_operand" "=r")
2967         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2968   "TARGET_SHMEDIA"
2969   "addz.l       %1, r63, %0"
2970   [(set_attr "type" "arith_media")])
2972 (define_insn "zero_extendhidi2"
2973   [(set (match_operand:DI 0 "register_operand" "=r,r")
2974         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2975   "TARGET_SHMEDIA"
2976   "@
2977         #
2978         ld%M1.uw        %m1, %0"
2979   [(set_attr "type" "*,load_media")])
2981 (define_split
2982   [(set (match_operand:DI 0 "register_operand" "")
2983         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2984   "TARGET_SHMEDIA && reload_completed"
2985   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2986    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2987   "
2989   if (GET_CODE (operands[1]) == TRUNCATE)
2990     operands[1] = XEXP (operands[1], 0);
2993 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2994 ;; reload the entire truncate expression.
2995 (define_insn_and_split "*loaddi_trunc"
2996   [(set (match_operand 0 "int_gpr_dest" "=r")
2997         (truncate (match_operand:DI 1 "memory_operand" "m")))]
2998   "TARGET_SHMEDIA && reload_completed"
2999   "#"
3000   "TARGET_SHMEDIA && reload_completed"
3001   [(set (match_dup 0) (match_dup 1))]
3002   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3004 (define_insn "zero_extendqidi2"
3005   [(set (match_operand:DI 0 "register_operand" "=r,r")
3006         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3007   "TARGET_SHMEDIA"
3008   "@
3009         andi    %1, 255, %0
3010         ld%M1.ub        %m1, %0"
3011   [(set_attr "type" "arith_media,load_media")])
3013 (define_expand "zero_extendhisi2"
3014   [(set (match_operand:SI 0 "arith_reg_operand" "")
3015         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3016   ""
3017   "
3019   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3020     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3023 (define_insn "*zero_extendhisi2_compact"
3024   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3025         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3026   "TARGET_SH1"
3027   "extu.w       %1,%0"
3028   [(set_attr "type" "arith")])
3030 (define_insn "*zero_extendhisi2_media"
3031   [(set (match_operand:SI 0 "register_operand" "=r,r")
3032         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3033   "TARGET_SHMEDIA"
3034   "@
3035         #
3036         ld%M1.uw        %m1, %0"
3037   [(set_attr "type" "arith_media,load_media")])
3039 (define_split
3040   [(set (match_operand:SI 0 "register_operand" "")
3041         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3042   "TARGET_SHMEDIA && reload_completed"
3043   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3044    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3045   "
3047   if (GET_CODE (operands[1]) == TRUNCATE)
3048     operands[1] = XEXP (operands[1], 0);
3051 (define_expand "zero_extendqisi2"
3052   [(set (match_operand:SI 0 "arith_reg_operand" "")
3053         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3054   ""
3055   "
3057   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3058     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3061 (define_insn "*zero_extendqisi2_compact"
3062   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3063         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3064   "TARGET_SH1"
3065   "extu.b       %1,%0"
3066   [(set_attr "type" "arith")])
3068 (define_insn "*zero_extendqisi2_media"
3069   [(set (match_operand:SI 0 "register_operand" "=r,r")
3070         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3071   "TARGET_SHMEDIA"
3072   "@
3073         andi    %1, 255, %0
3074         ld%M1.ub        %m1, %0"
3075   [(set_attr "type" "arith_media,load_media")])
3077 (define_insn "zero_extendqihi2"
3078   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3079         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3080   "TARGET_SH1"
3081   "extu.b       %1,%0"
3082   [(set_attr "type" "arith")])
3084 ;; -------------------------------------------------------------------------
3085 ;; Sign extension instructions
3086 ;; -------------------------------------------------------------------------
3088 ;; ??? This should be a define expand.
3089 ;; ??? Or perhaps it should be dropped?
3091 ;; convert_move generates good code for SH[1-4].
3092 (define_insn "extendsidi2"
3093   [(set (match_operand:DI 0 "register_operand" "=r,r")
3094         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3095   "TARGET_SHMEDIA"
3096   "@
3097         add.l   %1, r63, %0
3098         ld%M1.l %m1, %0"
3099   [(set_attr "type" "arith_media,load_media")])
3101 (define_insn "extendhidi2"
3102   [(set (match_operand:DI 0 "register_operand" "=r,r")
3103         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3104   "TARGET_SHMEDIA"
3105   "@
3106         #
3107         ld%M1.w %m1, %0"
3108   [(set_attr "type" "*,load_media")])
3110 (define_split
3111   [(set (match_operand:DI 0 "register_operand" "")
3112         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3113   "TARGET_SHMEDIA && reload_completed"
3114   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3115    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3116   "
3118   if (GET_CODE (operands[1]) == TRUNCATE)
3119     operands[1] = XEXP (operands[1], 0);
3122 (define_insn "extendqidi2"
3123   [(set (match_operand:DI 0 "register_operand" "=r,r")
3124         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3125   "TARGET_SHMEDIA"
3126   "@
3127         #
3128         ld%M1.b %m1, %0"
3129   [(set_attr "type" "*,load_media")])
3131 (define_split
3132   [(set (match_operand:DI 0 "register_operand" "")
3133         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3134   "TARGET_SHMEDIA && reload_completed"
3135   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3136    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3137   "
3139   if (GET_CODE (operands[1]) == TRUNCATE)
3140     operands[1] = XEXP (operands[1], 0);
3143 (define_expand "extendhisi2"
3144   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3145         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3146   ""
3147   "")
3149 (define_insn "*extendhisi2_compact"
3150   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3151         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3152   "TARGET_SH1"
3153   "@
3154         exts.w  %1,%0
3155         mov.w   %1,%0"
3156   [(set_attr "type" "arith,load")])
3158 (define_insn "*extendhisi2_media"
3159   [(set (match_operand:SI 0 "register_operand" "=r,r")
3160         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3161   "TARGET_SHMEDIA"
3162   "@
3163         #
3164         ld%M1.w %m1, %0"
3165   [(set_attr "type" "arith_media,load_media")])
3167 (define_split
3168   [(set (match_operand:SI 0 "register_operand" "")
3169         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3170   "TARGET_SHMEDIA && reload_completed"
3171   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3172    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3173   "
3175   if (GET_CODE (operands[1]) == TRUNCATE)
3176     operands[1] = XEXP (operands[1], 0);
3179 (define_expand "extendqisi2"
3180   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3181         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3182   ""
3183   "")
3185 (define_insn "*extendqisi2_compact"
3186   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3187         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3188   "TARGET_SH1"
3189   "@
3190         exts.b  %1,%0
3191         mov.b   %1,%0"
3192   [(set_attr "type" "arith,load")])
3194 (define_insn "*extendqisi2_media"
3195   [(set (match_operand:SI 0 "register_operand" "=r,r")
3196         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3197   "TARGET_SHMEDIA"
3198   "@
3199         #
3200         ld%M1.b %m1, %0"
3201   [(set_attr "type" "arith_media,load_media")])
3203 (define_split
3204   [(set (match_operand:SI 0 "register_operand" "")
3205         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3206   "TARGET_SHMEDIA && reload_completed"
3207   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3208    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3209    "
3211   if (GET_CODE (operands[1]) == TRUNCATE)
3212     operands[1] = XEXP (operands[1], 0);
3215 (define_insn "extendqihi2"
3216   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3217         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3218   "TARGET_SH1"
3219   "@
3220         exts.b  %1,%0
3221         mov.b   %1,%0"
3222   [(set_attr "type" "arith,load")])
3224 /* It would seem useful to combine the truncXi patterns into the movXi
3225    patterns, but unary operators are ignored when matching constraints,
3226    so we need separate patterns.  */
3227 (define_insn "truncdisi2"
3228   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3229         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3230   "TARGET_SHMEDIA"
3231   "@
3232         add.l   %1, r63, %0
3233         st%M0.l %m0, %1
3234         fst%M0.s        %m0, %T1
3235         fmov.ls %1, %0
3236         fmov.sl %T1, %0
3237         fmov.s  %T1, %0"
3238   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3241 (define_insn "truncdihi2"
3242   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3243         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3244   "TARGET_SHMEDIA"
3245   "@
3246         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3247         st%M0.w %m0, %1"
3248   [(set_attr "type"   "arith_media,store_media")
3249    (set_attr "length" "8,4")])
3251 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3252 ; Because we use zero extension, we can't provide signed QImode compares
3253 ; using a simple compare or conditional banch insn.
3254 (define_insn "truncdiqi2"
3255   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3256         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3257   "TARGET_SHMEDIA"
3258   "@
3259         andi    %1, 255, %0
3260         st%M0.b %m0, %1"
3261   [(set_attr "type"   "arith_media,store")])
3263 ;; -------------------------------------------------------------------------
3264 ;; Move instructions
3265 ;; -------------------------------------------------------------------------
3267 ;; define push and pop so it is easy for sh.c
3268 ;; We can't use push and pop on SHcompact because the stack must always
3269 ;; be 8-byte aligned.
3271 (define_expand "push"
3272   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3273         (match_operand:SI 0 "register_operand" "r,l,x"))]
3274   "TARGET_SH1 && ! TARGET_SH5"
3275   "")
3277 (define_expand "pop"
3278   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3279         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3280   "TARGET_SH1 && ! TARGET_SH5"
3281   "")
3283 (define_expand "push_e"
3284   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3285                    (match_operand:SF 0 "" ""))
3286               (use (reg:PSI FPSCR_REG))
3287               (clobber (scratch:SI))])]
3288   "TARGET_SH1 && ! TARGET_SH5"
3289   "")
3291 (define_insn "push_fpul"
3292   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3293   "TARGET_SH2E && ! TARGET_SH5"
3294   "sts.l        fpul,@-r15"
3295   [(set_attr "type" "store")
3296    (set_attr "late_fp_use" "yes")
3297    (set_attr "hit_stack" "yes")])
3299 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3300 ;; so use that.
3301 (define_expand "push_4"
3302   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3303                    (match_operand:DF 0 "" ""))
3304               (use (reg:PSI FPSCR_REG))
3305               (clobber (scratch:SI))])]
3306   "TARGET_SH1 && ! TARGET_SH5"
3307   "")
3309 (define_expand "pop_e"
3310   [(parallel [(set (match_operand:SF 0 "" "")
3311               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3312               (use (reg:PSI FPSCR_REG))
3313               (clobber (scratch:SI))])]
3314   "TARGET_SH1 && ! TARGET_SH5"
3315   "")
3317 (define_insn "pop_fpul"
3318   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3319   "TARGET_SH2E && ! TARGET_SH5"
3320   "lds.l        @r15+,fpul"
3321   [(set_attr "type" "load")
3322    (set_attr "hit_stack" "yes")])
3324 (define_expand "pop_4"
3325   [(parallel [(set (match_operand:DF 0 "" "")
3326                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3327               (use (reg:PSI FPSCR_REG))
3328               (clobber (scratch:SI))])]
3329   "TARGET_SH1 && ! TARGET_SH5"
3330   "")
3332 (define_expand "push_fpscr"
3333   [(const_int 0)]
3334   "TARGET_SH2E"
3335   "
3337   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3338                                                  gen_rtx_PRE_DEC (Pmode,
3339                                                           stack_pointer_rtx)),
3340                                         get_fpscr_rtx ()));
3341   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3342   DONE;
3345 (define_expand "pop_fpscr"
3346   [(const_int 0)]
3347   "TARGET_SH2E"
3348   "
3350   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3351                                         gen_rtx_MEM (PSImode,
3352                                                  gen_rtx_POST_INC (Pmode,
3353                                                           stack_pointer_rtx))));
3354   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3355   DONE;
3358 ;; These two patterns can happen as the result of optimization, when
3359 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3360 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3362 (define_insn "clrt"
3363   [(set (reg:SI T_REG) (const_int 0))]
3364   "TARGET_SH1"
3365   "clrt")
3367 (define_insn "sett"
3368   [(set (reg:SI T_REG) (const_int 1))]
3369   "TARGET_SH1"
3370   "sett")
3372 ;; t/r must come after r/r, lest reload will try to reload stuff like
3373 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3374 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3375 (define_insn "movsi_i"
3376   [(set (match_operand:SI 0 "general_movdst_operand"
3377             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3378         (match_operand:SI 1 "general_movsrc_operand"
3379          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3380   "TARGET_SH1
3381    && ! TARGET_SH2E
3382    && ! TARGET_SH2A
3383    && (register_operand (operands[0], SImode)
3384        || register_operand (operands[1], SImode))"
3385   "@
3386         mov.l   %1,%0
3387         mov     %1,%0
3388         cmp/pl  %1
3389         mov.l   %1,%0
3390         sts     %1,%0
3391         sts     %1,%0
3392         movt    %0
3393         mov.l   %1,%0
3394         sts.l   %1,%0
3395         sts.l   %1,%0
3396         lds     %1,%0
3397         lds     %1,%0
3398         lds.l   %1,%0
3399         lds.l   %1,%0
3400         fake    %1,%0"
3401   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3402    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3404 ;; t/r must come after r/r, lest reload will try to reload stuff like
3405 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3406 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3407 ;; will require a reload.
3408 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3409 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3410 (define_insn "movsi_ie"
3411   [(set (match_operand:SI 0 "general_movdst_operand"
3412             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3413         (match_operand:SI 1 "general_movsrc_operand"
3414          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3415   "(TARGET_SH2E || TARGET_SH2A)
3416    && (register_operand (operands[0], SImode)
3417        || register_operand (operands[1], SImode))"
3418   "@
3419         mov.l   %1,%0
3420         mov     %1,%0
3421         movi20  %1,%0
3422         cmp/pl  %1
3423         mov.l   %1,%0
3424         sts     %1,%0
3425         sts     %1,%0
3426         movt    %0
3427         mov.l   %1,%0
3428         sts.l   %1,%0
3429         sts.l   %1,%0
3430         lds     %1,%0
3431         lds     %1,%0
3432         lds.l   %1,%0
3433         lds.l   %1,%0
3434         lds.l   %1,%0
3435         sts.l   %1,%0
3436         fake    %1,%0
3437         lds     %1,%0
3438         sts     %1,%0
3439         fsts    fpul,%0
3440         flds    %1,fpul
3441         fmov    %1,%0
3442         ! move optimized away"
3443   [(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")
3444    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3445    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3447 (define_insn "movsi_i_lowpart"
3448   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3449         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3450    "TARGET_SH1
3451     && (register_operand (operands[0], SImode)
3452         || register_operand (operands[1], SImode))"
3453   "@
3454         mov.l   %1,%0
3455         mov     %1,%0
3456         mov.l   %1,%0
3457         sts     %1,%0
3458         sts     %1,%0
3459         movt    %0
3460         mov.l   %1,%0
3461         fake    %1,%0"
3462   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3464 (define_insn_and_split "load_ra"
3465   [(set (match_operand:SI 0 "general_movdst_operand" "")
3466         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3467   "TARGET_SH1"
3468   "#"
3469   "&& ! currently_expanding_to_rtl"
3470   [(set (match_dup 0) (match_dup 1))]
3471   "
3473   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3474     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3477 (define_insn "*movsi_media"
3478   [(set (match_operand:SI 0 "general_movdst_operand"
3479                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3480         (match_operand:SI 1 "general_movsrc_operand"
3481          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3482   "TARGET_SHMEDIA_FPU
3483    && (register_operand (operands[0], SImode)
3484        || sh_register_operand (operands[1], SImode))"
3485   "@
3486         add.l   %1, r63, %0
3487         movi    %1, %0
3488         #
3489         ld%M1.l %m1, %0
3490         st%M0.l %m0, %N1
3491         fld%M1.s        %m1, %0
3492         fst%M0.s        %m0, %1
3493         fmov.ls %N1, %0
3494         fmov.sl %1, %0
3495         fmov.s  %1, %0
3496         ptabs   %1, %0
3497         gettr   %1, %0
3498         pt      %1, %0"
3499   [(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")
3500    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3502 (define_insn "*movsi_media_nofpu"
3503   [(set (match_operand:SI 0 "general_movdst_operand"
3504                 "=r,r,r,r,m,*b,r,b")
3505         (match_operand:SI 1 "general_movsrc_operand"
3506          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3507   "TARGET_SHMEDIA
3508    && (register_operand (operands[0], SImode)
3509        || sh_register_operand (operands[1], SImode))"
3510   "@
3511         add.l   %1, r63, %0
3512         movi    %1, %0
3513         #
3514         ld%M1.l %m1, %0
3515         st%M0.l %m0, %N1
3516         ptabs   %1, %0
3517         gettr   %1, %0
3518         pt      %1, %0"
3519   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3520    (set_attr "length" "4,4,8,4,4,4,4,12")])
3522 (define_split
3523   [(set (match_operand:SI 0 "arith_reg_operand" "")
3524         (match_operand:SI 1 "immediate_operand" ""))]
3525   "TARGET_SHMEDIA && reload_completed
3526    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3527   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3528   "
3530   operands[2] = shallow_copy_rtx (operands[1]);
3531   PUT_MODE (operands[2], DImode);
3534 (define_split
3535   [(set (match_operand:SI 0 "register_operand" "")
3536         (match_operand:SI 1 "immediate_operand" ""))]
3537   "TARGET_SHMEDIA && reload_completed
3538    && ((GET_CODE (operands[1]) == CONST_INT
3539         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3540        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3541   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3543 (define_expand "movsi"
3544   [(set (match_operand:SI 0 "general_movdst_operand" "")
3545         (match_operand:SI 1 "general_movsrc_operand" ""))]
3546   ""
3547   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3549 (define_expand "ic_invalidate_line"
3550   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3551                                 (match_dup 1)] UNSPEC_ICACHE)
3552               (clobber (scratch:SI))])]
3553   "TARGET_HARD_SH4 || TARGET_SH5"
3554   "
3556   if (TARGET_SHMEDIA)
3557     {
3558       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3559       DONE;
3560     }
3561   else if (TARGET_SHCOMPACT)
3562     {
3563       operands[1] = function_symbol (\"__ic_invalidate\");
3564       operands[1] = force_reg (Pmode, operands[1]);
3565       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3566       DONE;
3567     }
3568   else if (TARGET_SH4A_ARCH)
3569     {
3570       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3571       DONE;
3572     }
3573   operands[0] = force_reg (Pmode, operands[0]);
3574   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3575                                                                Pmode)));
3578 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3579 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3580 ;; the requirement *1*00 for associative address writes.  The alignment of
3581 ;; %0 implies that its least significant bit is cleared,
3582 ;; thus we clear the V bit of a matching entry if there is one.
3583 (define_insn "ic_invalidate_line_i"
3584   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3585                      (match_operand:SI 1 "register_operand" "r")]
3586                      UNSPEC_ICACHE)
3587    (clobber (match_scratch:SI 2 "=&r"))]
3588   "TARGET_HARD_SH4"
3589   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3590   [(set_attr "length" "8")
3591    (set_attr "type" "cwb")])
3593 (define_insn "ic_invalidate_line_sh4a"
3594   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3595                     UNSPEC_ICACHE)]
3596   "TARGET_SH4A_ARCH"
3597   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3598   [(set_attr "length" "16")
3599    (set_attr "type" "cwb")])
3601 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3602 ;; an add in the code that calculates the address.
3603 (define_insn "ic_invalidate_line_media"
3604   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3605                     UNSPEC_ICACHE)]
3606   "TARGET_SHMEDIA"
3607   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3608   [(set_attr "length" "16")
3609    (set_attr "type" "invalidate_line_media")])
3611 (define_insn "ic_invalidate_line_compact"
3612   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3613                      (match_operand:SI 1 "register_operand" "r")]
3614                     UNSPEC_ICACHE)
3615    (clobber (reg:SI PR_REG))]
3616   "TARGET_SHCOMPACT"
3617   "jsr @%1%#"
3618   [(set_attr "type" "sfunc")
3619    (set_attr "needs_delay_slot" "yes")])
3621 (define_expand "initialize_trampoline"
3622   [(match_operand:SI 0 "" "")
3623    (match_operand:SI 1 "" "")
3624    (match_operand:SI 2 "" "")]
3625   "TARGET_SHCOMPACT"
3626   "
3628   rtx sfun, tramp;
3630   tramp = force_reg (Pmode, operands[0]);
3631   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3632   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3633   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3635   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3636   DONE;
3639 (define_insn "initialize_trampoline_compact"
3640   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3641                      (match_operand:SI 1 "register_operand" "r")
3642                      (reg:SI R2_REG) (reg:SI R3_REG)]
3643                     UNSPEC_INIT_TRAMP)
3645    (clobber (reg:SI PR_REG))]
3646   "TARGET_SHCOMPACT"
3647   "jsr @%1%#"
3648   [(set_attr "type" "sfunc")
3649    (set_attr "needs_delay_slot" "yes")])
3651 (define_insn "movqi_i"
3652   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3653         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3654   "TARGET_SH1
3655    && (arith_reg_operand (operands[0], QImode)
3656        || arith_reg_operand (operands[1], QImode))"
3657   "@
3658         mov     %1,%0
3659         mov.b   %1,%0
3660         mov.b   %1,%0
3661         movt    %0
3662         sts     %1,%0
3663         lds     %1,%0"
3664  [(set_attr "type" "move,load,store,move,move,move")])
3666 (define_insn "*movqi_media"
3667   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3668         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3669   "TARGET_SHMEDIA
3670    && (arith_reg_operand (operands[0], QImode)
3671        || arith_reg_or_0_operand (operands[1], QImode))"
3672   "@
3673         add.l   %1, r63, %0
3674         movi    %1, %0
3675         ld%M1.ub        %m1, %0
3676         st%M0.b %m0, %N1"
3677   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3679 (define_expand "movqi"
3680   [(set (match_operand:QI 0 "general_operand" "")
3681         (match_operand:QI 1 "general_operand"  ""))]
3682   ""
3683   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3685 (define_expand "reload_inqi"
3686   [(set (match_operand:SI 2 "" "=&r")
3687         (match_operand:QI 1 "inqhi_operand" ""))
3688    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3689         (truncate:QI (match_dup 3)))]
3690   "TARGET_SHMEDIA"
3691   "
3693   rtx inner = XEXP (operands[1], 0);
3694   int regno = REGNO (inner);
3696   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3697   operands[1] = gen_rtx_REG (SImode, regno);
3698   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3701 /* When storing r0, we have to avoid reg+reg addressing.  */
3702 (define_insn "movhi_i"
3703   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3704         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3705   "TARGET_SH1
3706    && (arith_reg_operand (operands[0], HImode)
3707        || arith_reg_operand (operands[1], HImode))
3708    && (GET_CODE (operands[0]) != MEM
3709        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3710        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3711        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3712   "@
3713         mov.w   %1,%0
3714         mov     %1,%0
3715         mov.w   %1,%0
3716         movt    %0
3717         mov.w   %1,%0
3718         sts     %1,%0
3719         lds     %1,%0
3720         fake    %1,%0"
3721   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3723 (define_insn "*movhi_media"
3724   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3725         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3726   "TARGET_SHMEDIA
3727    && (arith_reg_operand (operands[0], HImode)
3728        || arith_reg_or_0_operand (operands[1], HImode))"
3729   "@
3730         add.l   %1, r63, %0
3731         movi    %1, %0
3732         #
3733         ld%M1.w %m1, %0
3734         st%M0.w %m0, %N1"
3735   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3737 (define_split
3738   [(set (match_operand:HI 0 "register_operand" "")
3739         (match_operand:HI 1 "immediate_operand" ""))]
3740   "TARGET_SHMEDIA && reload_completed
3741    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3742   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3744 (define_expand "movhi"
3745   [(set (match_operand:HI 0 "general_movdst_operand" "")
3746         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3747   ""
3748   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3750 (define_expand "reload_inhi"
3751   [(set (match_operand:SI 2 "" "=&r")
3752         (match_operand:HI 1 "inqhi_operand" ""))
3753    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3754         (truncate:HI (match_dup 3)))]
3755   "TARGET_SHMEDIA"
3756   "
3758   rtx inner = XEXP (operands[1], 0);
3759   int regno = REGNO (inner);
3761   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3762   operands[1] = gen_rtx_REG (SImode, regno);
3763   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3766 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3767 ;; compiled with -m2 -ml -O3 -funroll-loops
3768 (define_insn "*movdi_i"
3769   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3770         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3771   "TARGET_SH1
3772    && (arith_reg_operand (operands[0], DImode)
3773        || arith_reg_operand (operands[1], DImode))"
3774   "* return output_movedouble (insn, operands, DImode);"
3775   [(set_attr "length" "4")
3776    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3778 ;; If the output is a register and the input is memory or a register, we have
3779 ;; to be careful and see which word needs to be loaded first.
3781 (define_split
3782   [(set (match_operand:DI 0 "general_movdst_operand" "")
3783         (match_operand:DI 1 "general_movsrc_operand" ""))]
3784   "TARGET_SH1 && reload_completed"
3785   [(set (match_dup 2) (match_dup 3))
3786    (set (match_dup 4) (match_dup 5))]
3787   "
3789   int regno;
3791   if ((GET_CODE (operands[0]) == MEM
3792        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3793       || (GET_CODE (operands[1]) == MEM
3794           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3795     FAIL;
3797   if (GET_CODE (operands[0]) == REG)
3798     regno = REGNO (operands[0]);
3799   else if (GET_CODE (operands[0]) == SUBREG)
3800     regno = subreg_regno (operands[0]);
3801   else if (GET_CODE (operands[0]) == MEM)
3802     regno = -1;
3803   else
3804     abort ();
3806   if (regno == -1
3807       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3808     {
3809       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3810       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3811       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3812       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3813     }
3814   else
3815     {
3816       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3817       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3818       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3819       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3820     }
3822   if (operands[2] == 0 || operands[3] == 0
3823       || operands[4] == 0 || operands[5] == 0)
3824     FAIL;
3827 (define_insn "*movdi_media"
3828   [(set (match_operand:DI 0 "general_movdst_operand"
3829                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3830         (match_operand:DI 1 "general_movsrc_operand"
3831          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3832   "TARGET_SHMEDIA_FPU
3833    && (register_operand (operands[0], DImode)
3834        || sh_register_operand (operands[1], DImode))"
3835   "@
3836         add     %1, r63, %0
3837         movi    %1, %0
3838         #
3839         ld%M1.q %m1, %0
3840         st%M0.q %m0, %N1
3841         fld%M1.d        %m1, %0
3842         fst%M0.d        %m0, %1
3843         fmov.qd %N1, %0
3844         fmov.dq %1, %0
3845         fmov.d  %1, %0
3846         ptabs   %1, %0
3847         gettr   %1, %0
3848         pt      %1, %0"
3849   [(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")
3850    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3852 (define_insn "*movdi_media_nofpu"
3853   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3854         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3855   "TARGET_SHMEDIA
3856    && (register_operand (operands[0], DImode)
3857        || sh_register_operand (operands[1], DImode))"
3858   "@
3859         add     %1, r63, %0
3860         movi    %1, %0
3861         #
3862         ld%M1.q %m1, %0
3863         st%M0.q %m0, %N1
3864         ptabs   %1, %0
3865         gettr   %1, %0
3866         pt      %1, %0"
3867   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3868    (set_attr "length" "4,4,16,4,4,4,4,*")])
3870 (define_split
3871   [(set (match_operand:DI 0 "arith_reg_operand" "")
3872         (match_operand:DI 1 "immediate_operand" ""))]
3873   "TARGET_SHMEDIA && reload_completed
3874    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3875   [(set (match_dup 0) (match_dup 1))]
3876   "
3878   rtx insn;
3880   if (TARGET_SHMEDIA64)
3881     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3882   else
3883     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3885   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3886                                         REG_NOTES (insn));
3888   DONE;
3891 (define_expand "movdi_const"
3892   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3893         (const:DI (sign_extend:DI
3894                    (truncate:HI
3895                     (ashiftrt:DI
3896                      (match_operand:DI 1 "immediate_operand" "s")
3897                      (const_int 48))))))
3898    (set (match_dup 0)
3899         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3900                 (zero_extend:DI
3901                  (truncate:HI
3902                   (const:DI
3903                    (sign_extend:DI
3904                     (truncate:HI
3905                      (ashiftrt:SI
3906                       (match_dup 1)
3907                       (const_int 32)))))))))
3908    (set (match_dup 0)
3909         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3910                 (zero_extend:DI
3911                  (truncate:HI
3912                   (const:DI
3913                    (sign_extend:DI
3914                     (truncate:HI
3915                      (ashiftrt:SI
3916                       (match_dup 1)
3917                       (const_int 16)))))))))
3918    (set (match_dup 0)
3919         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3920                 (zero_extend:DI
3921                  (truncate:HI
3922                   (const:DI
3923                    (sign_extend:DI
3924                     (truncate:HI
3925                      (match_dup 1))))))))]
3926   "TARGET_SHMEDIA64 && reload_completed
3927    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3928   "
3930   sh_mark_label (operands[1], 4);
3933 (define_expand "movdi_const_32bit"
3934   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3935         (const:DI (sign_extend:DI
3936                    (truncate:HI
3937                     (ashiftrt:DI
3938                      (match_operand:DI 1 "immediate_operand" "s")
3939                      (const_int 16))))))
3940    (set (match_dup 0)
3941         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3942                 (zero_extend:DI
3943                  (truncate:HI
3944                   (const:DI
3945                    (sign_extend:DI
3946                     (truncate:HI
3947                      (match_dup 1))))))))]
3948   "TARGET_SHMEDIA32 && reload_completed
3949    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3950   "
3952   sh_mark_label (operands[1], 2);
3955 (define_expand "movdi_const_16bit"
3956   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3957         (const:DI (sign_extend:DI
3958                    (truncate:HI
3959                     (match_operand:DI 1 "immediate_operand" "s")))))]
3960   "TARGET_SHMEDIA && flag_pic && reload_completed
3961    && GET_CODE (operands[1]) == SYMBOL_REF"
3962   "")
3964 (define_split
3965   [(set (match_operand:DI 0 "arith_reg_operand" "")
3966         (match_operand:DI 1 "immediate_operand" ""))]
3967   "TARGET_SHMEDIA && reload_completed
3968    && GET_CODE (operands[1]) == CONST_INT
3969    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3970   [(set (match_dup 0) (match_dup 2))
3971    (match_dup 1)]
3972   "
3974   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3975   unsigned HOST_WIDE_INT low = val;
3976   unsigned HOST_WIDE_INT high = val;
3977   unsigned HOST_WIDE_INT sign;
3978   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3980   /* Sign-extend the 16 least-significant bits.  */
3981   low &= 0xffff;
3982   low ^= 0x8000;
3983   low -= 0x8000;
3985   /* Arithmetic shift right the word by 16 bits.  */
3986   high >>= 16;
3987   sign = 1;
3988   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3989   high ^= sign;
3990   high -= sign;
3991   do
3992     {
3993       /* If we can't generate the constant with a two-insn movi / shori
3994          sequence, try some other strategies.  */
3995       if (! CONST_OK_FOR_I16 (high))
3996         {
3997           /* Try constant load / left shift.  We know VAL != 0.  */
3998           val2 = val ^ (val-1);
3999           if (val2 > 0x1ffff)
4000             {
4001               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4003               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4004                   || (! CONST_OK_FOR_I16 (high >> 16)
4005                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4006                 {
4007                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4008                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4009                                                    GEN_INT (trailing_zeroes));
4010                   break;
4011                 }
4012             }
4013           /* Try constant load / right shift.  */
4014           val2 = (val >> 15) + 1;
4015           if (val2 == (val2 & -val2))
4016             {
4017               int shift = 49 - exact_log2 (val2);
4019               val2 = trunc_int_for_mode (val << shift, DImode);
4020               if (CONST_OK_FOR_I16 (val2))
4021                 {
4022                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4023                                                    GEN_INT (shift));
4024                   break;
4025                 }
4026             }
4027           /* Try mperm.w .  */
4028           val2 = val & 0xffff;
4029           if ((val >> 16 & 0xffff) == val2
4030               && (val >> 32 & 0xffff) == val2
4031               && (val >> 48 & 0xffff) == val2)
4032             {
4033               val2 = (HOST_WIDE_INT) val >> 48;
4034               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4035               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4036               break;
4037             }
4038           /* Try movi / mshflo.l  */
4039           val2 = (HOST_WIDE_INT) val >> 32;
4040           if (val2 == ((unsigned HOST_WIDE_INT)
4041                         trunc_int_for_mode (val, SImode)))
4042             {
4043               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4044                                              operands[0]);
4045               break;
4046             }
4047           /* Try movi / mshflo.l w/ r63.  */
4048           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4049           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4050             {
4051               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4052                                              const0_rtx);
4053               break;
4054             }
4055         }
4056       val2 = high;
4057       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4058     }
4059   while (0);
4060   operands[2] = GEN_INT (val2);
4063 (define_split
4064   [(set (match_operand:DI 0 "arith_reg_operand" "")
4065         (match_operand:DI 1 "immediate_operand" ""))]
4066   "TARGET_SHMEDIA && reload_completed
4067    && GET_CODE (operands[1]) == CONST_DOUBLE"
4068   [(set (match_dup 0) (match_dup 2))
4069   (set (match_dup 0)
4070        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4071                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4072   "
4074   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4075   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4076   unsigned HOST_WIDE_INT val = low;
4077   unsigned HOST_WIDE_INT sign;
4079   /* Sign-extend the 16 least-significant bits.  */
4080   val &= 0xffff;
4081   val ^= 0x8000;
4082   val -= 0x8000;
4083   operands[1] = GEN_INT (val);
4085   /* Arithmetic shift right the double-word by 16 bits.  */
4086   low >>= 16;
4087   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4088   high >>= 16;
4089   sign = 1;
4090   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4091   high ^= sign;
4092   high -= sign;
4094   /* This will only be true if high is a sign-extension of low, i.e.,
4095      it must be either 0 or (unsigned)-1, and be zero iff the
4096      most-significant bit of low is set.  */
4097   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4098     operands[2] = GEN_INT (low);
4099   else
4100     operands[2] = immed_double_const (low, high, DImode);
4103 (define_insn "shori_media"
4104   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4105         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4106                            (const_int 16))
4107                 (zero_extend:DI
4108                  (truncate:HI
4109                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4110   "TARGET_SHMEDIA"
4111   "@
4112         shori   %u2, %0
4113         #"
4114   [(set_attr "type" "arith_media,*")])
4116 (define_expand "movdi"
4117   [(set (match_operand:DI 0 "general_movdst_operand" "")
4118         (match_operand:DI 1 "general_movsrc_operand" ""))]
4119   ""
4120   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4122 (define_insn "movdf_media"
4123   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4124         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4125   "TARGET_SHMEDIA_FPU
4126    && (register_operand (operands[0], DFmode)
4127        || sh_register_operand (operands[1], DFmode))"
4128   "@
4129         fmov.d  %1, %0
4130         fmov.qd %N1, %0
4131         fmov.dq %1, %0
4132         add     %1, r63, %0
4133         #
4134         fld%M1.d        %m1, %0
4135         fst%M0.d        %m0, %1
4136         ld%M1.q %m1, %0
4137         st%M0.q %m0, %N1"
4138   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4140 (define_insn "movdf_media_nofpu"
4141   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4142         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4143   "TARGET_SHMEDIA
4144    && (register_operand (operands[0], DFmode)
4145        || sh_register_operand (operands[1], DFmode))"
4146   "@
4147         add     %1, r63, %0
4148         #
4149         ld%M1.q %m1, %0
4150         st%M0.q %m0, %N1"
4151   [(set_attr "type" "arith_media,*,load_media,store_media")])
4153 (define_split
4154   [(set (match_operand:DF 0 "arith_reg_operand" "")
4155         (match_operand:DF 1 "immediate_operand" ""))]
4156   "TARGET_SHMEDIA && reload_completed"
4157   [(set (match_dup 3) (match_dup 2))]
4158   "
4160   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4161   long values[2];
4162   REAL_VALUE_TYPE value;
4164   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4165   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4167   if (HOST_BITS_PER_WIDE_INT >= 64)
4168     operands[2] = immed_double_const ((unsigned long) values[endian]
4169                                       | ((HOST_WIDE_INT) values[1 - endian]
4170                                          << 32), 0, DImode);
4171   else if (HOST_BITS_PER_WIDE_INT == 32)
4172     operands[2] = immed_double_const (values[endian], values[1 - endian],
4173                                       DImode);
4174   else
4175     abort ();
4177   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4180 ;; ??? This should be a define expand.
4182 (define_insn "movdf_k"
4183   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4184         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4185   "TARGET_SH1
4186    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
4187        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4188        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4189        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4190    && (arith_reg_operand (operands[0], DFmode)
4191        || arith_reg_operand (operands[1], DFmode))"
4192   "* return output_movedouble (insn, operands, DFmode);"
4193   [(set_attr "length" "4")
4194    (set_attr "type" "move,pcload,load,store")])
4196 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4197 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4198 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4199 ;; the d/m/c/X alternative, which is split later into single-precision
4200 ;; instructions.  And when not optimizing, no splits are done before fixing
4201 ;; up pcloads, so we need usable length information for that.
4202 (define_insn "movdf_i4"
4203   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4204         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4205    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4206    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4207   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4208    && (arith_reg_operand (operands[0], DFmode)
4209        || arith_reg_operand (operands[1], DFmode))"
4210   "@
4211         fmov    %1,%0
4212         #
4213         #
4214         fmov.d  %1,%0
4215         fmov.d  %1,%0
4216         #
4217         #
4218         #
4219         #
4220         #"
4221   [(set_attr_alternative "length"
4222      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4223       (const_int 4)
4224       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4225       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4226       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4227       (const_int 4)
4228       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4229       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4230       ;; increment or decrement r15 explicitly.
4231       (if_then_else
4232        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4233        (const_int 10) (const_int 8))
4234       (if_then_else
4235        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4236        (const_int 10) (const_int 8))])
4237    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4238    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4239    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4240                                            (const_string "double")
4241                                            (const_string "none")))])
4243 ;; Moving DFmode between fp/general registers through memory
4244 ;; (the top of the stack) is faster than moving through fpul even for
4245 ;; little endian.  Because the type of an instruction is important for its
4246 ;; scheduling,  it is beneficial to split these operations, rather than
4247 ;; emitting them in one single chunk, even if this will expose a stack
4248 ;; use that will prevent scheduling of other stack accesses beyond this
4249 ;; instruction.
4250 (define_split
4251   [(set (match_operand:DF 0 "register_operand" "")
4252         (match_operand:DF 1 "register_operand" ""))
4253    (use (match_operand:PSI 2 "fpscr_operand" ""))
4254    (clobber (match_scratch:SI 3 "=X"))]
4255   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
4256    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4257   [(const_int 0)]
4258   "
4260   rtx insn, tos;
4262   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4263     {
4264       emit_move_insn (stack_pointer_rtx,
4265                       plus_constant (stack_pointer_rtx, -8));
4266       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4267     }
4268   else
4269     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4270   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4271   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4272     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4273   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4274     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4275   else
4276     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4277   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4278   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4279     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4280   else
4281     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4282   DONE;
4285 ;; local-alloc sometimes allocates scratch registers even when not required,
4286 ;; so we must be prepared to handle these.
4288 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4289 (define_split
4290   [(set (match_operand:DF 0 "general_movdst_operand" "")
4291         (match_operand:DF 1 "general_movsrc_operand"  ""))
4292    (use (match_operand:PSI 2 "fpscr_operand" ""))
4293    (clobber (match_scratch:SI 3 ""))]
4294   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
4295    && reload_completed
4296    && true_regnum (operands[0]) < 16
4297    && true_regnum (operands[1]) < 16"
4298   [(set (match_dup 0) (match_dup 1))]
4299   "
4301   /* If this was a reg <-> mem operation with base + index reg addressing,
4302      we have to handle this in a special way.  */
4303   rtx mem = operands[0];
4304   int store_p = 1;
4305   if (! memory_operand (mem, DFmode))
4306     {
4307       mem = operands[1];
4308       store_p = 0;
4309     }
4310   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4311     mem = SUBREG_REG (mem);
4312   if (GET_CODE (mem) == MEM)
4313     {
4314       rtx addr = XEXP (mem, 0);
4315       if (GET_CODE (addr) == PLUS
4316           && GET_CODE (XEXP (addr, 0)) == REG
4317           && GET_CODE (XEXP (addr, 1)) == REG)
4318         {
4319           int offset;
4320           rtx reg0 = gen_rtx_REG (Pmode, 0);
4321           rtx regop = operands[store_p], word0 ,word1;
4323           if (GET_CODE (regop) == SUBREG)
4324             alter_subreg (&regop);
4325           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4326             offset = 2;
4327           else
4328             offset = 4;
4329           mem = copy_rtx (mem);
4330           PUT_MODE (mem, SImode);
4331           word0 = gen_rtx_SUBREG (SImode, regop, 0);
4332           alter_subreg (&word0);
4333           word1 = gen_rtx_SUBREG (SImode, regop, 4);
4334           alter_subreg (&word1);
4335           if (store_p || ! refers_to_regno_p (REGNO (word0),
4336                                               REGNO (word0) + 1, addr, 0))
4337             {
4338               emit_insn (store_p
4339                          ? gen_movsi_ie (mem, word0)
4340                          : gen_movsi_ie (word0, mem));
4341               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4342               mem = copy_rtx (mem);
4343               emit_insn (store_p
4344                          ? gen_movsi_ie (mem, word1)
4345                          : gen_movsi_ie (word1, mem));
4346               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4347             }
4348           else
4349             {
4350               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4351               emit_insn (gen_movsi_ie (word1, mem));
4352               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4353               mem = copy_rtx (mem);
4354               emit_insn (gen_movsi_ie (word0, mem));
4355             }
4356           DONE;
4357         }
4358     }
4361 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4362 (define_split
4363   [(set (match_operand:DF 0 "register_operand" "")
4364         (match_operand:DF 1 "memory_operand"  ""))
4365    (use (match_operand:PSI 2 "fpscr_operand" ""))
4366    (clobber (reg:SI R0_REG))]
4367   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
4368   [(parallel [(set (match_dup 0) (match_dup 1))
4369               (use (match_dup 2))
4370               (clobber (scratch:SI))])]
4371   "")
4373 (define_expand "reload_indf"
4374   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4375                    (match_operand:DF 1 "immediate_operand" "FQ"))
4376               (use (reg:PSI FPSCR_REG))
4377               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4378   "TARGET_SH1"
4379   "")
4381 (define_expand "reload_outdf"
4382   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4383                    (match_operand:DF 1 "register_operand" "af,r"))
4384               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4385   "TARGET_SH1"
4386   "")
4388 ;; Simplify no-op moves.
4389 (define_split
4390   [(set (match_operand:SF 0 "register_operand" "")
4391         (match_operand:SF 1 "register_operand" ""))
4392    (use (match_operand:PSI 2 "fpscr_operand" ""))
4393    (clobber (match_scratch:SI 3 ""))]
4394   "TARGET_SH2E && reload_completed
4395    && true_regnum (operands[0]) == true_regnum (operands[1])"
4396   [(set (match_dup 0) (match_dup 0))]
4397   "")
4399 ;; fmovd substitute post-reload splits
4400 (define_split
4401   [(set (match_operand:DF 0 "register_operand" "")
4402         (match_operand:DF 1 "register_operand" ""))
4403    (use (match_operand:PSI 2 "fpscr_operand" ""))
4404    (clobber (match_scratch:SI 3 ""))]
4405   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4406    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4407    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4408   [(const_int 0)]
4409   "
4411   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4412   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4413                            gen_rtx_REG (SFmode, src), operands[2]));
4414   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4415                            gen_rtx_REG (SFmode, src + 1), operands[2]));
4416   DONE;
4419 (define_split
4420   [(set (match_operand:DF 0 "register_operand" "")
4421         (mem:DF (match_operand:SI 1 "register_operand" "")))
4422    (use (match_operand:PSI 2 "fpscr_operand" ""))
4423    (clobber (match_scratch:SI 3 ""))]
4424   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4425    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4426    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4427   [(const_int 0)]
4428   "
4430   int regno = true_regnum (operands[0]);
4431   rtx insn;
4432   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4434   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4435                                            regno + !! TARGET_LITTLE_ENDIAN),
4436                                   mem2, operands[2]));
4437   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4438   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4439                                            regno + ! TARGET_LITTLE_ENDIAN),
4440                                   gen_rtx_MEM (SFmode, operands[1]),
4441                                   operands[2]));
4442   DONE;
4445 (define_split
4446   [(set (match_operand:DF 0 "register_operand" "")
4447         (match_operand:DF 1 "memory_operand" ""))
4448    (use (match_operand:PSI 2 "fpscr_operand" ""))
4449    (clobber (match_scratch:SI 3 ""))]
4450   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4451    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4452   [(const_int 0)]
4453   "
4455   int regno = true_regnum (operands[0]);
4456   rtx addr, insn, adjust = NULL_RTX;
4457   rtx mem2 = copy_rtx (operands[1]);
4458   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4459   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4461   PUT_MODE (mem2, SFmode);
4462   operands[1] = copy_rtx (mem2);
4463   addr = XEXP (mem2, 0);
4464   if (GET_CODE (addr) != POST_INC)
4465     {
4466       /* If we have to modify the stack pointer, the value that we have
4467          read with post-increment might be modified by an interrupt,
4468          so write it back.  */
4469       if (REGNO (addr) == STACK_POINTER_REGNUM)
4470         adjust = gen_push_e (reg0);
4471       else
4472         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4473       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4474     }
4475   addr = XEXP (addr, 0);
4476   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4477   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4478   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4479   if (adjust)
4480     emit_insn (adjust);
4481   else
4482     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4483   DONE;
4486 (define_split
4487   [(set (match_operand:DF 0 "memory_operand" "")
4488         (match_operand:DF 1 "register_operand" ""))
4489    (use (match_operand:PSI 2 "fpscr_operand" ""))
4490    (clobber (match_scratch:SI 3 ""))]
4491   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
4492    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4493   [(const_int 0)]
4494   "
4496   int regno = true_regnum (operands[1]);
4497   rtx insn, addr, adjust = NULL_RTX;
4499   operands[0] = copy_rtx (operands[0]);
4500   PUT_MODE (operands[0], SFmode);
4501   insn = emit_insn (gen_movsf_ie (operands[0],
4502                                   gen_rtx_REG (SFmode,
4503                                            regno + ! TARGET_LITTLE_ENDIAN),
4504                                   operands[2]));
4505   operands[0] = copy_rtx (operands[0]);
4506   addr = XEXP (operands[0], 0);
4507   if (GET_CODE (addr) != PRE_DEC)
4508     {
4509       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4510       emit_insn_before (adjust, insn);
4511       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4512     }
4513   addr = XEXP (addr, 0);
4514   if (! adjust)
4515     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4516   insn = emit_insn (gen_movsf_ie (operands[0],
4517                                   gen_rtx_REG (SFmode,
4518                                            regno + !! TARGET_LITTLE_ENDIAN),
4519                                   operands[2]));
4520   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4521   DONE;
4524 ;; If the output is a register and the input is memory or a register, we have
4525 ;; to be careful and see which word needs to be loaded first.
4527 (define_split
4528   [(set (match_operand:DF 0 "general_movdst_operand" "")
4529         (match_operand:DF 1 "general_movsrc_operand" ""))]
4530   "TARGET_SH1 && reload_completed"
4531   [(set (match_dup 2) (match_dup 3))
4532    (set (match_dup 4) (match_dup 5))]
4533   "
4535   int regno;
4537   if ((GET_CODE (operands[0]) == MEM
4538        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4539       || (GET_CODE (operands[1]) == MEM
4540           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4541     FAIL;
4543   if (GET_CODE (operands[0]) == REG)
4544     regno = REGNO (operands[0]);
4545   else if (GET_CODE (operands[0]) == SUBREG)
4546     regno = subreg_regno (operands[0]);
4547   else if (GET_CODE (operands[0]) == MEM)
4548     regno = -1;
4549   else
4550     abort ();
4552   if (regno == -1
4553       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4554     {
4555       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4556       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4557       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4558       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4559     }
4560   else
4561     {
4562       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4563       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4564       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4565       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4566     }
4568   if (operands[2] == 0 || operands[3] == 0
4569       || operands[4] == 0 || operands[5] == 0)
4570     FAIL;
4573 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4574 ;; used only once, let combine add in the index again.
4576 (define_split
4577   [(set (match_operand:SI 0 "register_operand" "")
4578         (match_operand:SI 1 "" ""))
4579    (clobber (match_operand 2 "register_operand" ""))]
4580   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4581   [(use (reg:SI R0_REG))]
4582   "
4584   rtx addr, reg, const_int;
4586   if (GET_CODE (operands[1]) != MEM)
4587     FAIL;
4588   addr = XEXP (operands[1], 0);
4589   if (GET_CODE (addr) != PLUS)
4590     FAIL;
4591   reg = XEXP (addr, 0);
4592   const_int = XEXP (addr, 1);
4593   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4594          && GET_CODE (const_int) == CONST_INT))
4595     FAIL;
4596   emit_move_insn (operands[2], const_int);
4597   emit_move_insn (operands[0],
4598                   change_address (operands[1], VOIDmode,
4599                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4600   DONE;
4603 (define_split
4604   [(set (match_operand:SI 1 "" "")
4605         (match_operand:SI 0 "register_operand" ""))
4606    (clobber (match_operand 2 "register_operand" ""))]
4607   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4608   [(use (reg:SI R0_REG))]
4609   "
4611   rtx addr, reg, const_int;
4613   if (GET_CODE (operands[1]) != MEM)
4614     FAIL;
4615   addr = XEXP (operands[1], 0);
4616   if (GET_CODE (addr) != PLUS)
4617     FAIL;
4618   reg = XEXP (addr, 0);
4619   const_int = XEXP (addr, 1);
4620   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4621          && GET_CODE (const_int) == CONST_INT))
4622     FAIL;
4623   emit_move_insn (operands[2], const_int);
4624   emit_move_insn (change_address (operands[1], VOIDmode,
4625                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4626                   operands[0]);
4627   DONE;
4630 (define_expand "movdf"
4631   [(set (match_operand:DF 0 "general_movdst_operand" "")
4632         (match_operand:DF 1 "general_movsrc_operand" ""))]
4633   ""
4634   "
4636   if (prepare_move_operands (operands, DFmode)) DONE;
4637   if (TARGET_SHMEDIA)
4638     {
4639       if (TARGET_SHMEDIA_FPU)
4640         emit_insn (gen_movdf_media (operands[0], operands[1]));
4641       else
4642         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4643       DONE;
4644     }
4645   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
4646     {
4647       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4648       DONE;
4649     }
4652 ;;This is incompatible with the way gcc uses subregs.
4653 ;;(define_insn "movv2sf_i"
4654 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4655 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4656 ;;  "TARGET_SHMEDIA_FPU
4657 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4658 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4659 ;;  "@
4660 ;;      #
4661 ;;      fld%M1.p        %m1, %0
4662 ;;      fst%M0.p        %m0, %1"
4663 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4665 (define_insn_and_split "movv2sf_i"
4666   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4667         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4668   "TARGET_SHMEDIA_FPU"
4669   "#"
4670   "TARGET_SHMEDIA_FPU && reload_completed"
4671   [(set (match_dup 0) (match_dup 1))]
4672   "
4674   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4675   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4678 (define_expand "movv2sf"
4679   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4680         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4681   "TARGET_SHMEDIA_FPU"
4682   "
4684   if (prepare_move_operands (operands, V2SFmode))
4685     DONE;
4688 (define_expand "addv2sf3"
4689   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4690    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4691    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4692   "TARGET_SHMEDIA_FPU"
4693   "
4695   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4696   DONE;
4699 (define_expand "subv2sf3"
4700   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4701    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4702    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4703   "TARGET_SHMEDIA_FPU"
4704   "
4706   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4707   DONE;
4710 (define_expand "mulv2sf3"
4711   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4712    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4713    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4714   "TARGET_SHMEDIA_FPU"
4715   "
4717   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4718   DONE;
4721 (define_expand "divv2sf3"
4722   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4723    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4724    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4725   "TARGET_SHMEDIA_FPU"
4726   "
4728   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4729   DONE;
4732 (define_insn_and_split "*movv4sf_i"
4733   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4734         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4735   "TARGET_SHMEDIA_FPU"
4736   "#"
4737   "&& reload_completed"
4738   [(const_int 0)]
4739   "
4741   int i;
4743   for (i = 0; i < 4/2; i++)
4744     {
4745       rtx x, y;
4747       if (GET_CODE (operands[0]) == MEM)
4748         x = gen_rtx_MEM (V2SFmode,
4749                          plus_constant (XEXP (operands[0], 0),
4750                                         i * GET_MODE_SIZE (V2SFmode)));
4751       else
4752         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4754       if (GET_CODE (operands[1]) == MEM)
4755         y = gen_rtx_MEM (V2SFmode,
4756                          plus_constant (XEXP (operands[1], 0),
4757                                         i * GET_MODE_SIZE (V2SFmode)));
4758       else
4759         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4761       emit_insn (gen_movv2sf_i (x, y));
4762     }
4764   DONE;
4766   [(set_attr "length" "8")])
4768 (define_expand "movv4sf"
4769   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4770         (match_operand:V4SF 1 "general_operand" ""))]
4771   "TARGET_SHMEDIA_FPU"
4772   "
4774   if (prepare_move_operands (operands, V4SFmode))
4775     DONE;
4778 (define_insn_and_split "*movv16sf_i"
4779   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4780         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4781   "TARGET_SHMEDIA_FPU"
4782   "#"
4783   "&& reload_completed"
4784   [(const_int 0)]
4785   "
4787   int i;
4789   for (i = 0; i < 16/2; i++)
4790     {
4791       rtx x,y;
4793       if (GET_CODE (operands[0]) == MEM)
4794         x = gen_rtx_MEM (V2SFmode,
4795                          plus_constant (XEXP (operands[0], 0),
4796                                         i * GET_MODE_SIZE (V2SFmode)));
4797       else
4798         {
4799           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4800           alter_subreg (&x);
4801         }
4803       if (GET_CODE (operands[1]) == MEM)
4804         y = gen_rtx_MEM (V2SFmode,
4805                          plus_constant (XEXP (operands[1], 0),
4806                                         i * GET_MODE_SIZE (V2SFmode)));
4807       else
4808         {
4809           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4810           alter_subreg (&y);
4811         }
4813       emit_insn (gen_movv2sf_i (x, y));
4814     }
4816   DONE;
4818   [(set_attr "length" "32")])
4820 (define_expand "movv16sf"
4821   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4822         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4823   "TARGET_SHMEDIA_FPU"
4824   "
4826   if (prepare_move_operands (operands, V16SFmode))
4827     DONE;
4830 (define_insn "movsf_media"
4831   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4832         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4833   "TARGET_SHMEDIA_FPU
4834    && (register_operand (operands[0], SFmode)
4835        || sh_register_operand (operands[1], SFmode))"
4836   "@
4837         fmov.s  %1, %0
4838         fmov.ls %N1, %0
4839         fmov.sl %1, %0
4840         add.l   %1, r63, %0
4841         #
4842         fld%M1.s        %m1, %0
4843         fst%M0.s        %m0, %1
4844         ld%M1.l %m1, %0
4845         st%M0.l %m0, %N1"
4846   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4848 (define_insn "movsf_media_nofpu"
4849   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4850         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4851   "TARGET_SHMEDIA
4852    && (register_operand (operands[0], SFmode)
4853        || sh_register_operand (operands[1], SFmode))"
4854   "@
4855         add.l   %1, r63, %0
4856         #
4857         ld%M1.l %m1, %0
4858         st%M0.l %m0, %N1"
4859   [(set_attr "type" "arith_media,*,load_media,store_media")])
4861 (define_split
4862   [(set (match_operand:SF 0 "arith_reg_operand" "")
4863         (match_operand:SF 1 "immediate_operand" ""))]
4864   "TARGET_SHMEDIA && reload_completed
4865    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4866   [(set (match_dup 3) (match_dup 2))]
4867   "
4869   long values;
4870   REAL_VALUE_TYPE value;
4872   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4873   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4874   operands[2] = GEN_INT (values);
4876   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4879 (define_insn "movsf_i"
4880   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4881         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4882   "TARGET_SH1
4883    && (! TARGET_SH2E
4884        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4885        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4886        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4887    && (arith_reg_operand (operands[0], SFmode)
4888        || arith_reg_operand (operands[1], SFmode))"
4889   "@
4890         mov     %1,%0
4891         mov     #0,%0
4892         mov.l   %1,%0
4893         mov.l   %1,%0
4894         mov.l   %1,%0
4895         lds     %1,%0
4896         sts     %1,%0"
4897   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4899 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4900 ;; update_flow_info would not know where to put REG_EQUAL notes
4901 ;; when the destination changes mode.
4902 (define_insn "movsf_ie"
4903   [(set (match_operand:SF 0 "general_movdst_operand"
4904          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4905         (match_operand:SF 1 "general_movsrc_operand"
4906           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4907    (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"))
4908    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4910   "TARGET_SH2E
4911    && (arith_reg_operand (operands[0], SFmode)
4912        || arith_reg_operand (operands[1], SFmode)
4913        || arith_reg_operand (operands[3], SImode)
4914        || (fpul_operand (operands[0], SFmode)
4915            && memory_operand (operands[1], SFmode)
4916            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4917        || (fpul_operand (operands[1], SFmode)
4918            && memory_operand (operands[0], SFmode)
4919            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4920   "@
4921         fmov    %1,%0
4922         mov     %1,%0
4923         fldi0   %0
4924         fldi1   %0
4925         #
4926         fmov.s  %1,%0
4927         fmov.s  %1,%0
4928         mov.l   %1,%0
4929         mov.l   %1,%0
4930         mov.l   %1,%0
4931         fsts    fpul,%0
4932         flds    %1,fpul
4933         lds.l   %1,%0
4934         #
4935         sts     %1,%0
4936         lds     %1,%0
4937         sts.l   %1,%0
4938         lds.l   %1,%0
4939         ! move optimized away"
4940   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4941    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4942    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
4943    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4944                                            (const_string "single")
4945                                            (const_string "none")))])
4947 (define_split
4948   [(set (match_operand:SF 0 "register_operand" "")
4949         (match_operand:SF 1 "register_operand" ""))
4950    (use (match_operand:PSI 2 "fpscr_operand" ""))
4951    (clobber (reg:SI FPUL_REG))]
4952   "TARGET_SH1"
4953   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4954               (use (match_dup 2))
4955               (clobber (scratch:SI))])
4956    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4957               (use (match_dup 2))
4958               (clobber (scratch:SI))])]
4959   "")
4961 (define_expand "movsf"
4962   [(set (match_operand:SF 0 "general_movdst_operand" "")
4963         (match_operand:SF 1 "general_movsrc_operand" ""))]
4964   ""
4965   "
4967   if (prepare_move_operands (operands, SFmode))
4968     DONE;
4969   if (TARGET_SHMEDIA)
4970     {
4971       if (TARGET_SHMEDIA_FPU)
4972         emit_insn (gen_movsf_media (operands[0], operands[1]));
4973       else
4974         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4975       DONE;
4976     }
4977   if (TARGET_SH2E)
4978     {
4979       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4980       DONE;
4981     }
4984 (define_insn "mov_nop"
4985   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4986   "TARGET_SH2E"
4987   ""
4988   [(set_attr "length" "0")
4989    (set_attr "type" "nil")])
4991 (define_expand "reload_insf"
4992   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4993                    (match_operand:SF 1 "immediate_operand" "FQ"))
4994               (use (reg:PSI FPSCR_REG))
4995               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4996   "TARGET_SH1"
4997   "")
4999 (define_expand "reload_insi"
5000   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5001                    (match_operand:SF 1 "immediate_operand" "FQ"))
5002               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5003   "TARGET_SH1"
5004   "")
5006 (define_insn "*movsi_y"
5007   [(set (match_operand:SI 0 "register_operand" "=y,y")
5008         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5009    (clobber (match_scratch:SI 2 "=&z,r"))]
5010   "TARGET_SH2E
5011    && (reload_in_progress || reload_completed)"
5012   "#"
5013   [(set_attr "length" "4")
5014    (set_attr "type" "pcload,move")])
5016 (define_split
5017   [(set (match_operand:SI 0 "register_operand" "")
5018         (match_operand:SI 1 "immediate_operand" ""))
5019    (clobber (match_operand:SI 2 "register_operand" ""))]
5020   "TARGET_SH1"
5021   [(set (match_dup 2) (match_dup 1))
5022    (set (match_dup 0) (match_dup 2))]
5023   "")
5025 (define_split
5026   [(set (match_operand:SI 0 "register_operand" "")
5027         (match_operand:SI 1 "memory_operand" ""))
5028    (clobber (reg:SI R0_REG))]
5029   "TARGET_SH1"
5030   [(set (match_dup 0) (match_dup 1))]
5031   "")
5033 ;; ------------------------------------------------------------------------
5034 ;; Define the real conditional branch instructions.
5035 ;; ------------------------------------------------------------------------
5037 (define_insn "branch_true"
5038   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5039                            (label_ref (match_operand 0 "" ""))
5040                            (pc)))]
5041   "TARGET_SH1"
5042   "* return output_branch (1, insn, operands);"
5043   [(set_attr "type" "cbranch")])
5045 (define_insn "branch_false"
5046   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5047                            (label_ref (match_operand 0 "" ""))
5048                            (pc)))]
5049   "TARGET_SH1"
5050   "* return output_branch (0, insn, operands);"
5051   [(set_attr "type" "cbranch")])
5053 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5054 ;; which destination is too far away.
5055 ;; The const_int_operand is distinct for each branch target; it avoids
5056 ;; unwanted matches with redundant_insn.
5057 (define_insn "block_branch_redirect"
5058   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5059   "TARGET_SH1"
5060   ""
5061   [(set_attr "length" "0")])
5063 ;; This one has the additional purpose to record a possible scratch register
5064 ;; for the following branch.
5065 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5066 ;; because the insn then might be deemed dead and deleted.  And we can't
5067 ;; make the use in the jump insn explicit because that would disable
5068 ;; delay slot scheduling from the target.
5069 (define_insn "indirect_jump_scratch"
5070   [(set (match_operand:SI 0 "register_operand" "=r")
5071         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5072    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5073   "TARGET_SH1"
5074   ""
5075   [(set_attr "length" "0")])
5077 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5078 ;; being pulled into the delay slot of a condbranch that has been made to
5079 ;; jump around the unconditional jump because it was out of range.
5080 (define_insn "stuff_delay_slot"
5081   [(set (pc)
5082         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5083    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5084   "TARGET_SH1"
5085   ""
5086   [(set_attr "length" "0")
5087    (set_attr "cond_delay_slot" "yes")])
5089 ;; Conditional branch insns
5091 (define_expand "beq_media"
5092   [(set (pc)
5093         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5094                           (match_operand:DI 2 "arith_operand" "r,I06"))
5095                       (label_ref:DI (match_operand 0 "" ""))
5096                       (pc)))]
5097   "TARGET_SHMEDIA"
5098   "")
5100 (define_insn "*beq_media_i"
5101   [(set (pc)
5102         (if_then_else (match_operator 3 "equality_comparison_operator"
5103                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5104                          (match_operand:DI 2 "arith_operand" "r,I06")])
5105                       (match_operand:DI 0 "target_operand" "b,b")
5106                       (pc)))]
5107   "TARGET_SHMEDIA"
5108   "@
5109         b%o3%'  %1, %2, %0
5110         b%o3i%' %1, %2, %0"
5111   [(set_attr "type" "cbranch_media")])
5113 (define_expand "bne_media"
5114   [(set (pc)
5115         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5116                           (match_operand:DI 2 "arith_operand" "r,I06"))
5117                       (label_ref:DI (match_operand 0 "" ""))
5118                       (pc)))]
5119   "TARGET_SHMEDIA"
5120   "")
5122 (define_expand "bgt_media"
5123   [(set (pc)
5124         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5125                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5126                       (label_ref:DI (match_operand 0 "" ""))
5127                       (pc)))]
5128   "TARGET_SHMEDIA"
5129   "")
5131 (define_expand "bge_media"
5132   [(set (pc)
5133         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5134                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5135                       (label_ref:DI (match_operand 0 "" ""))
5136                       (pc)))]
5137   "TARGET_SHMEDIA"
5138   "")
5140 (define_expand "bgtu_media"
5141   [(set (pc)
5142         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5143                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5144                       (label_ref:DI (match_operand 0 "" ""))
5145                       (pc)))]
5146   "TARGET_SHMEDIA"
5147   "")
5149 (define_expand "bgeu_media"
5150   [(set (pc)
5151         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5152                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5153                       (label_ref:DI (match_operand 0 "" ""))
5154                       (pc)))]
5155   "TARGET_SHMEDIA"
5156   "")
5158 (define_insn "*bgt_media_i"
5159   [(set (pc)
5160         (if_then_else (match_operator 3 "greater_comparison_operator"
5161                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5162                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5163                       (match_operand:DI 0 "target_operand" "b")
5164                       (pc)))]
5165   "TARGET_SHMEDIA"
5166   "b%o3%'       %N1, %N2, %0"
5167   [(set_attr "type" "cbranch_media")])
5169 ;; These are only needed to make invert_jump() happy.
5170 (define_insn "*blt_media_i"
5171   [(set (pc)
5172         (if_then_else (match_operator 3 "less_comparison_operator"
5173                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5174                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5175                       (match_operand:DI 0 "target_operand" "b")
5176                       (pc)))]
5177   "TARGET_SHMEDIA"
5178   "b%o3%'       %N2, %N1, %0"
5179   [(set_attr "type" "cbranch_media")])
5181 (define_expand "beq"
5182   [(set (pc)
5183         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5184                       (label_ref (match_operand 0 "" ""))
5185                       (pc)))]
5186   ""
5187   "
5189   if (TARGET_SHMEDIA)
5190     {
5191       if (GET_MODE (sh_compare_op0) != DImode)
5192         {
5193           rtx tmp = gen_reg_rtx (DImode);
5195           emit_insn (gen_seq (tmp));
5196           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5197           DONE;
5198         }
5200       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5201       emit_jump_insn (gen_beq_media (operands[0],
5202                                      sh_compare_op0, sh_compare_op1));
5203       DONE;
5204     }
5206   from_compare (operands, EQ);
5209 (define_expand "bne"
5210   [(set (pc)
5211         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5212                       (label_ref (match_operand 0 "" ""))
5213                       (pc)))]
5214   ""
5215   "
5217   if (TARGET_SHMEDIA)
5218     {
5219       if (GET_MODE (sh_compare_op0) != DImode)
5220         {
5221           rtx tmp = gen_reg_rtx (DImode);
5223           emit_insn (gen_seq (tmp));
5224           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5225           DONE;
5226         }
5228       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5229       emit_jump_insn (gen_bne_media (operands[0],
5230                                      sh_compare_op0, sh_compare_op1));
5231       DONE;
5232     }
5234   from_compare (operands, EQ);
5237 (define_expand "bgt"
5238   [(set (pc)
5239         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5240                       (label_ref (match_operand 0 "" ""))
5241                       (pc)))]
5242   ""
5243   "
5245   if (TARGET_SHMEDIA)
5246     {
5247       if (GET_MODE (sh_compare_op0) != DImode)
5248         {
5249           rtx tmp = gen_reg_rtx (DImode);
5251           emit_insn (gen_sgt (tmp));
5252           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5253           DONE;
5254         }
5256       if (sh_compare_op0 != const0_rtx)
5257         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5258       if (sh_compare_op1 != const0_rtx)
5259         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5260       emit_jump_insn (gen_bgt_media (operands[0],
5261                                      sh_compare_op0, sh_compare_op1));
5262       DONE;
5263     }
5265   from_compare (operands, GT);
5268 (define_expand "blt"
5269   [(set (pc)
5270         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5271                       (label_ref (match_operand 0 "" ""))
5272                       (pc)))]
5273   ""
5274   "
5276   if (TARGET_SHMEDIA)
5277     {
5278       if (GET_MODE (sh_compare_op0) != DImode)
5279         {
5280           rtx tmp = gen_reg_rtx (DImode);
5282           emit_insn (gen_slt (tmp));
5283           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5284           DONE;
5285         }
5287       if (sh_compare_op0 != const0_rtx)
5288         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5289       if (sh_compare_op1 != const0_rtx)
5290         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5291       emit_jump_insn (gen_bgt_media (operands[0],
5292                                      sh_compare_op1, sh_compare_op0));
5293       DONE;
5294     }
5296   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5297     {
5298       rtx tmp = sh_compare_op0;
5299       sh_compare_op0 = sh_compare_op1;
5300       sh_compare_op1 = tmp;
5301       emit_insn (gen_bgt (operands[0]));
5302       DONE;
5303     }
5304   from_compare (operands, GE);
5307 (define_expand "ble"
5308   [(set (pc)
5309         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5310                       (label_ref (match_operand 0 "" ""))
5311                       (pc)))]
5312   ""
5313   "
5315   if (TARGET_SHMEDIA)
5316     {
5317       if (GET_MODE (sh_compare_op0) != DImode)
5318         {
5319           rtx tmp = gen_reg_rtx (DImode);
5321           emit_insn (gen_sle (tmp));
5322           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5323           DONE;
5324         }
5326       if (sh_compare_op0 != const0_rtx)
5327         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5328       if (sh_compare_op1 != const0_rtx)
5329         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5330       emit_jump_insn (gen_bge_media (operands[0],
5331                                      sh_compare_op1, sh_compare_op0));
5332       DONE;
5333     }
5335   if (TARGET_SH2E
5336       && TARGET_IEEE
5337       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5338     {
5339       rtx tmp = sh_compare_op0;
5340       sh_compare_op0 = sh_compare_op1;
5341       sh_compare_op1 = tmp;
5342       emit_insn (gen_bge (operands[0]));
5343       DONE;
5344     }
5345   from_compare (operands, GT);
5348 (define_expand "bge"
5349   [(set (pc)
5350         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5351                       (label_ref (match_operand 0 "" ""))
5352                       (pc)))]
5353   ""
5354   "
5356   if (TARGET_SHMEDIA)
5357     {
5358       if (GET_MODE (sh_compare_op0) != DImode)
5359         {
5360           rtx tmp = gen_reg_rtx (DImode);
5362           emit_insn (gen_sge (tmp));
5363           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5364           DONE;
5365         }
5367       if (sh_compare_op0 != const0_rtx)
5368         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5369       if (sh_compare_op1 != const0_rtx)
5370         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5371       emit_jump_insn (gen_bge_media (operands[0],
5372                                      sh_compare_op0, sh_compare_op1));
5373       DONE;
5374     }
5376   if (TARGET_SH2E
5377       && ! TARGET_IEEE
5378       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5379     {
5380       rtx tmp = sh_compare_op0;
5381       sh_compare_op0 = sh_compare_op1;
5382       sh_compare_op1 = tmp;
5383       emit_insn (gen_ble (operands[0]));
5384       DONE;
5385     }
5386   from_compare (operands, GE);
5389 (define_expand "bgtu"
5390   [(set (pc)
5391         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5392                       (label_ref (match_operand 0 "" ""))
5393                       (pc)))]
5394   ""
5395   "
5397   if (TARGET_SHMEDIA)
5398     {
5399       if (sh_compare_op0 != const0_rtx)
5400         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5401       if (sh_compare_op1 != const0_rtx)
5402         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5403       emit_jump_insn (gen_bgtu_media (operands[0],
5404                                       sh_compare_op0, sh_compare_op1));
5405       DONE;
5406     }
5408   from_compare (operands, GTU);
5411 (define_expand "bltu"
5412   [(set (pc)
5413         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5414                       (label_ref (match_operand 0 "" ""))
5415                       (pc)))]
5416   ""
5417   "
5419   if (TARGET_SHMEDIA)
5420     {
5421       if (sh_compare_op0 != const0_rtx)
5422         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5423       if (sh_compare_op1 != const0_rtx)
5424         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5425       emit_jump_insn (gen_bgtu_media (operands[0],
5426                                       sh_compare_op1, sh_compare_op0));
5427       DONE;
5428     }
5430   from_compare (operands, GEU);
5433 (define_expand "bgeu"
5434   [(set (pc)
5435         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5436                       (label_ref (match_operand 0 "" ""))
5437                       (pc)))]
5438   ""
5439   "
5441   if (TARGET_SHMEDIA)
5442     {
5443       if (sh_compare_op0 != const0_rtx)
5444         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5445       if (sh_compare_op1 != const0_rtx)
5446         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5447       emit_jump_insn (gen_bgeu_media (operands[0],
5448                                       sh_compare_op0, sh_compare_op1));
5449       DONE;
5450     }
5452   from_compare (operands, GEU);
5455 (define_expand "bleu"
5456   [(set (pc)
5457         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5458                       (label_ref (match_operand 0 "" ""))
5459                       (pc)))]
5460   ""
5461   "
5463   if (TARGET_SHMEDIA)
5464     {
5465       if (sh_compare_op0 != const0_rtx)
5466         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5467       if (sh_compare_op1 != const0_rtx)
5468         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5469       emit_jump_insn (gen_bgeu_media (operands[0],
5470                                       sh_compare_op1, sh_compare_op0));
5471       DONE;
5472     }
5474   from_compare (operands, GTU);
5477 (define_expand "bunordered"
5478   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5479    (set (pc)
5480         (if_then_else (ne (match_dup 1) (const_int 0))
5481                       (label_ref:DI (match_operand 0 "" ""))
5482                       (pc)))]
5483   "TARGET_SHMEDIA"
5484   "
5486   operands[1] = gen_reg_rtx (DImode);
5487   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5488   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5491 ;; ------------------------------------------------------------------------
5492 ;; Jump and linkage insns
5493 ;; ------------------------------------------------------------------------
5495 (define_insn "jump_compact"
5496   [(set (pc)
5497         (label_ref (match_operand 0 "" "")))]
5498   "TARGET_SH1"
5499   "*
5501   /* The length is 16 if the delay slot is unfilled.  */
5502   if (get_attr_length(insn) > 4)
5503     return output_far_jump(insn, operands[0]);
5504   else
5505     return   \"bra      %l0%#\";
5507   [(set_attr "type" "jump")
5508    (set_attr "needs_delay_slot" "yes")])
5510 ;; ??? It would be much saner to explicitly use the scratch register
5511 ;; in the jump insn, and have indirect_jump_scratch only set it,
5512 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5513 ;; from the target then, as it uses simplejump_p.
5514 ;;(define_insn "jump_compact_far"
5515 ;;  [(set (pc)
5516 ;;      (label_ref (match_operand 0 "" "")))
5517 ;;   (use (match_operand 1 "register_operand" "r")]
5518 ;;  "TARGET_SH1"
5519 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5520 ;;  [(set_attr "type" "jump")
5521 ;;   (set_attr "needs_delay_slot" "yes")])
5523 (define_insn "jump_media"
5524   [(set (pc)
5525         (match_operand:DI 0 "target_operand" "b"))]
5526   "TARGET_SHMEDIA"
5527   "blink        %0, r63"
5528   [(set_attr "type" "jump_media")])
5530 (define_expand "jump"
5531   [(set (pc)
5532         (label_ref (match_operand 0 "" "")))]
5533   ""
5534   "
5536   if (TARGET_SH1)
5537     emit_jump_insn (gen_jump_compact (operands[0]));
5538   else if (TARGET_SHMEDIA)
5539     {
5540       if (reload_in_progress || reload_completed)
5541         FAIL;
5542       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5543                                                          operands[0])));
5544     }
5545   DONE;
5548 (define_insn "force_mode_for_call"
5549   [(use (reg:PSI FPSCR_REG))]
5550   "TARGET_SHCOMPACT"
5551   ""
5552   [(set_attr "length" "0")
5553    (set (attr "fp_mode")
5554         (if_then_else (eq_attr "fpu_single" "yes")
5555                       (const_string "single") (const_string "double")))])
5557 (define_insn "calli"
5558   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5559          (match_operand 1 "" ""))
5560    (use (reg:PSI FPSCR_REG))
5561    (clobber (reg:SI PR_REG))]
5562   "TARGET_SH1"
5563   "jsr  @%0%#"
5564   [(set_attr "type" "call")
5565    (set (attr "fp_mode")
5566         (if_then_else (eq_attr "fpu_single" "yes")
5567                       (const_string "single") (const_string "double")))
5568    (set_attr "needs_delay_slot" "yes")
5569    (set_attr "fp_set" "unknown")])
5571 ;; This is a pc-rel call, using bsrf, for use with PIC.
5573 (define_insn "calli_pcrel"
5574   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5575          (match_operand 1 "" ""))
5576    (use (reg:PSI FPSCR_REG))
5577    (use (reg:SI PIC_REG))
5578    (use (match_operand 2 "" ""))
5579    (clobber (reg:SI PR_REG))]
5580   "TARGET_SH2"
5581   "bsrf %0\\n%O2:%#"
5582   [(set_attr "type" "call")
5583    (set (attr "fp_mode")
5584         (if_then_else (eq_attr "fpu_single" "yes")
5585                       (const_string "single") (const_string "double")))
5586    (set_attr "needs_delay_slot" "yes")
5587    (set_attr "fp_set" "unknown")])
5589 (define_insn_and_split "call_pcrel"
5590   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5591          (match_operand 1 "" ""))
5592    (use (reg:PSI FPSCR_REG))
5593    (use (reg:SI PIC_REG))
5594    (clobber (reg:SI PR_REG))
5595    (clobber (match_scratch:SI 2 "=r"))]
5596   "TARGET_SH2"
5597   "#"
5598   "reload_completed"
5599   [(const_int 0)]
5600   "
5602   rtx lab = PATTERN (gen_call_site ());
5604   if (SYMBOL_REF_LOCAL_P (operands[0]))
5605     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5606   else
5607     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5608   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5609   DONE;
5611   [(set_attr "type" "call")
5612    (set (attr "fp_mode")
5613         (if_then_else (eq_attr "fpu_single" "yes")
5614                       (const_string "single") (const_string "double")))
5615    (set_attr "needs_delay_slot" "yes")
5616    (set_attr "fp_set" "unknown")])
5618 (define_insn "call_compact"
5619   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5620          (match_operand 1 "" ""))
5621    (match_operand 2 "immediate_operand" "n")
5622    (use (reg:SI R0_REG))
5623    (use (reg:SI R1_REG))
5624    (use (reg:PSI FPSCR_REG))
5625    (clobber (reg:SI PR_REG))]
5626   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5627   "jsr  @%0%#"
5628   [(set_attr "type" "call")
5629    (set (attr "fp_mode")
5630         (if_then_else (eq_attr "fpu_single" "yes")
5631                       (const_string "single") (const_string "double")))
5632    (set_attr "needs_delay_slot" "yes")])
5634 (define_insn "call_compact_rettramp"
5635   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5636          (match_operand 1 "" ""))
5637    (match_operand 2 "immediate_operand" "n")
5638    (use (reg:SI R0_REG))
5639    (use (reg:SI R1_REG))
5640    (use (reg:PSI FPSCR_REG))
5641    (clobber (reg:SI R10_REG))
5642    (clobber (reg:SI PR_REG))]
5643   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5644   "jsr  @%0%#"
5645   [(set_attr "type" "call")
5646    (set (attr "fp_mode")
5647         (if_then_else (eq_attr "fpu_single" "yes")
5648                       (const_string "single") (const_string "double")))
5649    (set_attr "needs_delay_slot" "yes")])
5651 (define_insn "call_media"
5652   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5653          (match_operand 1 "" ""))
5654    (clobber (reg:DI PR_MEDIA_REG))]
5655   "TARGET_SHMEDIA"
5656   "blink        %0, r18"
5657   [(set_attr "type" "jump_media")])
5659 (define_insn "call_valuei"
5660   [(set (match_operand 0 "" "=rf")
5661         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5662               (match_operand 2 "" "")))
5663    (use (reg:PSI FPSCR_REG))
5664    (clobber (reg:SI PR_REG))]
5665   "TARGET_SH1"
5666   "jsr  @%1%#"
5667   [(set_attr "type" "call")
5668    (set (attr "fp_mode")
5669         (if_then_else (eq_attr "fpu_single" "yes")
5670                       (const_string "single") (const_string "double")))
5671    (set_attr "needs_delay_slot" "yes")
5672    (set_attr "fp_set" "unknown")])
5674 (define_insn "call_valuei_pcrel"
5675   [(set (match_operand 0 "" "=rf")
5676         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5677               (match_operand 2 "" "")))
5678    (use (reg:PSI FPSCR_REG))
5679    (use (reg:SI PIC_REG))
5680    (use (match_operand 3 "" ""))
5681    (clobber (reg:SI PR_REG))]
5682   "TARGET_SH2"
5683   "bsrf %1\\n%O3:%#"
5684   [(set_attr "type" "call")
5685    (set (attr "fp_mode")
5686         (if_then_else (eq_attr "fpu_single" "yes")
5687                       (const_string "single") (const_string "double")))
5688    (set_attr "needs_delay_slot" "yes")
5689    (set_attr "fp_set" "unknown")])
5691 (define_insn_and_split "call_value_pcrel"
5692   [(set (match_operand 0 "" "=rf")
5693         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5694               (match_operand 2 "" "")))
5695    (use (reg:PSI FPSCR_REG))
5696    (use (reg:SI PIC_REG))
5697    (clobber (reg:SI PR_REG))
5698    (clobber (match_scratch:SI 3 "=r"))]
5699   "TARGET_SH2"
5700   "#"
5701   "reload_completed"
5702   [(const_int 0)]
5703   "
5705   rtx lab = PATTERN (gen_call_site ());
5707   if (SYMBOL_REF_LOCAL_P (operands[1]))
5708     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5709   else
5710     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5711   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5712                                          operands[2], lab));
5713   DONE;
5715   [(set_attr "type" "call")
5716    (set (attr "fp_mode")
5717         (if_then_else (eq_attr "fpu_single" "yes")
5718                       (const_string "single") (const_string "double")))
5719    (set_attr "needs_delay_slot" "yes")
5720    (set_attr "fp_set" "unknown")])
5722 (define_insn "call_value_compact"
5723   [(set (match_operand 0 "" "=rf")
5724         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5725               (match_operand 2 "" "")))
5726    (match_operand 3 "immediate_operand" "n")
5727    (use (reg:SI R0_REG))
5728    (use (reg:SI R1_REG))
5729    (use (reg:PSI FPSCR_REG))
5730    (clobber (reg:SI PR_REG))]
5731   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5732   "jsr  @%1%#"
5733   [(set_attr "type" "call")
5734    (set (attr "fp_mode")
5735         (if_then_else (eq_attr "fpu_single" "yes")
5736                       (const_string "single") (const_string "double")))
5737    (set_attr "needs_delay_slot" "yes")])
5739 (define_insn "call_value_compact_rettramp"
5740   [(set (match_operand 0 "" "=rf")
5741         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5742               (match_operand 2 "" "")))
5743    (match_operand 3 "immediate_operand" "n")
5744    (use (reg:SI R0_REG))
5745    (use (reg:SI R1_REG))
5746    (use (reg:PSI FPSCR_REG))
5747    (clobber (reg:SI R10_REG))
5748    (clobber (reg:SI PR_REG))]
5749   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5750   "jsr  @%1%#"
5751   [(set_attr "type" "call")
5752    (set (attr "fp_mode")
5753         (if_then_else (eq_attr "fpu_single" "yes")
5754                       (const_string "single") (const_string "double")))
5755    (set_attr "needs_delay_slot" "yes")])
5757 (define_insn "call_value_media"
5758   [(set (match_operand 0 "" "=rf")
5759         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5760               (match_operand 2 "" "")))
5761    (clobber (reg:DI PR_MEDIA_REG))]
5762   "TARGET_SHMEDIA"
5763   "blink        %1, r18"
5764   [(set_attr "type" "jump_media")])
5766 (define_expand "call"
5767   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5768                             (match_operand 1 "" ""))
5769               (match_operand 2 "" "")
5770               (use (reg:PSI FPSCR_REG))
5771               (clobber (reg:SI PR_REG))])]
5772   ""
5773   "
5775   if (TARGET_SHMEDIA)
5776     {
5777       operands[0] = XEXP (operands[0], 0);
5778       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5779         {
5780           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5781             {
5782               rtx reg = gen_reg_rtx (Pmode);
5784               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5785               operands[0] = reg;
5786             }
5787           else
5788             {
5789               operands[0] = gen_sym2PIC (operands[0]);
5790               PUT_MODE (operands[0], Pmode);
5791             }
5792         }
5793       if (GET_MODE (operands[0]) == SImode)
5794         {
5795           if (GET_CODE (operands[0]) == REG)
5796             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5797           else if (GET_CODE (operands[0]) == SUBREG)
5798             {
5799               operands[0] = SUBREG_REG (operands[0]);
5800               if (GET_MODE (operands[0]) != DImode)
5801                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5802             }
5803           else
5804             {
5805               operands[0] = shallow_copy_rtx (operands[0]);
5806               PUT_MODE (operands[0], DImode);
5807             }
5808         }
5809       if (! target_reg_operand (operands[0], DImode))
5810         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5811       emit_call_insn (gen_call_media (operands[0], operands[1]));
5812       DONE;
5813     }
5814   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5815     {
5816       rtx cookie_rtx = operands[2];
5817       long cookie = INTVAL (cookie_rtx);
5818       rtx func = XEXP (operands[0], 0);
5819       rtx r0, r1;
5821       if (flag_pic)
5822         {
5823           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5824             {
5825               rtx reg = gen_reg_rtx (Pmode);
5827               emit_insn (gen_symGOTPLT2reg (reg, func));
5828               func = reg;
5829             }
5830           else
5831             func = legitimize_pic_address (func, Pmode, 0);
5832         }
5834       r0 = gen_rtx_REG (SImode, R0_REG);
5835       r1 = gen_rtx_REG (SImode, R1_REG);
5837       /* Since such a call function may use all call-clobbered
5838          registers, we force a mode switch earlier, so that we don't
5839          run out of registers when adjusting fpscr for the call.  */
5840       emit_insn (gen_force_mode_for_call ());
5842       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5843       if (flag_pic)
5844         {
5845           rtx reg = gen_reg_rtx (Pmode);
5847           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5848           operands[0] = reg;
5849         }
5850       operands[0] = force_reg (SImode, operands[0]);
5852       emit_move_insn (r0, func);
5853       emit_move_insn (r1, cookie_rtx);
5855       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5856         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5857                                                    operands[2]));
5858       else
5859         emit_call_insn (gen_call_compact (operands[0], operands[1],
5860                                           operands[2]));
5862       DONE;
5863     }
5864   else if (TARGET_SHCOMPACT && flag_pic
5865            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5866            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5867     {
5868       rtx reg = gen_reg_rtx (Pmode);
5870       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5871       XEXP (operands[0], 0) = reg;
5872     }
5873   if (flag_pic && TARGET_SH2
5874       && GET_CODE (operands[0]) == MEM
5875       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5876     {
5877       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5878       DONE;
5879     }
5880   else
5881   {
5882     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5883     operands[1] = operands[2];
5884   }
5886   emit_call_insn (gen_calli (operands[0], operands[1]));
5887   DONE;
5890 (define_insn "call_pop_compact"
5891   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5892          (match_operand 1 "" ""))
5893    (match_operand 2 "immediate_operand" "n")
5894    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5895                                  (match_operand 3 "immediate_operand" "n")))
5896    (use (reg:SI R0_REG))
5897    (use (reg:SI R1_REG))
5898    (use (reg:PSI FPSCR_REG))
5899    (clobber (reg:SI PR_REG))]
5900   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5901   "jsr  @%0%#"
5902   [(set_attr "type" "call")
5903    (set (attr "fp_mode")
5904         (if_then_else (eq_attr "fpu_single" "yes")
5905                       (const_string "single") (const_string "double")))
5906    (set_attr "needs_delay_slot" "yes")])
5908 (define_insn "call_pop_compact_rettramp"
5909   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5910          (match_operand 1 "" ""))
5911    (match_operand 2 "immediate_operand" "n")
5912    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5913                                  (match_operand 3 "immediate_operand" "n")))
5914    (use (reg:SI R0_REG))
5915    (use (reg:SI R1_REG))
5916    (use (reg:PSI FPSCR_REG))
5917    (clobber (reg:SI R10_REG))
5918    (clobber (reg:SI PR_REG))]
5919   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5920   "jsr  @%0%#"
5921   [(set_attr "type" "call")
5922    (set (attr "fp_mode")
5923         (if_then_else (eq_attr "fpu_single" "yes")
5924                       (const_string "single") (const_string "double")))
5925    (set_attr "needs_delay_slot" "yes")])
5927 (define_expand "call_pop"
5928   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5929                     (match_operand 1 "" ""))
5930              (match_operand 2 "" "")
5931              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5932                                            (match_operand 3 "" "")))])]
5933   "TARGET_SHCOMPACT"
5934   "
5936   if (operands[2] && INTVAL (operands[2]))
5937     {
5938       rtx cookie_rtx = operands[2];
5939       long cookie = INTVAL (cookie_rtx);
5940       rtx func = XEXP (operands[0], 0);
5941       rtx r0, r1;
5943       if (flag_pic)
5944         {
5945           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5946             {
5947               rtx reg = gen_reg_rtx (Pmode);
5949               emit_insn (gen_symGOTPLT2reg (reg, func));
5950               func = reg;
5951             }
5952           else
5953             func = legitimize_pic_address (func, Pmode, 0);
5954         }
5956       r0 = gen_rtx_REG (SImode, R0_REG);
5957       r1 = gen_rtx_REG (SImode, R1_REG);
5959       /* Since such a call function may use all call-clobbered
5960          registers, we force a mode switch earlier, so that we don't
5961          run out of registers when adjusting fpscr for the call.  */
5962       emit_insn (gen_force_mode_for_call ());
5964       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5965       if (flag_pic)
5966         {
5967           rtx reg = gen_reg_rtx (Pmode);
5969           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5970           operands[0] = reg;
5971         }
5972       operands[0] = force_reg (SImode, operands[0]);
5974       emit_move_insn (r0, func);
5975       emit_move_insn (r1, cookie_rtx);
5977       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5978         emit_call_insn (gen_call_pop_compact_rettramp
5979                         (operands[0], operands[1], operands[2], operands[3]));
5980       else
5981         emit_call_insn (gen_call_pop_compact
5982                         (operands[0], operands[1], operands[2], operands[3]));
5984       DONE;
5985     }
5987   abort ();
5990 (define_expand "call_value"
5991   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5992                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5993                                  (match_operand 2 "" "")))
5994               (match_operand 3 "" "")
5995               (use (reg:PSI FPSCR_REG))
5996               (clobber (reg:SI PR_REG))])]
5997   ""
5998   "
6000   if (TARGET_SHMEDIA)
6001     {
6002       operands[1] = XEXP (operands[1], 0);
6003       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6004         {
6005           if (! SYMBOL_REF_LOCAL_P (operands[1]))
6006             {
6007               rtx reg = gen_reg_rtx (Pmode);
6009               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6010               operands[1] = reg;
6011             }
6012           else
6013             {
6014               operands[1] = gen_sym2PIC (operands[1]);
6015               PUT_MODE (operands[1], Pmode);
6016             }
6017         }
6018       if (GET_MODE (operands[1]) == SImode)
6019         {
6020           if (GET_CODE (operands[1]) == REG)
6021             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6022           else if (GET_CODE (operands[1]) == SUBREG)
6023             {
6024               operands[1] = SUBREG_REG (operands[1]);
6025               if (GET_MODE (operands[1]) != DImode)
6026                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6027             }
6028           else
6029             {
6030               operands[1] = shallow_copy_rtx (operands[1]);
6031               PUT_MODE (operands[1], DImode);
6032             }
6033         }
6034       if (! target_reg_operand (operands[1], DImode))
6035         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6036       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6037                                             operands[2]));
6038       DONE;
6039     }
6040   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6041     {
6042       rtx cookie_rtx = operands[3];
6043       long cookie = INTVAL (cookie_rtx);
6044       rtx func = XEXP (operands[1], 0);
6045       rtx r0, r1;
6047       if (flag_pic)
6048         {
6049           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6050             {
6051               rtx reg = gen_reg_rtx (Pmode);
6053               emit_insn (gen_symGOTPLT2reg (reg, func));
6054               func = reg;
6055             }
6056           else
6057             func = legitimize_pic_address (func, Pmode, 0);
6058         }
6060       r0 = gen_rtx_REG (SImode, R0_REG);
6061       r1 = gen_rtx_REG (SImode, R1_REG);
6063       /* Since such a call function may use all call-clobbered
6064          registers, we force a mode switch earlier, so that we don't
6065          run out of registers when adjusting fpscr for the call.  */
6066       emit_insn (gen_force_mode_for_call ());
6068       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6069       if (flag_pic)
6070         {
6071           rtx reg = gen_reg_rtx (Pmode);
6073           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6074           operands[1] = reg;
6075         }
6076       operands[1] = force_reg (SImode, operands[1]);
6078       emit_move_insn (r0, func);
6079       emit_move_insn (r1, cookie_rtx);
6081       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6082         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6083                                                          operands[1],
6084                                                          operands[2],
6085                                                          operands[3]));
6086       else
6087         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6088                                                 operands[2], operands[3]));
6090       DONE;
6091     }
6092   else if (TARGET_SHCOMPACT && flag_pic
6093            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6094            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6095     {
6096       rtx reg = gen_reg_rtx (Pmode);
6098       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6099       XEXP (operands[1], 0) = reg;
6100     }
6101   if (flag_pic && TARGET_SH2
6102       && GET_CODE (operands[1]) == MEM
6103       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6104     {
6105       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6106                                             operands[2]));
6107       DONE;
6108     }
6109   else
6110     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6112   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6113   DONE;
6116 (define_insn "sibcalli"
6117   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6118          (match_operand 1 "" ""))
6119    (use (reg:PSI FPSCR_REG))
6120    (return)]
6121   "TARGET_SH1"
6122   "jmp  @%0%#"
6123   [(set_attr "needs_delay_slot" "yes")
6124    (set (attr "fp_mode")
6125         (if_then_else (eq_attr "fpu_single" "yes")
6126                       (const_string "single") (const_string "double")))
6127    (set_attr "type" "jump_ind")])
6129 (define_insn "sibcalli_pcrel"
6130   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6131          (match_operand 1 "" ""))
6132    (use (match_operand 2 "" ""))
6133    (use (reg:PSI FPSCR_REG))
6134    (return)]
6135   "TARGET_SH2"
6136   "braf %0\\n%O2:%#"
6137   [(set_attr "needs_delay_slot" "yes")
6138    (set (attr "fp_mode")
6139         (if_then_else (eq_attr "fpu_single" "yes")
6140                       (const_string "single") (const_string "double")))
6141    (set_attr "type" "jump_ind")])
6143 (define_insn_and_split "sibcall_pcrel"
6144   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6145          (match_operand 1 "" ""))
6146    (use (reg:PSI FPSCR_REG))
6147    (clobber (match_scratch:SI 2 "=k"))
6148    (return)]
6149   "TARGET_SH2"
6150   "#"
6151   "reload_completed"
6152   [(const_int 0)]
6153   "
6155   rtx lab = PATTERN (gen_call_site ());
6156   rtx call_insn;
6158   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6159   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6160                                                   lab));
6161   SIBLING_CALL_P (call_insn) = 1;
6162   DONE;
6164   [(set_attr "needs_delay_slot" "yes")
6165    (set (attr "fp_mode")
6166         (if_then_else (eq_attr "fpu_single" "yes")
6167                       (const_string "single") (const_string "double")))
6168    (set_attr "type" "jump_ind")])
6170 (define_insn "sibcall_compact"
6171   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6172          (match_operand 1 "" ""))
6173    (return)
6174    (use (match_operand:SI 2 "register_operand" "z,x"))
6175    (use (reg:SI R1_REG))
6176    (use (reg:PSI FPSCR_REG))
6177    ;; We want to make sure the `x' above will only match MACH_REG
6178    ;; because sibcall_epilogue may clobber MACL_REG.
6179    (clobber (reg:SI MACL_REG))]
6180   "TARGET_SHCOMPACT"
6181   "@
6182         jmp     @%0%#
6183         jmp     @%0\\n  sts     %2, r0"
6184   [(set_attr "needs_delay_slot" "yes,no")
6185    (set_attr "length" "2,4")
6186    (set (attr "fp_mode") (const_string "single"))
6187    (set_attr "type" "jump_ind")])
6189 (define_insn "sibcall_media"
6190   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6191          (match_operand 1 "" ""))
6192    (use (reg:SI PR_MEDIA_REG))
6193    (return)]
6194   "TARGET_SHMEDIA"
6195   "blink        %0, r63"
6196   [(set_attr "type" "jump_media")])
6198 (define_expand "sibcall"
6199   [(parallel
6200     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6201            (match_operand 1 "" ""))
6202      (match_operand 2 "" "")
6203      (use (reg:PSI FPSCR_REG))
6204      (return)])]
6205   ""
6206   "
6208   if (TARGET_SHMEDIA)
6209     {
6210       operands[0] = XEXP (operands[0], 0);
6211       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6212         {
6213           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6214             {
6215               rtx reg = gen_reg_rtx (Pmode);
6217               /* We must not use GOTPLT for sibcalls, because PIC_REG
6218                  must be restored before the PLT code gets to run.  */
6219               emit_insn (gen_symGOT2reg (reg, operands[0]));
6220               operands[0] = reg;
6221             }
6222           else
6223             {
6224               operands[0] = gen_sym2PIC (operands[0]);
6225               PUT_MODE (operands[0], Pmode);
6226             }
6227         }
6228       if (GET_MODE (operands[0]) == SImode)
6229         {
6230           if (GET_CODE (operands[0]) == REG)
6231             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6232           else if (GET_CODE (operands[0]) == SUBREG)
6233             {
6234               operands[0] = SUBREG_REG (operands[0]);
6235               if (GET_MODE (operands[0]) != DImode)
6236                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6237             }
6238           else
6239             {
6240               operands[0] = shallow_copy_rtx (operands[0]);
6241               PUT_MODE (operands[0], DImode);
6242             }
6243         }
6244       if (! target_reg_operand (operands[0], DImode))
6245         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6246       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6247       DONE;
6248     }
6249   else if (TARGET_SHCOMPACT && operands[2]
6250            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6251     {
6252       rtx cookie_rtx = operands[2];
6253       long cookie = INTVAL (cookie_rtx);
6254       rtx func = XEXP (operands[0], 0);
6255       rtx mach, r1;
6257       if (flag_pic)
6258         {
6259           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6260             {
6261               rtx reg = gen_reg_rtx (Pmode);
6263               emit_insn (gen_symGOT2reg (reg, func));
6264               func = reg;
6265             }
6266           else
6267             func = legitimize_pic_address (func, Pmode, 0);
6268         }
6270       /* FIXME: if we could tell whether all argument registers are
6271          already taken, we could decide whether to force the use of
6272          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6273          simple way to tell.  We could use the CALL_COOKIE, but we
6274          can't currently tell a register used for regular argument
6275          passing from one that is unused.  If we leave it up to reload
6276          to decide which register to use, it seems to always choose
6277          R0_REG, which leaves no available registers in SIBCALL_REGS
6278          to hold the address of the trampoline.  */
6279       mach = gen_rtx_REG (SImode, MACH_REG);
6280       r1 = gen_rtx_REG (SImode, R1_REG);
6282       /* Since such a call function may use all call-clobbered
6283          registers, we force a mode switch earlier, so that we don't
6284          run out of registers when adjusting fpscr for the call.  */
6285       emit_insn (gen_force_mode_for_call ());
6287       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6288       if (flag_pic)
6289         {
6290           rtx reg = gen_reg_rtx (Pmode);
6292           emit_insn (gen_symGOT2reg (reg, operands[0]));
6293           operands[0] = reg;
6294         }
6295       operands[0] = force_reg (SImode, operands[0]);
6297       /* We don't need a return trampoline, since the callee will
6298          return directly to the upper caller.  */
6299       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6300         {
6301           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6302           cookie_rtx = GEN_INT (cookie);
6303         }
6305       emit_move_insn (mach, func);
6306       emit_move_insn (r1, cookie_rtx);
6308       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6309       DONE;
6310     }
6311   else if (TARGET_SHCOMPACT && flag_pic
6312            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6313            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6314     {
6315       rtx reg = gen_reg_rtx (Pmode);
6317       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6318       XEXP (operands[0], 0) = reg;
6319     }
6320   if (flag_pic && TARGET_SH2
6321       && GET_CODE (operands[0]) == MEM
6322       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6323       /* The PLT needs the PIC register, but the epilogue would have
6324          to restore it, so we can only use PC-relative PIC calls for
6325          static functions.  */
6326       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6327     {
6328       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6329       DONE;
6330     }
6331   else
6332     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6334   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6335   DONE;
6338 (define_expand "sibcall_value"
6339   [(set (match_operand 0 "" "")
6340         (call (match_operand 1 "" "")
6341               (match_operand 2 "" "")))
6342    (match_operand 3 "" "")]
6343   ""
6344   "
6346   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6347   DONE;
6350 (define_insn "call_value_pop_compact"
6351   [(set (match_operand 0 "" "=rf")
6352         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6353               (match_operand 2 "" "")))
6354    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6355                                  (match_operand 4 "immediate_operand" "n")))
6356    (match_operand 3 "immediate_operand" "n")
6357    (use (reg:SI R0_REG))
6358    (use (reg:SI R1_REG))
6359    (use (reg:PSI FPSCR_REG))
6360    (clobber (reg:SI PR_REG))]
6361   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6362   "jsr  @%1%#"
6363   [(set_attr "type" "call")
6364    (set (attr "fp_mode")
6365         (if_then_else (eq_attr "fpu_single" "yes")
6366                       (const_string "single") (const_string "double")))
6367    (set_attr "needs_delay_slot" "yes")])
6369 (define_insn "call_value_pop_compact_rettramp"
6370   [(set (match_operand 0 "" "=rf")
6371         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6372               (match_operand 2 "" "")))
6373    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6374                                  (match_operand 4 "immediate_operand" "n")))
6375    (match_operand 3 "immediate_operand" "n")
6376    (use (reg:SI R0_REG))
6377    (use (reg:SI R1_REG))
6378    (use (reg:PSI FPSCR_REG))
6379    (clobber (reg:SI R10_REG))
6380    (clobber (reg:SI PR_REG))]
6381   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6382   "jsr  @%1%#"
6383   [(set_attr "type" "call")
6384    (set (attr "fp_mode")
6385         (if_then_else (eq_attr "fpu_single" "yes")
6386                       (const_string "single") (const_string "double")))
6387    (set_attr "needs_delay_slot" "yes")])
6389 (define_expand "call_value_pop"
6390   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6391                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6392                                  (match_operand 2 "" "")))
6393               (match_operand 3 "" "")
6394               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6395                                             (match_operand 4 "" "")))])]
6396   "TARGET_SHCOMPACT"
6397   "
6399   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6400     {
6401       rtx cookie_rtx = operands[3];
6402       long cookie = INTVAL (cookie_rtx);
6403       rtx func = XEXP (operands[1], 0);
6404       rtx r0, r1;
6406       if (flag_pic)
6407         {
6408           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6409             {
6410               rtx reg = gen_reg_rtx (Pmode);
6412               emit_insn (gen_symGOTPLT2reg (reg, func));
6413               func = reg;
6414             }
6415           else
6416             func = legitimize_pic_address (func, Pmode, 0);
6417         }
6419       r0 = gen_rtx_REG (SImode, R0_REG);
6420       r1 = gen_rtx_REG (SImode, R1_REG);
6422       /* Since such a call function may use all call-clobbered
6423          registers, we force a mode switch earlier, so that we don't
6424          run out of registers when adjusting fpscr for the call.  */
6425       emit_insn (gen_force_mode_for_call ());
6427       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6428       if (flag_pic)
6429         {
6430           rtx reg = gen_reg_rtx (Pmode);
6432           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6433           operands[1] = reg;
6434         }
6435       operands[1] = force_reg (SImode, operands[1]);
6437       emit_move_insn (r0, func);
6438       emit_move_insn (r1, cookie_rtx);
6440       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6441         emit_call_insn (gen_call_value_pop_compact_rettramp
6442                         (operands[0], operands[1], operands[2],
6443                          operands[3], operands[4]));
6444       else
6445         emit_call_insn (gen_call_value_pop_compact
6446                         (operands[0], operands[1], operands[2],
6447                          operands[3], operands[4]));
6449       DONE;
6450     }
6452   abort ();
6455 (define_expand "sibcall_epilogue"
6456   [(return)]
6457   ""
6458   "
6460   sh_expand_epilogue (1);
6461   if (TARGET_SHCOMPACT)
6462     {
6463       rtx insn, set;
6465       /* If epilogue clobbers r0, preserve it in macl.  */
6466       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6467         if ((set = single_set (insn))
6468             && GET_CODE (SET_DEST (set)) == REG
6469             && REGNO (SET_DEST (set)) == R0_REG)
6470           {
6471             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6472             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6473             rtx i;
6475             /* We can't tell at this point whether the sibcall is a
6476                sibcall_compact and, if it is, whether it uses r0 or
6477                mach as operand 2, so let the instructions that
6478                preserve r0 be optimized away if r0 turns out to be
6479                dead.  */
6480             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6481             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6482                                                REG_NOTES (i));
6483             i = emit_move_insn (r0, tmp);
6484             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6485                                                REG_NOTES (i));
6486             break;
6487           }
6488     }
6489   DONE;
6492 (define_insn "indirect_jump_compact"
6493   [(set (pc)
6494         (match_operand:SI 0 "arith_reg_operand" "r"))]
6495   "TARGET_SH1"
6496   "jmp  @%0%#"
6497   [(set_attr "needs_delay_slot" "yes")
6498    (set_attr "type" "jump_ind")])
6500 (define_expand "indirect_jump"
6501   [(set (pc)
6502         (match_operand 0 "register_operand" ""))]
6503   ""
6504   "
6506   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6507     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6510 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6511 ;; which can be present in structured code from indirect jumps which can not
6512 ;; be present in structured code.  This allows -fprofile-arcs to work.
6514 ;; For SH1 processors.
6515 (define_insn "casesi_jump_1"
6516   [(set (pc)
6517         (match_operand:SI 0 "register_operand" "r"))
6518    (use (label_ref (match_operand 1 "" "")))]
6519   "TARGET_SH1"
6520   "jmp  @%0%#"
6521   [(set_attr "needs_delay_slot" "yes")
6522    (set_attr "type" "jump_ind")])
6524 ;; For all later processors.
6525 (define_insn "casesi_jump_2"
6526   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6527                       (label_ref (match_operand 1 "" ""))))
6528    (use (label_ref (match_operand 2 "" "")))]
6529   "TARGET_SH2
6530    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6531   "braf %0%#"
6532   [(set_attr "needs_delay_slot" "yes")
6533    (set_attr "type" "jump_ind")])
6535 (define_insn "casesi_jump_media"
6536   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6537    (use (label_ref (match_operand 1 "" "")))]
6538   "TARGET_SHMEDIA"
6539   "blink        %0, r63"
6540   [(set_attr "type" "jump_media")])
6542 ;; Call subroutine returning any type.
6543 ;; ??? This probably doesn't work.
6545 (define_expand "untyped_call"
6546   [(parallel [(call (match_operand 0 "" "")
6547                     (const_int 0))
6548               (match_operand 1 "" "")
6549               (match_operand 2 "" "")])]
6550   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
6551   "
6553   int i;
6555   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6557   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6558     {
6559       rtx set = XVECEXP (operands[2], 0, i);
6560       emit_move_insn (SET_DEST (set), SET_SRC (set));
6561     }
6563   /* The optimizer does not know that the call sets the function value
6564      registers we stored in the result block.  We avoid problems by
6565      claiming that all hard registers are used and clobbered at this
6566      point.  */
6567   emit_insn (gen_blockage ());
6569   DONE;
6572 ;; ------------------------------------------------------------------------
6573 ;; Misc insns
6574 ;; ------------------------------------------------------------------------
6576 (define_insn "dect"
6577   [(set (reg:SI T_REG)
6578         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6579    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6580   "TARGET_SH2"
6581   "dt   %0"
6582   [(set_attr "type" "arith")])
6584 (define_insn "nop"
6585   [(const_int 0)]
6586   ""
6587   "nop")
6589 ;; Load address of a label. This is only generated by the casesi expand,
6590 ;; and by machine_dependent_reorg (fixing up fp moves).
6591 ;; This must use unspec, because this only works for labels that are
6592 ;; within range,
6594 (define_insn "mova"
6595   [(set (reg:SI R0_REG)
6596         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6597   "TARGET_SH1"
6598   "mova %O0,r0"
6599   [(set_attr "in_delay_slot" "no")
6600    (set_attr "type" "arith")])
6602 ;; machine_dependent_reorg will make this a `mova'.
6603 (define_insn "mova_const"
6604   [(set (reg:SI R0_REG)
6605         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6606   "TARGET_SH1"
6607   "#"
6608   [(set_attr "in_delay_slot" "no")
6609    (set_attr "type" "arith")])
6611 (define_expand "GOTaddr2picreg"
6612   [(set (reg:SI R0_REG)
6613         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6614                    UNSPEC_MOVA))
6615    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6616    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6617   "" "
6619   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6620   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6622   if (TARGET_SH5)
6623     operands[1] = gen_datalabel_ref (operands[1]);
6625   if (TARGET_SHMEDIA)
6626     {
6627       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6628       rtx dipic = operands[0];
6629       rtx lab = PATTERN (gen_call_site ());
6630       rtx insn, equiv;
6632       equiv = operands[1];
6633       operands[1] = gen_rtx_MINUS (DImode,
6634                                    operands[1],
6635                                    gen_rtx_CONST
6636                                    (DImode,
6637                                     gen_rtx_MINUS (DImode,
6638                                                    gen_rtx_CONST (DImode,
6639                                                                   lab),
6640                                                    pc_rtx)));
6641       operands[1] = gen_sym2PIC (operands[1]);
6642       PUT_MODE (operands[1], DImode);
6644       if (GET_MODE (dipic) != DImode)
6645         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6647       if (TARGET_SHMEDIA64)
6648         emit_insn (gen_movdi_const (dipic, operands[1]));
6649       else
6650         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6652       emit_insn (gen_ptrel (tr, dipic, lab));
6654       if (GET_MODE (operands[0]) != GET_MODE (tr))
6655         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6657       insn = emit_move_insn (operands[0], tr);
6659       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6660                                             REG_NOTES (insn));
6662       DONE;
6663     }
6667 (define_insn "*ptb"
6668   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6669         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6670                              UNSPEC_DATALABEL)))]
6671   "TARGET_SHMEDIA && flag_pic
6672    && EXTRA_CONSTRAINT_Csy (operands[1])"
6673   "ptb/u        datalabel %1, %0"
6674   [(set_attr "type" "pt_media")
6675    (set_attr "length" "*")])
6677 (define_insn "ptrel"
6678   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6679         (plus:DI (match_operand:DI 1 "register_operand" "r")
6680               (pc)))
6681    (match_operand:DI 2 "" "")]
6682   "TARGET_SHMEDIA"
6683   "%O2: ptrel/u %1, %0"
6684   [(set_attr "type" "ptabs_media")])
6686 (define_expand "builtin_setjmp_receiver"
6687   [(match_operand 0 "" "")]
6688   "flag_pic"
6689   "
6691   emit_insn (gen_GOTaddr2picreg ());
6692   DONE;
6695 (define_expand "call_site"
6696   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6697   "TARGET_SH1"
6698   "
6700   static HOST_WIDE_INT i = 0;
6701   operands[0] = GEN_INT (i);
6702   i++;
6705 (define_expand "sym_label2reg"
6706   [(set (match_operand:SI 0 "" "")
6707         (const:SI (minus:SI
6708                    (const:SI
6709                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6710                    (const:SI
6711                     (plus:SI
6712                      (match_operand:SI 2 "" "")
6713                      (const_int 2))))))]
6714   "TARGET_SH1" "")
6716 (define_expand "symGOT_load"
6717   [(set (match_dup 2) (match_operand 1 "" ""))
6718    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6719    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6720   ""
6721   "
6723   rtx insn;
6725   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6726   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6728   if (TARGET_SHMEDIA)
6729     {
6730       rtx reg = operands[2];
6732       if (GET_MODE (reg) != DImode)
6733         reg = gen_rtx_SUBREG (DImode, reg, 0);
6735       if (flag_pic > 1)
6736         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6737       else
6738         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6739     }
6740   else
6741     emit_move_insn (operands[2], operands[1]);
6743   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6744                                              operands[2],
6745                                              gen_rtx_REG (Pmode, PIC_REG)));
6747   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6749   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6750                                                                   0), 0, 0),
6751                                         REG_NOTES (insn));
6753   DONE;
6756 (define_expand "sym2GOT"
6757   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6758   ""
6759   "")
6761 (define_expand "symGOT2reg"
6762   [(match_operand 0 "" "") (match_operand 1 "" "")]
6763   ""
6764   "
6766   rtx gotsym, insn;
6768   gotsym = gen_sym2GOT (operands[1]);
6769   PUT_MODE (gotsym, Pmode);
6770   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6772   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
6774   DONE;
6777 (define_expand "sym2GOTPLT"
6778   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6779   ""
6780   "")
6782 (define_expand "symGOTPLT2reg"
6783   [(match_operand 0 "" "") (match_operand 1 "" "")]
6784   ""
6785   "
6787   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6788   DONE;
6791 (define_expand "sym2GOTOFF"
6792   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6793   ""
6794   "")
6796 (define_expand "symGOTOFF2reg"
6797   [(match_operand 0 "" "") (match_operand 1 "" "")]
6798   ""
6799   "
6801   rtx gotoffsym, insn;
6802   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6804   gotoffsym = gen_sym2GOTOFF (operands[1]);
6805   PUT_MODE (gotoffsym, Pmode);
6806   emit_move_insn (t, gotoffsym);
6807   insn = emit_move_insn (operands[0],
6808                          gen_rtx_PLUS (Pmode, t,
6809                                        gen_rtx_REG (Pmode, PIC_REG)));
6811   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6812                                         REG_NOTES (insn));
6814   DONE;
6817 (define_expand "symPLT_label2reg"
6818   [(set (match_operand:SI 0 "" "")
6819         (const:SI (minus:SI
6820                    (const:SI
6821                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6822                    (const:SI
6823                     (minus:SI
6824                      (const:SI (plus:SI
6825                                 (match_operand:SI 2 "" "")
6826                                 (const_int 2)))
6827                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6828    ;; Even though the PIC register is not really used by the call
6829    ;; sequence in which this is expanded, the PLT code assumes the PIC
6830    ;; register is set, so we must not skip its initialization.  Since
6831    ;; we only use this expand as part of calling sequences, and never
6832    ;; to take the address of a function, this is the best point to
6833    ;; insert the (use).  Using the PLT to take the address of a
6834    ;; function would be wrong, not only because the PLT entry could
6835    ;; then be called from a function that doesn't initialize the PIC
6836    ;; register to the proper GOT, but also because pointers to the
6837    ;; same function might not compare equal, should they be set by
6838    ;; different shared libraries.
6839    (use (reg:SI PIC_REG))]
6840   "TARGET_SH1"
6841   "")
6843 (define_expand "sym2PIC"
6844   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6845   ""
6846   "")
6848 ;; TLS code generation.
6849 ;; ??? this should be a define_insn_and_split
6850 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6851 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6852 ;; for details.
6854 (define_insn "tls_global_dynamic"
6855   [(set (match_operand:SI 0 "register_operand" "=&z")
6856         (call (unspec:SI [(match_operand:SI 1 "" "")]
6857                           UNSPEC_TLSGD)
6858               (const_int 0)))
6859    (use (reg:PSI FPSCR_REG))
6860    (use (reg:SI PIC_REG))
6861    (clobber (reg:SI PR_REG))
6862    (clobber (scratch:SI))]
6863   "TARGET_SH1"
6864   "*
6866   return \"\\
6867 mov.l\\t1f,r4\\n\\
6868 \\tmova\\t2f,r0\\n\\
6869 \\tmov.l\\t2f,r1\\n\\
6870 \\tadd\\tr0,r1\\n\\
6871 \\tjsr\\t@r1\\n\\
6872 \\tadd\\tr12,r4\\n\\
6873 \\tbra\\t3f\\n\\
6874 \\tnop\\n\\
6875 \\t.align\\t2\\n\\
6876 1:\\t.long\\t%a1@TLSGD\\n\\
6877 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6878 3:\";
6880   [(set_attr "type" "tls_load")
6881    (set_attr "length" "26")])
6883 (define_insn "tls_local_dynamic"
6884   [(set (match_operand:SI 0 "register_operand" "=&z")
6885         (call (unspec:SI [(match_operand:SI 1 "" "")]
6886                           UNSPEC_TLSLDM)
6887               (const_int 0)))
6888    (use (reg:PSI FPSCR_REG))
6889    (use (reg:SI PIC_REG))
6890    (clobber (reg:SI PR_REG))
6891    (clobber (scratch:SI))]
6892   "TARGET_SH1"
6893   "*
6895   return \"\\
6896 mov.l\\t1f,r4\\n\\
6897 \\tmova\\t2f,r0\\n\\
6898 \\tmov.l\\t2f,r1\\n\\
6899 \\tadd\\tr0,r1\\n\\
6900 \\tjsr\\t@r1\\n\\
6901 \\tadd\\tr12,r4\\n\\
6902 \\tbra\\t3f\\n\\
6903 \\tnop\\n\\
6904 \\t.align\\t2\\n\\
6905 1:\\t.long\\t%a1@TLSLDM\\n\\
6906 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6907 3:\";
6909   [(set_attr "type" "tls_load")
6910    (set_attr "length" "26")])
6912 (define_expand "sym2DTPOFF"
6913   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6914   ""
6915   "")
6917 (define_expand "symDTPOFF2reg"
6918   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6919   ""
6920   "
6922   rtx dtpoffsym, insn;
6923   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6925   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6926   PUT_MODE (dtpoffsym, Pmode);
6927   emit_move_insn (t, dtpoffsym);
6928   insn = emit_move_insn (operands[0],
6929                          gen_rtx_PLUS (Pmode, t, operands[2]));
6930   DONE;
6933 (define_expand "sym2GOTTPOFF"
6934   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6935   ""
6936   "")
6938 (define_insn "tls_initial_exec"
6939   [(set (match_operand:SI 0 "register_operand" "=&r")
6940         (unspec:SI [(match_operand:SI 1 "" "")]
6941                     UNSPEC_TLSIE))
6942    (use (reg:SI GBR_REG))
6943    (use (reg:SI PIC_REG))
6944    (clobber (reg:SI R0_REG))]
6945   ""
6946   "*
6948   return \"\\
6949 mov.l\\t1f,r0\\n\\
6950 \\tstc\\tgbr,%0\\n\\
6951 \\tmov.l\\t@(r0,r12),r0\\n\\
6952 \\tbra\\t2f\\n\\
6953 \\tadd\\tr0,%0\\n\\
6954 \\t.align\\t2\\n\\
6955 1:\\t.long\\t%a1\\n\\
6956 2:\";
6958   [(set_attr "type" "tls_load")
6959    (set_attr "length" "16")])
6961 (define_expand "sym2TPOFF"
6962   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6963   ""
6964   "")
6966 (define_expand "symTPOFF2reg"
6967   [(match_operand 0 "" "") (match_operand 1 "" "")]
6968   ""
6969   "
6971   rtx tpoffsym, insn;
6973   tpoffsym = gen_sym2TPOFF (operands[1]);
6974   PUT_MODE (tpoffsym, Pmode);
6975   insn = emit_move_insn (operands[0], tpoffsym);
6976   DONE;
6979 (define_insn "load_gbr"
6980   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6981    (use (reg:SI GBR_REG))]
6982   ""
6983   "stc  gbr,%0"
6984   [(set_attr "type" "tls_load")])
6986 ;; case instruction for switch statements.
6988 ;; Operand 0 is index
6989 ;; operand 1 is the minimum bound
6990 ;; operand 2 is the maximum bound - minimum bound + 1
6991 ;; operand 3 is CODE_LABEL for the table;
6992 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6994 (define_expand "casesi"
6995   [(match_operand:SI 0 "arith_reg_operand" "")
6996    (match_operand:SI 1 "arith_reg_operand" "")
6997    (match_operand:SI 2 "arith_reg_operand" "")
6998    (match_operand 3 "" "") (match_operand 4 "" "")]
6999   ""
7000   "
7002   rtx reg = gen_reg_rtx (SImode);
7003   rtx reg2 = gen_reg_rtx (SImode);
7004   if (TARGET_SHMEDIA)
7005     {
7006       rtx reg = gen_reg_rtx (DImode);
7007       rtx reg2 = gen_reg_rtx (DImode);
7008       rtx reg3 = gen_reg_rtx (DImode);
7009       rtx reg4 = gen_reg_rtx (DImode);
7010       rtx reg5 = gen_reg_rtx (DImode);
7012       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7013       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7014       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7016       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7017       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7018       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7019       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7020       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7021                                                (DImode, operands[3])));
7022       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7023       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7024       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7025       emit_barrier ();
7026       DONE;
7027     }
7028   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7029   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7030   /* If optimizing, casesi_worker depends on the mode of the instruction
7031      before label it 'uses' - operands[3].  */
7032   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7033                            reg));
7034   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7035   if (TARGET_SH2)
7036     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7037   else
7038     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7039   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7040      operands[3], but to lab.  We will fix this up in
7041      machine_dependent_reorg.  */
7042   emit_barrier ();
7043   DONE;
7046 (define_expand "casesi_0"
7047   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7048    (set (match_dup 4) (minus:SI (match_dup 4)
7049                                 (match_operand:SI 1 "arith_operand" "")))
7050    (set (reg:SI T_REG)
7051         (gtu:SI (match_dup 4)
7052                 (match_operand:SI 2 "arith_reg_operand" "")))
7053    (set (pc)
7054         (if_then_else (ne (reg:SI T_REG)
7055                           (const_int 0))
7056                       (label_ref (match_operand 3 "" ""))
7057                       (pc)))]
7058   "TARGET_SH1"
7059   "")
7061 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7062 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7063 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7065 (define_insn "casesi_worker_0"
7066   [(set (match_operand:SI 0 "register_operand" "=r,r")
7067         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7068                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7069    (clobber (match_scratch:SI 3 "=X,1"))
7070    (clobber (match_scratch:SI 4 "=&z,z"))]
7071   "TARGET_SH1"
7072   "#")
7074 (define_split
7075   [(set (match_operand:SI 0 "register_operand" "")
7076         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7077                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7078    (clobber (match_scratch:SI 3 ""))
7079    (clobber (match_scratch:SI 4 ""))]
7080   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7081   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7082    (parallel [(set (match_dup 0)
7083               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7084                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7085               (clobber (match_dup 3))])
7086    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7087   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7089 (define_split
7090   [(set (match_operand:SI 0 "register_operand" "")
7091         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7092                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7093    (clobber (match_scratch:SI 3 ""))
7094    (clobber (match_scratch:SI 4 ""))]
7095   "TARGET_SH2 && reload_completed"
7096   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7097    (parallel [(set (match_dup 0)
7098               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7099                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7100               (clobber (match_dup 3))])]
7101   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7103 (define_insn "casesi_worker_1"
7104   [(set (match_operand:SI 0 "register_operand" "=r,r")
7105         (unspec:SI [(reg:SI R0_REG)
7106                     (match_operand:SI 1 "register_operand" "0,r")
7107                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7108    (clobber (match_scratch:SI 3 "=X,1"))]
7109   "TARGET_SH1"
7110   "*
7112   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7114   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7115     abort ();
7117   switch (GET_MODE (diff_vec))
7118     {
7119     case SImode:
7120       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7121     case HImode:
7122       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7123     case QImode:
7124       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7125         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7126       return \"mov.b    @(r0,%1),%0\";
7127     default:
7128       abort ();
7129     }
7131   [(set_attr "length" "4")])
7133 (define_insn "casesi_worker_2"
7134   [(set (match_operand:SI 0 "register_operand" "=r,r")
7135         (unspec:SI [(reg:SI R0_REG)
7136                     (match_operand:SI 1 "register_operand" "0,r")
7137                     (label_ref (match_operand 2 "" ""))
7138                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7139    (clobber (match_operand:SI 4 "" "=X,1"))]
7140   "TARGET_SH2 && reload_completed && flag_pic"
7141   "*
7143   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7144   const char *load;
7146   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7147     abort ();
7149   switch (GET_MODE (diff_vec))
7150     {
7151     case SImode:
7152       output_asm_insn (\"shll2    %1\", operands);
7153       load = \"mov.l    @(r0,%1),%0\"; break;
7154     case HImode:
7155       output_asm_insn (\"add    %1,%1\", operands);
7156       load = \"mov.w    @(r0,%1),%0\"; break;
7157     case QImode:
7158       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7159         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7160       else
7161         load = \"mov.b  @(r0,%1),%0\";
7162       break;
7163     default:
7164       abort ();
7165     }
7166   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7167   return load;
7169   [(set_attr "length" "8")])
7171 (define_insn "casesi_shift_media"
7172   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7173         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7174                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7175                     UNSPEC_CASESI)))]
7176   "TARGET_SHMEDIA"
7177   "*
7179   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7181   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7182     abort ();
7184   switch (GET_MODE (diff_vec))
7185     {
7186     case SImode:
7187       return \"shlli    %1, 2, %0\";
7188     case HImode:
7189       return \"shlli    %1, 1, %0\";
7190     case QImode:
7191       if (rtx_equal_p (operands[0], operands[1]))
7192         return \"\";
7193       return \"add      %1, r63, %0\";
7194     default:
7195       abort ();
7196     }
7198   [(set_attr "type" "arith_media")])
7200 (define_insn "casesi_load_media"
7201   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7202         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7203                          (match_operand 2 "arith_reg_operand" "r")
7204                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7205   "TARGET_SHMEDIA"
7206   "*
7208   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7210   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7211     abort ();
7213   switch (GET_MODE (diff_vec))
7214     {
7215     case SImode:
7216       return \"ldx.l    %1, %2, %0\";
7217     case HImode:
7218 #if 0
7219       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7220         return \"ldx.uw %1, %2, %0\";
7221 #endif
7222       return \"ldx.w    %1, %2, %0\";
7223     case QImode:
7224       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7225         return \"ldx.ub %1, %2, %0\";
7226       return \"ldx.b    %1, %2, %0\";
7227     default:
7228       abort ();
7229     }
7231   [(set_attr "type" "load_media")])
7233 (define_expand "return"
7234   [(return)]
7235   "reload_completed && ! sh_need_epilogue ()"
7236   "
7238   if (TARGET_SHMEDIA)
7239     {
7240       emit_jump_insn (gen_return_media ());
7241       DONE;
7242     }
7244   if (TARGET_SHCOMPACT
7245       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7246     {
7247       emit_jump_insn (gen_shcompact_return_tramp ());
7248       DONE;
7249     }
7252 (define_insn "*return_i"
7253   [(return)]
7254   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7255                     && (current_function_args_info.call_cookie
7256                         & CALL_COOKIE_RET_TRAMP (1)))
7257    && reload_completed"
7258   "%@   %#"
7259   [(set_attr "type" "return")
7260    (set_attr "needs_delay_slot" "yes")])
7262 (define_expand "shcompact_return_tramp"
7263   [(return)]
7264   "TARGET_SHCOMPACT
7265    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7266   "
7268   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7269   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7271   if (flag_pic)
7272     emit_insn (gen_symGOTPLT2reg (reg, sym));
7273   else
7274     emit_move_insn (reg, sym);
7276   emit_jump_insn (gen_shcompact_return_tramp_i ());
7277   DONE;
7280 (define_insn "shcompact_return_tramp_i"
7281   [(parallel [(return) (use (reg:SI R0_REG))])]
7282   "TARGET_SHCOMPACT
7283    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7284   "jmp  @r0%#"
7285   [(set_attr "type" "jump_ind")
7286    (set_attr "needs_delay_slot" "yes")])
7288 (define_insn "return_media_i"
7289   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7290   "TARGET_SHMEDIA && reload_completed"
7291   "blink        %0, r63"
7292   [(set_attr "type" "jump_media")])
7294 (define_insn "return_media_rte"
7295   [(return)]
7296   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7297   "rte"
7298   [(set_attr "type" "jump_media")])
7300 (define_expand "return_media"
7301   [(return)]
7302   "TARGET_SHMEDIA && reload_completed"
7303   "
7305   int tr_regno = sh_media_register_for_return ();
7306   rtx tr;
7308   if (current_function_interrupt)
7309     {
7310       emit_jump_insn (gen_return_media_rte ());
7311       DONE;
7312     }
7313   if (tr_regno < 0)
7314     {
7315       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7317       if (! call_really_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7318         abort ();
7319       tr_regno = TR0_REG;
7320       tr = gen_rtx_REG (DImode, tr_regno);
7321       emit_move_insn (tr, r18);
7322     }
7323   else
7324     tr = gen_rtx_REG (DImode, tr_regno);
7326   emit_jump_insn (gen_return_media_i (tr));
7327   DONE;
7330 (define_insn "shcompact_preserve_incoming_args"
7331   [(set (match_operand:SI 0 "register_operand" "+r")
7332         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7333   "TARGET_SHCOMPACT"
7334   ""
7335   [(set_attr "length" "0")])
7337 (define_insn "shcompact_incoming_args"
7338   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7339    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7340    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7341    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7342    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7343    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7344    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7345    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7346    (set (mem:BLK (reg:SI MACL_REG))
7347         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7348    (use (reg:SI R0_REG))
7349    (clobber (reg:SI R0_REG))
7350    (clobber (reg:SI MACL_REG))
7351    (clobber (reg:SI MACH_REG))
7352    (clobber (reg:SI PR_REG))]
7353   "TARGET_SHCOMPACT"
7354   "jsr  @r0%#"
7355   [(set_attr "needs_delay_slot" "yes")])
7357 (define_insn "shmedia_save_restore_regs_compact"
7358   [(set (reg:SI SP_REG)
7359         (plus:SI (reg:SI SP_REG)
7360                  (match_operand:SI 0 "immediate_operand" "i")))
7361    (use (reg:SI R0_REG))
7362    (clobber (reg:SI PR_REG))]
7363   "TARGET_SHCOMPACT
7364    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7365        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7366   "jsr @r0%#"
7367   [(set_attr "needs_delay_slot" "yes")])
7369 (define_expand "prologue"
7370   [(const_int 0)]
7371   ""
7372   "sh_expand_prologue (); DONE;")
7374 (define_expand "epilogue"
7375   [(return)]
7376   ""
7377   "
7379   sh_expand_epilogue (0);
7380   emit_jump_insn (gen_return ());
7381   DONE;
7384 (define_expand "eh_return"
7385   [(use (match_operand 0 "register_operand" ""))]
7386   ""
7388   rtx ra = operands[0];
7390   if (TARGET_SHMEDIA64)
7391     emit_insn (gen_eh_set_ra_di (ra));
7392   else
7393     emit_insn (gen_eh_set_ra_si (ra));
7395   DONE;
7398 ;; Clobber the return address on the stack.  We can't expand this
7399 ;; until we know where it will be put in the stack frame.
7401 (define_insn "eh_set_ra_si"
7402   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7403    (clobber (match_scratch:SI 1 "=&r"))]
7404   "! TARGET_SHMEDIA64"
7405   "#")
7407 (define_insn "eh_set_ra_di"
7408   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7409    (clobber (match_scratch:DI 1 "=&r"))]
7410   "TARGET_SHMEDIA64"
7411   "#")
7413 (define_split
7414   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7415    (clobber (match_scratch 1 ""))]
7416   "reload_completed"
7417   [(const_int 0)]
7418   "
7420   sh_set_return_address (operands[0], operands[1]);
7421   DONE;
7424 (define_insn "blockage"
7425   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7426   ""
7427   ""
7428   [(set_attr "length" "0")])
7430 ;; ------------------------------------------------------------------------
7431 ;; Scc instructions
7432 ;; ------------------------------------------------------------------------
7434 (define_insn "movt"
7435   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7436         (eq:SI (reg:SI T_REG) (const_int 1)))]
7437   "TARGET_SH1"
7438   "movt %0"
7439   [(set_attr "type" "arith")])
7441 (define_expand "seq"
7442   [(set (match_operand:SI 0 "arith_reg_operand" "")
7443         (match_dup 1))]
7444   ""
7445   "
7447   if (TARGET_SHMEDIA)
7448     {
7449       if (GET_MODE (operands[0]) != DImode)
7450         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7451       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7452       if (sh_compare_op1 != const0_rtx)
7453         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7454                                     ? GET_MODE (sh_compare_op0)
7455                                     : GET_MODE (sh_compare_op1),
7456                                     sh_compare_op1);
7458       switch (GET_MODE (sh_compare_op0))
7459         {
7460         case DImode:
7461           emit_insn (gen_cmpeqdi_media (operands[0],
7462                                         sh_compare_op0, sh_compare_op1));
7463           break;
7465         case SFmode:
7466           if (! TARGET_SHMEDIA_FPU)
7467             FAIL;
7468           emit_insn (gen_cmpeqsf_media (operands[0],
7469                                         sh_compare_op0, sh_compare_op1));
7470           break;
7472         case DFmode:
7473           if (! TARGET_SHMEDIA_FPU)
7474             FAIL;
7475           emit_insn (gen_cmpeqdf_media (operands[0],
7476                                         sh_compare_op0, sh_compare_op1));
7477           break;
7479         default:
7480           FAIL;
7481         }
7482       DONE;
7483     }
7484   if (sh_expand_t_scc (EQ, operands[0]))
7485     DONE;
7486   if (! currently_expanding_to_rtl)
7487     FAIL;
7488   operands[1] = prepare_scc_operands (EQ);
7491 (define_expand "slt"
7492   [(set (match_operand:SI 0 "arith_reg_operand" "")
7493         (match_dup 1))]
7494   ""
7495   "
7497   if (TARGET_SHMEDIA)
7498     {
7499       if (GET_MODE (operands[0]) != DImode)
7500         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7501       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7502       if (sh_compare_op1 != const0_rtx)
7503         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7504                                     ? GET_MODE (sh_compare_op0)
7505                                     : GET_MODE (sh_compare_op1),
7506                                     sh_compare_op1);
7508       switch (GET_MODE (sh_compare_op0))
7509         {
7510         case DImode:
7511           emit_insn (gen_cmpgtdi_media (operands[0],
7512                                         sh_compare_op1, sh_compare_op0));
7513           break;
7515         case SFmode:
7516           if (! TARGET_SHMEDIA_FPU)
7517             FAIL;
7518           emit_insn (gen_cmpgtsf_media (operands[0],
7519                                         sh_compare_op1, sh_compare_op0));
7520           break;
7522         case DFmode:
7523           if (! TARGET_SHMEDIA_FPU)
7524             FAIL;
7525           emit_insn (gen_cmpgtdf_media (operands[0],
7526                                         sh_compare_op1, sh_compare_op0));
7527           break;
7529         default:
7530           FAIL;
7531         }
7532       DONE;
7533     }
7534   if (! currently_expanding_to_rtl)
7535     FAIL;
7536   operands[1] = prepare_scc_operands (LT);
7539 (define_expand "sle"
7540   [(match_operand:SI 0 "arith_reg_operand" "")]
7541   ""
7542   "
7544   rtx tmp = sh_compare_op0;
7546   if (TARGET_SHMEDIA)
7547     {
7548       if (GET_MODE (operands[0]) != DImode)
7549         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7550       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7551       if (sh_compare_op1 != const0_rtx)
7552         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7553                                     ? GET_MODE (sh_compare_op0)
7554                                     : GET_MODE (sh_compare_op1),
7555                                     sh_compare_op1);
7557       switch (GET_MODE (sh_compare_op0))
7558         {
7559         case DImode:
7560           {
7561             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7563             emit_insn (gen_cmpgtdi_media (tmp,
7564                                           sh_compare_op0, sh_compare_op1));
7565             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7566             break;
7567           }
7569         case SFmode:
7570           if (! TARGET_SHMEDIA_FPU)
7571             FAIL;
7572           emit_insn (gen_cmpgesf_media (operands[0],
7573                                         sh_compare_op1, sh_compare_op0));
7574           break;
7576         case DFmode:
7577           if (! TARGET_SHMEDIA_FPU)
7578             FAIL;
7579           emit_insn (gen_cmpgedf_media (operands[0],
7580                                         sh_compare_op1, sh_compare_op0));
7581           break;
7583         default:
7584           FAIL;
7585         }
7586       DONE;
7587     }
7589   sh_compare_op0 = sh_compare_op1;
7590   sh_compare_op1 = tmp;
7591   emit_insn (gen_sge (operands[0]));
7592   DONE;
7595 (define_expand "sgt"
7596   [(set (match_operand:SI 0 "arith_reg_operand" "")
7597         (match_dup 1))]
7598   ""
7599   "
7601   if (TARGET_SHMEDIA)
7602     {
7603       if (GET_MODE (operands[0]) != DImode)
7604         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7605       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7606       if (sh_compare_op1 != const0_rtx)
7607         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7608                                     ? GET_MODE (sh_compare_op0)
7609                                     : GET_MODE (sh_compare_op1),
7610                                     sh_compare_op1);
7612       switch (GET_MODE (sh_compare_op0))
7613         {
7614         case DImode:
7615           emit_insn (gen_cmpgtdi_media (operands[0],
7616                                         sh_compare_op0, sh_compare_op1));
7617           break;
7619         case SFmode:
7620           if (! TARGET_SHMEDIA_FPU)
7621             FAIL;
7622           emit_insn (gen_cmpgtsf_media (operands[0],
7623                                         sh_compare_op0, sh_compare_op1));
7624           break;
7626         case DFmode:
7627           if (! TARGET_SHMEDIA_FPU)
7628             FAIL;
7629           emit_insn (gen_cmpgtdf_media (operands[0],
7630                                         sh_compare_op0, sh_compare_op1));
7631           break;
7633         default:
7634           FAIL;
7635         }
7636       DONE;
7637     }
7638   if (! currently_expanding_to_rtl)
7639     FAIL;
7640   operands[1] = prepare_scc_operands (GT);
7643 (define_expand "sge"
7644   [(set (match_operand:SI 0 "arith_reg_operand" "")
7645         (match_dup 1))]
7646   ""
7647   "
7649   if (TARGET_SHMEDIA)
7650     {
7651       if (GET_MODE (operands[0]) != DImode)
7652         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7653       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7654       if (sh_compare_op1 != const0_rtx)
7655         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7656                                     ? GET_MODE (sh_compare_op0)
7657                                     : GET_MODE (sh_compare_op1),
7658                                     sh_compare_op1);
7660       switch (GET_MODE (sh_compare_op0))
7661         {
7662         case DImode:
7663           {
7664             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7666             emit_insn (gen_cmpgtdi_media (tmp,
7667                                           sh_compare_op1, sh_compare_op0));
7668             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7669             break;
7670           }
7672         case SFmode:
7673           if (! TARGET_SHMEDIA_FPU)
7674             FAIL;
7675           emit_insn (gen_cmpgesf_media (operands[0],
7676                                         sh_compare_op0, sh_compare_op1));
7677           break;
7679         case DFmode:
7680           if (! TARGET_SHMEDIA_FPU)
7681             FAIL;
7682           emit_insn (gen_cmpgedf_media (operands[0],
7683                                         sh_compare_op0, sh_compare_op1));
7684           break;
7686         default:
7687           FAIL;
7688         }
7689       DONE;
7690     }
7692   if (! currently_expanding_to_rtl)
7693     FAIL;
7694   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7695     {
7696       if (TARGET_IEEE)
7697         {
7698           rtx lab = gen_label_rtx ();
7699           prepare_scc_operands (EQ);
7700           emit_jump_insn (gen_branch_true (lab));
7701           prepare_scc_operands (GT);
7702           emit_label (lab);
7703           emit_insn (gen_movt (operands[0]));
7704         }
7705       else
7706         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7707       DONE;
7708     }
7709   operands[1] = prepare_scc_operands (GE);
7712 (define_expand "sgtu"
7713   [(set (match_operand:SI 0 "arith_reg_operand" "")
7714         (match_dup 1))]
7715   ""
7716   "
7718   if (TARGET_SHMEDIA)
7719     {
7720       if (GET_MODE (operands[0]) != DImode)
7721         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7722       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7723       if (sh_compare_op1 != const0_rtx)
7724         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7725                                     ? GET_MODE (sh_compare_op0)
7726                                     : GET_MODE (sh_compare_op1),
7727                                     sh_compare_op1);
7729       emit_insn (gen_cmpgtudi_media (operands[0],
7730                                      sh_compare_op0, sh_compare_op1));
7731       DONE;
7732     }
7733   if (! currently_expanding_to_rtl)
7734     FAIL;
7735   operands[1] = prepare_scc_operands (GTU);
7738 (define_expand "sltu"
7739   [(set (match_operand:SI 0 "arith_reg_operand" "")
7740         (match_dup 1))]
7741   ""
7742   "
7744   if (TARGET_SHMEDIA)
7745     {
7746       if (GET_MODE (operands[0]) != DImode)
7747         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7748       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7749       if (sh_compare_op1 != const0_rtx)
7750         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7751                                     ? GET_MODE (sh_compare_op0)
7752                                     : GET_MODE (sh_compare_op1),
7753                                     sh_compare_op1);
7755       emit_insn (gen_cmpgtudi_media (operands[0],
7756                                      sh_compare_op1, sh_compare_op0));
7757       DONE;
7758     }
7759   if (! currently_expanding_to_rtl)
7760     FAIL;
7761   operands[1] = prepare_scc_operands (LTU);
7764 (define_expand "sleu"
7765   [(set (match_operand:SI 0 "arith_reg_operand" "")
7766         (match_dup 1))]
7767   ""
7768   "
7770   if (TARGET_SHMEDIA)
7771     {
7772       rtx tmp;
7774       if (GET_MODE (operands[0]) != DImode)
7775         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7776       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7777       if (sh_compare_op1 != const0_rtx)
7778         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7779                                     ? GET_MODE (sh_compare_op0)
7780                                     : GET_MODE (sh_compare_op1),
7781                                     sh_compare_op1);
7783       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7785       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7786       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7788       DONE;
7789     }
7790   if (! currently_expanding_to_rtl)
7791     FAIL;
7792   operands[1] = prepare_scc_operands (LEU);
7795 (define_expand "sgeu"
7796   [(set (match_operand:SI 0 "arith_reg_operand" "")
7797         (match_dup 1))]
7798   ""
7799   "
7801   if (TARGET_SHMEDIA)
7802     {
7803       rtx tmp;
7805       if (GET_MODE (operands[0]) != DImode)
7806         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7807       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7808       if (sh_compare_op1 != const0_rtx)
7809         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7810                                     ? GET_MODE (sh_compare_op0)
7811                                     : GET_MODE (sh_compare_op1),
7812                                     sh_compare_op1);
7814       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7816       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7817       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7819       DONE;
7820     }
7822   if (! currently_expanding_to_rtl)
7823     FAIL;
7824   operands[1] = prepare_scc_operands (GEU);
7827 ;; sne moves the complement of the T reg to DEST like this:
7828 ;;      cmp/eq ...
7829 ;;      mov    #-1,temp
7830 ;;      negc   temp,dest
7831 ;;   This is better than xoring compare result with 1 because it does
7832 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7833 ;;   loop.
7835 (define_expand "sne"
7836   [(set (match_dup 2) (const_int -1))
7837    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7838                    (neg:SI (plus:SI (match_dup 1)
7839                                     (match_dup 2))))
7840               (set (reg:SI T_REG)
7841                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7842                           (const_int 0)))])]
7843   ""
7844   "
7846   if (TARGET_SHMEDIA)
7847     {
7848       rtx tmp;
7850       if (GET_MODE (operands[0]) != DImode)
7851         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7853       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7854         FAIL;
7856       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7857       if (sh_compare_op1 != const0_rtx)
7858         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7859                                     ? GET_MODE (sh_compare_op0)
7860                                     : GET_MODE (sh_compare_op1),
7861                                     sh_compare_op1);
7863       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7865       emit_insn (gen_seq (tmp));
7866       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7868       DONE;
7869     }
7871   if (sh_expand_t_scc (NE, operands[0]))
7872     DONE;
7873   if (! currently_expanding_to_rtl)
7874     FAIL;
7875   operands[1] = prepare_scc_operands (EQ);
7876   operands[2] = gen_reg_rtx (SImode);
7879 (define_expand "sunordered"
7880   [(set (match_operand:DI 0 "arith_reg_operand" "")
7881         (unordered:DI (match_dup 1) (match_dup 2)))]
7882   "TARGET_SHMEDIA_FPU"
7883   "
7885   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7886   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7889 ;; Use the same trick for FP sle / sge
7890 (define_expand "movnegt"
7891   [(set (match_dup 2) (const_int -1))
7892    (parallel [(set (match_operand 0 "" "")
7893                    (neg:SI (plus:SI (match_dup 1)
7894                                     (match_dup 2))))
7895               (set (reg:SI T_REG)
7896                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7897                           (const_int 0)))])]
7898   "TARGET_SH1"
7899   "operands[2] = gen_reg_rtx (SImode);")
7901 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7902 ;; This prevents a regression that occurred when we switched from xor to
7903 ;; mov/neg for sne.
7905 (define_split
7906   [(set (match_operand:SI 0 "arith_reg_operand" "")
7907         (plus:SI (reg:SI T_REG)
7908                  (const_int -1)))]
7909   "TARGET_SH1"
7910   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7911    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7912   "")
7914 ;; -------------------------------------------------------------------------
7915 ;; Instructions to cope with inline literal tables
7916 ;; -------------------------------------------------------------------------
7918 ; 2 byte integer in line
7920 (define_insn "consttable_2"
7921  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7922                     (match_operand 1 "" "")]
7923                    UNSPECV_CONST2)]
7924  ""
7925  "*
7927   if (operands[1] != const0_rtx)
7928     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7929   return \"\";
7931  [(set_attr "length" "2")
7932  (set_attr "in_delay_slot" "no")])
7934 ; 4 byte integer in line
7936 (define_insn "consttable_4"
7937  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7938                     (match_operand 1 "" "")]
7939                    UNSPECV_CONST4)]
7940  ""
7941  "*
7943   if (operands[1] != const0_rtx)
7944     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7945   return \"\";
7947  [(set_attr "length" "4")
7948   (set_attr "in_delay_slot" "no")])
7950 ; 8 byte integer in line
7952 (define_insn "consttable_8"
7953  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7954                     (match_operand 1 "" "")]
7955                    UNSPECV_CONST8)]
7956  ""
7957  "*
7959   if (operands[1] != const0_rtx)
7960     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7961   return \"\";
7963  [(set_attr "length" "8")
7964   (set_attr "in_delay_slot" "no")])
7966 ; 4 byte floating point
7968 (define_insn "consttable_sf"
7969  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7970                     (match_operand 1 "" "")]
7971                    UNSPECV_CONST4)]
7972  ""
7973  "*
7975   if (operands[1] != const0_rtx)
7976     {
7977       REAL_VALUE_TYPE d;
7978       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7979       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7980     }
7981   return \"\";
7983  [(set_attr "length" "4")
7984   (set_attr "in_delay_slot" "no")])
7986 ; 8 byte floating point
7988 (define_insn "consttable_df"
7989  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7990                     (match_operand 1 "" "")]
7991                    UNSPECV_CONST8)]
7992  ""
7993  "*
7995   if (operands[1] != const0_rtx)
7996     {
7997       REAL_VALUE_TYPE d;
7998       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7999       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
8000     }
8001   return \"\";
8003  [(set_attr "length" "8")
8004   (set_attr "in_delay_slot" "no")])
8006 ;; Alignment is needed for some constant tables; it may also be added for
8007 ;; Instructions at the start of loops, or after unconditional branches.
8008 ;; ??? We would get more accurate lengths if we did instruction
8009 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8010 ;; here is too conservative.
8012 ; align to a two byte boundary
8014 (define_expand "align_2"
8015  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8016  ""
8017  "")
8019 ; align to a four byte boundary
8020 ;; align_4 and align_log are instructions for the starts of loops, or
8021 ;; after unconditional branches, which may take up extra room.
8023 (define_expand "align_4"
8024  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8025  ""
8026  "")
8028 ; align to a cache line boundary
8030 (define_insn "align_log"
8031  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8032  ""
8033  ""
8034  [(set_attr "length" "0")
8035   (set_attr "in_delay_slot" "no")])
8037 ; emitted at the end of the literal table, used to emit the
8038 ; 32bit branch labels if needed.
8040 (define_insn "consttable_end"
8041   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8042   ""
8043   "* return output_jump_label_table ();"
8044   [(set_attr "in_delay_slot" "no")])
8046 ; emitted at the end of the window in the literal table.
8048 (define_insn "consttable_window_end"
8049   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8050   ""
8051   ""
8052   [(set_attr "length" "0")
8053    (set_attr "in_delay_slot" "no")])
8055 ;; -------------------------------------------------------------------------
8056 ;; Misc
8057 ;; -------------------------------------------------------------------------
8059 ;; String/block move insn.
8061 (define_expand "movmemsi"
8062   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8063                    (mem:BLK (match_operand:BLK 1 "" "")))
8064               (use (match_operand:SI 2 "nonmemory_operand" ""))
8065               (use (match_operand:SI 3 "immediate_operand" ""))
8066               (clobber (reg:SI PR_REG))
8067               (clobber (reg:SI R4_REG))
8068               (clobber (reg:SI R5_REG))
8069               (clobber (reg:SI R0_REG))])]
8070   "TARGET_SH1 && ! TARGET_SH5"
8071   "
8073   if(expand_block_move (operands))
8074      DONE;
8075   else FAIL;
8078 (define_insn "block_move_real"
8079   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8080                    (mem:BLK (reg:SI R5_REG)))
8081               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8082               (clobber (reg:SI PR_REG))
8083               (clobber (reg:SI R0_REG))])]
8084   "TARGET_SH1 && ! TARGET_HARD_SH4"
8085   "jsr  @%0%#"
8086   [(set_attr "type" "sfunc")
8087    (set_attr "needs_delay_slot" "yes")])
8089 (define_insn "block_lump_real"
8090   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8091                    (mem:BLK (reg:SI R5_REG)))
8092               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8093               (use (reg:SI R6_REG))
8094               (clobber (reg:SI PR_REG))
8095               (clobber (reg:SI T_REG))
8096               (clobber (reg:SI R4_REG))
8097               (clobber (reg:SI R5_REG))
8098               (clobber (reg:SI R6_REG))
8099               (clobber (reg:SI R0_REG))])]
8100   "TARGET_SH1 && ! TARGET_HARD_SH4"
8101   "jsr  @%0%#"
8102   [(set_attr "type" "sfunc")
8103    (set_attr "needs_delay_slot" "yes")])
8105 (define_insn "block_move_real_i4"
8106   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8107                    (mem:BLK (reg:SI R5_REG)))
8108               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8109               (clobber (reg:SI PR_REG))
8110               (clobber (reg:SI R0_REG))
8111               (clobber (reg:SI R1_REG))
8112               (clobber (reg:SI R2_REG))])]
8113   "TARGET_HARD_SH4"
8114   "jsr  @%0%#"
8115   [(set_attr "type" "sfunc")
8116    (set_attr "needs_delay_slot" "yes")])
8118 (define_insn "block_lump_real_i4"
8119   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8120                    (mem:BLK (reg:SI R5_REG)))
8121               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8122               (use (reg:SI R6_REG))
8123               (clobber (reg:SI PR_REG))
8124               (clobber (reg:SI T_REG))
8125               (clobber (reg:SI R4_REG))
8126               (clobber (reg:SI R5_REG))
8127               (clobber (reg:SI R6_REG))
8128               (clobber (reg:SI R0_REG))
8129               (clobber (reg:SI R1_REG))
8130               (clobber (reg:SI R2_REG))
8131               (clobber (reg:SI R3_REG))])]
8132   "TARGET_HARD_SH4"
8133   "jsr  @%0%#"
8134   [(set_attr "type" "sfunc")
8135    (set_attr "needs_delay_slot" "yes")])
8137 ;; -------------------------------------------------------------------------
8138 ;; Floating point instructions.
8139 ;; -------------------------------------------------------------------------
8141 ;; ??? All patterns should have a type attribute.
8143 (define_expand "fpu_switch0"
8144   [(set (match_operand:SI 0 "" "") (match_dup 2))
8145    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8146   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8147   "
8149   operands[1] = get_fpscr_rtx ();
8150   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8151   if (flag_pic)
8152     operands[2] = legitimize_pic_address (operands[2], SImode,
8153                                           no_new_pseudos ? operands[0] : 0);
8156 (define_expand "fpu_switch1"
8157   [(set (match_operand:SI 0 "" "") (match_dup 2))
8158    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8159    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8160   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8161   "
8163   operands[1] = get_fpscr_rtx ();
8164   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8165   if (flag_pic)
8166     operands[2] = legitimize_pic_address (operands[2], SImode,
8167                                           no_new_pseudos ? operands[0] : 0);
8168   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8171 (define_expand "movpsi"
8172   [(set (match_operand:PSI 0 "register_operand" "")
8173         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8174   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8175   "")
8177 ;; The c / m alternative is a fake to guide reload to load directly into
8178 ;; fpscr, since reload doesn't know how to use post-increment.
8179 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8180 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8181 ;; predicate after reload.
8182 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8183 ;; like a mac -> gpr move.
8184 (define_insn "fpu_switch"
8185   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8186         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8187   "TARGET_SH2E
8188    && (! reload_completed
8189        || true_regnum (operands[0]) != FPSCR_REG
8190        || GET_CODE (operands[1]) != MEM
8191        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8192   "@
8193         ! precision stays the same
8194         lds.l   %1,fpscr
8195         mov.l   %1,%0
8196         #
8197         lds     %1,fpscr
8198         mov     %1,%0
8199         mov.l   %1,%0
8200         sts     fpscr,%0
8201         sts.l   fpscr,%0"
8202   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8203    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8205 (define_split
8206   [(set (reg:PSI FPSCR_REG)
8207         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8208   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8209   [(set (match_dup 0) (match_dup 0))]
8210   "
8212   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8213                                         gen_rtx_MEM (PSImode,
8214                                                  gen_rtx_POST_INC (Pmode,
8215                                                           operands[0]))));
8216   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8219 (define_split
8220   [(set (reg:PSI FPSCR_REG)
8221         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8222   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8223   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8224   "
8226   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8227                                         gen_rtx_MEM (PSImode,
8228                                                  gen_rtx_POST_INC (Pmode,
8229                                                           operands[0]))));
8230   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8233 ;; ??? This uses the fp unit, but has no type indicating that.
8234 ;; If we did that, this would either give a bogus latency or introduce
8235 ;; a bogus FIFO constraint.
8236 ;; Since this insn is currently only used for prologues/epilogues,
8237 ;; it is probably best to claim no function unit, which matches the
8238 ;; current setting.
8239 (define_insn "toggle_sz"
8240   [(set (reg:PSI FPSCR_REG)
8241         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8242   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8243   "fschg"
8244   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8246 ;; There's no way we can use it today, since optimize mode switching
8247 ;; doesn't enable us to know from which mode we're switching to the
8248 ;; mode it requests, to tell whether we can use a relative mode switch
8249 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8250 ;; memory).
8251 (define_insn "toggle_pr"
8252   [(set (reg:PSI FPSCR_REG)
8253         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8254   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8255   "fpchg"
8256   [(set_attr "type" "fp")])
8258 (define_expand "addsf3"
8259   [(set (match_operand:SF 0 "arith_reg_operand" "")
8260         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8261                  (match_operand:SF 2 "arith_reg_operand" "")))]
8262   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8263   "
8265   if (TARGET_SH2E)
8266     {
8267       expand_sf_binop (&gen_addsf3_i, operands);
8268       DONE;
8269     }
8272 (define_insn "*addsf3_media"
8273   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8274         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8275                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8276   "TARGET_SHMEDIA_FPU"
8277   "fadd.s       %1, %2, %0"
8278   [(set_attr "type" "fparith_media")])
8280 (define_insn_and_split "unary_sf_op"
8281   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8282         (vec_select:V2SF
8283          (vec_concat:V2SF
8284           (vec_select:SF
8285            (match_dup 0)
8286            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8287           (match_operator:SF 2 "unary_float_operator"
8288             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8289                             (parallel [(match_operand 4
8290                                         "const_int_operand" "n")]))]))
8291          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8292   "TARGET_SHMEDIA_FPU"
8293   "#"
8294   "TARGET_SHMEDIA_FPU && reload_completed"
8295   [(set (match_dup 5) (match_dup 6))]
8296   "
8298   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8299   rtx op1 = gen_rtx_REG (SFmode,
8300                          (true_regnum (operands[1])
8301                           + (INTVAL (operands[4]) ^ endian)));
8303   operands[7] = gen_rtx_REG (SFmode,
8304                              (true_regnum (operands[0])
8305                               + (INTVAL (operands[3]) ^ endian)));
8306   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8308   [(set_attr "type" "fparith_media")])
8310 (define_insn_and_split "binary_sf_op"
8311   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8312         (vec_select:V2SF
8313          (vec_concat:V2SF
8314           (vec_select:SF
8315            (match_dup 0)
8316            (parallel [(match_operand 7 "const_int_operand" "n")]))
8317           (match_operator:SF 3 "binary_float_operator"
8318             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8319                             (parallel [(match_operand 5
8320                                         "const_int_operand" "n")]))
8321              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8322                             (parallel [(match_operand 6
8323                                         "const_int_operand" "n")]))]))
8324          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8325   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8326   "#"
8327   "&& reload_completed"
8328   [(set (match_dup 8) (match_dup 9))]
8329   "
8331   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8332   rtx op1 = gen_rtx_REG (SFmode,
8333                          (true_regnum (operands[1])
8334                           + (INTVAL (operands[5]) ^ endian)));
8335   rtx op2 = gen_rtx_REG (SFmode,
8336                          (true_regnum (operands[2])
8337                           + (INTVAL (operands[6]) ^ endian)));
8339   operands[8] = gen_rtx_REG (SFmode,
8340                              (true_regnum (operands[0])
8341                               + (INTVAL (operands[4]) ^ endian)));
8342   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8344   [(set_attr "type" "fparith_media")])
8346 (define_insn "addsf3_i"
8347   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8348         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8349                  (match_operand:SF 2 "arith_reg_operand" "f")))
8350    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8351   "TARGET_SH2E"
8352   "fadd %2,%0"
8353   [(set_attr "type" "fp")
8354    (set_attr "fp_mode" "single")])
8356 (define_expand "subsf3"
8357   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8358         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8359                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8360   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8361   "
8363   if (TARGET_SH2E)
8364     {
8365       expand_sf_binop (&gen_subsf3_i, operands);
8366       DONE;
8367     }
8370 (define_insn "*subsf3_media"
8371   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8372         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8373                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8374   "TARGET_SHMEDIA_FPU"
8375   "fsub.s       %1, %2, %0"
8376   [(set_attr "type" "fparith_media")])
8378 (define_insn "subsf3_i"
8379   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8380         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8381                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8382    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8383   "TARGET_SH2E"
8384   "fsub %2,%0"
8385   [(set_attr "type" "fp")
8386    (set_attr "fp_mode" "single")])
8388 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8389 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8390 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8391 ;; SH3E, we use a separate insn for SH3E mulsf3.
8393 (define_expand "mulsf3"
8394   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8395         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8396                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8397   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8398   "
8400   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8401     expand_sf_binop (&gen_mulsf3_i4, operands);
8402   else if (TARGET_SH2E)
8403     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8404   if (! TARGET_SHMEDIA)
8405     DONE;
8408 (define_insn "*mulsf3_media"
8409   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8410         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8411                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8412   "TARGET_SHMEDIA_FPU"
8413   "fmul.s       %1, %2, %0"
8414   [(set_attr "type" "fparith_media")])
8416 (define_insn "mulsf3_i4"
8417   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8418         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8419                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8420    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8421   "TARGET_SH2E"
8422   "fmul %2,%0"
8423   [(set_attr "type" "fp")
8424    (set_attr "fp_mode" "single")])
8426 (define_insn "mulsf3_ie"
8427   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8428         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8429                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8430   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8431   "fmul %2,%0"
8432   [(set_attr "type" "fp")])
8434 (define_insn "*mac_media"
8435   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8436         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8437                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8438                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8439   "TARGET_SHMEDIA_FPU"
8440   "fmac.s %1, %2, %0"
8441   [(set_attr "type" "fparith_media")])
8443 (define_insn "*macsf3"
8444   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8445         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8446                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8447                  (match_operand:SF 3 "arith_reg_operand" "0")))
8448    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8449   "TARGET_SH2E && ! TARGET_SH4"
8450   "fmac fr0,%2,%0"
8451   [(set_attr "type" "fp")
8452    (set_attr "fp_mode" "single")])
8454 (define_expand "divsf3"
8455   [(set (match_operand:SF 0 "arith_reg_operand" "")
8456         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8457                 (match_operand:SF 2 "arith_reg_operand" "")))]
8458   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8459   "
8461   if (TARGET_SH2E)
8462     {
8463       expand_sf_binop (&gen_divsf3_i, operands);
8464       DONE;
8465     }
8468 (define_insn "*divsf3_media"
8469   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8470         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8471                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8472   "TARGET_SHMEDIA_FPU"
8473   "fdiv.s       %1, %2, %0"
8474   [(set_attr "type" "fdiv_media")])
8476 (define_insn "divsf3_i"
8477   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8478         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8479                  (match_operand:SF 2 "arith_reg_operand" "f")))
8480    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8481   "TARGET_SH2E"
8482   "fdiv %2,%0"
8483   [(set_attr "type" "fdiv")
8484    (set_attr "fp_mode" "single")])
8486 (define_insn "floatdisf2"
8487   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8488         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8489   "TARGET_SHMEDIA_FPU"
8490   "float.qs %1, %0"
8491   [(set_attr "type" "fpconv_media")])
8493 (define_expand "floatsisf2"
8494   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8495         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8496   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8497   "
8499   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8500     {
8501       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8502       DONE;
8503     }
8506 (define_insn "*floatsisf2_media"
8507   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8508         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8509   "TARGET_SHMEDIA_FPU"
8510   "float.ls     %1, %0"
8511   [(set_attr "type" "fpconv_media")])
8513 (define_insn "floatsisf2_i4"
8514   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8515         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8516    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8517   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8518   "float        %1,%0"
8519   [(set_attr "type" "fp")
8520    (set_attr "fp_mode" "single")])
8522 (define_insn "*floatsisf2_ie"
8523   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8524         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8525   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8526   "float        %1,%0"
8527   [(set_attr "type" "fp")])
8529 (define_insn "fix_truncsfdi2"
8530   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8531         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8532   "TARGET_SHMEDIA_FPU"
8533   "ftrc.sq %1, %0"
8534   [(set_attr "type" "fpconv_media")])
8536 (define_expand "fix_truncsfsi2"
8537   [(set (match_operand:SI 0 "fpul_operand" "=y")
8538         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8539   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8540   "
8542   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
8543     {
8544       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8545       DONE;
8546     }
8549 (define_insn "*fix_truncsfsi2_media"
8550   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8551         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8552   "TARGET_SHMEDIA_FPU"
8553   "ftrc.sl      %1, %0"
8554   [(set_attr "type" "fpconv_media")])
8556 (define_insn "fix_truncsfsi2_i4"
8557   [(set (match_operand:SI 0 "fpul_operand" "=y")
8558         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8559    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8560   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8561   "ftrc %1,%0"
8562   [(set_attr "type" "ftrc_s")
8563    (set_attr "fp_mode" "single")])
8565 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8566 ;; fix_truncsfsi2_i4.
8567 ;; (define_insn "fix_truncsfsi2_i4_2"
8568 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8569 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8570 ;;   (use (reg:PSI FPSCR_REG))
8571 ;;   (clobber (reg:SI FPUL_REG))]
8572 ;;  "TARGET_SH4"
8573 ;;  "#"
8574 ;;  [(set_attr "length" "4")
8575 ;;   (set_attr "fp_mode" "single")])
8577 ;;(define_split
8578 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8579 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8580 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8581 ;;   (clobber (reg:SI FPUL_REG))]
8582 ;;  "TARGET_SH4"
8583 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8584 ;;            (use (match_dup 2))])
8585 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8587 (define_insn "*fixsfsi"
8588   [(set (match_operand:SI 0 "fpul_operand" "=y")
8589         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8590   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8591   "ftrc %1,%0"
8592   [(set_attr "type" "fp")])
8594 (define_insn "cmpgtsf_t"
8595   [(set (reg:SI T_REG)
8596         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8597                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8598   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8599   "fcmp/gt      %1,%0"
8600   [(set_attr "type" "fp")
8601    (set_attr "fp_mode" "single")])
8603 (define_insn "cmpeqsf_t"
8604   [(set (reg:SI T_REG)
8605         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8606                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8607   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8608   "fcmp/eq      %1,%0"
8609   [(set_attr "type" "fp")
8610    (set_attr "fp_mode" "single")])
8612 (define_insn "ieee_ccmpeqsf_t"
8613   [(set (reg:SI T_REG)
8614         (ior:SI (reg:SI T_REG)
8615                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8616                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8617   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8618   "* return output_ieee_ccmpeq (insn, operands);"
8619   [(set_attr "length" "4")])
8622 (define_insn "cmpgtsf_t_i4"
8623   [(set (reg:SI T_REG)
8624         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8625                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8626    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8627   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8628   "fcmp/gt      %1,%0"
8629   [(set_attr "type" "fp")
8630    (set_attr "fp_mode" "single")])
8632 (define_insn "cmpeqsf_t_i4"
8633   [(set (reg:SI T_REG)
8634         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8635                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8636    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8637   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
8638   "fcmp/eq      %1,%0"
8639   [(set_attr "type" "fp")
8640    (set_attr "fp_mode" "single")])
8642 (define_insn "*ieee_ccmpeqsf_t_4"
8643   [(set (reg:SI T_REG)
8644         (ior:SI (reg:SI T_REG)
8645                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8646                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8647    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8648   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
8649   "* return output_ieee_ccmpeq (insn, operands);"
8650   [(set_attr "length" "4")
8651    (set_attr "fp_mode" "single")])
8653 (define_insn "cmpeqsf_media"
8654   [(set (match_operand:DI 0 "register_operand" "=r")
8655         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8656                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8657   "TARGET_SHMEDIA_FPU"
8658   "fcmpeq.s     %1, %2, %0"
8659   [(set_attr "type" "fcmp_media")])
8661 (define_insn "cmpgtsf_media"
8662   [(set (match_operand:DI 0 "register_operand" "=r")
8663         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8664                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8665   "TARGET_SHMEDIA_FPU"
8666   "fcmpgt.s     %1, %2, %0"
8667   [(set_attr "type" "fcmp_media")])
8669 (define_insn "cmpgesf_media"
8670   [(set (match_operand:DI 0 "register_operand" "=r")
8671         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8672                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8673   "TARGET_SHMEDIA_FPU"
8674   "fcmpge.s     %1, %2, %0"
8675   [(set_attr "type" "fcmp_media")])
8677 (define_insn "cmpunsf_media"
8678   [(set (match_operand:DI 0 "register_operand" "=r")
8679         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8680                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8681   "TARGET_SHMEDIA_FPU"
8682   "fcmpun.s     %1, %2, %0"
8683   [(set_attr "type" "fcmp_media")])
8685 (define_expand "cmpsf"
8686   [(set (reg:SI T_REG)
8687         (compare (match_operand:SF 0 "arith_operand" "")
8688                  (match_operand:SF 1 "arith_operand" "")))]
8689   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8690   "
8692   sh_compare_op0 = operands[0];
8693   sh_compare_op1 = operands[1];
8694   DONE;
8697 (define_expand "negsf2"
8698   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8699         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8700   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8701   "
8703   if (TARGET_SH2E)
8704     {
8705       expand_sf_unop (&gen_negsf2_i, operands);
8706       DONE;
8707     }
8710 (define_insn "*negsf2_media"
8711   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8712         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8713   "TARGET_SHMEDIA_FPU"
8714   "fneg.s       %1, %0"
8715   [(set_attr "type" "fmove_media")])
8717 (define_insn "negsf2_i"
8718   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8719         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8720    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8721   "TARGET_SH2E"
8722   "fneg %0"
8723   [(set_attr "type" "fmove")
8724    (set_attr "fp_mode" "single")])
8726 (define_expand "sqrtsf2"
8727   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8728         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8729   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8730   "
8732   if (TARGET_SH3E)
8733     {
8734       expand_sf_unop (&gen_sqrtsf2_i, operands);
8735       DONE;
8736     }
8739 (define_insn "*sqrtsf2_media"
8740   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8741         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8742   "TARGET_SHMEDIA_FPU"
8743   "fsqrt.s      %1, %0"
8744   [(set_attr "type" "fdiv_media")])
8746 (define_insn "sqrtsf2_i"
8747   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8748         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8749    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8750   "TARGET_SH3E"
8751   "fsqrt        %0"
8752   [(set_attr "type" "fdiv")
8753    (set_attr "fp_mode" "single")])
8755 (define_insn "rsqrtsf2"
8756   [(set (match_operand:SF 0 "register_operand" "=f")
8757         (div:SF (match_operand:SF 1 "immediate_operand" "i")
8758                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8759    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8760   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8761    && operands[1] == CONST1_RTX (SFmode)"
8762   "fsrra        %0"
8763   [(set_attr "type" "fsrra")
8764    (set_attr "fp_mode" "single")])
8766 (define_insn "fsca"
8767   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8768         (vec_concat:V2SF
8769          (unspec:SF [(mult:SF
8770                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8771                       (match_operand:SF 2 "immediate_operand" "i"))
8772                     ] UNSPEC_FSINA)
8773          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8774                     ] UNSPEC_FCOSA)))
8775    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8776   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8777    && operands[2] == sh_fsca_int2sf ()"
8778   "fsca fpul,%d0"
8779   [(set_attr "type" "fsca")
8780    (set_attr "fp_mode" "single")])
8782 (define_expand "sinsf2"
8783   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8784         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8785                    UNSPEC_FSINA))]
8786   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8787   "
8789   rtx scaled = gen_reg_rtx (SFmode);
8790   rtx truncated = gen_reg_rtx (SImode);
8791   rtx fsca = gen_reg_rtx (V2SFmode);
8792   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8794   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8795   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8796   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8797                           get_fpscr_rtx ()));
8798   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8799   DONE;
8802 (define_expand "cossf2"
8803   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8804         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8805                    UNSPEC_FCOSA))]
8806   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8807   "
8809   rtx scaled = gen_reg_rtx (SFmode);
8810   rtx truncated = gen_reg_rtx (SImode);
8811   rtx fsca = gen_reg_rtx (V2SFmode);
8812   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8814   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8815   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8816   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8817                           get_fpscr_rtx ()));
8818   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8819   DONE;
8822 (define_expand "sindf2"
8823   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8824         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8825                    UNSPEC_FSINA))]
8826   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8827   "
8829   rtx scaled = gen_reg_rtx (DFmode);
8830   rtx truncated = gen_reg_rtx (SImode);
8831   rtx fsca = gen_reg_rtx (V2SFmode);
8832   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8833   rtx sfresult = gen_reg_rtx (SFmode);
8835   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8836   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8837   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8838                           get_fpscr_rtx ()));
8839   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8840   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8841   DONE;
8844 (define_expand "cosdf2"
8845   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8846         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8847                    UNSPEC_FCOSA))]
8848   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8849   "
8851   rtx scaled = gen_reg_rtx (DFmode);
8852   rtx truncated = gen_reg_rtx (SImode);
8853   rtx fsca = gen_reg_rtx (V2SFmode);
8854   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8855   rtx sfresult = gen_reg_rtx (SFmode);
8857   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8858   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8859   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8860                           get_fpscr_rtx ()));
8861   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8862   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8863   DONE;
8866 (define_expand "abssf2"
8867   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8868         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8869   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8870   "
8872   if (TARGET_SH2E)
8873     {
8874       expand_sf_unop (&gen_abssf2_i, operands);
8875       DONE;
8876     }
8879 (define_insn "*abssf2_media"
8880   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8881         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8882   "TARGET_SHMEDIA_FPU"
8883   "fabs.s       %1, %0"
8884   [(set_attr "type" "fmove_media")])
8886 (define_insn "abssf2_i"
8887   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8888         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8889    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8890   "TARGET_SH2E"
8891   "fabs %0"
8892   [(set_attr "type" "fmove")
8893    (set_attr "fp_mode" "single")])
8895 (define_expand "adddf3"
8896   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8897         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8898                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8899   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8900   "
8902   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8903     {
8904       expand_df_binop (&gen_adddf3_i, operands);
8905       DONE;
8906     }
8909 (define_insn "*adddf3_media"
8910   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8911         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8912                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8913   "TARGET_SHMEDIA_FPU"
8914   "fadd.d       %1, %2, %0"
8915   [(set_attr "type" "dfparith_media")])
8917 (define_insn "adddf3_i"
8918   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8919         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8920                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8921    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8922   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8923   "fadd %2,%0"
8924   [(set_attr "type" "dfp_arith")
8925    (set_attr "fp_mode" "double")])
8927 (define_expand "subdf3"
8928   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8929         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8930                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8931   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8932   "
8934   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8935     {
8936       expand_df_binop (&gen_subdf3_i, operands);
8937       DONE;
8938     }
8941 (define_insn "*subdf3_media"
8942   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8943         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8944                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8945   "TARGET_SHMEDIA_FPU"
8946   "fsub.d       %1, %2, %0"
8947   [(set_attr "type" "dfparith_media")])
8949 (define_insn "subdf3_i"
8950   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8951         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8952                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8953    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8954   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8955   "fsub %2,%0"
8956   [(set_attr "type" "dfp_arith")
8957    (set_attr "fp_mode" "double")])
8959 (define_expand "muldf3"
8960   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8961         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8962                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8963   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8964   "
8966   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8967     {
8968       expand_df_binop (&gen_muldf3_i, operands);
8969       DONE;
8970     }
8973 (define_insn "*muldf3_media"
8974   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8975         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8976                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8977   "TARGET_SHMEDIA_FPU"
8978   "fmul.d       %1, %2, %0"
8979   [(set_attr "type" "dfmul_media")])
8981 (define_insn "muldf3_i"
8982   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8983         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8984                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8985    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8986   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
8987   "fmul %2,%0"
8988   [(set_attr "type" "dfp_arith")
8989    (set_attr "fp_mode" "double")])
8991 (define_expand "divdf3"
8992   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8993         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8994                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8995   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
8996   "
8998   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
8999     {
9000       expand_df_binop (&gen_divdf3_i, operands);
9001       DONE;
9002     }
9005 (define_insn "*divdf3_media"
9006   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9007         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
9008                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9009   "TARGET_SHMEDIA_FPU"
9010   "fdiv.d       %1, %2, %0"
9011   [(set_attr "type" "dfdiv_media")])
9013 (define_insn "divdf3_i"
9014   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9015         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
9016                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
9017    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9018   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9019   "fdiv %2,%0"
9020   [(set_attr "type" "dfdiv")
9021    (set_attr "fp_mode" "double")])
9023 (define_insn "floatdidf2"
9024   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9025         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
9026   "TARGET_SHMEDIA_FPU"
9027   "float.qd     %1, %0"
9028   [(set_attr "type" "dfpconv_media")])
9030 (define_expand "floatsidf2"
9031   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9032         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
9033   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9034   "
9036   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9037     {
9038       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
9039                                       get_fpscr_rtx ()));
9040       DONE;
9041     }
9044 (define_insn "*floatsidf2_media"
9045   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9046         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
9047   "TARGET_SHMEDIA_FPU"
9048   "float.ld     %1, %0"
9049   [(set_attr "type" "dfpconv_media")])
9051 (define_insn "floatsidf2_i"
9052   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9053         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
9054    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9055   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9056   "float        %1,%0"
9057   [(set_attr "type" "dfp_conv")
9058    (set_attr "fp_mode" "double")])
9060 (define_insn "fix_truncdfdi2"
9061   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
9062         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9063   "TARGET_SHMEDIA_FPU"
9064   "ftrc.dq      %1, %0"
9065   [(set_attr "type" "dfpconv_media")])
9067 (define_expand "fix_truncdfsi2"
9068   [(set (match_operand:SI 0 "fpul_operand" "")
9069         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9070   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9071   "
9073   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9074     {
9075       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9076                                           get_fpscr_rtx ()));
9077       DONE;
9078     }
9081 (define_insn "*fix_truncdfsi2_media"
9082   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9083         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9084   "TARGET_SHMEDIA_FPU"
9085   "ftrc.dl      %1, %0"
9086   [(set_attr "type" "dfpconv_media")])
9088 (define_insn "fix_truncdfsi2_i"
9089   [(set (match_operand:SI 0 "fpul_operand" "=y")
9090         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9091    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9092   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9093   "ftrc %1,%0"
9094   [(set_attr "type" "dfp_conv")
9095    (set_attr "dfp_comp" "no")
9096    (set_attr "fp_mode" "double")])
9098 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
9099 ;; fix_truncdfsi2_i.
9100 ;; (define_insn "fix_truncdfsi2_i4"
9101 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9102 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9103 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9104 ;;    (clobber (reg:SI FPUL_REG))]
9105 ;;   "TARGET_SH4"
9106 ;;   "#"
9107 ;;   [(set_attr "length" "4")
9108 ;;    (set_attr "fp_mode" "double")])
9110 ;; (define_split
9111 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9112 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9113 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9114 ;;    (clobber (reg:SI FPUL_REG))]
9115 ;;   "TARGET_SH4"
9116 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9117 ;;            (use (match_dup 2))])
9118 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
9120 (define_insn "cmpgtdf_t"
9121   [(set (reg:SI T_REG)
9122         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9123                (match_operand:DF 1 "arith_reg_operand" "f")))
9124    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9125   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9126   "fcmp/gt      %1,%0"
9127   [(set_attr "type" "dfp_cmp")
9128    (set_attr "fp_mode" "double")])
9130 (define_insn "cmpeqdf_t"
9131   [(set (reg:SI T_REG)
9132         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9133                (match_operand:DF 1 "arith_reg_operand" "f")))
9134    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9135   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9136   "fcmp/eq      %1,%0"
9137   [(set_attr "type" "dfp_cmp")
9138    (set_attr "fp_mode" "double")])
9140 (define_insn "*ieee_ccmpeqdf_t"
9141   [(set (reg:SI T_REG)
9142         (ior:SI (reg:SI T_REG)
9143                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9144                        (match_operand:DF 1 "arith_reg_operand" "f"))))
9145    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9146   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9147   "* return output_ieee_ccmpeq (insn, operands);"
9148   [(set_attr "length" "4")
9149    (set_attr "fp_mode" "double")])
9151 (define_insn "cmpeqdf_media"
9152   [(set (match_operand:DI 0 "register_operand" "=r")
9153         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9154                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9155   "TARGET_SHMEDIA_FPU"
9156   "fcmpeq.d     %1,%2,%0"
9157   [(set_attr "type" "fcmp_media")])
9159 (define_insn "cmpgtdf_media"
9160   [(set (match_operand:DI 0 "register_operand" "=r")
9161         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9162                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9163   "TARGET_SHMEDIA_FPU"
9164   "fcmpgt.d     %1,%2,%0"
9165   [(set_attr "type" "fcmp_media")])
9167 (define_insn "cmpgedf_media"
9168   [(set (match_operand:DI 0 "register_operand" "=r")
9169         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9170                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9171   "TARGET_SHMEDIA_FPU"
9172   "fcmpge.d     %1,%2,%0"
9173   [(set_attr "type" "fcmp_media")])
9175 (define_insn "cmpundf_media"
9176   [(set (match_operand:DI 0 "register_operand" "=r")
9177         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9178                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9179   "TARGET_SHMEDIA_FPU"
9180   "fcmpun.d     %1,%2,%0"
9181   [(set_attr "type" "fcmp_media")])
9183 (define_expand "cmpdf"
9184   [(set (reg:SI T_REG)
9185         (compare (match_operand:DF 0 "arith_operand" "")
9186                  (match_operand:DF 1 "arith_operand" "")))]
9187   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9188   "
9190   sh_compare_op0 = operands[0];
9191   sh_compare_op1 = operands[1];
9192   DONE;
9195 (define_expand "negdf2"
9196   [(set (match_operand:DF 0 "arith_reg_operand" "")
9197         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9198   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9199   "
9201   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9202     {
9203       expand_df_unop (&gen_negdf2_i, operands);
9204       DONE;
9205     }
9208 (define_insn "*negdf2_media"
9209   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9210         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9211   "TARGET_SHMEDIA_FPU"
9212   "fneg.d       %1, %0"
9213   [(set_attr "type" "fmove_media")])
9215 (define_insn "negdf2_i"
9216   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9217         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9218    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9219   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9220   "fneg %0"
9221   [(set_attr "type" "fmove")
9222    (set_attr "fp_mode" "double")])
9224 (define_expand "sqrtdf2"
9225   [(set (match_operand:DF 0 "arith_reg_operand" "")
9226         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9227   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9228   "
9230   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9231     {
9232       expand_df_unop (&gen_sqrtdf2_i, operands);
9233       DONE;
9234     }
9237 (define_insn "*sqrtdf2_media"
9238   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9239         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9240   "TARGET_SHMEDIA_FPU"
9241   "fsqrt.d      %1, %0"
9242   [(set_attr "type" "dfdiv_media")])
9244 (define_insn "sqrtdf2_i"
9245   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9246         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9247    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9248   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9249   "fsqrt        %0"
9250   [(set_attr "type" "dfdiv")
9251    (set_attr "fp_mode" "double")])
9253 (define_expand "absdf2"
9254   [(set (match_operand:DF 0 "arith_reg_operand" "")
9255         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9256   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9257   "
9259   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9260     {
9261       expand_df_unop (&gen_absdf2_i, operands);
9262       DONE;
9263     }
9266 (define_insn "*absdf2_media"
9267   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9268         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9269   "TARGET_SHMEDIA_FPU"
9270   "fabs.d       %1, %0"
9271   [(set_attr "type" "fmove_media")])
9273 (define_insn "absdf2_i"
9274   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9275         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9276    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9277   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9278   "fabs %0"
9279   [(set_attr "type" "fmove")
9280    (set_attr "fp_mode" "double")])
9282 (define_expand "extendsfdf2"
9283   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9284         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9285   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9286   "
9288   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9289     {
9290       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9291                                         get_fpscr_rtx ()));
9292       DONE;
9293     }
9296 (define_insn "*extendsfdf2_media"
9297   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9298         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9299   "TARGET_SHMEDIA_FPU"
9300   "fcnv.sd      %1, %0"
9301   [(set_attr "type" "dfpconv_media")])
9303 (define_insn "extendsfdf2_i4"
9304   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9305         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9306    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9307   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9308   "fcnvsd  %1,%0"
9309   [(set_attr "type" "fp")
9310    (set_attr "fp_mode" "double")])
9312 (define_expand "truncdfsf2"
9313   [(set (match_operand:SF 0 "fpul_operand" "")
9314         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9315   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9316   "
9318   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
9319     {
9320       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9321                                        get_fpscr_rtx ()));
9322       DONE;
9323     }
9326 (define_insn "*truncdfsf2_media"
9327   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9328         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9329   "TARGET_SHMEDIA_FPU"
9330   "fcnv.ds      %1, %0"
9331   [(set_attr "type" "dfpconv_media")])
9333 (define_insn "truncdfsf2_i4"
9334   [(set (match_operand:SF 0 "fpul_operand" "=y")
9335         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9336    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9337   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9338   "fcnvds  %1,%0"
9339   [(set_attr "type" "fp")
9340    (set_attr "fp_mode" "double")])
9342 ;; Bit field extract patterns.  These give better code for packed bitfields,
9343 ;; because they allow auto-increment addresses to be generated.
9345 (define_expand "insv"
9346   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9347                          (match_operand:SI 1 "immediate_operand" "")
9348                          (match_operand:SI 2 "immediate_operand" ""))
9349         (match_operand:SI 3 "general_operand" ""))]
9350   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9351   "
9353   rtx addr_target, orig_address, shift_reg, qi_val;
9354   HOST_WIDE_INT bitsize, size, v = 0;
9355   rtx x = operands[3];
9357   /* ??? expmed doesn't care for non-register predicates.  */
9358   if (! memory_operand (operands[0], VOIDmode)
9359       || ! immediate_operand (operands[1], VOIDmode)
9360       || ! immediate_operand (operands[2], VOIDmode)
9361       || ! general_operand (x, VOIDmode))
9362     FAIL;
9363   /* If this isn't a 16 / 24 / 32 bit field, or if
9364      it doesn't start on a byte boundary, then fail.  */
9365   bitsize = INTVAL (operands[1]);
9366   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9367       || (INTVAL (operands[2]) % 8) != 0)
9368     FAIL;
9370   size = bitsize / 8;
9371   orig_address = XEXP (operands[0], 0);
9372   shift_reg = gen_reg_rtx (SImode);
9373   if (GET_CODE (x) == CONST_INT)
9374     {
9375       v = INTVAL (x);
9376       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9377     }
9378   else
9379     {
9380       emit_insn (gen_movsi (shift_reg, operands[3]));
9381       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9382     }
9383   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9385   operands[0] = replace_equiv_address (operands[0], addr_target);
9386   emit_insn (gen_movqi (operands[0], qi_val));
9388   while (size -= 1)
9389     {
9390       if (GET_CODE (x) == CONST_INT)
9391         qi_val
9392           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9393       else
9394         {
9395           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9396           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9397         }
9398       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9399       emit_insn (gen_movqi (operands[0], qi_val));
9400     }
9402   DONE;
9405 (define_insn "movua"
9406   [(set (match_operand:SI 0 "register_operand" "=z")
9407         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9408                          (const_int 32) (const_int 0)))]
9409   "TARGET_SH4A_ARCH"
9410   "movua.l      %1,%0"
9411   [(set_attr "type" "movua")])
9413 ;; We shouldn't need this, but cse replaces increments with references
9414 ;; to other regs before flow has a chance to create post_inc
9415 ;; addressing modes, and only postreload's cse_move2add brings the
9416 ;; increments back to a usable form.
9417 (define_peephole2
9418   [(set (match_operand:SI 0 "register_operand" "")
9419         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9420                          (const_int 32) (const_int 0)))
9421    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9422   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9423   [(set (match_operand:SI 0 "register_operand" "")
9424         (sign_extract:SI (mem:SI (post_inc:SI
9425                                   (match_operand:SI 1 "register_operand" "")))
9426                          (const_int 32) (const_int 0)))]
9427   "")
9429 (define_expand "extv"
9430   [(set (match_operand:SI 0 "register_operand" "")
9431         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9432                          (match_operand 2 "const_int_operand" "")
9433                          (match_operand 3 "const_int_operand" "")))]
9434   ""
9436   if (TARGET_SH4A_ARCH
9437       && INTVAL (operands[2]) == 32
9438       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9439       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9440     {
9441       emit_insn (gen_movua (operands[0],
9442                             adjust_address (operands[1], SImode, 0)));
9443       DONE;
9444     }
9446   FAIL;
9449 (define_expand "extzv"
9450   [(set (match_operand:SI 0 "register_operand" "")
9451         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9452                          (match_operand 2 "const_int_operand" "")
9453                          (match_operand 3 "const_int_operand" "")))]
9454   ""
9456   if (TARGET_SH4A_ARCH
9457       && INTVAL (operands[2]) == 32
9458       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9459       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9460     {
9461       emit_insn (gen_movua (operands[0],
9462                             adjust_address (operands[1], SImode, 0)));
9463       DONE;
9464     }
9466   FAIL;
9470 ;; -------------------------------------------------------------------------
9471 ;; Peepholes
9472 ;; -------------------------------------------------------------------------
9474 ;; This matches cases where a stack pointer increment at the start of the
9475 ;; epilogue combines with a stack slot read loading the return value.
9477 (define_peephole
9478   [(set (match_operand:SI 0 "arith_reg_operand" "")
9479         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9480    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9481   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9482   "mov.l        @%1+,%0")
9484 ;; See the comment on the dt combiner pattern above.
9486 (define_peephole
9487   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9488         (plus:SI (match_dup 0)
9489                  (const_int -1)))
9490    (set (reg:SI T_REG)
9491         (eq:SI (match_dup 0)
9492                (const_int 0)))]
9493   "TARGET_SH2"
9494   "dt   %0")
9496 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9497 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9498 ;; reload when the constant is too large for a reg+offset address.
9500 ;; ??? We would get much better code if this was done in reload.  This would
9501 ;; require modifying find_reloads_address to recognize that if the constant
9502 ;; is out-of-range for an immediate add, then we get better code by reloading
9503 ;; the constant into a register than by reloading the sum into a register,
9504 ;; since the former is one instruction shorter if the address does not need
9505 ;; to be offsettable.  Unfortunately this does not work, because there is
9506 ;; only one register, r0, that can be used as an index register.  This register
9507 ;; is also the function return value register.  So, if we try to force reload
9508 ;; to use double-reg addresses, then we end up with some instructions that
9509 ;; need to use r0 twice.  The only way to fix this is to change the calling
9510 ;; convention so that r0 is not used to return values.
9512 (define_peephole
9513   [(set (match_operand:SI 0 "register_operand" "=r")
9514         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9515    (set (mem:SI (match_dup 0))
9516         (match_operand:SI 2 "general_movsrc_operand" ""))]
9517   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9518   "mov.l        %2,@(%0,%1)")
9520 (define_peephole
9521   [(set (match_operand:SI 0 "register_operand" "=r")
9522         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9523    (set (match_operand:SI 2 "general_movdst_operand" "")
9524         (mem:SI (match_dup 0)))]
9525   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9526   "mov.l        @(%0,%1),%2")
9528 (define_peephole
9529   [(set (match_operand:SI 0 "register_operand" "=r")
9530         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9531    (set (mem:HI (match_dup 0))
9532         (match_operand:HI 2 "general_movsrc_operand" ""))]
9533   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9534   "mov.w        %2,@(%0,%1)")
9536 (define_peephole
9537   [(set (match_operand:SI 0 "register_operand" "=r")
9538         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9539    (set (match_operand:HI 2 "general_movdst_operand" "")
9540         (mem:HI (match_dup 0)))]
9541   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9542   "mov.w        @(%0,%1),%2")
9544 (define_peephole
9545   [(set (match_operand:SI 0 "register_operand" "=r")
9546         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9547    (set (mem:QI (match_dup 0))
9548         (match_operand:QI 2 "general_movsrc_operand" ""))]
9549   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9550   "mov.b        %2,@(%0,%1)")
9552 (define_peephole
9553   [(set (match_operand:SI 0 "register_operand" "=r")
9554         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9555    (set (match_operand:QI 2 "general_movdst_operand" "")
9556         (mem:QI (match_dup 0)))]
9557   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9558   "mov.b        @(%0,%1),%2")
9560 (define_peephole
9561   [(set (match_operand:SI 0 "register_operand" "=r")
9562         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9563    (set (mem:SF (match_dup 0))
9564         (match_operand:SF 2 "general_movsrc_operand" ""))]
9565   "TARGET_SH1 && REGNO (operands[0]) == 0
9566    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9567        || (GET_CODE (operands[2]) == SUBREG
9568            && REGNO (SUBREG_REG (operands[2])) < 16))
9569    && reg_unused_after (operands[0], insn)"
9570   "mov.l        %2,@(%0,%1)")
9572 (define_peephole
9573   [(set (match_operand:SI 0 "register_operand" "=r")
9574         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9575    (set (match_operand:SF 2 "general_movdst_operand" "")
9577         (mem:SF (match_dup 0)))]
9578   "TARGET_SH1 && REGNO (operands[0]) == 0
9579    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9580        || (GET_CODE (operands[2]) == SUBREG
9581            && REGNO (SUBREG_REG (operands[2])) < 16))
9582    && reg_unused_after (operands[0], insn)"
9583   "mov.l        @(%0,%1),%2")
9585 (define_peephole
9586   [(set (match_operand:SI 0 "register_operand" "=r")
9587         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9588    (set (mem:SF (match_dup 0))
9589         (match_operand:SF 2 "general_movsrc_operand" ""))]
9590   "TARGET_SH2E && REGNO (operands[0]) == 0
9591    && ((GET_CODE (operands[2]) == REG
9592         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9593        || (GET_CODE (operands[2]) == SUBREG
9594            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9595    && reg_unused_after (operands[0], insn)"
9596   "fmov{.s|}    %2,@(%0,%1)")
9598 (define_peephole
9599   [(set (match_operand:SI 0 "register_operand" "=r")
9600         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9601    (set (match_operand:SF 2 "general_movdst_operand" "")
9603         (mem:SF (match_dup 0)))]
9604   "TARGET_SH2E && REGNO (operands[0]) == 0
9605    && ((GET_CODE (operands[2]) == REG
9606         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9607        || (GET_CODE (operands[2]) == SUBREG
9608            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9609    && reg_unused_after (operands[0], insn)"
9610   "fmov{.s|}    @(%0,%1),%2")
9612 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9613 (define_insn "sp_switch_1"
9614   [(const_int 1)]
9615   "TARGET_SH1"
9616   "*
9618   rtx xoperands[1];
9620   xoperands[0] = sp_switch;
9621   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9622   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9623   return \"mov r0,r15\";
9625   [(set_attr "length" "10")])
9627 ;; Switch back to the original stack for interrupt functions with the
9628 ;; sp_switch attribute.  */
9629 (define_insn "sp_switch_2"
9630   [(const_int 2)]
9631   "TARGET_SH1"
9632   "mov.l @r15+,r15\;mov.l @r15+,r0"
9633   [(set_attr "length" "4")])
9635 ;; Integer vector moves
9637 (define_expand "movv8qi"
9638   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9639         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9640   "TARGET_SHMEDIA"
9641   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9643 (define_insn "movv8qi_i"
9644   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9645         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9646   "TARGET_SHMEDIA
9647    && (register_operand (operands[0], V8QImode)
9648        || sh_register_operand (operands[1], V8QImode))"
9649   "@
9650         add     %1, r63, %0
9651         movi    %1, %0
9652         #
9653         ld%M1.q %m1, %0
9654         st%M0.q %m0, %N1"
9655   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9656    (set_attr "length" "4,4,16,4,4")])
9658 (define_split
9659   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9660         (subreg:V8QI (const_int 0) 0))]
9661   "TARGET_SHMEDIA"
9662   [(set (match_dup 0)
9663         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9664                             (const_int 0) (const_int 0) (const_int 0)
9665                             (const_int 0) (const_int 0)]))])
9667 (define_split
9668   [(set (match_operand 0 "arith_reg_dest" "")
9669         (match_operand 1 "sh_rep_vec" ""))]
9670   "TARGET_SHMEDIA && reload_completed
9671    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9672    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9673    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9674    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9675        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9676    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9677        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9678   [(set (match_dup 0) (match_dup 1))
9679    (match_dup 2)]
9680   "
9682   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9683   rtx elt1 = XVECEXP (operands[1], 0, 1);
9685   if (unit_size > 2)
9686     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9687   else
9688     {
9689       if (unit_size < 2)
9690         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9691       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9692     }
9693   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9694   operands[1] = XVECEXP (operands[1], 0, 0);
9695   if (unit_size < 2)
9696     {
9697       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9698         operands[1]
9699           = GEN_INT (TARGET_LITTLE_ENDIAN
9700                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9701                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9702       else
9703         {
9704           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9705           operands[1]
9706             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9707         }
9708     }
9711 (define_split
9712   [(set (match_operand 0 "arith_reg_dest" "")
9713         (match_operand 1 "sh_const_vec" ""))]
9714   "TARGET_SHMEDIA && reload_completed
9715    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9716    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
9717    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9718   [(set (match_dup 0) (match_dup 1))]
9719   "
9721   rtx v = operands[1];
9722   enum machine_mode new_mode
9723     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9725   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9726   operands[1]
9727     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9730 (define_expand "movv2hi"
9731   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9732         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9733   "TARGET_SHMEDIA"
9734   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9736 (define_insn "movv2hi_i"
9737   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9738         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9739   "TARGET_SHMEDIA
9740    && (register_operand (operands[0], V2HImode)
9741        || sh_register_operand (operands[1], V2HImode))"
9742   "@
9743         addz.l  %1, r63, %0
9744         movi    %1, %0
9745         #
9746         ld%M1.l %m1, %0
9747         st%M0.l %m0, %N1"
9748   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9749    (set_attr "length" "4,4,16,4,4")])
9751 (define_expand "movv4hi"
9752   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9753         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9754   "TARGET_SHMEDIA"
9755   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9757 (define_insn "movv4hi_i"
9758   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9759         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9760   "TARGET_SHMEDIA
9761    && (register_operand (operands[0], V4HImode)
9762        || sh_register_operand (operands[1], V4HImode))"
9763   "@
9764         add     %1, r63, %0
9765         movi    %1, %0
9766         #
9767         ld%M1.q %m1, %0
9768         st%M0.q %m0, %N1"
9769   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9770    (set_attr "length" "4,4,16,4,4")])
9772 (define_expand "movv2si"
9773   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9774         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9775   "TARGET_SHMEDIA"
9776   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9778 (define_insn "movv2si_i"
9779   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9780         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9781   "TARGET_SHMEDIA
9782    && (register_operand (operands[0], V2SImode)
9783        || sh_register_operand (operands[1], V2SImode))"
9784   "@
9785         add     %1, r63, %0
9786         #
9787         #
9788         ld%M1.q %m1, %0
9789         st%M0.q %m0, %N1"
9790   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9791    (set_attr "length" "4,4,16,4,4")])
9793 ;; Multimedia Intrinsics
9795 (define_insn "absv2si2"
9796   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9797         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9798   "TARGET_SHMEDIA"
9799   "mabs.l       %1, %0"
9800   [(set_attr "type" "mcmp_media")])
9802 (define_insn "absv4hi2"
9803   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9804         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9805   "TARGET_SHMEDIA"
9806   "mabs.w       %1, %0"
9807   [(set_attr "type" "mcmp_media")])
9809 (define_insn "addv2si3"
9810   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9811         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9812                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9813   "TARGET_SHMEDIA"
9814   "madd.l       %1, %2, %0"
9815   [(set_attr "type" "arith_media")])
9817 (define_insn "addv4hi3"
9818   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9819         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9820                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9821   "TARGET_SHMEDIA"
9822   "madd.w       %1, %2, %0"
9823   [(set_attr "type" "arith_media")])
9825 (define_insn "ssaddv2si3"
9826   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9827         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9828                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9829   "TARGET_SHMEDIA"
9830   "madds.l      %1, %2, %0"
9831   [(set_attr "type" "mcmp_media")])
9833 (define_insn "usaddv8qi3"
9834   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9835         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9836                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9837   "TARGET_SHMEDIA"
9838   "madds.ub     %1, %2, %0"
9839   [(set_attr "type" "mcmp_media")])
9841 (define_insn "ssaddv4hi3"
9842   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9843         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9844                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9845   "TARGET_SHMEDIA"
9846   "madds.w      %1, %2, %0"
9847   [(set_attr "type" "mcmp_media")])
9849 (define_insn "negcmpeqv8qi"
9850   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9851         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9852                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9853   "TARGET_SHMEDIA"
9854   "mcmpeq.b     %N1, %N2, %0"
9855   [(set_attr "type" "mcmp_media")])
9857 (define_insn "negcmpeqv2si"
9858   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9859         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9860                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9861   "TARGET_SHMEDIA"
9862   "mcmpeq.l     %N1, %N2, %0"
9863   [(set_attr "type" "mcmp_media")])
9865 (define_insn "negcmpeqv4hi"
9866   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9867         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9868                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9869   "TARGET_SHMEDIA"
9870   "mcmpeq.w     %N1, %N2, %0"
9871   [(set_attr "type" "mcmp_media")])
9873 (define_insn "negcmpgtuv8qi"
9874   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9875         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9876                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9877   "TARGET_SHMEDIA"
9878   "mcmpgt.ub    %N1, %N2, %0"
9879   [(set_attr "type" "mcmp_media")])
9881 (define_insn "negcmpgtv2si"
9882   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9883         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9884                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9885   "TARGET_SHMEDIA"
9886   "mcmpgt.l     %N1, %N2, %0"
9887   [(set_attr "type" "mcmp_media")])
9889 (define_insn "negcmpgtv4hi"
9890   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9891         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9892                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9893   "TARGET_SHMEDIA"
9894   "mcmpgt.w     %N1, %N2, %0"
9895   [(set_attr "type" "mcmp_media")])
9897 (define_insn "mcmv"
9898   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9899         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9900                         (match_operand:DI 2 "arith_reg_operand" "r"))
9901                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9902                         (not:DI (match_dup 2)))))]
9903   "TARGET_SHMEDIA"
9904   "mcmv %N1, %2, %0"
9905   [(set_attr "type" "arith_media")])
9907 (define_insn "mcnvs_lw"
9908   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9909         (vec_concat:V4HI
9910          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9911          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9912   "TARGET_SHMEDIA"
9913   "mcnvs.lw     %N1, %N2, %0"
9914   [(set_attr "type" "mcmp_media")])
9916 (define_insn "mcnvs_wb"
9917   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9918         (vec_concat:V8QI
9919          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9920          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9921   "TARGET_SHMEDIA"
9922   "mcnvs.wb     %N1, %N2, %0"
9923   [(set_attr "type" "mcmp_media")])
9925 (define_insn "mcnvs_wub"
9926   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9927         (vec_concat:V8QI
9928          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9929          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9930   "TARGET_SHMEDIA"
9931   "mcnvs.wub    %N1, %N2, %0"
9932   [(set_attr "type" "mcmp_media")])
9934 (define_insn "mextr_rl"
9935   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9936         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9937                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9938                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9939                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9940   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9941   "*
9943   static char templ[16];
9945   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9946            (int) INTVAL (operands[3]) >> 3);
9947   return templ;
9949   [(set_attr "type" "arith_media")])
9951 (define_insn "*mextr_lr"
9952   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9953         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9954                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9955                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9956                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9957   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9958   "*
9960   static char templ[16];
9962   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9963            (int) INTVAL (operands[4]) >> 3);
9964   return templ;
9966   [(set_attr "type" "arith_media")])
9968 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9969 ; vector then varies depending on endianness.
9970 (define_expand "mextr1"
9971   [(match_operand:DI 0 "arith_reg_dest" "")
9972    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9973    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9974   "TARGET_SHMEDIA"
9975   "
9977   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9978                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9979   DONE;
9982 (define_expand "mextr2"
9983   [(match_operand:DI 0 "arith_reg_dest" "")
9984    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9985    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9986   "TARGET_SHMEDIA"
9987   "
9989   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9990                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9991   DONE;
9994 (define_expand "mextr3"
9995   [(match_operand:DI 0 "arith_reg_dest" "")
9996    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9997    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9998   "TARGET_SHMEDIA"
9999   "
10001   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10002                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
10003   DONE;
10006 (define_expand "mextr4"
10007   [(match_operand:DI 0 "arith_reg_dest" "")
10008    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10009    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10010   "TARGET_SHMEDIA"
10011   "
10013   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10014                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
10015   DONE;
10018 (define_expand "mextr5"
10019   [(match_operand:DI 0 "arith_reg_dest" "")
10020    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10021    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10022   "TARGET_SHMEDIA"
10023   "
10025   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10026                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
10027   DONE;
10030 (define_expand "mextr6"
10031   [(match_operand:DI 0 "arith_reg_dest" "")
10032    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10033    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10034   "TARGET_SHMEDIA"
10035   "
10037   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10038                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
10039   DONE;
10042 (define_expand "mextr7"
10043   [(match_operand:DI 0 "arith_reg_dest" "")
10044    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10045    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
10046   "TARGET_SHMEDIA"
10047   "
10049   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
10050                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
10051   DONE;
10054 (define_expand "mmacfx_wl"
10055   [(match_operand:V2SI 0 "arith_reg_dest" "")
10056    (match_operand:V2HI 1 "extend_reg_operand" "")
10057    (match_operand:V2HI 2 "extend_reg_operand" "")
10058    (match_operand:V2SI 3 "arith_reg_operand" "")]
10059   "TARGET_SHMEDIA"
10060   "
10062   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
10063                               operands[1], operands[2]));
10064   DONE;
10067 (define_insn "mmacfx_wl_i"
10068   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10069         (ss_plus:V2SI
10070          (match_operand:V2SI 1 "arith_reg_operand" "0")
10071          (ss_truncate:V2SI
10072           (ashift:V2DI
10073            (sign_extend:V2DI
10074             (mult:V2SI
10075              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10076              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10077            (const_int 1)))))]
10078   "TARGET_SHMEDIA"
10079   "mmacfx.wl    %2, %3, %0"
10080   [(set_attr "type" "mac_media")])
10082 (define_expand "mmacnfx_wl"
10083   [(match_operand:V2SI 0 "arith_reg_dest" "")
10084    (match_operand:V2HI 1 "extend_reg_operand" "")
10085    (match_operand:V2HI 2 "extend_reg_operand" "")
10086    (match_operand:V2SI 3 "arith_reg_operand" "")]
10087   "TARGET_SHMEDIA"
10088   "
10090   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10091                                operands[1], operands[2]));
10092   DONE;
10095 (define_insn "mmacnfx_wl_i"
10096   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10097         (ss_minus:V2SI
10098          (match_operand:V2SI 1 "arith_reg_operand" "0")
10099          (ss_truncate:V2SI
10100           (ashift:V2DI
10101            (sign_extend:V2DI
10102             (mult:V2SI
10103              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10104              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10105            (const_int 1)))))]
10106   "TARGET_SHMEDIA"
10107   "mmacnfx.wl   %2, %3, %0"
10108   [(set_attr "type" "mac_media")])
10110 (define_insn "mulv2si3"
10111   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10112         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10113                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10114   "TARGET_SHMEDIA"
10115   "mmul.l       %1, %2, %0"
10116   [(set_attr "type" "d2mpy_media")])
10118 (define_insn "mulv4hi3"
10119   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10120         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10121                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10122   "TARGET_SHMEDIA"
10123   "mmul.w       %1, %2, %0"
10124   [(set_attr "type" "dmpy_media")])
10126 (define_insn "mmulfx_l"
10127   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10128         (ss_truncate:V2SI
10129          (ashiftrt:V2DI
10130           (mult:V2DI
10131            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10132            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10133           (const_int 31))))]
10134   "TARGET_SHMEDIA"
10135   "mmulfx.l     %1, %2, %0"
10136   [(set_attr "type" "d2mpy_media")])
10138 (define_insn "mmulfx_w"
10139   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10140         (ss_truncate:V4HI
10141          (ashiftrt:V4SI
10142           (mult:V4SI
10143            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10144            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10145           (const_int 15))))]
10146   "TARGET_SHMEDIA"
10147   "mmulfx.w     %1, %2, %0"
10148   [(set_attr "type" "dmpy_media")])
10150 (define_insn "mmulfxrp_w"
10151   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10152         (ss_truncate:V4HI
10153          (ashiftrt:V4SI
10154           (plus:V4SI
10155            (mult:V4SI
10156             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10157             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10158            (const_int 16384))
10159           (const_int 15))))]
10160   "TARGET_SHMEDIA"
10161   "mmulfxrp.w   %1, %2, %0"
10162   [(set_attr "type" "dmpy_media")])
10164 (define_expand "mmulhi_wl"
10165   [(match_operand:V2SI 0 "arith_reg_dest" "")
10166    (match_operand:V4HI 1 "arith_reg_operand" "")
10167    (match_operand:V4HI 2 "arith_reg_operand" "")]
10168   "TARGET_SHMEDIA"
10169   "
10171   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10172              (operands[0], operands[1], operands[2]));
10173   DONE;
10176 (define_expand "mmullo_wl"
10177   [(match_operand:V2SI 0 "arith_reg_dest" "")
10178    (match_operand:V4HI 1 "arith_reg_operand" "")
10179    (match_operand:V4HI 2 "arith_reg_operand" "")]
10180   "TARGET_SHMEDIA"
10181   "
10183   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10184              (operands[0], operands[1], operands[2]));
10185   DONE;
10188 (define_insn "mmul23_wl"
10189   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10190         (vec_select:V2SI
10191          (mult:V4SI
10192           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10193           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10194          (parallel [(const_int 2) (const_int 3)])))]
10195   "TARGET_SHMEDIA"
10196   "* return (TARGET_LITTLE_ENDIAN
10197              ? \"mmulhi.wl      %1, %2, %0\"
10198              : \"mmullo.wl      %1, %2, %0\");"
10199   [(set_attr "type" "dmpy_media")])
10201 (define_insn "mmul01_wl"
10202   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10203         (vec_select:V2SI
10204          (mult:V4SI
10205           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10206           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10207          (parallel [(const_int 0) (const_int 1)])))]
10208   "TARGET_SHMEDIA"
10209   "* return (TARGET_LITTLE_ENDIAN
10210              ? \"mmullo.wl      %1, %2, %0\"
10211              : \"mmulhi.wl      %1, %2, %0\");"
10212   [(set_attr "type" "dmpy_media")])
10214 (define_expand "mmulsum_wq"
10215   [(match_operand:DI 0 "arith_reg_dest" "")
10216    (match_operand:V4HI 1 "arith_reg_operand" "")
10217    (match_operand:V4HI 2 "arith_reg_operand" "")
10218    (match_operand:DI 3 "arith_reg_operand" "")]
10219   "TARGET_SHMEDIA"
10220   "
10222   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10223                                operands[1], operands[2]));
10224   DONE;
10227 (define_insn "mmulsum_wq_i"
10228   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10229         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10230          (plus:DI
10231           (plus:DI
10232            (vec_select:DI
10233             (mult:V4DI
10234              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10235              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10236             (parallel [(const_int 0)]))
10237            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10238                                      (sign_extend:V4DI (match_dup 3)))
10239                           (parallel [(const_int 1)])))
10240           (plus:DI
10241            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10242                                      (sign_extend:V4DI (match_dup 3)))
10243                           (parallel [(const_int 2)]))
10244            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10245                                      (sign_extend:V4DI (match_dup 3)))
10246                           (parallel [(const_int 3)]))))))]
10247   "TARGET_SHMEDIA"
10248   "mmulsum.wq   %2, %3, %0"
10249   [(set_attr "type" "mac_media")])
10251 (define_expand "mperm_w"
10252   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10253    (match_operand:V4HI 1 "arith_reg_operand" "r")
10254    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10255   "TARGET_SHMEDIA"
10256   "
10258   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10259              (operands[0], operands[1], operands[2]));
10260   DONE;
10263 ; This use of vec_select isn't exactly correct according to rtl.texi
10264 ; (because not constant), but it seems a straightforward extension.
10265 (define_insn "mperm_w_little"
10266   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10267         (vec_select:V4HI
10268          (match_operand:V4HI 1 "arith_reg_operand" "r")
10269          (parallel
10270           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10271                             (const_int 2) (const_int 0))
10272            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10273            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10274            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10275   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10276   "mperm.w      %1, %N2, %0"
10277   [(set_attr "type" "arith_media")])
10279 (define_insn "mperm_w_big"
10280   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10281         (vec_select:V4HI
10282          (match_operand:V4HI 1 "arith_reg_operand" "r")
10283          (parallel
10284           [(zero_extract:QI (not:QI (match_operand:QI 2
10285                                      "extend_reg_or_0_operand" "rZ"))
10286                             (const_int 2) (const_int 0))
10287            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10288            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10289            (zero_extract:QI (not:QI (match_dup 2))
10290                             (const_int 2) (const_int 6))])))]
10291   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10292   "mperm.w      %1, %N2, %0"
10293   [(set_attr "type" "arith_media")])
10295 (define_insn "mperm_w0"
10296   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10297         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10298                                           "trunc_hi_operand" "r"))))]
10299   "TARGET_SHMEDIA"
10300   "mperm.w      %1, r63, %0"
10301   [(set_attr "type" "arith_media")])
10303 (define_expand "msad_ubq"
10304   [(match_operand:DI 0 "arith_reg_dest" "")
10305    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10306    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10307    (match_operand:DI 3 "arith_reg_operand" "")]
10308   "TARGET_SHMEDIA"
10309   "
10311   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10312                              operands[1], operands[2]));
10313   DONE;
10316 (define_insn "msad_ubq_i"
10317   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10318         (plus:DI
10319          (plus:DI
10320           (plus:DI
10321            (plus:DI
10322             (match_operand:DI 1 "arith_reg_operand" "0")
10323             (abs:DI (vec_select:DI
10324                      (minus:V8DI
10325                       (zero_extend:V8DI
10326                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10327                       (zero_extend:V8DI
10328                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10329                      (parallel [(const_int 0)]))))
10330            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10331                                               (zero_extend:V8DI (match_dup 3)))
10332                                   (parallel [(const_int 1)]))))
10333           (plus:DI
10334            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10335                                               (zero_extend:V8DI (match_dup 3)))
10336                                   (parallel [(const_int 2)])))
10337            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10338                                               (zero_extend:V8DI (match_dup 3)))
10339                                   (parallel [(const_int 3)])))))
10340          (plus:DI
10341           (plus:DI
10342            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10343                                               (zero_extend:V8DI (match_dup 3)))
10344                                   (parallel [(const_int 4)])))
10345            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10346                                               (zero_extend:V8DI (match_dup 3)))
10347                                   (parallel [(const_int 5)]))))
10348           (plus:DI
10349            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10350                                               (zero_extend:V8DI (match_dup 3)))
10351                                   (parallel [(const_int 6)])))
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 7)])))))))]
10355   "TARGET_SHMEDIA"
10356   "msad.ubq     %N2, %N3, %0"
10357   [(set_attr "type" "mac_media")])
10359 (define_insn "mshalds_l"
10360   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10361         (ss_truncate:V2SI
10362          (ashift:V2DI
10363           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10364           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10365                   (const_int 31)))))]
10366   "TARGET_SHMEDIA"
10367   "mshalds.l    %1, %2, %0"
10368   [(set_attr "type" "mcmp_media")])
10370 (define_insn "mshalds_w"
10371   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10372         (ss_truncate:V4HI
10373          (ashift:V4SI
10374           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10375           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10376                   (const_int 15)))))]
10377   "TARGET_SHMEDIA"
10378   "mshalds.w    %1, %2, %0"
10379   [(set_attr "type" "mcmp_media")])
10381 (define_insn "ashrv2si3"
10382   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10383         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10384                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10385   "TARGET_SHMEDIA"
10386   "mshard.l     %1, %2, %0"
10387   [(set_attr "type" "arith_media")])
10389 (define_insn "ashrv4hi3"
10390   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10391         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10392                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10393   "TARGET_SHMEDIA"
10394   "mshard.w     %1, %2, %0"
10395   [(set_attr "type" "arith_media")])
10397 (define_insn "mshards_q"
10398   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10399         (ss_truncate:HI
10400          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10401                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10402   "TARGET_SHMEDIA"
10403   "mshards.q    %1, %N2, %0"
10404   [(set_attr "type" "mcmp_media")])
10406 (define_expand "mshfhi_b"
10407   [(match_operand:V8QI 0 "arith_reg_dest" "")
10408    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10409    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10410   "TARGET_SHMEDIA"
10411   "
10413   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10414              (operands[0], operands[1], operands[2]));
10415   DONE;
10418 (define_expand "mshflo_b"
10419   [(match_operand:V8QI 0 "arith_reg_dest" "")
10420    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10421    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10422   "TARGET_SHMEDIA"
10423   "
10425   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10426              (operands[0], operands[1], operands[2]));
10427   DONE;
10430 (define_insn "mshf4_b"
10431   [(set
10432     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10433     (vec_select:V8QI
10434      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10435                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10436      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10437                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10438   "TARGET_SHMEDIA"
10439   "* return (TARGET_LITTLE_ENDIAN
10440              ? \"mshfhi.b       %N1, %N2, %0\"
10441              : \"mshflo.b       %N1, %N2, %0\");"
10442   [(set_attr "type" "arith_media")])
10444 (define_insn "mshf0_b"
10445   [(set
10446     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10447     (vec_select:V8QI
10448      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10449                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10450      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10451                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10452   "TARGET_SHMEDIA"
10453   "* return (TARGET_LITTLE_ENDIAN
10454              ? \"mshflo.b       %N1, %N2, %0\"
10455              : \"mshfhi.b       %N1, %N2, %0\");"
10456   [(set_attr "type" "arith_media")])
10458 (define_expand "mshfhi_l"
10459   [(match_operand:V2SI 0 "arith_reg_dest" "")
10460    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10461    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10462   "TARGET_SHMEDIA"
10463   "
10465   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10466              (operands[0], operands[1], operands[2]));
10467   DONE;
10470 (define_expand "mshflo_l"
10471   [(match_operand:V2SI 0 "arith_reg_dest" "")
10472    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10473    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10474   "TARGET_SHMEDIA"
10475   "
10477   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10478              (operands[0], operands[1], operands[2]));
10479   DONE;
10482 (define_insn "mshf4_l"
10483   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10484         (vec_select:V2SI
10485          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10486                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10487          (parallel [(const_int 1) (const_int 3)])))]
10488   "TARGET_SHMEDIA"
10489   "* return (TARGET_LITTLE_ENDIAN
10490              ? \"mshfhi.l       %N1, %N2, %0\"
10491              : \"mshflo.l       %N1, %N2, %0\");"
10492   [(set_attr "type" "arith_media")])
10494 (define_insn "mshf0_l"
10495   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10496         (vec_select:V2SI
10497          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10498                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10499          (parallel [(const_int 0) (const_int 2)])))]
10500   "TARGET_SHMEDIA"
10501   "* return (TARGET_LITTLE_ENDIAN
10502              ? \"mshflo.l       %N1, %N2, %0\"
10503              : \"mshfhi.l       %N1, %N2, %0\");"
10504   [(set_attr "type" "arith_media")])
10506 (define_expand "mshfhi_w"
10507   [(match_operand:V4HI 0 "arith_reg_dest" "")
10508    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10509    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10510   "TARGET_SHMEDIA"
10511   "
10513   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10514              (operands[0], operands[1], operands[2]));
10515   DONE;
10518 (define_expand "mshflo_w"
10519   [(match_operand:V4HI 0 "arith_reg_dest" "")
10520    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10521    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10522   "TARGET_SHMEDIA"
10523   "
10525   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10526              (operands[0], operands[1], operands[2]));
10527   DONE;
10530 (define_insn "mshf4_w"
10531   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10532         (vec_select:V4HI
10533          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10534                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10535          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10536   "TARGET_SHMEDIA"
10537   "* return (TARGET_LITTLE_ENDIAN
10538              ? \"mshfhi.w       %N1, %N2, %0\"
10539              : \"mshflo.w       %N1, %N2, %0\");"
10540   [(set_attr "type" "arith_media")])
10542 (define_insn "mshf0_w"
10543   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10544         (vec_select:V4HI
10545          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10546                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10547          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10548   "TARGET_SHMEDIA"
10549   "* return (TARGET_LITTLE_ENDIAN
10550              ? \"mshflo.w       %N1, %N2, %0\"
10551              : \"mshfhi.w       %N1, %N2, %0\");"
10552   [(set_attr "type" "arith_media")])
10554 (define_insn "mshflo_w_x"
10555   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10556         (vec_select:V4HI
10557          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10558                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10559          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10560   "TARGET_SHMEDIA"
10561   "mshflo.w     %N1, %N2, %0"
10562   [(set_attr "type" "arith_media")])
10564 /* These are useful to expand ANDs and as combiner patterns.  */
10565 (define_insn_and_split "mshfhi_l_di"
10566   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10567         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10568                              (const_int 32))
10569                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10570                         (const_int -4294967296))))]
10571   "TARGET_SHMEDIA"
10572   "@
10573         mshfhi.l        %N1, %N2, %0
10574         #"
10575   "TARGET_SHMEDIA && reload_completed
10576    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10577   [(set (match_dup 3) (match_dup 4))
10578    (set (match_dup 5) (match_dup 6))]
10579   "
10581   operands[3] = gen_lowpart (SImode, operands[0]);
10582   operands[4] = gen_highpart (SImode, operands[1]);
10583   operands[5] = gen_highpart (SImode, operands[0]);
10584   operands[6] = gen_highpart (SImode, operands[2]);
10586   [(set_attr "type" "arith_media")])
10588 (define_insn "*mshfhi_l_di_rev"
10589   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10590         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10591                         (const_int -4294967296))
10592                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10593                              (const_int 32))))]
10594   "TARGET_SHMEDIA"
10595   "mshfhi.l     %N2, %N1, %0"
10596   [(set_attr "type" "arith_media")])
10598 (define_split
10599   [(set (match_operand:DI 0 "arith_reg_dest" "")
10600         (ior:DI (zero_extend:DI (match_operand:SI 1
10601                                               "extend_reg_or_0_operand" ""))
10602                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10603                         (const_int -4294967296))))
10604    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10605   "TARGET_SHMEDIA"
10606   [(const_int 0)]
10607   "
10609   emit_insn (gen_ashldi3_media (operands[3],
10610                                 simplify_gen_subreg (DImode, operands[1],
10611                                                      SImode, 0),
10612                                 GEN_INT (32)));
10613   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10614   DONE;
10617 (define_insn "mshflo_l_di"
10618   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10619         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10620                         (const_int 4294967295))
10621                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10622                            (const_int 32))))]
10624   "TARGET_SHMEDIA"
10625   "mshflo.l     %N1, %N2, %0"
10626   [(set_attr "type" "arith_media")])
10628 (define_insn "*mshflo_l_di_rev"
10629   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10630         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10631                            (const_int 32))
10632                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10633                         (const_int 4294967295))))]
10635   "TARGET_SHMEDIA"
10636   "mshflo.l     %N2, %N1, %0"
10637   [(set_attr "type" "arith_media")])
10639 ;; Combiner pattern for trampoline initialization.
10640 (define_insn_and_split "*double_shori"
10641   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10642         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10643                            (const_int 32))
10644                 (match_operand:DI 2 "const_int_operand" "n")))]
10645   "TARGET_SHMEDIA
10646    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10647   "#"
10648   "rtx_equal_p (operands[0], operands[1])"
10649   [(const_int 0)]
10650   "
10652   HOST_WIDE_INT v = INTVAL (operands[2]);
10654   emit_insn (gen_shori_media (operands[0], operands[0],
10655              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10656   emit_insn (gen_shori_media (operands[0], operands[0],
10657                               gen_int_mode (v, HImode)));
10658   DONE;
10662 (define_insn "*mshflo_l_di_x"
10663   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10664         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10665                                  "rZ"))
10666                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10667                            (const_int 32))))]
10669   "TARGET_SHMEDIA"
10670   "mshflo.l     %N1, %N2, %0"
10671   [(set_attr "type" "arith_media")])
10673 (define_insn_and_split "concat_v2sf"
10674   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10675 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10676         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10677                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10679   "TARGET_SHMEDIA"
10680   "@
10681         mshflo.l        %N1, %N2, %0
10682         #
10683         #"
10684   "TARGET_SHMEDIA && reload_completed
10685    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10686   [(set (match_dup 3) (match_dup 1))
10687    (set (match_dup 4) (match_dup 2))]
10688   "
10690   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10691   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10693   [(set_attr "type" "arith_media")])
10695 (define_insn "*mshflo_l_di_x_rev"
10696   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10697         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10698                            (const_int 32))
10699                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10701   "TARGET_SHMEDIA"
10702   "mshflo.l     %N2, %N1, %0"
10703   [(set_attr "type" "arith_media")])
10705 (define_insn "ashlv2si3"
10706   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10707         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10708                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10709   "TARGET_SHMEDIA"
10710   "mshlld.l     %1, %2, %0"
10711   [(set_attr "type" "arith_media")])
10713 (define_insn "ashlv4hi3"
10714   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10715         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10716                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10717   "TARGET_SHMEDIA"
10718   "mshlld.w     %1, %2, %0"
10719   [(set_attr "type" "arith_media")])
10721 (define_insn "lshrv2si3"
10722   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10723         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10724                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10725   "TARGET_SHMEDIA"
10726   "mshlrd.l     %1, %2, %0"
10727   [(set_attr "type" "arith_media")])
10729 (define_insn "lshrv4hi3"
10730   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10731         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10732                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10733   "TARGET_SHMEDIA"
10734   "mshlrd.w     %1, %2, %0"
10735   [(set_attr "type" "arith_media")])
10737 (define_insn "subv2si3"
10738   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10739         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10740                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10741   "TARGET_SHMEDIA"
10742   "msub.l       %N1, %2, %0"
10743   [(set_attr "type" "arith_media")])
10745 (define_insn "subv4hi3"
10746   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10747         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10748                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10749   "TARGET_SHMEDIA"
10750   "msub.w       %N1, %2, %0"
10751   [(set_attr "type" "arith_media")])
10753 (define_insn "sssubv2si3"
10754   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10755         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10756                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10757   "TARGET_SHMEDIA"
10758   "msubs.l      %N1, %2, %0"
10759   [(set_attr "type" "mcmp_media")])
10761 (define_insn "ussubv8qi3"
10762   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10763         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10764                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10765   "TARGET_SHMEDIA"
10766   "msubs.ub     %1, %2, %0"
10767   [(set_attr "type" "mcmp_media")])
10769 (define_insn "sssubv4hi3"
10770   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10771         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10772                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10773   "TARGET_SHMEDIA"
10774   "msubs.w      %N1, %2, %0"
10775   [(set_attr "type" "mcmp_media")])
10777 ;; Floating Point Intrinsics
10779 (define_insn "fcosa_s"
10780   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10781         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10782                    UNSPEC_FCOSA))]
10783   "TARGET_SHMEDIA"
10784   "fcosa.s      %1, %0"
10785   [(set_attr "type" "atrans_media")])
10787 (define_insn "fsina_s"
10788   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10789         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10790                    UNSPEC_FSINA))]
10791   "TARGET_SHMEDIA"
10792   "fsina.s      %1, %0"
10793   [(set_attr "type" "atrans_media")])
10795 (define_insn "fipr"
10796   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10797         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10798                                                     "fp_arith_reg_operand" "f")
10799                                                    (match_operand:V4SF 2
10800                                                     "fp_arith_reg_operand" "f"))
10801                                          (parallel [(const_int 0)]))
10802                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10803                                          (parallel [(const_int 1)])))
10804                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10805                                          (parallel [(const_int 2)]))
10806                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10807                                          (parallel [(const_int 3)])))))]
10808   "TARGET_SHMEDIA"
10809   "fipr.s       %1, %2, %0"
10810   [(set_attr "type" "fparith_media")])
10812 (define_insn "fsrra_s"
10813   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10814         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10815                    UNSPEC_FSRRA))]
10816   "TARGET_SHMEDIA"
10817   "fsrra.s      %1, %0"
10818   [(set_attr "type" "atrans_media")])
10820 (define_insn "ftrv"
10821   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10822         (plus:V4SF
10823          (plus:V4SF
10824           (mult:V4SF
10825            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10826                             (parallel [(const_int 0) (const_int 5)
10827                                        (const_int 10) (const_int 15)]))
10828            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10829           (mult:V4SF
10830            (vec_select:V4SF (match_dup 1)
10831                             (parallel [(const_int 4) (const_int 9)
10832                                        (const_int 14) (const_int 3)]))
10833            (vec_select:V4SF (match_dup 2)
10834                             (parallel [(const_int 1) (const_int 2)
10835                                        (const_int 3) (const_int 0)]))))
10836          (plus:V4SF
10837           (mult:V4SF
10838            (vec_select:V4SF (match_dup 1)
10839                             (parallel [(const_int 8) (const_int 13)
10840                                        (const_int 2) (const_int 7)]))
10841            (vec_select:V4SF (match_dup 2)
10842                             (parallel [(const_int 2) (const_int 3)
10843                                        (const_int 0) (const_int 1)])))
10844           (mult:V4SF
10845            (vec_select:V4SF (match_dup 1)
10846                             (parallel [(const_int 12) (const_int 1)
10847                                        (const_int 6) (const_int 11)]))
10848            (vec_select:V4SF (match_dup 2)
10849                             (parallel [(const_int 3) (const_int 0)
10850                                        (const_int 1) (const_int 2)]))))))]
10851   "TARGET_SHMEDIA"
10852   "ftrv.s %1, %2, %0"
10853   [(set_attr "type" "fparith_media")])
10855 (define_insn "nsb"
10856   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10857         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10858                    UNSPEC_NSB))]
10859   "TARGET_SHMEDIA"
10860   "nsb  %1, %0"
10861   [(set_attr "type" "arith_media")])
10863 (define_insn "nsbsi"
10864   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10865         (zero_extend:SI
10866          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10867                     UNSPEC_NSB)))]
10868   "TARGET_SHMEDIA"
10869   "nsb  %1, %0"
10870   [(set_attr "type" "arith_media")])
10872 (define_insn "nsbdi"
10873   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10874         (zero_extend:DI
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_expand "ffsdi2"
10882   [(set (match_operand:DI 0 "arith_reg_dest" "")
10883         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10884   "TARGET_SHMEDIA"
10885   "
10887   rtx scratch = gen_reg_rtx (DImode);
10888   rtx last;
10890   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10891   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10892   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10893   emit_insn (gen_nsbdi (scratch, scratch));
10894   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10895   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10896   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10897   REG_NOTES (last)
10898     = gen_rtx_EXPR_LIST (REG_EQUAL,
10899                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10900   DONE;
10903 (define_expand "ffssi2"
10904   [(set (match_operand:SI 0 "arith_reg_dest" "")
10905         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10906   "TARGET_SHMEDIA"
10907   "
10909   rtx scratch = gen_reg_rtx (SImode);
10910   rtx discratch = gen_reg_rtx (DImode);
10911   rtx last;
10913   emit_insn (gen_adddi3 (discratch,
10914                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10915                          constm1_rtx));
10916   emit_insn (gen_andcdi3 (discratch,
10917                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10918                           discratch));
10919   emit_insn (gen_nsbsi (scratch, discratch));
10920   last = emit_insn (gen_subsi3 (operands[0],
10921                                 force_reg (SImode, GEN_INT (63)), scratch));
10922   REG_NOTES (last)
10923     = gen_rtx_EXPR_LIST (REG_EQUAL,
10924                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10925   DONE;
10928 (define_insn "byterev"
10929   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10930         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10931                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10932                                     (const_int 4) (const_int 3) (const_int 2)
10933                                     (const_int 1) (const_int 0)])))]
10934   "TARGET_SHMEDIA"
10935   "byterev      %1, %0"
10936   [(set_attr "type" "arith_media")])
10938 (define_insn "prefetch"
10939   [(prefetch (match_operand:QI 0 "address_operand" "p")
10940              (match_operand:SI 1 "const_int_operand" "n")
10941              (match_operand:SI 2 "const_int_operand" "n"))]
10942   "TARGET_SHMEDIA || TARGET_HARD_SH4"
10943   "*
10945   if (TARGET_HARD_SH4)
10946     return \"pref @%0\";
10947   operands[0] = gen_rtx_MEM (QImode, operands[0]);
10948   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
10949   return \"\";
10951   [(set_attr "type" "other")])