gcc/ChangeLog:
[official-gcc.git] / gcc / config / sh / sh.md
blob77ba4d59d74982cce6a1fdf47b95ef1a1fbd5b97
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,sh3,sh3e,sh4,sh4a,sh5"
165   (const (symbol_ref "sh_cpu_attr")))
167 (define_attr "endian" "big,little"
168  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169                       (const_string "little") (const_string "big"))))
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174                          (const_string "yes") (const_string "no"))))
176 (define_attr "fmovd" "yes,no"
177   (const (if_then_else (symbol_ref "TARGET_FMOVD")
178                        (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181   (const
182    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184          (const_string "sh1"))))
186 ;; cbranch      conditional branch instructions
187 ;; jump         unconditional jumps
188 ;; arith        ordinary arithmetic
189 ;; arith3       a compound insn that behaves similarly to a sequence of
190 ;;              three insns of type arith
191 ;; arith3b      like above, but might end with a redirected branch
192 ;; load         from memory
193 ;; load_si      Likewise, SImode variant for general register.
194 ;; fload        Likewise, but load to fp register.
195 ;; store        to memory
196 ;; move         general purpose register to register
197 ;; mt_group     other sh4 mt instructions
198 ;; fmove        register to register, floating point
199 ;; smpy         word precision integer multiply
200 ;; dmpy         longword or doublelongword precision integer multiply
201 ;; return       rts
202 ;; pload        load of pr reg, which can't be put into delay slot of rts
203 ;; prset        copy register to pr reg, ditto
204 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
205 ;; prget        copy pr to register, ditto
206 ;; pcload       pc relative load of constant value
207 ;; pcfload      Likewise, but load to fp register.
208 ;; pcload_si    Likewise, SImode variant for general register.
209 ;; rte          return from exception
210 ;; sfunc        special function call with known used registers
211 ;; call         function call
212 ;; fp           floating point
213 ;; fdiv         floating point divide (or square root)
214 ;; gp_fpul      move from general purpose register to fpul
215 ;; fpul_gp      move from fpul to general purpose register
216 ;; mac_gp       move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s       fix_truncsfsi2_i4
219 ;; dfdiv        double precision floating point divide (or square root)
220 ;; cwb          ic_invalidate_line_i
221 ;; movua        SH4a unaligned load
222 ;; fsrra        square root reciprocal approximate
223 ;; fsca         sine and cosine approximate
224 ;; tls_load     load TLS related address
225 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
226 ;; cbranch_media SHmedia conditional branch instructions
227 ;; cmp_media    SHmedia compare instructions
228 ;; dfdiv_media  SHmedia double precision divide and square root
229 ;; dfmul_media  SHmedia double precision multiply instruction
230 ;; dfparith_media SHmedia double precision floating point arithmetic
231 ;; dfpconv_media SHmedia double precision floating point conversions
232 ;; dmpy_media   SHmedia longword multiply
233 ;; fcmp_media   SHmedia floating point compare instructions
234 ;; fdiv_media   SHmedia single precision divide and square root
235 ;; fload_media  SHmedia floating point register load instructions
236 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
237 ;; fparith_media SHmedia single precision floating point arithmetic
238 ;; fpconv_media SHmedia single precision floating point conversions
239 ;; fstore_media SHmedia floating point register store instructions
240 ;; gettr_media  SHmedia gettr instruction
241 ;; invalidate_line_media SHmedia invalidate_line sequence
242 ;; jump_media   SHmedia unconditional branch instructions
243 ;; load_media   SHmedia general register load instructions
244 ;; pt_media     SHmedia pt instruction (expanded by assembler)
245 ;; ptabs_media  SHmedia ptabs instruction
246 ;; store_media  SHmedia general register store instructions
247 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
248 ;; mac_media    SHmedia mac-style fixed point operations
249 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
250 ;; atrans       SHmedia approximate transcendental functions
251 ;; ustore_media SHmedia unaligned stores
252 ;; nil          no-op move, will be deleted.
254 (define_attr "type"
255  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
256   (const_string "other"))
258 ;; We define a new attribute namely "insn_class".We use
259 ;; this for the DFA based pipeline description.
261 ;; mt_group      SH4 "mt" group instructions.
263 ;; ex_group      SH4 "ex" group instructions.
265 ;; ls_group      SH4 "ls" group instructions.
268 (define_attr "insn_class"
269   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
270   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
271          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
272          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
273          (eq_attr "type" "cbranch,jump") (const_string "br_group")
274          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
275            (const_string "fe_group")
276          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
277         (const_string "none")))
278 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
279 ;; so these do not belong in an insn group, although they are modeled
280 ;; with their own define_insn_reservations.
282 ;; Indicate what precision must be selected in fpscr for this insn, if any.
284 (define_attr "fp_mode" "single,double,none" (const_string "none"))
286 ;; Indicate if the fpu mode is set by this instruction
287 ;; "unknown" must have the value as "none" in fp_mode, and means
288 ;; that the instruction/abi has left the processor in an unknown
289 ;; state.
290 ;; "none" means that nothing has changed and no mode is set.
291 ;; This attribute is only used for the Renesas ABI.
292 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
294 ; If a conditional branch destination is within -252..258 bytes away
295 ; from the instruction it can be 2 bytes long.  Something in the
296 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
297 ; branches are initially assumed to be 16 bytes long.
298 ; In machine_dependent_reorg, we split all branches that are longer than
299 ; 2 bytes.
301 ;; The maximum range used for SImode constant pool entries is 1018.  A final
302 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
303 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
304 ;; instruction around the pool table, 2 bytes of alignment before the table,
305 ;; and 30 bytes of alignment after the table.  That gives a maximum total
306 ;; pool size of 1058 bytes.
307 ;; Worst case code/pool content size ratio is 1:2 (using asms).
308 ;; Thus, in the worst case, there is one instruction in front of a maximum
309 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
310 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
311 ;; If we have a forward branch, the initial table will be put after the
312 ;; unconditional branch.
314 ;; ??? We could do much better by keeping track of the actual pcloads within
315 ;; the branch range and in the pcload range in front of the branch range.
317 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
318 ;; inside an le.
319 (define_attr "short_cbranch_p" "no,yes"
320   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
321          (const_string "no")
322          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
323          (const_string "yes")
324          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
325          (const_string "no")
326          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
327          (const_string "yes")
328          ] (const_string "no")))
330 (define_attr "med_branch_p" "no,yes"
331   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
332               (const_int 1988))
333          (const_string "yes")
334          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
335          (const_string "no")
336          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
337               (const_int 8186))
338          (const_string "yes")
339          ] (const_string "no")))
341 (define_attr "med_cbranch_p" "no,yes"
342   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
343               (const_int 1986))
344          (const_string "yes")
345          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
346          (const_string "no")
347          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
348                (const_int 8184))
349          (const_string "yes")
350          ] (const_string "no")))
352 (define_attr "braf_branch_p" "no,yes"
353   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
356               (const_int 20660))
357          (const_string "yes")
358          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
359          (const_string "no")
360          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
361               (const_int 65530))
362          (const_string "yes")
363          ] (const_string "no")))
365 (define_attr "braf_cbranch_p" "no,yes"
366   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
367          (const_string "no")
368          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
369               (const_int 20658))
370          (const_string "yes")
371          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
372          (const_string "no")
373          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
374               (const_int 65528))
375          (const_string "yes")
376          ] (const_string "no")))
378 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
379 ; For wider ranges, we need a combination of a code and a data part.
380 ; If we can get a scratch register for a long range jump, the code
381 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
382 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
383 ; long; otherwise, it must be 6 bytes long.
385 ; All other instructions are two bytes long by default.
387 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
388 ;; but getattrtab doesn't understand this.
389 (define_attr "length" ""
390   (cond [(eq_attr "type" "cbranch")
391          (cond [(eq_attr "short_cbranch_p" "yes")
392                 (const_int 2)
393                 (eq_attr "med_cbranch_p" "yes")
394                 (const_int 6)
395                 (eq_attr "braf_cbranch_p" "yes")
396                 (const_int 12)
397 ;; ??? using pc is not computed transitively.
398                 (ne (match_dup 0) (match_dup 0))
399                 (const_int 14)
400                 (ne (symbol_ref ("flag_pic")) (const_int 0))
401                 (const_int 24)
402                 ] (const_int 16))
403          (eq_attr "type" "jump")
404          (cond [(eq_attr "med_branch_p" "yes")
405                 (const_int 2)
406                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
407                          (symbol_ref "INSN"))
408                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
409                          (symbol_ref "code_for_indirect_jump_scratch")))
410                 (if_then_else (eq_attr "braf_branch_p" "yes")
411                               (const_int 6)
412                               (const_int 10))
413                 (eq_attr "braf_branch_p" "yes")
414                 (const_int 10)
415 ;; ??? using pc is not computed transitively.
416                 (ne (match_dup 0) (match_dup 0))
417                 (const_int 12)
418                 (ne (symbol_ref ("flag_pic")) (const_int 0))
419                 (const_int 22)
420                 ] (const_int 14))
421          (eq_attr "type" "pt_media")
422          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
423                        (const_int 20) (const_int 12))
424          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
425                          (const_int 4)
426                          (const_int 2))))
428 ;; DFA descriptions for the pipelines
430 (include "sh1.md")
431 (include "shmedia.md")
432 (include "sh4.md")
434 ;; Definitions for filling delay slots
436 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
438 ;; ??? This should be (nil) instead of (const_int 0)
439 (define_attr "hit_stack" "yes,no"
440         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
441                    (const_int 0))
442                (const_string "no")]
443               (const_string "yes")))
445 (define_attr "interrupt_function" "no,yes"
446   (const (symbol_ref "current_function_interrupt")))
448 (define_attr "in_delay_slot" "yes,no"
449   (cond [(eq_attr "type" "cbranch") (const_string "no")
450          (eq_attr "type" "pcload,pcload_si") (const_string "no")
451          (eq_attr "needs_delay_slot" "yes") (const_string "no")
452          (eq_attr "length" "2") (const_string "yes")
453          ] (const_string "no")))
455 (define_attr "cond_delay_slot" "yes,no"
456   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
457          ] (const_string "no")))
459 (define_attr "is_sfunc" ""
460   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
462 (define_attr "is_mac_media" ""
463   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
465 (define_attr "branch_zero" "yes,no"
466   (cond [(eq_attr "type" "!cbranch") (const_string "no")
467          (ne (symbol_ref "(next_active_insn (insn)\
468                            == (prev_active_insn\
469                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
470                           && get_attr_length (next_active_insn (insn)) == 2")
471              (const_int 0))
472          (const_string "yes")]
473         (const_string "no")))
475 ;; SH4 Double-precision computation with double-precision result -
476 ;; the two halves are ready at different times.
477 (define_attr "dfp_comp" "yes,no"
478   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
479         (const_string "no")))
481 ;; Insns for which the latency of a preceding fp insn is decreased by one.
482 (define_attr "late_fp_use" "yes,no" (const_string "no"))
483 ;; And feeding insns for which this relevant.
484 (define_attr "any_fp_comp" "yes,no"
485   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
486          (const_string "yes")]
487         (const_string "no")))
489 (define_attr "any_int_load" "yes,no"
490   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
491          (const_string "yes")]
492         (const_string "no")))
494 (define_delay
495   (eq_attr "needs_delay_slot" "yes")
496   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
498 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
499 ;; and thus we can't put a pop instruction in its delay slot.
500 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
501 ;; instruction can go in the delay slot.
503 ;; Since a normal return (rts) implicitly uses the PR register,
504 ;; we can't allow PR register loads in an rts delay slot.
506 (define_delay
507   (eq_attr "type" "return")
508   [(and (eq_attr "in_delay_slot" "yes")
509         (ior (and (eq_attr "interrupt_function" "no")
510                   (eq_attr "type" "!pload,prset"))
511              (and (eq_attr "interrupt_function" "yes")
512                   (ior
513                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
514                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
516 ;; Since a call implicitly uses the PR register, we can't allow
517 ;; a PR register store in a jsr delay slot.
519 (define_delay
520   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
521   [(and (eq_attr "in_delay_slot" "yes")
522         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
524 ;; Say that we have annulled true branches, since this gives smaller and
525 ;; faster code when branches are predicted as not taken.
527 (define_delay
528   (and (eq_attr "type" "cbranch")
529        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
530   ;; SH2e has a hardware bug that pretty much prohibits the use of
531   ;; annuled delay slots.
532   [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
533                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
535 ;; -------------------------------------------------------------------------
536 ;; SImode signed integer comparisons
537 ;; -------------------------------------------------------------------------
539 (define_insn ""
540   [(set (reg:SI T_REG)
541         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
542                        (match_operand:SI 1 "arith_operand" "K08,r"))
543                (const_int 0)))]
544   "TARGET_SH1"
545   "tst  %1,%0"
546   [(set_attr "type" "mt_group")])
548 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
549 ;; That would still allow reload to create cmpi instructions, but would
550 ;; perhaps allow forcing the constant into a register when that is better.
551 ;; Probably should use r0 for mem/imm compares, but force constant into a
552 ;; register for pseudo/imm compares.
554 (define_insn "cmpeqsi_t"
555   [(set (reg:SI T_REG)
556         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
557                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
558   "TARGET_SH1"
559   "@
560         tst     %0,%0
561         cmp/eq  %1,%0
562         cmp/eq  %1,%0"
563    [(set_attr "type" "mt_group")])
565 (define_insn "cmpgtsi_t"
566   [(set (reg:SI T_REG)
567         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
568                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
569   "TARGET_SH1"
570   "@
571         cmp/gt  %1,%0
572         cmp/pl  %0"
573    [(set_attr "type" "mt_group")])
575 (define_insn "cmpgesi_t"
576   [(set (reg:SI T_REG)
577         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
578                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
579   "TARGET_SH1"
580   "@
581         cmp/ge  %1,%0
582         cmp/pz  %0"
583    [(set_attr "type" "mt_group")])
585 ;; -------------------------------------------------------------------------
586 ;; SImode unsigned integer comparisons
587 ;; -------------------------------------------------------------------------
589 (define_insn "cmpgeusi_t"
590   [(set (reg:SI T_REG)
591         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
592                 (match_operand:SI 1 "arith_reg_operand" "r")))]
593   "TARGET_SH1"
594   "cmp/hs       %1,%0"
595    [(set_attr "type" "mt_group")])
597 (define_insn "cmpgtusi_t"
598   [(set (reg:SI T_REG)
599         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
600                 (match_operand:SI 1 "arith_reg_operand" "r")))]
601   "TARGET_SH1"
602   "cmp/hi       %1,%0"
603    [(set_attr "type" "mt_group")])
605 ;; We save the compare operands in the cmpxx patterns and use them when
606 ;; we generate the branch.
608 (define_expand "cmpsi"
609   [(set (reg:SI T_REG)
610         (compare (match_operand:SI 0 "cmpsi_operand" "")
611                  (match_operand:SI 1 "arith_operand" "")))]
612   "TARGET_SH1"
613   "
615   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
616       && GET_CODE (operands[1]) != CONST_INT)
617     operands[0] = copy_to_mode_reg (SImode, operands[0]);
618   sh_compare_op0 = operands[0];
619   sh_compare_op1 = operands[1];
620   DONE;
623 ;; -------------------------------------------------------------------------
624 ;; DImode signed integer comparisons
625 ;; -------------------------------------------------------------------------
627 ;; ??? Could get better scheduling by splitting the initial test from the
628 ;; rest of the insn after reload.  However, the gain would hardly justify
629 ;; the sh.md size increase necessary to do that.
631 (define_insn ""
632   [(set (reg:SI T_REG)
633         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
634                        (match_operand:DI 1 "arith_operand" "r"))
635                (const_int 0)))]
636   "TARGET_SH1"
637   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
638                                  insn, operands);"
639   [(set_attr "length" "6")
640    (set_attr "type" "arith3b")])
642 (define_insn "cmpeqdi_t"
643   [(set (reg:SI T_REG)
644         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
645                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
646   "TARGET_SH1"
647   "@
648         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
649         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
650   [(set_attr "length" "6")
651    (set_attr "type" "arith3b")])
653 (define_split
654   [(set (reg:SI T_REG)
655         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
656                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
657 ;; If we applied this split when not optimizing, it would only be
658 ;; applied during the machine-dependent reorg, when no new basic blocks
659 ;; may be created.
660   "TARGET_SH1 && reload_completed && optimize"
661   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
662    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
663                            (label_ref (match_dup 6))
664                            (pc)))
665    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
666    (match_dup 6)]
667   "
669   operands[2]
670     = gen_rtx_REG (SImode,
671                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
672   operands[3]
673     = (operands[1] == const0_rtx
674        ? const0_rtx
675        : gen_rtx_REG (SImode,
676                       true_regnum (operands[1])
677                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
678   operands[4] = gen_lowpart (SImode, operands[0]);
679   operands[5] = gen_lowpart (SImode, operands[1]);
680   operands[6] = gen_label_rtx ();
683 (define_insn "cmpgtdi_t"
684   [(set (reg:SI T_REG)
685         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
686                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
687   "TARGET_SH2"
688   "@
689         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
690         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
691   [(set_attr "length" "8")
692    (set_attr "type" "arith3")])
694 (define_insn "cmpgedi_t"
695   [(set (reg:SI T_REG)
696         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
697                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
698   "TARGET_SH2"
699   "@
700         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
701         cmp/pz\\t%S0"
702   [(set_attr "length" "8,2")
703    (set_attr "type" "arith3,mt_group")])
705 ;; -------------------------------------------------------------------------
706 ;; DImode unsigned integer comparisons
707 ;; -------------------------------------------------------------------------
709 (define_insn "cmpgeudi_t"
710   [(set (reg:SI T_REG)
711         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
712                 (match_operand:DI 1 "arith_reg_operand" "r")))]
713   "TARGET_SH2"
714   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
715   [(set_attr "length" "8")
716    (set_attr "type" "arith3")])
718 (define_insn "cmpgtudi_t"
719   [(set (reg:SI T_REG)
720         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
721                 (match_operand:DI 1 "arith_reg_operand" "r")))]
722   "TARGET_SH2"
723   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
724   [(set_attr "length" "8")
725    (set_attr "type" "arith3")])
727 (define_insn "cmpeqdi_media"
728   [(set (match_operand:DI 0 "register_operand" "=r")
729         (eq:DI (match_operand:DI 1 "register_operand" "%r")
730                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
731   "TARGET_SHMEDIA"
732   "cmpeq        %1, %N2, %0"
733   [(set_attr "type" "cmp_media")])
735 (define_insn "cmpgtdi_media"
736   [(set (match_operand:DI 0 "register_operand" "=r")
737         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
738                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
739   "TARGET_SHMEDIA"
740   "cmpgt        %N1, %N2, %0"
741   [(set_attr "type" "cmp_media")])
743 (define_insn "cmpgtudi_media"
744   [(set (match_operand:DI 0 "register_operand" "=r")
745         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
746                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
747   "TARGET_SHMEDIA"
748   "cmpgtu       %N1, %N2, %0"
749   [(set_attr "type" "cmp_media")])
751 ;; We save the compare operands in the cmpxx patterns and use them when
752 ;; we generate the branch.
754 (define_expand "cmpdi"
755   [(set (reg:SI T_REG)
756         (compare (match_operand:DI 0 "arith_operand" "")
757                  (match_operand:DI 1 "arith_operand" "")))]
758   "TARGET_SH2 || TARGET_SHMEDIA"
759   "
761   sh_compare_op0 = operands[0];
762   sh_compare_op1 = operands[1];
763   DONE;
765 ;; -------------------------------------------------------------------------
766 ;; Conditional move instructions
767 ;; -------------------------------------------------------------------------
769 ;; The insn names may seem reversed, but note that cmveq performs the move
770 ;; if op1 == 0, and cmvne does it if op1 != 0.
772 (define_insn "movdicc_false"
773   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
774         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
775                              (const_int 0))
776          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
777          (match_operand:DI 3 "arith_reg_operand" "0")))]
778   "TARGET_SHMEDIA"
779   "cmveq        %1, %N2, %0"
780   [(set_attr "type" "arith_media")])
782 (define_insn "movdicc_true"
783   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
784         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
785                              (const_int 0))
786          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
787          (match_operand:DI 3 "arith_reg_operand" "0")))]
788   "TARGET_SHMEDIA"
789   "cmvne        %1, %N2, %0"
790   [(set_attr "type" "arith_media")])
792 (define_expand "movdicc"
793   [(set (match_operand:DI 0 "register_operand" "")
794         (if_then_else:DI (match_operand 1 "comparison_operator" "")
795                          (match_operand:DI 2 "register_operand" "")
796                          (match_operand:DI 3 "register_operand" "")))]
797   "TARGET_SHMEDIA"
798   "
800   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
801       && GET_MODE (sh_compare_op0) == DImode
802       && sh_compare_op1 == const0_rtx)
803     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
804                                   sh_compare_op0, sh_compare_op1);
805   else
806     {
807       rtx tmp;
809       if (no_new_pseudos)
810         FAIL;
812       tmp = gen_reg_rtx (DImode);
814       switch (GET_CODE (operands[1]))
815         {
816         case EQ:
817           emit_insn (gen_seq (tmp));
818           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
819           break;
821         case NE:
822           emit_insn (gen_seq (tmp));
823           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
824           break;
826         case GT:
827           emit_insn (gen_sgt (tmp));
828           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
829           break;
831         case LT:
832           emit_insn (gen_slt (tmp));
833           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
834           break;
836         case GE:
837           emit_insn (gen_slt (tmp));
838           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
839           break;
841         case LE:
842           emit_insn (gen_sgt (tmp));
843           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
844           break;
846         case GTU:
847           emit_insn (gen_sgtu (tmp));
848           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
849           break;
851         case LTU:
852           emit_insn (gen_sltu (tmp));
853           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
854           break;
856         case GEU:
857           emit_insn (gen_sltu (tmp));
858           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
859           break;
861         case LEU:
862           emit_insn (gen_sgtu (tmp));
863           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
864           break;
866         case UNORDERED:
867           emit_insn (gen_sunordered (tmp));
868           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
869           break;
871         case ORDERED:
872           emit_insn (gen_sunordered (tmp));
873           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
874           break;
876         case UNEQ:
877         case UNGE:
878         case UNGT:
879         case UNLE:
880         case UNLT:
881         case LTGT:
882           FAIL;
884         default:
885           abort ();
886         }
887     }
890 ;; -------------------------------------------------------------------------
891 ;; Addition instructions
892 ;; -------------------------------------------------------------------------
894 (define_expand "adddi3"
895   [(set (match_operand:DI 0 "arith_reg_operand" "")
896         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
897                  (match_operand:DI 2 "arith_operand" "")))]
898   ""
899   "
901   if (TARGET_SH1)
902     {
903       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
904         FAIL;
905       operands[2] = force_reg (DImode, operands[2]);
906       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
907       DONE;
908     }
911 (define_insn "*adddi3_media"
912   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
913         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
914                  (match_operand:DI 2 "arith_operand" "r,I10")))]
915   "TARGET_SHMEDIA"
916   "@
917         add     %1, %2, %0
918         addi    %1, %2, %0"
919   [(set_attr "type" "arith_media")])
921 (define_insn "adddi3z_media"
922   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
923         (zero_extend:DI
924          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
925                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
926   "TARGET_SHMEDIA"
927   "addz.l       %1, %N2, %0"
928   [(set_attr "type" "arith_media")])
930 (define_insn "adddi3_compact"
931   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
932         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
933                  (match_operand:DI 2 "arith_reg_operand" "r")))
934    (clobber (reg:SI T_REG))]
935   "TARGET_SH1"
936   "#"
937   [(set_attr "length" "6")])
939 (define_split
940   [(set (match_operand:DI 0 "arith_reg_operand" "")
941         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
942                  (match_operand:DI 2 "arith_reg_operand" "")))
943    (clobber (reg:SI T_REG))]
944   "TARGET_SH1 && reload_completed"
945   [(const_int 0)]
946   "
948   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
949   high0 = gen_rtx_REG (SImode,
950                        true_regnum (operands[0])
951                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
952   high2 = gen_rtx_REG (SImode,
953                        true_regnum (operands[2])
954                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
955   emit_insn (gen_clrt ());
956   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
957   emit_insn (gen_addc1 (high0, high0, high2));
958   DONE;
961 (define_insn "addc"
962   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
963         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
964                           (match_operand:SI 2 "arith_reg_operand" "r"))
965                  (reg:SI T_REG)))
966    (set (reg:SI T_REG)
967         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
968   "TARGET_SH1"
969   "addc %2,%0"
970   [(set_attr "type" "arith")])
972 (define_insn "addc1"
973   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
974         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
975                           (match_operand:SI 2 "arith_reg_operand" "r"))
976                  (reg:SI T_REG)))
977    (clobber (reg:SI T_REG))]
978   "TARGET_SH1"
979   "addc %2,%0"
980   [(set_attr "type" "arith")])
982 (define_expand "addsi3"
983   [(set (match_operand:SI 0 "arith_reg_operand" "")
984         (plus:SI (match_operand:SI 1 "arith_operand" "")
985                  (match_operand:SI 2 "arith_operand" "")))]
986   ""
987   "
989   if (TARGET_SHMEDIA)
990     operands[1] = force_reg (SImode, operands[1]);
993 (define_insn "addsi3_media"
994   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
995         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
996                  (match_operand:SI 2 "arith_operand" "r,I10")))]
997   "TARGET_SHMEDIA"
998   "@
999         add.l   %1, %2, %0
1000         addi.l  %1, %2, %0"
1001   [(set_attr "type" "arith_media")])
1003 (define_insn "*addsi3_compact"
1004   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1005         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1006                  (match_operand:SI 2 "arith_operand" "rI08")))]
1007   "TARGET_SH1"
1008   "add  %2,%0"
1009   [(set_attr "type" "arith")])
1011 ;; -------------------------------------------------------------------------
1012 ;; Subtraction instructions
1013 ;; -------------------------------------------------------------------------
1015 (define_expand "subdi3"
1016   [(set (match_operand:DI 0 "arith_reg_operand" "")
1017         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1018                   (match_operand:DI 2 "arith_reg_operand" "")))]
1019   ""
1020   "
1022   if (TARGET_SH1)
1023     {
1024       operands[1] = force_reg (DImode, operands[1]);
1025       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1026       DONE;
1027     }
1030 (define_insn "*subdi3_media"
1031   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1032         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1033                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1034   "TARGET_SHMEDIA"
1035   "sub  %N1, %2, %0"
1036   [(set_attr "type" "arith_media")])
1038 (define_insn "subdi3_compact"
1039   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1040         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1041                  (match_operand:DI 2 "arith_reg_operand" "r")))
1042    (clobber (reg:SI T_REG))]
1043   "TARGET_SH1"
1044   "#"
1045   [(set_attr "length" "6")])
1047 (define_split
1048   [(set (match_operand:DI 0 "arith_reg_operand" "")
1049         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1050                   (match_operand:DI 2 "arith_reg_operand" "")))
1051    (clobber (reg:SI T_REG))]
1052   "TARGET_SH1 && reload_completed"
1053   [(const_int 0)]
1054   "
1056   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1057   high0 = gen_rtx_REG (SImode,
1058                        true_regnum (operands[0])
1059                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1060   high2 = gen_rtx_REG (SImode,
1061                        true_regnum (operands[2])
1062                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1063   emit_insn (gen_clrt ());
1064   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1065   emit_insn (gen_subc1 (high0, high0, high2));
1066   DONE;
1069 (define_insn "subc"
1070   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1071         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1072                             (match_operand:SI 2 "arith_reg_operand" "r"))
1073                   (reg:SI T_REG)))
1074    (set (reg:SI T_REG)
1075         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1076                           (reg:SI T_REG))
1077                 (match_dup 1)))]
1078   "TARGET_SH1"
1079   "subc %2,%0"
1080   [(set_attr "type" "arith")])
1082 (define_insn "subc1"
1083   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1084         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1085                             (match_operand:SI 2 "arith_reg_operand" "r"))
1086                   (reg:SI T_REG)))
1087    (clobber (reg:SI T_REG))]
1088   "TARGET_SH1"
1089   "subc %2,%0"
1090   [(set_attr "type" "arith")])
1092 (define_insn "*subsi3_internal"
1093   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1094         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1095                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1096   "TARGET_SH1"
1097   "sub  %2,%0"
1098   [(set_attr "type" "arith")])
1100 (define_insn "*subsi3_media"
1101   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1102         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1103                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1104   "TARGET_SHMEDIA"
1105   "sub.l        %N1, %2, %0"
1106   [(set_attr "type" "arith_media")])
1108 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1109 ;; will sometimes save one instruction.  Otherwise we might get
1110 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1111 ;; are the same.
1113 (define_expand "subsi3"
1114   [(set (match_operand:SI 0 "arith_reg_operand" "")
1115         (minus:SI (match_operand:SI 1 "arith_operand" "")
1116                   (match_operand:SI 2 "arith_reg_operand" "")))]
1117   ""
1118   "
1120   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1121     {
1122       emit_insn (gen_negsi2 (operands[0], operands[2]));
1123       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1124       DONE;
1125     }
1126   if (TARGET_SHMEDIA)
1127     {
1128       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1129         FAIL;
1130       if (operands[1] != const0_rtx)
1131         operands[1] = force_reg (SImode, operands[1]);
1132     }
1135 ;; -------------------------------------------------------------------------
1136 ;; Division instructions
1137 ;; -------------------------------------------------------------------------
1139 ;; We take advantage of the library routines which don't clobber as many
1140 ;; registers as a normal function call would.
1142 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1143 ;; also has an effect on the register that holds the address of the sfunc.
1144 ;; To make this work, we have an extra dummy insn that shows the use
1145 ;; of this register for reorg.
1147 (define_insn "use_sfunc_addr"
1148   [(set (reg:SI PR_REG)
1149         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1150   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1151   ""
1152   [(set_attr "length" "0")])
1154 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1155 ;; hard register 0.  If we used hard register 0, then the next instruction
1156 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1157 ;; gets allocated to a stack slot that needs its address reloaded, then
1158 ;; there is nothing to prevent reload from using r0 to reload the address.
1159 ;; This reload would clobber the value in r0 we are trying to store.
1160 ;; If we let reload allocate r0, then this problem can never happen.
1162 (define_insn "udivsi3_i1"
1163   [(set (match_operand:SI 0 "register_operand" "=z")
1164         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1165    (clobber (reg:SI T_REG))
1166    (clobber (reg:SI PR_REG))
1167    (clobber (reg:SI R4_REG))
1168    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1169   "TARGET_SH1 && ! TARGET_SH4"
1170   "jsr  @%1%#"
1171   [(set_attr "type" "sfunc")
1172    (set_attr "needs_delay_slot" "yes")])
1174 ; Since shmedia-nofpu code could be linked against shcompact code, and
1175 ; the udivsi3 libcall has the same name, we must consider all registers
1176 ; clobbered that are in the union of the registers clobbered by the
1177 ; shmedia and the shcompact implementation.  Note, if the shcompact
1178 ; implementation actually used shcompact code, we'd need to clobber
1179 ; also r23 and fr23.
1180 (define_insn "udivsi3_i1_media"
1181   [(set (match_operand:SI 0 "register_operand" "=z")
1182         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1183    (clobber (reg:SI T_MEDIA_REG))
1184    (clobber (reg:SI PR_MEDIA_REG))
1185    (clobber (reg:SI R20_REG))
1186    (clobber (reg:SI R21_REG))
1187    (clobber (reg:SI R22_REG))
1188    (clobber (reg:DI TR0_REG))
1189    (clobber (reg:DI TR1_REG))
1190    (clobber (reg:DI TR2_REG))
1191    (use (match_operand:DI 1 "target_operand" "b"))]
1192   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1193   "blink        %1, r18"
1194   [(set_attr "type" "sfunc")
1195    (set_attr "needs_delay_slot" "yes")])
1197 (define_expand "udivsi3_i4_media"
1198   [(set (match_dup 3)
1199         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1200    (set (match_dup 4)
1201         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1202    (set (match_dup 5) (float:DF (match_dup 3)))
1203    (set (match_dup 6) (float:DF (match_dup 4)))
1204    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1205    (set (match_dup 8) (fix:DI (match_dup 7)))
1206    (set (match_operand:SI 0 "register_operand" "")
1207         (truncate:SI (match_dup 8)))]
1208   "TARGET_SHMEDIA_FPU"
1209   "
1211   operands[3] = gen_reg_rtx (DImode);
1212   operands[4] = gen_reg_rtx (DImode);
1213   operands[5] = gen_reg_rtx (DFmode);
1214   operands[6] = gen_reg_rtx (DFmode);
1215   operands[7] = gen_reg_rtx (DFmode);
1216   operands[8] = gen_reg_rtx (DImode);
1219 (define_insn "udivsi3_i4"
1220   [(set (match_operand:SI 0 "register_operand" "=y")
1221         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1222    (clobber (reg:SI T_REG))
1223    (clobber (reg:SI PR_REG))
1224    (clobber (reg:DF DR0_REG))
1225    (clobber (reg:DF DR2_REG))
1226    (clobber (reg:DF DR4_REG))
1227    (clobber (reg:SI R0_REG))
1228    (clobber (reg:SI R1_REG))
1229    (clobber (reg:SI R4_REG))
1230    (clobber (reg:SI R5_REG))
1231    (use (reg:PSI FPSCR_REG))
1232    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1233   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1234   "jsr  @%1%#"
1235   [(set_attr "type" "sfunc")
1236    (set_attr "fp_mode" "double")
1237    (set_attr "needs_delay_slot" "yes")])
1239 (define_insn "udivsi3_i4_single"
1240   [(set (match_operand:SI 0 "register_operand" "=y")
1241         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1242    (clobber (reg:SI T_REG))
1243    (clobber (reg:SI PR_REG))
1244    (clobber (reg:DF DR0_REG))
1245    (clobber (reg:DF DR2_REG))
1246    (clobber (reg:DF DR4_REG))
1247    (clobber (reg:SI R0_REG))
1248    (clobber (reg:SI R1_REG))
1249    (clobber (reg:SI R4_REG))
1250    (clobber (reg:SI R5_REG))
1251    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1252   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1253   "jsr  @%1%#"
1254   [(set_attr "type" "sfunc")
1255    (set_attr "needs_delay_slot" "yes")])
1257 (define_expand "udivsi3"
1258   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1259    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1260    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1261    (parallel [(set (match_operand:SI 0 "register_operand" "")
1262                    (udiv:SI (reg:SI R4_REG)
1263                             (reg:SI R5_REG)))
1264               (clobber (reg:SI T_REG))
1265               (clobber (reg:SI PR_REG))
1266               (clobber (reg:SI R4_REG))
1267               (use (match_dup 3))])]
1268   ""
1269   "
1271   rtx first, last;
1273   operands[3] = gen_reg_rtx (Pmode);
1274   /* Emit the move of the address to a pseudo outside of the libcall.  */
1275   if (TARGET_HARD_SH4 && TARGET_SH2E)
1276     {
1277       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1278       if (TARGET_FPU_SINGLE)
1279         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1280       else
1281         last = gen_udivsi3_i4 (operands[0], operands[3]);
1282     }
1283   else if (TARGET_SHMEDIA_FPU)
1284     {
1285       operands[1] = force_reg (SImode, operands[1]);
1286       operands[2] = force_reg (SImode, operands[2]);
1287       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1288       DONE;
1289     }
1290   else if (TARGET_SH5)
1291     {
1292       emit_move_insn (operands[3],
1293                       function_symbol (TARGET_FPU_ANY
1294                                        ? \"__udivsi3_i4\"
1295                                        : \"__udivsi3\"));
1297       if (TARGET_SHMEDIA)
1298         last = gen_udivsi3_i1_media (operands[0],
1299                                      Pmode == DImode
1300                                      ? operands[3]
1301                                      : gen_rtx_SUBREG (DImode, operands[3],
1302                                                        0));
1303       else if (TARGET_FPU_ANY)
1304         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1305       else
1306         last = gen_udivsi3_i1 (operands[0], operands[3]);
1307     }
1308   else
1309     {
1310       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1311       last = gen_udivsi3_i1 (operands[0], operands[3]);
1312     }
1313   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1314   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1315   last = emit_insn (last);
1316   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1317      invariant code motion can move it.  */
1318   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1319   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1320   DONE;
1323 (define_insn "divsi3_i1"
1324   [(set (match_operand:SI 0 "register_operand" "=z")
1325         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1326    (clobber (reg:SI T_REG))
1327    (clobber (reg:SI PR_REG))
1328    (clobber (reg:SI R1_REG))
1329    (clobber (reg:SI R2_REG))
1330    (clobber (reg:SI R3_REG))
1331    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1332   "TARGET_SH1 && ! TARGET_SH4"
1333   "jsr  @%1%#"
1334   [(set_attr "type" "sfunc")
1335    (set_attr "needs_delay_slot" "yes")])
1337 ; Since shmedia-nofpu code could be linked against shcompact code, and
1338 ; the sdivsi3 libcall has the same name, we must consider all registers
1339 ; clobbered that are in the union of the registers clobbered by the
1340 ; shmedia and the shcompact implementation.  Note, if the shcompact
1341 ; implementation actually used shcompact code, we'd need to clobber
1342 ; also r22, r23 and fr23.
1343 (define_insn "divsi3_i1_media"
1344   [(set (match_operand:SI 0 "register_operand" "=z")
1345         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1346    (clobber (reg:SI T_MEDIA_REG))
1347    (clobber (reg:SI PR_MEDIA_REG))
1348    (clobber (reg:SI R1_REG))
1349    (clobber (reg:SI R2_REG))
1350    (clobber (reg:SI R3_REG))
1351    (clobber (reg:SI R20_REG))
1352    (clobber (reg:SI R21_REG))
1353    (clobber (reg:DI TR0_REG))
1354    (clobber (reg:DI TR1_REG))
1355    (clobber (reg:DI TR2_REG))
1356    (use (match_operand:DI 1 "target_operand" "b"))]
1357   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1358   "blink        %1, r18"
1359   [(set_attr "type" "sfunc")])
1361 (define_expand "divsi3_i4_media"
1362   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1363    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1364    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1365    (set (match_operand:SI 0 "register_operand" "=r")
1366         (fix:SI (match_dup 5)))]
1367   "TARGET_SHMEDIA_FPU"
1368   "
1370   operands[3] = gen_reg_rtx (DFmode);
1371   operands[4] = gen_reg_rtx (DFmode);
1372   operands[5] = gen_reg_rtx (DFmode);
1375 (define_insn "divsi3_i4"
1376   [(set (match_operand:SI 0 "register_operand" "=y")
1377         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1378    (clobber (reg:SI PR_REG))
1379    (clobber (reg:DF DR0_REG))
1380    (clobber (reg:DF DR2_REG))
1381    (use (reg:PSI FPSCR_REG))
1382    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1383   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1384   "jsr  @%1%#"
1385   [(set_attr "type" "sfunc")
1386    (set_attr "fp_mode" "double")
1387    (set_attr "needs_delay_slot" "yes")])
1389 (define_insn "divsi3_i4_single"
1390   [(set (match_operand:SI 0 "register_operand" "=y")
1391         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1392    (clobber (reg:SI PR_REG))
1393    (clobber (reg:DF DR0_REG))
1394    (clobber (reg:DF DR2_REG))
1395    (clobber (reg:SI R2_REG))
1396    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1397   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1398   "jsr  @%1%#"
1399   [(set_attr "type" "sfunc")
1400    (set_attr "needs_delay_slot" "yes")])
1402 (define_expand "divsi3"
1403   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1404    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1405    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1406    (parallel [(set (match_operand:SI 0 "register_operand" "")
1407                    (div:SI (reg:SI R4_REG)
1408                            (reg:SI R5_REG)))
1409               (clobber (reg:SI T_REG))
1410               (clobber (reg:SI PR_REG))
1411               (clobber (reg:SI R1_REG))
1412               (clobber (reg:SI R2_REG))
1413               (clobber (reg:SI R3_REG))
1414               (use (match_dup 3))])]
1415   ""
1416   "
1418   rtx first, last;
1420   operands[3] = gen_reg_rtx (Pmode);
1421   /* Emit the move of the address to a pseudo outside of the libcall.  */
1422   if (TARGET_HARD_SH4 && TARGET_SH2E)
1423     {
1424       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1425       if (TARGET_FPU_SINGLE)
1426         last = gen_divsi3_i4_single (operands[0], operands[3]);
1427       else
1428         last = gen_divsi3_i4 (operands[0], operands[3]);
1429     }
1430   else if (TARGET_SHMEDIA_FPU)
1431     {
1432       operands[1] = force_reg (SImode, operands[1]);
1433       operands[2] = force_reg (SImode, operands[2]);
1434       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1435       DONE;
1436     }
1437   else if (TARGET_SH5)
1438     {
1439       emit_move_insn (operands[3],
1440                       function_symbol (TARGET_FPU_ANY
1441                                        ? \"__sdivsi3_i4\"
1442                                        : \"__sdivsi3\"));
1444       if (TARGET_SHMEDIA)
1445         last = gen_divsi3_i1_media (operands[0],
1446                                     Pmode == DImode
1447                                     ? operands[3]
1448                                     : gen_rtx_SUBREG (DImode, operands[3],
1449                                                       0));
1450       else if (TARGET_FPU_ANY)
1451         last = gen_divsi3_i4_single (operands[0], operands[3]);
1452       else
1453         last = gen_divsi3_i1 (operands[0], operands[3]);
1454     }
1455   else
1456     {
1457       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1458       last = gen_divsi3_i1 (operands[0], operands[3]);
1459     }
1460   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1461   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1462   last = emit_insn (last);
1463   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1464      invariant code motion can move it.  */
1465   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1466   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1467   DONE;
1470 ;; -------------------------------------------------------------------------
1471 ;; Multiplication instructions
1472 ;; -------------------------------------------------------------------------
1474 (define_insn "umulhisi3_i"
1475   [(set (reg:SI MACL_REG)
1476         (mult:SI (zero_extend:SI
1477                   (match_operand:HI 0 "arith_reg_operand" "r"))
1478                  (zero_extend:SI
1479                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1480   "TARGET_SH1"
1481   "mulu.w       %1,%0"
1482   [(set_attr "type" "smpy")])
1484 (define_insn "mulhisi3_i"
1485   [(set (reg:SI MACL_REG)
1486         (mult:SI (sign_extend:SI
1487                   (match_operand:HI 0 "arith_reg_operand" "r"))
1488                  (sign_extend:SI
1489                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1490   "TARGET_SH1"
1491   "muls.w       %1,%0"
1492   [(set_attr "type" "smpy")])
1494 (define_expand "mulhisi3"
1495   [(set (reg:SI MACL_REG)
1496         (mult:SI (sign_extend:SI
1497                   (match_operand:HI 1 "arith_reg_operand" ""))
1498                  (sign_extend:SI
1499                   (match_operand:HI 2 "arith_reg_operand" ""))))
1500    (set (match_operand:SI 0 "arith_reg_operand" "")
1501         (reg:SI MACL_REG))]
1502   "TARGET_SH1"
1503   "
1505   rtx first, last;
1507   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1508   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1509   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1510      invariant code motion can move it.  */
1511   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1512   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1513   /* expand_binop can't find a suitable code in umul_widen_optab to
1514      make a REG_EQUAL note from, so make one here.
1515      See also smulsi3_highpart.
1516      ??? Alternatively, we could put this at the calling site of expand_binop,
1517      i.e. expand_expr.  */
1518   REG_NOTES (last)
1519     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1520                          REG_NOTES (last));
1521   DONE;
1524 (define_expand "umulhisi3"
1525   [(set (reg:SI MACL_REG)
1526         (mult:SI (zero_extend:SI
1527                   (match_operand:HI 1 "arith_reg_operand" ""))
1528                  (zero_extend:SI
1529                   (match_operand:HI 2 "arith_reg_operand" ""))))
1530    (set (match_operand:SI 0 "arith_reg_operand" "")
1531         (reg:SI MACL_REG))]
1532   "TARGET_SH1"
1533   "
1535   rtx first, last;
1537   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1538   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1539   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1540      invariant code motion can move it.  */
1541   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1542   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1543   /* expand_binop can't find a suitable code in umul_widen_optab to
1544      make a REG_EQUAL note from, so make one here.
1545      See also smulsi3_highpart.
1546      ??? Alternatively, we could put this at the calling site of expand_binop,
1547      i.e. expand_expr.  */
1548   REG_NOTES (last)
1549     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1550                          REG_NOTES (last));
1551   DONE;
1554 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1555 ;; a call to a routine which clobbers known registers.
1557 (define_insn ""
1558   [(set (match_operand:SI 1 "register_operand" "=z")
1559         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1560    (clobber (reg:SI MACL_REG))
1561    (clobber (reg:SI T_REG))
1562    (clobber (reg:SI PR_REG))
1563    (clobber (reg:SI R3_REG))
1564    (clobber (reg:SI R2_REG))
1565    (clobber (reg:SI R1_REG))
1566    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1567   "TARGET_SH1"
1568   "jsr  @%0%#"
1569   [(set_attr "type" "sfunc")
1570    (set_attr "needs_delay_slot" "yes")])
1572 (define_expand "mulsi3_call"
1573   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1574    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1575    (parallel[(set (match_operand:SI 0 "register_operand" "")
1576                   (mult:SI (reg:SI R4_REG)
1577                            (reg:SI R5_REG)))
1578              (clobber (reg:SI MACL_REG))
1579              (clobber (reg:SI T_REG))
1580              (clobber (reg:SI PR_REG))
1581              (clobber (reg:SI R3_REG))
1582              (clobber (reg:SI R2_REG))
1583              (clobber (reg:SI R1_REG))
1584              (use (match_operand:SI 3 "register_operand" ""))])]
1585   "TARGET_SH1"
1586   "")
1588 (define_insn "mul_l"
1589   [(set (reg:SI MACL_REG)
1590         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1591                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1592   "TARGET_SH2"
1593   "mul.l        %1,%0"
1594   [(set_attr "type" "dmpy")])
1596 (define_expand "mulsi3"
1597   [(set (reg:SI MACL_REG)
1598         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1599                   (match_operand:SI 2 "arith_reg_operand" "")))
1600    (set (match_operand:SI 0 "arith_reg_operand" "")
1601         (reg:SI MACL_REG))]
1602   "TARGET_SH1"
1603   "
1605   rtx first, last;
1607   if (!TARGET_SH2)
1608     {
1609       /* The address must be set outside the libcall,
1610          since it goes into a pseudo.  */
1611       rtx sym = function_symbol (\"__mulsi3\");
1612       rtx addr = force_reg (SImode, sym);
1613       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1614                                    operands[2], addr);
1615       first = insns;
1616       last = emit_insn (insns);
1617     }
1618   else
1619     {
1620       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1622       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1623       /* consec_sets_giv can only recognize the first insn that sets a
1624          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1625          note.  */
1626       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1627     }
1628   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1629      invariant code motion can move it.  */
1630   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1631   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1632   DONE;
1635 (define_insn "mulsidi3_i"
1636   [(set (reg:SI MACH_REG)
1637         (truncate:SI
1638          (lshiftrt:DI
1639           (mult:DI
1640            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1641            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1642           (const_int 32))))
1643    (set (reg:SI MACL_REG)
1644         (mult:SI (match_dup 0)
1645                  (match_dup 1)))]
1646   "TARGET_SH2"
1647   "dmuls.l      %1,%0"
1648   [(set_attr "type" "dmpy")])
1650 (define_expand "mulsidi3"
1651   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1652         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1653                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1654   "TARGET_SH2 || TARGET_SHMEDIA"
1655   "
1657   if (TARGET_SH2)
1658     {
1659        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1660                                         operands[2]));
1661        DONE;
1662     }
1665 (define_insn "mulsidi3_media"
1666   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1667         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1668                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1669   "TARGET_SHMEDIA"
1670   "muls.l       %1, %2, %0"
1671   [(set_attr "type" "dmpy_media")])
1673 (define_insn "mulsidi3_compact"
1674   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1675         (mult:DI
1676          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1677          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1678    (clobber (reg:SI MACH_REG))
1679    (clobber (reg:SI MACL_REG))]
1680   "TARGET_SH2"
1681   "#")
1683 (define_split
1684   [(set (match_operand:DI 0 "arith_reg_operand" "")
1685         (mult:DI
1686          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1687          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1688    (clobber (reg:SI MACH_REG))
1689    (clobber (reg:SI MACL_REG))]
1690   "TARGET_SH2"
1691   [(const_int 0)]
1692   "
1694   rtx low_dst = gen_lowpart (SImode, operands[0]);
1695   rtx high_dst = gen_highpart (SImode, operands[0]);
1697   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1699   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1700   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1701   /* We need something to tag the possible REG_EQUAL notes on to.  */
1702   emit_move_insn (operands[0], operands[0]);
1703   DONE;
1706 (define_insn "umulsidi3_i"
1707   [(set (reg:SI MACH_REG)
1708         (truncate:SI
1709          (lshiftrt:DI
1710           (mult:DI
1711            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1712            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1713           (const_int 32))))
1714    (set (reg:SI MACL_REG)
1715         (mult:SI (match_dup 0)
1716                  (match_dup 1)))]
1717   "TARGET_SH2"
1718   "dmulu.l      %1,%0"
1719   [(set_attr "type" "dmpy")])
1721 (define_expand "umulsidi3"
1722   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1723         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1724                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1725   "TARGET_SH2 || TARGET_SHMEDIA"
1726   "
1728   if (TARGET_SH2)
1729     {
1730        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1731                                          operands[2]));
1732        DONE;
1733     }
1736 (define_insn "umulsidi3_media"
1737   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1738         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1739                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1740   "TARGET_SHMEDIA"
1741   "mulu.l       %1, %2, %0"
1742   [(set_attr "type" "dmpy_media")])
1744 (define_insn "umulsidi3_compact"
1745   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1746         (mult:DI
1747          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1748          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1749    (clobber (reg:SI MACH_REG))
1750    (clobber (reg:SI MACL_REG))]
1751   "TARGET_SH2"
1752   "#")
1754 (define_split
1755   [(set (match_operand:DI 0 "arith_reg_operand" "")
1756         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1757                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1758    (clobber (reg:SI MACH_REG))
1759    (clobber (reg:SI MACL_REG))]
1760   "TARGET_SH2"
1761   [(const_int 0)]
1762   "
1764   rtx low_dst = gen_lowpart (SImode, operands[0]);
1765   rtx high_dst = gen_highpart (SImode, operands[0]);
1767   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1769   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1770   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1771   /* We need something to tag the possible REG_EQUAL notes on to.  */
1772   emit_move_insn (operands[0], operands[0]);
1773   DONE;
1776 (define_insn "smulsi3_highpart_i"
1777   [(set (reg:SI MACH_REG)
1778         (truncate:SI
1779          (lshiftrt:DI
1780           (mult:DI
1781            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1782            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1783           (const_int 32))))
1784    (clobber (reg:SI MACL_REG))]
1785   "TARGET_SH2"
1786   "dmuls.l      %1,%0"
1787   [(set_attr "type" "dmpy")])
1789 (define_expand "smulsi3_highpart"
1790   [(parallel
1791     [(set (reg:SI MACH_REG)
1792           (truncate:SI
1793            (lshiftrt:DI
1794             (mult:DI
1795              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1796              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1797             (const_int 32))))
1798     (clobber (reg:SI MACL_REG))])
1799    (set (match_operand:SI 0 "arith_reg_operand" "")
1800         (reg:SI MACH_REG))]
1801   "TARGET_SH2"
1802   "
1804   rtx first, last;
1806   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1807   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1808   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1809      invariant code motion can move it.  */
1810   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1811   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1812   /* expand_binop can't find a suitable code in mul_highpart_optab to
1813      make a REG_EQUAL note from, so make one here.
1814      See also {,u}mulhisi.
1815      ??? Alternatively, we could put this at the calling site of expand_binop,
1816      i.e. expand_mult_highpart.  */
1817   REG_NOTES (last)
1818     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1819                          REG_NOTES (last));
1820   DONE;
1823 (define_insn "umulsi3_highpart_i"
1824   [(set (reg:SI MACH_REG)
1825         (truncate:SI
1826          (lshiftrt:DI
1827           (mult:DI
1828            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1829            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1830           (const_int 32))))
1831    (clobber (reg:SI MACL_REG))]
1832   "TARGET_SH2"
1833   "dmulu.l      %1,%0"
1834   [(set_attr "type" "dmpy")])
1836 (define_expand "umulsi3_highpart"
1837   [(parallel
1838     [(set (reg:SI MACH_REG)
1839           (truncate:SI
1840            (lshiftrt:DI
1841             (mult:DI
1842              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1843              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1844             (const_int 32))))
1845     (clobber (reg:SI MACL_REG))])
1846    (set (match_operand:SI 0 "arith_reg_operand" "")
1847         (reg:SI MACH_REG))]
1848   "TARGET_SH2"
1849   "
1851   rtx first, last;
1853   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1854   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1855   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1856      invariant code motion can move it.  */
1857   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1858   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1859   DONE;
1862 ;; -------------------------------------------------------------------------
1863 ;; Logical operations
1864 ;; -------------------------------------------------------------------------
1866 (define_insn "*andsi3_compact"
1867   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1868         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1869                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1870   "TARGET_SH1"
1871   "and  %2,%0"
1872   [(set_attr "type" "arith")])
1874 ;; If the constant is 255, then emit an extu.b instruction instead of an
1875 ;; and, since that will give better code.
1877 (define_expand "andsi3"
1878   [(set (match_operand:SI 0 "arith_reg_operand" "")
1879         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1880                 (match_operand:SI 2 "logical_operand" "")))]
1881   "TARGET_SH1"
1882   "
1884   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1885     {
1886       emit_insn (gen_zero_extendqisi2 (operands[0],
1887                                        gen_lowpart (QImode, operands[1])));
1888       DONE;
1889     }
1892 (define_insn_and_split "anddi3"
1893   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1894         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1895                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1896   "TARGET_SHMEDIA"
1897   "@
1898         and     %1, %2, %0
1899         andi    %1, %2, %0
1900         #"
1901   "reload_completed
1902    && ! logical_operand (operands[2], DImode)"
1903   [(const_int 0)]
1904   "
1906   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1907     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1908   else
1909     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1910   DONE;
1912   [(set_attr "type" "arith_media")])
1914 (define_insn "andcdi3"
1915   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1916         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
1917                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
1918   "TARGET_SHMEDIA"
1919   "andc %1,%2,%0"
1920   [(set_attr "type" "arith_media")])
1922 (define_insn "iorsi3"
1923   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1924         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1925                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1926   "TARGET_SH1"
1927   "or   %2,%0"
1928   [(set_attr "type" "arith")])
1930 (define_insn "iordi3"
1931   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1932         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1933                 (match_operand:DI 2 "logical_operand" "r,I10")))]
1934   "TARGET_SHMEDIA"
1935   "@
1936         or      %1, %2, %0
1937         ori     %1, %2, %0"
1938   [(set_attr "type" "arith_media")])
1940 (define_insn "xorsi3"
1941   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
1942         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1943                 (match_operand:SI 2 "logical_operand" "K08,r")))]
1944   "TARGET_SH1"
1945   "xor  %2,%0"
1946   [(set_attr "type" "arith")])
1948 (define_insn "xordi3"
1949   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1950         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1951                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
1952   "TARGET_SHMEDIA"
1953   "@
1954         xor     %1, %2, %0
1955         xori    %1, %2, %0"
1956   [(set_attr "type" "arith_media")])
1958 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
1959 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
1960 (define_split
1961   [(set (match_operand:DI 0 "arith_reg_operand" "")
1962         (sign_extend:DI (match_operator 4 "binary_logical_operator"
1963                           [(match_operand 1 "any_register_operand" "")
1964                            (match_operand 2 "any_register_operand" "")])))]
1965   "TARGET_SHMEDIA"
1966   [(set (match_dup 5) (match_dup 4))
1967    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
1970   enum machine_mode inmode = GET_MODE (operands[1]);
1971   int offset = 0;
1973   if (GET_CODE (operands[0]) == SUBREG)
1974     {
1975       offset = SUBREG_BYTE (operands[0]);
1976       operands[0] = SUBREG_REG (operands[0]);
1977     }
1978   if (GET_CODE (operands[0]) != REG)
1979     abort ();
1980   if (! TARGET_LITTLE_ENDIAN)
1981     offset += 8 - GET_MODE_SIZE (inmode);
1982   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
1985 ;; -------------------------------------------------------------------------
1986 ;; Shifts and rotates
1987 ;; -------------------------------------------------------------------------
1989 (define_expand "rotldi3"
1990   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1991         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
1992                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
1993   "TARGET_SHMEDIA"
1994   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
1996 (define_insn "rotldi3_mextr"
1997   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1998         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
1999                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2000   "TARGET_SHMEDIA"
2001   "*
2003   static char templ[16];
2005   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2006            8 - (int) (INTVAL (operands[2]) >> 3));
2007   return templ;
2009   [(set_attr "type" "arith_media")])
2011 (define_expand "rotrdi3"
2012   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2013         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2014                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2015   "TARGET_SHMEDIA"
2016   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2018 (define_insn "rotrdi3_mextr"
2019   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2020         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2021                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2022   "TARGET_SHMEDIA"
2023   "*
2025   static char templ[16];
2027   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2028   return templ;
2030   [(set_attr "type" "arith_media")])
2032 (define_insn "rotlsi3_1"
2033   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2034         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2035                    (const_int 1)))
2036    (set (reg:SI T_REG)
2037         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2038   "TARGET_SH1"
2039   "rotl %0"
2040   [(set_attr "type" "arith")])
2042 (define_insn "rotlsi3_31"
2043   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2044         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2045                    (const_int 31)))
2046    (clobber (reg:SI T_REG))]
2047   "TARGET_SH1"
2048   "rotr %0"
2049   [(set_attr "type" "arith")])
2051 (define_insn "rotlsi3_16"
2052   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2053         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2054                    (const_int 16)))]
2055   "TARGET_SH1"
2056   "swap.w       %1,%0"
2057   [(set_attr "type" "arith")])
2059 (define_expand "rotlsi3"
2060   [(set (match_operand:SI 0 "arith_reg_operand" "")
2061         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2062                    (match_operand:SI 2 "immediate_operand" "")))]
2063   "TARGET_SH1"
2064   "
2066   static const char rot_tab[] = {
2067     000, 000, 000, 000, 000, 000, 010, 001,
2068     001, 001, 011, 013, 003, 003, 003, 003,
2069     003, 003, 003, 003, 003, 013, 012, 002,
2070     002, 002, 010, 000, 000, 000, 000, 000,
2071   };
2073   int count, choice;
2075   if (GET_CODE (operands[2]) != CONST_INT)
2076     FAIL;
2077   count = INTVAL (operands[2]);
2078   choice = rot_tab[count];
2079   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2080     FAIL;
2081   choice &= 7;
2082   switch (choice)
2083     {
2084     case 0:
2085       emit_move_insn (operands[0], operands[1]);
2086       count -= (count & 16) * 2;
2087       break;
2088     case 3:
2089      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2090      count -= 16;
2091      break;
2092     case 1:
2093     case 2:
2094       {
2095         rtx parts[2];
2096         parts[0] = gen_reg_rtx (SImode);
2097         parts[1] = gen_reg_rtx (SImode);
2098         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2099         emit_move_insn (parts[choice-1], operands[1]);
2100         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2101         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2102         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2103         count = (count & ~16) - 8;
2104       }
2105     }
2107   for (; count > 0; count--)
2108     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2109   for (; count < 0; count++)
2110     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2112   DONE;
2115 (define_insn "*rotlhi3_8"
2116   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2117         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2118                    (const_int 8)))]
2119   "TARGET_SH1"
2120   "swap.b       %1,%0"
2121   [(set_attr "type" "arith")])
2123 (define_expand "rotlhi3"
2124   [(set (match_operand:HI 0 "arith_reg_operand" "")
2125         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2126                    (match_operand:HI 2 "immediate_operand" "")))]
2127   "TARGET_SH1"
2128   "
2130   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2131     FAIL;
2135 ;; shift left
2137 ;; This pattern is used by init_expmed for computing the costs of shift
2138 ;; insns.
2140 (define_insn_and_split "ashlsi3_std"
2141   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2142         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2143                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2144    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2145   "TARGET_SH3
2146    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2147        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2148   "@
2149    shld %2,%0
2150    add  %0,%0
2151    shll%O2      %0
2152    #"
2153   "TARGET_SH3
2154    && reload_completed
2155    && GET_CODE (operands[2]) == CONST_INT
2156    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2157   [(set (match_dup 3) (match_dup 2))
2158    (parallel
2159     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2160      (clobber (match_dup 4))])]
2161   "operands[4] = gen_rtx_SCRATCH (SImode);"
2162   [(set_attr "length" "*,*,*,4")
2163    (set_attr "type" "dyn_shift,arith,arith,arith")])
2165 (define_insn "ashlhi3_k"
2166   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2167         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2168                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2169   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2170   "@
2171         add     %0,%0
2172         shll%O2 %0"
2173   [(set_attr "type" "arith")])
2175 (define_insn "ashlsi3_n"
2176   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2177         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2178                    (match_operand:SI 2 "const_int_operand" "n")))
2179    (clobber (reg:SI T_REG))]
2180   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2181   "#"
2182   [(set (attr "length")
2183         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2184                (const_string "2")
2185                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2186                (const_string "4")
2187                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2188                (const_string "6")]
2189               (const_string "8")))
2190    (set_attr "type" "arith")])
2192 (define_split
2193   [(set (match_operand:SI 0 "arith_reg_operand" "")
2194         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2195                    (match_operand:SI 2 "const_int_operand" "")))
2196    (clobber (reg:SI T_REG))]
2197   "TARGET_SH1 && reload_completed"
2198   [(use (reg:SI R0_REG))]
2199   "
2201   gen_shifty_op (ASHIFT, operands);
2202   DONE;
2205 (define_insn "ashlsi3_media"
2206   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2207         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2208                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2209   "TARGET_SHMEDIA"
2210   "@
2211         shlld.l %1, %2, %0
2212         shlli.l %1, %2, %0"
2213   [(set_attr "type" "arith_media")])
2215 (define_expand "ashlsi3"
2216   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2217                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2218                               (match_operand:SI 2 "nonmemory_operand" "")))
2219               (clobber (reg:SI T_REG))])]
2220   ""
2221   "
2223   if (TARGET_SHMEDIA)
2224     {
2225       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2226       DONE;
2227     }
2228   if (GET_CODE (operands[2]) == CONST_INT
2229       && sh_dynamicalize_shift_p (operands[2]))
2230     operands[2] = force_reg (SImode, operands[2]);
2231   if (TARGET_SH3)
2232     {
2233       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2234       DONE;
2235     }
2236   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2237     FAIL;
2240 (define_insn "ashlhi3"
2241   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2242         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2243                    (match_operand:HI 2 "const_int_operand" "n")))
2244    (clobber (reg:SI T_REG))]
2245   "TARGET_SH1"
2246   "#"
2247   [(set (attr "length")
2248         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2249                (const_string "2")
2250                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2251                (const_string "4")]
2252               (const_string "6")))
2253    (set_attr "type" "arith")])
2255 (define_split
2256   [(set (match_operand:HI 0 "arith_reg_operand" "")
2257         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2258                    (match_operand:HI 2 "const_int_operand" "")))
2259    (clobber (reg:SI T_REG))]
2260   "TARGET_SH1 && reload_completed"
2261   [(use (reg:SI R0_REG))]
2262   "
2264   gen_shifty_hi_op (ASHIFT, operands);
2265   DONE;
2269 ; arithmetic shift right
2272 (define_insn "ashrsi3_k"
2273   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2274         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2275                      (match_operand:SI 2 "const_int_operand" "M")))
2276    (clobber (reg:SI T_REG))]
2277   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2278   "shar %0"
2279   [(set_attr "type" "arith")])
2281 ;; We can't do HImode right shifts correctly unless we start out with an
2282 ;; explicit zero / sign extension; doing that would result in worse overall
2283 ;; code, so just let the machine independent code widen the mode.
2284 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2287 ;; ??? This should be a define expand.
2289 (define_insn "ashrsi2_16"
2290   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2291         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2292                      (const_int 16)))]
2293   "TARGET_SH1"
2294   "#"
2295   [(set_attr "length" "4")])
2297 (define_split
2298   [(set (match_operand:SI 0 "arith_reg_operand" "")
2299         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2300                      (const_int 16)))]
2301   "TARGET_SH1"
2302   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2303    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2304   "operands[2] = gen_lowpart (HImode, operands[0]);")
2306 ;; ??? This should be a define expand.
2308 (define_insn "ashrsi2_31"
2309   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2310         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2311                      (const_int 31)))
2312    (clobber (reg:SI T_REG))]
2313   "TARGET_SH1"
2314   "#"
2315   [(set_attr "length" "4")])
2317 (define_split
2318   [(set (match_operand:SI 0 "arith_reg_operand" "")
2319         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2320                      (const_int 31)))
2321    (clobber (reg:SI T_REG))]
2322   "TARGET_SH1"
2323   [(const_int 0)]
2324   "
2326   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2327   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2328   DONE;
2331 (define_insn "ashlsi_c"
2332   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2333         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2334    (set (reg:SI T_REG)
2335         (lt:SI (match_dup 1) (const_int 0)))]
2336   "TARGET_SH1"
2337   "shll %0"
2338   [(set_attr "type" "arith")])
2340 (define_insn "ashrsi3_d"
2341   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2342         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2343                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2344   "TARGET_SH3"
2345   "shad %2,%0"
2346   [(set_attr "type" "dyn_shift")])
2348 (define_insn "ashrsi3_n"
2349   [(set (reg:SI R4_REG)
2350         (ashiftrt:SI (reg:SI R4_REG)
2351                      (match_operand:SI 0 "const_int_operand" "i")))
2352    (clobber (reg:SI T_REG))
2353    (clobber (reg:SI PR_REG))
2354    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2355   "TARGET_SH1"
2356   "jsr  @%1%#"
2357   [(set_attr "type" "sfunc")
2358    (set_attr "needs_delay_slot" "yes")])
2360 (define_insn "ashrsi3_media"
2361   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2362         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2363                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2364   "TARGET_SHMEDIA"
2365   "@
2366         shard.l %1, %2, %0
2367         shari.l %1, %2, %0"
2368   [(set_attr "type" "arith_media")])
2370 (define_expand "ashrsi3"
2371   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2372                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2373                                 (match_operand:SI 2 "nonmemory_operand" "")))
2374               (clobber (reg:SI T_REG))])]
2375   ""
2376   "
2378   if (TARGET_SHMEDIA)
2379     {
2380       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2381       DONE;
2382     }
2383   if (expand_ashiftrt (operands))
2384     DONE;
2385   else
2386     FAIL;
2389 ;; logical shift right
2391 (define_insn "lshrsi3_d"
2392   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2393         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2394                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2395   "TARGET_SH3"
2396   "shld %2,%0"
2397   [(set_attr "type" "dyn_shift")])
2399 ;;  Only the single bit shift clobbers the T bit.
2401 (define_insn "lshrsi3_m"
2402   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2403         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2404                      (match_operand:SI 2 "const_int_operand" "M")))
2405    (clobber (reg:SI T_REG))]
2406   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2407   "shlr %0"
2408   [(set_attr "type" "arith")])
2410 (define_insn "lshrsi3_k"
2411   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2412         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2413                      (match_operand:SI 2 "const_int_operand" "P27")))]
2414   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2415    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2416   "shlr%O2      %0"
2417   [(set_attr "type" "arith")])
2419 (define_insn "lshrsi3_n"
2420   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2421         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2422                      (match_operand:SI 2 "const_int_operand" "n")))
2423    (clobber (reg:SI T_REG))]
2424   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2425   "#"
2426   [(set (attr "length")
2427         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2428                (const_string "2")
2429                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2430                (const_string "4")
2431                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2432                (const_string "6")]
2433               (const_string "8")))
2434    (set_attr "type" "arith")])
2436 (define_split
2437   [(set (match_operand:SI 0 "arith_reg_operand" "")
2438         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2439                      (match_operand:SI 2 "const_int_operand" "")))
2440    (clobber (reg:SI T_REG))]
2441   "TARGET_SH1 && reload_completed"
2442   [(use (reg:SI R0_REG))]
2443   "
2445   gen_shifty_op (LSHIFTRT, operands);
2446   DONE;
2449 (define_insn "lshrsi3_media"
2450   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2451         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2452                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2453   "TARGET_SHMEDIA"
2454   "@
2455         shlrd.l %1, %2, %0
2456         shlri.l %1, %2, %0"
2457   [(set_attr "type" "arith_media")])
2459 (define_expand "lshrsi3"
2460   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2461                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2462                                 (match_operand:SI 2 "nonmemory_operand" "")))
2463               (clobber (reg:SI T_REG))])]
2464   ""
2465   "
2467   if (TARGET_SHMEDIA)
2468     {
2469       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2470       DONE;
2471     }
2472   if (GET_CODE (operands[2]) == CONST_INT
2473       && sh_dynamicalize_shift_p (operands[2]))
2474     operands[2] = force_reg (SImode, operands[2]);
2475   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2476     {
2477       rtx count = copy_to_mode_reg (SImode, operands[2]);
2478       emit_insn (gen_negsi2 (count, count));
2479       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2480       DONE;
2481     }
2482   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2483     FAIL;
2486 ;; ??? This should be a define expand.
2488 (define_insn "ashldi3_k"
2489   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2490         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2491                    (const_int 1)))
2492    (clobber (reg:SI T_REG))]
2493   "TARGET_SH1"
2494   "shll %R0\;rotcl      %S0"
2495   [(set_attr "length" "4")
2496    (set_attr "type" "arith")])
2498 (define_insn "ashldi3_media"
2499   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2500         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2501                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2502   "TARGET_SHMEDIA"
2503   "@
2504         shlld   %1, %2, %0
2505         shlli   %1, %2, %0"
2506   [(set_attr "type" "arith_media")])
2508 (define_expand "ashldi3"
2509   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2510                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2511                               (match_operand:DI 2 "immediate_operand" "")))
2512               (clobber (reg:SI T_REG))])]
2513   ""
2514   "
2516   if (TARGET_SHMEDIA)
2517     {
2518       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2519       DONE;
2520     }
2521   if (GET_CODE (operands[2]) != CONST_INT
2522       || INTVAL (operands[2]) != 1)
2523     FAIL;
2526 ;; ??? This should be a define expand.
2528 (define_insn "lshrdi3_k"
2529   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2530         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2531                      (const_int 1)))
2532    (clobber (reg:SI T_REG))]
2533   "TARGET_SH1"
2534   "shlr %S0\;rotcr      %R0"
2535   [(set_attr "length" "4")
2536    (set_attr "type" "arith")])
2538 (define_insn "lshrdi3_media"
2539   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2540         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2541                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2542   "TARGET_SHMEDIA"
2543   "@
2544         shlrd   %1, %2, %0
2545         shlri   %1, %2, %0"
2546   [(set_attr "type" "arith_media")])
2548 (define_expand "lshrdi3"
2549   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2550                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2551                                (match_operand:DI 2 "immediate_operand" "")))
2552              (clobber (reg:SI T_REG))])]
2553   ""
2554   "
2556   if (TARGET_SHMEDIA)
2557     {
2558       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2559       DONE;
2560     }
2561   if (GET_CODE (operands[2]) != CONST_INT
2562       || INTVAL (operands[2]) != 1)
2563     FAIL;
2566 ;; ??? This should be a define expand.
2568 (define_insn "ashrdi3_k"
2569   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2570         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2571                      (const_int 1)))
2572    (clobber (reg:SI T_REG))]
2573   "TARGET_SH1"
2574   "shar %S0\;rotcr      %R0"
2575   [(set_attr "length" "4")
2576    (set_attr "type" "arith")])
2578 (define_insn "ashrdi3_media"
2579   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2580         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2581                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2582   "TARGET_SHMEDIA"
2583   "@
2584         shard   %1, %2, %0
2585         shari   %1, %2, %0"
2586   [(set_attr "type" "arith_media")])
2588 (define_expand "ashrdi3"
2589   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2590                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2591                                 (match_operand:DI 2 "immediate_operand" "")))
2592               (clobber (reg:SI T_REG))])]
2593   ""
2594   "
2596   if (TARGET_SHMEDIA)
2597     {
2598       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2599       DONE;
2600     }
2601   if (GET_CODE (operands[2]) != CONST_INT
2602       || INTVAL (operands[2]) != 1)
2603     FAIL;
2606 ;; combined left/right shift
2608 (define_split
2609   [(set (match_operand:SI 0 "register_operand" "")
2610         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2611                            (match_operand:SI 2 "const_int_operand" ""))
2612                 (match_operand:SI 3 "const_int_operand" "")))]
2613   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2614   [(use (reg:SI R0_REG))]
2615   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2616    DONE;")
2618 (define_split
2619   [(set (match_operand:SI 0 "register_operand" "")
2620         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2621                            (match_operand:SI 2 "const_int_operand" ""))
2622                 (match_operand:SI 3 "const_int_operand" "")))
2623    (clobber (reg:SI T_REG))]
2624   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2625   [(use (reg:SI R0_REG))]
2626   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2627    DONE;")
2629 (define_insn ""
2630   [(set (match_operand:SI 0 "register_operand" "=r")
2631         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2632                            (match_operand:SI 2 "const_int_operand" "n"))
2633                 (match_operand:SI 3 "const_int_operand" "n")))
2634    (clobber (reg:SI T_REG))]
2635   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2636  "#"
2637   [(set (attr "length")
2638         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2639                (const_string "4")
2640                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2641                (const_string "6")
2642                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2643                (const_string "8")
2644                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2645                (const_string "10")
2646                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2647                (const_string "12")
2648                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2649                (const_string "14")
2650                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2651                (const_string "16")]
2652               (const_string "18")))
2653    (set_attr "type" "arith")])
2655 (define_insn ""
2656   [(set (match_operand:SI 0 "register_operand" "=z")
2657         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2658                            (match_operand:SI 2 "const_int_operand" "n"))
2659                 (match_operand:SI 3 "const_int_operand" "n")))
2660    (clobber (reg:SI T_REG))]
2661   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2662  "#"
2663   [(set (attr "length")
2664         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2665                (const_string "4")
2666                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2667                (const_string "6")
2668                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2669                (const_string "8")]
2670               (const_string "10")))
2671    (set_attr "type" "arith")])
2673 ;; shift left / and combination with a scratch register: The combine pass
2674 ;; does not accept the individual instructions, even though they are
2675 ;; cheap.  But it needs a precise description so that it is usable after
2676 ;; reload.
2677 (define_insn "and_shl_scratch"
2678   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2679         (lshiftrt:SI
2680          (ashift:SI
2681           (and:SI
2682            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2683                         (match_operand:SI 2 "const_int_operand" "N,n"))
2684            (match_operand:SI 3 "" "0,r"))
2685           (match_operand:SI 4 "const_int_operand" "n,n"))
2686          (match_operand:SI 5 "const_int_operand" "n,n")))
2687    (clobber (reg:SI T_REG))]
2688   "TARGET_SH1"
2689   "#"
2690   [(set (attr "length")
2691         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2692                (const_string "4")
2693                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2694                (const_string "6")
2695                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2696                (const_string "8")
2697                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2698                (const_string "10")]
2699               (const_string "12")))
2700    (set_attr "type" "arith")])
2702 (define_split
2703   [(set (match_operand:SI 0 "register_operand" "")
2704         (lshiftrt:SI
2705          (ashift:SI
2706           (and:SI
2707            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2708                         (match_operand:SI 2 "const_int_operand" ""))
2709            (match_operand:SI 3 "register_operand" ""))
2710           (match_operand:SI 4 "const_int_operand" ""))
2711          (match_operand:SI 5 "const_int_operand" "")))
2712    (clobber (reg:SI T_REG))]
2713   "TARGET_SH1"
2714   [(use (reg:SI R0_REG))]
2715   "
2717   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2719   if (INTVAL (operands[2]))
2720     {
2721       gen_shifty_op (LSHIFTRT, operands);
2722     }
2723   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2724   operands[2] = operands[4];
2725   gen_shifty_op (ASHIFT, operands);
2726   if (INTVAL (operands[5]))
2727     {
2728       operands[2] = operands[5];
2729       gen_shifty_op (LSHIFTRT, operands);
2730     }
2731   DONE;
2734 ;; signed left/right shift combination.
2735 (define_split
2736   [(set (match_operand:SI 0 "register_operand" "")
2737         (sign_extract:SI
2738          (ashift:SI (match_operand:SI 1 "register_operand" "")
2739                     (match_operand:SI 2 "const_int_operand" ""))
2740          (match_operand:SI 3 "const_int_operand" "")
2741          (const_int 0)))
2742    (clobber (reg:SI T_REG))]
2743   "TARGET_SH1"
2744   [(use (reg:SI R0_REG))]
2745   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2746    DONE;")
2748 (define_insn "shl_sext_ext"
2749   [(set (match_operand:SI 0 "register_operand" "=r")
2750         (sign_extract:SI
2751          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2752                     (match_operand:SI 2 "const_int_operand" "n"))
2753          (match_operand:SI 3 "const_int_operand" "n")
2754          (const_int 0)))
2755    (clobber (reg:SI T_REG))]
2756   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2757   "#"
2758   [(set (attr "length")
2759         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2760                (const_string "2")
2761                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2762                (const_string "4")
2763                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2764                (const_string "6")
2765                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2766                (const_string "8")
2767                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2768                (const_string "10")
2769                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2770                (const_string "12")
2771                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2772                (const_string "14")
2773                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2774                (const_string "16")]
2775               (const_string "18")))
2776     (set_attr "type" "arith")])
2778 (define_insn "shl_sext_sub"
2779   [(set (match_operand:SI 0 "register_operand" "=z")
2780         (sign_extract:SI
2781          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2782                     (match_operand:SI 2 "const_int_operand" "n"))
2783          (match_operand:SI 3 "const_int_operand" "n")
2784          (const_int 0)))
2785    (clobber (reg:SI T_REG))]
2786   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2787   "#"
2788   [(set (attr "length")
2789         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2790                (const_string "6")
2791                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2792                (const_string "8")
2793                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2794                (const_string "10")
2795                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2796                (const_string "12")]
2797               (const_string "14")))
2798     (set_attr "type" "arith")])
2800 ;; These patterns are found in expansions of DImode shifts by 16, and
2801 ;; allow the xtrct instruction to be generated from C source.
2803 (define_insn "xtrct_left"
2804   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2805         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2806                            (const_int 16))
2807                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2808                              (const_int 16))))]
2809   "TARGET_SH1"
2810   "xtrct        %1,%0"
2811   [(set_attr "type" "arith")])
2813 (define_insn "xtrct_right"
2814   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2815         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2816                              (const_int 16))
2817                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2818                            (const_int 16))))]
2819   "TARGET_SH1"
2820   "xtrct        %2,%0"
2821   [(set_attr "type" "arith")])
2823 ;; -------------------------------------------------------------------------
2824 ;; Unary arithmetic
2825 ;; -------------------------------------------------------------------------
2827 (define_insn "negc"
2828   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2829         (neg:SI (plus:SI (reg:SI T_REG)
2830                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2831    (set (reg:SI T_REG)
2832         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2833                (const_int 0)))]
2834   "TARGET_SH1"
2835   "negc %1,%0"
2836   [(set_attr "type" "arith")])
2838 (define_insn "*negdi_media"
2839   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2840         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2841   "TARGET_SHMEDIA"
2842   "sub  r63, %1, %0"
2843   [(set_attr "type" "arith_media")])
2845 (define_expand "negdi2"
2846   [(set (match_operand:DI 0 "arith_reg_operand" "")
2847         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2848   ""
2849   "
2851   if (TARGET_SH1)
2852     {
2853       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2854       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2856       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2857       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2859       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2860       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2862       emit_insn (gen_clrt ());
2863       emit_insn (gen_negc (low_dst, low_src));
2864       emit_insn (gen_negc (high_dst, high_src));
2865       DONE;
2866     }
2869 (define_insn "negsi2"
2870   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2871         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2872   "TARGET_SH1"
2873   "neg  %1,%0"
2874   [(set_attr "type" "arith")])
2876 (define_insn "one_cmplsi2"
2877   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2878         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2879   "TARGET_SH1"
2880   "not  %1,%0"
2881   [(set_attr "type" "arith")])
2883 (define_expand "one_cmpldi2"
2884   [(set (match_operand:DI 0 "arith_reg_operand" "")
2885         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2886                 (const_int -1)))]
2887   "TARGET_SHMEDIA" "")
2889 ;; -------------------------------------------------------------------------
2890 ;; Zero extension instructions
2891 ;; -------------------------------------------------------------------------
2893 (define_insn "zero_extendsidi2"
2894   [(set (match_operand:DI 0 "register_operand" "=r")
2895         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2896   "TARGET_SHMEDIA"
2897   "addz.l       %1, r63, %0"
2898   [(set_attr "type" "arith_media")])
2900 (define_insn "zero_extendhidi2"
2901   [(set (match_operand:DI 0 "register_operand" "=r,r")
2902         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2903   "TARGET_SHMEDIA"
2904   "@
2905         #
2906         ld%M1.uw        %m1, %0"
2907   [(set_attr "type" "*,load_media")])
2909 (define_split
2910   [(set (match_operand:DI 0 "register_operand" "")
2911         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2912   "TARGET_SHMEDIA && reload_completed"
2913   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2914    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2915   "
2917   if (GET_CODE (operands[1]) == TRUNCATE)
2918     operands[1] = XEXP (operands[1], 0);
2921 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
2922 ;; reload the entire truncate expression.
2923 (define_insn_and_split "*loaddi_trunc"
2924   [(set (match_operand 0 "int_gpr_dest" "=r")
2925         (truncate (match_operand:DI 1 "memory_operand" "m")))]
2926   "TARGET_SHMEDIA && reload_completed"
2927   "#"
2928   "TARGET_SHMEDIA && reload_completed"
2929   [(set (match_dup 0) (match_dup 1))]
2930   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
2932 (define_insn "zero_extendqidi2"
2933   [(set (match_operand:DI 0 "register_operand" "=r,r")
2934         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
2935   "TARGET_SHMEDIA"
2936   "@
2937         andi    %1, 255, %0
2938         ld%M1.ub        %m1, %0"
2939   [(set_attr "type" "arith_media,load_media")])
2941 (define_expand "zero_extendhisi2"
2942   [(set (match_operand:SI 0 "arith_reg_operand" "")
2943         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
2944   ""
2945   "
2947   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
2948     operands[1] = copy_to_mode_reg (HImode, operands[1]);
2951 (define_insn "*zero_extendhisi2_compact"
2952   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2953         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
2954   "TARGET_SH1"
2955   "extu.w       %1,%0"
2956   [(set_attr "type" "arith")])
2958 (define_insn "*zero_extendhisi2_media"
2959   [(set (match_operand:SI 0 "register_operand" "=r,r")
2960         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2961   "TARGET_SHMEDIA"
2962   "@
2963         #
2964         ld%M1.uw        %m1, %0"
2965   [(set_attr "type" "arith_media,load_media")])
2967 (define_split
2968   [(set (match_operand:SI 0 "register_operand" "")
2969         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
2970   "TARGET_SHMEDIA && reload_completed"
2971   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
2972    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
2973   "
2975   if (GET_CODE (operands[1]) == TRUNCATE)
2976     operands[1] = XEXP (operands[1], 0);
2979 (define_expand "zero_extendqisi2"
2980   [(set (match_operand:SI 0 "arith_reg_operand" "")
2981         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
2982   ""
2983   "
2985   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
2986     operands[1] = copy_to_mode_reg (QImode, operands[1]);
2989 (define_insn "*zero_extendqisi2_compact"
2990   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2991         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
2992   "TARGET_SH1"
2993   "extu.b       %1,%0"
2994   [(set_attr "type" "arith")])
2996 (define_insn "*zero_extendqisi2_media"
2997   [(set (match_operand:SI 0 "register_operand" "=r,r")
2998         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
2999   "TARGET_SHMEDIA"
3000   "@
3001         andi    %1, 255, %0
3002         ld%M1.ub        %m1, %0"
3003   [(set_attr "type" "arith_media,load_media")])
3005 (define_insn "zero_extendqihi2"
3006   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3007         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3008   "TARGET_SH1"
3009   "extu.b       %1,%0"
3010   [(set_attr "type" "arith")])
3012 ;; -------------------------------------------------------------------------
3013 ;; Sign extension instructions
3014 ;; -------------------------------------------------------------------------
3016 ;; ??? This should be a define expand.
3017 ;; ??? Or perhaps it should be dropped?
3019 ;; convert_move generates good code for SH[1-4].
3020 (define_insn "extendsidi2"
3021   [(set (match_operand:DI 0 "register_operand" "=r,r")
3022         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3023   "TARGET_SHMEDIA"
3024   "@
3025         add.l   %1, r63, %0
3026         ld%M1.l %m1, %0"
3027   [(set_attr "type" "arith_media,load_media")])
3029 (define_insn "extendhidi2"
3030   [(set (match_operand:DI 0 "register_operand" "=r,r")
3031         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3032   "TARGET_SHMEDIA"
3033   "@
3034         #
3035         ld%M1.w %m1, %0"
3036   [(set_attr "type" "*,load_media")])
3038 (define_split
3039   [(set (match_operand:DI 0 "register_operand" "")
3040         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3041   "TARGET_SHMEDIA && reload_completed"
3042   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3043    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3044   "
3046   if (GET_CODE (operands[1]) == TRUNCATE)
3047     operands[1] = XEXP (operands[1], 0);
3050 (define_insn "extendqidi2"
3051   [(set (match_operand:DI 0 "register_operand" "=r,r")
3052         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3053   "TARGET_SHMEDIA"
3054   "@
3055         #
3056         ld%M1.b %m1, %0"
3057   [(set_attr "type" "*,load_media")])
3059 (define_split
3060   [(set (match_operand:DI 0 "register_operand" "")
3061         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3062   "TARGET_SHMEDIA && reload_completed"
3063   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3064    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3065   "
3067   if (GET_CODE (operands[1]) == TRUNCATE)
3068     operands[1] = XEXP (operands[1], 0);
3071 (define_expand "extendhisi2"
3072   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3073         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3074   ""
3075   "")
3077 (define_insn "*extendhisi2_compact"
3078   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3079         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3080   "TARGET_SH1"
3081   "@
3082         exts.w  %1,%0
3083         mov.w   %1,%0"
3084   [(set_attr "type" "arith,load")])
3086 (define_insn "*extendhisi2_media"
3087   [(set (match_operand:SI 0 "register_operand" "=r,r")
3088         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3089   "TARGET_SHMEDIA"
3090   "@
3091         #
3092         ld%M1.w %m1, %0"
3093   [(set_attr "type" "arith_media,load_media")])
3095 (define_split
3096   [(set (match_operand:SI 0 "register_operand" "")
3097         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3098   "TARGET_SHMEDIA && reload_completed"
3099   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3100    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3101   "
3103   if (GET_CODE (operands[1]) == TRUNCATE)
3104     operands[1] = XEXP (operands[1], 0);
3107 (define_expand "extendqisi2"
3108   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3109         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3110   ""
3111   "")
3113 (define_insn "*extendqisi2_compact"
3114   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3115         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3116   "TARGET_SH1"
3117   "@
3118         exts.b  %1,%0
3119         mov.b   %1,%0"
3120   [(set_attr "type" "arith,load")])
3122 (define_insn "*extendqisi2_media"
3123   [(set (match_operand:SI 0 "register_operand" "=r,r")
3124         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3125   "TARGET_SHMEDIA"
3126   "@
3127         #
3128         ld%M1.b %m1, %0"
3129   [(set_attr "type" "arith_media,load_media")])
3131 (define_split
3132   [(set (match_operand:SI 0 "register_operand" "")
3133         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3134   "TARGET_SHMEDIA && reload_completed"
3135   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3136    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3137    "
3139   if (GET_CODE (operands[1]) == TRUNCATE)
3140     operands[1] = XEXP (operands[1], 0);
3143 (define_insn "extendqihi2"
3144   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3145         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3146   "TARGET_SH1"
3147   "@
3148         exts.b  %1,%0
3149         mov.b   %1,%0"
3150   [(set_attr "type" "arith,load")])
3152 /* It would seem useful to combine the truncXi patterns into the movXi
3153    patterns, but unary operators are ignored when matching constraints,
3154    so we need separate patterns.  */
3155 (define_insn "truncdisi2"
3156   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3157         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3158   "TARGET_SHMEDIA"
3159   "@
3160         add.l   %1, r63, %0
3161         st%M0.l %m0, %1
3162         fst%M0.s        %m0, %T1
3163         fmov.ls %1, %0
3164         fmov.sl %T1, %0
3165         fmov.s  %T1, %0"
3166   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3169 (define_insn "truncdihi2"
3170   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3171         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3172   "TARGET_SHMEDIA"
3173   "@
3174         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3175         st%M0.w %m0, %1"
3176   [(set_attr "type"   "arith_media,store_media")
3177    (set_attr "length" "8,4")])
3179 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3180 ; Because we use zero extension, we can't provide signed QImode compares
3181 ; using a simple compare or conditional banch insn.
3182 (define_insn "truncdiqi2"
3183   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3184         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3185   "TARGET_SHMEDIA"
3186   "@
3187         andi    %1, 255, %0
3188         st%M0.b %m0, %1"
3189   [(set_attr "type"   "arith_media,store")])
3191 ;; -------------------------------------------------------------------------
3192 ;; Move instructions
3193 ;; -------------------------------------------------------------------------
3195 ;; define push and pop so it is easy for sh.c
3196 ;; We can't use push and pop on SHcompact because the stack must always
3197 ;; be 8-byte aligned.
3199 (define_expand "push"
3200   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3201         (match_operand:SI 0 "register_operand" "r,l,x"))]
3202   "TARGET_SH1 && ! TARGET_SH5"
3203   "")
3205 (define_expand "pop"
3206   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3207         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3208   "TARGET_SH1 && ! TARGET_SH5"
3209   "")
3211 (define_expand "push_e"
3212   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3213                    (match_operand:SF 0 "" ""))
3214               (use (reg:PSI FPSCR_REG))
3215               (clobber (scratch:SI))])]
3216   "TARGET_SH1 && ! TARGET_SH5"
3217   "")
3219 (define_insn "push_fpul"
3220   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3221   "TARGET_SH2E && ! TARGET_SH5"
3222   "sts.l        fpul,@-r15"
3223   [(set_attr "type" "store")
3224    (set_attr "late_fp_use" "yes")
3225    (set_attr "hit_stack" "yes")])
3227 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3228 ;; so use that.
3229 (define_expand "push_4"
3230   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3231                    (match_operand:DF 0 "" ""))
3232               (use (reg:PSI FPSCR_REG))
3233               (clobber (scratch:SI))])]
3234   "TARGET_SH1 && ! TARGET_SH5"
3235   "")
3237 (define_expand "pop_e"
3238   [(parallel [(set (match_operand:SF 0 "" "")
3239               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3240               (use (reg:PSI FPSCR_REG))
3241               (clobber (scratch:SI))])]
3242   "TARGET_SH1 && ! TARGET_SH5"
3243   "")
3245 (define_insn "pop_fpul"
3246   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3247   "TARGET_SH2E && ! TARGET_SH5"
3248   "lds.l        @r15+,fpul"
3249   [(set_attr "type" "load")
3250    (set_attr "hit_stack" "yes")])
3252 (define_expand "pop_4"
3253   [(parallel [(set (match_operand:DF 0 "" "")
3254                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3255               (use (reg:PSI FPSCR_REG))
3256               (clobber (scratch:SI))])]
3257   "TARGET_SH1 && ! TARGET_SH5"
3258   "")
3260 (define_expand "push_fpscr"
3261   [(const_int 0)]
3262   "TARGET_SH2E"
3263   "
3265   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3266                                                  gen_rtx_PRE_DEC (Pmode,
3267                                                           stack_pointer_rtx)),
3268                                         get_fpscr_rtx ()));
3269   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3270   DONE;
3273 (define_expand "pop_fpscr"
3274   [(const_int 0)]
3275   "TARGET_SH2E"
3276   "
3278   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3279                                         gen_rtx_MEM (PSImode,
3280                                                  gen_rtx_POST_INC (Pmode,
3281                                                           stack_pointer_rtx))));
3282   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3283   DONE;
3286 ;; These two patterns can happen as the result of optimization, when
3287 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3288 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3290 (define_insn "clrt"
3291   [(set (reg:SI T_REG) (const_int 0))]
3292   "TARGET_SH1"
3293   "clrt")
3295 (define_insn "sett"
3296   [(set (reg:SI T_REG) (const_int 1))]
3297   "TARGET_SH1"
3298   "sett")
3300 ;; t/r must come after r/r, lest reload will try to reload stuff like
3301 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3302 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3303 (define_insn "movsi_i"
3304   [(set (match_operand:SI 0 "general_movdst_operand"
3305             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3306         (match_operand:SI 1 "general_movsrc_operand"
3307          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3308   "TARGET_SH1
3309    && ! TARGET_SH2E
3310    && (register_operand (operands[0], SImode)
3311        || register_operand (operands[1], SImode))"
3312   "@
3313         mov.l   %1,%0
3314         mov     %1,%0
3315         cmp/pl  %1
3316         mov.l   %1,%0
3317         sts     %1,%0
3318         sts     %1,%0
3319         movt    %0
3320         mov.l   %1,%0
3321         sts.l   %1,%0
3322         sts.l   %1,%0
3323         lds     %1,%0
3324         lds     %1,%0
3325         lds.l   %1,%0
3326         lds.l   %1,%0
3327         fake    %1,%0"
3328   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3329    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3331 ;; t/r must come after r/r, lest reload will try to reload stuff like
3332 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3333 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3334 ;; will require a reload.
3335 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3336 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3337 (define_insn "movsi_ie"
3338   [(set (match_operand:SI 0 "general_movdst_operand"
3339             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3340         (match_operand:SI 1 "general_movsrc_operand"
3341          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3342   "TARGET_SH2E
3343    && (register_operand (operands[0], SImode)
3344        || register_operand (operands[1], SImode))"
3345   "@
3346         mov.l   %1,%0
3347         mov     %1,%0
3348         cmp/pl  %1
3349         mov.l   %1,%0
3350         sts     %1,%0
3351         sts     %1,%0
3352         movt    %0
3353         mov.l   %1,%0
3354         sts.l   %1,%0
3355         sts.l   %1,%0
3356         lds     %1,%0
3357         lds     %1,%0
3358         lds.l   %1,%0
3359         lds.l   %1,%0
3360         lds.l   %1,%0
3361         sts.l   %1,%0
3362         fake    %1,%0
3363         lds     %1,%0
3364         sts     %1,%0
3365         fsts    fpul,%0
3366         flds    %1,fpul
3367         fmov    %1,%0
3368         ! move optimized away"
3369   [(set_attr "type" "pcload_si,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")
3370    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3371    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3373 (define_insn "movsi_i_lowpart"
3374   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3375         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3376    "TARGET_SH1
3377     && (register_operand (operands[0], SImode)
3378         || register_operand (operands[1], SImode))"
3379   "@
3380         mov.l   %1,%0
3381         mov     %1,%0
3382         mov.l   %1,%0
3383         sts     %1,%0
3384         sts     %1,%0
3385         movt    %0
3386         mov.l   %1,%0
3387         fake    %1,%0"
3388   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3390 (define_insn_and_split "load_ra"
3391   [(set (match_operand:SI 0 "general_movdst_operand" "")
3392         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3393   "TARGET_SH1"
3394   "#"
3395   "&& ! rtx_equal_function_value_matters"
3396   [(set (match_dup 0) (match_dup 1))]
3397   "
3399   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3400     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3403 (define_insn "*movsi_media"
3404   [(set (match_operand:SI 0 "general_movdst_operand"
3405                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3406         (match_operand:SI 1 "general_movsrc_operand"
3407          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3408   "TARGET_SHMEDIA_FPU
3409    && (register_operand (operands[0], SImode)
3410        || sh_register_operand (operands[1], SImode))"
3411   "@
3412         add.l   %1, r63, %0
3413         movi    %1, %0
3414         #
3415         ld%M1.l %m1, %0
3416         st%M0.l %m0, %N1
3417         fld%M1.s        %m1, %0
3418         fst%M0.s        %m0, %1
3419         fmov.ls %N1, %0
3420         fmov.sl %1, %0
3421         fmov.s  %1, %0
3422         ptabs   %1, %0
3423         gettr   %1, %0
3424         pt      %1, %0"
3425   [(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")
3426    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3428 (define_insn "*movsi_media_nofpu"
3429   [(set (match_operand:SI 0 "general_movdst_operand"
3430                 "=r,r,r,r,m,*b,r,b")
3431         (match_operand:SI 1 "general_movsrc_operand"
3432          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3433   "TARGET_SHMEDIA
3434    && (register_operand (operands[0], SImode)
3435        || sh_register_operand (operands[1], SImode))"
3436   "@
3437         add.l   %1, r63, %0
3438         movi    %1, %0
3439         #
3440         ld%M1.l %m1, %0
3441         st%M0.l %m0, %N1
3442         ptabs   %1, %0
3443         gettr   %1, %0
3444         pt      %1, %0"
3445   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3446    (set_attr "length" "4,4,8,4,4,4,4,12")])
3448 (define_split
3449   [(set (match_operand:SI 0 "arith_reg_operand" "")
3450         (match_operand:SI 1 "immediate_operand" ""))]
3451   "TARGET_SHMEDIA && reload_completed
3452    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3453   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3454   "
3456   operands[2] = shallow_copy_rtx (operands[1]);
3457   PUT_MODE (operands[2], DImode);
3460 (define_split
3461   [(set (match_operand:SI 0 "register_operand" "")
3462         (match_operand:SI 1 "immediate_operand" ""))]
3463   "TARGET_SHMEDIA && reload_completed
3464    && ((GET_CODE (operands[1]) == CONST_INT
3465         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3466        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3467   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3469 (define_expand "movsi"
3470   [(set (match_operand:SI 0 "general_movdst_operand" "")
3471         (match_operand:SI 1 "general_movsrc_operand" ""))]
3472   ""
3473   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3475 (define_expand "ic_invalidate_line"
3476   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3477                                 (match_dup 1)] UNSPEC_ICACHE)
3478               (clobber (scratch:SI))])]
3479   "TARGET_HARD_SH4 || TARGET_SH5"
3480   "
3482   if (TARGET_SHMEDIA)
3483     {
3484       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3485       DONE;
3486     }
3487   else if (TARGET_SHCOMPACT)
3488     {
3489       operands[1] = function_symbol (\"__ic_invalidate\");
3490       operands[1] = force_reg (Pmode, operands[1]);
3491       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3492       DONE;
3493     }
3494   else if (TARGET_SH4A_ARCH)
3495     {
3496       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
3497       DONE;
3498     }
3499   operands[0] = force_reg (Pmode, operands[0]);
3500   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3501                                                                Pmode)));
3504 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3505 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3506 ;; the requirement *1*00 for associative address writes.  The alignment of
3507 ;; %0 implies that its least significant bit is cleared,
3508 ;; thus we clear the V bit of a matching entry if there is one.
3509 (define_insn "ic_invalidate_line_i"
3510   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3511                      (match_operand:SI 1 "register_operand" "r")]
3512                      UNSPEC_ICACHE)
3513    (clobber (match_scratch:SI 2 "=&r"))]
3514   "TARGET_HARD_SH4"
3515   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3516   [(set_attr "length" "8")
3517    (set_attr "type" "cwb")])
3519 (define_insn "ic_invalidate_line_sh4a"
3520   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
3521                     UNSPEC_ICACHE)]
3522   "TARGET_SH4A_ARCH"
3523   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
3524   [(set_attr "length" "16")
3525    (set_attr "type" "cwb")])
3527 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3528 ;; an add in the code that calculates the address.
3529 (define_insn "ic_invalidate_line_media"
3530   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3531                     UNSPEC_ICACHE)]
3532   "TARGET_SHMEDIA"
3533   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3534   [(set_attr "length" "16")
3535    (set_attr "type" "invalidate_line_media")])
3537 (define_insn "ic_invalidate_line_compact"
3538   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3539                      (match_operand:SI 1 "register_operand" "r")]
3540                     UNSPEC_ICACHE)
3541    (clobber (reg:SI PR_REG))]
3542   "TARGET_SHCOMPACT"
3543   "jsr @%1%#"
3544   [(set_attr "type" "sfunc")
3545    (set_attr "needs_delay_slot" "yes")])
3547 (define_expand "initialize_trampoline"
3548   [(match_operand:SI 0 "" "")
3549    (match_operand:SI 1 "" "")
3550    (match_operand:SI 2 "" "")]
3551   "TARGET_SHCOMPACT"
3552   "
3554   rtx sfun, tramp;
3556   tramp = force_reg (Pmode, operands[0]);
3557   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3558   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3559   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3561   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3562   DONE;
3565 (define_insn "initialize_trampoline_compact"
3566   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3567                      (match_operand:SI 1 "register_operand" "r")
3568                      (reg:SI R2_REG) (reg:SI R3_REG)]
3569                     UNSPEC_INIT_TRAMP)
3571    (clobber (reg:SI PR_REG))]
3572   "TARGET_SHCOMPACT"
3573   "jsr @%1%#"
3574   [(set_attr "type" "sfunc")
3575    (set_attr "needs_delay_slot" "yes")])
3577 (define_insn "movqi_i"
3578   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3579         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3580   "TARGET_SH1
3581    && (arith_reg_operand (operands[0], QImode)
3582        || arith_reg_operand (operands[1], QImode))"
3583   "@
3584         mov     %1,%0
3585         mov.b   %1,%0
3586         mov.b   %1,%0
3587         movt    %0
3588         sts     %1,%0
3589         lds     %1,%0"
3590  [(set_attr "type" "move,load,store,move,move,move")])
3592 (define_insn "*movqi_media"
3593   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3594         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3595   "TARGET_SHMEDIA
3596    && (arith_reg_operand (operands[0], QImode)
3597        || arith_reg_or_0_operand (operands[1], QImode))"
3598   "@
3599         add.l   %1, r63, %0
3600         movi    %1, %0
3601         ld%M1.ub        %m1, %0
3602         st%M0.b %m0, %N1"
3603   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3605 (define_expand "movqi"
3606   [(set (match_operand:QI 0 "general_operand" "")
3607         (match_operand:QI 1 "general_operand"  ""))]
3608   ""
3609   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3611 (define_expand "reload_inqi"
3612   [(set (match_operand:SI 2 "" "=&r")
3613         (match_operand:QI 1 "inqhi_operand" ""))
3614    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3615         (truncate:QI (match_dup 3)))]
3616   "TARGET_SHMEDIA"
3617   "
3619   rtx inner = XEXP (operands[1], 0);
3620   int regno = REGNO (inner);
3622   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3623   operands[1] = gen_rtx_REG (SImode, regno);
3624   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3627 /* When storing r0, we have to avoid reg+reg addressing.  */
3628 (define_insn "movhi_i"
3629   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3630         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3631   "TARGET_SH1
3632    && (arith_reg_operand (operands[0], HImode)
3633        || arith_reg_operand (operands[1], HImode))
3634    && (GET_CODE (operands[0]) != MEM
3635        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3636        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3637        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3638   "@
3639         mov.w   %1,%0
3640         mov     %1,%0
3641         mov.w   %1,%0
3642         movt    %0
3643         mov.w   %1,%0
3644         sts     %1,%0
3645         lds     %1,%0
3646         fake    %1,%0"
3647   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3649 (define_insn "*movhi_media"
3650   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3651         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3652   "TARGET_SHMEDIA
3653    && (arith_reg_operand (operands[0], HImode)
3654        || arith_reg_or_0_operand (operands[1], HImode))"
3655   "@
3656         add.l   %1, r63, %0
3657         movi    %1, %0
3658         #
3659         ld%M1.w %m1, %0
3660         st%M0.w %m0, %N1"
3661   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3663 (define_split
3664   [(set (match_operand:HI 0 "register_operand" "")
3665         (match_operand:HI 1 "immediate_operand" ""))]
3666   "TARGET_SHMEDIA && reload_completed
3667    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3668   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3670 (define_expand "movhi"
3671   [(set (match_operand:HI 0 "general_movdst_operand" "")
3672         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3673   ""
3674   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3676 (define_expand "reload_inhi"
3677   [(set (match_operand:SI 2 "" "=&r")
3678         (match_operand:HI 1 "inqhi_operand" ""))
3679    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3680         (truncate:HI (match_dup 3)))]
3681   "TARGET_SHMEDIA"
3682   "
3684   rtx inner = XEXP (operands[1], 0);
3685   int regno = REGNO (inner);
3687   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3688   operands[1] = gen_rtx_REG (SImode, regno);
3689   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3692 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3693 ;; compiled with -m2 -ml -O3 -funroll-loops
3694 (define_insn "*movdi_i"
3695   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3696         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3697   "TARGET_SH1
3698    && (arith_reg_operand (operands[0], DImode)
3699        || arith_reg_operand (operands[1], DImode))"
3700   "* return output_movedouble (insn, operands, DImode);"
3701   [(set_attr "length" "4")
3702    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3704 ;; If the output is a register and the input is memory or a register, we have
3705 ;; to be careful and see which word needs to be loaded first.
3707 (define_split
3708   [(set (match_operand:DI 0 "general_movdst_operand" "")
3709         (match_operand:DI 1 "general_movsrc_operand" ""))]
3710   "TARGET_SH1 && reload_completed"
3711   [(set (match_dup 2) (match_dup 3))
3712    (set (match_dup 4) (match_dup 5))]
3713   "
3715   int regno;
3717   if ((GET_CODE (operands[0]) == MEM
3718        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3719       || (GET_CODE (operands[1]) == MEM
3720           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3721     FAIL;
3723   if (GET_CODE (operands[0]) == REG)
3724     regno = REGNO (operands[0]);
3725   else if (GET_CODE (operands[0]) == SUBREG)
3726     regno = subreg_regno (operands[0]);
3727   else if (GET_CODE (operands[0]) == MEM)
3728     regno = -1;
3729   else
3730     abort ();
3732   if (regno == -1
3733       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3734     {
3735       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3736       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3737       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3738       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3739     }
3740   else
3741     {
3742       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3743       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3744       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3745       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3746     }
3748   if (operands[2] == 0 || operands[3] == 0
3749       || operands[4] == 0 || operands[5] == 0)
3750     FAIL;
3753 (define_insn "*movdi_media"
3754   [(set (match_operand:DI 0 "general_movdst_operand"
3755                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3756         (match_operand:DI 1 "general_movsrc_operand"
3757          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3758   "TARGET_SHMEDIA_FPU
3759    && (register_operand (operands[0], DImode)
3760        || sh_register_operand (operands[1], DImode))"
3761   "@
3762         add     %1, r63, %0
3763         movi    %1, %0
3764         #
3765         ld%M1.q %m1, %0
3766         st%M0.q %m0, %N1
3767         fld%M1.d        %m1, %0
3768         fst%M0.d        %m0, %1
3769         fmov.qd %N1, %0
3770         fmov.dq %1, %0
3771         fmov.d  %1, %0
3772         ptabs   %1, %0
3773         gettr   %1, %0
3774         pt      %1, %0"
3775   [(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")
3776    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3778 (define_insn "*movdi_media_nofpu"
3779   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3780         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3781   "TARGET_SHMEDIA
3782    && (register_operand (operands[0], DImode)
3783        || sh_register_operand (operands[1], DImode))"
3784   "@
3785         add     %1, r63, %0
3786         movi    %1, %0
3787         #
3788         ld%M1.q %m1, %0
3789         st%M0.q %m0, %N1
3790         ptabs   %1, %0
3791         gettr   %1, %0
3792         pt      %1, %0"
3793   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3794    (set_attr "length" "4,4,16,4,4,4,4,*")])
3796 (define_split
3797   [(set (match_operand:DI 0 "arith_reg_operand" "")
3798         (match_operand:DI 1 "immediate_operand" ""))]
3799   "TARGET_SHMEDIA && reload_completed
3800    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3801   [(set (match_dup 0) (match_dup 1))]
3802   "
3804   rtx insn;
3806   if (TARGET_SHMEDIA64)
3807     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3808   else
3809     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3811   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3812                                         REG_NOTES (insn));
3814   DONE;
3817 (define_expand "movdi_const"
3818   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3819         (const:DI (sign_extend:DI
3820                    (truncate:HI
3821                     (ashiftrt:DI
3822                      (match_operand:DI 1 "immediate_operand" "s")
3823                      (const_int 48))))))
3824    (set (match_dup 0)
3825         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3826                 (zero_extend:DI
3827                  (truncate:HI
3828                   (const:DI
3829                    (sign_extend:DI
3830                     (truncate:HI
3831                      (ashiftrt:SI
3832                       (match_dup 1)
3833                       (const_int 32)))))))))
3834    (set (match_dup 0)
3835         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3836                 (zero_extend:DI
3837                  (truncate:HI
3838                   (const:DI
3839                    (sign_extend:DI
3840                     (truncate:HI
3841                      (ashiftrt:SI
3842                       (match_dup 1)
3843                       (const_int 16)))))))))
3844    (set (match_dup 0)
3845         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3846                 (zero_extend:DI
3847                  (truncate:HI
3848                   (const:DI
3849                    (sign_extend:DI
3850                     (truncate:HI
3851                      (match_dup 1))))))))]
3852   "TARGET_SHMEDIA64 && reload_completed
3853    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3854   "
3856   sh_mark_label (operands[1], 4);
3859 (define_expand "movdi_const_32bit"
3860   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3861         (const:DI (sign_extend:DI
3862                    (truncate:HI
3863                     (ashiftrt:DI
3864                      (match_operand:DI 1 "immediate_operand" "s")
3865                      (const_int 16))))))
3866    (set (match_dup 0)
3867         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3868                 (zero_extend:DI
3869                  (truncate:HI
3870                   (const:DI
3871                    (sign_extend:DI
3872                     (truncate:HI
3873                      (match_dup 1))))))))]
3874   "TARGET_SHMEDIA32 && reload_completed
3875    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3876   "
3878   sh_mark_label (operands[1], 2);
3881 (define_expand "movdi_const_16bit"
3882   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3883         (const:DI (sign_extend:DI
3884                    (truncate:HI
3885                     (match_operand:DI 1 "immediate_operand" "s")))))]
3886   "TARGET_SHMEDIA && flag_pic && reload_completed
3887    && GET_CODE (operands[1]) == SYMBOL_REF"
3888   "")
3890 (define_split
3891   [(set (match_operand:DI 0 "arith_reg_operand" "")
3892         (match_operand:DI 1 "immediate_operand" ""))]
3893   "TARGET_SHMEDIA && reload_completed
3894    && GET_CODE (operands[1]) == CONST_INT
3895    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3896   [(set (match_dup 0) (match_dup 2))
3897    (match_dup 1)]
3898   "
3900   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3901   unsigned HOST_WIDE_INT low = val;
3902   unsigned HOST_WIDE_INT high = val;
3903   unsigned HOST_WIDE_INT sign;
3904   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3906   /* Sign-extend the 16 least-significant bits.  */
3907   low &= 0xffff;
3908   low ^= 0x8000;
3909   low -= 0x8000;
3911   /* Arithmetic shift right the word by 16 bits.  */
3912   high >>= 16;
3913   sign = 1;
3914   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3915   high ^= sign;
3916   high -= sign;
3917   do
3918     {
3919       /* If we can't generate the constant with a two-insn movi / shori
3920          sequence, try some other strategies.  */
3921       if (! CONST_OK_FOR_I16 (high))
3922         {
3923           /* Try constant load / left shift.  We know VAL != 0.  */
3924           val2 = val ^ (val-1);
3925           if (val2 > 0x1ffff)
3926             {
3927               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3929               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
3930                   || (! CONST_OK_FOR_I16 (high >> 16)
3931                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
3932                 {
3933                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3934                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
3935                                                    GEN_INT (trailing_zeroes));
3936                   break;
3937                 }
3938             }
3939           /* Try constant load / right shift.  */
3940           val2 = (val >> 15) + 1;
3941           if (val2 == (val2 & -val2))
3942             {
3943               int shift = 49 - exact_log2 (val2);
3945               val2 = trunc_int_for_mode (val << shift, DImode);
3946               if (CONST_OK_FOR_I16 (val2))
3947                 {
3948                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3949                                                    GEN_INT (shift));
3950                   break;
3951                 }
3952             }
3953           /* Try mperm.w .  */
3954           val2 = val & 0xffff;
3955           if ((val >> 16 & 0xffff) == val2
3956               && (val >> 32 & 0xffff) == val2
3957               && (val >> 48 & 0xffff) == val2)
3958             {
3959               val2 = (HOST_WIDE_INT) val >> 48;
3960               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3961               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3962               break;
3963             }
3964           /* Try movi / mshflo.l  */
3965           val2 = (HOST_WIDE_INT) val >> 32;
3966           if (val2 == ((unsigned HOST_WIDE_INT)
3967                         trunc_int_for_mode (val, SImode)))
3968             {
3969               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3970                                              operands[0]);
3971               break;
3972             }
3973           /* Try movi / mshflo.l w/ r63.  */
3974           val2 = val + ((HOST_WIDE_INT) -1 << 32);
3975           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
3976             {
3977               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3978                                              const0_rtx);
3979               break;
3980             }
3981         }
3982       val2 = high;
3983       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
3984     }
3985   while (0);
3986   operands[2] = GEN_INT (val2);
3989 (define_split
3990   [(set (match_operand:DI 0 "arith_reg_operand" "")
3991         (match_operand:DI 1 "immediate_operand" ""))]
3992   "TARGET_SHMEDIA && reload_completed
3993    && GET_CODE (operands[1]) == CONST_DOUBLE"
3994   [(set (match_dup 0) (match_dup 2))
3995   (set (match_dup 0)
3996        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3997                (zero_extend:DI (truncate:HI (match_dup 1)))))]
3998   "
4000   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4001   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4002   unsigned HOST_WIDE_INT val = low;
4003   unsigned HOST_WIDE_INT sign;
4005   /* Sign-extend the 16 least-significant bits.  */
4006   val &= 0xffff;
4007   val ^= 0x8000;
4008   val -= 0x8000;
4009   operands[1] = GEN_INT (val);
4011   /* Arithmetic shift right the double-word by 16 bits.  */
4012   low >>= 16;
4013   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4014   high >>= 16;
4015   sign = 1;
4016   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4017   high ^= sign;
4018   high -= sign;
4020   /* This will only be true if high is a sign-extension of low, i.e.,
4021      it must be either 0 or (unsigned)-1, and be zero iff the
4022      most-significant bit of low is set.  */
4023   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4024     operands[2] = GEN_INT (low);
4025   else
4026     operands[2] = immed_double_const (low, high, DImode);
4029 (define_insn "shori_media"
4030   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4031         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4032                            (const_int 16))
4033                 (zero_extend:DI
4034                  (truncate:HI
4035                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4036   "TARGET_SHMEDIA"
4037   "@
4038         shori   %u2, %0
4039         #"
4040   [(set_attr "type" "arith_media,*")])
4042 (define_expand "movdi"
4043   [(set (match_operand:DI 0 "general_movdst_operand" "")
4044         (match_operand:DI 1 "general_movsrc_operand" ""))]
4045   ""
4046   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4048 (define_insn "movdf_media"
4049   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4050         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4051   "TARGET_SHMEDIA_FPU
4052    && (register_operand (operands[0], DFmode)
4053        || sh_register_operand (operands[1], DFmode))"
4054   "@
4055         fmov.d  %1, %0
4056         fmov.qd %N1, %0
4057         fmov.dq %1, %0
4058         add     %1, r63, %0
4059         #
4060         fld%M1.d        %m1, %0
4061         fst%M0.d        %m0, %1
4062         ld%M1.q %m1, %0
4063         st%M0.q %m0, %N1"
4064   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4066 (define_insn "movdf_media_nofpu"
4067   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4068         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4069   "TARGET_SHMEDIA
4070    && (register_operand (operands[0], DFmode)
4071        || sh_register_operand (operands[1], DFmode))"
4072   "@
4073         add     %1, r63, %0
4074         #
4075         ld%M1.q %m1, %0
4076         st%M0.q %m0, %N1"
4077   [(set_attr "type" "arith_media,*,load_media,store_media")])
4079 (define_split
4080   [(set (match_operand:DF 0 "arith_reg_operand" "")
4081         (match_operand:DF 1 "immediate_operand" ""))]
4082   "TARGET_SHMEDIA && reload_completed"
4083   [(set (match_dup 3) (match_dup 2))]
4084   "
4086   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4087   long values[2];
4088   REAL_VALUE_TYPE value;
4090   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4091   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4093   if (HOST_BITS_PER_WIDE_INT >= 64)
4094     operands[2] = immed_double_const ((unsigned long) values[endian]
4095                                       | ((HOST_WIDE_INT) values[1 - endian]
4096                                          << 32), 0, DImode);
4097   else if (HOST_BITS_PER_WIDE_INT == 32)
4098     operands[2] = immed_double_const (values[endian], values[1 - endian],
4099                                       DImode);
4100   else
4101     abort ();
4103   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4106 ;; ??? This should be a define expand.
4108 (define_insn "movdf_k"
4109   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4110         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4111   "TARGET_SH1
4112    && (! TARGET_SH4 || reload_completed
4113        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4114        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4115        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4116    && (arith_reg_operand (operands[0], DFmode)
4117        || arith_reg_operand (operands[1], DFmode))"
4118   "* return output_movedouble (insn, operands, DFmode);"
4119   [(set_attr "length" "4")
4120    (set_attr "type" "move,pcload,load,store")])
4122 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4123 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4124 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4125 ;; the d/m/c/X alternative, which is split later into single-precision
4126 ;; instructions.  And when not optimizing, no splits are done before fixing
4127 ;; up pcloads, so we need usable length information for that.
4128 (define_insn "movdf_i4"
4129   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4130         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4131    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4132    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4133   "TARGET_SH4
4134    && (arith_reg_operand (operands[0], DFmode)
4135        || arith_reg_operand (operands[1], DFmode))"
4136   "@
4137         fmov    %1,%0
4138         #
4139         #
4140         fmov.d  %1,%0
4141         fmov.d  %1,%0
4142         #
4143         #
4144         #
4145         #
4146         #"
4147   [(set_attr_alternative "length"
4148      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4149       (const_int 4)
4150       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4151       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4152       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4153       (const_int 4)
4154       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4155       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4156       ;; increment or decrement r15 explicitly.
4157       (if_then_else
4158        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4159        (const_int 10) (const_int 8))
4160       (if_then_else
4161        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4162        (const_int 10) (const_int 8))])
4163    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4164    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4165    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4166                                            (const_string "double")
4167                                            (const_string "none")))])
4169 ;; Moving DFmode between fp/general registers through memory
4170 ;; (the top of the stack) is faster than moving through fpul even for
4171 ;; little endian.  Because the type of an instruction is important for its
4172 ;; scheduling,  it is beneficial to split these operations, rather than
4173 ;; emitting them in one single chunk, even if this will expose a stack
4174 ;; use that will prevent scheduling of other stack accesses beyond this
4175 ;; instruction.
4176 (define_split
4177   [(set (match_operand:DF 0 "register_operand" "")
4178         (match_operand:DF 1 "register_operand" ""))
4179    (use (match_operand:PSI 2 "fpscr_operand" ""))
4180    (clobber (match_scratch:SI 3 "=X"))]
4181   "TARGET_SH4 && reload_completed
4182    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4183   [(const_int 0)]
4184   "
4186   rtx insn, tos;
4188   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4189     {
4190       emit_move_insn (stack_pointer_rtx,
4191                       plus_constant (stack_pointer_rtx, -8));
4192       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4193     }
4194   else
4195     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4196   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4197   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4198     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4199   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4200     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4201   else
4202     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4203   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4204   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4205     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4206   else
4207     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4208   DONE;
4211 ;; local-alloc sometimes allocates scratch registers even when not required,
4212 ;; so we must be prepared to handle these.
4214 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4215 (define_split
4216   [(set (match_operand:DF 0 "general_movdst_operand" "")
4217         (match_operand:DF 1 "general_movsrc_operand"  ""))
4218    (use (match_operand:PSI 2 "fpscr_operand" ""))
4219    (clobber (match_scratch:SI 3 ""))]
4220   "TARGET_SH4
4221    && reload_completed
4222    && true_regnum (operands[0]) < 16
4223    && true_regnum (operands[1]) < 16"
4224   [(set (match_dup 0) (match_dup 1))]
4225   "
4227   /* If this was a reg <-> mem operation with base + index reg addressing,
4228      we have to handle this in a special way.  */
4229   rtx mem = operands[0];
4230   int store_p = 1;
4231   if (! memory_operand (mem, DFmode))
4232     {
4233       mem = operands[1];
4234       store_p = 0;
4235     }
4236   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4237     mem = SUBREG_REG (mem);
4238   if (GET_CODE (mem) == MEM)
4239     {
4240       rtx addr = XEXP (mem, 0);
4241       if (GET_CODE (addr) == PLUS
4242           && GET_CODE (XEXP (addr, 0)) == REG
4243           && GET_CODE (XEXP (addr, 1)) == REG)
4244         {
4245           int offset;
4246           rtx reg0 = gen_rtx_REG (Pmode, 0);
4247           rtx regop = operands[store_p], word0 ,word1;
4249           if (GET_CODE (regop) == SUBREG)
4250             alter_subreg (&regop);
4251           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4252             offset = 2;
4253           else
4254             offset = 4;
4255           mem = copy_rtx (mem);
4256           PUT_MODE (mem, SImode);
4257           word0 = gen_rtx_SUBREG (SImode, regop, 0);
4258           alter_subreg (&word0);
4259           word1 = gen_rtx_SUBREG (SImode, regop, 4);
4260           alter_subreg (&word1);
4261           if (store_p || ! refers_to_regno_p (REGNO (word0),
4262                                               REGNO (word0) + 1, addr, 0))
4263             {
4264               emit_insn (store_p
4265                          ? gen_movsi_ie (mem, word0)
4266                          : gen_movsi_ie (word0, mem));
4267               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4268               mem = copy_rtx (mem);
4269               emit_insn (store_p
4270                          ? gen_movsi_ie (mem, word1)
4271                          : gen_movsi_ie (word1, mem));
4272               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4273             }
4274           else
4275             {
4276               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4277               emit_insn (gen_movsi_ie (word1, mem));
4278               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4279               mem = copy_rtx (mem);
4280               emit_insn (gen_movsi_ie (word0, mem));
4281             }
4282           DONE;
4283         }
4284     }
4287 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4288 (define_split
4289   [(set (match_operand:DF 0 "register_operand" "")
4290         (match_operand:DF 1 "memory_operand"  ""))
4291    (use (match_operand:PSI 2 "fpscr_operand" ""))
4292    (clobber (reg:SI R0_REG))]
4293   "TARGET_SH4 && reload_completed"
4294   [(parallel [(set (match_dup 0) (match_dup 1))
4295               (use (match_dup 2))
4296               (clobber (scratch:SI))])]
4297   "")
4299 (define_expand "reload_indf"
4300   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4301                    (match_operand:DF 1 "immediate_operand" "FQ"))
4302               (use (reg:PSI FPSCR_REG))
4303               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4304   "TARGET_SH1"
4305   "")
4307 (define_expand "reload_outdf"
4308   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4309                    (match_operand:DF 1 "register_operand" "af,r"))
4310               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4311   "TARGET_SH1"
4312   "")
4314 ;; Simplify no-op moves.
4315 (define_split
4316   [(set (match_operand:SF 0 "register_operand" "")
4317         (match_operand:SF 1 "register_operand" ""))
4318    (use (match_operand:PSI 2 "fpscr_operand" ""))
4319    (clobber (match_scratch:SI 3 ""))]
4320   "TARGET_SH2E && reload_completed
4321    && true_regnum (operands[0]) == true_regnum (operands[1])"
4322   [(set (match_dup 0) (match_dup 0))]
4323   "")
4325 ;; fmovd substitute post-reload splits
4326 (define_split
4327   [(set (match_operand:DF 0 "register_operand" "")
4328         (match_operand:DF 1 "register_operand" ""))
4329    (use (match_operand:PSI 2 "fpscr_operand" ""))
4330    (clobber (match_scratch:SI 3 ""))]
4331   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4332    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4333    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4334   [(const_int 0)]
4335   "
4337   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4338   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4339                            gen_rtx_REG (SFmode, src), operands[2]));
4340   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4341                            gen_rtx_REG (SFmode, src + 1), operands[2]));
4342   DONE;
4345 (define_split
4346   [(set (match_operand:DF 0 "register_operand" "")
4347         (mem:DF (match_operand:SI 1 "register_operand" "")))
4348    (use (match_operand:PSI 2 "fpscr_operand" ""))
4349    (clobber (match_scratch:SI 3 ""))]
4350   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4351    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4352    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4353   [(const_int 0)]
4354   "
4356   int regno = true_regnum (operands[0]);
4357   rtx insn;
4358   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4360   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4361                                            regno + !! TARGET_LITTLE_ENDIAN),
4362                                   mem2, operands[2]));
4363   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4364   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4365                                            regno + ! TARGET_LITTLE_ENDIAN),
4366                                   gen_rtx_MEM (SFmode, operands[1]),
4367                                   operands[2]));
4368   DONE;
4371 (define_split
4372   [(set (match_operand:DF 0 "register_operand" "")
4373         (match_operand:DF 1 "memory_operand" ""))
4374    (use (match_operand:PSI 2 "fpscr_operand" ""))
4375    (clobber (match_scratch:SI 3 ""))]
4376   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4377    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4378   [(const_int 0)]
4379   "
4381   int regno = true_regnum (operands[0]);
4382   rtx addr, insn, adjust = NULL_RTX;
4383   rtx mem2 = copy_rtx (operands[1]);
4384   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4385   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4387   PUT_MODE (mem2, SFmode);
4388   operands[1] = copy_rtx (mem2);
4389   addr = XEXP (mem2, 0);
4390   if (GET_CODE (addr) != POST_INC)
4391     {
4392       /* If we have to modify the stack pointer, the value that we have
4393          read with post-increment might be modified by an interrupt,
4394          so write it back.  */
4395       if (REGNO (addr) == STACK_POINTER_REGNUM)
4396         adjust = gen_push_e (reg0);
4397       else
4398         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4399       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4400     }
4401   addr = XEXP (addr, 0);
4402   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4403   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4404   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4405   if (adjust)
4406     emit_insn (adjust);
4407   else
4408     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4409   DONE;
4412 (define_split
4413   [(set (match_operand:DF 0 "memory_operand" "")
4414         (match_operand:DF 1 "register_operand" ""))
4415    (use (match_operand:PSI 2 "fpscr_operand" ""))
4416    (clobber (match_scratch:SI 3 ""))]
4417   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4418    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4419   [(const_int 0)]
4420   "
4422   int regno = true_regnum (operands[1]);
4423   rtx insn, addr, adjust = NULL_RTX;
4425   operands[0] = copy_rtx (operands[0]);
4426   PUT_MODE (operands[0], SFmode);
4427   insn = emit_insn (gen_movsf_ie (operands[0],
4428                                   gen_rtx_REG (SFmode,
4429                                            regno + ! TARGET_LITTLE_ENDIAN),
4430                                   operands[2]));
4431   operands[0] = copy_rtx (operands[0]);
4432   addr = XEXP (operands[0], 0);
4433   if (GET_CODE (addr) != PRE_DEC)
4434     {
4435       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4436       emit_insn_before (adjust, insn);
4437       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4438     }
4439   addr = XEXP (addr, 0);
4440   if (! adjust)
4441     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4442   insn = emit_insn (gen_movsf_ie (operands[0],
4443                                   gen_rtx_REG (SFmode,
4444                                            regno + !! TARGET_LITTLE_ENDIAN),
4445                                   operands[2]));
4446   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4447   DONE;
4450 ;; If the output is a register and the input is memory or a register, we have
4451 ;; to be careful and see which word needs to be loaded first.
4453 (define_split
4454   [(set (match_operand:DF 0 "general_movdst_operand" "")
4455         (match_operand:DF 1 "general_movsrc_operand" ""))]
4456   "TARGET_SH1 && reload_completed"
4457   [(set (match_dup 2) (match_dup 3))
4458    (set (match_dup 4) (match_dup 5))]
4459   "
4461   int regno;
4463   if ((GET_CODE (operands[0]) == MEM
4464        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4465       || (GET_CODE (operands[1]) == MEM
4466           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4467     FAIL;
4469   if (GET_CODE (operands[0]) == REG)
4470     regno = REGNO (operands[0]);
4471   else if (GET_CODE (operands[0]) == SUBREG)
4472     regno = subreg_regno (operands[0]);
4473   else if (GET_CODE (operands[0]) == MEM)
4474     regno = -1;
4475   else
4476     abort ();
4478   if (regno == -1
4479       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4480     {
4481       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4482       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4483       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4484       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4485     }
4486   else
4487     {
4488       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4489       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4490       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4491       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4492     }
4494   if (operands[2] == 0 || operands[3] == 0
4495       || operands[4] == 0 || operands[5] == 0)
4496     FAIL;
4499 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4500 ;; used only once, let combine add in the index again.
4502 (define_split
4503   [(set (match_operand:SI 0 "register_operand" "")
4504         (match_operand:SI 1 "" ""))
4505    (clobber (match_operand 2 "register_operand" ""))]
4506   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4507   [(use (reg:SI R0_REG))]
4508   "
4510   rtx addr, reg, const_int;
4512   if (GET_CODE (operands[1]) != MEM)
4513     FAIL;
4514   addr = XEXP (operands[1], 0);
4515   if (GET_CODE (addr) != PLUS)
4516     FAIL;
4517   reg = XEXP (addr, 0);
4518   const_int = XEXP (addr, 1);
4519   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4520          && GET_CODE (const_int) == CONST_INT))
4521     FAIL;
4522   emit_move_insn (operands[2], const_int);
4523   emit_move_insn (operands[0],
4524                   change_address (operands[1], VOIDmode,
4525                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4526   DONE;
4529 (define_split
4530   [(set (match_operand:SI 1 "" "")
4531         (match_operand:SI 0 "register_operand" ""))
4532    (clobber (match_operand 2 "register_operand" ""))]
4533   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4534   [(use (reg:SI R0_REG))]
4535   "
4537   rtx addr, reg, const_int;
4539   if (GET_CODE (operands[1]) != MEM)
4540     FAIL;
4541   addr = XEXP (operands[1], 0);
4542   if (GET_CODE (addr) != PLUS)
4543     FAIL;
4544   reg = XEXP (addr, 0);
4545   const_int = XEXP (addr, 1);
4546   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4547          && GET_CODE (const_int) == CONST_INT))
4548     FAIL;
4549   emit_move_insn (operands[2], const_int);
4550   emit_move_insn (change_address (operands[1], VOIDmode,
4551                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4552                   operands[0]);
4553   DONE;
4556 (define_expand "movdf"
4557   [(set (match_operand:DF 0 "general_movdst_operand" "")
4558         (match_operand:DF 1 "general_movsrc_operand" ""))]
4559   ""
4560   "
4562   if (prepare_move_operands (operands, DFmode)) DONE;
4563   if (TARGET_SHMEDIA)
4564     {
4565       if (TARGET_SHMEDIA_FPU)
4566         emit_insn (gen_movdf_media (operands[0], operands[1]));
4567       else
4568         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4569       DONE;
4570     }
4571   if (TARGET_SH4)
4572     {
4573       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4574       DONE;
4575     }
4578 ;;This is incompatible with the way gcc uses subregs.
4579 ;;(define_insn "movv2sf_i"
4580 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4581 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4582 ;;  "TARGET_SHMEDIA_FPU
4583 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4584 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4585 ;;  "@
4586 ;;      #
4587 ;;      fld%M1.p        %m1, %0
4588 ;;      fst%M0.p        %m0, %1"
4589 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4591 (define_insn_and_split "movv2sf_i"
4592   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4593         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4594   "TARGET_SHMEDIA_FPU"
4595   "#"
4596   "TARGET_SHMEDIA_FPU && reload_completed"
4597   [(set (match_dup 0) (match_dup 1))]
4598   "
4600   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4601   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4604 (define_expand "movv2sf"
4605   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4606         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4607   "TARGET_SHMEDIA_FPU"
4608   "
4610   if (prepare_move_operands (operands, V2SFmode))
4611     DONE;
4614 (define_expand "addv2sf3"
4615   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4616    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4617    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4618   "TARGET_SHMEDIA_FPU"
4619   "
4621   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4622   DONE;
4625 (define_expand "subv2sf3"
4626   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4627    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4628    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4629   "TARGET_SHMEDIA_FPU"
4630   "
4632   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4633   DONE;
4636 (define_expand "mulv2sf3"
4637   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4638    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4639    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4640   "TARGET_SHMEDIA_FPU"
4641   "
4643   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4644   DONE;
4647 (define_expand "divv2sf3"
4648   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4649    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4650    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4651   "TARGET_SHMEDIA_FPU"
4652   "
4654   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4655   DONE;
4658 (define_insn_and_split "*movv4sf_i"
4659   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4660         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4661   "TARGET_SHMEDIA_FPU"
4662   "#"
4663   "&& reload_completed"
4664   [(const_int 0)]
4665   "
4667   int i;
4669   for (i = 0; i < 4/2; i++)
4670     {
4671       rtx x, y;
4673       if (GET_CODE (operands[0]) == MEM)
4674         x = gen_rtx_MEM (V2SFmode,
4675                          plus_constant (XEXP (operands[0], 0),
4676                                         i * GET_MODE_SIZE (V2SFmode)));
4677       else
4678         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4680       if (GET_CODE (operands[1]) == MEM)
4681         y = gen_rtx_MEM (V2SFmode,
4682                          plus_constant (XEXP (operands[1], 0),
4683                                         i * GET_MODE_SIZE (V2SFmode)));
4684       else
4685         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4687       emit_insn (gen_movv2sf_i (x, y));
4688     }
4690   DONE;
4692   [(set_attr "length" "8")])
4694 (define_expand "movv4sf"
4695   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4696         (match_operand:V4SF 1 "general_operand" ""))]
4697   "TARGET_SHMEDIA_FPU"
4698   "
4700   if (prepare_move_operands (operands, V4SFmode))
4701     DONE;
4704 (define_insn_and_split "*movv16sf_i"
4705   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4706         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4707   "TARGET_SHMEDIA_FPU"
4708   "#"
4709   "&& reload_completed"
4710   [(const_int 0)]
4711   "
4713   int i;
4715   for (i = 0; i < 16/2; i++)
4716     {
4717       rtx x,y;
4719       if (GET_CODE (operands[0]) == MEM)
4720         x = gen_rtx_MEM (V2SFmode,
4721                          plus_constant (XEXP (operands[0], 0),
4722                                         i * GET_MODE_SIZE (V2SFmode)));
4723       else
4724         {
4725           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4726           alter_subreg (&x);
4727         }
4729       if (GET_CODE (operands[1]) == MEM)
4730         y = gen_rtx_MEM (V2SFmode,
4731                          plus_constant (XEXP (operands[1], 0),
4732                                         i * GET_MODE_SIZE (V2SFmode)));
4733       else
4734         {
4735           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4736           alter_subreg (&y);
4737         }
4739       emit_insn (gen_movv2sf_i (x, y));
4740     }
4742   DONE;
4744   [(set_attr "length" "32")])
4746 (define_expand "movv16sf"
4747   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4748         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4749   "TARGET_SHMEDIA_FPU"
4750   "
4752   if (prepare_move_operands (operands, V16SFmode))
4753     DONE;
4756 (define_insn "movsf_media"
4757   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4758         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4759   "TARGET_SHMEDIA_FPU
4760    && (register_operand (operands[0], SFmode)
4761        || sh_register_operand (operands[1], SFmode))"
4762   "@
4763         fmov.s  %1, %0
4764         fmov.ls %N1, %0
4765         fmov.sl %1, %0
4766         add.l   %1, r63, %0
4767         #
4768         fld%M1.s        %m1, %0
4769         fst%M0.s        %m0, %1
4770         ld%M1.l %m1, %0
4771         st%M0.l %m0, %N1"
4772   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4774 (define_insn "movsf_media_nofpu"
4775   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4776         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4777   "TARGET_SHMEDIA
4778    && (register_operand (operands[0], SFmode)
4779        || sh_register_operand (operands[1], SFmode))"
4780   "@
4781         add.l   %1, r63, %0
4782         #
4783         ld%M1.l %m1, %0
4784         st%M0.l %m0, %N1"
4785   [(set_attr "type" "arith_media,*,load_media,store_media")])
4787 (define_split
4788   [(set (match_operand:SF 0 "arith_reg_operand" "")
4789         (match_operand:SF 1 "immediate_operand" ""))]
4790   "TARGET_SHMEDIA && reload_completed
4791    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4792   [(set (match_dup 3) (match_dup 2))]
4793   "
4795   long values;
4796   REAL_VALUE_TYPE value;
4798   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4799   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4800   operands[2] = GEN_INT (values);
4802   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4805 (define_insn "movsf_i"
4806   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4807         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4808   "TARGET_SH1
4809    && (! TARGET_SH2E
4810        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4811        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4812        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4813    && (arith_reg_operand (operands[0], SFmode)
4814        || arith_reg_operand (operands[1], SFmode))"
4815   "@
4816         mov     %1,%0
4817         mov     #0,%0
4818         mov.l   %1,%0
4819         mov.l   %1,%0
4820         mov.l   %1,%0
4821         lds     %1,%0
4822         sts     %1,%0"
4823   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4825 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4826 ;; update_flow_info would not know where to put REG_EQUAL notes
4827 ;; when the destination changes mode.
4828 (define_insn "movsf_ie"
4829   [(set (match_operand:SF 0 "general_movdst_operand"
4830          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4831         (match_operand:SF 1 "general_movsrc_operand"
4832           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4833    (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"))
4834    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4836   "TARGET_SH2E
4837    && (arith_reg_operand (operands[0], SFmode)
4838        || arith_reg_operand (operands[1], SFmode)
4839        || arith_reg_operand (operands[3], SImode)
4840        || (fpul_operand (operands[0], SFmode)
4841            && memory_operand (operands[1], SFmode)
4842            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4843        || (fpul_operand (operands[1], SFmode)
4844            && memory_operand (operands[0], SFmode)
4845            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4846   "@
4847         fmov    %1,%0
4848         mov     %1,%0
4849         fldi0   %0
4850         fldi1   %0
4851         #
4852         fmov.s  %1,%0
4853         fmov.s  %1,%0
4854         mov.l   %1,%0
4855         mov.l   %1,%0
4856         mov.l   %1,%0
4857         fsts    fpul,%0
4858         flds    %1,fpul
4859         lds.l   %1,%0
4860         #
4861         sts     %1,%0
4862         lds     %1,%0
4863         sts.l   %1,%0
4864         lds.l   %1,%0
4865         ! move optimized away"
4866   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4867    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4868    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4869    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4870                                            (const_string "single")
4871                                            (const_string "none")))])
4873 (define_split
4874   [(set (match_operand:SF 0 "register_operand" "")
4875         (match_operand:SF 1 "register_operand" ""))
4876    (use (match_operand:PSI 2 "fpscr_operand" ""))
4877    (clobber (reg:SI FPUL_REG))]
4878   "TARGET_SH1"
4879   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4880               (use (match_dup 2))
4881               (clobber (scratch:SI))])
4882    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4883               (use (match_dup 2))
4884               (clobber (scratch:SI))])]
4885   "")
4887 (define_expand "movsf"
4888   [(set (match_operand:SF 0 "general_movdst_operand" "")
4889         (match_operand:SF 1 "general_movsrc_operand" ""))]
4890   ""
4891   "
4893   if (prepare_move_operands (operands, SFmode))
4894     DONE;
4895   if (TARGET_SHMEDIA)
4896     {
4897       if (TARGET_SHMEDIA_FPU)
4898         emit_insn (gen_movsf_media (operands[0], operands[1]));
4899       else
4900         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4901       DONE;
4902     }
4903   if (TARGET_SH2E)
4904     {
4905       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4906       DONE;
4907     }
4910 (define_insn "mov_nop"
4911   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4912   "TARGET_SH2E"
4913   ""
4914   [(set_attr "length" "0")
4915    (set_attr "type" "nil")])
4917 (define_expand "reload_insf"
4918   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4919                    (match_operand:SF 1 "immediate_operand" "FQ"))
4920               (use (reg:PSI FPSCR_REG))
4921               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4922   "TARGET_SH1"
4923   "")
4925 (define_expand "reload_insi"
4926   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4927                    (match_operand:SF 1 "immediate_operand" "FQ"))
4928               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4929   "TARGET_SH1"
4930   "")
4932 (define_insn "*movsi_y"
4933   [(set (match_operand:SI 0 "register_operand" "=y,y")
4934         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
4935    (clobber (match_scratch:SI 2 "=&z,r"))]
4936   "TARGET_SH2E
4937    && (reload_in_progress || reload_completed)"
4938   "#"
4939   [(set_attr "length" "4")
4940    (set_attr "type" "pcload,move")])
4942 (define_split
4943   [(set (match_operand:SI 0 "register_operand" "")
4944         (match_operand:SI 1 "immediate_operand" ""))
4945    (clobber (match_operand:SI 2 "register_operand" ""))]
4946   "TARGET_SH1"
4947   [(set (match_dup 2) (match_dup 1))
4948    (set (match_dup 0) (match_dup 2))]
4949   "")
4951 (define_split
4952   [(set (match_operand:SI 0 "register_operand" "")
4953         (match_operand:SI 1 "memory_operand" ""))
4954    (clobber (reg:SI R0_REG))]
4955   "TARGET_SH1"
4956   [(set (match_dup 0) (match_dup 1))]
4957   "")
4959 ;; ------------------------------------------------------------------------
4960 ;; Define the real conditional branch instructions.
4961 ;; ------------------------------------------------------------------------
4963 (define_insn "branch_true"
4964   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4965                            (label_ref (match_operand 0 "" ""))
4966                            (pc)))]
4967   "TARGET_SH1"
4968   "* return output_branch (1, insn, operands);"
4969   [(set_attr "type" "cbranch")])
4971 (define_insn "branch_false"
4972   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
4973                            (label_ref (match_operand 0 "" ""))
4974                            (pc)))]
4975   "TARGET_SH1"
4976   "* return output_branch (0, insn, operands);"
4977   [(set_attr "type" "cbranch")])
4979 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
4980 ;; which destination is too far away.
4981 ;; The const_int_operand is distinct for each branch target; it avoids
4982 ;; unwanted matches with redundant_insn.
4983 (define_insn "block_branch_redirect"
4984   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
4985   "TARGET_SH1"
4986   ""
4987   [(set_attr "length" "0")])
4989 ;; This one has the additional purpose to record a possible scratch register
4990 ;; for the following branch.
4991 ;; ??? Unfortunately, just setting the scratch register is not good enough,
4992 ;; because the insn then might be deemed dead and deleted.  And we can't
4993 ;; make the use in the jump insn explicit because that would disable
4994 ;; delay slot scheduling from the target.
4995 (define_insn "indirect_jump_scratch"
4996   [(set (match_operand:SI 0 "register_operand" "=r")
4997         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
4998    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
4999   "TARGET_SH1"
5000   ""
5001   [(set_attr "length" "0")])
5003 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5004 ;; being pulled into the delay slot of a condbranch that has been made to
5005 ;; jump around the unconditional jump because it was out of range.
5006 (define_insn "stuff_delay_slot"
5007   [(set (pc)
5008         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5009    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5010   "TARGET_SH1"
5011   ""
5012   [(set_attr "length" "0")
5013    (set_attr "cond_delay_slot" "yes")])
5015 ;; Conditional branch insns
5017 (define_expand "beq_media"
5018   [(set (pc)
5019         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5020                           (match_operand:DI 2 "arith_operand" "r,I06"))
5021                       (label_ref:DI (match_operand 0 "" ""))
5022                       (pc)))]
5023   "TARGET_SHMEDIA"
5024   "")
5026 (define_insn "*beq_media_i"
5027   [(set (pc)
5028         (if_then_else (match_operator 3 "equality_comparison_operator"
5029                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5030                          (match_operand:DI 2 "arith_operand" "r,I06")])
5031                       (match_operand:DI 0 "target_operand" "b,b")
5032                       (pc)))]
5033   "TARGET_SHMEDIA"
5034   "@
5035         b%o3%'  %1, %2, %0
5036         b%o3i%' %1, %2, %0"
5037   [(set_attr "type" "cbranch_media")])
5039 (define_expand "bne_media"
5040   [(set (pc)
5041         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5042                           (match_operand:DI 2 "arith_operand" "r,I06"))
5043                       (label_ref:DI (match_operand 0 "" ""))
5044                       (pc)))]
5045   "TARGET_SHMEDIA"
5046   "")
5048 (define_expand "bgt_media"
5049   [(set (pc)
5050         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5051                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5052                       (label_ref:DI (match_operand 0 "" ""))
5053                       (pc)))]
5054   "TARGET_SHMEDIA"
5055   "")
5057 (define_expand "bge_media"
5058   [(set (pc)
5059         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5060                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5061                       (label_ref:DI (match_operand 0 "" ""))
5062                       (pc)))]
5063   "TARGET_SHMEDIA"
5064   "")
5066 (define_expand "bgtu_media"
5067   [(set (pc)
5068         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5069                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5070                       (label_ref:DI (match_operand 0 "" ""))
5071                       (pc)))]
5072   "TARGET_SHMEDIA"
5073   "")
5075 (define_expand "bgeu_media"
5076   [(set (pc)
5077         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5078                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5079                       (label_ref:DI (match_operand 0 "" ""))
5080                       (pc)))]
5081   "TARGET_SHMEDIA"
5082   "")
5084 (define_insn "*bgt_media_i"
5085   [(set (pc)
5086         (if_then_else (match_operator 3 "greater_comparison_operator"
5087                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5088                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5089                       (match_operand:DI 0 "target_operand" "b")
5090                       (pc)))]
5091   "TARGET_SHMEDIA"
5092   "b%o3%'       %N1, %N2, %0"
5093   [(set_attr "type" "cbranch_media")])
5095 ;; These are only needed to make invert_jump() happy.
5096 (define_insn "*blt_media_i"
5097   [(set (pc)
5098         (if_then_else (match_operator 3 "less_comparison_operator"
5099                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5100                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5101                       (match_operand:DI 0 "target_operand" "b")
5102                       (pc)))]
5103   "TARGET_SHMEDIA"
5104   "b%o3%'       %N2, %N1, %0"
5105   [(set_attr "type" "cbranch_media")])
5107 (define_expand "beq"
5108   [(set (pc)
5109         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5110                       (label_ref (match_operand 0 "" ""))
5111                       (pc)))]
5112   ""
5113   "
5115   if (TARGET_SHMEDIA)
5116     {
5117       if (GET_MODE (sh_compare_op0) != DImode)
5118         {
5119           rtx tmp = gen_reg_rtx (DImode);
5121           emit_insn (gen_seq (tmp));
5122           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5123           DONE;
5124         }
5126       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5127       emit_jump_insn (gen_beq_media (operands[0],
5128                                      sh_compare_op0, sh_compare_op1));
5129       DONE;
5130     }
5132   from_compare (operands, EQ);
5135 (define_expand "bne"
5136   [(set (pc)
5137         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5138                       (label_ref (match_operand 0 "" ""))
5139                       (pc)))]
5140   ""
5141   "
5143   if (TARGET_SHMEDIA)
5144     {
5145       if (GET_MODE (sh_compare_op0) != DImode)
5146         {
5147           rtx tmp = gen_reg_rtx (DImode);
5149           emit_insn (gen_seq (tmp));
5150           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5151           DONE;
5152         }
5154       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5155       emit_jump_insn (gen_bne_media (operands[0],
5156                                      sh_compare_op0, sh_compare_op1));
5157       DONE;
5158     }
5160   from_compare (operands, EQ);
5163 (define_expand "bgt"
5164   [(set (pc)
5165         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5166                       (label_ref (match_operand 0 "" ""))
5167                       (pc)))]
5168   ""
5169   "
5171   if (TARGET_SHMEDIA)
5172     {
5173       if (GET_MODE (sh_compare_op0) != DImode)
5174         {
5175           rtx tmp = gen_reg_rtx (DImode);
5177           emit_insn (gen_sgt (tmp));
5178           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5179           DONE;
5180         }
5182       if (sh_compare_op0 != const0_rtx)
5183         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5184       if (sh_compare_op1 != const0_rtx)
5185         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5186       emit_jump_insn (gen_bgt_media (operands[0],
5187                                      sh_compare_op0, sh_compare_op1));
5188       DONE;
5189     }
5191   from_compare (operands, GT);
5194 (define_expand "blt"
5195   [(set (pc)
5196         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5197                       (label_ref (match_operand 0 "" ""))
5198                       (pc)))]
5199   ""
5200   "
5202   if (TARGET_SHMEDIA)
5203     {
5204       if (GET_MODE (sh_compare_op0) != DImode)
5205         {
5206           rtx tmp = gen_reg_rtx (DImode);
5208           emit_insn (gen_slt (tmp));
5209           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5210           DONE;
5211         }
5213       if (sh_compare_op0 != const0_rtx)
5214         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5215       if (sh_compare_op1 != const0_rtx)
5216         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5217       emit_jump_insn (gen_bgt_media (operands[0],
5218                                      sh_compare_op1, sh_compare_op0));
5219       DONE;
5220     }
5222   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5223     {
5224       rtx tmp = sh_compare_op0;
5225       sh_compare_op0 = sh_compare_op1;
5226       sh_compare_op1 = tmp;
5227       emit_insn (gen_bgt (operands[0]));
5228       DONE;
5229     }
5230   from_compare (operands, GE);
5233 (define_expand "ble"
5234   [(set (pc)
5235         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5236                       (label_ref (match_operand 0 "" ""))
5237                       (pc)))]
5238   ""
5239   "
5241   if (TARGET_SHMEDIA)
5242     {
5243       if (GET_MODE (sh_compare_op0) != DImode)
5244         {
5245           rtx tmp = gen_reg_rtx (DImode);
5247           emit_insn (gen_sle (tmp));
5248           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5249           DONE;
5250         }
5252       if (sh_compare_op0 != const0_rtx)
5253         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5254       if (sh_compare_op1 != const0_rtx)
5255         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5256       emit_jump_insn (gen_bge_media (operands[0],
5257                                      sh_compare_op1, sh_compare_op0));
5258       DONE;
5259     }
5261   if (TARGET_SH2E
5262       && TARGET_IEEE
5263       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5264     {
5265       rtx tmp = sh_compare_op0;
5266       sh_compare_op0 = sh_compare_op1;
5267       sh_compare_op1 = tmp;
5268       emit_insn (gen_bge (operands[0]));
5269       DONE;
5270     }
5271   from_compare (operands, GT);
5274 (define_expand "bge"
5275   [(set (pc)
5276         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5277                       (label_ref (match_operand 0 "" ""))
5278                       (pc)))]
5279   ""
5280   "
5282   if (TARGET_SHMEDIA)
5283     {
5284       if (GET_MODE (sh_compare_op0) != DImode)
5285         {
5286           rtx tmp = gen_reg_rtx (DImode);
5288           emit_insn (gen_sge (tmp));
5289           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5290           DONE;
5291         }
5293       if (sh_compare_op0 != const0_rtx)
5294         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5295       if (sh_compare_op1 != const0_rtx)
5296         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5297       emit_jump_insn (gen_bge_media (operands[0],
5298                                      sh_compare_op0, sh_compare_op1));
5299       DONE;
5300     }
5302   if (TARGET_SH2E
5303       && ! TARGET_IEEE
5304       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5305     {
5306       rtx tmp = sh_compare_op0;
5307       sh_compare_op0 = sh_compare_op1;
5308       sh_compare_op1 = tmp;
5309       emit_insn (gen_ble (operands[0]));
5310       DONE;
5311     }
5312   from_compare (operands, GE);
5315 (define_expand "bgtu"
5316   [(set (pc)
5317         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5318                       (label_ref (match_operand 0 "" ""))
5319                       (pc)))]
5320   ""
5321   "
5323   if (TARGET_SHMEDIA)
5324     {
5325       if (sh_compare_op0 != const0_rtx)
5326         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5327       if (sh_compare_op1 != const0_rtx)
5328         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5329       emit_jump_insn (gen_bgtu_media (operands[0],
5330                                       sh_compare_op0, sh_compare_op1));
5331       DONE;
5332     }
5334   from_compare (operands, GTU);
5337 (define_expand "bltu"
5338   [(set (pc)
5339         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5340                       (label_ref (match_operand 0 "" ""))
5341                       (pc)))]
5342   ""
5343   "
5345   if (TARGET_SHMEDIA)
5346     {
5347       if (sh_compare_op0 != const0_rtx)
5348         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5349       if (sh_compare_op1 != const0_rtx)
5350         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5351       emit_jump_insn (gen_bgtu_media (operands[0],
5352                                       sh_compare_op1, sh_compare_op0));
5353       DONE;
5354     }
5356   from_compare (operands, GEU);
5359 (define_expand "bgeu"
5360   [(set (pc)
5361         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5362                       (label_ref (match_operand 0 "" ""))
5363                       (pc)))]
5364   ""
5365   "
5367   if (TARGET_SHMEDIA)
5368     {
5369       if (sh_compare_op0 != const0_rtx)
5370         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5371       if (sh_compare_op1 != const0_rtx)
5372         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5373       emit_jump_insn (gen_bgeu_media (operands[0],
5374                                       sh_compare_op0, sh_compare_op1));
5375       DONE;
5376     }
5378   from_compare (operands, GEU);
5381 (define_expand "bleu"
5382   [(set (pc)
5383         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5384                       (label_ref (match_operand 0 "" ""))
5385                       (pc)))]
5386   ""
5387   "
5389   if (TARGET_SHMEDIA)
5390     {
5391       if (sh_compare_op0 != const0_rtx)
5392         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5393       if (sh_compare_op1 != const0_rtx)
5394         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5395       emit_jump_insn (gen_bgeu_media (operands[0],
5396                                       sh_compare_op1, sh_compare_op0));
5397       DONE;
5398     }
5400   from_compare (operands, GTU);
5403 (define_expand "bunordered"
5404   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5405    (set (pc)
5406         (if_then_else (ne (match_dup 1) (const_int 0))
5407                       (label_ref:DI (match_operand 0 "" ""))
5408                       (pc)))]
5409   "TARGET_SHMEDIA"
5410   "
5412   operands[1] = gen_reg_rtx (DImode);
5413   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5414   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5417 ;; ------------------------------------------------------------------------
5418 ;; Jump and linkage insns
5419 ;; ------------------------------------------------------------------------
5421 (define_insn "jump_compact"
5422   [(set (pc)
5423         (label_ref (match_operand 0 "" "")))]
5424   "TARGET_SH1"
5425   "*
5427   /* The length is 16 if the delay slot is unfilled.  */
5428   if (get_attr_length(insn) > 4)
5429     return output_far_jump(insn, operands[0]);
5430   else
5431     return   \"bra      %l0%#\";
5433   [(set_attr "type" "jump")
5434    (set_attr "needs_delay_slot" "yes")])
5436 ;; ??? It would be much saner to explicitly use the scratch register
5437 ;; in the jump insn, and have indirect_jump_scratch only set it,
5438 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5439 ;; from the target then, as it uses simplejump_p.
5440 ;;(define_insn "jump_compact_far"
5441 ;;  [(set (pc)
5442 ;;      (label_ref (match_operand 0 "" "")))
5443 ;;   (use (match_operand 1 "register_operand" "r")]
5444 ;;  "TARGET_SH1"
5445 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5446 ;;  [(set_attr "type" "jump")
5447 ;;   (set_attr "needs_delay_slot" "yes")])
5449 (define_insn "jump_media"
5450   [(set (pc)
5451         (match_operand:DI 0 "target_operand" "b"))]
5452   "TARGET_SHMEDIA"
5453   "blink        %0, r63"
5454   [(set_attr "type" "jump_media")])
5456 (define_expand "jump"
5457   [(set (pc)
5458         (label_ref (match_operand 0 "" "")))]
5459   ""
5460   "
5462   if (TARGET_SH1)
5463     emit_jump_insn (gen_jump_compact (operands[0]));
5464   else if (TARGET_SHMEDIA)
5465     {
5466       if (reload_in_progress || reload_completed)
5467         FAIL;
5468       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5469                                                          operands[0])));
5470     }
5471   DONE;
5474 (define_insn "force_mode_for_call"
5475   [(use (reg:PSI FPSCR_REG))]
5476   "TARGET_SHCOMPACT"
5477   ""
5478   [(set_attr "length" "0")
5479    (set (attr "fp_mode")
5480         (if_then_else (eq_attr "fpu_single" "yes")
5481                       (const_string "single") (const_string "double")))])
5483 (define_insn "calli"
5484   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5485          (match_operand 1 "" ""))
5486    (use (reg:PSI FPSCR_REG))
5487    (clobber (reg:SI PR_REG))]
5488   "TARGET_SH1"
5489   "jsr  @%0%#"
5490   [(set_attr "type" "call")
5491    (set (attr "fp_mode")
5492         (if_then_else (eq_attr "fpu_single" "yes")
5493                       (const_string "single") (const_string "double")))
5494    (set_attr "needs_delay_slot" "yes")
5495    (set_attr "fp_set" "unknown")])
5497 ;; This is a pc-rel call, using bsrf, for use with PIC.
5499 (define_insn "calli_pcrel"
5500   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5501          (match_operand 1 "" ""))
5502    (use (reg:PSI FPSCR_REG))
5503    (use (reg:SI PIC_REG))
5504    (use (match_operand 2 "" ""))
5505    (clobber (reg:SI PR_REG))]
5506   "TARGET_SH2"
5507   "bsrf %0\\n%O2:%#"
5508   [(set_attr "type" "call")
5509    (set (attr "fp_mode")
5510         (if_then_else (eq_attr "fpu_single" "yes")
5511                       (const_string "single") (const_string "double")))
5512    (set_attr "needs_delay_slot" "yes")
5513    (set_attr "fp_set" "unknown")])
5515 (define_insn_and_split "call_pcrel"
5516   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5517          (match_operand 1 "" ""))
5518    (use (reg:PSI FPSCR_REG))
5519    (use (reg:SI PIC_REG))
5520    (clobber (reg:SI PR_REG))
5521    (clobber (match_scratch:SI 2 "=r"))]
5522   "TARGET_SH2"
5523   "#"
5524   "reload_completed"
5525   [(const_int 0)]
5526   "
5528   rtx lab = PATTERN (gen_call_site ());
5530   if (SYMBOL_REF_LOCAL_P (operands[0]))
5531     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5532   else
5533     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5534   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5535   DONE;
5537   [(set_attr "type" "call")
5538    (set (attr "fp_mode")
5539         (if_then_else (eq_attr "fpu_single" "yes")
5540                       (const_string "single") (const_string "double")))
5541    (set_attr "needs_delay_slot" "yes")
5542    (set_attr "fp_set" "unknown")])
5544 (define_insn "call_compact"
5545   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5546          (match_operand 1 "" ""))
5547    (match_operand 2 "immediate_operand" "n")
5548    (use (reg:SI R0_REG))
5549    (use (reg:SI R1_REG))
5550    (use (reg:PSI FPSCR_REG))
5551    (clobber (reg:SI PR_REG))]
5552   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5553   "jsr  @%0%#"
5554   [(set_attr "type" "call")
5555    (set (attr "fp_mode")
5556         (if_then_else (eq_attr "fpu_single" "yes")
5557                       (const_string "single") (const_string "double")))
5558    (set_attr "needs_delay_slot" "yes")])
5560 (define_insn "call_compact_rettramp"
5561   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5562          (match_operand 1 "" ""))
5563    (match_operand 2 "immediate_operand" "n")
5564    (use (reg:SI R0_REG))
5565    (use (reg:SI R1_REG))
5566    (use (reg:PSI FPSCR_REG))
5567    (clobber (reg:SI R10_REG))
5568    (clobber (reg:SI PR_REG))]
5569   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5570   "jsr  @%0%#"
5571   [(set_attr "type" "call")
5572    (set (attr "fp_mode")
5573         (if_then_else (eq_attr "fpu_single" "yes")
5574                       (const_string "single") (const_string "double")))
5575    (set_attr "needs_delay_slot" "yes")])
5577 (define_insn "call_media"
5578   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5579          (match_operand 1 "" ""))
5580    (clobber (reg:DI PR_MEDIA_REG))]
5581   "TARGET_SHMEDIA"
5582   "blink        %0, r18"
5583   [(set_attr "type" "jump_media")])
5585 (define_insn "call_valuei"
5586   [(set (match_operand 0 "" "=rf")
5587         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5588               (match_operand 2 "" "")))
5589    (use (reg:PSI FPSCR_REG))
5590    (clobber (reg:SI PR_REG))]
5591   "TARGET_SH1"
5592   "jsr  @%1%#"
5593   [(set_attr "type" "call")
5594    (set (attr "fp_mode")
5595         (if_then_else (eq_attr "fpu_single" "yes")
5596                       (const_string "single") (const_string "double")))
5597    (set_attr "needs_delay_slot" "yes")
5598    (set_attr "fp_set" "unknown")])
5600 (define_insn "call_valuei_pcrel"
5601   [(set (match_operand 0 "" "=rf")
5602         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5603               (match_operand 2 "" "")))
5604    (use (reg:PSI FPSCR_REG))
5605    (use (reg:SI PIC_REG))
5606    (use (match_operand 3 "" ""))
5607    (clobber (reg:SI PR_REG))]
5608   "TARGET_SH2"
5609   "bsrf %1\\n%O3:%#"
5610   [(set_attr "type" "call")
5611    (set (attr "fp_mode")
5612         (if_then_else (eq_attr "fpu_single" "yes")
5613                       (const_string "single") (const_string "double")))
5614    (set_attr "needs_delay_slot" "yes")
5615    (set_attr "fp_set" "unknown")])
5617 (define_insn_and_split "call_value_pcrel"
5618   [(set (match_operand 0 "" "=rf")
5619         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5620               (match_operand 2 "" "")))
5621    (use (reg:PSI FPSCR_REG))
5622    (use (reg:SI PIC_REG))
5623    (clobber (reg:SI PR_REG))
5624    (clobber (match_scratch:SI 3 "=r"))]
5625   "TARGET_SH2"
5626   "#"
5627   "reload_completed"
5628   [(const_int 0)]
5629   "
5631   rtx lab = PATTERN (gen_call_site ());
5633   if (SYMBOL_REF_LOCAL_P (operands[1]))
5634     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5635   else
5636     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5637   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5638                                          operands[2], lab));
5639   DONE;
5641   [(set_attr "type" "call")
5642    (set (attr "fp_mode")
5643         (if_then_else (eq_attr "fpu_single" "yes")
5644                       (const_string "single") (const_string "double")))
5645    (set_attr "needs_delay_slot" "yes")
5646    (set_attr "fp_set" "unknown")])
5648 (define_insn "call_value_compact"
5649   [(set (match_operand 0 "" "=rf")
5650         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5651               (match_operand 2 "" "")))
5652    (match_operand 3 "immediate_operand" "n")
5653    (use (reg:SI R0_REG))
5654    (use (reg:SI R1_REG))
5655    (use (reg:PSI FPSCR_REG))
5656    (clobber (reg:SI PR_REG))]
5657   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5658   "jsr  @%1%#"
5659   [(set_attr "type" "call")
5660    (set (attr "fp_mode")
5661         (if_then_else (eq_attr "fpu_single" "yes")
5662                       (const_string "single") (const_string "double")))
5663    (set_attr "needs_delay_slot" "yes")])
5665 (define_insn "call_value_compact_rettramp"
5666   [(set (match_operand 0 "" "=rf")
5667         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5668               (match_operand 2 "" "")))
5669    (match_operand 3 "immediate_operand" "n")
5670    (use (reg:SI R0_REG))
5671    (use (reg:SI R1_REG))
5672    (use (reg:PSI FPSCR_REG))
5673    (clobber (reg:SI R10_REG))
5674    (clobber (reg:SI PR_REG))]
5675   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5676   "jsr  @%1%#"
5677   [(set_attr "type" "call")
5678    (set (attr "fp_mode")
5679         (if_then_else (eq_attr "fpu_single" "yes")
5680                       (const_string "single") (const_string "double")))
5681    (set_attr "needs_delay_slot" "yes")])
5683 (define_insn "call_value_media"
5684   [(set (match_operand 0 "" "=rf")
5685         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5686               (match_operand 2 "" "")))
5687    (clobber (reg:DI PR_MEDIA_REG))]
5688   "TARGET_SHMEDIA"
5689   "blink        %1, r18"
5690   [(set_attr "type" "jump_media")])
5692 (define_expand "call"
5693   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5694                             (match_operand 1 "" ""))
5695               (match_operand 2 "" "")
5696               (use (reg:PSI FPSCR_REG))
5697               (clobber (reg:SI PR_REG))])]
5698   ""
5699   "
5701   if (TARGET_SHMEDIA)
5702     {
5703       operands[0] = XEXP (operands[0], 0);
5704       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5705         {
5706           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5707             {
5708               rtx reg = gen_reg_rtx (Pmode);
5710               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5711               operands[0] = reg;
5712             }
5713           else
5714             {
5715               operands[0] = gen_sym2PIC (operands[0]);
5716               PUT_MODE (operands[0], Pmode);
5717             }
5718         }
5719       if (GET_MODE (operands[0]) == SImode)
5720         {
5721           if (GET_CODE (operands[0]) == REG)
5722             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5723           else if (GET_CODE (operands[0]) == SUBREG)
5724             {
5725               operands[0] = SUBREG_REG (operands[0]);
5726               if (GET_MODE (operands[0]) != DImode)
5727                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5728             }
5729           else
5730             {
5731               operands[0] = shallow_copy_rtx (operands[0]);
5732               PUT_MODE (operands[0], DImode);
5733             }
5734         }
5735       if (! target_reg_operand (operands[0], DImode))
5736         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5737       emit_call_insn (gen_call_media (operands[0], operands[1]));
5738       DONE;
5739     }
5740   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5741     {
5742       rtx cookie_rtx = operands[2];
5743       long cookie = INTVAL (cookie_rtx);
5744       rtx func = XEXP (operands[0], 0);
5745       rtx r0, r1;
5747       if (flag_pic)
5748         {
5749           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5750             {
5751               rtx reg = gen_reg_rtx (Pmode);
5753               emit_insn (gen_symGOTPLT2reg (reg, func));
5754               func = reg;
5755             }
5756           else
5757             func = legitimize_pic_address (func, Pmode, 0);
5758         }
5760       r0 = gen_rtx_REG (SImode, R0_REG);
5761       r1 = gen_rtx_REG (SImode, R1_REG);
5763       /* Since such a call function may use all call-clobbered
5764          registers, we force a mode switch earlier, so that we don't
5765          run out of registers when adjusting fpscr for the call.  */
5766       emit_insn (gen_force_mode_for_call ());
5768       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5769       if (flag_pic)
5770         {
5771           rtx reg = gen_reg_rtx (Pmode);
5773           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5774           operands[0] = reg;
5775         }
5776       operands[0] = force_reg (SImode, operands[0]);
5778       emit_move_insn (r0, func);
5779       emit_move_insn (r1, cookie_rtx);
5781       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5782         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5783                                                    operands[2]));
5784       else
5785         emit_call_insn (gen_call_compact (operands[0], operands[1],
5786                                           operands[2]));
5788       DONE;
5789     }
5790   else if (TARGET_SHCOMPACT && flag_pic
5791            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5792            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5793     {
5794       rtx reg = gen_reg_rtx (Pmode);
5796       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5797       XEXP (operands[0], 0) = reg;
5798     }
5799   if (flag_pic && TARGET_SH2
5800       && GET_CODE (operands[0]) == MEM
5801       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5802     {
5803       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5804       DONE;
5805     }
5806   else
5807   {
5808     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5809     operands[1] = operands[2];
5810   }
5812   emit_call_insn (gen_calli (operands[0], operands[1]));
5813   DONE;
5816 (define_insn "call_pop_compact"
5817   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5818          (match_operand 1 "" ""))
5819    (match_operand 2 "immediate_operand" "n")
5820    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5821                                  (match_operand 3 "immediate_operand" "n")))
5822    (use (reg:SI R0_REG))
5823    (use (reg:SI R1_REG))
5824    (use (reg:PSI FPSCR_REG))
5825    (clobber (reg:SI PR_REG))]
5826   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5827   "jsr  @%0%#"
5828   [(set_attr "type" "call")
5829    (set (attr "fp_mode")
5830         (if_then_else (eq_attr "fpu_single" "yes")
5831                       (const_string "single") (const_string "double")))
5832    (set_attr "needs_delay_slot" "yes")])
5834 (define_insn "call_pop_compact_rettramp"
5835   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5836          (match_operand 1 "" ""))
5837    (match_operand 2 "immediate_operand" "n")
5838    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5839                                  (match_operand 3 "immediate_operand" "n")))
5840    (use (reg:SI R0_REG))
5841    (use (reg:SI R1_REG))
5842    (use (reg:PSI FPSCR_REG))
5843    (clobber (reg:SI R10_REG))
5844    (clobber (reg:SI PR_REG))]
5845   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5846   "jsr  @%0%#"
5847   [(set_attr "type" "call")
5848    (set (attr "fp_mode")
5849         (if_then_else (eq_attr "fpu_single" "yes")
5850                       (const_string "single") (const_string "double")))
5851    (set_attr "needs_delay_slot" "yes")])
5853 (define_expand "call_pop"
5854   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5855                     (match_operand 1 "" ""))
5856              (match_operand 2 "" "")
5857              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5858                                            (match_operand 3 "" "")))])]
5859   "TARGET_SHCOMPACT"
5860   "
5862   if (operands[2] && INTVAL (operands[2]))
5863     {
5864       rtx cookie_rtx = operands[2];
5865       long cookie = INTVAL (cookie_rtx);
5866       rtx func = XEXP (operands[0], 0);
5867       rtx r0, r1;
5869       if (flag_pic)
5870         {
5871           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5872             {
5873               rtx reg = gen_reg_rtx (Pmode);
5875               emit_insn (gen_symGOTPLT2reg (reg, func));
5876               func = reg;
5877             }
5878           else
5879             func = legitimize_pic_address (func, Pmode, 0);
5880         }
5882       r0 = gen_rtx_REG (SImode, R0_REG);
5883       r1 = gen_rtx_REG (SImode, R1_REG);
5885       /* Since such a call function may use all call-clobbered
5886          registers, we force a mode switch earlier, so that we don't
5887          run out of registers when adjusting fpscr for the call.  */
5888       emit_insn (gen_force_mode_for_call ());
5890       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5891       if (flag_pic)
5892         {
5893           rtx reg = gen_reg_rtx (Pmode);
5895           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5896           operands[0] = reg;
5897         }
5898       operands[0] = force_reg (SImode, operands[0]);
5900       emit_move_insn (r0, func);
5901       emit_move_insn (r1, cookie_rtx);
5903       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5904         emit_call_insn (gen_call_pop_compact_rettramp
5905                         (operands[0], operands[1], operands[2], operands[3]));
5906       else
5907         emit_call_insn (gen_call_pop_compact
5908                         (operands[0], operands[1], operands[2], operands[3]));
5910       DONE;
5911     }
5913   abort ();
5916 (define_expand "call_value"
5917   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5918                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5919                                  (match_operand 2 "" "")))
5920               (match_operand 3 "" "")
5921               (use (reg:PSI FPSCR_REG))
5922               (clobber (reg:SI PR_REG))])]
5923   ""
5924   "
5926   if (TARGET_SHMEDIA)
5927     {
5928       operands[1] = XEXP (operands[1], 0);
5929       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5930         {
5931           if (! SYMBOL_REF_LOCAL_P (operands[1]))
5932             {
5933               rtx reg = gen_reg_rtx (Pmode);
5935               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5936               operands[1] = reg;
5937             }
5938           else
5939             {
5940               operands[1] = gen_sym2PIC (operands[1]);
5941               PUT_MODE (operands[1], Pmode);
5942             }
5943         }
5944       if (GET_MODE (operands[1]) == SImode)
5945         {
5946           if (GET_CODE (operands[1]) == REG)
5947             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5948           else if (GET_CODE (operands[1]) == SUBREG)
5949             {
5950               operands[1] = SUBREG_REG (operands[1]);
5951               if (GET_MODE (operands[1]) != DImode)
5952                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5953             }
5954           else
5955             {
5956               operands[1] = shallow_copy_rtx (operands[1]);
5957               PUT_MODE (operands[1], DImode);
5958             }
5959         }
5960       if (! target_reg_operand (operands[1], DImode))
5961         operands[1] = copy_to_mode_reg (DImode, operands[1]);
5962       emit_call_insn (gen_call_value_media (operands[0], operands[1],
5963                                             operands[2]));
5964       DONE;
5965     }
5966   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5967     {
5968       rtx cookie_rtx = operands[3];
5969       long cookie = INTVAL (cookie_rtx);
5970       rtx func = XEXP (operands[1], 0);
5971       rtx r0, r1;
5973       if (flag_pic)
5974         {
5975           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5976             {
5977               rtx reg = gen_reg_rtx (Pmode);
5979               emit_insn (gen_symGOTPLT2reg (reg, func));
5980               func = reg;
5981             }
5982           else
5983             func = legitimize_pic_address (func, Pmode, 0);
5984         }
5986       r0 = gen_rtx_REG (SImode, R0_REG);
5987       r1 = gen_rtx_REG (SImode, R1_REG);
5989       /* Since such a call function may use all call-clobbered
5990          registers, we force a mode switch earlier, so that we don't
5991          run out of registers when adjusting fpscr for the call.  */
5992       emit_insn (gen_force_mode_for_call ());
5994       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5995       if (flag_pic)
5996         {
5997           rtx reg = gen_reg_rtx (Pmode);
5999           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6000           operands[1] = reg;
6001         }
6002       operands[1] = force_reg (SImode, operands[1]);
6004       emit_move_insn (r0, func);
6005       emit_move_insn (r1, cookie_rtx);
6007       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6008         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6009                                                          operands[1],
6010                                                          operands[2],
6011                                                          operands[3]));
6012       else
6013         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6014                                                 operands[2], operands[3]));
6016       DONE;
6017     }
6018   else if (TARGET_SHCOMPACT && flag_pic
6019            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6020            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6021     {
6022       rtx reg = gen_reg_rtx (Pmode);
6024       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6025       XEXP (operands[1], 0) = reg;
6026     }
6027   if (flag_pic && TARGET_SH2
6028       && GET_CODE (operands[1]) == MEM
6029       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6030     {
6031       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6032                                             operands[2]));
6033       DONE;
6034     }
6035   else
6036     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6038   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6039   DONE;
6042 (define_insn "sibcalli"
6043   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6044          (match_operand 1 "" ""))
6045    (use (reg:PSI FPSCR_REG))
6046    (return)]
6047   "TARGET_SH1"
6048   "jmp  @%0%#"
6049   [(set_attr "needs_delay_slot" "yes")
6050    (set (attr "fp_mode")
6051         (if_then_else (eq_attr "fpu_single" "yes")
6052                       (const_string "single") (const_string "double")))
6053    (set_attr "type" "jump_ind")])
6055 (define_insn "sibcalli_pcrel"
6056   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6057          (match_operand 1 "" ""))
6058    (use (match_operand 2 "" ""))
6059    (use (reg:PSI FPSCR_REG))
6060    (return)]
6061   "TARGET_SH2"
6062   "braf %0\\n%O2:%#"
6063   [(set_attr "needs_delay_slot" "yes")
6064    (set (attr "fp_mode")
6065         (if_then_else (eq_attr "fpu_single" "yes")
6066                       (const_string "single") (const_string "double")))
6067    (set_attr "type" "jump_ind")])
6069 (define_insn_and_split "sibcall_pcrel"
6070   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6071          (match_operand 1 "" ""))
6072    (use (reg:PSI FPSCR_REG))
6073    (clobber (match_scratch:SI 2 "=k"))
6074    (return)]
6075   "TARGET_SH2"
6076   "#"
6077   "reload_completed"
6078   [(const_int 0)]
6079   "
6081   rtx lab = PATTERN (gen_call_site ());
6082   rtx call_insn;
6084   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6085   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6086                                                   lab));
6087   SIBLING_CALL_P (call_insn) = 1;
6088   DONE;
6090   [(set_attr "needs_delay_slot" "yes")
6091    (set (attr "fp_mode")
6092         (if_then_else (eq_attr "fpu_single" "yes")
6093                       (const_string "single") (const_string "double")))
6094    (set_attr "type" "jump_ind")])
6096 (define_insn "sibcall_compact"
6097   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6098          (match_operand 1 "" ""))
6099    (return)
6100    (use (match_operand:SI 2 "register_operand" "z,x"))
6101    (use (reg:SI R1_REG))
6102    (use (reg:PSI FPSCR_REG))
6103    ;; We want to make sure the `x' above will only match MACH_REG
6104    ;; because sibcall_epilogue may clobber MACL_REG.
6105    (clobber (reg:SI MACL_REG))]
6106   "TARGET_SHCOMPACT"
6107   "@
6108         jmp     @%0%#
6109         jmp     @%0\\n  sts     %2, r0"
6110   [(set_attr "needs_delay_slot" "yes,no")
6111    (set_attr "length" "2,4")
6112    (set (attr "fp_mode") (const_string "single"))
6113    (set_attr "type" "jump_ind")])
6115 (define_insn "sibcall_media"
6116   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6117          (match_operand 1 "" ""))
6118    (use (reg:SI PR_MEDIA_REG))
6119    (return)]
6120   "TARGET_SHMEDIA"
6121   "blink        %0, r63"
6122   [(set_attr "type" "jump_media")])
6124 (define_expand "sibcall"
6125   [(parallel
6126     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6127            (match_operand 1 "" ""))
6128      (match_operand 2 "" "")
6129      (use (reg:PSI FPSCR_REG))
6130      (return)])]
6131   ""
6132   "
6134   if (TARGET_SHMEDIA)
6135     {
6136       operands[0] = XEXP (operands[0], 0);
6137       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6138         {
6139           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6140             {
6141               rtx reg = gen_reg_rtx (Pmode);
6143               /* We must not use GOTPLT for sibcalls, because PIC_REG
6144                  must be restored before the PLT code gets to run.  */
6145               emit_insn (gen_symGOT2reg (reg, operands[0]));
6146               operands[0] = reg;
6147             }
6148           else
6149             {
6150               operands[0] = gen_sym2PIC (operands[0]);
6151               PUT_MODE (operands[0], Pmode);
6152             }
6153         }
6154       if (GET_MODE (operands[0]) == SImode)
6155         {
6156           if (GET_CODE (operands[0]) == REG)
6157             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6158           else if (GET_CODE (operands[0]) == SUBREG)
6159             {
6160               operands[0] = SUBREG_REG (operands[0]);
6161               if (GET_MODE (operands[0]) != DImode)
6162                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6163             }
6164           else
6165             {
6166               operands[0] = shallow_copy_rtx (operands[0]);
6167               PUT_MODE (operands[0], DImode);
6168             }
6169         }
6170       if (! target_reg_operand (operands[0], DImode))
6171         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6172       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6173       DONE;
6174     }
6175   else if (TARGET_SHCOMPACT && operands[2]
6176            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6177     {
6178       rtx cookie_rtx = operands[2];
6179       long cookie = INTVAL (cookie_rtx);
6180       rtx func = XEXP (operands[0], 0);
6181       rtx mach, r1;
6183       if (flag_pic)
6184         {
6185           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6186             {
6187               rtx reg = gen_reg_rtx (Pmode);
6189               emit_insn (gen_symGOT2reg (reg, func));
6190               func = reg;
6191             }
6192           else
6193             func = legitimize_pic_address (func, Pmode, 0);
6194         }
6196       /* FIXME: if we could tell whether all argument registers are
6197          already taken, we could decide whether to force the use of
6198          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6199          simple way to tell.  We could use the CALL_COOKIE, but we
6200          can't currently tell a register used for regular argument
6201          passing from one that is unused.  If we leave it up to reload
6202          to decide which register to use, it seems to always choose
6203          R0_REG, which leaves no available registers in SIBCALL_REGS
6204          to hold the address of the trampoline.  */
6205       mach = gen_rtx_REG (SImode, MACH_REG);
6206       r1 = gen_rtx_REG (SImode, R1_REG);
6208       /* Since such a call function may use all call-clobbered
6209          registers, we force a mode switch earlier, so that we don't
6210          run out of registers when adjusting fpscr for the call.  */
6211       emit_insn (gen_force_mode_for_call ());
6213       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6214       if (flag_pic)
6215         {
6216           rtx reg = gen_reg_rtx (Pmode);
6218           emit_insn (gen_symGOT2reg (reg, operands[0]));
6219           operands[0] = reg;
6220         }
6221       operands[0] = force_reg (SImode, operands[0]);
6223       /* We don't need a return trampoline, since the callee will
6224          return directly to the upper caller.  */
6225       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6226         {
6227           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6228           cookie_rtx = GEN_INT (cookie);
6229         }
6231       emit_move_insn (mach, func);
6232       emit_move_insn (r1, cookie_rtx);
6234       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6235       DONE;
6236     }
6237   else if (TARGET_SHCOMPACT && flag_pic
6238            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6239            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6240     {
6241       rtx reg = gen_reg_rtx (Pmode);
6243       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6244       XEXP (operands[0], 0) = reg;
6245     }
6246   if (flag_pic && TARGET_SH2
6247       && GET_CODE (operands[0]) == MEM
6248       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6249       /* The PLT needs the PIC register, but the epilogue would have
6250          to restore it, so we can only use PC-relative PIC calls for
6251          static functions.  */
6252       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6253     {
6254       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6255       DONE;
6256     }
6257   else
6258     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6260   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6261   DONE;
6264 (define_expand "sibcall_value"
6265   [(set (match_operand 0 "" "")
6266         (call (match_operand 1 "" "")
6267               (match_operand 2 "" "")))
6268    (match_operand 3 "" "")]
6269   ""
6270   "
6272   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6273   DONE;
6276 (define_insn "call_value_pop_compact"
6277   [(set (match_operand 0 "" "=rf")
6278         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6279               (match_operand 2 "" "")))
6280    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6281                                  (match_operand 4 "immediate_operand" "n")))
6282    (match_operand 3 "immediate_operand" "n")
6283    (use (reg:SI R0_REG))
6284    (use (reg:SI R1_REG))
6285    (use (reg:PSI FPSCR_REG))
6286    (clobber (reg:SI PR_REG))]
6287   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6288   "jsr  @%1%#"
6289   [(set_attr "type" "call")
6290    (set (attr "fp_mode")
6291         (if_then_else (eq_attr "fpu_single" "yes")
6292                       (const_string "single") (const_string "double")))
6293    (set_attr "needs_delay_slot" "yes")])
6295 (define_insn "call_value_pop_compact_rettramp"
6296   [(set (match_operand 0 "" "=rf")
6297         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6298               (match_operand 2 "" "")))
6299    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6300                                  (match_operand 4 "immediate_operand" "n")))
6301    (match_operand 3 "immediate_operand" "n")
6302    (use (reg:SI R0_REG))
6303    (use (reg:SI R1_REG))
6304    (use (reg:PSI FPSCR_REG))
6305    (clobber (reg:SI R10_REG))
6306    (clobber (reg:SI PR_REG))]
6307   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6308   "jsr  @%1%#"
6309   [(set_attr "type" "call")
6310    (set (attr "fp_mode")
6311         (if_then_else (eq_attr "fpu_single" "yes")
6312                       (const_string "single") (const_string "double")))
6313    (set_attr "needs_delay_slot" "yes")])
6315 (define_expand "call_value_pop"
6316   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6317                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6318                                  (match_operand 2 "" "")))
6319               (match_operand 3 "" "")
6320               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6321                                             (match_operand 4 "" "")))])]
6322   "TARGET_SHCOMPACT"
6323   "
6325   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6326     {
6327       rtx cookie_rtx = operands[3];
6328       long cookie = INTVAL (cookie_rtx);
6329       rtx func = XEXP (operands[1], 0);
6330       rtx r0, r1;
6332       if (flag_pic)
6333         {
6334           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6335             {
6336               rtx reg = gen_reg_rtx (Pmode);
6338               emit_insn (gen_symGOTPLT2reg (reg, func));
6339               func = reg;
6340             }
6341           else
6342             func = legitimize_pic_address (func, Pmode, 0);
6343         }
6345       r0 = gen_rtx_REG (SImode, R0_REG);
6346       r1 = gen_rtx_REG (SImode, R1_REG);
6348       /* Since such a call function may use all call-clobbered
6349          registers, we force a mode switch earlier, so that we don't
6350          run out of registers when adjusting fpscr for the call.  */
6351       emit_insn (gen_force_mode_for_call ());
6353       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6354       if (flag_pic)
6355         {
6356           rtx reg = gen_reg_rtx (Pmode);
6358           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6359           operands[1] = reg;
6360         }
6361       operands[1] = force_reg (SImode, operands[1]);
6363       emit_move_insn (r0, func);
6364       emit_move_insn (r1, cookie_rtx);
6366       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6367         emit_call_insn (gen_call_value_pop_compact_rettramp
6368                         (operands[0], operands[1], operands[2],
6369                          operands[3], operands[4]));
6370       else
6371         emit_call_insn (gen_call_value_pop_compact
6372                         (operands[0], operands[1], operands[2],
6373                          operands[3], operands[4]));
6375       DONE;
6376     }
6378   abort ();
6381 (define_expand "sibcall_epilogue"
6382   [(return)]
6383   ""
6384   "
6386   sh_expand_epilogue (1);
6387   if (TARGET_SHCOMPACT)
6388     {
6389       rtx insn, set;
6391       /* If epilogue clobbers r0, preserve it in macl.  */
6392       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6393         if ((set = single_set (insn))
6394             && GET_CODE (SET_DEST (set)) == REG
6395             && REGNO (SET_DEST (set)) == R0_REG)
6396           {
6397             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6398             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6399             rtx i;
6401             /* We can't tell at this point whether the sibcall is a
6402                sibcall_compact and, if it is, whether it uses r0 or
6403                mach as operand 2, so let the instructions that
6404                preserve r0 be optimized away if r0 turns out to be
6405                dead.  */
6406             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6407             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6408                                                REG_NOTES (i));
6409             i = emit_move_insn (r0, tmp);
6410             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6411                                                REG_NOTES (i));
6412             break;
6413           }
6414     }
6415   DONE;
6418 (define_insn "indirect_jump_compact"
6419   [(set (pc)
6420         (match_operand:SI 0 "arith_reg_operand" "r"))]
6421   "TARGET_SH1"
6422   "jmp  @%0%#"
6423   [(set_attr "needs_delay_slot" "yes")
6424    (set_attr "type" "jump_ind")])
6426 (define_expand "indirect_jump"
6427   [(set (pc)
6428         (match_operand 0 "register_operand" ""))]
6429   ""
6430   "
6432   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6433     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6436 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6437 ;; which can be present in structured code from indirect jumps which can not
6438 ;; be present in structured code.  This allows -fprofile-arcs to work.
6440 ;; For SH1 processors.
6441 (define_insn "casesi_jump_1"
6442   [(set (pc)
6443         (match_operand:SI 0 "register_operand" "r"))
6444    (use (label_ref (match_operand 1 "" "")))]
6445   "TARGET_SH1"
6446   "jmp  @%0%#"
6447   [(set_attr "needs_delay_slot" "yes")
6448    (set_attr "type" "jump_ind")])
6450 ;; For all later processors.
6451 (define_insn "casesi_jump_2"
6452   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6453                       (label_ref (match_operand 1 "" ""))))
6454    (use (label_ref (match_operand 2 "" "")))]
6455   "TARGET_SH2
6456    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6457   "braf %0%#"
6458   [(set_attr "needs_delay_slot" "yes")
6459    (set_attr "type" "jump_ind")])
6461 (define_insn "casesi_jump_media"
6462   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6463    (use (label_ref (match_operand 1 "" "")))]
6464   "TARGET_SHMEDIA"
6465   "blink        %0, r63"
6466   [(set_attr "type" "jump_media")])
6468 ;; Call subroutine returning any type.
6469 ;; ??? This probably doesn't work.
6471 (define_expand "untyped_call"
6472   [(parallel [(call (match_operand 0 "" "")
6473                     (const_int 0))
6474               (match_operand 1 "" "")
6475               (match_operand 2 "" "")])]
6476   "TARGET_SH2E || TARGET_SHMEDIA"
6477   "
6479   int i;
6481   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6483   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6484     {
6485       rtx set = XVECEXP (operands[2], 0, i);
6486       emit_move_insn (SET_DEST (set), SET_SRC (set));
6487     }
6489   /* The optimizer does not know that the call sets the function value
6490      registers we stored in the result block.  We avoid problems by
6491      claiming that all hard registers are used and clobbered at this
6492      point.  */
6493   emit_insn (gen_blockage ());
6495   DONE;
6498 ;; ------------------------------------------------------------------------
6499 ;; Misc insns
6500 ;; ------------------------------------------------------------------------
6502 (define_insn "dect"
6503   [(set (reg:SI T_REG)
6504         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6505    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6506   "TARGET_SH2"
6507   "dt   %0"
6508   [(set_attr "type" "arith")])
6510 (define_insn "nop"
6511   [(const_int 0)]
6512   ""
6513   "nop")
6515 ;; Load address of a label. This is only generated by the casesi expand,
6516 ;; and by machine_dependent_reorg (fixing up fp moves).
6517 ;; This must use unspec, because this only works for labels that are
6518 ;; within range,
6520 (define_insn "mova"
6521   [(set (reg:SI R0_REG)
6522         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6523   "TARGET_SH1"
6524   "mova %O0,r0"
6525   [(set_attr "in_delay_slot" "no")
6526    (set_attr "type" "arith")])
6528 ;; machine_dependent_reorg will make this a `mova'.
6529 (define_insn "mova_const"
6530   [(set (reg:SI R0_REG)
6531         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6532   "TARGET_SH1"
6533   "#"
6534   [(set_attr "in_delay_slot" "no")
6535    (set_attr "type" "arith")])
6537 (define_expand "GOTaddr2picreg"
6538   [(set (reg:SI R0_REG)
6539         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6540                    UNSPEC_MOVA))
6541    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6542    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6543   "" "
6545   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6546   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6548   if (TARGET_SH5)
6549     operands[1] = gen_datalabel_ref (operands[1]);
6551   if (TARGET_SHMEDIA)
6552     {
6553       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6554       rtx dipic = operands[0];
6555       rtx lab = PATTERN (gen_call_site ());
6556       rtx insn, equiv;
6558       equiv = operands[1];
6559       operands[1] = gen_rtx_MINUS (DImode,
6560                                    operands[1],
6561                                    gen_rtx_CONST
6562                                    (DImode,
6563                                     gen_rtx_MINUS (DImode,
6564                                                    gen_rtx_CONST (DImode,
6565                                                                   lab),
6566                                                    pc_rtx)));
6567       operands[1] = gen_sym2PIC (operands[1]);
6568       PUT_MODE (operands[1], DImode);
6570       if (GET_MODE (dipic) != DImode)
6571         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6573       if (TARGET_SHMEDIA64)
6574         emit_insn (gen_movdi_const (dipic, operands[1]));
6575       else
6576         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6578       emit_insn (gen_ptrel (tr, dipic, lab));
6580       if (GET_MODE (operands[0]) != GET_MODE (tr))
6581         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6583       insn = emit_move_insn (operands[0], tr);
6585       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6586                                             REG_NOTES (insn));
6588       DONE;
6589     }
6593 (define_insn "*ptb"
6594   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6595         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6596                              UNSPEC_DATALABEL)))]
6597   "TARGET_SHMEDIA && flag_pic
6598    && EXTRA_CONSTRAINT_Csy (operands[1])"
6599   "ptb/u        datalabel %1, %0"
6600   [(set_attr "type" "pt_media")
6601    (set_attr "length" "*")])
6603 (define_insn "ptrel"
6604   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6605         (plus:DI (match_operand:DI 1 "register_operand" "r")
6606               (pc)))
6607    (match_operand:DI 2 "" "")]
6608   "TARGET_SHMEDIA"
6609   "%O2: ptrel/u %1, %0"
6610   [(set_attr "type" "ptabs_media")])
6612 (define_expand "builtin_setjmp_receiver"
6613   [(match_operand 0 "" "")]
6614   "flag_pic"
6615   "
6617   emit_insn (gen_GOTaddr2picreg ());
6618   DONE;
6621 (define_expand "call_site"
6622   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6623   "TARGET_SH1"
6624   "
6626   static HOST_WIDE_INT i = 0;
6627   operands[0] = GEN_INT (i);
6628   i++;
6631 (define_expand "sym_label2reg"
6632   [(set (match_operand:SI 0 "" "")
6633         (const:SI (minus:SI
6634                    (const:SI
6635                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6636                    (const:SI
6637                     (plus:SI
6638                      (match_operand:SI 2 "" "")
6639                      (const_int 2))))))]
6640   "TARGET_SH1" "")
6642 (define_expand "symGOT_load"
6643   [(set (match_dup 2) (match_operand 1 "" ""))
6644    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6645    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6646   ""
6647   "
6649   rtx insn;
6651   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6652   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6654   if (TARGET_SHMEDIA)
6655     {
6656       rtx reg = operands[2];
6658       if (GET_MODE (reg) != DImode)
6659         reg = gen_rtx_SUBREG (DImode, reg, 0);
6661       if (flag_pic > 1)
6662         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6663       else
6664         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6665     }
6666   else
6667     emit_move_insn (operands[2], operands[1]);
6669   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6670                                              operands[2],
6671                                              gen_rtx_REG (Pmode, PIC_REG)));
6673   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6675   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6676                                                                   0), 0, 0),
6677                                         REG_NOTES (insn));
6679   DONE;
6682 (define_expand "sym2GOT"
6683   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6684   ""
6685   "")
6687 (define_expand "symGOT2reg"
6688   [(match_operand 0 "" "") (match_operand 1 "" "")]
6689   ""
6690   "
6692   rtx gotsym, insn;
6694   gotsym = gen_sym2GOT (operands[1]);
6695   PUT_MODE (gotsym, Pmode);
6696   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6698   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6700   DONE;
6703 (define_expand "sym2GOTPLT"
6704   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6705   ""
6706   "")
6708 (define_expand "symGOTPLT2reg"
6709   [(match_operand 0 "" "") (match_operand 1 "" "")]
6710   ""
6711   "
6713   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6714   DONE;
6717 (define_expand "sym2GOTOFF"
6718   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6719   ""
6720   "")
6722 (define_expand "symGOTOFF2reg"
6723   [(match_operand 0 "" "") (match_operand 1 "" "")]
6724   ""
6725   "
6727   rtx gotoffsym, insn;
6728   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6730   gotoffsym = gen_sym2GOTOFF (operands[1]);
6731   PUT_MODE (gotoffsym, Pmode);
6732   emit_move_insn (t, gotoffsym);
6733   insn = emit_move_insn (operands[0],
6734                          gen_rtx_PLUS (Pmode, t,
6735                                        gen_rtx_REG (Pmode, PIC_REG)));
6737   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6738                                         REG_NOTES (insn));
6740   DONE;
6743 (define_expand "symPLT_label2reg"
6744   [(set (match_operand:SI 0 "" "")
6745         (const:SI (minus:SI
6746                    (const:SI
6747                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6748                    (const:SI
6749                     (minus:SI
6750                      (const:SI (plus:SI
6751                                 (match_operand:SI 2 "" "")
6752                                 (const_int 2)))
6753                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6754    ;; Even though the PIC register is not really used by the call
6755    ;; sequence in which this is expanded, the PLT code assumes the PIC
6756    ;; register is set, so we must not skip its initialization.  Since
6757    ;; we only use this expand as part of calling sequences, and never
6758    ;; to take the address of a function, this is the best point to
6759    ;; insert the (use).  Using the PLT to take the address of a
6760    ;; function would be wrong, not only because the PLT entry could
6761    ;; then be called from a function that doesn't initialize the PIC
6762    ;; register to the proper GOT, but also because pointers to the
6763    ;; same function might not compare equal, should they be set by
6764    ;; different shared libraries.
6765    (use (reg:SI PIC_REG))]
6766   "TARGET_SH1"
6767   "")
6769 (define_expand "sym2PIC"
6770   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6771   ""
6772   "")
6774 ;; TLS code generation.
6775 ;; ??? this should be a define_insn_and_split
6776 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6777 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6778 ;; for details.
6780 (define_insn "tls_global_dynamic"
6781   [(set (match_operand:SI 0 "register_operand" "=&z")
6782         (call (unspec:SI [(match_operand:SI 1 "" "")]
6783                           UNSPEC_TLSGD)
6784               (const_int 0)))
6785    (use (reg:PSI FPSCR_REG))
6786    (use (reg:SI PIC_REG))
6787    (clobber (reg:SI PR_REG))
6788    (clobber (scratch:SI))]
6789   "TARGET_SH1"
6790   "*
6792   return \"\\
6793 mov.l\\t1f,r4\\n\\
6794 \\tmova\\t2f,r0\\n\\
6795 \\tmov.l\\t2f,r1\\n\\
6796 \\tadd\\tr0,r1\\n\\
6797 \\tjsr\\t@r1\\n\\
6798 \\tadd\\tr12,r4\\n\\
6799 \\tbra\\t3f\\n\\
6800 \\tnop\\n\\
6801 \\t.align\\t2\\n\\
6802 1:\\t.long\\t%a1@TLSGD\\n\\
6803 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6804 3:\";
6806   [(set_attr "type" "tls_load")
6807    (set_attr "length" "26")])
6809 (define_insn "tls_local_dynamic"
6810   [(set (match_operand:SI 0 "register_operand" "=&z")
6811         (call (unspec:SI [(match_operand:SI 1 "" "")]
6812                           UNSPEC_TLSLDM)
6813               (const_int 0)))
6814    (use (reg:PSI FPSCR_REG))
6815    (use (reg:SI PIC_REG))
6816    (clobber (reg:SI PR_REG))
6817    (clobber (scratch:SI))]
6818   "TARGET_SH1"
6819   "*
6821   return \"\\
6822 mov.l\\t1f,r4\\n\\
6823 \\tmova\\t2f,r0\\n\\
6824 \\tmov.l\\t2f,r1\\n\\
6825 \\tadd\\tr0,r1\\n\\
6826 \\tjsr\\t@r1\\n\\
6827 \\tadd\\tr12,r4\\n\\
6828 \\tbra\\t3f\\n\\
6829 \\tnop\\n\\
6830 \\t.align\\t2\\n\\
6831 1:\\t.long\\t%a1@TLSLDM\\n\\
6832 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6833 3:\";
6835   [(set_attr "type" "tls_load")
6836    (set_attr "length" "26")])
6838 (define_expand "sym2DTPOFF"
6839   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6840   ""
6841   "")
6843 (define_expand "symDTPOFF2reg"
6844   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6845   ""
6846   "
6848   rtx dtpoffsym, insn;
6849   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6851   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6852   PUT_MODE (dtpoffsym, Pmode);
6853   emit_move_insn (t, dtpoffsym);
6854   insn = emit_move_insn (operands[0],
6855                          gen_rtx_PLUS (Pmode, t, operands[2]));
6856   DONE;
6859 (define_expand "sym2GOTTPOFF"
6860   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6861   ""
6862   "")
6864 (define_insn "tls_initial_exec"
6865   [(set (match_operand:SI 0 "register_operand" "=&r")
6866         (unspec:SI [(match_operand:SI 1 "" "")]
6867                     UNSPEC_TLSIE))
6868    (use (reg:SI GBR_REG))
6869    (use (reg:SI PIC_REG))
6870    (clobber (reg:SI R0_REG))]
6871   ""
6872   "*
6874   return \"\\
6875 mov.l\\t1f,r0\\n\\
6876 \\tstc\\tgbr,%0\\n\\
6877 \\tmov.l\\t@(r0,r12),r0\\n\\
6878 \\tbra\\t2f\\n\\
6879 \\tadd\\tr0,%0\\n\\
6880 \\t.align\\t2\\n\\
6881 1:\\t.long\\t%a1\\n\\
6882 2:\";
6884   [(set_attr "type" "tls_load")
6885    (set_attr "length" "16")])
6887 (define_expand "sym2TPOFF"
6888   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6889   ""
6890   "")
6892 (define_expand "symTPOFF2reg"
6893   [(match_operand 0 "" "") (match_operand 1 "" "")]
6894   ""
6895   "
6897   rtx tpoffsym, insn;
6899   tpoffsym = gen_sym2TPOFF (operands[1]);
6900   PUT_MODE (tpoffsym, Pmode);
6901   insn = emit_move_insn (operands[0], tpoffsym);
6902   DONE;
6905 (define_insn "load_gbr"
6906   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6907    (use (reg:SI GBR_REG))]
6908   ""
6909   "stc  gbr,%0"
6910   [(set_attr "type" "tls_load")])
6912 ;; case instruction for switch statements.
6914 ;; Operand 0 is index
6915 ;; operand 1 is the minimum bound
6916 ;; operand 2 is the maximum bound - minimum bound + 1
6917 ;; operand 3 is CODE_LABEL for the table;
6918 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6920 (define_expand "casesi"
6921   [(match_operand:SI 0 "arith_reg_operand" "")
6922    (match_operand:SI 1 "arith_reg_operand" "")
6923    (match_operand:SI 2 "arith_reg_operand" "")
6924    (match_operand 3 "" "") (match_operand 4 "" "")]
6925   ""
6926   "
6928   rtx reg = gen_reg_rtx (SImode);
6929   rtx reg2 = gen_reg_rtx (SImode);
6930   if (TARGET_SHMEDIA)
6931     {
6932       rtx reg = gen_reg_rtx (DImode);
6933       rtx reg2 = gen_reg_rtx (DImode);
6934       rtx reg3 = gen_reg_rtx (DImode);
6935       rtx reg4 = gen_reg_rtx (DImode);
6936       rtx reg5 = gen_reg_rtx (DImode);
6938       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6939       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6940       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6942       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6943       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6944       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6945       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6946       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6947                                                (DImode, operands[3])));
6948       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6949       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6950       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6951       emit_barrier ();
6952       DONE;
6953     }
6954   operands[1] = copy_to_mode_reg (SImode, operands[1]);
6955   operands[2] = copy_to_mode_reg (SImode, operands[2]);
6956   /* If optimizing, casesi_worker depends on the mode of the instruction
6957      before label it 'uses' - operands[3].  */
6958   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6959                            reg));
6960   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6961   if (TARGET_SH2)
6962     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6963   else
6964     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6965   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6966      operands[3], but to lab.  We will fix this up in
6967      machine_dependent_reorg.  */
6968   emit_barrier ();
6969   DONE;
6972 (define_expand "casesi_0"
6973   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6974    (set (match_dup 4) (minus:SI (match_dup 4)
6975                                 (match_operand:SI 1 "arith_operand" "")))
6976    (set (reg:SI T_REG)
6977         (gtu:SI (match_dup 4)
6978                 (match_operand:SI 2 "arith_reg_operand" "")))
6979    (set (pc)
6980         (if_then_else (ne (reg:SI T_REG)
6981                           (const_int 0))
6982                       (label_ref (match_operand 3 "" ""))
6983                       (pc)))]
6984   "TARGET_SH1"
6985   "")
6987 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6988 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6989 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6991 (define_insn "casesi_worker_0"
6992   [(set (match_operand:SI 0 "register_operand" "=r,r")
6993         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6994                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6995    (clobber (match_scratch:SI 3 "=X,1"))
6996    (clobber (match_scratch:SI 4 "=&z,z"))]
6997   "TARGET_SH1"
6998   "#")
7000 (define_split
7001   [(set (match_operand:SI 0 "register_operand" "")
7002         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7003                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7004    (clobber (match_scratch:SI 3 ""))
7005    (clobber (match_scratch:SI 4 ""))]
7006   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7007   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7008    (parallel [(set (match_dup 0)
7009               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7010                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7011               (clobber (match_dup 3))])
7012    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7013   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7015 (define_split
7016   [(set (match_operand:SI 0 "register_operand" "")
7017         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7018                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7019    (clobber (match_scratch:SI 3 ""))
7020    (clobber (match_scratch:SI 4 ""))]
7021   "TARGET_SH2 && reload_completed"
7022   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7023    (parallel [(set (match_dup 0)
7024               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7025                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7026               (clobber (match_dup 3))])]
7027   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7029 (define_insn "casesi_worker_1"
7030   [(set (match_operand:SI 0 "register_operand" "=r,r")
7031         (unspec:SI [(reg:SI R0_REG)
7032                     (match_operand:SI 1 "register_operand" "0,r")
7033                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7034    (clobber (match_scratch:SI 3 "=X,1"))]
7035   "TARGET_SH1"
7036   "*
7038   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7040   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7041     abort ();
7043   switch (GET_MODE (diff_vec))
7044     {
7045     case SImode:
7046       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7047     case HImode:
7048       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7049     case QImode:
7050       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7051         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7052       return \"mov.b    @(r0,%1),%0\";
7053     default:
7054       abort ();
7055     }
7057   [(set_attr "length" "4")])
7059 (define_insn "casesi_worker_2"
7060   [(set (match_operand:SI 0 "register_operand" "=r,r")
7061         (unspec:SI [(reg:SI R0_REG)
7062                     (match_operand:SI 1 "register_operand" "0,r")
7063                     (label_ref (match_operand 2 "" ""))
7064                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7065    (clobber (match_operand:SI 4 "" "=X,1"))]
7066   "TARGET_SH2 && reload_completed && flag_pic"
7067   "*
7069   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7070   const char *load;
7072   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7073     abort ();
7075   switch (GET_MODE (diff_vec))
7076     {
7077     case SImode:
7078       output_asm_insn (\"shll2    %1\", operands);
7079       load = \"mov.l    @(r0,%1),%0\"; break;
7080     case HImode:
7081       output_asm_insn (\"add    %1,%1\", operands);
7082       load = \"mov.w    @(r0,%1),%0\"; break;
7083     case QImode:
7084       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7085         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7086       else
7087         load = \"mov.b  @(r0,%1),%0\";
7088       break;
7089     default:
7090       abort ();
7091     }
7092   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7093   return load;
7095   [(set_attr "length" "8")])
7097 (define_insn "casesi_shift_media"
7098   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7099         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7100                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7101                     UNSPEC_CASESI)))]
7102   "TARGET_SHMEDIA"
7103   "*
7105   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7107   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7108     abort ();
7110   switch (GET_MODE (diff_vec))
7111     {
7112     case SImode:
7113       return \"shlli    %1, 2, %0\";
7114     case HImode:
7115       return \"shlli    %1, 1, %0\";
7116     case QImode:
7117       if (rtx_equal_p (operands[0], operands[1]))
7118         return \"\";
7119       return \"add      %1, r63, %0\";
7120     default:
7121       abort ();
7122     }
7124   [(set_attr "type" "arith_media")])
7126 (define_insn "casesi_load_media"
7127   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7128         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7129                          (match_operand 2 "arith_reg_operand" "r")
7130                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7131   "TARGET_SHMEDIA"
7132   "*
7134   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7136   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7137     abort ();
7139   switch (GET_MODE (diff_vec))
7140     {
7141     case SImode:
7142       return \"ldx.l    %1, %2, %0\";
7143     case HImode:
7144 #if 0
7145       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7146         return \"ldx.uw %1, %2, %0\";
7147 #endif
7148       return \"ldx.w    %1, %2, %0\";
7149     case QImode:
7150       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7151         return \"ldx.ub %1, %2, %0\";
7152       return \"ldx.b    %1, %2, %0\";
7153     default:
7154       abort ();
7155     }
7157   [(set_attr "type" "load_media")])
7159 (define_expand "return"
7160   [(return)]
7161   "reload_completed && ! sh_need_epilogue ()"
7162   "
7164   if (TARGET_SHMEDIA)
7165     {
7166       emit_jump_insn (gen_return_media ());
7167       DONE;
7168     }
7170   if (TARGET_SHCOMPACT
7171       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7172     {
7173       emit_jump_insn (gen_shcompact_return_tramp ());
7174       DONE;
7175     }
7178 (define_insn "*return_i"
7179   [(return)]
7180   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7181                     && (current_function_args_info.call_cookie
7182                         & CALL_COOKIE_RET_TRAMP (1)))
7183    && reload_completed"
7184   "%@   %#"
7185   [(set_attr "type" "return")
7186    (set_attr "needs_delay_slot" "yes")])
7188 (define_expand "shcompact_return_tramp"
7189   [(return)]
7190   "TARGET_SHCOMPACT
7191    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7192   "
7194   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7195   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7197   if (flag_pic)
7198     emit_insn (gen_symGOTPLT2reg (reg, sym));
7199   else
7200     emit_move_insn (reg, sym);
7202   emit_jump_insn (gen_shcompact_return_tramp_i ());
7203   DONE;
7206 (define_insn "shcompact_return_tramp_i"
7207   [(parallel [(return) (use (reg:SI R0_REG))])]
7208   "TARGET_SHCOMPACT
7209    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7210   "jmp  @r0%#"
7211   [(set_attr "type" "jump_ind")
7212    (set_attr "needs_delay_slot" "yes")])
7214 (define_insn "return_media_i"
7215   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7216   "TARGET_SHMEDIA && reload_completed"
7217   "blink        %0, r63"
7218   [(set_attr "type" "jump_media")])
7220 (define_insn "return_media_rte"
7221   [(return)]
7222   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7223   "rte"
7224   [(set_attr "type" "jump_media")])
7226 (define_expand "return_media"
7227   [(return)]
7228   "TARGET_SHMEDIA && reload_completed"
7229   "
7231   int tr_regno = sh_media_register_for_return ();
7232   rtx tr;
7234   if (current_function_interrupt)
7235     {
7236       emit_jump_insn (gen_return_media_rte ());
7237       DONE;
7238     }
7239   if (tr_regno < 0)
7240     {
7241       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7243       if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7244         abort ();
7245       tr_regno = TR0_REG;
7246       tr = gen_rtx_REG (DImode, tr_regno);
7247       emit_move_insn (tr, r18);
7248     }
7249   else
7250     tr = gen_rtx_REG (DImode, tr_regno);
7252   emit_jump_insn (gen_return_media_i (tr));
7253   DONE;
7256 (define_insn "shcompact_preserve_incoming_args"
7257   [(set (match_operand:SI 0 "register_operand" "+r")
7258         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7259   "TARGET_SHCOMPACT"
7260   ""
7261   [(set_attr "length" "0")])
7263 (define_insn "shcompact_incoming_args"
7264   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7265    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7266    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7267    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7268    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7269    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7270    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7271    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7272    (set (mem:BLK (reg:SI MACL_REG))
7273         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7274    (use (reg:SI R0_REG))
7275    (clobber (reg:SI R0_REG))
7276    (clobber (reg:SI MACL_REG))
7277    (clobber (reg:SI MACH_REG))
7278    (clobber (reg:SI PR_REG))]
7279   "TARGET_SHCOMPACT"
7280   "jsr  @r0%#"
7281   [(set_attr "needs_delay_slot" "yes")])
7283 (define_insn "shmedia_save_restore_regs_compact"
7284   [(set (reg:SI SP_REG)
7285         (plus:SI (reg:SI SP_REG)
7286                  (match_operand:SI 0 "immediate_operand" "i")))
7287    (use (reg:SI R0_REG))
7288    (clobber (reg:SI PR_REG))]
7289   "TARGET_SHCOMPACT
7290    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7291        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7292   "jsr @r0%#"
7293   [(set_attr "needs_delay_slot" "yes")])
7295 (define_expand "prologue"
7296   [(const_int 0)]
7297   ""
7298   "sh_expand_prologue (); DONE;")
7300 (define_expand "epilogue"
7301   [(return)]
7302   ""
7303   "
7305   sh_expand_epilogue (0);
7306   emit_jump_insn (gen_return ());
7307   DONE;
7310 (define_expand "eh_return"
7311   [(use (match_operand 0 "register_operand" ""))]
7312   ""
7314   rtx ra = operands[0];
7316   if (TARGET_SHMEDIA64)
7317     emit_insn (gen_eh_set_ra_di (ra));
7318   else
7319     emit_insn (gen_eh_set_ra_si (ra));
7321   DONE;
7324 ;; Clobber the return address on the stack.  We can't expand this
7325 ;; until we know where it will be put in the stack frame.
7327 (define_insn "eh_set_ra_si"
7328   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7329    (clobber (match_scratch:SI 1 "=&r"))]
7330   "! TARGET_SHMEDIA64"
7331   "#")
7333 (define_insn "eh_set_ra_di"
7334   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7335    (clobber (match_scratch:DI 1 "=&r"))]
7336   "TARGET_SHMEDIA64"
7337   "#")
7339 (define_split
7340   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7341    (clobber (match_scratch 1 ""))]
7342   "reload_completed"
7343   [(const_int 0)]
7344   "
7346   sh_set_return_address (operands[0], operands[1]);
7347   DONE;
7350 (define_insn "blockage"
7351   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7352   ""
7353   ""
7354   [(set_attr "length" "0")])
7356 ;; ------------------------------------------------------------------------
7357 ;; Scc instructions
7358 ;; ------------------------------------------------------------------------
7360 (define_insn "movt"
7361   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7362         (eq:SI (reg:SI T_REG) (const_int 1)))]
7363   "TARGET_SH1"
7364   "movt %0"
7365   [(set_attr "type" "arith")])
7367 (define_expand "seq"
7368   [(set (match_operand:SI 0 "arith_reg_operand" "")
7369         (match_dup 1))]
7370   ""
7371   "
7373   if (TARGET_SHMEDIA)
7374     {
7375       if (GET_MODE (operands[0]) != DImode)
7376         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7377       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7378       if (sh_compare_op1 != const0_rtx)
7379         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7380                                     ? GET_MODE (sh_compare_op0)
7381                                     : GET_MODE (sh_compare_op1),
7382                                     sh_compare_op1);
7384       switch (GET_MODE (sh_compare_op0))
7385         {
7386         case DImode:
7387           emit_insn (gen_cmpeqdi_media (operands[0],
7388                                         sh_compare_op0, sh_compare_op1));
7389           break;
7391         case SFmode:
7392           if (! TARGET_SHMEDIA_FPU)
7393             FAIL;
7394           emit_insn (gen_cmpeqsf_media (operands[0],
7395                                         sh_compare_op0, sh_compare_op1));
7396           break;
7398         case DFmode:
7399           if (! TARGET_SHMEDIA_FPU)
7400             FAIL;
7401           emit_insn (gen_cmpeqdf_media (operands[0],
7402                                         sh_compare_op0, sh_compare_op1));
7403           break;
7405         default:
7406           FAIL;
7407         }
7408       DONE;
7409     }
7410   if (sh_expand_t_scc (EQ, operands[0]))
7411     DONE;
7412   if (! rtx_equal_function_value_matters)
7413     FAIL;
7414   operands[1] = prepare_scc_operands (EQ);
7417 (define_expand "slt"
7418   [(set (match_operand:SI 0 "arith_reg_operand" "")
7419         (match_dup 1))]
7420   ""
7421   "
7423   if (TARGET_SHMEDIA)
7424     {
7425       if (GET_MODE (operands[0]) != DImode)
7426         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7427       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7428       if (sh_compare_op1 != const0_rtx)
7429         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7430                                     ? GET_MODE (sh_compare_op0)
7431                                     : GET_MODE (sh_compare_op1),
7432                                     sh_compare_op1);
7434       switch (GET_MODE (sh_compare_op0))
7435         {
7436         case DImode:
7437           emit_insn (gen_cmpgtdi_media (operands[0],
7438                                         sh_compare_op1, sh_compare_op0));
7439           break;
7441         case SFmode:
7442           if (! TARGET_SHMEDIA_FPU)
7443             FAIL;
7444           emit_insn (gen_cmpgtsf_media (operands[0],
7445                                         sh_compare_op1, sh_compare_op0));
7446           break;
7448         case DFmode:
7449           if (! TARGET_SHMEDIA_FPU)
7450             FAIL;
7451           emit_insn (gen_cmpgtdf_media (operands[0],
7452                                         sh_compare_op1, sh_compare_op0));
7453           break;
7455         default:
7456           FAIL;
7457         }
7458       DONE;
7459     }
7460   if (! rtx_equal_function_value_matters)
7461     FAIL;
7462   operands[1] = prepare_scc_operands (LT);
7465 (define_expand "sle"
7466   [(match_operand:SI 0 "arith_reg_operand" "")]
7467   ""
7468   "
7470   rtx tmp = sh_compare_op0;
7472   if (TARGET_SHMEDIA)
7473     {
7474       if (GET_MODE (operands[0]) != DImode)
7475         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7476       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7477       if (sh_compare_op1 != const0_rtx)
7478         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7479                                     ? GET_MODE (sh_compare_op0)
7480                                     : GET_MODE (sh_compare_op1),
7481                                     sh_compare_op1);
7483       switch (GET_MODE (sh_compare_op0))
7484         {
7485         case DImode:
7486           {
7487             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7489             emit_insn (gen_cmpgtdi_media (tmp,
7490                                           sh_compare_op0, sh_compare_op1));
7491             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7492             break;
7493           }
7495         case SFmode:
7496           if (! TARGET_SHMEDIA_FPU)
7497             FAIL;
7498           emit_insn (gen_cmpgesf_media (operands[0],
7499                                         sh_compare_op1, sh_compare_op0));
7500           break;
7502         case DFmode:
7503           if (! TARGET_SHMEDIA_FPU)
7504             FAIL;
7505           emit_insn (gen_cmpgedf_media (operands[0],
7506                                         sh_compare_op1, sh_compare_op0));
7507           break;
7509         default:
7510           FAIL;
7511         }
7512       DONE;
7513     }
7515   sh_compare_op0 = sh_compare_op1;
7516   sh_compare_op1 = tmp;
7517   emit_insn (gen_sge (operands[0]));
7518   DONE;
7521 (define_expand "sgt"
7522   [(set (match_operand:SI 0 "arith_reg_operand" "")
7523         (match_dup 1))]
7524   ""
7525   "
7527   if (TARGET_SHMEDIA)
7528     {
7529       if (GET_MODE (operands[0]) != DImode)
7530         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7531       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7532       if (sh_compare_op1 != const0_rtx)
7533         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7534                                     ? GET_MODE (sh_compare_op0)
7535                                     : GET_MODE (sh_compare_op1),
7536                                     sh_compare_op1);
7538       switch (GET_MODE (sh_compare_op0))
7539         {
7540         case DImode:
7541           emit_insn (gen_cmpgtdi_media (operands[0],
7542                                         sh_compare_op0, sh_compare_op1));
7543           break;
7545         case SFmode:
7546           if (! TARGET_SHMEDIA_FPU)
7547             FAIL;
7548           emit_insn (gen_cmpgtsf_media (operands[0],
7549                                         sh_compare_op0, sh_compare_op1));
7550           break;
7552         case DFmode:
7553           if (! TARGET_SHMEDIA_FPU)
7554             FAIL;
7555           emit_insn (gen_cmpgtdf_media (operands[0],
7556                                         sh_compare_op0, sh_compare_op1));
7557           break;
7559         default:
7560           FAIL;
7561         }
7562       DONE;
7563     }
7564   if (! rtx_equal_function_value_matters)
7565     FAIL;
7566   operands[1] = prepare_scc_operands (GT);
7569 (define_expand "sge"
7570   [(set (match_operand:SI 0 "arith_reg_operand" "")
7571         (match_dup 1))]
7572   ""
7573   "
7575   if (TARGET_SHMEDIA)
7576     {
7577       if (GET_MODE (operands[0]) != DImode)
7578         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7579       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7580       if (sh_compare_op1 != const0_rtx)
7581         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7582                                     ? GET_MODE (sh_compare_op0)
7583                                     : GET_MODE (sh_compare_op1),
7584                                     sh_compare_op1);
7586       switch (GET_MODE (sh_compare_op0))
7587         {
7588         case DImode:
7589           {
7590             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7592             emit_insn (gen_cmpgtdi_media (tmp,
7593                                           sh_compare_op1, sh_compare_op0));
7594             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7595             break;
7596           }
7598         case SFmode:
7599           if (! TARGET_SHMEDIA_FPU)
7600             FAIL;
7601           emit_insn (gen_cmpgesf_media (operands[0],
7602                                         sh_compare_op0, sh_compare_op1));
7603           break;
7605         case DFmode:
7606           if (! TARGET_SHMEDIA_FPU)
7607             FAIL;
7608           emit_insn (gen_cmpgedf_media (operands[0],
7609                                         sh_compare_op0, sh_compare_op1));
7610           break;
7612         default:
7613           FAIL;
7614         }
7615       DONE;
7616     }
7618   if (! rtx_equal_function_value_matters)
7619     FAIL;
7620   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7621     {
7622       if (TARGET_IEEE)
7623         {
7624           rtx lab = gen_label_rtx ();
7625           prepare_scc_operands (EQ);
7626           emit_jump_insn (gen_branch_true (lab));
7627           prepare_scc_operands (GT);
7628           emit_label (lab);
7629           emit_insn (gen_movt (operands[0]));
7630         }
7631       else
7632         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7633       DONE;
7634     }
7635   operands[1] = prepare_scc_operands (GE);
7638 (define_expand "sgtu"
7639   [(set (match_operand:SI 0 "arith_reg_operand" "")
7640         (match_dup 1))]
7641   ""
7642   "
7644   if (TARGET_SHMEDIA)
7645     {
7646       if (GET_MODE (operands[0]) != DImode)
7647         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7648       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7649       if (sh_compare_op1 != const0_rtx)
7650         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7651                                     ? GET_MODE (sh_compare_op0)
7652                                     : GET_MODE (sh_compare_op1),
7653                                     sh_compare_op1);
7655       emit_insn (gen_cmpgtudi_media (operands[0],
7656                                      sh_compare_op0, sh_compare_op1));
7657       DONE;
7658     }
7659   if (! rtx_equal_function_value_matters)
7660     FAIL;
7661   operands[1] = prepare_scc_operands (GTU);
7664 (define_expand "sltu"
7665   [(set (match_operand:SI 0 "arith_reg_operand" "")
7666         (match_dup 1))]
7667   ""
7668   "
7670   if (TARGET_SHMEDIA)
7671     {
7672       if (GET_MODE (operands[0]) != DImode)
7673         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7674       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7675       if (sh_compare_op1 != const0_rtx)
7676         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7677                                     ? GET_MODE (sh_compare_op0)
7678                                     : GET_MODE (sh_compare_op1),
7679                                     sh_compare_op1);
7681       emit_insn (gen_cmpgtudi_media (operands[0],
7682                                      sh_compare_op1, sh_compare_op0));
7683       DONE;
7684     }
7685   if (! rtx_equal_function_value_matters)
7686     FAIL;
7687   operands[1] = prepare_scc_operands (LTU);
7690 (define_expand "sleu"
7691   [(set (match_operand:SI 0 "arith_reg_operand" "")
7692         (match_dup 1))]
7693   ""
7694   "
7696   if (TARGET_SHMEDIA)
7697     {
7698       rtx tmp;
7700       if (GET_MODE (operands[0]) != DImode)
7701         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7702       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7703       if (sh_compare_op1 != const0_rtx)
7704         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7705                                     ? GET_MODE (sh_compare_op0)
7706                                     : GET_MODE (sh_compare_op1),
7707                                     sh_compare_op1);
7709       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7711       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7712       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7714       DONE;
7715     }
7716   if (! rtx_equal_function_value_matters)
7717     FAIL;
7718   operands[1] = prepare_scc_operands (LEU);
7721 (define_expand "sgeu"
7722   [(set (match_operand:SI 0 "arith_reg_operand" "")
7723         (match_dup 1))]
7724   ""
7725   "
7727   if (TARGET_SHMEDIA)
7728     {
7729       rtx tmp;
7731       if (GET_MODE (operands[0]) != DImode)
7732         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7733       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7734       if (sh_compare_op1 != const0_rtx)
7735         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7736                                     ? GET_MODE (sh_compare_op0)
7737                                     : GET_MODE (sh_compare_op1),
7738                                     sh_compare_op1);
7740       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7742       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7743       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7745       DONE;
7746     }
7748   if (! rtx_equal_function_value_matters)
7749     FAIL;
7750   operands[1] = prepare_scc_operands (GEU);
7753 ;; sne moves the complement of the T reg to DEST like this:
7754 ;;      cmp/eq ...
7755 ;;      mov    #-1,temp
7756 ;;      negc   temp,dest
7757 ;;   This is better than xoring compare result with 1 because it does
7758 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7759 ;;   loop.
7761 (define_expand "sne"
7762   [(set (match_dup 2) (const_int -1))
7763    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7764                    (neg:SI (plus:SI (match_dup 1)
7765                                     (match_dup 2))))
7766               (set (reg:SI T_REG)
7767                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7768                           (const_int 0)))])]
7769   ""
7770   "
7772   if (TARGET_SHMEDIA)
7773     {
7774       rtx tmp;
7776       if (GET_MODE (operands[0]) != DImode)
7777         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7779       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7780         FAIL;
7782       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7783       if (sh_compare_op1 != const0_rtx)
7784         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7785                                     ? GET_MODE (sh_compare_op0)
7786                                     : GET_MODE (sh_compare_op1),
7787                                     sh_compare_op1);
7789       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7791       emit_insn (gen_seq (tmp));
7792       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7794       DONE;
7795     }
7797   if (sh_expand_t_scc (NE, operands[0]))
7798     DONE;
7799   if (! rtx_equal_function_value_matters)
7800     FAIL;
7801   operands[1] = prepare_scc_operands (EQ);
7802   operands[2] = gen_reg_rtx (SImode);
7805 (define_expand "sunordered"
7806   [(set (match_operand:DI 0 "arith_reg_operand" "")
7807         (unordered:DI (match_dup 1) (match_dup 2)))]
7808   "TARGET_SHMEDIA_FPU"
7809   "
7811   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7812   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7815 ;; Use the same trick for FP sle / sge
7816 (define_expand "movnegt"
7817   [(set (match_dup 2) (const_int -1))
7818    (parallel [(set (match_operand 0 "" "")
7819                    (neg:SI (plus:SI (match_dup 1)
7820                                     (match_dup 2))))
7821               (set (reg:SI T_REG)
7822                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7823                           (const_int 0)))])]
7824   "TARGET_SH1"
7825   "operands[2] = gen_reg_rtx (SImode);")
7827 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7828 ;; This prevents a regression that occurred when we switched from xor to
7829 ;; mov/neg for sne.
7831 (define_split
7832   [(set (match_operand:SI 0 "arith_reg_operand" "")
7833         (plus:SI (reg:SI T_REG)
7834                  (const_int -1)))]
7835   "TARGET_SH1"
7836   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7837    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7838   "")
7840 ;; -------------------------------------------------------------------------
7841 ;; Instructions to cope with inline literal tables
7842 ;; -------------------------------------------------------------------------
7844 ; 2 byte integer in line
7846 (define_insn "consttable_2"
7847  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7848                     (match_operand 1 "" "")]
7849                    UNSPECV_CONST2)]
7850  ""
7851  "*
7853   if (operands[1] != const0_rtx)
7854     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7855   return \"\";
7857  [(set_attr "length" "2")
7858  (set_attr "in_delay_slot" "no")])
7860 ; 4 byte integer in line
7862 (define_insn "consttable_4"
7863  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7864                     (match_operand 1 "" "")]
7865                    UNSPECV_CONST4)]
7866  ""
7867  "*
7869   if (operands[1] != const0_rtx)
7870     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7871   return \"\";
7873  [(set_attr "length" "4")
7874   (set_attr "in_delay_slot" "no")])
7876 ; 8 byte integer in line
7878 (define_insn "consttable_8"
7879  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7880                     (match_operand 1 "" "")]
7881                    UNSPECV_CONST8)]
7882  ""
7883  "*
7885   if (operands[1] != const0_rtx)
7886     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7887   return \"\";
7889  [(set_attr "length" "8")
7890   (set_attr "in_delay_slot" "no")])
7892 ; 4 byte floating point
7894 (define_insn "consttable_sf"
7895  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7896                     (match_operand 1 "" "")]
7897                    UNSPECV_CONST4)]
7898  ""
7899  "*
7901   if (operands[1] != const0_rtx)
7902     {
7903       REAL_VALUE_TYPE d;
7904       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7905       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7906     }
7907   return \"\";
7909  [(set_attr "length" "4")
7910   (set_attr "in_delay_slot" "no")])
7912 ; 8 byte floating point
7914 (define_insn "consttable_df"
7915  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7916                     (match_operand 1 "" "")]
7917                    UNSPECV_CONST8)]
7918  ""
7919  "*
7921   if (operands[1] != const0_rtx)
7922     {
7923       REAL_VALUE_TYPE d;
7924       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7925       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7926     }
7927   return \"\";
7929  [(set_attr "length" "8")
7930   (set_attr "in_delay_slot" "no")])
7932 ;; Alignment is needed for some constant tables; it may also be added for
7933 ;; Instructions at the start of loops, or after unconditional branches.
7934 ;; ??? We would get more accurate lengths if we did instruction
7935 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7936 ;; here is too conservative.
7938 ; align to a two byte boundary
7940 (define_expand "align_2"
7941  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7942  ""
7943  "")
7945 ; align to a four byte boundary
7946 ;; align_4 and align_log are instructions for the starts of loops, or
7947 ;; after unconditional branches, which may take up extra room.
7949 (define_expand "align_4"
7950  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7951  ""
7952  "")
7954 ; align to a cache line boundary
7956 (define_insn "align_log"
7957  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7958  ""
7959  ""
7960  [(set_attr "length" "0")
7961   (set_attr "in_delay_slot" "no")])
7963 ; emitted at the end of the literal table, used to emit the
7964 ; 32bit branch labels if needed.
7966 (define_insn "consttable_end"
7967   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7968   ""
7969   "* return output_jump_label_table ();"
7970   [(set_attr "in_delay_slot" "no")])
7972 ; emitted at the end of the window in the literal table.
7974 (define_insn "consttable_window_end"
7975   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7976   ""
7977   ""
7978   [(set_attr "length" "0")
7979    (set_attr "in_delay_slot" "no")])
7981 ;; -------------------------------------------------------------------------
7982 ;; Misc
7983 ;; -------------------------------------------------------------------------
7985 ;; String/block move insn.
7987 (define_expand "movmemsi"
7988   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7989                    (mem:BLK (match_operand:BLK 1 "" "")))
7990               (use (match_operand:SI 2 "nonmemory_operand" ""))
7991               (use (match_operand:SI 3 "immediate_operand" ""))
7992               (clobber (reg:SI PR_REG))
7993               (clobber (reg:SI R4_REG))
7994               (clobber (reg:SI R5_REG))
7995               (clobber (reg:SI R0_REG))])]
7996   "TARGET_SH1 && ! TARGET_SH5"
7997   "
7999   if(expand_block_move (operands))
8000      DONE;
8001   else FAIL;
8004 (define_insn "block_move_real"
8005   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8006                    (mem:BLK (reg:SI R5_REG)))
8007               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8008               (clobber (reg:SI PR_REG))
8009               (clobber (reg:SI R0_REG))])]
8010   "TARGET_SH1 && ! TARGET_HARD_SH4"
8011   "jsr  @%0%#"
8012   [(set_attr "type" "sfunc")
8013    (set_attr "needs_delay_slot" "yes")])
8015 (define_insn "block_lump_real"
8016   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8017                    (mem:BLK (reg:SI R5_REG)))
8018               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8019               (use (reg:SI R6_REG))
8020               (clobber (reg:SI PR_REG))
8021               (clobber (reg:SI T_REG))
8022               (clobber (reg:SI R4_REG))
8023               (clobber (reg:SI R5_REG))
8024               (clobber (reg:SI R6_REG))
8025               (clobber (reg:SI R0_REG))])]
8026   "TARGET_SH1 && ! TARGET_HARD_SH4"
8027   "jsr  @%0%#"
8028   [(set_attr "type" "sfunc")
8029    (set_attr "needs_delay_slot" "yes")])
8031 (define_insn "block_move_real_i4"
8032   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8033                    (mem:BLK (reg:SI R5_REG)))
8034               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8035               (clobber (reg:SI PR_REG))
8036               (clobber (reg:SI R0_REG))
8037               (clobber (reg:SI R1_REG))
8038               (clobber (reg:SI R2_REG))])]
8039   "TARGET_HARD_SH4"
8040   "jsr  @%0%#"
8041   [(set_attr "type" "sfunc")
8042    (set_attr "needs_delay_slot" "yes")])
8044 (define_insn "block_lump_real_i4"
8045   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8046                    (mem:BLK (reg:SI R5_REG)))
8047               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8048               (use (reg:SI R6_REG))
8049               (clobber (reg:SI PR_REG))
8050               (clobber (reg:SI T_REG))
8051               (clobber (reg:SI R4_REG))
8052               (clobber (reg:SI R5_REG))
8053               (clobber (reg:SI R6_REG))
8054               (clobber (reg:SI R0_REG))
8055               (clobber (reg:SI R1_REG))
8056               (clobber (reg:SI R2_REG))
8057               (clobber (reg:SI R3_REG))])]
8058   "TARGET_HARD_SH4"
8059   "jsr  @%0%#"
8060   [(set_attr "type" "sfunc")
8061    (set_attr "needs_delay_slot" "yes")])
8063 ;; -------------------------------------------------------------------------
8064 ;; Floating point instructions.
8065 ;; -------------------------------------------------------------------------
8067 ;; ??? All patterns should have a type attribute.
8069 (define_expand "fpu_switch0"
8070   [(set (match_operand:SI 0 "" "") (match_dup 2))
8071    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8072   "TARGET_SH4"
8073   "
8075   operands[1] = get_fpscr_rtx ();
8076   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8077   if (flag_pic)
8078     operands[2] = legitimize_pic_address (operands[2], SImode,
8079                                           no_new_pseudos ? operands[0] : 0);
8082 (define_expand "fpu_switch1"
8083   [(set (match_operand:SI 0 "" "") (match_dup 2))
8084    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8085    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8086   "TARGET_SH4"
8087   "
8089   operands[1] = get_fpscr_rtx ();
8090   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8091   if (flag_pic)
8092     operands[2] = legitimize_pic_address (operands[2], SImode,
8093                                           no_new_pseudos ? operands[0] : 0);
8094   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8097 (define_expand "movpsi"
8098   [(set (match_operand:PSI 0 "register_operand" "")
8099         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8100   "TARGET_SH4"
8101   "")
8103 ;; The c / m alternative is a fake to guide reload to load directly into
8104 ;; fpscr, since reload doesn't know how to use post-increment.
8105 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8106 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8107 ;; predicate after reload.
8108 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8109 ;; like a mac -> gpr move.
8110 (define_insn "fpu_switch"
8111   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8112         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8113   "TARGET_SH2E
8114    && (! reload_completed
8115        || true_regnum (operands[0]) != FPSCR_REG
8116        || GET_CODE (operands[1]) != MEM
8117        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8118   "@
8119         ! precision stays the same
8120         lds.l   %1,fpscr
8121         mov.l   %1,%0
8122         #
8123         lds     %1,fpscr
8124         mov     %1,%0
8125         mov.l   %1,%0
8126         sts     fpscr,%0
8127         sts.l   fpscr,%0"
8128   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8129    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8131 (define_split
8132   [(set (reg:PSI FPSCR_REG)
8133         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8134   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8135   [(set (match_dup 0) (match_dup 0))]
8136   "
8138   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8139                                         gen_rtx_MEM (PSImode,
8140                                                  gen_rtx_POST_INC (Pmode,
8141                                                           operands[0]))));
8142   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8145 (define_split
8146   [(set (reg:PSI FPSCR_REG)
8147         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8148   "TARGET_SH4"
8149   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8150   "
8152   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8153                                         gen_rtx_MEM (PSImode,
8154                                                  gen_rtx_POST_INC (Pmode,
8155                                                           operands[0]))));
8156   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8159 ;; ??? This uses the fp unit, but has no type indicating that.
8160 ;; If we did that, this would either give a bogus latency or introduce
8161 ;; a bogus FIFO constraint.
8162 ;; Since this insn is currently only used for prologues/epilogues,
8163 ;; it is probably best to claim no function unit, which matches the
8164 ;; current setting.
8165 (define_insn "toggle_sz"
8166   [(set (reg:PSI FPSCR_REG)
8167         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8168   "TARGET_SH4"
8169   "fschg"
8170   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
8172 ;; There's no way we can use it today, since optimize mode switching
8173 ;; doesn't enable us to know from which mode we're switching to the
8174 ;; mode it requests, to tell whether we can use a relative mode switch
8175 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
8176 ;; memory).
8177 (define_insn "toggle_pr"
8178   [(set (reg:PSI FPSCR_REG)
8179         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
8180   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
8181   "fpchg"
8182   [(set_attr "type" "fp")])
8184 (define_expand "addsf3"
8185   [(set (match_operand:SF 0 "arith_reg_operand" "")
8186         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8187                  (match_operand:SF 2 "arith_reg_operand" "")))]
8188   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8189   "
8191   if (TARGET_SH2E)
8192     {
8193       expand_sf_binop (&gen_addsf3_i, operands);
8194       DONE;
8195     }
8198 (define_insn "*addsf3_media"
8199   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8200         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8201                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8202   "TARGET_SHMEDIA_FPU"
8203   "fadd.s       %1, %2, %0"
8204   [(set_attr "type" "fparith_media")])
8206 (define_insn_and_split "unary_sf_op"
8207   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8208         (vec_select:V2SF
8209          (vec_concat:V2SF
8210           (vec_select:SF
8211            (match_dup 0)
8212            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8213           (match_operator:SF 2 "unary_float_operator"
8214             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8215                             (parallel [(match_operand 4
8216                                         "const_int_operand" "n")]))]))
8217          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8218   "TARGET_SHMEDIA_FPU"
8219   "#"
8220   "TARGET_SHMEDIA_FPU && reload_completed"
8221   [(set (match_dup 5) (match_dup 6))]
8222   "
8224   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8225   rtx op1 = gen_rtx_REG (SFmode,
8226                          (true_regnum (operands[1])
8227                           + (INTVAL (operands[4]) ^ endian)));
8229   operands[7] = gen_rtx_REG (SFmode,
8230                              (true_regnum (operands[0])
8231                               + (INTVAL (operands[3]) ^ endian)));
8232   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8234   [(set_attr "type" "fparith_media")])
8236 (define_insn_and_split "binary_sf_op"
8237   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8238         (vec_select:V2SF
8239          (vec_concat:V2SF
8240           (vec_select:SF
8241            (match_dup 0)
8242            (parallel [(match_operand 7 "const_int_operand" "n")]))
8243           (match_operator:SF 3 "binary_float_operator"
8244             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8245                             (parallel [(match_operand 5
8246                                         "const_int_operand" "n")]))
8247              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8248                             (parallel [(match_operand 6
8249                                         "const_int_operand" "n")]))]))
8250          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8251   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8252   "#"
8253   "&& reload_completed"
8254   [(set (match_dup 8) (match_dup 9))]
8255   "
8257   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8258   rtx op1 = gen_rtx_REG (SFmode,
8259                          (true_regnum (operands[1])
8260                           + (INTVAL (operands[5]) ^ endian)));
8261   rtx op2 = gen_rtx_REG (SFmode,
8262                          (true_regnum (operands[2])
8263                           + (INTVAL (operands[6]) ^ endian)));
8265   operands[8] = gen_rtx_REG (SFmode,
8266                              (true_regnum (operands[0])
8267                               + (INTVAL (operands[4]) ^ endian)));
8268   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8270   [(set_attr "type" "fparith_media")])
8272 (define_insn "addsf3_i"
8273   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8274         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8275                  (match_operand:SF 2 "arith_reg_operand" "f")))
8276    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8277   "TARGET_SH2E"
8278   "fadd %2,%0"
8279   [(set_attr "type" "fp")
8280    (set_attr "fp_mode" "single")])
8282 (define_expand "subsf3"
8283   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8284         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8285                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8286   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8287   "
8289   if (TARGET_SH2E)
8290     {
8291       expand_sf_binop (&gen_subsf3_i, operands);
8292       DONE;
8293     }
8296 (define_insn "*subsf3_media"
8297   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8298         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8299                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8300   "TARGET_SHMEDIA_FPU"
8301   "fsub.s       %1, %2, %0"
8302   [(set_attr "type" "fparith_media")])
8304 (define_insn "subsf3_i"
8305   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8306         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8307                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8308    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8309   "TARGET_SH2E"
8310   "fsub %2,%0"
8311   [(set_attr "type" "fp")
8312    (set_attr "fp_mode" "single")])
8314 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8315 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8316 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8317 ;; SH3E, we use a separate insn for SH3E mulsf3.
8319 (define_expand "mulsf3"
8320   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8321         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8322                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8323   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8324   "
8326   if (TARGET_SH4)
8327     expand_sf_binop (&gen_mulsf3_i4, operands);
8328   else if (TARGET_SH2E)
8329     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8330   if (! TARGET_SHMEDIA)
8331     DONE;
8334 (define_insn "*mulsf3_media"
8335   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8336         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8337                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8338   "TARGET_SHMEDIA_FPU"
8339   "fmul.s       %1, %2, %0"
8340   [(set_attr "type" "fparith_media")])
8342 (define_insn "mulsf3_i4"
8343   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8344         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8345                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8346    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8347   "TARGET_SH2E"
8348   "fmul %2,%0"
8349   [(set_attr "type" "fp")
8350    (set_attr "fp_mode" "single")])
8352 (define_insn "mulsf3_ie"
8353   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8354         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8355                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8356   "TARGET_SH2E && ! TARGET_SH4"
8357   "fmul %2,%0"
8358   [(set_attr "type" "fp")])
8360 (define_insn "*mac_media"
8361   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8362         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8363                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8364                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8365   "TARGET_SHMEDIA_FPU"
8366   "fmac.s %1, %2, %0"
8367   [(set_attr "type" "fparith_media")])
8369 (define_insn "*macsf3"
8370   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8371         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8372                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8373                  (match_operand:SF 3 "arith_reg_operand" "0")))
8374    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8375   "TARGET_SH2E && ! TARGET_SH4"
8376   "fmac fr0,%2,%0"
8377   [(set_attr "type" "fp")
8378    (set_attr "fp_mode" "single")])
8380 (define_expand "divsf3"
8381   [(set (match_operand:SF 0 "arith_reg_operand" "")
8382         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8383                 (match_operand:SF 2 "arith_reg_operand" "")))]
8384   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8385   "
8387   if (TARGET_SH2E)
8388     {
8389       expand_sf_binop (&gen_divsf3_i, operands);
8390       DONE;
8391     }
8394 (define_insn "*divsf3_media"
8395   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8396         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8397                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8398   "TARGET_SHMEDIA_FPU"
8399   "fdiv.s       %1, %2, %0"
8400   [(set_attr "type" "fdiv_media")])
8402 (define_insn "divsf3_i"
8403   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8404         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8405                  (match_operand:SF 2 "arith_reg_operand" "f")))
8406    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8407   "TARGET_SH2E"
8408   "fdiv %2,%0"
8409   [(set_attr "type" "fdiv")
8410    (set_attr "fp_mode" "single")])
8412 (define_insn "floatdisf2"
8413   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8414         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8415   "TARGET_SHMEDIA_FPU"
8416   "float.qs %1, %0"
8417   [(set_attr "type" "fpconv_media")])
8419 (define_expand "floatsisf2"
8420   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8421         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8422   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8423   "
8425   if (TARGET_SH4)
8426     {
8427       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8428       DONE;
8429     }
8432 (define_insn "*floatsisf2_media"
8433   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8434         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8435   "TARGET_SHMEDIA_FPU"
8436   "float.ls     %1, %0"
8437   [(set_attr "type" "fpconv_media")])
8439 (define_insn "floatsisf2_i4"
8440   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8441         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8442    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8443   "TARGET_SH4"
8444   "float        %1,%0"
8445   [(set_attr "type" "fp")
8446    (set_attr "fp_mode" "single")])
8448 (define_insn "*floatsisf2_ie"
8449   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8450         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8451   "TARGET_SH2E && ! TARGET_SH4"
8452   "float        %1,%0"
8453   [(set_attr "type" "fp")])
8455 (define_insn "fix_truncsfdi2"
8456   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8457         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8458   "TARGET_SHMEDIA_FPU"
8459   "ftrc.sq %1, %0"
8460   [(set_attr "type" "fpconv_media")])
8462 (define_expand "fix_truncsfsi2"
8463   [(set (match_operand:SI 0 "fpul_operand" "=y")
8464         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8465   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8466   "
8468   if (TARGET_SH4)
8469     {
8470       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8471       DONE;
8472     }
8475 (define_insn "*fix_truncsfsi2_media"
8476   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8477         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8478   "TARGET_SHMEDIA_FPU"
8479   "ftrc.sl      %1, %0"
8480   [(set_attr "type" "fpconv_media")])
8482 (define_insn "fix_truncsfsi2_i4"
8483   [(set (match_operand:SI 0 "fpul_operand" "=y")
8484         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8485    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8486   "TARGET_SH4"
8487   "ftrc %1,%0"
8488   [(set_attr "type" "ftrc_s")
8489    (set_attr "fp_mode" "single")])
8491 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8492 ;; fix_truncsfsi2_i4.
8493 ;; (define_insn "fix_truncsfsi2_i4_2"
8494 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8495 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8496 ;;   (use (reg:PSI FPSCR_REG))
8497 ;;   (clobber (reg:SI FPUL_REG))]
8498 ;;  "TARGET_SH4"
8499 ;;  "#"
8500 ;;  [(set_attr "length" "4")
8501 ;;   (set_attr "fp_mode" "single")])
8503 ;;(define_split
8504 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8505 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8506 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8507 ;;   (clobber (reg:SI FPUL_REG))]
8508 ;;  "TARGET_SH4"
8509 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8510 ;;            (use (match_dup 2))])
8511 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8513 (define_insn "*fixsfsi"
8514   [(set (match_operand:SI 0 "fpul_operand" "=y")
8515         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8516   "TARGET_SH2E && ! TARGET_SH4"
8517   "ftrc %1,%0"
8518   [(set_attr "type" "fp")])
8520 (define_insn "cmpgtsf_t"
8521   [(set (reg:SI T_REG)
8522         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8523                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8524   "TARGET_SH2E && ! TARGET_SH4"
8525   "fcmp/gt      %1,%0"
8526   [(set_attr "type" "fp")
8527    (set_attr "fp_mode" "single")])
8529 (define_insn "cmpeqsf_t"
8530   [(set (reg:SI T_REG)
8531         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8532                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8533   "TARGET_SH2E && ! TARGET_SH4"
8534   "fcmp/eq      %1,%0"
8535   [(set_attr "type" "fp")
8536    (set_attr "fp_mode" "single")])
8538 (define_insn "ieee_ccmpeqsf_t"
8539   [(set (reg:SI T_REG)
8540         (ior:SI (reg:SI T_REG)
8541                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8542                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8543   "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8544   "* return output_ieee_ccmpeq (insn, operands);"
8545   [(set_attr "length" "4")])
8548 (define_insn "cmpgtsf_t_i4"
8549   [(set (reg:SI T_REG)
8550         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8551                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8552    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8553   "TARGET_SH4"
8554   "fcmp/gt      %1,%0"
8555   [(set_attr "type" "fp")
8556    (set_attr "fp_mode" "single")])
8558 (define_insn "cmpeqsf_t_i4"
8559   [(set (reg:SI T_REG)
8560         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8561                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8562    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8563   "TARGET_SH4"
8564   "fcmp/eq      %1,%0"
8565   [(set_attr "type" "fp")
8566    (set_attr "fp_mode" "single")])
8568 (define_insn "*ieee_ccmpeqsf_t_4"
8569   [(set (reg:SI T_REG)
8570         (ior:SI (reg:SI T_REG)
8571                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8572                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8573    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8574   "TARGET_IEEE && TARGET_SH4"
8575   "* return output_ieee_ccmpeq (insn, operands);"
8576   [(set_attr "length" "4")
8577    (set_attr "fp_mode" "single")])
8579 (define_insn "cmpeqsf_media"
8580   [(set (match_operand:DI 0 "register_operand" "=r")
8581         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8582                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8583   "TARGET_SHMEDIA_FPU"
8584   "fcmpeq.s     %1, %2, %0"
8585   [(set_attr "type" "fcmp_media")])
8587 (define_insn "cmpgtsf_media"
8588   [(set (match_operand:DI 0 "register_operand" "=r")
8589         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8590                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8591   "TARGET_SHMEDIA_FPU"
8592   "fcmpgt.s     %1, %2, %0"
8593   [(set_attr "type" "fcmp_media")])
8595 (define_insn "cmpgesf_media"
8596   [(set (match_operand:DI 0 "register_operand" "=r")
8597         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8598                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8599   "TARGET_SHMEDIA_FPU"
8600   "fcmpge.s     %1, %2, %0"
8601   [(set_attr "type" "fcmp_media")])
8603 (define_insn "cmpunsf_media"
8604   [(set (match_operand:DI 0 "register_operand" "=r")
8605         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8606                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8607   "TARGET_SHMEDIA_FPU"
8608   "fcmpun.s     %1, %2, %0"
8609   [(set_attr "type" "fcmp_media")])
8611 (define_expand "cmpsf"
8612   [(set (reg:SI T_REG)
8613         (compare (match_operand:SF 0 "arith_operand" "")
8614                  (match_operand:SF 1 "arith_operand" "")))]
8615   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8616   "
8618   sh_compare_op0 = operands[0];
8619   sh_compare_op1 = operands[1];
8620   DONE;
8623 (define_expand "negsf2"
8624   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8625         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8626   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8627   "
8629   if (TARGET_SH2E)
8630     {
8631       expand_sf_unop (&gen_negsf2_i, operands);
8632       DONE;
8633     }
8636 (define_insn "*negsf2_media"
8637   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8638         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8639   "TARGET_SHMEDIA_FPU"
8640   "fneg.s       %1, %0"
8641   [(set_attr "type" "fmove_media")])
8643 (define_insn "negsf2_i"
8644   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8645         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8646    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8647   "TARGET_SH2E"
8648   "fneg %0"
8649   [(set_attr "type" "fmove")
8650    (set_attr "fp_mode" "single")])
8652 (define_expand "sqrtsf2"
8653   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8654         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8655   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8656   "
8658   if (TARGET_SH3E)
8659     {
8660       expand_sf_unop (&gen_sqrtsf2_i, operands);
8661       DONE;
8662     }
8665 (define_insn "*sqrtsf2_media"
8666   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8667         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8668   "TARGET_SHMEDIA_FPU"
8669   "fsqrt.s      %1, %0"
8670   [(set_attr "type" "fdiv_media")])
8672 (define_insn "sqrtsf2_i"
8673   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8674         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8675    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8676   "TARGET_SH3E"
8677   "fsqrt        %0"
8678   [(set_attr "type" "fdiv")
8679    (set_attr "fp_mode" "single")])
8681 (define_insn "rsqrtsf2"
8682   [(set (match_operand:SF 0 "register_operand" "=f")
8683         (div:SF (match_operand:SF 1 "immediate_operand" "i")
8684                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
8685    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8686   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8687    && operands[1] == CONST1_RTX (SFmode)"
8688   "fsrra        %0"
8689   [(set_attr "type" "fsrra")
8690    (set_attr "fp_mode" "single")])
8692 (define_insn "fsca"
8693   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8694         (vec_concat:V2SF
8695          (unspec:SF [(mult:SF
8696                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
8697                       (match_operand:SF 2 "immediate_operand" "i"))
8698                     ] UNSPEC_FSINA)
8699          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
8700                     ] UNSPEC_FCOSA)))
8701    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8702   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
8703    && operands[2] == sh_fsca_int2sf ()"
8704   "fsca fpul,%d0"
8705   [(set_attr "type" "fsca")
8706    (set_attr "fp_mode" "single")])
8708 (define_expand "sinsf2"
8709   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8710         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8711                    UNSPEC_FSINA))]
8712   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8713   "
8715   rtx scaled = gen_reg_rtx (SFmode);
8716   rtx truncated = gen_reg_rtx (SImode);
8717   rtx fsca = gen_reg_rtx (V2SFmode);
8718   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8720   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8721   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8722   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8723                           get_fpscr_rtx ()));
8724   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
8725   DONE;
8728 (define_expand "cossf2"
8729   [(set (match_operand:SF 0 "nonimmediate_operand" "")
8730         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
8731                    UNSPEC_FCOSA))]
8732   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
8733   "
8735   rtx scaled = gen_reg_rtx (SFmode);
8736   rtx truncated = gen_reg_rtx (SImode);
8737   rtx fsca = gen_reg_rtx (V2SFmode);
8738   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
8740   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
8741   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
8742   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8743                           get_fpscr_rtx ()));
8744   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
8745   DONE;
8748 (define_expand "sindf2"
8749   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8750         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8751                    UNSPEC_FSINA))]
8752   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8753   "
8755   rtx scaled = gen_reg_rtx (DFmode);
8756   rtx truncated = gen_reg_rtx (SImode);
8757   rtx fsca = gen_reg_rtx (V2SFmode);
8758   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8759   rtx sfresult = gen_reg_rtx (SFmode);
8761   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8762   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8763   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8764                           get_fpscr_rtx ()));
8765   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
8766   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8767   DONE;
8770 (define_expand "cosdf2"
8771   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8772         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
8773                    UNSPEC_FCOSA))]
8774   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
8775   "
8777   rtx scaled = gen_reg_rtx (DFmode);
8778   rtx truncated = gen_reg_rtx (SImode);
8779   rtx fsca = gen_reg_rtx (V2SFmode);
8780   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
8781   rtx sfresult = gen_reg_rtx (SFmode);
8783   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
8784   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
8785   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
8786                           get_fpscr_rtx ()));
8787   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
8788   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
8789   DONE;
8792 (define_expand "abssf2"
8793   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8794         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8795   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8796   "
8798   if (TARGET_SH2E)
8799     {
8800       expand_sf_unop (&gen_abssf2_i, operands);
8801       DONE;
8802     }
8805 (define_insn "*abssf2_media"
8806   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8807         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8808   "TARGET_SHMEDIA_FPU"
8809   "fabs.s       %1, %0"
8810   [(set_attr "type" "fmove_media")])
8812 (define_insn "abssf2_i"
8813   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8814         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8815    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8816   "TARGET_SH2E"
8817   "fabs %0"
8818   [(set_attr "type" "fmove")
8819    (set_attr "fp_mode" "single")])
8821 (define_expand "adddf3"
8822   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8823         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8824                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8825   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8826   "
8828   if (TARGET_SH4)
8829     {
8830       expand_df_binop (&gen_adddf3_i, operands);
8831       DONE;
8832     }
8835 (define_insn "*adddf3_media"
8836   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8837         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8838                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8839   "TARGET_SHMEDIA_FPU"
8840   "fadd.d       %1, %2, %0"
8841   [(set_attr "type" "dfparith_media")])
8843 (define_insn "adddf3_i"
8844   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8845         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8846                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8847    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8848   "TARGET_SH4"
8849   "fadd %2,%0"
8850   [(set_attr "type" "dfp_arith")
8851    (set_attr "fp_mode" "double")])
8853 (define_expand "subdf3"
8854   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8855         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8856                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8857   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8858   "
8860   if (TARGET_SH4)
8861     {
8862       expand_df_binop (&gen_subdf3_i, operands);
8863       DONE;
8864     }
8867 (define_insn "*subdf3_media"
8868   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8869         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8870                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8871   "TARGET_SHMEDIA_FPU"
8872   "fsub.d       %1, %2, %0"
8873   [(set_attr "type" "dfparith_media")])
8875 (define_insn "subdf3_i"
8876   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8877         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8878                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8879    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8880   "TARGET_SH4"
8881   "fsub %2,%0"
8882   [(set_attr "type" "dfp_arith")
8883    (set_attr "fp_mode" "double")])
8885 (define_expand "muldf3"
8886   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8887         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8888                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8889   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8890   "
8892   if (TARGET_SH4)
8893     {
8894       expand_df_binop (&gen_muldf3_i, operands);
8895       DONE;
8896     }
8899 (define_insn "*muldf3_media"
8900   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8901         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8902                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8903   "TARGET_SHMEDIA_FPU"
8904   "fmul.d       %1, %2, %0"
8905   [(set_attr "type" "dfmul_media")])
8907 (define_insn "muldf3_i"
8908   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8909         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8910                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8911    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8912   "TARGET_SH4"
8913   "fmul %2,%0"
8914   [(set_attr "type" "dfp_arith")
8915    (set_attr "fp_mode" "double")])
8917 (define_expand "divdf3"
8918   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8919         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8920                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8921   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8922   "
8924   if (TARGET_SH4)
8925     {
8926       expand_df_binop (&gen_divdf3_i, operands);
8927       DONE;
8928     }
8931 (define_insn "*divdf3_media"
8932   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8933         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8934                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8935   "TARGET_SHMEDIA_FPU"
8936   "fdiv.d       %1, %2, %0"
8937   [(set_attr "type" "dfdiv_media")])
8939 (define_insn "divdf3_i"
8940   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8941         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8942                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8943    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8944   "TARGET_SH4"
8945   "fdiv %2,%0"
8946   [(set_attr "type" "dfdiv")
8947    (set_attr "fp_mode" "double")])
8949 (define_insn "floatdidf2"
8950   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8951         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8952   "TARGET_SHMEDIA_FPU"
8953   "float.qd     %1, %0"
8954   [(set_attr "type" "dfpconv_media")])
8956 (define_expand "floatsidf2"
8957   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8958         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8959   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8960   "
8962   if (TARGET_SH4)
8963     {
8964       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8965                                       get_fpscr_rtx ()));
8966       DONE;
8967     }
8970 (define_insn "*floatsidf2_media"
8971   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8972         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8973   "TARGET_SHMEDIA_FPU"
8974   "float.ld     %1, %0"
8975   [(set_attr "type" "dfpconv_media")])
8977 (define_insn "floatsidf2_i"
8978   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8979         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8980    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8981   "TARGET_SH4"
8982   "float        %1,%0"
8983   [(set_attr "type" "dfp_conv")
8984    (set_attr "fp_mode" "double")])
8986 (define_insn "fix_truncdfdi2"
8987   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8988         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8989   "TARGET_SHMEDIA_FPU"
8990   "ftrc.dq      %1, %0"
8991   [(set_attr "type" "dfpconv_media")])
8993 (define_expand "fix_truncdfsi2"
8994   [(set (match_operand:SI 0 "fpul_operand" "")
8995         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8996   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8997   "
8999   if (TARGET_SH4)
9000     {
9001       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
9002                                           get_fpscr_rtx ()));
9003       DONE;
9004     }
9007 (define_insn "*fix_truncdfsi2_media"
9008   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
9009         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9010   "TARGET_SHMEDIA_FPU"
9011   "ftrc.dl      %1, %0"
9012   [(set_attr "type" "dfpconv_media")])
9014 (define_insn "fix_truncdfsi2_i"
9015   [(set (match_operand:SI 0 "fpul_operand" "=y")
9016         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9017    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9018   "TARGET_SH4"
9019   "ftrc %1,%0"
9020   [(set_attr "type" "dfp_conv")
9021    (set_attr "dfp_comp" "no")
9022    (set_attr "fp_mode" "double")])
9024 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
9025 ;; fix_truncdfsi2_i.
9026 ;; (define_insn "fix_truncdfsi2_i4"
9027 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9028 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9029 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9030 ;;    (clobber (reg:SI FPUL_REG))]
9031 ;;   "TARGET_SH4"
9032 ;;   "#"
9033 ;;   [(set_attr "length" "4")
9034 ;;    (set_attr "fp_mode" "double")])
9036 ;; (define_split
9037 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9038 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9039 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9040 ;;    (clobber (reg:SI FPUL_REG))]
9041 ;;   "TARGET_SH4"
9042 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9043 ;;            (use (match_dup 2))])
9044 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
9046 (define_insn "cmpgtdf_t"
9047   [(set (reg:SI T_REG)
9048         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9049                (match_operand:DF 1 "arith_reg_operand" "f")))
9050    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9051   "TARGET_SH4"
9052   "fcmp/gt      %1,%0"
9053   [(set_attr "type" "dfp_cmp")
9054    (set_attr "fp_mode" "double")])
9056 (define_insn "cmpeqdf_t"
9057   [(set (reg:SI T_REG)
9058         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9059                (match_operand:DF 1 "arith_reg_operand" "f")))
9060    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9061   "TARGET_SH4"
9062   "fcmp/eq      %1,%0"
9063   [(set_attr "type" "dfp_cmp")
9064    (set_attr "fp_mode" "double")])
9066 (define_insn "*ieee_ccmpeqdf_t"
9067   [(set (reg:SI T_REG)
9068         (ior:SI (reg:SI T_REG)
9069                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9070                        (match_operand:DF 1 "arith_reg_operand" "f"))))
9071    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9072   "TARGET_IEEE && TARGET_SH4"
9073   "* return output_ieee_ccmpeq (insn, operands);"
9074   [(set_attr "length" "4")
9075    (set_attr "fp_mode" "double")])
9077 (define_insn "cmpeqdf_media"
9078   [(set (match_operand:DI 0 "register_operand" "=r")
9079         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9080                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9081   "TARGET_SHMEDIA_FPU"
9082   "fcmpeq.d     %1,%2,%0"
9083   [(set_attr "type" "fcmp_media")])
9085 (define_insn "cmpgtdf_media"
9086   [(set (match_operand:DI 0 "register_operand" "=r")
9087         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9088                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9089   "TARGET_SHMEDIA_FPU"
9090   "fcmpgt.d     %1,%2,%0"
9091   [(set_attr "type" "fcmp_media")])
9093 (define_insn "cmpgedf_media"
9094   [(set (match_operand:DI 0 "register_operand" "=r")
9095         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9096                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9097   "TARGET_SHMEDIA_FPU"
9098   "fcmpge.d     %1,%2,%0"
9099   [(set_attr "type" "fcmp_media")])
9101 (define_insn "cmpundf_media"
9102   [(set (match_operand:DI 0 "register_operand" "=r")
9103         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9104                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9105   "TARGET_SHMEDIA_FPU"
9106   "fcmpun.d     %1,%2,%0"
9107   [(set_attr "type" "fcmp_media")])
9109 (define_expand "cmpdf"
9110   [(set (reg:SI T_REG)
9111         (compare (match_operand:DF 0 "arith_operand" "")
9112                  (match_operand:DF 1 "arith_operand" "")))]
9113   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9114   "
9116   sh_compare_op0 = operands[0];
9117   sh_compare_op1 = operands[1];
9118   DONE;
9121 (define_expand "negdf2"
9122   [(set (match_operand:DF 0 "arith_reg_operand" "")
9123         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9124   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9125   "
9127   if (TARGET_SH4)
9128     {
9129       expand_df_unop (&gen_negdf2_i, operands);
9130       DONE;
9131     }
9134 (define_insn "*negdf2_media"
9135   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9136         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9137   "TARGET_SHMEDIA_FPU"
9138   "fneg.d       %1, %0"
9139   [(set_attr "type" "fmove_media")])
9141 (define_insn "negdf2_i"
9142   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9143         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9144    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9145   "TARGET_SH4"
9146   "fneg %0"
9147   [(set_attr "type" "fmove")
9148    (set_attr "fp_mode" "double")])
9150 (define_expand "sqrtdf2"
9151   [(set (match_operand:DF 0 "arith_reg_operand" "")
9152         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9153   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9154   "
9156   if (TARGET_SH4)
9157     {
9158       expand_df_unop (&gen_sqrtdf2_i, operands);
9159       DONE;
9160     }
9163 (define_insn "*sqrtdf2_media"
9164   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9165         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9166   "TARGET_SHMEDIA_FPU"
9167   "fsqrt.d      %1, %0"
9168   [(set_attr "type" "dfdiv_media")])
9170 (define_insn "sqrtdf2_i"
9171   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9172         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9173    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9174   "TARGET_SH4"
9175   "fsqrt        %0"
9176   [(set_attr "type" "dfdiv")
9177    (set_attr "fp_mode" "double")])
9179 (define_expand "absdf2"
9180   [(set (match_operand:DF 0 "arith_reg_operand" "")
9181         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9182   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9183   "
9185   if (TARGET_SH4)
9186     {
9187       expand_df_unop (&gen_absdf2_i, operands);
9188       DONE;
9189     }
9192 (define_insn "*absdf2_media"
9193   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9194         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9195   "TARGET_SHMEDIA_FPU"
9196   "fabs.d       %1, %0"
9197   [(set_attr "type" "fmove_media")])
9199 (define_insn "absdf2_i"
9200   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9201         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9202    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9203   "TARGET_SH4"
9204   "fabs %0"
9205   [(set_attr "type" "fmove")
9206    (set_attr "fp_mode" "double")])
9208 (define_expand "extendsfdf2"
9209   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9210         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9211   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9212   "
9214   if (TARGET_SH4)
9215     {
9216       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9217                                         get_fpscr_rtx ()));
9218       DONE;
9219     }
9222 (define_insn "*extendsfdf2_media"
9223   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9224         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9225   "TARGET_SHMEDIA_FPU"
9226   "fcnv.sd      %1, %0"
9227   [(set_attr "type" "dfpconv_media")])
9229 (define_insn "extendsfdf2_i4"
9230   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9231         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9232    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9233   "TARGET_SH4"
9234   "fcnvsd  %1,%0"
9235   [(set_attr "type" "fp")
9236    (set_attr "fp_mode" "double")])
9238 (define_expand "truncdfsf2"
9239   [(set (match_operand:SF 0 "fpul_operand" "")
9240         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9241   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9242   "
9244   if (TARGET_SH4)
9245     {
9246       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9247                                        get_fpscr_rtx ()));
9248       DONE;
9249     }
9252 (define_insn "*truncdfsf2_media"
9253   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9254         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9255   "TARGET_SHMEDIA_FPU"
9256   "fcnv.ds      %1, %0"
9257   [(set_attr "type" "dfpconv_media")])
9259 (define_insn "truncdfsf2_i4"
9260   [(set (match_operand:SF 0 "fpul_operand" "=y")
9261         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9262    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9263   "TARGET_SH4"
9264   "fcnvds  %1,%0"
9265   [(set_attr "type" "fp")
9266    (set_attr "fp_mode" "double")])
9268 ;; Bit field extract patterns.  These give better code for packed bitfields,
9269 ;; because they allow auto-increment addresses to be generated.
9271 (define_expand "insv"
9272   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9273                          (match_operand:SI 1 "immediate_operand" "")
9274                          (match_operand:SI 2 "immediate_operand" ""))
9275         (match_operand:SI 3 "general_operand" ""))]
9276   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9277   "
9279   rtx addr_target, orig_address, shift_reg, qi_val;
9280   HOST_WIDE_INT bitsize, size, v = 0;
9281   rtx x = operands[3];
9283   /* ??? expmed doesn't care for non-register predicates.  */
9284   if (! memory_operand (operands[0], VOIDmode)
9285       || ! immediate_operand (operands[1], VOIDmode)
9286       || ! immediate_operand (operands[2], VOIDmode)
9287       || ! general_operand (x, VOIDmode))
9288     FAIL;
9289   /* If this isn't a 16 / 24 / 32 bit field, or if
9290      it doesn't start on a byte boundary, then fail.  */
9291   bitsize = INTVAL (operands[1]);
9292   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9293       || (INTVAL (operands[2]) % 8) != 0)
9294     FAIL;
9296   size = bitsize / 8;
9297   orig_address = XEXP (operands[0], 0);
9298   shift_reg = gen_reg_rtx (SImode);
9299   if (GET_CODE (x) == CONST_INT)
9300     {
9301       v = INTVAL (x);
9302       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9303     }
9304   else
9305     {
9306       emit_insn (gen_movsi (shift_reg, operands[3]));
9307       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9308     }
9309   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9311   operands[0] = replace_equiv_address (operands[0], addr_target);
9312   emit_insn (gen_movqi (operands[0], qi_val));
9314   while (size -= 1)
9315     {
9316       if (GET_CODE (x) == CONST_INT)
9317         qi_val
9318           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9319       else
9320         {
9321           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9322           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9323         }
9324       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9325       emit_insn (gen_movqi (operands[0], qi_val));
9326     }
9328   DONE;
9331 (define_insn "movua"
9332   [(set (match_operand:SI 0 "register_operand" "=z")
9333         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
9334                          (const_int 32) (const_int 0)))]
9335   "TARGET_SH4A_ARCH"
9336   "movua.l      %1,%0"
9337   [(set_attr "type" "movua")])
9339 ;; We shouldn't need this, but cse replaces increments with references
9340 ;; to other regs before flow has a chance to create post_inc
9341 ;; addressing modes, and only postreload's cse_move2add brings the
9342 ;; increments back to a usable form.
9343 (define_peephole2
9344   [(set (match_operand:SI 0 "register_operand" "")
9345         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
9346                          (const_int 32) (const_int 0)))
9347    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9348   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
9349   [(set (match_operand:SI 0 "register_operand" "")
9350         (sign_extract:SI (mem:SI (post_inc:SI
9351                                   (match_operand:SI 1 "register_operand" "")))
9352                          (const_int 32) (const_int 0)))]
9353   "")
9355 (define_expand "extv"
9356   [(set (match_operand:SI 0 "register_operand" "")
9357         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9358                          (match_operand 2 "const_int_operand" "")
9359                          (match_operand 3 "const_int_operand" "")))]
9360   ""
9362   if (TARGET_SH4A_ARCH
9363       && INTVAL (operands[2]) == 32
9364       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9365       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9366     {
9367       emit_insn (gen_movua (operands[0],
9368                             adjust_address (operands[1], SImode, 0)));
9369       DONE;
9370     }
9372   FAIL;
9375 (define_expand "extzv"
9376   [(set (match_operand:SI 0 "register_operand" "")
9377         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
9378                          (match_operand 2 "const_int_operand" "")
9379                          (match_operand 3 "const_int_operand" "")))]
9380   ""
9382   if (TARGET_SH4A_ARCH
9383       && INTVAL (operands[2]) == 32
9384       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
9385       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
9386     {
9387       emit_insn (gen_movua (operands[0],
9388                             adjust_address (operands[1], SImode, 0)));
9389       DONE;
9390     }
9392   FAIL;
9396 ;; -------------------------------------------------------------------------
9397 ;; Peepholes
9398 ;; -------------------------------------------------------------------------
9400 ;; This matches cases where a stack pointer increment at the start of the
9401 ;; epilogue combines with a stack slot read loading the return value.
9403 (define_peephole
9404   [(set (match_operand:SI 0 "arith_reg_operand" "")
9405         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9406    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9407   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9408   "mov.l        @%1+,%0")
9410 ;; See the comment on the dt combiner pattern above.
9412 (define_peephole
9413   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9414         (plus:SI (match_dup 0)
9415                  (const_int -1)))
9416    (set (reg:SI T_REG)
9417         (eq:SI (match_dup 0)
9418                (const_int 0)))]
9419   "TARGET_SH2"
9420   "dt   %0")
9422 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9423 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9424 ;; reload when the constant is too large for a reg+offset address.
9426 ;; ??? We would get much better code if this was done in reload.  This would
9427 ;; require modifying find_reloads_address to recognize that if the constant
9428 ;; is out-of-range for an immediate add, then we get better code by reloading
9429 ;; the constant into a register than by reloading the sum into a register,
9430 ;; since the former is one instruction shorter if the address does not need
9431 ;; to be offsettable.  Unfortunately this does not work, because there is
9432 ;; only one register, r0, that can be used as an index register.  This register
9433 ;; is also the function return value register.  So, if we try to force reload
9434 ;; to use double-reg addresses, then we end up with some instructions that
9435 ;; need to use r0 twice.  The only way to fix this is to change the calling
9436 ;; convention so that r0 is not used to return values.
9438 (define_peephole
9439   [(set (match_operand:SI 0 "register_operand" "=r")
9440         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9441    (set (mem:SI (match_dup 0))
9442         (match_operand:SI 2 "general_movsrc_operand" ""))]
9443   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9444   "mov.l        %2,@(%0,%1)")
9446 (define_peephole
9447   [(set (match_operand:SI 0 "register_operand" "=r")
9448         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9449    (set (match_operand:SI 2 "general_movdst_operand" "")
9450         (mem:SI (match_dup 0)))]
9451   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9452   "mov.l        @(%0,%1),%2")
9454 (define_peephole
9455   [(set (match_operand:SI 0 "register_operand" "=r")
9456         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9457    (set (mem:HI (match_dup 0))
9458         (match_operand:HI 2 "general_movsrc_operand" ""))]
9459   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9460   "mov.w        %2,@(%0,%1)")
9462 (define_peephole
9463   [(set (match_operand:SI 0 "register_operand" "=r")
9464         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9465    (set (match_operand:HI 2 "general_movdst_operand" "")
9466         (mem:HI (match_dup 0)))]
9467   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9468   "mov.w        @(%0,%1),%2")
9470 (define_peephole
9471   [(set (match_operand:SI 0 "register_operand" "=r")
9472         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9473    (set (mem:QI (match_dup 0))
9474         (match_operand:QI 2 "general_movsrc_operand" ""))]
9475   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9476   "mov.b        %2,@(%0,%1)")
9478 (define_peephole
9479   [(set (match_operand:SI 0 "register_operand" "=r")
9480         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9481    (set (match_operand:QI 2 "general_movdst_operand" "")
9482         (mem:QI (match_dup 0)))]
9483   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9484   "mov.b        @(%0,%1),%2")
9486 (define_peephole
9487   [(set (match_operand:SI 0 "register_operand" "=r")
9488         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9489    (set (mem:SF (match_dup 0))
9490         (match_operand:SF 2 "general_movsrc_operand" ""))]
9491   "TARGET_SH1 && REGNO (operands[0]) == 0
9492    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9493        || (GET_CODE (operands[2]) == SUBREG
9494            && REGNO (SUBREG_REG (operands[2])) < 16))
9495    && reg_unused_after (operands[0], insn)"
9496   "mov.l        %2,@(%0,%1)")
9498 (define_peephole
9499   [(set (match_operand:SI 0 "register_operand" "=r")
9500         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9501    (set (match_operand:SF 2 "general_movdst_operand" "")
9503         (mem:SF (match_dup 0)))]
9504   "TARGET_SH1 && REGNO (operands[0]) == 0
9505    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9506        || (GET_CODE (operands[2]) == SUBREG
9507            && REGNO (SUBREG_REG (operands[2])) < 16))
9508    && reg_unused_after (operands[0], insn)"
9509   "mov.l        @(%0,%1),%2")
9511 (define_peephole
9512   [(set (match_operand:SI 0 "register_operand" "=r")
9513         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9514    (set (mem:SF (match_dup 0))
9515         (match_operand:SF 2 "general_movsrc_operand" ""))]
9516   "TARGET_SH2E && REGNO (operands[0]) == 0
9517    && ((GET_CODE (operands[2]) == REG
9518         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9519        || (GET_CODE (operands[2]) == SUBREG
9520            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9521    && reg_unused_after (operands[0], insn)"
9522   "fmov{.s|}    %2,@(%0,%1)")
9524 (define_peephole
9525   [(set (match_operand:SI 0 "register_operand" "=r")
9526         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9527    (set (match_operand:SF 2 "general_movdst_operand" "")
9529         (mem:SF (match_dup 0)))]
9530   "TARGET_SH2E && REGNO (operands[0]) == 0
9531    && ((GET_CODE (operands[2]) == REG
9532         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9533        || (GET_CODE (operands[2]) == SUBREG
9534            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9535    && reg_unused_after (operands[0], insn)"
9536   "fmov{.s|}    @(%0,%1),%2")
9538 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9539 (define_insn "sp_switch_1"
9540   [(const_int 1)]
9541   "TARGET_SH1"
9542   "*
9544   rtx xoperands[1];
9546   xoperands[0] = sp_switch;
9547   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9548   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9549   return \"mov r0,r15\";
9551   [(set_attr "length" "10")])
9553 ;; Switch back to the original stack for interrupt functions with the
9554 ;; sp_switch attribute.  */
9555 (define_insn "sp_switch_2"
9556   [(const_int 2)]
9557   "TARGET_SH1"
9558   "mov.l @r15+,r15\;mov.l @r15+,r0"
9559   [(set_attr "length" "4")])
9561 ;; Integer vector moves
9563 (define_expand "movv8qi"
9564   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9565         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9566   "TARGET_SHMEDIA"
9567   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9569 (define_insn "movv8qi_i"
9570   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9571         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9572   "TARGET_SHMEDIA
9573    && (register_operand (operands[0], V8QImode)
9574        || sh_register_operand (operands[1], V8QImode))"
9575   "@
9576         add     %1, r63, %0
9577         movi    %1, %0
9578         #
9579         ld%M1.q %m1, %0
9580         st%M0.q %m0, %N1"
9581   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9582    (set_attr "length" "4,4,16,4,4")])
9584 (define_split
9585   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9586         (subreg:V8QI (const_int 0) 0))]
9587   "TARGET_SHMEDIA"
9588   [(set (match_dup 0)
9589         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9590                             (const_int 0) (const_int 0) (const_int 0)
9591                             (const_int 0) (const_int 0)]))])
9593 (define_split
9594   [(set (match_operand 0 "arith_reg_dest" "")
9595         (match_operand 1 "sh_rep_vec" ""))]
9596   "TARGET_SHMEDIA && reload_completed
9597    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9598    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9599    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9600    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9601        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9602    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9603        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9604   [(set (match_dup 0) (match_dup 1))
9605    (match_dup 2)]
9606   "
9608   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9609   rtx elt1 = XVECEXP (operands[1], 0, 1);
9611   if (unit_size > 2)
9612     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9613   else
9614     {
9615       if (unit_size < 2)
9616         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9617       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9618     }
9619   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9620   operands[1] = XVECEXP (operands[1], 0, 0);
9621   if (unit_size < 2)
9622     {
9623       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9624         operands[1]
9625           = GEN_INT (TARGET_LITTLE_ENDIAN
9626                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9627                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9628       else
9629         {
9630           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9631           operands[1]
9632             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9633         }
9634     }
9637 (define_split
9638   [(set (match_operand 0 "arith_reg_dest" "")
9639         (match_operand 1 "sh_const_vec" ""))]
9640   "TARGET_SHMEDIA && reload_completed
9641    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9642    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9643    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9644   [(set (match_dup 0) (match_dup 1))]
9645   "
9647   rtx v = operands[1];
9648   enum machine_mode new_mode
9649     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9651   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9652   operands[1]
9653     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9656 (define_expand "movv2hi"
9657   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9658         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9659   "TARGET_SHMEDIA"
9660   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9662 (define_insn "movv2hi_i"
9663   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9664         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9665   "TARGET_SHMEDIA
9666    && (register_operand (operands[0], V2HImode)
9667        || sh_register_operand (operands[1], V2HImode))"
9668   "@
9669         addz.l  %1, r63, %0
9670         movi    %1, %0
9671         #
9672         ld%M1.l %m1, %0
9673         st%M0.l %m0, %N1"
9674   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9675    (set_attr "length" "4,4,16,4,4")])
9677 (define_expand "movv4hi"
9678   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9679         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9680   "TARGET_SHMEDIA"
9681   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9683 (define_insn "movv4hi_i"
9684   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9685         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9686   "TARGET_SHMEDIA
9687    && (register_operand (operands[0], V4HImode)
9688        || sh_register_operand (operands[1], V4HImode))"
9689   "@
9690         add     %1, r63, %0
9691         movi    %1, %0
9692         #
9693         ld%M1.q %m1, %0
9694         st%M0.q %m0, %N1"
9695   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9696    (set_attr "length" "4,4,16,4,4")])
9698 (define_expand "movv2si"
9699   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9700         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9701   "TARGET_SHMEDIA"
9702   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9704 (define_insn "movv2si_i"
9705   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9706         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9707   "TARGET_SHMEDIA
9708    && (register_operand (operands[0], V2SImode)
9709        || sh_register_operand (operands[1], V2SImode))"
9710   "@
9711         add     %1, r63, %0
9712         #
9713         #
9714         ld%M1.q %m1, %0
9715         st%M0.q %m0, %N1"
9716   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9717    (set_attr "length" "4,4,16,4,4")])
9719 ;; Multimedia Intrinsics
9721 (define_insn "absv2si2"
9722   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9723         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9724   "TARGET_SHMEDIA"
9725   "mabs.l       %1, %0"
9726   [(set_attr "type" "mcmp_media")])
9728 (define_insn "absv4hi2"
9729   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9730         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9731   "TARGET_SHMEDIA"
9732   "mabs.w       %1, %0"
9733   [(set_attr "type" "mcmp_media")])
9735 (define_insn "addv2si3"
9736   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9737         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9738                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9739   "TARGET_SHMEDIA"
9740   "madd.l       %1, %2, %0"
9741   [(set_attr "type" "arith_media")])
9743 (define_insn "addv4hi3"
9744   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9745         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9746                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9747   "TARGET_SHMEDIA"
9748   "madd.w       %1, %2, %0"
9749   [(set_attr "type" "arith_media")])
9751 (define_insn "ssaddv2si3"
9752   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9753         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9754                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9755   "TARGET_SHMEDIA"
9756   "madds.l      %1, %2, %0"
9757   [(set_attr "type" "mcmp_media")])
9759 (define_insn "usaddv8qi3"
9760   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9761         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9762                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9763   "TARGET_SHMEDIA"
9764   "madds.ub     %1, %2, %0"
9765   [(set_attr "type" "mcmp_media")])
9767 (define_insn "ssaddv4hi3"
9768   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9769         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9770                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9771   "TARGET_SHMEDIA"
9772   "madds.w      %1, %2, %0"
9773   [(set_attr "type" "mcmp_media")])
9775 (define_insn "negcmpeqv8qi"
9776   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9777         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9778                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9779   "TARGET_SHMEDIA"
9780   "mcmpeq.b     %N1, %N2, %0"
9781   [(set_attr "type" "mcmp_media")])
9783 (define_insn "negcmpeqv2si"
9784   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9785         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9786                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9787   "TARGET_SHMEDIA"
9788   "mcmpeq.l     %N1, %N2, %0"
9789   [(set_attr "type" "mcmp_media")])
9791 (define_insn "negcmpeqv4hi"
9792   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9793         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9794                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9795   "TARGET_SHMEDIA"
9796   "mcmpeq.w     %N1, %N2, %0"
9797   [(set_attr "type" "mcmp_media")])
9799 (define_insn "negcmpgtuv8qi"
9800   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9801         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9802                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9803   "TARGET_SHMEDIA"
9804   "mcmpgt.ub    %N1, %N2, %0"
9805   [(set_attr "type" "mcmp_media")])
9807 (define_insn "negcmpgtv2si"
9808   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9809         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9810                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9811   "TARGET_SHMEDIA"
9812   "mcmpgt.l     %N1, %N2, %0"
9813   [(set_attr "type" "mcmp_media")])
9815 (define_insn "negcmpgtv4hi"
9816   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9817         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9818                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9819   "TARGET_SHMEDIA"
9820   "mcmpgt.w     %N1, %N2, %0"
9821   [(set_attr "type" "mcmp_media")])
9823 (define_insn "mcmv"
9824   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9825         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9826                         (match_operand:DI 2 "arith_reg_operand" "r"))
9827                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9828                         (not:DI (match_dup 2)))))]
9829   "TARGET_SHMEDIA"
9830   "mcmv %N1, %2, %0"
9831   [(set_attr "type" "arith_media")])
9833 (define_insn "mcnvs_lw"
9834   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9835         (vec_concat:V4HI
9836          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9837          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9838   "TARGET_SHMEDIA"
9839   "mcnvs.lw     %N1, %N2, %0"
9840   [(set_attr "type" "mcmp_media")])
9842 (define_insn "mcnvs_wb"
9843   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9844         (vec_concat:V8QI
9845          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9846          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9847   "TARGET_SHMEDIA"
9848   "mcnvs.wb     %N1, %N2, %0"
9849   [(set_attr "type" "mcmp_media")])
9851 (define_insn "mcnvs_wub"
9852   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9853         (vec_concat:V8QI
9854          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9855          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9856   "TARGET_SHMEDIA"
9857   "mcnvs.wub    %N1, %N2, %0"
9858   [(set_attr "type" "mcmp_media")])
9860 (define_insn "mextr_rl"
9861   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9862         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9863                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9864                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9865                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9866   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9867   "*
9869   static char templ[16];
9871   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9872            (int) INTVAL (operands[3]) >> 3);
9873   return templ;
9875   [(set_attr "type" "arith_media")])
9877 (define_insn "*mextr_lr"
9878   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9879         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9880                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9881                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9882                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9883   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9884   "*
9886   static char templ[16];
9888   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9889            (int) INTVAL (operands[4]) >> 3);
9890   return templ;
9892   [(set_attr "type" "arith_media")])
9894 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9895 ; vector then varies depending on endianness.
9896 (define_expand "mextr1"
9897   [(match_operand:DI 0 "arith_reg_dest" "")
9898    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9899    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9900   "TARGET_SHMEDIA"
9901   "
9903   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9904                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9905   DONE;
9908 (define_expand "mextr2"
9909   [(match_operand:DI 0 "arith_reg_dest" "")
9910    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9911    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9912   "TARGET_SHMEDIA"
9913   "
9915   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9916                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9917   DONE;
9920 (define_expand "mextr3"
9921   [(match_operand:DI 0 "arith_reg_dest" "")
9922    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9923    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9924   "TARGET_SHMEDIA"
9925   "
9927   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9928                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9929   DONE;
9932 (define_expand "mextr4"
9933   [(match_operand:DI 0 "arith_reg_dest" "")
9934    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9935    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9936   "TARGET_SHMEDIA"
9937   "
9939   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9940                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9941   DONE;
9944 (define_expand "mextr5"
9945   [(match_operand:DI 0 "arith_reg_dest" "")
9946    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9947    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9948   "TARGET_SHMEDIA"
9949   "
9951   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9952                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9953   DONE;
9956 (define_expand "mextr6"
9957   [(match_operand:DI 0 "arith_reg_dest" "")
9958    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9959    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9960   "TARGET_SHMEDIA"
9961   "
9963   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9964                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9965   DONE;
9968 (define_expand "mextr7"
9969   [(match_operand:DI 0 "arith_reg_dest" "")
9970    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9971    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9972   "TARGET_SHMEDIA"
9973   "
9975   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9976                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9977   DONE;
9980 (define_expand "mmacfx_wl"
9981   [(match_operand:V2SI 0 "arith_reg_dest" "")
9982    (match_operand:V2HI 1 "extend_reg_operand" "")
9983    (match_operand:V2HI 2 "extend_reg_operand" "")
9984    (match_operand:V2SI 3 "arith_reg_operand" "")]
9985   "TARGET_SHMEDIA"
9986   "
9988   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9989                               operands[1], operands[2]));
9990   DONE;
9993 (define_insn "mmacfx_wl_i"
9994   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9995         (ss_plus:V2SI
9996          (match_operand:V2SI 1 "arith_reg_operand" "0")
9997          (ss_truncate:V2SI
9998           (ashift:V2DI
9999            (sign_extend:V2DI
10000             (mult:V2SI
10001              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10002              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10003            (const_int 1)))))]
10004   "TARGET_SHMEDIA"
10005   "mmacfx.wl    %2, %3, %0"
10006   [(set_attr "type" "mac_media")])
10008 (define_expand "mmacnfx_wl"
10009   [(match_operand:V2SI 0 "arith_reg_dest" "")
10010    (match_operand:V2HI 1 "extend_reg_operand" "")
10011    (match_operand:V2HI 2 "extend_reg_operand" "")
10012    (match_operand:V2SI 3 "arith_reg_operand" "")]
10013   "TARGET_SHMEDIA"
10014   "
10016   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
10017                                operands[1], operands[2]));
10018   DONE;
10021 (define_insn "mmacnfx_wl_i"
10022   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10023         (ss_minus:V2SI
10024          (match_operand:V2SI 1 "arith_reg_operand" "0")
10025          (ss_truncate:V2SI
10026           (ashift:V2DI
10027            (sign_extend:V2DI
10028             (mult:V2SI
10029              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
10030              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
10031            (const_int 1)))))]
10032   "TARGET_SHMEDIA"
10033   "mmacnfx.wl   %2, %3, %0"
10034   [(set_attr "type" "mac_media")])
10036 (define_insn "mulv2si3"
10037   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10038         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10039                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10040   "TARGET_SHMEDIA"
10041   "mmul.l       %1, %2, %0"
10042   [(set_attr "type" "d2mpy_media")])
10044 (define_insn "mulv4hi3"
10045   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10046         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10047                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10048   "TARGET_SHMEDIA"
10049   "mmul.w       %1, %2, %0"
10050   [(set_attr "type" "dmpy_media")])
10052 (define_insn "mmulfx_l"
10053   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10054         (ss_truncate:V2SI
10055          (ashiftrt:V2DI
10056           (mult:V2DI
10057            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10058            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
10059           (const_int 31))))]
10060   "TARGET_SHMEDIA"
10061   "mmulfx.l     %1, %2, %0"
10062   [(set_attr "type" "d2mpy_media")])
10064 (define_insn "mmulfx_w"
10065   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10066         (ss_truncate:V4HI
10067          (ashiftrt:V4SI
10068           (mult:V4SI
10069            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10070            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10071           (const_int 15))))]
10072   "TARGET_SHMEDIA"
10073   "mmulfx.w     %1, %2, %0"
10074   [(set_attr "type" "dmpy_media")])
10076 (define_insn "mmulfxrp_w"
10077   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10078         (ss_truncate:V4HI
10079          (ashiftrt:V4SI
10080           (plus:V4SI
10081            (mult:V4SI
10082             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10083             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10084            (const_int 16384))
10085           (const_int 15))))]
10086   "TARGET_SHMEDIA"
10087   "mmulfxrp.w   %1, %2, %0"
10088   [(set_attr "type" "dmpy_media")])
10090 (define_expand "mmulhi_wl"
10091   [(match_operand:V2SI 0 "arith_reg_dest" "")
10092    (match_operand:V4HI 1 "arith_reg_operand" "")
10093    (match_operand:V4HI 2 "arith_reg_operand" "")]
10094   "TARGET_SHMEDIA"
10095   "
10097   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
10098              (operands[0], operands[1], operands[2]));
10099   DONE;
10102 (define_expand "mmullo_wl"
10103   [(match_operand:V2SI 0 "arith_reg_dest" "")
10104    (match_operand:V4HI 1 "arith_reg_operand" "")
10105    (match_operand:V4HI 2 "arith_reg_operand" "")]
10106   "TARGET_SHMEDIA"
10107   "
10109   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10110              (operands[0], operands[1], operands[2]));
10111   DONE;
10114 (define_insn "mmul23_wl"
10115   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10116         (vec_select:V2SI
10117          (mult:V4SI
10118           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10119           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10120          (parallel [(const_int 2) (const_int 3)])))]
10121   "TARGET_SHMEDIA"
10122   "* return (TARGET_LITTLE_ENDIAN
10123              ? \"mmulhi.wl      %1, %2, %0\"
10124              : \"mmullo.wl      %1, %2, %0\");"
10125   [(set_attr "type" "dmpy_media")])
10127 (define_insn "mmul01_wl"
10128   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10129         (vec_select:V2SI
10130          (mult:V4SI
10131           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10132           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10133          (parallel [(const_int 0) (const_int 1)])))]
10134   "TARGET_SHMEDIA"
10135   "* return (TARGET_LITTLE_ENDIAN
10136              ? \"mmullo.wl      %1, %2, %0\"
10137              : \"mmulhi.wl      %1, %2, %0\");"
10138   [(set_attr "type" "dmpy_media")])
10140 (define_expand "mmulsum_wq"
10141   [(match_operand:DI 0 "arith_reg_dest" "")
10142    (match_operand:V4HI 1 "arith_reg_operand" "")
10143    (match_operand:V4HI 2 "arith_reg_operand" "")
10144    (match_operand:DI 3 "arith_reg_operand" "")]
10145   "TARGET_SHMEDIA"
10146   "
10148   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10149                                operands[1], operands[2]));
10150   DONE;
10153 (define_insn "mmulsum_wq_i"
10154   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10155         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10156          (plus:DI
10157           (plus:DI
10158            (vec_select:DI
10159             (mult:V4DI
10160              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10161              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10162             (parallel [(const_int 0)]))
10163            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10164                                      (sign_extend:V4DI (match_dup 3)))
10165                           (parallel [(const_int 1)])))
10166           (plus:DI
10167            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10168                                      (sign_extend:V4DI (match_dup 3)))
10169                           (parallel [(const_int 2)]))
10170            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10171                                      (sign_extend:V4DI (match_dup 3)))
10172                           (parallel [(const_int 3)]))))))]
10173   "TARGET_SHMEDIA"
10174   "mmulsum.wq   %2, %3, %0"
10175   [(set_attr "type" "mac_media")])
10177 (define_expand "mperm_w"
10178   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10179    (match_operand:V4HI 1 "arith_reg_operand" "r")
10180    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10181   "TARGET_SHMEDIA"
10182   "
10184   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10185              (operands[0], operands[1], operands[2]));
10186   DONE;
10189 ; This use of vec_select isn't exactly correct according to rtl.texi
10190 ; (because not constant), but it seems a straightforward extension.
10191 (define_insn "mperm_w_little"
10192   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10193         (vec_select:V4HI
10194          (match_operand:V4HI 1 "arith_reg_operand" "r")
10195          (parallel
10196           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10197                             (const_int 2) (const_int 0))
10198            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10199            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10200            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10201   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10202   "mperm.w      %1, %N2, %0"
10203   [(set_attr "type" "arith_media")])
10205 (define_insn "mperm_w_big"
10206   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10207         (vec_select:V4HI
10208          (match_operand:V4HI 1 "arith_reg_operand" "r")
10209          (parallel
10210           [(zero_extract:QI (not:QI (match_operand:QI 2
10211                                      "extend_reg_or_0_operand" "rZ"))
10212                             (const_int 2) (const_int 0))
10213            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10214            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10215            (zero_extract:QI (not:QI (match_dup 2))
10216                             (const_int 2) (const_int 6))])))]
10217   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10218   "mperm.w      %1, %N2, %0"
10219   [(set_attr "type" "arith_media")])
10221 (define_insn "mperm_w0"
10222   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10223         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10224                                           "trunc_hi_operand" "r"))))]
10225   "TARGET_SHMEDIA"
10226   "mperm.w      %1, r63, %0"
10227   [(set_attr "type" "arith_media")])
10229 (define_expand "msad_ubq"
10230   [(match_operand:DI 0 "arith_reg_dest" "")
10231    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10232    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10233    (match_operand:DI 3 "arith_reg_operand" "")]
10234   "TARGET_SHMEDIA"
10235   "
10237   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10238                              operands[1], operands[2]));
10239   DONE;
10242 (define_insn "msad_ubq_i"
10243   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10244         (plus:DI
10245          (plus:DI
10246           (plus:DI
10247            (plus:DI
10248             (match_operand:DI 1 "arith_reg_operand" "0")
10249             (abs:DI (vec_select:DI
10250                      (minus:V8DI
10251                       (zero_extend:V8DI
10252                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10253                       (zero_extend:V8DI
10254                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10255                      (parallel [(const_int 0)]))))
10256            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10257                                               (zero_extend:V8DI (match_dup 3)))
10258                                   (parallel [(const_int 1)]))))
10259           (plus:DI
10260            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10261                                               (zero_extend:V8DI (match_dup 3)))
10262                                   (parallel [(const_int 2)])))
10263            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10264                                               (zero_extend:V8DI (match_dup 3)))
10265                                   (parallel [(const_int 3)])))))
10266          (plus:DI
10267           (plus:DI
10268            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10269                                               (zero_extend:V8DI (match_dup 3)))
10270                                   (parallel [(const_int 4)])))
10271            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10272                                               (zero_extend:V8DI (match_dup 3)))
10273                                   (parallel [(const_int 5)]))))
10274           (plus:DI
10275            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10276                                               (zero_extend:V8DI (match_dup 3)))
10277                                   (parallel [(const_int 6)])))
10278            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10279                                               (zero_extend:V8DI (match_dup 3)))
10280                                   (parallel [(const_int 7)])))))))]
10281   "TARGET_SHMEDIA"
10282   "msad.ubq     %N2, %N3, %0"
10283   [(set_attr "type" "mac_media")])
10285 (define_insn "mshalds_l"
10286   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10287         (ss_truncate:V2SI
10288          (ashift:V2DI
10289           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10290           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10291                   (const_int 31)))))]
10292   "TARGET_SHMEDIA"
10293   "mshalds.l    %1, %2, %0"
10294   [(set_attr "type" "mcmp_media")])
10296 (define_insn "mshalds_w"
10297   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10298         (ss_truncate:V4HI
10299          (ashift:V4SI
10300           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10301           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10302                   (const_int 15)))))]
10303   "TARGET_SHMEDIA"
10304   "mshalds.w    %1, %2, %0"
10305   [(set_attr "type" "mcmp_media")])
10307 (define_insn "ashrv2si3"
10308   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10309         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10310                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10311   "TARGET_SHMEDIA"
10312   "mshard.l     %1, %2, %0"
10313   [(set_attr "type" "arith_media")])
10315 (define_insn "ashrv4hi3"
10316   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10317         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10318                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10319   "TARGET_SHMEDIA"
10320   "mshard.w     %1, %2, %0"
10321   [(set_attr "type" "arith_media")])
10323 (define_insn "mshards_q"
10324   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10325         (ss_truncate:HI
10326          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10327                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10328   "TARGET_SHMEDIA"
10329   "mshards.q    %1, %N2, %0"
10330   [(set_attr "type" "mcmp_media")])
10332 (define_expand "mshfhi_b"
10333   [(match_operand:V8QI 0 "arith_reg_dest" "")
10334    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10335    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10336   "TARGET_SHMEDIA"
10337   "
10339   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10340              (operands[0], operands[1], operands[2]));
10341   DONE;
10344 (define_expand "mshflo_b"
10345   [(match_operand:V8QI 0 "arith_reg_dest" "")
10346    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10347    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10348   "TARGET_SHMEDIA"
10349   "
10351   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10352              (operands[0], operands[1], operands[2]));
10353   DONE;
10356 (define_insn "mshf4_b"
10357   [(set
10358     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10359     (vec_select:V8QI
10360      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10361                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10362      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10363                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10364   "TARGET_SHMEDIA"
10365   "* return (TARGET_LITTLE_ENDIAN
10366              ? \"mshfhi.b       %N1, %N2, %0\"
10367              : \"mshflo.b       %N1, %N2, %0\");"
10368   [(set_attr "type" "arith_media")])
10370 (define_insn "mshf0_b"
10371   [(set
10372     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10373     (vec_select:V8QI
10374      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10375                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10376      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10377                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10378   "TARGET_SHMEDIA"
10379   "* return (TARGET_LITTLE_ENDIAN
10380              ? \"mshflo.b       %N1, %N2, %0\"
10381              : \"mshfhi.b       %N1, %N2, %0\");"
10382   [(set_attr "type" "arith_media")])
10384 (define_expand "mshfhi_l"
10385   [(match_operand:V2SI 0 "arith_reg_dest" "")
10386    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10387    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10388   "TARGET_SHMEDIA"
10389   "
10391   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10392              (operands[0], operands[1], operands[2]));
10393   DONE;
10396 (define_expand "mshflo_l"
10397   [(match_operand:V2SI 0 "arith_reg_dest" "")
10398    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10399    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10400   "TARGET_SHMEDIA"
10401   "
10403   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10404              (operands[0], operands[1], operands[2]));
10405   DONE;
10408 (define_insn "mshf4_l"
10409   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10410         (vec_select:V2SI
10411          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10412                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10413          (parallel [(const_int 1) (const_int 3)])))]
10414   "TARGET_SHMEDIA"
10415   "* return (TARGET_LITTLE_ENDIAN
10416              ? \"mshfhi.l       %N1, %N2, %0\"
10417              : \"mshflo.l       %N1, %N2, %0\");"
10418   [(set_attr "type" "arith_media")])
10420 (define_insn "mshf0_l"
10421   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10422         (vec_select:V2SI
10423          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10424                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10425          (parallel [(const_int 0) (const_int 2)])))]
10426   "TARGET_SHMEDIA"
10427   "* return (TARGET_LITTLE_ENDIAN
10428              ? \"mshflo.l       %N1, %N2, %0\"
10429              : \"mshfhi.l       %N1, %N2, %0\");"
10430   [(set_attr "type" "arith_media")])
10432 (define_expand "mshfhi_w"
10433   [(match_operand:V4HI 0 "arith_reg_dest" "")
10434    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10435    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10436   "TARGET_SHMEDIA"
10437   "
10439   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10440              (operands[0], operands[1], operands[2]));
10441   DONE;
10444 (define_expand "mshflo_w"
10445   [(match_operand:V4HI 0 "arith_reg_dest" "")
10446    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10447    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10448   "TARGET_SHMEDIA"
10449   "
10451   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10452              (operands[0], operands[1], operands[2]));
10453   DONE;
10456 (define_insn "mshf4_w"
10457   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10458         (vec_select:V4HI
10459          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10460                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10461          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10462   "TARGET_SHMEDIA"
10463   "* return (TARGET_LITTLE_ENDIAN
10464              ? \"mshfhi.w       %N1, %N2, %0\"
10465              : \"mshflo.w       %N1, %N2, %0\");"
10466   [(set_attr "type" "arith_media")])
10468 (define_insn "mshf0_w"
10469   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10470         (vec_select:V4HI
10471          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10472                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10473          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10474   "TARGET_SHMEDIA"
10475   "* return (TARGET_LITTLE_ENDIAN
10476              ? \"mshflo.w       %N1, %N2, %0\"
10477              : \"mshfhi.w       %N1, %N2, %0\");"
10478   [(set_attr "type" "arith_media")])
10480 (define_insn "mshflo_w_x"
10481   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10482         (vec_select:V4HI
10483          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10484                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10485          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10486   "TARGET_SHMEDIA"
10487   "mshflo.w     %N1, %N2, %0"
10488   [(set_attr "type" "arith_media")])
10490 /* These are useful to expand ANDs and as combiner patterns.  */
10491 (define_insn_and_split "mshfhi_l_di"
10492   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10493         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10494                              (const_int 32))
10495                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10496                         (const_int -4294967296))))]
10497   "TARGET_SHMEDIA"
10498   "@
10499         mshfhi.l        %N1, %N2, %0
10500         #"
10501   "TARGET_SHMEDIA && reload_completed
10502    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10503   [(set (match_dup 3) (match_dup 4))
10504    (set (match_dup 5) (match_dup 6))]
10505   "
10507   operands[3] = gen_lowpart (SImode, operands[0]);
10508   operands[4] = gen_highpart (SImode, operands[1]);
10509   operands[5] = gen_highpart (SImode, operands[0]);
10510   operands[6] = gen_highpart (SImode, operands[2]);
10512   [(set_attr "type" "arith_media")])
10514 (define_insn "*mshfhi_l_di_rev"
10515   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10516         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10517                         (const_int -4294967296))
10518                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10519                              (const_int 32))))]
10520   "TARGET_SHMEDIA"
10521   "mshfhi.l     %N2, %N1, %0"
10522   [(set_attr "type" "arith_media")])
10524 (define_split
10525   [(set (match_operand:DI 0 "arith_reg_dest" "")
10526         (ior:DI (zero_extend:DI (match_operand:SI 1
10527                                               "extend_reg_or_0_operand" ""))
10528                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10529                         (const_int -4294967296))))
10530    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10531   "TARGET_SHMEDIA"
10532   [(const_int 0)]
10533   "
10535   emit_insn (gen_ashldi3_media (operands[3],
10536                                 simplify_gen_subreg (DImode, operands[1],
10537                                                      SImode, 0),
10538                                 GEN_INT (32)));
10539   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10540   DONE;
10543 (define_insn "mshflo_l_di"
10544   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10545         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10546                         (const_int 4294967295))
10547                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10548                            (const_int 32))))]
10550   "TARGET_SHMEDIA"
10551   "mshflo.l     %N1, %N2, %0"
10552   [(set_attr "type" "arith_media")])
10554 (define_insn "*mshflo_l_di_rev"
10555   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10556         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10557                            (const_int 32))
10558                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10559                         (const_int 4294967295))))]
10561   "TARGET_SHMEDIA"
10562   "mshflo.l     %N2, %N1, %0"
10563   [(set_attr "type" "arith_media")])
10565 ;; Combiner pattern for trampoline initialization.
10566 (define_insn_and_split "*double_shori"
10567   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10568         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10569                            (const_int 32))
10570                 (match_operand:DI 2 "const_int_operand" "n")))]
10571   "TARGET_SHMEDIA
10572    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10573   "#"
10574   "rtx_equal_p (operands[0], operands[1])"
10575   [(const_int 0)]
10576   "
10578   HOST_WIDE_INT v = INTVAL (operands[2]);
10580   emit_insn (gen_shori_media (operands[0], operands[0],
10581              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10582   emit_insn (gen_shori_media (operands[0], operands[0],
10583                               gen_int_mode (v, HImode)));
10584   DONE;
10588 (define_insn "*mshflo_l_di_x"
10589   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10590         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10591                                  "rZ"))
10592                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10593                            (const_int 32))))]
10595   "TARGET_SHMEDIA"
10596   "mshflo.l     %N1, %N2, %0"
10597   [(set_attr "type" "arith_media")])
10599 (define_insn_and_split "concat_v2sf"
10600   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10601 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10602         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10603                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10605   "TARGET_SHMEDIA"
10606   "@
10607         mshflo.l        %N1, %N2, %0
10608         #
10609         #"
10610   "TARGET_SHMEDIA && reload_completed
10611    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10612   [(set (match_dup 3) (match_dup 1))
10613    (set (match_dup 4) (match_dup 2))]
10614   "
10616   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10617   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10619   [(set_attr "type" "arith_media")])
10621 (define_insn "*mshflo_l_di_x_rev"
10622   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10623         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10624                            (const_int 32))
10625                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10627   "TARGET_SHMEDIA"
10628   "mshflo.l     %N2, %N1, %0"
10629   [(set_attr "type" "arith_media")])
10631 (define_insn "ashlv2si3"
10632   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10633         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10634                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10635   "TARGET_SHMEDIA"
10636   "mshlld.l     %1, %2, %0"
10637   [(set_attr "type" "arith_media")])
10639 (define_insn "ashlv4hi3"
10640   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10641         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10642                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10643   "TARGET_SHMEDIA"
10644   "mshlld.w     %1, %2, %0"
10645   [(set_attr "type" "arith_media")])
10647 (define_insn "lshrv2si3"
10648   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10649         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10650                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10651   "TARGET_SHMEDIA"
10652   "mshlrd.l     %1, %2, %0"
10653   [(set_attr "type" "arith_media")])
10655 (define_insn "lshrv4hi3"
10656   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10657         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10658                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10659   "TARGET_SHMEDIA"
10660   "mshlrd.w     %1, %2, %0"
10661   [(set_attr "type" "arith_media")])
10663 (define_insn "subv2si3"
10664   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10665         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10666                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10667   "TARGET_SHMEDIA"
10668   "msub.l       %N1, %2, %0"
10669   [(set_attr "type" "arith_media")])
10671 (define_insn "subv4hi3"
10672   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10673         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10674                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10675   "TARGET_SHMEDIA"
10676   "msub.w       %N1, %2, %0"
10677   [(set_attr "type" "arith_media")])
10679 (define_insn "sssubv2si3"
10680   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10681         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10682                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10683   "TARGET_SHMEDIA"
10684   "msubs.l      %N1, %2, %0"
10685   [(set_attr "type" "mcmp_media")])
10687 (define_insn "ussubv8qi3"
10688   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10689         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10690                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10691   "TARGET_SHMEDIA"
10692   "msubs.ub     %1, %2, %0"
10693   [(set_attr "type" "mcmp_media")])
10695 (define_insn "sssubv4hi3"
10696   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10697         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10698                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10699   "TARGET_SHMEDIA"
10700   "msubs.w      %N1, %2, %0"
10701   [(set_attr "type" "mcmp_media")])
10703 ;; Floating Point Intrinsics
10705 (define_insn "fcosa_s"
10706   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10707         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10708                    UNSPEC_FCOSA))]
10709   "TARGET_SHMEDIA"
10710   "fcosa.s      %1, %0"
10711   [(set_attr "type" "atrans_media")])
10713 (define_insn "fsina_s"
10714   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10715         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10716                    UNSPEC_FSINA))]
10717   "TARGET_SHMEDIA"
10718   "fsina.s      %1, %0"
10719   [(set_attr "type" "atrans_media")])
10721 (define_insn "fipr"
10722   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10723         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10724                                                     "fp_arith_reg_operand" "f")
10725                                                    (match_operand:V4SF 2
10726                                                     "fp_arith_reg_operand" "f"))
10727                                          (parallel [(const_int 0)]))
10728                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10729                                          (parallel [(const_int 1)])))
10730                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10731                                          (parallel [(const_int 2)]))
10732                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10733                                          (parallel [(const_int 3)])))))]
10734   "TARGET_SHMEDIA"
10735   "fipr.s       %1, %2, %0"
10736   [(set_attr "type" "fparith_media")])
10738 (define_insn "fsrra_s"
10739   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10740         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10741                    UNSPEC_FSRRA))]
10742   "TARGET_SHMEDIA"
10743   "fsrra.s      %1, %0"
10744   [(set_attr "type" "atrans_media")])
10746 (define_insn "ftrv"
10747   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10748         (plus:V4SF
10749          (plus:V4SF
10750           (mult:V4SF
10751            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10752                             (parallel [(const_int 0) (const_int 5)
10753                                        (const_int 10) (const_int 15)]))
10754            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10755           (mult:V4SF
10756            (vec_select:V4SF (match_dup 1)
10757                             (parallel [(const_int 4) (const_int 9)
10758                                        (const_int 14) (const_int 3)]))
10759            (vec_select:V4SF (match_dup 2)
10760                             (parallel [(const_int 1) (const_int 2)
10761                                        (const_int 3) (const_int 0)]))))
10762          (plus:V4SF
10763           (mult:V4SF
10764            (vec_select:V4SF (match_dup 1)
10765                             (parallel [(const_int 8) (const_int 13)
10766                                        (const_int 2) (const_int 7)]))
10767            (vec_select:V4SF (match_dup 2)
10768                             (parallel [(const_int 2) (const_int 3)
10769                                        (const_int 0) (const_int 1)])))
10770           (mult:V4SF
10771            (vec_select:V4SF (match_dup 1)
10772                             (parallel [(const_int 12) (const_int 1)
10773                                        (const_int 6) (const_int 11)]))
10774            (vec_select:V4SF (match_dup 2)
10775                             (parallel [(const_int 3) (const_int 0)
10776                                        (const_int 1) (const_int 2)]))))))]
10777   "TARGET_SHMEDIA"
10778   "ftrv.s %1, %2, %0"
10779   [(set_attr "type" "fparith_media")])
10781 (define_insn "nsb"
10782   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10783         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10784                    UNSPEC_NSB))]
10785   "TARGET_SHMEDIA"
10786   "nsb  %1, %0"
10787   [(set_attr "type" "arith_media")])
10789 (define_insn "nsbsi"
10790   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10791         (zero_extend:SI
10792          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10793                     UNSPEC_NSB)))]
10794   "TARGET_SHMEDIA"
10795   "nsb  %1, %0"
10796   [(set_attr "type" "arith_media")])
10798 (define_insn "nsbdi"
10799   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10800         (zero_extend:DI
10801          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10802                     UNSPEC_NSB)))]
10803   "TARGET_SHMEDIA"
10804   "nsb  %1, %0"
10805   [(set_attr "type" "arith_media")])
10807 (define_expand "ffsdi2"
10808   [(set (match_operand:DI 0 "arith_reg_dest" "")
10809         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10810   "TARGET_SHMEDIA"
10811   "
10813   rtx scratch = gen_reg_rtx (DImode);
10814   rtx last;
10816   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10817   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10818   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10819   emit_insn (gen_nsbdi (scratch, scratch));
10820   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10821   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10822   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10823   REG_NOTES (last)
10824     = gen_rtx_EXPR_LIST (REG_EQUAL,
10825                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10826   DONE;
10829 (define_expand "ffssi2"
10830   [(set (match_operand:SI 0 "arith_reg_dest" "")
10831         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10832   "TARGET_SHMEDIA"
10833   "
10835   rtx scratch = gen_reg_rtx (SImode);
10836   rtx discratch = gen_reg_rtx (DImode);
10837   rtx last;
10839   emit_insn (gen_adddi3 (discratch,
10840                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10841                          constm1_rtx));
10842   emit_insn (gen_andcdi3 (discratch,
10843                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10844                           discratch));
10845   emit_insn (gen_nsbsi (scratch, discratch));
10846   last = emit_insn (gen_subsi3 (operands[0],
10847                                 force_reg (SImode, GEN_INT (63)), scratch));
10848   REG_NOTES (last)
10849     = gen_rtx_EXPR_LIST (REG_EQUAL,
10850                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10851   DONE;
10854 (define_insn "byterev"
10855   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10856         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10857                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10858                                     (const_int 4) (const_int 3) (const_int 2)
10859                                     (const_int 1) (const_int 0)])))]
10860   "TARGET_SHMEDIA"
10861   "byterev      %1, %0"
10862   [(set_attr "type" "arith_media")])
10864 (define_insn "prefetch"
10865   [(prefetch (match_operand:QI 0 "address_operand" "p")
10866              (match_operand:SI 1 "const_int_operand" "n")
10867              (match_operand:SI 2 "const_int_operand" "n"))]
10868   "TARGET_SHMEDIA || TARGET_HARD_SH4"
10869   "*
10871   if (TARGET_HARD_SH4)
10872     return \"pref @%0\";
10873   operands[0] = gen_rtx_MEM (QImode, operands[0]);
10874   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
10875   return \"\";
10877   [(set_attr "type" "other")])