Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / gcc4 / gcc / config / sh / sh.md
blob17b76e6b98a770cc3d9618850bb3b7587a1f8ef9
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
50 ;; Special formats used for outputting SH instructions:
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
60 ;; Special predicates:
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
82   (FPSCR_REG    151)
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
116   (XD0_REG      136)
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
146   (UNSPEC_DIV_INV_M0    30)
147   (UNSPEC_DIV_INV_M1    31)
148   (UNSPEC_DIV_INV_M2    32)
149   (UNSPEC_DIV_INV_M3    33)
150   (UNSPEC_DIV_INV20     34)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153   (UNSPEC_SP_SET        40)
154   (UNSPEC_SP_TEST       41)
156   ;; These are used with unspec_volatile.
157   (UNSPECV_BLOCKAGE     0)
158   (UNSPECV_ALIGN        1)
159   (UNSPECV_CONST2       2)
160   (UNSPECV_CONST4       4)
161   (UNSPECV_CONST8       6)
162   (UNSPECV_WINDOW_END   10)
163   (UNSPECV_CONST_END    11)
166 ;; -------------------------------------------------------------------------
167 ;; Attributes
168 ;; -------------------------------------------------------------------------
170 ;; Target CPU.
172 (define_attr "cpu"
173  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
174   (const (symbol_ref "sh_cpu_attr")))
176 (define_attr "endian" "big,little"
177  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
178                       (const_string "little") (const_string "big"))))
180 ;; Indicate if the default fpu mode is single precision.
181 (define_attr "fpu_single" "yes,no"
182   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
183                          (const_string "yes") (const_string "no"))))
185 (define_attr "fmovd" "yes,no"
186   (const (if_then_else (symbol_ref "TARGET_FMOVD")
187                        (const_string "yes") (const_string "no"))))
188 ;; pipeline model
189 (define_attr "pipe_model" "sh1,sh4,sh5media"
190   (const
191    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
192           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
193          (const_string "sh1"))))
195 ;; cbranch      conditional branch instructions
196 ;; jump         unconditional jumps
197 ;; arith        ordinary arithmetic
198 ;; arith3       a compound insn that behaves similarly to a sequence of
199 ;;              three insns of type arith
200 ;; arith3b      like above, but might end with a redirected branch
201 ;; load         from memory
202 ;; load_si      Likewise, SImode variant for general register.
203 ;; fload        Likewise, but load to fp register.
204 ;; store        to memory
205 ;; move         general purpose register to register
206 ;; mt_group     other sh4 mt instructions
207 ;; fmove        register to register, floating point
208 ;; smpy         word precision integer multiply
209 ;; dmpy         longword or doublelongword precision integer multiply
210 ;; return       rts
211 ;; pload        load of pr reg, which can't be put into delay slot of rts
212 ;; prset        copy register to pr reg, ditto
213 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
214 ;; prget        copy pr to register, ditto
215 ;; pcload       pc relative load of constant value
216 ;; pcfload      Likewise, but load to fp register.
217 ;; pcload_si    Likewise, SImode variant for general register.
218 ;; rte          return from exception
219 ;; sfunc        special function call with known used registers
220 ;; call         function call
221 ;; fp           floating point
222 ;; fdiv         floating point divide (or square root)
223 ;; gp_fpul      move from general purpose register to fpul
224 ;; fpul_gp      move from fpul to general purpose register
225 ;; mac_gp       move from mac[lh] to general purpose register
226 ;; dfp_arith, dfp_cmp,dfp_conv
227 ;; ftrc_s       fix_truncsfsi2_i4
228 ;; dfdiv        double precision floating point divide (or square root)
229 ;; cwb          ic_invalidate_line_i
230 ;; movua        SH4a unaligned load
231 ;; fsrra        square root reciprocal approximate
232 ;; fsca         sine and cosine approximate
233 ;; tls_load     load TLS related address
234 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
235 ;; cbranch_media SHmedia conditional branch instructions
236 ;; cmp_media    SHmedia compare instructions
237 ;; dfdiv_media  SHmedia double precision divide and square root
238 ;; dfmul_media  SHmedia double precision multiply instruction
239 ;; dfparith_media SHmedia double precision floating point arithmetic
240 ;; dfpconv_media SHmedia double precision floating point conversions
241 ;; dmpy_media   SHmedia longword multiply
242 ;; fcmp_media   SHmedia floating point compare instructions
243 ;; fdiv_media   SHmedia single precision divide and square root
244 ;; fload_media  SHmedia floating point register load instructions
245 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
246 ;; fparith_media SHmedia single precision floating point arithmetic
247 ;; fpconv_media SHmedia single precision floating point conversions
248 ;; fstore_media SHmedia floating point register store instructions
249 ;; gettr_media  SHmedia gettr instruction
250 ;; invalidate_line_media SHmedia invalidate_line sequence
251 ;; jump_media   SHmedia unconditional branch instructions
252 ;; load_media   SHmedia general register load instructions
253 ;; pt_media     SHmedia pt instruction (expanded by assembler)
254 ;; ptabs_media  SHmedia ptabs instruction
255 ;; store_media  SHmedia general register store instructions
256 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
257 ;; mac_media    SHmedia mac-style fixed point operations
258 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
259 ;; atrans_media SHmedia approximate transcendental functions
260 ;; ustore_media SHmedia unaligned stores
261 ;; nil          no-op move, will be deleted.
263 (define_attr "type"
264  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
265   (const_string "other"))
267 ;; We define a new attribute namely "insn_class".We use
268 ;; this for the DFA based pipeline description.
270 ;; mt_group      SH4 "mt" group instructions.
272 ;; ex_group      SH4 "ex" group instructions.
274 ;; ls_group      SH4 "ls" group instructions.
277 (define_attr "insn_class"
278   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
279   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
280          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
281          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
282          (eq_attr "type" "cbranch,jump") (const_string "br_group")
283          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
284            (const_string "fe_group")
285          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
286         (const_string "none")))
287 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
288 ;; so these do not belong in an insn group, although they are modeled
289 ;; with their own define_insn_reservations.
291 ;; Indicate what precision must be selected in fpscr for this insn, if any.
293 (define_attr "fp_mode" "single,double,none" (const_string "none"))
295 ;; Indicate if the fpu mode is set by this instruction
296 ;; "unknown" must have the value as "none" in fp_mode, and means
297 ;; that the instruction/abi has left the processor in an unknown
298 ;; state.
299 ;; "none" means that nothing has changed and no mode is set.
300 ;; This attribute is only used for the Renesas ABI.
301 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
303 ; If a conditional branch destination is within -252..258 bytes away
304 ; from the instruction it can be 2 bytes long.  Something in the
305 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
306 ; branches are initially assumed to be 16 bytes long.
307 ; In machine_dependent_reorg, we split all branches that are longer than
308 ; 2 bytes.
310 ;; The maximum range used for SImode constant pool entries is 1018.  A final
311 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
312 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
313 ;; instruction around the pool table, 2 bytes of alignment before the table,
314 ;; and 30 bytes of alignment after the table.  That gives a maximum total
315 ;; pool size of 1058 bytes.
316 ;; Worst case code/pool content size ratio is 1:2 (using asms).
317 ;; Thus, in the worst case, there is one instruction in front of a maximum
318 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
319 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
320 ;; If we have a forward branch, the initial table will be put after the
321 ;; unconditional branch.
323 ;; ??? We could do much better by keeping track of the actual pcloads within
324 ;; the branch range and in the pcload range in front of the branch range.
326 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
327 ;; inside an le.
328 (define_attr "short_cbranch_p" "no,yes"
329   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
330          (const_string "no")
331          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
332          (const_string "yes")
333          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
334          (const_string "no")
335          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
336          (const_string "yes")
337          ] (const_string "no")))
339 (define_attr "med_branch_p" "no,yes"
340   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
341               (const_int 1988))
342          (const_string "yes")
343          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
344          (const_string "no")
345          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
346               (const_int 8186))
347          (const_string "yes")
348          ] (const_string "no")))
350 (define_attr "med_cbranch_p" "no,yes"
351   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
352               (const_int 1986))
353          (const_string "yes")
354          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
355          (const_string "no")
356          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
357                (const_int 8184))
358          (const_string "yes")
359          ] (const_string "no")))
361 (define_attr "braf_branch_p" "no,yes"
362   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
363          (const_string "no")
364          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
365               (const_int 20660))
366          (const_string "yes")
367          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
368          (const_string "no")
369          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
370               (const_int 65530))
371          (const_string "yes")
372          ] (const_string "no")))
374 (define_attr "braf_cbranch_p" "no,yes"
375   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
376          (const_string "no")
377          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
378               (const_int 20658))
379          (const_string "yes")
380          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
381          (const_string "no")
382          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
383               (const_int 65528))
384          (const_string "yes")
385          ] (const_string "no")))
387 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
388 ; For wider ranges, we need a combination of a code and a data part.
389 ; If we can get a scratch register for a long range jump, the code
390 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
391 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
392 ; long; otherwise, it must be 6 bytes long.
394 ; All other instructions are two bytes long by default.
396 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
397 ;; but getattrtab doesn't understand this.
398 (define_attr "length" ""
399   (cond [(eq_attr "type" "cbranch")
400          (cond [(eq_attr "short_cbranch_p" "yes")
401                 (const_int 2)
402                 (eq_attr "med_cbranch_p" "yes")
403                 (const_int 6)
404                 (eq_attr "braf_cbranch_p" "yes")
405                 (const_int 12)
406 ;; ??? using pc is not computed transitively.
407                 (ne (match_dup 0) (match_dup 0))
408                 (const_int 14)
409                 (ne (symbol_ref ("flag_pic")) (const_int 0))
410                 (const_int 24)
411                 ] (const_int 16))
412          (eq_attr "type" "jump")
413          (cond [(eq_attr "med_branch_p" "yes")
414                 (const_int 2)
415                 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
416                          (const_int 0))
417                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
418                               (symbol_ref "INSN"))
419                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
420                               (symbol_ref "code_for_indirect_jump_scratch"))))
421                 (cond [(eq_attr "braf_branch_p" "yes")
422                        (const_int 6)
423                        (eq (symbol_ref "flag_pic") (const_int 0))
424                        (const_int 10)
425                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
426                        (const_int 10)] (const_int 18))
427                 (eq_attr "braf_branch_p" "yes")
428                 (const_int 10)
429 ;; ??? using pc is not computed transitively.
430                 (ne (match_dup 0) (match_dup 0))
431                 (const_int 12)
432                 (ne (symbol_ref ("flag_pic")) (const_int 0))
433                 (const_int 22)
434                 ] (const_int 14))
435          (eq_attr "type" "pt_media")
436          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
437                        (const_int 20) (const_int 12))
438          (and (eq_attr "type" "jump_media")
439               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
440          (const_int 8)
441          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
442                          (const_int 4)
443                          (const_int 2))))
445 ;; DFA descriptions for the pipelines
447 (include "sh1.md")
448 (include "shmedia.md")
449 (include "sh4.md")
451 (include "predicates.md")
453 ;; Definitions for filling delay slots
455 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
457 ;; ??? This should be (nil) instead of (const_int 0)
458 (define_attr "hit_stack" "yes,no"
459         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
460                    (const_int 0))
461                (const_string "no")]
462               (const_string "yes")))
464 (define_attr "interrupt_function" "no,yes"
465   (const (symbol_ref "current_function_interrupt")))
467 (define_attr "in_delay_slot" "yes,no"
468   (cond [(eq_attr "type" "cbranch") (const_string "no")
469          (eq_attr "type" "pcload,pcload_si") (const_string "no")
470          (eq_attr "needs_delay_slot" "yes") (const_string "no")
471          (eq_attr "length" "2") (const_string "yes")
472          ] (const_string "no")))
474 (define_attr "cond_delay_slot" "yes,no"
475   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
476          ] (const_string "no")))
478 (define_attr "is_sfunc" ""
479   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
481 (define_attr "is_mac_media" ""
482   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
484 (define_attr "branch_zero" "yes,no"
485   (cond [(eq_attr "type" "!cbranch") (const_string "no")
486          (ne (symbol_ref "(next_active_insn (insn)\
487                            == (prev_active_insn\
488                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
489                           && get_attr_length (next_active_insn (insn)) == 2")
490              (const_int 0))
491          (const_string "yes")]
492         (const_string "no")))
494 ;; SH4 Double-precision computation with double-precision result -
495 ;; the two halves are ready at different times.
496 (define_attr "dfp_comp" "yes,no"
497   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
498         (const_string "no")))
500 ;; Insns for which the latency of a preceding fp insn is decreased by one.
501 (define_attr "late_fp_use" "yes,no" (const_string "no"))
502 ;; And feeding insns for which this relevant.
503 (define_attr "any_fp_comp" "yes,no"
504   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
505          (const_string "yes")]
506         (const_string "no")))
508 (define_attr "any_int_load" "yes,no"
509   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
510          (const_string "yes")]
511         (const_string "no")))
513 (define_attr "highpart" "user, ignore, extend, depend, must_split"
514   (const_string "user"))
516 (define_delay
517   (eq_attr "needs_delay_slot" "yes")
518   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
520 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
521 ;; and thus we can't put a pop instruction in its delay slot.
522 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
523 ;; instruction can go in the delay slot.
525 ;; Since a normal return (rts) implicitly uses the PR register,
526 ;; we can't allow PR register loads in an rts delay slot.
528 (define_delay
529   (eq_attr "type" "return")
530   [(and (eq_attr "in_delay_slot" "yes")
531         (ior (and (eq_attr "interrupt_function" "no")
532                   (eq_attr "type" "!pload,prset"))
533              (and (eq_attr "interrupt_function" "yes")
534                   (ior
535                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
536                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
538 ;; Since a call implicitly uses the PR register, we can't allow
539 ;; a PR register store in a jsr delay slot.
541 (define_delay
542   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
543   [(and (eq_attr "in_delay_slot" "yes")
544         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
546 ;; Say that we have annulled true branches, since this gives smaller and
547 ;; faster code when branches are predicted as not taken.
549 ;; ??? The non-annulled condition should really be "in_delay_slot",
550 ;; but insns that can be filled in non-annulled get priority over insns
551 ;; that can only be filled in anulled.
553 (define_delay
554   (and (eq_attr "type" "cbranch")
555        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
556   ;; SH2e has a hardware bug that pretty much prohibits the use of
557   ;; annuled delay slots.
558   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
559                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
561 ;; -------------------------------------------------------------------------
562 ;; SImode signed integer comparisons
563 ;; -------------------------------------------------------------------------
565 (define_insn ""
566   [(set (reg:SI T_REG)
567         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
568                        (match_operand:SI 1 "arith_operand" "K08,r"))
569                (const_int 0)))]
570   "TARGET_SH1"
571   "tst  %1,%0"
572   [(set_attr "type" "mt_group")])
574 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
575 ;; That would still allow reload to create cmpi instructions, but would
576 ;; perhaps allow forcing the constant into a register when that is better.
577 ;; Probably should use r0 for mem/imm compares, but force constant into a
578 ;; register for pseudo/imm compares.
580 (define_insn "cmpeqsi_t"
581   [(set (reg:SI T_REG)
582         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
583                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
584   "TARGET_SH1"
585   "@
586         tst     %0,%0
587         cmp/eq  %1,%0
588         cmp/eq  %1,%0"
589    [(set_attr "type" "mt_group")])
591 (define_insn "cmpgtsi_t"
592   [(set (reg:SI T_REG)
593         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
594                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
595   "TARGET_SH1"
596   "@
597         cmp/gt  %1,%0
598         cmp/pl  %0"
599    [(set_attr "type" "mt_group")])
601 (define_insn "cmpgesi_t"
602   [(set (reg:SI T_REG)
603         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
604                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
605   "TARGET_SH1"
606   "@
607         cmp/ge  %1,%0
608         cmp/pz  %0"
609    [(set_attr "type" "mt_group")])
611 ;; -------------------------------------------------------------------------
612 ;; SImode unsigned integer comparisons
613 ;; -------------------------------------------------------------------------
615 (define_insn "cmpgeusi_t"
616   [(set (reg:SI T_REG)
617         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
618                 (match_operand:SI 1 "arith_reg_operand" "r")))]
619   "TARGET_SH1"
620   "cmp/hs       %1,%0"
621    [(set_attr "type" "mt_group")])
623 (define_insn "cmpgtusi_t"
624   [(set (reg:SI T_REG)
625         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
626                 (match_operand:SI 1 "arith_reg_operand" "r")))]
627   "TARGET_SH1"
628   "cmp/hi       %1,%0"
629    [(set_attr "type" "mt_group")])
631 ;; We save the compare operands in the cmpxx patterns and use them when
632 ;; we generate the branch.
634 (define_expand "cmpsi"
635   [(set (reg:SI T_REG)
636         (compare (match_operand:SI 0 "cmpsi_operand" "")
637                  (match_operand:SI 1 "arith_operand" "")))]
638   "TARGET_SH1 || TARGET_SHMEDIA"
639   "
641   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
642       && GET_CODE (operands[1]) != CONST_INT)
643     operands[0] = copy_to_mode_reg (SImode, operands[0]);
644   sh_compare_op0 = operands[0];
645   sh_compare_op1 = operands[1];
646   DONE;
649 ;; -------------------------------------------------------------------------
650 ;; DImode signed integer comparisons
651 ;; -------------------------------------------------------------------------
653 ;; ??? Could get better scheduling by splitting the initial test from the
654 ;; rest of the insn after reload.  However, the gain would hardly justify
655 ;; the sh.md size increase necessary to do that.
657 (define_insn ""
658   [(set (reg:SI T_REG)
659         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
660                        (match_operand:DI 1 "arith_operand" "r"))
661                (const_int 0)))]
662   "TARGET_SH1"
663   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
664                                  insn, operands);"
665   [(set_attr "length" "6")
666    (set_attr "type" "arith3b")])
668 (define_insn "cmpeqdi_t"
669   [(set (reg:SI T_REG)
670         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
671                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
672   "TARGET_SH1"
673   "@
674         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
675         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
676   [(set_attr "length" "6")
677    (set_attr "type" "arith3b")])
679 (define_split
680   [(set (reg:SI T_REG)
681         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
682                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
683 ;; If we applied this split when not optimizing, it would only be
684 ;; applied during the machine-dependent reorg, when no new basic blocks
685 ;; may be created.
686   "TARGET_SH1 && reload_completed && optimize"
687   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
688    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
689                            (label_ref (match_dup 6))
690                            (pc)))
691    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
692    (match_dup 6)]
693   "
695   operands[2]
696     = gen_rtx_REG (SImode,
697                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
698   operands[3]
699     = (operands[1] == const0_rtx
700        ? const0_rtx
701        : gen_rtx_REG (SImode,
702                       true_regnum (operands[1])
703                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
704   operands[4] = gen_lowpart (SImode, operands[0]);
705   operands[5] = gen_lowpart (SImode, operands[1]);
706   operands[6] = gen_label_rtx ();
709 (define_insn "cmpgtdi_t"
710   [(set (reg:SI T_REG)
711         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
712                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
713   "TARGET_SH2"
714   "@
715         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
716         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
717   [(set_attr "length" "8")
718    (set_attr "type" "arith3")])
720 (define_insn "cmpgedi_t"
721   [(set (reg:SI T_REG)
722         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
723                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
724   "TARGET_SH2"
725   "@
726         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
727         cmp/pz\\t%S0"
728   [(set_attr "length" "8,2")
729    (set_attr "type" "arith3,mt_group")])
731 ;; -------------------------------------------------------------------------
732 ;; DImode unsigned integer comparisons
733 ;; -------------------------------------------------------------------------
735 (define_insn "cmpgeudi_t"
736   [(set (reg:SI T_REG)
737         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
738                 (match_operand:DI 1 "arith_reg_operand" "r")))]
739   "TARGET_SH2"
740   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
741   [(set_attr "length" "8")
742    (set_attr "type" "arith3")])
744 (define_insn "cmpgtudi_t"
745   [(set (reg:SI T_REG)
746         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
747                 (match_operand:DI 1 "arith_reg_operand" "r")))]
748   "TARGET_SH2"
749   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
750   [(set_attr "length" "8")
751    (set_attr "type" "arith3")])
753 (define_insn "cmpeqsi_media"
754   [(set (match_operand:DI 0 "register_operand" "=r")
755         (eq:DI (match_operand:SI 1 "logical_operand" "%r")
756                (match_operand:SI 2 "cmp_operand" "Nr")))]
757   "TARGET_SHMEDIA"
758   "cmpeq        %1, %N2, %0"
759   [(set_attr "type" "cmp_media")])
761 (define_insn "cmpeqdi_media"
762   [(set (match_operand:DI 0 "register_operand" "=r")
763         (eq:DI (match_operand:DI 1 "register_operand" "%r")
764                (match_operand:DI 2 "cmp_operand" "Nr")))]
765   "TARGET_SHMEDIA"
766   "cmpeq        %1, %N2, %0"
767   [(set_attr "type" "cmp_media")])
769 (define_insn "cmpgtsi_media"
770   [(set (match_operand:DI 0 "register_operand" "=r")
771         (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
772                (match_operand:SI 2 "cmp_operand" "rN")))]
773   "TARGET_SHMEDIA"
774   "cmpgt        %N1, %N2, %0"
775   [(set_attr "type" "cmp_media")])
777 (define_insn "cmpgtdi_media"
778   [(set (match_operand:DI 0 "register_operand" "=r")
779         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
780                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
781   "TARGET_SHMEDIA"
782   "cmpgt        %N1, %N2, %0"
783   [(set_attr "type" "cmp_media")])
785 (define_insn "cmpgtusi_media"
786   [(set (match_operand:DI 0 "register_operand" "=r")
787         (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
788                 (match_operand:SI 2 "cmp_operand" "rN")))]
789   "TARGET_SHMEDIA"
790   "cmpgtu       %N1, %N2, %0"
791   [(set_attr "type" "cmp_media")])
793 (define_insn "cmpgtudi_media"
794   [(set (match_operand:DI 0 "register_operand" "=r")
795         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
796                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
797   "TARGET_SHMEDIA"
798   "cmpgtu       %N1, %N2, %0"
799   [(set_attr "type" "cmp_media")])
801 (define_insn "cmpsieqsi_media"
802   [(set (match_operand:SI 0 "register_operand" "=r")
803         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
804                (match_operand:SI 2 "cmp_operand" "Nr")))]
805   "TARGET_SHMEDIA"
806   "cmpeq        %1, %N2, %0"
807   [(set_attr "type" "cmp_media")])
809 (define_insn "cmpsieqdi_media"
810   [(set (match_operand:SI 0 "register_operand" "=r")
811         (eq:SI (match_operand:DI 1 "register_operand" "%r")
812                (match_operand:DI 2 "cmp_operand" "Nr")))]
813   "TARGET_SHMEDIA"
814   "cmpeq        %1, %N2, %0"
815   [(set_attr "type" "cmp_media")])
817 (define_insn "cmpsigtsi_media"
818   [(set (match_operand:SI 0 "register_operand" "=r")
819         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
820                (match_operand:SI 2 "cmp_operand" "rN")))]
821   "TARGET_SHMEDIA"
822   "cmpgt        %N1, %N2, %0"
823   [(set_attr "type" "cmp_media")])
825 (define_insn "cmpsigtdi_media"
826   [(set (match_operand:SI 0 "register_operand" "=r")
827         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
828                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
829   "TARGET_SHMEDIA"
830   "cmpgt        %N1, %N2, %0"
831   [(set_attr "type" "cmp_media")])
833 (define_insn "cmpsigtusi_media"
834   [(set (match_operand:SI 0 "register_operand" "=r")
835         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
836                 (match_operand:SI 2 "cmp_operand" "rN")))]
837   "TARGET_SHMEDIA"
838   "cmpgtu       %N1, %N2, %0"
839   [(set_attr "type" "cmp_media")])
841 (define_insn "cmpsigtudi_media"
842   [(set (match_operand:SI 0 "register_operand" "=r")
843         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
844                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
845   "TARGET_SHMEDIA"
846   "cmpgtu       %N1, %N2, %0"
847   [(set_attr "type" "cmp_media")])
849 ; These two patterns are for combine.
850 (define_insn "*cmpne0si_media"
851   [(set (match_operand:DI 0 "register_operand" "=r")
852         (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
853   "TARGET_SHMEDIA"
854   "cmpgtu       %1,r63,%0"
855   [(set_attr "type" "cmp_media")])
857 (define_insn "*cmpne0sisi_media"
858   [(set (match_operand:SI 0 "register_operand" "=r")
859         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
860   "TARGET_SHMEDIA"
861   "cmpgtu       %1,r63,%0"
862   [(set_attr "type" "cmp_media")])
864 ;; We save the compare operands in the cmpxx patterns and use them when
865 ;; we generate the branch.
867 (define_expand "cmpdi"
868   [(set (reg:SI T_REG)
869         (compare (match_operand:DI 0 "arith_operand" "")
870                  (match_operand:DI 1 "arith_operand" "")))]
871   "TARGET_SH2 || TARGET_SHMEDIA"
872   "
874   sh_compare_op0 = operands[0];
875   sh_compare_op1 = operands[1];
876   DONE;
878 ;; -------------------------------------------------------------------------
879 ;; Conditional move instructions
880 ;; -------------------------------------------------------------------------
882 ;; The insn names may seem reversed, but note that cmveq performs the move
883 ;; if op1 == 0, and cmvne does it if op1 != 0.
885 (define_insn "movdicc_false"
886   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
887         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
888                              (const_int 0))
889          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
890          (match_operand:DI 3 "arith_reg_operand" "0")))]
891   "TARGET_SHMEDIA"
892   "cmveq        %1, %N2, %0"
893   [(set_attr "type" "arith_media")])
895 (define_insn "movdicc_true"
896   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
897         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
898                              (const_int 0))
899          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
900          (match_operand:DI 3 "arith_reg_operand" "0")))]
901   "TARGET_SHMEDIA"
902   "cmvne        %1, %N2, %0"
903   [(set_attr "type" "arith_media")])
905 (define_peephole2
906   [(set (match_operand:DI 0 "arith_reg_dest" "")
907         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
908                            [(match_operand:DI 1 "arith_reg_operand" "")
909                             (const_int 0)])
910          (match_operand:DI 2 "arith_reg_dest" "")
911          (match_dup 0)))
912    (set (match_dup 2) (match_dup 0))]
913   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
914   [(set (match_dup 2)
915         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
916   "
918   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
919                                 VOIDmode, operands[1], CONST0_RTX (DImode));
922 (define_peephole2
923   [(set (match_operand:DI 0 "general_movdst_operand" "")
924         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
925    (set (match_operand:DI 2 "arith_reg_dest" "")
926         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
927                            [(match_operand:DI 3 "arith_reg_operand" "")
928                             (const_int 0)])
929          (match_dup 0)
930          (match_dup 2)))]
931   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
932   [(set (match_dup 2)
933         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
934   "")
936 (define_expand "movdicc"
937   [(set (match_operand:DI 0 "register_operand" "")
938         (if_then_else:DI (match_operand 1 "comparison_operator" "")
939                          (match_operand:DI 2 "register_operand" "")
940                          (match_operand:DI 3 "register_operand" "")))]
941   "TARGET_SHMEDIA"
942   "
944   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
945       && GET_MODE (sh_compare_op0) == DImode
946       && sh_compare_op1 == const0_rtx)
947     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
948                                   sh_compare_op0, sh_compare_op1);
949   else
950     {
951       rtx tmp;
953       if (no_new_pseudos)
954         FAIL;
956       tmp = gen_reg_rtx (DImode);
958       switch (GET_CODE (operands[1]))
959         {
960         case EQ:
961           emit_insn (gen_seq (tmp));
962           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
963           break;
965         case NE:
966           emit_insn (gen_seq (tmp));
967           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
968           break;
970         case GT:
971           emit_insn (gen_sgt (tmp));
972           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
973           break;
975         case LT:
976           emit_insn (gen_slt (tmp));
977           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
978           break;
980         case GE:
981           emit_insn (gen_slt (tmp));
982           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
983           break;
985         case LE:
986           emit_insn (gen_sgt (tmp));
987           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
988           break;
990         case GTU:
991           emit_insn (gen_sgtu (tmp));
992           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
993           break;
995         case LTU:
996           emit_insn (gen_sltu (tmp));
997           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
998           break;
1000         case GEU:
1001           emit_insn (gen_sltu (tmp));
1002           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1003           break;
1005         case LEU:
1006           emit_insn (gen_sgtu (tmp));
1007           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1008           break;
1010         case UNORDERED:
1011           emit_insn (gen_sunordered (tmp));
1012           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1013           break;
1015         case ORDERED:
1016           emit_insn (gen_sunordered (tmp));
1017           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1018           break;
1020         case UNEQ:
1021         case UNGE:
1022         case UNGT:
1023         case UNLE:
1024         case UNLT:
1025         case LTGT:
1026           FAIL;
1028         default:
1029           gcc_unreachable ();
1030         }
1031     }
1034 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1035 ;; SImode to DImode.
1036 (define_insn "movsicc_false"
1037   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1038         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1039                           (const_int 0))
1040          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1041          (match_operand:SI 3 "arith_reg_operand" "0")))]
1042   "TARGET_SHMEDIA"
1043   "cmveq        %1, %N2, %0"
1044   [(set_attr "type" "arith_media")])
1046 (define_insn "movsicc_true"
1047   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1048         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1049                           (const_int 0))
1050          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1051          (match_operand:SI 3 "arith_reg_operand" "0")))]
1052   "TARGET_SHMEDIA"
1053   "cmvne        %1, %N2, %0"
1054   [(set_attr "type" "arith_media")])
1056 (define_peephole2
1057   [(set (match_operand:SI 0 "arith_reg_dest" "")
1058         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1059                            [(match_operand:SI 1 "arith_reg_operand" "")
1060                             (const_int 0)])
1061          (match_operand:SI 2 "arith_reg_dest" "")
1062          (match_dup 0)))
1063    (set (match_dup 2) (match_dup 0))]
1064   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1065   [(set (match_dup 2)
1066         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1067   "
1069   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1070                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1073 (define_peephole2
1074   [(set (match_operand:SI 0 "general_movdst_operand" "")
1075         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1076    (set (match_operand:SI 2 "arith_reg_dest" "")
1077         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1078                            [(match_operand:SI 3 "arith_reg_operand" "")
1079                             (const_int 0)])
1080          (match_dup 0)
1081          (match_dup 2)))]
1082   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1083    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1084   [(set (match_dup 2)
1085         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1086   "
1088   replace_rtx (operands[4], operands[0], operands[1]);
1091 (define_peephole2
1092   [(set (match_operand 0 "any_register_operand" "")
1093         (match_operand 1 "any_register_operand" ""))
1094    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1095    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1096   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1097     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1098    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1099    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1100    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1101    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1102    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1103    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1104    && (REGNO_REG_CLASS (REGNO (operands[0]))
1105        == REGNO_REG_CLASS (REGNO (operands[2])))
1106    && (REGNO_REG_CLASS (REGNO (operands[1]))
1107        == REGNO_REG_CLASS (REGNO (operands[0])))"
1108   [(set (match_dup 0) (match_dup 3))
1109    (set (match_dup 4) (match_dup 5))]
1110   "
1112   rtx set1, set2;
1113   rtx replacements[4];
1115   /* We want to replace occurrences of operands[0] with operands[1] and
1116      operands[2] with operands[0] in operands[4]/operands[5].
1117      Doing just two replace_rtx calls naively would result in the second
1118      replacement undoing all that the first did if operands[1] and operands[2]
1119      are identical, so we must do this simultaneously.  */
1120   replacements[0] = operands[0];
1121   replacements[1] = operands[1];
1122   replacements[2] = operands[2];
1123   replacements[3] = operands[0];
1124   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1125       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1126       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1127     FAIL;
1129   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1130   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1131   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1132   /* The operands array is aliased to recog_data.operand, which gets
1133      clobbered by extract_insn, so finish with it now.  */
1134   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1135   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1136   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1137      always uses emit_insn.  */
1138   /* Check that we don't violate matching constraints or earlyclobbers.  */
1139   extract_insn (emit_insn (set1));
1140   if (! constrain_operands (1))
1141     goto failure;
1142   extract_insn (emit (set2));
1143   if (! constrain_operands (1))
1144     {
1145       rtx tmp;
1146     failure:
1147       tmp = replacements[0];
1148       replacements[0] = replacements[1];
1149       replacements[1] = tmp;
1150       tmp = replacements[2];
1151       replacements[2] = replacements[3];
1152       replacements[3] = tmp;
1153       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1154       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1155       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1156       FAIL;
1157     }
1158   DONE;
1161 ;; The register allocator is rather clumsy in handling multi-way conditional
1162 ;; moves, so allow the combiner to make them, and we split them up after
1163 ;; reload.  */
1164 (define_insn_and_split "*movsicc_umin"
1165   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1166         (umin:SI (if_then_else:SI
1167                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1168                        (const_int 0))
1169                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1170                    (match_operand:SI 3 "register_operand" "0"))
1171                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1172    (clobber (match_scratch:SI 5 "=&r"))]
1173   "TARGET_SHMEDIA && no_new_pseudos"
1174   "#"
1175   "TARGET_SHMEDIA && reload_completed"
1176   [(pc)]
1177   "
1179   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1180                                 operands[3]));
1181   emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1182   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1183                                 operands[0]));
1184   DONE;
1187 (define_expand "movsicc"
1188   [(set (match_operand:SI 0 "register_operand" "")
1189         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1190                          (match_operand:SI 2 "register_operand" "")
1191                          (match_operand:SI 3 "register_operand" "")))]
1192   "TARGET_SHMEDIA"
1193   "
1195   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1196       && GET_MODE (sh_compare_op0) == SImode
1197       && sh_compare_op1 == const0_rtx)
1198     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1199                                   sh_compare_op0, sh_compare_op1);
1200   else
1201     {
1202       rtx tmp;
1204       if (no_new_pseudos)
1205         FAIL;
1207       tmp = gen_reg_rtx (SImode);
1209       switch (GET_CODE (operands[1]))
1210         {
1211         case EQ:
1212           emit_insn (gen_seq (tmp));
1213           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1214           break;
1216         case NE:
1217           emit_insn (gen_seq (tmp));
1218           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1219           break;
1221         case GT:
1222           emit_insn (gen_sgt (tmp));
1223           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1224           break;
1226         case LT:
1227           emit_insn (gen_slt (tmp));
1228           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1229           break;
1231         case GE:
1232           emit_insn (gen_slt (tmp));
1233           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1234           break;
1236         case LE:
1237           emit_insn (gen_sgt (tmp));
1238           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1239           break;
1241         case GTU:
1242           emit_insn (gen_sgtu (tmp));
1243           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1244           break;
1246         case LTU:
1247           emit_insn (gen_sltu (tmp));
1248           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1249           break;
1251         case GEU:
1252           emit_insn (gen_sltu (tmp));
1253           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1254           break;
1256         case LEU:
1257           emit_insn (gen_sgtu (tmp));
1258           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1259           break;
1261         case UNORDERED:
1262           emit_insn (gen_sunordered (tmp));
1263           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1264           break;
1266         case ORDERED:
1267           emit_insn (gen_sunordered (tmp));
1268           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1269           break;
1271         case UNEQ:
1272         case UNGE:
1273         case UNGT:
1274         case UNLE:
1275         case UNLT:
1276         case LTGT:
1277           FAIL;
1279         default:
1280           abort ();
1281         }
1282     }
1285 (define_expand "movqicc"
1286   [(set (match_operand:QI 0 "register_operand" "")
1287         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1288                          (match_operand:QI 2 "register_operand" "")
1289                          (match_operand:QI 3 "register_operand" "")))]
1290   "TARGET_SHMEDIA"
1291   "
1293   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1294   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1295   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1296   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1297   DONE;
1300 ;; -------------------------------------------------------------------------
1301 ;; Addition instructions
1302 ;; -------------------------------------------------------------------------
1304 (define_expand "adddi3"
1305   [(set (match_operand:DI 0 "arith_reg_operand" "")
1306         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1307                  (match_operand:DI 2 "arith_operand" "")))]
1308   ""
1309   "
1311   if (TARGET_SH1)
1312     {
1313       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1314         FAIL;
1315       operands[2] = force_reg (DImode, operands[2]);
1316       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1317       DONE;
1318     }
1321 (define_insn "*adddi3_media"
1322   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1323         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1324                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1325   "TARGET_SHMEDIA"
1326   "@
1327         add     %1, %2, %0
1328         addi    %1, %2, %0"
1329   [(set_attr "type" "arith_media")])
1331 (define_insn "*adddisi3_media"
1332   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1333         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1334                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1335   "TARGET_SHMEDIA"
1336   "@
1337         add.l   %1, %2, %0
1338         addi.l  %1, %2, %0"
1339   [(set_attr "type" "arith_media")
1340    (set_attr "highpart" "ignore")])
1342 (define_insn "adddi3z_media"
1343   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1344         (zero_extend:DI
1345          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1346                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1347   "TARGET_SHMEDIA"
1348   "addz.l       %1, %N2, %0"
1349   [(set_attr "type" "arith_media")
1350    (set_attr "highpart" "ignore")])
1352 (define_insn "adddi3_compact"
1353   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1354         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1355                  (match_operand:DI 2 "arith_reg_operand" "r")))
1356    (clobber (reg:SI T_REG))]
1357   "TARGET_SH1"
1358   "#"
1359   [(set_attr "length" "6")])
1361 (define_split
1362   [(set (match_operand:DI 0 "arith_reg_dest" "")
1363         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1364                  (match_operand:DI 2 "arith_reg_operand" "")))
1365    (clobber (reg:SI T_REG))]
1366   "TARGET_SH1 && reload_completed"
1367   [(const_int 0)]
1368   "
1370   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1371   high0 = gen_rtx_REG (SImode,
1372                        true_regnum (operands[0])
1373                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1374   high2 = gen_rtx_REG (SImode,
1375                        true_regnum (operands[2])
1376                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1377   emit_insn (gen_clrt ());
1378   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1379   emit_insn (gen_addc1 (high0, high0, high2));
1380   DONE;
1383 (define_insn "addc"
1384   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1385         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1386                           (match_operand:SI 2 "arith_reg_operand" "r"))
1387                  (reg:SI T_REG)))
1388    (set (reg:SI T_REG)
1389         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1390   "TARGET_SH1"
1391   "addc %2,%0"
1392   [(set_attr "type" "arith")])
1394 (define_insn "addc1"
1395   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1396         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1397                           (match_operand:SI 2 "arith_reg_operand" "r"))
1398                  (reg:SI T_REG)))
1399    (clobber (reg:SI T_REG))]
1400   "TARGET_SH1"
1401   "addc %2,%0"
1402   [(set_attr "type" "arith")])
1404 (define_expand "addsi3"
1405   [(set (match_operand:SI 0 "arith_reg_operand" "")
1406         (plus:SI (match_operand:SI 1 "arith_operand" "")
1407                  (match_operand:SI 2 "arith_operand" "")))]
1408   ""
1409   "
1411   if (TARGET_SHMEDIA)
1412     operands[1] = force_reg (SImode, operands[1]);
1415 (define_insn "addsi3_media"
1416   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1417         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1418                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1419   "TARGET_SHMEDIA"
1420   "@
1421         add.l   %1, %2, %0
1422         addi.l  %1, %2, %0"
1423   [(set_attr "type" "arith_media")
1424    (set_attr "highpart" "ignore")])
1426 (define_insn "addsidi3_media"
1427   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1428         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1429                                   "%r,r")
1430                                  (match_operand:SI 2 "arith_operand"
1431                                   "r,I10"))))]
1432   "TARGET_SHMEDIA"
1433   "@
1434         add.l   %1, %2, %0
1435         addi.l  %1, %2, %0"
1436   [(set_attr "type" "arith_media")
1437    (set_attr "highpart" "ignore")])
1439 (define_insn "*addsi3_compact"
1440   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1441         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1442                  (match_operand:SI 2 "arith_operand" "rI08")))]
1443   "TARGET_SH1"
1444   "add  %2,%0"
1445   [(set_attr "type" "arith")])
1447 ;; -------------------------------------------------------------------------
1448 ;; Subtraction instructions
1449 ;; -------------------------------------------------------------------------
1451 (define_expand "subdi3"
1452   [(set (match_operand:DI 0 "arith_reg_operand" "")
1453         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1454                   (match_operand:DI 2 "arith_reg_operand" "")))]
1455   ""
1456   "
1458   if (TARGET_SH1)
1459     {
1460       operands[1] = force_reg (DImode, operands[1]);
1461       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1462       DONE;
1463     }
1466 (define_insn "*subdi3_media"
1467   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1468         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1469                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1470   "TARGET_SHMEDIA"
1471   "sub  %N1, %2, %0"
1472   [(set_attr "type" "arith_media")])
1473   
1474 (define_insn "subdisi3_media"
1475   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1476         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1477                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1478   "TARGET_SHMEDIA"
1479   "sub.l        %N1, %2, %0"
1480   [(set_attr "type" "arith_media")
1481    (set_attr "highpart" "ignore")])
1483 (define_insn "subdi3_compact"
1484   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1485         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1486                  (match_operand:DI 2 "arith_reg_operand" "r")))
1487    (clobber (reg:SI T_REG))]
1488   "TARGET_SH1"
1489   "#"
1490   [(set_attr "length" "6")])
1492 (define_split
1493   [(set (match_operand:DI 0 "arith_reg_dest" "")
1494         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1495                   (match_operand:DI 2 "arith_reg_operand" "")))
1496    (clobber (reg:SI T_REG))]
1497   "TARGET_SH1 && reload_completed"
1498   [(const_int 0)]
1499   "
1501   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1502   high0 = gen_rtx_REG (SImode,
1503                        true_regnum (operands[0])
1504                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1505   high2 = gen_rtx_REG (SImode,
1506                        true_regnum (operands[2])
1507                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1508   emit_insn (gen_clrt ());
1509   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1510   emit_insn (gen_subc1 (high0, high0, high2));
1511   DONE;
1514 (define_insn "subc"
1515   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1516         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1517                             (match_operand:SI 2 "arith_reg_operand" "r"))
1518                   (reg:SI T_REG)))
1519    (set (reg:SI T_REG)
1520         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1521                           (reg:SI T_REG))
1522                 (match_dup 1)))]
1523   "TARGET_SH1"
1524   "subc %2,%0"
1525   [(set_attr "type" "arith")])
1527 (define_insn "subc1"
1528   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1529         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1530                             (match_operand:SI 2 "arith_reg_operand" "r"))
1531                   (reg:SI T_REG)))
1532    (clobber (reg:SI T_REG))]
1533   "TARGET_SH1"
1534   "subc %2,%0"
1535   [(set_attr "type" "arith")])
1537 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1538 ;; pattern for this case.  This helps multimedia applications that compute
1539 ;; the sum of absolute differences.
1540 (define_insn "mov_neg_si_t"
1541   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1542   "TARGET_SH1"
1543   "subc %0,%0"
1544   [(set_attr "type" "arith")])
1546 (define_insn "*subsi3_internal"
1547   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1548         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1549                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1550   "TARGET_SH1"
1551   "sub  %2,%0"
1552   [(set_attr "type" "arith")])
1554 (define_insn_and_split "*subsi3_media"
1555   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1556         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1557                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1558   "TARGET_SHMEDIA
1559    && (operands[1] != constm1_rtx
1560        || (GET_CODE (operands[2]) != TRUNCATE
1561            && GET_CODE (operands[2]) != SUBREG))"
1562   "sub.l        %N1, %2, %0"
1563   "operands[1] == constm1_rtx"
1564   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1565   ""
1566   [(set_attr "type" "arith_media")
1567    (set_attr "highpart" "ignore")])
1569 (define_split
1570   [(set (match_operand:SI 0 "arith_reg_dest" "")
1571         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1572                                                        "general_extend_operand"
1573                                                        "") 0)) 0)))]
1574   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1575   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1576    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1577   "")
1579 (define_split
1580   [(set (match_operand:SI 0 "arith_reg_dest" "")
1581         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1582                                                        "general_extend_operand"
1583                                                        "") 0)) 3)))]
1584   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1585   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1586    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1587   "")
1588 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1589 ;; will sometimes save one instruction.  Otherwise we might get
1590 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1591 ;; are the same.
1593 (define_expand "subsi3"
1594   [(set (match_operand:SI 0 "arith_reg_operand" "")
1595         (minus:SI (match_operand:SI 1 "arith_operand" "")
1596                   (match_operand:SI 2 "arith_reg_operand" "")))]
1597   ""
1598   "
1600   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1601     {
1602       emit_insn (gen_negsi2 (operands[0], operands[2]));
1603       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1604       DONE;
1605     }
1606   if (TARGET_SHMEDIA)
1607     {
1608       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1609         FAIL;
1610       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1611         operands[1] = force_reg (SImode, operands[1]);
1612     }
1615 ;; -------------------------------------------------------------------------
1616 ;; Division instructions
1617 ;; -------------------------------------------------------------------------
1619 ;; We take advantage of the library routines which don't clobber as many
1620 ;; registers as a normal function call would.
1622 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1623 ;; also has an effect on the register that holds the address of the sfunc.
1624 ;; To make this work, we have an extra dummy insn that shows the use
1625 ;; of this register for reorg.
1627 (define_insn "use_sfunc_addr"
1628   [(set (reg:SI PR_REG)
1629         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1630   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1631   ""
1632   [(set_attr "length" "0")])
1634 (define_insn "udivsi3_sh2a"
1635   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1636         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1637                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1638   "TARGET_SH2A"
1639   "divu %2,%1"
1640   [(set_attr "type" "arith")
1641    (set_attr "in_delay_slot" "no")])
1643 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1644 ;; hard register 0.  If we used hard register 0, then the next instruction
1645 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1646 ;; gets allocated to a stack slot that needs its address reloaded, then
1647 ;; there is nothing to prevent reload from using r0 to reload the address.
1648 ;; This reload would clobber the value in r0 we are trying to store.
1649 ;; If we let reload allocate r0, then this problem can never happen.
1651 (define_insn "udivsi3_i1"
1652   [(set (match_operand:SI 0 "register_operand" "=z")
1653         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1654    (clobber (reg:SI T_REG))
1655    (clobber (reg:SI PR_REG))
1656    (clobber (reg:SI R4_REG))
1657    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1658   "TARGET_SH1 && ! TARGET_SH4"
1659   "jsr  @%1%#"
1660   [(set_attr "type" "sfunc")
1661    (set_attr "needs_delay_slot" "yes")])
1663 ; Since shmedia-nofpu code could be linked against shcompact code, and
1664 ; the udivsi3 libcall has the same name, we must consider all registers
1665 ; clobbered that are in the union of the registers clobbered by the
1666 ; shmedia and the shcompact implementation.  Note, if the shcompact
1667 ; implementation actually used shcompact code, we'd need to clobber
1668 ; also r23 and fr23.
1669 (define_insn "udivsi3_i1_media"
1670   [(set (match_operand:SI 0 "register_operand" "=z")
1671         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1672    (clobber (reg:SI T_MEDIA_REG))
1673    (clobber (reg:SI PR_MEDIA_REG))
1674    (clobber (reg:SI R20_REG))
1675    (clobber (reg:SI R21_REG))
1676    (clobber (reg:SI R22_REG))
1677    (clobber (reg:DI TR0_REG))
1678    (clobber (reg:DI TR1_REG))
1679    (clobber (reg:DI TR2_REG))
1680    (use (match_operand 1 "target_reg_operand" "b"))]
1681   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1682   "blink        %1, r18"
1683   [(set_attr "type" "sfunc")
1684    (set_attr "needs_delay_slot" "yes")])
1686 (define_expand "udivsi3_i4_media"
1687   [(set (match_dup 3)
1688         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1689    (set (match_dup 4)
1690         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1691    (set (match_dup 5) (float:DF (match_dup 3)))
1692    (set (match_dup 6) (float:DF (match_dup 4)))
1693    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1694    (set (match_dup 8) (fix:DI (match_dup 7)))
1695    (set (match_operand:SI 0 "register_operand" "")
1696         (truncate:SI (match_dup 8)))]
1697   "TARGET_SHMEDIA_FPU"
1698   "
1700   operands[3] = gen_reg_rtx (DImode);
1701   operands[4] = gen_reg_rtx (DImode);
1702   operands[5] = gen_reg_rtx (DFmode);
1703   operands[6] = gen_reg_rtx (DFmode);
1704   operands[7] = gen_reg_rtx (DFmode);
1705   operands[8] = gen_reg_rtx (DImode);
1708 (define_insn "udivsi3_i4"
1709   [(set (match_operand:SI 0 "register_operand" "=y")
1710         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1711    (clobber (reg:SI T_REG))
1712    (clobber (reg:SI PR_REG))
1713    (clobber (reg:DF DR0_REG))
1714    (clobber (reg:DF DR2_REG))
1715    (clobber (reg:DF DR4_REG))
1716    (clobber (reg:SI R0_REG))
1717    (clobber (reg:SI R1_REG))
1718    (clobber (reg:SI R4_REG))
1719    (clobber (reg:SI R5_REG))
1720    (use (reg:PSI FPSCR_REG))
1721    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1722   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1723   "jsr  @%1%#"
1724   [(set_attr "type" "sfunc")
1725    (set_attr "fp_mode" "double")
1726    (set_attr "needs_delay_slot" "yes")])
1728 (define_insn "udivsi3_i4_single"
1729   [(set (match_operand:SI 0 "register_operand" "=y")
1730         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1731    (clobber (reg:SI T_REG))
1732    (clobber (reg:SI PR_REG))
1733    (clobber (reg:DF DR0_REG))
1734    (clobber (reg:DF DR2_REG))
1735    (clobber (reg:DF DR4_REG))
1736    (clobber (reg:SI R0_REG))
1737    (clobber (reg:SI R1_REG))
1738    (clobber (reg:SI R4_REG))
1739    (clobber (reg:SI R5_REG))
1740    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1741   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1742   "jsr  @%1%#"
1743   [(set_attr "type" "sfunc")
1744    (set_attr "needs_delay_slot" "yes")])
1746 (define_expand "udivsi3"
1747   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1748    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1749    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1750    (parallel [(set (match_operand:SI 0 "register_operand" "")
1751                    (udiv:SI (reg:SI R4_REG)
1752                             (reg:SI R5_REG)))
1753               (clobber (reg:SI T_REG))
1754               (clobber (reg:SI PR_REG))
1755               (clobber (reg:SI R4_REG))
1756               (use (match_dup 3))])]
1757   ""
1758   "
1760   rtx first, last;
1762   operands[3] = gen_reg_rtx (Pmode);
1763   /* Emit the move of the address to a pseudo outside of the libcall.  */
1764   if (TARGET_HARD_SH4 && TARGET_SH2E)
1765     {
1766       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1767       if (TARGET_FPU_SINGLE)
1768         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1769       else
1770         last = gen_udivsi3_i4 (operands[0], operands[3]);
1771     }
1772   else if (TARGET_SHMEDIA_FPU)
1773     {
1774       operands[1] = force_reg (SImode, operands[1]);
1775       operands[2] = force_reg (SImode, operands[2]);
1776       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1777       DONE;
1778     }
1779   else if (TARGET_SH2A)
1780     {
1781       operands[1] = force_reg (SImode, operands[1]);
1782       operands[2] = force_reg (SImode, operands[2]);
1783       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1784       DONE;
1785     }
1786   else if (TARGET_SH5)
1787     {
1788       function_symbol (operands[3],
1789                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1790                        SFUNC_STATIC);
1792       if (TARGET_SHMEDIA)
1793         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1794       else if (TARGET_FPU_ANY)
1795         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1796       else
1797         last = gen_udivsi3_i1 (operands[0], operands[3]);
1798     }
1799   else
1800     {
1801       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1802       last = gen_udivsi3_i1 (operands[0], operands[3]);
1803     }
1804   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1805   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1806   last = emit_insn (last);
1807   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1808      invariant code motion can move it.  */
1809   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1810   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1811   DONE;
1814 (define_insn "divsi3_sh2a"
1815   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1816         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1817                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1818   "TARGET_SH2A"
1819   "divs %2,%1"
1820   [(set_attr "type" "arith")
1821    (set_attr "in_delay_slot" "no")])
1823 (define_insn "divsi3_i1"
1824   [(set (match_operand:SI 0 "register_operand" "=z")
1825         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1826    (clobber (reg:SI T_REG))
1827    (clobber (reg:SI PR_REG))
1828    (clobber (reg:SI R1_REG))
1829    (clobber (reg:SI R2_REG))
1830    (clobber (reg:SI R3_REG))
1831    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1832   "TARGET_SH1 && ! TARGET_SH4"
1833   "jsr  @%1%#"
1834   [(set_attr "type" "sfunc")
1835    (set_attr "needs_delay_slot" "yes")])
1837 (define_insn "divsi3_i1_media"
1838   [(set (match_operand:SI 0 "register_operand" "=z")
1839         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1840    (clobber (reg:SI T_MEDIA_REG))
1841    (clobber (reg:SI PR_MEDIA_REG))
1842    (clobber (reg:SI R1_REG))
1843    (clobber (reg:SI R20_REG))
1844    (clobber (reg:SI R21_REG))
1845    (clobber (reg:SI TR0_REG))
1846    (use (match_operand 1 "target_reg_operand" "b"))]
1847   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1848   "blink        %1, r18"
1849   [(set_attr "type" "sfunc")])
1851 (define_insn "divsi3_media_2"
1852   [(set (match_operand:SI 0 "register_operand" "=z")
1853         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1854    (clobber (reg:SI T_MEDIA_REG))
1855    (clobber (reg:SI PR_MEDIA_REG))
1856    (clobber (reg:SI R1_REG))
1857    (clobber (reg:SI R21_REG))
1858    (clobber (reg:SI TR0_REG))
1859    (use (reg:SI R20_REG))
1860    (use (match_operand 1 "target_reg_operand" "b"))]
1861   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1862   "blink        %1, r18"
1863   [(set_attr "type" "sfunc")])
1865 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1866 ;; hard reg clobbers and data dependencies that we need when we want
1867 ;; to rematerialize the division into a call.
1868 (define_insn_and_split "divsi_inv_call"
1869   [(set (match_operand:SI 0 "register_operand" "=r")
1870         (div:SI (match_operand:SI 1 "register_operand" "r")
1871                 (match_operand:SI 2 "register_operand" "r")))
1872    (clobber (reg:SI R4_REG))
1873    (clobber (reg:SI R5_REG))
1874    (clobber (reg:SI T_MEDIA_REG))
1875    (clobber (reg:SI PR_MEDIA_REG))
1876    (clobber (reg:SI R1_REG))
1877    (clobber (reg:SI R21_REG))
1878    (clobber (reg:SI TR0_REG))
1879    (clobber (reg:SI R20_REG))
1880    (use (match_operand:SI 3 "register_operand" "r"))]
1881   "TARGET_SHMEDIA"
1882   "#"
1883   "&& (high_life_started || reload_completed)"
1884   [(set (match_dup 0) (match_dup 3))]
1885   ""
1886   [(set_attr "highpart" "must_split")])
1888 ;; This is the combiner pattern for -mdiv=inv:call .
1889 (define_insn_and_split "*divsi_inv_call_combine"
1890   [(set (match_operand:SI 0 "register_operand" "=z")
1891         (div:SI (match_operand:SI 1 "register_operand" "r")
1892                 (match_operand:SI 2 "register_operand" "r")))
1893    (clobber (reg:SI R4_REG))
1894    (clobber (reg:SI R5_REG))
1895    (clobber (reg:SI T_MEDIA_REG))
1896    (clobber (reg:SI PR_MEDIA_REG))
1897    (clobber (reg:SI R1_REG))
1898    (clobber (reg:SI R21_REG))
1899    (clobber (reg:SI TR0_REG))
1900    (clobber (reg:SI R20_REG))
1901    (use (unspec:SI [(match_dup 1)
1902                     (match_operand:SI 3 "" "")
1903                     (unspec:SI [(match_operand:SI 4 "" "")
1904                                 (match_dup 3)
1905                                 (match_operand:DI 5 "" "")]
1906                      UNSPEC_DIV_INV_M2)
1907                     (match_operand:DI 6 "" "")
1908                     (const_int 0)
1909                     (const_int 0)]
1910          UNSPEC_DIV_INV_M3))]
1911   "TARGET_SHMEDIA"
1912   "#"
1913   "&& (high_life_started || reload_completed)"
1914   [(pc)]
1915   "
1917   const char *name = sh_divsi3_libfunc;
1918   enum sh_function_kind kind = SFUNC_GOT;
1919   rtx sym;
1921   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1922   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1923   while (TARGET_DIVIDE_INV_CALL2)
1924     {
1925       rtx x = operands[3];
1927       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1928         break;
1929       x = XVECEXP (x, 0, 0);
1930       name = \"__sdivsi3_2\";
1931       kind = SFUNC_STATIC;
1932       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1933       break;
1934     }
1935   sym = function_symbol (NULL, name, kind);
1936   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1937   DONE;
1939   [(set_attr "highpart" "must_split")])
1941 (define_expand "divsi3_i4_media"
1942   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1943    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1944    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1945    (set (match_operand:SI 0 "register_operand" "=r")
1946         (fix:SI (match_dup 5)))]
1947   "TARGET_SHMEDIA_FPU"
1948   "
1950   operands[3] = gen_reg_rtx (DFmode);
1951   operands[4] = gen_reg_rtx (DFmode);
1952   operands[5] = gen_reg_rtx (DFmode);
1955 (define_insn "divsi3_i4"
1956   [(set (match_operand:SI 0 "register_operand" "=y")
1957         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1958    (clobber (reg:SI PR_REG))
1959    (clobber (reg:DF DR0_REG))
1960    (clobber (reg:DF DR2_REG))
1961    (use (reg:PSI FPSCR_REG))
1962    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1963   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1964   "jsr  @%1%#"
1965   [(set_attr "type" "sfunc")
1966    (set_attr "fp_mode" "double")
1967    (set_attr "needs_delay_slot" "yes")])
1969 (define_insn "divsi3_i4_single"
1970   [(set (match_operand:SI 0 "register_operand" "=y")
1971         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1972    (clobber (reg:SI PR_REG))
1973    (clobber (reg:DF DR0_REG))
1974    (clobber (reg:DF DR2_REG))
1975    (clobber (reg:SI R2_REG))
1976    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1977   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1978   "jsr  @%1%#"
1979   [(set_attr "type" "sfunc")
1980    (set_attr "needs_delay_slot" "yes")])
1982 (define_expand "divsi3"
1983   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1984    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1985    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1986    (parallel [(set (match_operand:SI 0 "register_operand" "")
1987                    (div:SI (reg:SI R4_REG)
1988                            (reg:SI R5_REG)))
1989               (clobber (reg:SI T_REG))
1990               (clobber (reg:SI PR_REG))
1991               (clobber (reg:SI R1_REG))
1992               (clobber (reg:SI R2_REG))
1993               (clobber (reg:SI R3_REG))
1994               (use (match_dup 3))])]
1995   ""
1996   "
1998   rtx first, last;
2000   operands[3] = gen_reg_rtx (Pmode);
2001   /* Emit the move of the address to a pseudo outside of the libcall.  */
2002   if (TARGET_HARD_SH4 && TARGET_SH2E)
2003     {
2004       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2005       if (TARGET_FPU_SINGLE)
2006         last = gen_divsi3_i4_single (operands[0], operands[3]);
2007       else
2008         last = gen_divsi3_i4 (operands[0], operands[3]);
2009     }
2010   else if (TARGET_SH2A)
2011     {
2012       operands[1] = force_reg (SImode, operands[1]);
2013       operands[2] = force_reg (SImode, operands[2]);
2014       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2015       DONE;
2016     }
2017   else if (TARGET_DIVIDE_INV)
2018     {
2019       rtx dividend = operands[1];
2020       rtx divisor = operands[2];
2021       rtx tab_base;
2022       rtx nsb_res = gen_reg_rtx (DImode);
2023       rtx norm64 = gen_reg_rtx (DImode);
2024       rtx tab_ix = gen_reg_rtx (DImode);
2025       rtx norm32 = gen_reg_rtx (SImode);
2026       rtx i92 = force_reg (DImode, GEN_INT (92));
2027       rtx scratch0a = gen_reg_rtx (DImode);
2028       rtx scratch0b = gen_reg_rtx (DImode);
2029       rtx inv0 = gen_reg_rtx (SImode);
2030       rtx scratch1a = gen_reg_rtx (DImode);
2031       rtx scratch1b = gen_reg_rtx (DImode);
2032       rtx shift = gen_reg_rtx (DImode);
2033       rtx i2p27, i43;
2034       rtx inv1 = gen_reg_rtx (SImode);
2035       rtx scratch2a = gen_reg_rtx (DImode);
2036       rtx scratch2b = gen_reg_rtx (SImode);
2037       rtx inv2 = gen_reg_rtx (SImode);
2038       rtx scratch3a = gen_reg_rtx (DImode);
2039       rtx scratch3b = gen_reg_rtx (DImode);
2040       rtx scratch3c = gen_reg_rtx (DImode);
2041       rtx scratch3d = gen_reg_rtx (SImode);
2042       rtx scratch3e = gen_reg_rtx (DImode);
2043       rtx result = gen_reg_rtx (SImode);
2045       if (! arith_reg_or_0_operand (dividend, SImode))
2046         dividend = force_reg (SImode, dividend);
2047       if (! arith_reg_operand (divisor, SImode))
2048         divisor = force_reg (SImode, divisor);
2049       if (flag_pic && Pmode != DImode)
2050         {
2051           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2052           tab_base = gen_datalabel_ref (tab_base);
2053           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2054         }
2055       else
2056         {
2057           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2058           tab_base = gen_datalabel_ref (tab_base);
2059           tab_base = force_reg (DImode, tab_base);
2060         }
2061       if (TARGET_DIVIDE_INV20U)
2062         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2063       else
2064         i2p27 = GEN_INT (0);
2065       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2066         i43 = force_reg (DImode, GEN_INT (43));
2067       else
2068         i43 = GEN_INT (0);
2069       emit_insn (gen_nsbdi (nsb_res,
2070                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2071       emit_insn (gen_ashldi3_media (norm64,
2072                                     gen_rtx_SUBREG (DImode, divisor, 0),
2073                                     nsb_res));
2074       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2075       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2076       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2077                                    inv0, scratch0a, scratch0b,
2078                                    scratch1a, scratch1b));
2079       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2080       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2081                                    scratch2a));
2082       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2083                                    i2p27, i43,
2084                                    scratch3a, scratch3b, scratch3c,
2085                                    scratch2a, scratch2b, scratch3d, scratch3e));
2086       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2087         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2088       else if (TARGET_DIVIDE_INV_FP)
2089         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2090                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2091                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2092                                      gen_reg_rtx (DFmode)));
2093       else
2094         emit_move_insn (operands[0], result);
2095       DONE;
2096     }
2097   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2098     {
2099       operands[1] = force_reg (SImode, operands[1]);
2100       operands[2] = force_reg (SImode, operands[2]);
2101       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2102       DONE;
2103     }
2104   else if (TARGET_SH5)
2105     {
2106       if (TARGET_DIVIDE_CALL2)
2107         {
2108           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2109           tab_base = gen_datalabel_ref (tab_base);
2110           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2111         }
2112       if (TARGET_FPU_ANY && TARGET_SH1)
2113         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2114       else if (TARGET_DIVIDE_CALL2)
2115         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2116       else
2117         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2119       if (TARGET_SHMEDIA)
2120         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2121                 (operands[0], operands[3]));
2122       else if (TARGET_FPU_ANY)
2123         last = gen_divsi3_i4_single (operands[0], operands[3]);
2124       else
2125         last = gen_divsi3_i1 (operands[0], operands[3]);
2126     }
2127   else
2128     {
2129       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2130       last = gen_divsi3_i1 (operands[0], operands[3]);
2131     }
2132   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2133   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2134   last = emit_insn (last);
2135   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2136      invariant code motion can move it.  */
2137   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2138   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2139   DONE;
2142 ;; operands: inv0, tab_base, tab_ix, norm32
2143 ;; scratch equiv in sdivsi3_2: r19, r21
2144 (define_expand "divsi_inv_m0"
2145   [(set (match_operand:SI 0 "register_operand" "=r")
2146         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2147                     (match_operand:DI 2 "register_operand" "r")
2148                     (match_operand:SI 3 "register_operand" "r")]
2149          UNSPEC_DIV_INV_M0))
2150    (clobber (match_operand:DI 4 "register_operand" "=r"))
2151    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2152   "TARGET_SHMEDIA"
2153   "
2156 tab_base: r20
2157 tab_ix: r21
2158 norm32: r25
2159  ldx.ub r20, r21, r19 // u0.8
2160  shlli r21, 1, r21
2161  muls.l r25, r19, r19 // s2.38
2162  ldx.w r20, r21, r21  // s2.14
2163  shari r19, 24, r19   // truncate to s2.14
2164  sub r21, r19, r19    // some 11 bit inverse in s1.14
2167   rtx inv0 = operands[0];
2168   rtx tab_base = operands[1];
2169   rtx tab_ix = operands[2];
2170   rtx norm32 = operands[3];
2171   rtx scratch0 = operands[4];
2172   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2173   rtx scratch1 = operands[5];
2174   rtx mem;
2176   mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2177   emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2178   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2179   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2180   mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2181   emit_insn (gen_extendhidi2 (scratch1, mem));
2182   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2183   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2184   DONE;
2187 ;; operands: inv1, tab_base, tab_ix, norm32
2188 (define_insn_and_split "divsi_inv_m1"
2189   [(set (match_operand:SI 0 "register_operand" "=r")
2190         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2191                     (match_operand:DI 2 "register_operand" "r")
2192                     (match_operand:SI 3 "register_operand" "r")]
2193          UNSPEC_DIV_INV_M1))
2194    (clobber (match_operand:SI 4 "register_operand" "=r"))
2195    (clobber (match_operand:DI 5 "register_operand" "=r"))
2196    (clobber (match_operand:DI 6 "register_operand" "=r"))
2197    (clobber (match_operand:DI 7 "register_operand" "=r"))
2198    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2199   "TARGET_SHMEDIA"
2200   "#"
2201   "&& no_new_pseudos"
2202   [(pc)]
2203   "
2205 /* inv0: r19
2206  muls.l r19, r19, r18 // u0.28
2207  muls.l r25, r18, r18 // s2.58
2208  shlli r19, 45, r0    // multiply by two and convert to s2.58
2209  sub r0, r18, r18
2210  shari r18, 28, r18   // some 18 bit inverse in s1.30
2213   rtx inv1 = operands[0];
2214   rtx tab_base = operands[1];
2215   rtx tab_ix = operands[2];
2216   rtx norm32 = operands[3];
2217   rtx inv0 = operands[4];
2218   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2219   rtx scratch0a = operands[5];
2220   rtx scratch0b = operands[6];
2221   rtx scratch0 = operands[7];
2222   rtx scratch1 = operands[8];
2223   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2225   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2226                                scratch0a, scratch0b));
2227   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2228   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2229   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2230   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2231   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2232   DONE;
2235 ;; operands: inv2, norm32, inv1, i92
2236 (define_insn_and_split "divsi_inv_m2"
2237   [(set (match_operand:SI 0 "register_operand" "=r")
2238         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2239                     (match_operand:SI 2 "register_operand" "r")
2240                     (match_operand:DI 3 "register_operand" "r")]
2241          UNSPEC_DIV_INV_M2))
2242    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2243   "TARGET_SHMEDIA"
2244   "#"
2245   "&& no_new_pseudos"
2246   [(pc)]
2247   "
2250  muls.l r18, r25, r0  // s2.60
2251  shari r0, 16, r0     // s-16.44
2252   sub
2253  muls.l r0, r18, r19  // s-16.74
2254  shari r19, 30, r19   // s-16.44
2256   rtx inv2 = operands[0];
2257   rtx norm32 = operands[1];
2258   rtx inv1 = operands[2];
2259   rtx i92 = operands[3];
2260   rtx scratch0 = operands[4];
2261   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2263   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2264   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2265   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2266   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2267   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2268   DONE;
2271 (define_insn_and_split "divsi_inv_m3"
2272   [(set (match_operand:SI 0 "register_operand" "=r")
2273         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2274                     (match_operand:SI 2 "register_operand" "r")
2275                     (match_operand:SI 3 "register_operand" "r")
2276                     (match_operand:DI 4 "register_operand" "r")
2277                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2278                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2279          UNSPEC_DIV_INV_M3))
2280    (clobber (match_operand:DI 7 "register_operand" "=r"))
2281    (clobber (match_operand:DI 8 "register_operand" "=r"))
2282    (clobber (match_operand:DI 9 "register_operand" "=r"))
2283    (clobber (match_operand:DI 10 "register_operand" "=r"))
2284    (clobber (match_operand:SI 11 "register_operand" "=r"))
2285    (clobber (match_operand:SI 12 "register_operand" "=r"))
2286    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2287   "TARGET_SHMEDIA"
2288   "#"
2289   "&& no_new_pseudos"
2290   [(pc)]
2291   "
2294   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2295   r0: scratch0  r19: scratch1 r21: scratch2
2297   muls.l r18, r4, r25 // s32.30
2298  muls.l r19, r4, r19  // s15.30
2299  shari r25, 63, r21
2300   shari r19, 14, r19  // s18.-14
2301  sub r25, r19, r0
2302  shard r0, r1, r0
2303  sub r0, r21, r0
2306   rtx result = operands[0];
2307   rtx dividend = operands[1];
2308   rtx inv1 = operands[2];
2309   rtx inv2 = operands[3];
2310   rtx shift = operands[4];
2311   rtx scratch0 = operands[7];
2312   rtx scratch1 = operands[8];
2313   rtx scratch2 = operands[9];
2315   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2316   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2317   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2318   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2319   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2320   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2321   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2322   DONE;
2325 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2326 ;; inv1: tab_base, tab_ix, norm32
2327 ;; inv2: norm32, inv1, i92
2328 (define_insn_and_split "divsi_inv_m1_3"
2329   [(set (match_operand:SI 0 "register_operand" "=r")
2330         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2331                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2332                                 (match_operand:DI 3 "register_operand" "r")
2333                                 (match_operand:SI 4 "register_operand" "r")]
2334                      UNSPEC_DIV_INV_M1)
2335                     (unspec:SI [(match_dup 4)
2336                                 (unspec:SI [(match_dup 2)
2337                                             (match_dup 3)
2338                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2339                                 (match_operand:SI 5 "" "")]
2340                      UNSPEC_DIV_INV_M2)
2341                     (match_operand:DI 6 "register_operand" "r")
2342                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2343                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2344          UNSPEC_DIV_INV_M3))
2345    (clobber (match_operand:DI 9 "register_operand" "=r"))
2346    (clobber (match_operand:DI 10 "register_operand" "=r"))
2347    (clobber (match_operand:DI 11 "register_operand" "=r"))
2348    (clobber (match_operand:DI 12 "register_operand" "=r"))
2349    (clobber (match_operand:SI 13 "register_operand" "=r"))
2350    (clobber (match_operand:SI 14 "register_operand" "=r"))
2351    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2352   "TARGET_SHMEDIA
2353    && (TARGET_DIVIDE_INV_MINLAT
2354        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2355   "#"
2356   "&& no_new_pseudos"
2357   [(pc)]
2358   "
2360   rtx result = operands[0];
2361   rtx dividend = operands[1];
2362   rtx tab_base = operands[2];
2363   rtx tab_ix = operands[3];
2364   rtx norm32 = operands[4];
2365   /* rtx i92 = operands[5]; */
2366   rtx shift = operands[6];
2367   rtx i2p27 = operands[7];
2368   rtx i43 = operands[8];
2369   rtx scratch0 = operands[9];
2370   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2371   rtx scratch1 = operands[10];
2372   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2373   rtx scratch2 = operands[11];
2374   rtx scratch3 = operands[12];
2375   rtx scratch4 = operands[13];
2376   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2377   rtx scratch5 = operands[14];
2378   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2379   rtx scratch6 = operands[15];
2381   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2382                                scratch0, scratch1));
2383   /* inv0 == scratch4 */
2384   if (! TARGET_DIVIDE_INV20U)
2385     {
2386       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2387       i2p27 = scratch0;
2388       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2389     }
2390   else
2391     {
2392       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2393       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2394     }
2395   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2396   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2397   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2398   /* inv1 == scratch4 */
2400   if (TARGET_DIVIDE_INV_MINLAT)
2401     {
2402       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2403       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2404       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2405       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2406       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2407       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2408       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2409       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2410       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2411       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2412       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2413     }
2414   else
2415     {
2416       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2417       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2418       emit_insn (gen_nsbdi (scratch6,
2419                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2420       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2421       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2422       emit_insn (gen_divsi_inv20 (scratch2,
2423                                   norm32, scratch4, dividend,
2424                                   scratch6, scratch3, i43,
2425                                   /* scratch0 may be shared with i2p27.  */
2426                                   scratch0, scratch1, scratch5,
2427                                   label, label, i2p27));
2428     }
2429   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2430   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2431   DONE;
2434 (define_insn "divsi_inv20"
2435   [(set (match_operand:DI 0 "register_operand" "=&r")
2436         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2437                     (match_operand:SI 2 "register_operand" "r")
2438                     (match_operand:SI 3 "register_operand" "r")
2439                     (match_operand:DI 4 "register_operand" "r")
2440                     (match_operand:DI 5 "register_operand" "r")
2441                     (match_operand:DI 6 "register_operand" "r")
2442                     (match_operand:DI 12 "register_operand" "r")
2443                     (match_operand 10 "target_operand" "b")
2444                     (match_operand 11 "immediate_operand" "i")]
2445          UNSPEC_DIV_INV20))
2446    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2447    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2448    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2449   "TARGET_SHMEDIA
2450    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2451   "*
2453 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2454              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2455              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2456              %10 label (tr), %11 label (imm)
2458  muls.l inv1, norm32, scratch0  // s2.60
2459   muls.l inv1, dividend, result // s32.30
2460   xor i2p27, result_sign, round_scratch
2461  bge/u dividend_nsb, i43, tr.. (label)
2462  shari scratch0, 16, scratch0   // s-16.44
2463  muls.l sratch0_si, inv1, scratch0 // s-16.74
2464   sub result, round_scratch, result
2465   shari dividend, 14, scratch1   // s19.-14
2466  shari scratch0, 30, scratch0   // s-16.44
2467  muls.l scratch0, scratch1, round_scratch // s15.30
2468 label:
2469  sub result, round_scratch, result */
2471   int likely = TARGET_DIVIDE_INV20L;
2473   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2474   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2475   output_asm_insn (likely
2476                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2477                    : \"bge/u\t%4, %6, %10\", operands);
2478   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2479   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2480   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2481   return (likely
2482           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2483           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2486 (define_insn_and_split "divsi_inv_fp"
2487   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2488         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2489                 (match_operand:SI 2 "register_operand" "rf")))
2490    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2491    (clobber (match_operand:SI 4 "register_operand" "=r"))
2492    (clobber (match_operand:SI 5 "register_operand" "=r"))
2493    (clobber (match_operand:DF 6 "register_operand" "=r"))
2494    (clobber (match_operand:DF 7 "register_operand" "=r"))
2495    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2496   "TARGET_SHMEDIA_FPU"
2497   "#"
2498   "&& (high_life_started || reload_completed)"
2499   [(set (match_dup 0) (match_dup 3))]
2500   ""
2501   [(set_attr "highpart" "must_split")])
2503 ;; If a matching group of divide-by-inverse instructions is in the same
2504 ;; basic block after gcse & loop optimizations, we want to transform them
2505 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2506 (define_insn_and_split "*divsi_inv_fp_combine"
2507   [(set (match_operand:SI 0 "register_operand" "=f")
2508         (div:SI (match_operand:SI 1 "register_operand" "f")
2509                 (match_operand:SI 2 "register_operand" "f")))
2510    (use (unspec:SI [(match_dup 1)
2511                     (match_operand:SI 3 "" "")
2512                     (unspec:SI [(match_operand:SI 4 "" "")
2513                                 (match_dup 3)
2514                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2515                     (match_operand:DI 6 "" "")
2516                     (const_int 0)
2517                     (const_int 0)] UNSPEC_DIV_INV_M3))
2518    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2519    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2520    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2521    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2522    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2523   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2524   "#"
2525   "&& 1"
2526   [(set (match_dup 9) (float:DF (match_dup 1)))
2527    (set (match_dup 10) (float:DF (match_dup 2)))
2528    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2529    (set (match_dup 8)
2530         (fix:SI (match_dup 11)))
2531    (set (match_dup 0) (match_dup 8))]
2532   "
2534   if (! fp_arith_reg_operand (operands[1], SImode))
2535     {
2536       emit_move_insn (operands[7], operands[1]);
2537       operands[1] = operands[7];
2538     }
2539   if (! fp_arith_reg_operand (operands[2], SImode))
2540     {
2541       emit_move_insn (operands[8], operands[2]);
2542       operands[2] = operands[8];
2543     }
2545   [(set_attr "highpart" "must_split")])
2547 ;; -------------------------------------------------------------------------
2548 ;; Multiplication instructions
2549 ;; -------------------------------------------------------------------------
2551 (define_insn "umulhisi3_i"
2552   [(set (reg:SI MACL_REG)
2553         (mult:SI (zero_extend:SI
2554                   (match_operand:HI 0 "arith_reg_operand" "r"))
2555                  (zero_extend:SI
2556                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2557   "TARGET_SH1"
2558   "mulu.w       %1,%0"
2559   [(set_attr "type" "smpy")])
2561 (define_insn "mulhisi3_i"
2562   [(set (reg:SI MACL_REG)
2563         (mult:SI (sign_extend:SI
2564                   (match_operand:HI 0 "arith_reg_operand" "r"))
2565                  (sign_extend:SI
2566                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2567   "TARGET_SH1"
2568   "muls.w       %1,%0"
2569   [(set_attr "type" "smpy")])
2571 (define_expand "mulhisi3"
2572   [(set (reg:SI MACL_REG)
2573         (mult:SI (sign_extend:SI
2574                   (match_operand:HI 1 "arith_reg_operand" ""))
2575                  (sign_extend:SI
2576                   (match_operand:HI 2 "arith_reg_operand" ""))))
2577    (set (match_operand:SI 0 "arith_reg_operand" "")
2578         (reg:SI MACL_REG))]
2579   "TARGET_SH1"
2580   "
2582   rtx first, last;
2584   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2585   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2586   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2587      invariant code motion can move it.  */
2588   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2589   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2590   /* expand_binop can't find a suitable code in umul_widen_optab to
2591      make a REG_EQUAL note from, so make one here.
2592      See also smulsi3_highpart.
2593      ??? Alternatively, we could put this at the calling site of expand_binop,
2594      i.e. expand_expr.  */
2595   REG_NOTES (last)
2596     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2597                          REG_NOTES (last));
2598   DONE;
2601 (define_expand "umulhisi3"
2602   [(set (reg:SI MACL_REG)
2603         (mult:SI (zero_extend:SI
2604                   (match_operand:HI 1 "arith_reg_operand" ""))
2605                  (zero_extend:SI
2606                   (match_operand:HI 2 "arith_reg_operand" ""))))
2607    (set (match_operand:SI 0 "arith_reg_operand" "")
2608         (reg:SI MACL_REG))]
2609   "TARGET_SH1"
2610   "
2612   rtx first, last;
2614   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2615   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2616   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2617      invariant code motion can move it.  */
2618   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2619   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2620   /* expand_binop can't find a suitable code in umul_widen_optab to
2621      make a REG_EQUAL note from, so make one here.
2622      See also smulsi3_highpart.
2623      ??? Alternatively, we could put this at the calling site of expand_binop,
2624      i.e. expand_expr.  */
2625   REG_NOTES (last)
2626     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2627                          REG_NOTES (last));
2628   DONE;
2631 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2632 ;; a call to a routine which clobbers known registers.
2634 (define_insn ""
2635   [(set (match_operand:SI 1 "register_operand" "=z")
2636         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2637    (clobber (reg:SI MACL_REG))
2638    (clobber (reg:SI T_REG))
2639    (clobber (reg:SI PR_REG))
2640    (clobber (reg:SI R3_REG))
2641    (clobber (reg:SI R2_REG))
2642    (clobber (reg:SI R1_REG))
2643    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2644   "TARGET_SH1"
2645   "jsr  @%0%#"
2646   [(set_attr "type" "sfunc")
2647    (set_attr "needs_delay_slot" "yes")])
2649 (define_expand "mulsi3_call"
2650   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2651    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2652    (parallel[(set (match_operand:SI 0 "register_operand" "")
2653                   (mult:SI (reg:SI R4_REG)
2654                            (reg:SI R5_REG)))
2655              (clobber (reg:SI MACL_REG))
2656              (clobber (reg:SI T_REG))
2657              (clobber (reg:SI PR_REG))
2658              (clobber (reg:SI R3_REG))
2659              (clobber (reg:SI R2_REG))
2660              (clobber (reg:SI R1_REG))
2661              (use (match_operand:SI 3 "register_operand" ""))])]
2662   "TARGET_SH1"
2663   "")
2665 (define_insn "mul_r"
2666   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2667         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2668                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2669   "TARGET_SH2A"
2670   "mulr %2,%0"
2671   [(set_attr "type" "dmpy")])
2673 (define_insn "mul_l"
2674   [(set (reg:SI MACL_REG)
2675         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2676                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2677   "TARGET_SH2"
2678   "mul.l        %1,%0"
2679   [(set_attr "type" "dmpy")])
2681 (define_expand "mulsi3"
2682   [(set (reg:SI MACL_REG)
2683         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2684                   (match_operand:SI 2 "arith_reg_operand" "")))
2685    (set (match_operand:SI 0 "arith_reg_operand" "")
2686         (reg:SI MACL_REG))]
2687   "TARGET_SH1"
2688   "
2690   rtx first, last;
2692   if (!TARGET_SH2)
2693     {
2694       /* The address must be set outside the libcall,
2695          since it goes into a pseudo.  */
2696       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2697       rtx addr = force_reg (SImode, sym);
2698       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2699                                    operands[2], addr);
2700       first = insns;
2701       last = emit_insn (insns);
2702     }
2703   else
2704     {
2705       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2707       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2708       /* consec_sets_giv can only recognize the first insn that sets a
2709          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2710          note.  */
2711       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2712     }
2713   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2714      invariant code motion can move it.  */
2715   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2716   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2717   DONE;
2720 (define_insn "mulsidi3_i"
2721   [(set (reg:SI MACH_REG)
2722         (truncate:SI
2723          (lshiftrt:DI
2724           (mult:DI
2725            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2726            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2727           (const_int 32))))
2728    (set (reg:SI MACL_REG)
2729         (mult:SI (match_dup 0)
2730                  (match_dup 1)))]
2731   "TARGET_SH2"
2732   "dmuls.l      %1,%0"
2733   [(set_attr "type" "dmpy")])
2735 (define_expand "mulsidi3"
2736   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2737         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2738                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2739   "TARGET_SH2 || TARGET_SHMEDIA"
2740   "
2742   if (TARGET_SH2)
2743     {
2744        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2745                                         operands[2]));
2746        DONE;
2747     }
2750 (define_insn "mulsidi3_media"
2751   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2752         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2753                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2754   "TARGET_SHMEDIA"
2755   "muls.l       %1, %2, %0"
2756   [(set_attr "type" "dmpy_media")
2757    (set_attr "highpart" "ignore")])
2759 (define_insn "mulsidi3_compact"
2760   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2761         (mult:DI
2762          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2763          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2764    (clobber (reg:SI MACH_REG))
2765    (clobber (reg:SI MACL_REG))]
2766   "TARGET_SH2"
2767   "#")
2769 (define_split
2770   [(set (match_operand:DI 0 "arith_reg_dest" "")
2771         (mult:DI
2772          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2773          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2774    (clobber (reg:SI MACH_REG))
2775    (clobber (reg:SI MACL_REG))]
2776   "TARGET_SH2"
2777   [(const_int 0)]
2778   "
2780   rtx low_dst = gen_lowpart (SImode, operands[0]);
2781   rtx high_dst = gen_highpart (SImode, operands[0]);
2783   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2785   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2786   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2787   /* We need something to tag the possible REG_EQUAL notes on to.  */
2788   emit_move_insn (operands[0], operands[0]);
2789   DONE;
2792 (define_insn "umulsidi3_i"
2793   [(set (reg:SI MACH_REG)
2794         (truncate:SI
2795          (lshiftrt:DI
2796           (mult:DI
2797            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2798            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2799           (const_int 32))))
2800    (set (reg:SI MACL_REG)
2801         (mult:SI (match_dup 0)
2802                  (match_dup 1)))]
2803   "TARGET_SH2"
2804   "dmulu.l      %1,%0"
2805   [(set_attr "type" "dmpy")])
2807 (define_expand "umulsidi3"
2808   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2809         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2810                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2811   "TARGET_SH2 || TARGET_SHMEDIA"
2812   "
2814   if (TARGET_SH2)
2815     {
2816        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2817                                          operands[2]));
2818        DONE;
2819     }
2822 (define_insn "umulsidi3_media"
2823   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2824         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2825                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2826   "TARGET_SHMEDIA"
2827   "mulu.l       %1, %2, %0"
2828   [(set_attr "type" "dmpy_media")
2829    (set_attr "highpart" "ignore")])
2831 (define_insn "umulsidi3_compact"
2832   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2833         (mult:DI
2834          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2835          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2836    (clobber (reg:SI MACH_REG))
2837    (clobber (reg:SI MACL_REG))]
2838   "TARGET_SH2"
2839   "#")
2841 (define_split
2842   [(set (match_operand:DI 0 "arith_reg_dest" "")
2843         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2844                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2845    (clobber (reg:SI MACH_REG))
2846    (clobber (reg:SI MACL_REG))]
2847   "TARGET_SH2"
2848   [(const_int 0)]
2849   "
2851   rtx low_dst = gen_lowpart (SImode, operands[0]);
2852   rtx high_dst = gen_highpart (SImode, operands[0]);
2854   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2856   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2857   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2858   /* We need something to tag the possible REG_EQUAL notes on to.  */
2859   emit_move_insn (operands[0], operands[0]);
2860   DONE;
2863 (define_insn "smulsi3_highpart_i"
2864   [(set (reg:SI MACH_REG)
2865         (truncate:SI
2866          (lshiftrt:DI
2867           (mult:DI
2868            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2869            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2870           (const_int 32))))
2871    (clobber (reg:SI MACL_REG))]
2872   "TARGET_SH2"
2873   "dmuls.l      %1,%0"
2874   [(set_attr "type" "dmpy")])
2876 (define_expand "smulsi3_highpart"
2877   [(parallel
2878     [(set (reg:SI MACH_REG)
2879           (truncate:SI
2880            (lshiftrt:DI
2881             (mult:DI
2882              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2883              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2884             (const_int 32))))
2885     (clobber (reg:SI MACL_REG))])
2886    (set (match_operand:SI 0 "arith_reg_operand" "")
2887         (reg:SI MACH_REG))]
2888   "TARGET_SH2"
2889   "
2891   rtx first, last;
2893   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2894   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2895   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2896      invariant code motion can move it.  */
2897   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2898   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2899   /* expand_binop can't find a suitable code in mul_highpart_optab to
2900      make a REG_EQUAL note from, so make one here.
2901      See also {,u}mulhisi.
2902      ??? Alternatively, we could put this at the calling site of expand_binop,
2903      i.e. expand_mult_highpart.  */
2904   REG_NOTES (last)
2905     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2906                          REG_NOTES (last));
2907   DONE;
2910 (define_insn "umulsi3_highpart_i"
2911   [(set (reg:SI MACH_REG)
2912         (truncate:SI
2913          (lshiftrt:DI
2914           (mult:DI
2915            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2916            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2917           (const_int 32))))
2918    (clobber (reg:SI MACL_REG))]
2919   "TARGET_SH2"
2920   "dmulu.l      %1,%0"
2921   [(set_attr "type" "dmpy")])
2923 (define_expand "umulsi3_highpart"
2924   [(parallel
2925     [(set (reg:SI MACH_REG)
2926           (truncate:SI
2927            (lshiftrt:DI
2928             (mult:DI
2929              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2930              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2931             (const_int 32))))
2932     (clobber (reg:SI MACL_REG))])
2933    (set (match_operand:SI 0 "arith_reg_operand" "")
2934         (reg:SI MACH_REG))]
2935   "TARGET_SH2"
2936   "
2938   rtx first, last;
2940   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2941   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2942   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2943      invariant code motion can move it.  */
2944   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2945   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2946   DONE;
2949 (define_insn_and_split "muldi3"
2950   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2951         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2952                  (match_operand:DI 2 "arith_reg_operand" "r")))
2953    (clobber (match_scratch:DI 3 "=&r"))
2954    (clobber (match_scratch:DI 4 "=r"))]
2955   "TARGET_SHMEDIA"
2956   "#"
2957   "reload_completed"
2958   [(const_int 0)]
2959   "
2961   rtx op3_v2si, op2_v2si;
2963   op3_v2si = operands[3];
2964   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2965     {
2966       op3_v2si = XEXP (op3_v2si, 0);
2967       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2968     }
2969   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2970   op2_v2si = operands[2];
2971   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2972     {
2973       op2_v2si = XEXP (op2_v2si, 0);
2974       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2975     }
2976   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2977   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2978   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2979   emit_insn (gen_umulsidi3_media (operands[4],
2980                                  sh_gen_truncate (SImode, operands[1], 0),
2981                                  sh_gen_truncate (SImode, operands[2], 0)));
2982   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2983   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2984   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2985   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2986   DONE;
2990 ;; -------------------------------------------------------------------------
2991 ;; Logical operations
2992 ;; -------------------------------------------------------------------------
2994 (define_insn "*andsi3_compact"
2995   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2996         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2997                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2998   "TARGET_SH1"
2999   "and  %2,%0"
3000   [(set_attr "type" "arith")])
3002 (define_insn "*andsi3_media"
3003   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3004         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3005                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3006   "TARGET_SHMEDIA"
3007   "@
3008         and     %1, %2, %0
3009         andi    %1, %2, %0"
3010   [(set_attr "type" "arith_media")])
3012 ;; If the constant is 255, then emit an extu.b instruction instead of an
3013 ;; and, since that will give better code.
3015 (define_expand "andsi3"
3016   [(set (match_operand:SI 0 "arith_reg_operand" "")
3017         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3018                 (match_operand:SI 2 "logical_operand" "")))]
3019   ""
3020   "
3022   if (TARGET_SH1
3023       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255
3024       && (GET_CODE (operands[1]) != SUBREG
3025           || SCALAR_INT_MODE_P (GET_MODE (XEXP (operands[1], 0)))))
3026     {
3027       emit_insn (gen_zero_extendqisi2 (operands[0],
3028                                        gen_lowpart (QImode, operands[1])));
3029       DONE;
3030     }
3033 (define_insn_and_split "anddi3"
3034   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3035         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3036                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3037   "TARGET_SHMEDIA"
3038   "@
3039         and     %1, %2, %0
3040         andi    %1, %2, %0
3041         #"
3042   "reload_completed
3043    && ! logical_operand (operands[2], DImode)"
3044   [(const_int 0)]
3045   "
3047   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3048     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3049   else
3050     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3051   DONE;
3053   [(set_attr "type" "arith_media")])
3055 (define_insn "andcsi3"
3056   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3057         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3058                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3059   "TARGET_SHMEDIA"
3060   "andc %1,%2,%0"
3061   [(set_attr "type" "arith_media")])
3063 (define_insn "andcdi3"
3064   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3065         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3066                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3067   "TARGET_SHMEDIA"
3068   "andc %1,%2,%0"
3069   [(set_attr "type" "arith_media")])
3071 (define_expand "iorsi3"
3072   [(set (match_operand:SI 0 "arith_reg_operand" "")
3073         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3074                 (match_operand:SI 2 "logical_operand" "")))]
3075   ""
3076   "")
3078 (define_insn "*iorsi3_compact"
3079   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3080         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3081                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3082   "TARGET_SH1"
3083   "or   %2,%0"
3084   [(set_attr "type" "arith")])
3086 (define_insn "*iorsi3_media"
3087   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3088         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3089                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3090   "TARGET_SHMEDIA"
3091   "@
3092         or      %1, %2, %0
3093         ori     %1, %2, %0"
3094   [(set_attr "type" "arith_media")])
3096 (define_insn "iordi3"
3097   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3098         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3099                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3100   "TARGET_SHMEDIA"
3101   "@
3102         or      %1, %2, %0
3103         ori     %1, %2, %0"
3104   [(set_attr "type" "arith_media")])
3106 (define_insn_and_split "*logical_sidi3"
3107   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3108         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3109                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3110                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3111   "TARGET_SHMEDIA"
3112   "#"
3113   "&& reload_completed"
3114   [(set (match_dup 0) (match_dup 3))]
3115   "
3117   operands[3]
3118     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3119                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3120                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3123 (define_insn_and_split "*logical_sidisi3"
3124   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3125         (truncate:SI (sign_extend:DI
3126                         (match_operator:SI 3 "logical_operator"
3127                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3128                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3129   "TARGET_SHMEDIA"
3130   "#"
3131   "&& 1"
3132   [(set (match_dup 0) (match_dup 3))])
3134 (define_insn_and_split "*logical_sidi3_2"
3135   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3136         (sign_extend:DI (truncate:SI (sign_extend:DI
3137                         (match_operator:SI 3 "logical_operator"
3138                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3139                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3140   "TARGET_SHMEDIA"
3141   "#"
3142   "&& 1"
3143   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3145 (define_expand "xorsi3"
3146   [(set (match_operand:SI 0 "arith_reg_operand" "")
3147         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3148                 (match_operand:SI 2 "xor_operand" "")))]
3149   ""
3150   "")
3152 (define_insn "*xorsi3_compact"
3153   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3154         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3155                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3156   "TARGET_SH1"
3157   "xor  %2,%0"
3158   [(set_attr "type" "arith")])
3160 (define_insn "*xorsi3_media"
3161   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3162         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3163                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3164   "TARGET_SHMEDIA"
3165   "@
3166         xor     %1, %2, %0
3167         xori    %1, %2, %0"
3168   [(set_attr "type" "arith_media")])
3170 (define_insn "xordi3"
3171   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3172         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3173                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3174   "TARGET_SHMEDIA"
3175   "@
3176         xor     %1, %2, %0
3177         xori    %1, %2, %0"
3178   [(set_attr "type" "arith_media")])
3180 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3181 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3182 (define_split
3183   [(set (match_operand:DI 0 "arith_reg_dest" "")
3184         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3185                           [(match_operand 1 "any_register_operand" "")
3186                            (match_operand 2 "any_register_operand" "")])))]
3187   "TARGET_SHMEDIA"
3188   [(set (match_dup 5) (match_dup 4))
3189    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3192   enum machine_mode inmode = GET_MODE (operands[1]);
3193   int offset = 0;
3195   if (GET_CODE (operands[0]) == SUBREG)
3196     {
3197       offset = SUBREG_BYTE (operands[0]);
3198       operands[0] = SUBREG_REG (operands[0]);
3199     }
3200   gcc_assert (GET_CODE (operands[0]) == REG);
3201   if (! TARGET_LITTLE_ENDIAN)
3202     offset += 8 - GET_MODE_SIZE (inmode);
3203   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3206 ;; -------------------------------------------------------------------------
3207 ;; Shifts and rotates
3208 ;; -------------------------------------------------------------------------
3210 (define_expand "rotldi3"
3211   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3212         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3213                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3214   "TARGET_SHMEDIA"
3215   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3217 (define_insn "rotldi3_mextr"
3218   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3219         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3220                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3221   "TARGET_SHMEDIA"
3222   "*
3224   static char templ[16];
3226   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3227            8 - (int) (INTVAL (operands[2]) >> 3));
3228   return templ;
3230   [(set_attr "type" "arith_media")])
3232 (define_expand "rotrdi3"
3233   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3234         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3235                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3236   "TARGET_SHMEDIA"
3237   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3239 (define_insn "rotrdi3_mextr"
3240   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3241         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3242                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3243   "TARGET_SHMEDIA"
3244   "*
3246   static char templ[16];
3248   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3249   return templ;
3251   [(set_attr "type" "arith_media")])
3253 (define_split
3254   [(set (match_operand:DI 0 "arith_reg_dest" "")
3255         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3256                                          "ua_address_operand" "")))
3257                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3258                            (const_int 8))))
3259    (clobber (match_operand:DI 3 "register_operand" ""))]
3260   "TARGET_SHMEDIA"
3261   [(match_dup 4) (match_dup 5)]
3262   "
3264   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3265                  (operands[3], operands[1]));
3266   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3267                               GEN_INT (56), GEN_INT (8));
3270 (define_insn "rotlsi3_1"
3271   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3272         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3273                    (const_int 1)))
3274    (set (reg:SI T_REG)
3275         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3276   "TARGET_SH1"
3277   "rotl %0"
3278   [(set_attr "type" "arith")])
3280 (define_insn "rotlsi3_31"
3281   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3282         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3283                    (const_int 31)))
3284    (clobber (reg:SI T_REG))]
3285   "TARGET_SH1"
3286   "rotr %0"
3287   [(set_attr "type" "arith")])
3289 (define_insn "rotlsi3_16"
3290   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3291         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3292                    (const_int 16)))]
3293   "TARGET_SH1"
3294   "swap.w       %1,%0"
3295   [(set_attr "type" "arith")])
3297 (define_expand "rotlsi3"
3298   [(set (match_operand:SI 0 "arith_reg_dest" "")
3299         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3300                    (match_operand:SI 2 "immediate_operand" "")))]
3301   "TARGET_SH1"
3302   "
3304   static const char rot_tab[] = {
3305     000, 000, 000, 000, 000, 000, 010, 001,
3306     001, 001, 011, 013, 003, 003, 003, 003,
3307     003, 003, 003, 003, 003, 013, 012, 002,
3308     002, 002, 010, 000, 000, 000, 000, 000,
3309   };
3311   int count, choice;
3313   if (GET_CODE (operands[2]) != CONST_INT)
3314     FAIL;
3315   count = INTVAL (operands[2]);
3316   choice = rot_tab[count];
3317   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3318     FAIL;
3319   choice &= 7;
3320   switch (choice)
3321     {
3322     case 0:
3323       emit_move_insn (operands[0], operands[1]);
3324       count -= (count & 16) * 2;
3325       break;
3326     case 3:
3327      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3328      count -= 16;
3329      break;
3330     case 1:
3331     case 2:
3332       {
3333         rtx parts[2];
3334         parts[0] = gen_reg_rtx (SImode);
3335         parts[1] = gen_reg_rtx (SImode);
3336         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3337         emit_move_insn (parts[choice-1], operands[1]);
3338         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3339         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3340         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3341         count = (count & ~16) - 8;
3342       }
3343     }
3345   for (; count > 0; count--)
3346     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3347   for (; count < 0; count++)
3348     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3350   DONE;
3353 (define_insn "*rotlhi3_8"
3354   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3355         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3356                    (const_int 8)))]
3357   "TARGET_SH1"
3358   "swap.b       %1,%0"
3359   [(set_attr "type" "arith")])
3361 (define_expand "rotlhi3"
3362   [(set (match_operand:HI 0 "arith_reg_operand" "")
3363         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3364                    (match_operand:HI 2 "immediate_operand" "")))]
3365   "TARGET_SH1"
3366   "
3368   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3369     FAIL;
3373 ;; shift left
3375 (define_insn "ashlsi3_sh2a"
3376   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3377         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3378                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3379   "TARGET_SH2A"
3380   "shad %2,%0"
3381   [(set_attr "type" "arith")
3382    (set_attr "length" "4")])
3384 ;; This pattern is used by init_expmed for computing the costs of shift
3385 ;; insns.
3387 (define_insn_and_split "ashlsi3_std"
3388   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3389         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3390                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3391    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3392   "TARGET_SH3
3393    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3394        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3395   "@
3396    shld %2,%0
3397    add  %0,%0
3398    shll%O2      %0
3399    #"
3400   "TARGET_SH3
3401    && reload_completed
3402    && GET_CODE (operands[2]) == CONST_INT
3403    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3404   [(set (match_dup 3) (match_dup 2))
3405    (parallel
3406     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3407      (clobber (match_dup 4))])]
3408   "operands[4] = gen_rtx_SCRATCH (SImode);"
3409   [(set_attr "length" "*,*,*,4")
3410    (set_attr "type" "dyn_shift,arith,arith,arith")])
3412 (define_insn "ashlhi3_k"
3413   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3414         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3415                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3416   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3417   "@
3418         add     %0,%0
3419         shll%O2 %0"
3420   [(set_attr "type" "arith")])
3422 (define_insn "ashlsi3_n"
3423   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3424         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3425                    (match_operand:SI 2 "const_int_operand" "n")))
3426    (clobber (reg:SI T_REG))]
3427   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3428   "#"
3429   [(set (attr "length")
3430         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3431                (const_string "2")
3432                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3433                (const_string "4")
3434                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3435                (const_string "6")]
3436               (const_string "8")))
3437    (set_attr "type" "arith")])
3439 (define_split
3440   [(set (match_operand:SI 0 "arith_reg_dest" "")
3441         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3442                    (match_operand:SI 2 "const_int_operand" "")))
3443    (clobber (reg:SI T_REG))]
3444   "TARGET_SH1 && reload_completed"
3445   [(use (reg:SI R0_REG))]
3446   "
3448   gen_shifty_op (ASHIFT, operands);
3449   DONE;
3452 (define_insn "ashlsi3_media"
3453   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3454         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3455                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3456   "TARGET_SHMEDIA"
3457   "@
3458         shlld.l %1, %2, %0
3459         shlli.l %1, %2, %0"
3460   [(set_attr "type" "arith_media")
3461    (set_attr "highpart" "ignore")])
3463 (define_expand "ashlsi3"
3464   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3465                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3466                               (match_operand:SI 2 "nonmemory_operand" "")))
3467               (clobber (reg:SI T_REG))])]
3468   ""
3469   "
3471   if (TARGET_SHMEDIA)
3472     {
3473       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3474       DONE;
3475     }
3476   if (GET_CODE (operands[2]) == CONST_INT
3477       && sh_dynamicalize_shift_p (operands[2]))
3478     operands[2] = force_reg (SImode, operands[2]);
3479   if (TARGET_SH3)
3480     {
3481       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3482       DONE;
3483     }
3484   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3485     FAIL;
3488 (define_insn "*ashlhi3_n"
3489   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3490         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3491                    (match_operand:HI 2 "const_int_operand" "n")))
3492    (clobber (reg:SI T_REG))]
3493   "TARGET_SH1"
3494   "#"
3495   [(set (attr "length")
3496         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3497                (const_string "2")
3498                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3499                (const_string "4")]
3500               (const_string "6")))
3501    (set_attr "type" "arith")])
3503 (define_expand "ashlhi3"
3504   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3505                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3506                               (match_operand:SI 2 "nonmemory_operand" "")))
3507               (clobber (reg:SI T_REG))])]
3508   "TARGET_SH1"
3509   "
3511   if (GET_CODE (operands[2]) != CONST_INT)
3512     FAIL;
3513   /* It may be possible to call gen_ashlhi3 directly with more generic
3514      operands.  Make sure operands[1] is a HImode register here.  */
3515   if (!arith_reg_operand (operands[1], HImode))
3516     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3519 (define_split
3520   [(set (match_operand:HI 0 "arith_reg_dest" "")
3521         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3522                    (match_operand:HI 2 "const_int_operand" "")))
3523    (clobber (reg:SI T_REG))]
3524   "TARGET_SH1 && reload_completed"
3525   [(use (reg:SI R0_REG))]
3526   "
3528   gen_shifty_hi_op (ASHIFT, operands);
3529   DONE;
3533 ; arithmetic shift right
3536 (define_insn "ashrsi3_sh2a"
3537   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3538         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3539                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3540   "TARGET_SH2A"
3541   "shad %2,%0"
3542   [(set_attr "type" "dyn_shift")
3543    (set_attr "length" "4")])
3545 (define_insn "ashrsi3_k"
3546   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3547         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3548                      (match_operand:SI 2 "const_int_operand" "M")))
3549    (clobber (reg:SI T_REG))]
3550   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3551   "shar %0"
3552   [(set_attr "type" "arith")])
3554 ;; We can't do HImode right shifts correctly unless we start out with an
3555 ;; explicit zero / sign extension; doing that would result in worse overall
3556 ;; code, so just let the machine independent code widen the mode.
3557 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3560 ;; ??? This should be a define expand.
3562 (define_insn "ashrsi2_16"
3563   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3564         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3565                      (const_int 16)))]
3566   "TARGET_SH1"
3567   "#"
3568   [(set_attr "length" "4")])
3570 (define_split
3571   [(set (match_operand:SI 0 "arith_reg_dest" "")
3572         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3573                      (const_int 16)))]
3574   "TARGET_SH1"
3575   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3576    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3577   "operands[2] = gen_lowpart (HImode, operands[0]);")
3579 ;; ??? This should be a define expand.
3581 (define_insn "ashrsi2_31"
3582   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3583         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3584                      (const_int 31)))
3585    (clobber (reg:SI T_REG))]
3586   "TARGET_SH1"
3587   "#"
3588   [(set_attr "length" "4")])
3590 (define_split
3591   [(set (match_operand:SI 0 "arith_reg_dest" "")
3592         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3593                      (const_int 31)))
3594    (clobber (reg:SI T_REG))]
3595   "TARGET_SH1"
3596   [(const_int 0)]
3597   "
3599   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3600   emit_insn (gen_mov_neg_si_t (operands[0]));
3601   DONE;
3604 (define_peephole2
3605   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3606    (set (reg:SI T_REG)
3607         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3608   "TARGET_SH1
3609    && peep2_reg_dead_p (2, operands[0])
3610    && peep2_reg_dead_p (2, operands[1])"
3611   [(const_int 0)]
3612   "
3614   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3615   DONE;
3618 (define_insn "ashlsi_c"
3619   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3620         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3621    (set (reg:SI T_REG)
3622         (lt:SI (match_dup 1) (const_int 0)))]
3623   "TARGET_SH1"
3624   "shll %0"
3625   [(set_attr "type" "arith")])
3627 (define_insn "*ashlsi_c_void"
3628   [(set (reg:SI T_REG)
3629         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3630    (clobber (match_scratch:SI 1 "=0"))]
3631   "TARGET_SH1 && cse_not_expected"
3632   "shll %0"
3633   [(set_attr "type" "arith")])
3635 (define_insn "ashrsi3_d"
3636   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3637         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3638                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3639   "TARGET_SH3"
3640   "shad %2,%0"
3641   [(set_attr "type" "dyn_shift")])
3643 (define_insn "ashrsi3_n"
3644   [(set (reg:SI R4_REG)
3645         (ashiftrt:SI (reg:SI R4_REG)
3646                      (match_operand:SI 0 "const_int_operand" "i")))
3647    (clobber (reg:SI T_REG))
3648    (clobber (reg:SI PR_REG))
3649    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3650   "TARGET_SH1"
3651   "jsr  @%1%#"
3652   [(set_attr "type" "sfunc")
3653    (set_attr "needs_delay_slot" "yes")])
3655 (define_insn "ashrsi3_media"
3656   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3657         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3658                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3659   "TARGET_SHMEDIA"
3660   "@
3661         shard.l %1, %2, %0
3662         shari.l %1, %2, %0"
3663   [(set_attr "type" "arith_media")
3664    (set_attr "highpart" "ignore")])
3666 (define_expand "ashrsi3"
3667   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3668                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3669                                 (match_operand:SI 2 "nonmemory_operand" "")))
3670               (clobber (reg:SI T_REG))])]
3671   ""
3672   "
3674   if (TARGET_SHMEDIA)
3675     {
3676       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3677       DONE;
3678     }
3679   if (expand_ashiftrt (operands))
3680     DONE;
3681   else
3682     FAIL;
3685 ;; logical shift right
3687 (define_insn "lshrsi3_sh2a"
3688   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3689         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3690                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3691   "TARGET_SH2A"
3692   "shld %2,%0"
3693   [(set_attr "type" "dyn_shift")
3694    (set_attr "length" "4")])
3696 (define_insn "lshrsi3_d"
3697   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3698         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3699                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3700   "TARGET_SH3"
3701   "shld %2,%0"
3702   [(set_attr "type" "dyn_shift")])
3704 ;;  Only the single bit shift clobbers the T bit.
3706 (define_insn "lshrsi3_m"
3707   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3708         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3709                      (match_operand:SI 2 "const_int_operand" "M")))
3710    (clobber (reg:SI T_REG))]
3711   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3712   "shlr %0"
3713   [(set_attr "type" "arith")])
3715 (define_insn "lshrsi3_k"
3716   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3717         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3718                      (match_operand:SI 2 "const_int_operand" "P27")))]
3719   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3720    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3721   "shlr%O2      %0"
3722   [(set_attr "type" "arith")])
3724 (define_insn "lshrsi3_n"
3725   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3726         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3727                      (match_operand:SI 2 "const_int_operand" "n")))
3728    (clobber (reg:SI T_REG))]
3729   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3730   "#"
3731   [(set (attr "length")
3732         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3733                (const_string "2")
3734                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3735                (const_string "4")
3736                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3737                (const_string "6")]
3738               (const_string "8")))
3739    (set_attr "type" "arith")])
3741 (define_split
3742   [(set (match_operand:SI 0 "arith_reg_dest" "")
3743         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3744                      (match_operand:SI 2 "const_int_operand" "")))
3745    (clobber (reg:SI T_REG))]
3746   "TARGET_SH1 && reload_completed"
3747   [(use (reg:SI R0_REG))]
3748   "
3750   gen_shifty_op (LSHIFTRT, operands);
3751   DONE;
3754 (define_insn "lshrsi3_media"
3755   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3756         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3757                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3758   "TARGET_SHMEDIA"
3759   "@
3760         shlrd.l %1, %2, %0
3761         shlri.l %1, %2, %0"
3762   [(set_attr "type" "arith_media")
3763    (set_attr "highpart" "ignore")])
3765 (define_expand "lshrsi3"
3766   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3767                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3768                                 (match_operand:SI 2 "nonmemory_operand" "")))
3769               (clobber (reg:SI T_REG))])]
3770   ""
3771   "
3773   if (TARGET_SHMEDIA)
3774     {
3775       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3776       DONE;
3777     }
3778   if (GET_CODE (operands[2]) == CONST_INT
3779       && sh_dynamicalize_shift_p (operands[2]))
3780     operands[2] = force_reg (SImode, operands[2]);
3781   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3782     {
3783       rtx count = copy_to_mode_reg (SImode, operands[2]);
3784       emit_insn (gen_negsi2 (count, count));
3785       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3786       DONE;
3787     }
3788   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3789     FAIL;
3792 ;; ??? This should be a define expand.
3794 (define_insn "ashldi3_k"
3795   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3796         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3797                    (const_int 1)))
3798    (clobber (reg:SI T_REG))]
3799   "TARGET_SH1"
3800   "shll %R0\;rotcl      %S0"
3801   [(set_attr "length" "4")
3802    (set_attr "type" "arith")])
3804 (define_insn "ashldi3_media"
3805   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3806         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3807                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3808   "TARGET_SHMEDIA"
3809   "@
3810         shlld   %1, %2, %0
3811         shlli   %1, %2, %0"
3812   [(set_attr "type" "arith_media")])
3814 (define_insn "*ashldisi3_media"
3815   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3816         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3817                    (match_operand:DI 2 "const_int_operand" "n")))]
3818   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3819   "shlli.l      %1, %2, %0"
3820   [(set_attr "type" "arith_media")
3821    (set_attr "highpart" "ignore")])
3823 (define_expand "ashldi3"
3824   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3825                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3826                               (match_operand:DI 2 "immediate_operand" "")))
3827               (clobber (reg:SI T_REG))])]
3828   ""
3829   "
3831   if (TARGET_SHMEDIA)
3832     {
3833       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3834       DONE;
3835     }
3836   if (GET_CODE (operands[2]) != CONST_INT
3837       || INTVAL (operands[2]) != 1)
3838     FAIL;
3841 ;; ??? This should be a define expand.
3843 (define_insn "lshrdi3_k"
3844   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3845         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3846                      (const_int 1)))
3847    (clobber (reg:SI T_REG))]
3848   "TARGET_SH1"
3849   "shlr %S0\;rotcr      %R0"
3850   [(set_attr "length" "4")
3851    (set_attr "type" "arith")])
3853 (define_insn "lshrdi3_media"
3854   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3855         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3856                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3857   "TARGET_SHMEDIA
3858    && (arith_reg_dest (operands[0], DImode)
3859        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3860   "@
3861         shlrd   %1, %2, %0
3862         shlri   %1, %2, %0"
3863   [(set_attr "type" "arith_media")])
3865 (define_insn "*lshrdisi3_media"
3866   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3867         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3868                      (match_operand:DI 2 "const_int_operand" "n")))]
3869   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3870   "shlri.l      %1, %2, %0"
3871   [(set_attr "type" "arith_media")
3872    (set_attr "highpart" "ignore")])
3874 (define_expand "lshrdi3"
3875   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3876                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3877                                (match_operand:DI 2 "immediate_operand" "")))
3878              (clobber (reg:SI T_REG))])]
3879   ""
3880   "
3882   if (TARGET_SHMEDIA)
3883     {
3884       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3885       DONE;
3886     }
3887   if (GET_CODE (operands[2]) != CONST_INT
3888       || INTVAL (operands[2]) != 1)
3889     FAIL;
3892 ;; ??? This should be a define expand.
3894 (define_insn "ashrdi3_k"
3895   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3896         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3897                      (const_int 1)))
3898    (clobber (reg:SI T_REG))]
3899   "TARGET_SH1"
3900   "shar %S0\;rotcr      %R0"
3901   [(set_attr "length" "4")
3902    (set_attr "type" "arith")])
3904 (define_insn "ashrdi3_media"
3905   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3906         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3907                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3908   "TARGET_SHMEDIA
3909    && (arith_reg_dest (operands[0], DImode)
3910        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3911   "@
3912         shard   %1, %2, %0
3913         shari   %1, %2, %0"
3914   [(set_attr "type" "arith_media")])
3916 (define_insn "*ashrdisi3_media"
3917   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3918         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3919                      (match_operand:DI 2 "const_int_operand" "n")))]
3920   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3921   "shari.l      %1, %2, %0"
3922   [(set_attr "type" "arith_media")
3923    (set_attr "highpart" "ignore")])
3925 (define_insn "ashrdisi3_media_high"
3926   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3927         (truncate:SI
3928            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3929                         (match_operand:DI 2 "const_int_operand" "n"))))]
3930   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3931   "shari        %1, %2, %0"
3932   [(set_attr "type" "arith_media")])
3934 (define_insn "ashrdisi3_media_opaque"
3935   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3936         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3937                     (match_operand:DI 2 "const_int_operand" "n")]
3938          UNSPEC_ASHIFTRT))]
3939   "TARGET_SHMEDIA"
3940   "shari        %1, %2, %0"
3941   [(set_attr "type" "arith_media")])
3943 (define_expand "ashrdi3"
3944   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3945                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3946                                 (match_operand:DI 2 "immediate_operand" "")))
3947               (clobber (reg:SI T_REG))])]
3948   ""
3949   "
3951   if (TARGET_SHMEDIA)
3952     {
3953       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3954       DONE;
3955     }
3956   if (GET_CODE (operands[2]) != CONST_INT
3957       || INTVAL (operands[2]) != 1)
3958     FAIL;
3961 ;; combined left/right shift
3963 (define_split
3964   [(set (match_operand:SI 0 "register_operand" "")
3965         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3966                            (match_operand:SI 2 "const_int_operand" ""))
3967                 (match_operand:SI 3 "const_int_operand" "")))]
3968   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3969   [(use (reg:SI R0_REG))]
3970   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3971    DONE;")
3973 (define_split
3974   [(set (match_operand:SI 0 "register_operand" "")
3975         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3976                            (match_operand:SI 2 "const_int_operand" ""))
3977                 (match_operand:SI 3 "const_int_operand" "")))
3978    (clobber (reg:SI T_REG))]
3979   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3980   [(use (reg:SI R0_REG))]
3981   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3982    DONE;")
3984 (define_insn ""
3985   [(set (match_operand:SI 0 "register_operand" "=r")
3986         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3987                            (match_operand:SI 2 "const_int_operand" "n"))
3988                 (match_operand:SI 3 "const_int_operand" "n")))
3989    (clobber (reg:SI T_REG))]
3990   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3991  "#"
3992   [(set (attr "length")
3993         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3994                (const_string "4")
3995                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3996                (const_string "6")
3997                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3998                (const_string "8")
3999                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4000                (const_string "10")
4001                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4002                (const_string "12")
4003                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4004                (const_string "14")
4005                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4006                (const_string "16")]
4007               (const_string "18")))
4008    (set_attr "type" "arith")])
4010 (define_insn ""
4011   [(set (match_operand:SI 0 "register_operand" "=z")
4012         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4013                            (match_operand:SI 2 "const_int_operand" "n"))
4014                 (match_operand:SI 3 "const_int_operand" "n")))
4015    (clobber (reg:SI T_REG))]
4016   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4017  "#"
4018   [(set (attr "length")
4019         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4020                (const_string "4")
4021                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4022                (const_string "6")
4023                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4024                (const_string "8")]
4025               (const_string "10")))
4026    (set_attr "type" "arith")])
4028 ;; shift left / and combination with a scratch register: The combine pass
4029 ;; does not accept the individual instructions, even though they are
4030 ;; cheap.  But it needs a precise description so that it is usable after
4031 ;; reload.
4032 (define_insn "and_shl_scratch"
4033   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4034         (lshiftrt:SI
4035          (ashift:SI
4036           (and:SI
4037            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4038                         (match_operand:SI 2 "const_int_operand" "N,n"))
4039            (match_operand:SI 3 "" "0,r"))
4040           (match_operand:SI 4 "const_int_operand" "n,n"))
4041          (match_operand:SI 5 "const_int_operand" "n,n")))
4042    (clobber (reg:SI T_REG))]
4043   "TARGET_SH1"
4044   "#"
4045   [(set (attr "length")
4046         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4047                (const_string "4")
4048                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4049                (const_string "6")
4050                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4051                (const_string "8")
4052                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4053                (const_string "10")]
4054               (const_string "12")))
4055    (set_attr "type" "arith")])
4057 (define_split
4058   [(set (match_operand:SI 0 "register_operand" "")
4059         (lshiftrt:SI
4060          (ashift:SI
4061           (and:SI
4062            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4063                         (match_operand:SI 2 "const_int_operand" ""))
4064            (match_operand:SI 3 "register_operand" ""))
4065           (match_operand:SI 4 "const_int_operand" ""))
4066          (match_operand:SI 5 "const_int_operand" "")))
4067    (clobber (reg:SI T_REG))]
4068   "TARGET_SH1"
4069   [(use (reg:SI R0_REG))]
4070   "
4072   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4074   if (INTVAL (operands[2]))
4075     {
4076       gen_shifty_op (LSHIFTRT, operands);
4077     }
4078   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4079   operands[2] = operands[4];
4080   gen_shifty_op (ASHIFT, operands);
4081   if (INTVAL (operands[5]))
4082     {
4083       operands[2] = operands[5];
4084       gen_shifty_op (LSHIFTRT, operands);
4085     }
4086   DONE;
4089 ;; signed left/right shift combination.
4090 (define_split
4091   [(set (match_operand:SI 0 "register_operand" "")
4092         (sign_extract:SI
4093          (ashift:SI (match_operand:SI 1 "register_operand" "")
4094                     (match_operand:SI 2 "const_int_operand" ""))
4095          (match_operand:SI 3 "const_int_operand" "")
4096          (const_int 0)))
4097    (clobber (reg:SI T_REG))]
4098   "TARGET_SH1"
4099   [(use (reg:SI R0_REG))]
4100   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4101    DONE;")
4103 (define_insn "shl_sext_ext"
4104   [(set (match_operand:SI 0 "register_operand" "=r")
4105         (sign_extract:SI
4106          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4107                     (match_operand:SI 2 "const_int_operand" "n"))
4108          (match_operand:SI 3 "const_int_operand" "n")
4109          (const_int 0)))
4110    (clobber (reg:SI T_REG))]
4111   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4112   "#"
4113   [(set (attr "length")
4114         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4115                (const_string "2")
4116                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4117                (const_string "4")
4118                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4119                (const_string "6")
4120                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4121                (const_string "8")
4122                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4123                (const_string "10")
4124                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4125                (const_string "12")
4126                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4127                (const_string "14")
4128                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4129                (const_string "16")]
4130               (const_string "18")))
4131     (set_attr "type" "arith")])
4133 (define_insn "shl_sext_sub"
4134   [(set (match_operand:SI 0 "register_operand" "=z")
4135         (sign_extract:SI
4136          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4137                     (match_operand:SI 2 "const_int_operand" "n"))
4138          (match_operand:SI 3 "const_int_operand" "n")
4139          (const_int 0)))
4140    (clobber (reg:SI T_REG))]
4141   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4142   "#"
4143   [(set (attr "length")
4144         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4145                (const_string "6")
4146                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4147                (const_string "8")
4148                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4149                (const_string "10")
4150                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4151                (const_string "12")]
4152               (const_string "14")))
4153     (set_attr "type" "arith")])
4155 ;; These patterns are found in expansions of DImode shifts by 16, and
4156 ;; allow the xtrct instruction to be generated from C source.
4158 (define_insn "xtrct_left"
4159   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4160         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4161                            (const_int 16))
4162                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4163                              (const_int 16))))]
4164   "TARGET_SH1"
4165   "xtrct        %1,%0"
4166   [(set_attr "type" "arith")])
4168 (define_insn "xtrct_right"
4169   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4170         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4171                              (const_int 16))
4172                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4173                            (const_int 16))))]
4174   "TARGET_SH1"
4175   "xtrct        %2,%0"
4176   [(set_attr "type" "arith")])
4178 ;; -------------------------------------------------------------------------
4179 ;; Unary arithmetic
4180 ;; -------------------------------------------------------------------------
4182 (define_insn "negc"
4183   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4184         (neg:SI (plus:SI (reg:SI T_REG)
4185                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4186    (set (reg:SI T_REG)
4187         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4188                (const_int 0)))]
4189   "TARGET_SH1"
4190   "negc %1,%0"
4191   [(set_attr "type" "arith")])
4193 (define_insn "*negdi_media"
4194   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4195         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4196   "TARGET_SHMEDIA"
4197   "sub  r63, %1, %0"
4198   [(set_attr "type" "arith_media")])
4200 (define_expand "negdi2"
4201   [(set (match_operand:DI 0 "arith_reg_operand" "")
4202         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4203   ""
4204   "
4206   if (TARGET_SH1)
4207     {
4208       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4209       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4211       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4212       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4214       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4215       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4217       emit_insn (gen_clrt ());
4218       emit_insn (gen_negc (low_dst, low_src));
4219       emit_insn (gen_negc (high_dst, high_src));
4220       DONE;
4221     }
4224 (define_insn "negsi2"
4225   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4226         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4227   "TARGET_SH1"
4228   "neg  %1,%0"
4229   [(set_attr "type" "arith")])
4231 (define_insn "one_cmplsi2"
4232   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4233         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4234   "TARGET_SH1"
4235   "not  %1,%0"
4236   [(set_attr "type" "arith")])
4238 (define_expand "one_cmpldi2"
4239   [(set (match_operand:DI 0 "arith_reg_dest" "")
4240         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4241                 (const_int -1)))]
4242   "TARGET_SHMEDIA" "")
4244 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4245    This can be used as some kind of conditional execution, which is useful
4246    for abs.  */
4247 (define_split
4248   [(set (match_operand:SI 0 "arith_reg_dest" "")
4249         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4250                          (match_operand:SI 1 "arith_reg_operand" ""))
4251                  (reg:SI T_REG)))]
4252   "TARGET_HARD_SH4"
4253   [(const_int 0)]
4254   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4255    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4256    DONE;")
4258 (define_insn "cneg"
4259   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4260         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4261                       (match_operand:SI 1 "arith_reg_operand" "0")
4262                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4263   "TARGET_HARD_SH4"
4264   "bf 0f\;neg %2,%0\\n0:"
4265   [(set_attr "type" "arith") ;; poor approximation
4266    (set_attr "length" "4")])
4269 ;; -------------------------------------------------------------------------
4270 ;; Zero extension instructions
4271 ;; -------------------------------------------------------------------------
4273 (define_insn "zero_extendsidi2"
4274   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4275         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4276   "TARGET_SHMEDIA"
4277   "addz.l       %1, r63, %0"
4278   [(set_attr "type" "arith_media")
4279    (set_attr "highpart" "extend")])
4281 (define_insn "zero_extendhidi2"
4282   [(set (match_operand:DI 0 "register_operand" "=r,r")
4283         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4284   "TARGET_SHMEDIA"
4285   "@
4286         #
4287         ld%M1.uw        %m1, %0"
4288   [(set_attr "type" "*,load_media")
4289    (set (attr "highpart")
4290         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4291                (const_string "user")]
4292               (const_string "ignore")))])
4294 (define_split
4295   [(set (match_operand:DI 0 "register_operand" "")
4296         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4297   "TARGET_SHMEDIA && reload_completed"
4298   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4299    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4300   "
4302   if (GET_CODE (operands[1]) == TRUNCATE)
4303     operands[1] = XEXP (operands[1], 0);
4306 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4307 ;; reload the entire truncate expression.
4308 (define_insn_and_split "*loaddi_trunc"
4309   [(set (match_operand 0 "any_register_operand" "=r")
4310         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4311   "TARGET_SHMEDIA && reload_completed"
4312   "#"
4313   "TARGET_SHMEDIA && reload_completed"
4314   [(set (match_dup 0) (match_dup 1))]
4315   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4317 (define_insn "zero_extendqidi2"
4318   [(set (match_operand:DI 0 "register_operand" "=r,r")
4319         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4320   "TARGET_SHMEDIA"
4321   "@
4322         andi    %1, 255, %0
4323         ld%M1.ub        %m1, %0"
4324   [(set_attr "type" "arith_media,load_media")
4325    (set (attr "highpart")
4326         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4327                (const_string "user")]
4328               (const_string "ignore")))])
4330 (define_expand "zero_extendhisi2"
4331   [(set (match_operand:SI 0 "arith_reg_operand" "")
4332         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4333   ""
4334   "
4336   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4337     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4340 (define_insn "*zero_extendhisi2_compact"
4341   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4342         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4343   "TARGET_SH1"
4344   "extu.w       %1,%0"
4345   [(set_attr "type" "arith")])
4347 (define_insn "*zero_extendhisi2_media"
4348   [(set (match_operand:SI 0 "register_operand" "=r,r")
4349         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4350   "TARGET_SHMEDIA"
4351   "@
4352         #
4353         ld%M1.uw        %m1, %0"
4354   [(set_attr "type" "arith_media,load_media")
4355    (set (attr "highpart")
4356         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4357                (const_string "user")]
4358               (const_string "ignore")))])
4360 (define_split
4361   [(set (match_operand:SI 0 "register_operand" "")
4362         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4363   "TARGET_SHMEDIA && reload_completed"
4364   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4365    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4366   "
4368   rtx op1 = operands[1];
4370   if (GET_CODE (op1) == TRUNCATE)
4371     op1 = XEXP (op1, 0);
4372   operands[2]
4373     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4374                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4377 (define_expand "zero_extendqisi2"
4378   [(set (match_operand:SI 0 "arith_reg_operand" "")
4379         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4380   ""
4381   "
4383   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4384     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4387 (define_insn "*zero_extendqisi2_compact"
4388   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4389         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4390   "TARGET_SH1"
4391   "extu.b       %1,%0"
4392   [(set_attr "type" "arith")])
4394 (define_insn "*zero_extendqisi2_media"
4395   [(set (match_operand:SI 0 "register_operand" "=r,r")
4396         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4397   "TARGET_SHMEDIA"
4398   "@
4399         andi    %1, 255, %0
4400         ld%M1.ub        %m1, %0"
4401   [(set_attr "type" "arith_media,load_media")
4402    (set (attr "highpart")
4403         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4404                (const_string "user")]
4405               (const_string "ignore")))])
4407 (define_insn "zero_extendqihi2"
4408   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4409         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4410   "TARGET_SH1"
4411   "extu.b       %1,%0"
4412   [(set_attr "type" "arith")])
4414 ;; -------------------------------------------------------------------------
4415 ;; Sign extension instructions
4416 ;; -------------------------------------------------------------------------
4418 ;; ??? This should be a define expand.
4419 ;; ??? Or perhaps it should be dropped?
4421 ;; convert_move generates good code for SH[1-4].
4422 (define_insn "extendsidi2"
4423   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4424         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4425   "TARGET_SHMEDIA"
4426   "@
4427         add.l   %1, r63, %0
4428         ld%M1.l %m1, %0
4429         fmov.sl %1, %0"
4430   [(set_attr "type" "arith_media,load_media,fpconv_media")
4431    (set (attr "highpart")
4432         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4433                (const_string "user")]
4434               (const_string "extend")))])
4436 (define_insn "extendhidi2"
4437   [(set (match_operand:DI 0 "register_operand" "=r,r")
4438         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4439   "TARGET_SHMEDIA"
4440   "@
4441         #
4442         ld%M1.w %m1, %0"
4443   [(set_attr "type" "*,load_media")
4444    (set (attr "highpart")
4445         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4446                (const_string "user")]
4447               (const_string "ignore")))])
4449 (define_split
4450   [(set (match_operand:DI 0 "register_operand" "")
4451         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4452   "TARGET_SHMEDIA && reload_completed"
4453   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4454    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4455   "
4457   if (GET_CODE (operands[1]) == TRUNCATE)
4458     operands[1] = XEXP (operands[1], 0);
4461 (define_insn "extendqidi2"
4462   [(set (match_operand:DI 0 "register_operand" "=r,r")
4463         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4464   "TARGET_SHMEDIA"
4465   "@
4466         #
4467         ld%M1.b %m1, %0"
4468   [(set_attr "type" "*,load_media")
4469    (set (attr "highpart")
4470         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4471                (const_string "user")]
4472               (const_string "ignore")))])
4474 (define_split
4475   [(set (match_operand:DI 0 "register_operand" "")
4476         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4477   "TARGET_SHMEDIA && reload_completed"
4478   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4479    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4480   "
4482   if (GET_CODE (operands[1]) == TRUNCATE)
4483     operands[1] = XEXP (operands[1], 0);
4486 (define_expand "extendhisi2"
4487   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4488         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4489   ""
4490   "")
4492 (define_insn "*extendhisi2_compact"
4493   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4494         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4495   "TARGET_SH1"
4496   "@
4497         exts.w  %1,%0
4498         mov.w   %1,%0"
4499   [(set_attr "type" "arith,load")])
4501 (define_insn "*extendhisi2_media"
4502   [(set (match_operand:SI 0 "register_operand" "=r,r")
4503         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4504   "TARGET_SHMEDIA"
4505   "@
4506         #
4507         ld%M1.w %m1, %0"
4508   [(set_attr "type" "arith_media,load_media")
4509    (set (attr "highpart")
4510         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4511                (const_string "user")]
4512               (const_string "ignore")))])
4514 (define_split
4515   [(set (match_operand:SI 0 "register_operand" "")
4516         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4517   "TARGET_SHMEDIA && reload_completed"
4518   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4519    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4520   "
4522   rtx op1 = operands[1];
4523   if (GET_CODE (op1) == TRUNCATE)
4524     op1 = XEXP (op1, 0);
4525   operands[2]
4526     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4527                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4530 (define_expand "extendqisi2"
4531   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4532         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4533   ""
4534   "")
4536 (define_insn "*extendqisi2_compact"
4537   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4538         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4539   "TARGET_SH1"
4540   "@
4541         exts.b  %1,%0
4542         mov.b   %1,%0"
4543   [(set_attr "type" "arith,load")])
4545 (define_insn "*extendqisi2_media"
4546   [(set (match_operand:SI 0 "register_operand" "=r,r")
4547         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4548   "TARGET_SHMEDIA"
4549   "@
4550         #
4551         ld%M1.b %m1, %0"
4552   [(set_attr "type" "arith_media,load_media")
4553    (set (attr "highpart")
4554         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4555                (const_string "user")]
4556               (const_string "ignore")))])
4558 (define_split
4559   [(set (match_operand:SI 0 "register_operand" "")
4560         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4561   "TARGET_SHMEDIA && reload_completed"
4562   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4563    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4564    "
4566   rtx op1 = operands[1];
4567   if (GET_CODE (op1) == TRUNCATE)
4568     op1 = XEXP (op1, 0);
4569   operands[2]
4570     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4571                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4574 (define_insn "extendqihi2"
4575   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4576         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4577   "TARGET_SH1"
4578   "@
4579         exts.b  %1,%0
4580         mov.b   %1,%0"
4581   [(set_attr "type" "arith,load")])
4583 /* It would seem useful to combine the truncXi patterns into the movXi
4584    patterns, but unary operators are ignored when matching constraints,
4585    so we need separate patterns.  */
4586 (define_insn "truncdisi2"
4587   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4588         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4589   "TARGET_SHMEDIA"
4590   "@
4591         add.l   %1, r63, %0
4592         st%M0.l %m0, %1
4593         fst%M0.s        %m0, %T1
4594         fmov.ls %1, %0
4595         fmov.sl %T1, %0
4596         fmov.s  %T1, %0"
4597   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4598    (set (attr "highpart")
4599         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4600                (const_string "user")]
4601               (const_string "extend")))])
4603 (define_insn "truncdihi2"
4604   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4605         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4606   "TARGET_SHMEDIA"
4607   "@
4608         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4609         st%M0.w %m0, %1"
4610   [(set_attr "type"   "arith_media,store_media")
4611    (set_attr "length" "8,4")
4612    (set (attr "highpart")
4613         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4614                (const_string "user")]
4615               (const_string "extend")))])
4617 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4618 ; Because we use zero extension, we can't provide signed QImode compares
4619 ; using a simple compare or conditional banch insn.
4620 (define_insn "truncdiqi2"
4621   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4622         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4623   "TARGET_SHMEDIA"
4624   "@
4625         andi    %1, 255, %0
4626         st%M0.b %m0, %1"
4627   [(set_attr "type"   "arith_media,store")
4628    (set (attr "highpart")
4629         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4630                (const_string "user")]
4631               (const_string "extend")))])
4632 ;; -------------------------------------------------------------------------
4633 ;; Move instructions
4634 ;; -------------------------------------------------------------------------
4636 ;; define push and pop so it is easy for sh.c
4637 ;; We can't use push and pop on SHcompact because the stack must always
4638 ;; be 8-byte aligned.
4640 (define_expand "push"
4641   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4642         (match_operand:SI 0 "register_operand" "r,l,x"))]
4643   "TARGET_SH1 && ! TARGET_SH5"
4644   "")
4646 (define_expand "pop"
4647   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4648         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4649   "TARGET_SH1 && ! TARGET_SH5"
4650   "")
4652 (define_expand "push_e"
4653   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4654                    (match_operand:SF 0 "" ""))
4655               (use (reg:PSI FPSCR_REG))
4656               (clobber (scratch:SI))])]
4657   "TARGET_SH1 && ! TARGET_SH5"
4658   "")
4660 (define_insn "push_fpul"
4661   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4662   "TARGET_SH2E && ! TARGET_SH5"
4663   "sts.l        fpul,@-r15"
4664   [(set_attr "type" "store")
4665    (set_attr "late_fp_use" "yes")
4666    (set_attr "hit_stack" "yes")])
4668 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4669 ;; so use that.
4670 (define_expand "push_4"
4671   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4672                    (match_operand:DF 0 "" ""))
4673               (use (reg:PSI FPSCR_REG))
4674               (clobber (scratch:SI))])]
4675   "TARGET_SH1 && ! TARGET_SH5"
4676   "")
4678 (define_expand "pop_e"
4679   [(parallel [(set (match_operand:SF 0 "" "")
4680               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4681               (use (reg:PSI FPSCR_REG))
4682               (clobber (scratch:SI))])]
4683   "TARGET_SH1 && ! TARGET_SH5"
4684   "")
4686 (define_insn "pop_fpul"
4687   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4688   "TARGET_SH2E && ! TARGET_SH5"
4689   "lds.l        @r15+,fpul"
4690   [(set_attr "type" "load")
4691    (set_attr "hit_stack" "yes")])
4693 (define_expand "pop_4"
4694   [(parallel [(set (match_operand:DF 0 "" "")
4695                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4696               (use (reg:PSI FPSCR_REG))
4697               (clobber (scratch:SI))])]
4698   "TARGET_SH1 && ! TARGET_SH5"
4699   "")
4701 (define_expand "push_fpscr"
4702   [(const_int 0)]
4703   "TARGET_SH2E"
4704   "
4706   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4707                                                  gen_rtx_PRE_DEC (Pmode,
4708                                                           stack_pointer_rtx)),
4709                                         get_fpscr_rtx ()));
4710   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4711   DONE;
4714 (define_expand "pop_fpscr"
4715   [(const_int 0)]
4716   "TARGET_SH2E"
4717   "
4719   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4720                                         gen_frame_mem (PSImode,
4721                                                  gen_rtx_POST_INC (Pmode,
4722                                                           stack_pointer_rtx))));
4723   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4724   DONE;
4727 ;; These two patterns can happen as the result of optimization, when
4728 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4729 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4731 (define_insn "clrt"
4732   [(set (reg:SI T_REG) (const_int 0))]
4733   "TARGET_SH1"
4734   "clrt")
4736 (define_insn "sett"
4737   [(set (reg:SI T_REG) (const_int 1))]
4738   "TARGET_SH1"
4739   "sett")
4741 ;; t/r must come after r/r, lest reload will try to reload stuff like
4742 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4743 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4744 (define_insn "movsi_i"
4745   [(set (match_operand:SI 0 "general_movdst_operand"
4746             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4747         (match_operand:SI 1 "general_movsrc_operand"
4748          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4749   "TARGET_SH1
4750    && ! TARGET_SH2E
4751    && ! TARGET_SH2A
4752    && (register_operand (operands[0], SImode)
4753        || register_operand (operands[1], SImode))"
4754   "@
4755         mov.l   %1,%0
4756         mov     %1,%0
4757         cmp/pl  %1
4758         mov.l   %1,%0
4759         sts     %1,%0
4760         sts     %1,%0
4761         movt    %0
4762         mov.l   %1,%0
4763         sts.l   %1,%0
4764         sts.l   %1,%0
4765         lds     %1,%0
4766         lds     %1,%0
4767         lds.l   %1,%0
4768         lds.l   %1,%0
4769         fake    %1,%0"
4770   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4771    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4773 ;; t/r must come after r/r, lest reload will try to reload stuff like
4774 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4775 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4776 ;; will require a reload.
4777 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4778 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4779 (define_insn "movsi_ie"
4780   [(set (match_operand:SI 0 "general_movdst_operand"
4781             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4782         (match_operand:SI 1 "general_movsrc_operand"
4783          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4784   "(TARGET_SH2E || TARGET_SH2A)
4785    && (register_operand (operands[0], SImode)
4786        || register_operand (operands[1], SImode))"
4787   "@
4788         mov.l   %1,%0
4789         mov     %1,%0
4790         movi20  %1,%0
4791         cmp/pl  %1
4792         mov.l   %1,%0
4793         sts     %1,%0
4794         sts     %1,%0
4795         movt    %0
4796         mov.l   %1,%0
4797         sts.l   %1,%0
4798         sts.l   %1,%0
4799         lds     %1,%0
4800         lds     %1,%0
4801         lds.l   %1,%0
4802         lds.l   %1,%0
4803         lds.l   %1,%0
4804         sts.l   %1,%0
4805         fake    %1,%0
4806         lds     %1,%0
4807         sts     %1,%0
4808         fsts    fpul,%0
4809         flds    %1,fpul
4810         fmov    %1,%0
4811         ! move optimized away"
4812   [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4813    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4814    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4816 (define_insn "movsi_i_lowpart"
4817   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4818         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4819    "TARGET_SH1
4820     && (register_operand (operands[0], SImode)
4821         || register_operand (operands[1], SImode))"
4822   "@
4823         mov.l   %1,%0
4824         mov     %1,%0
4825         mov.l   %1,%0
4826         sts     %1,%0
4827         sts     %1,%0
4828         movt    %0
4829         mov.l   %1,%0
4830         fake    %1,%0"
4831   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4833 (define_insn_and_split "load_ra"
4834   [(set (match_operand:SI 0 "general_movdst_operand" "")
4835         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4836   "TARGET_SH1"
4837   "#"
4838   "&& ! currently_expanding_to_rtl"
4839   [(set (match_dup 0) (match_dup 1))]
4840   "
4842   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4843     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4846 ;; The '?'s in the following constraints may not reflect the time taken
4847 ;; to perform the move. They are there to discourage the use of floating-
4848 ;; point registers for storing integer values.
4849 (define_insn "*movsi_media"
4850   [(set (match_operand:SI 0 "general_movdst_operand"
4851                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4852         (match_operand:SI 1 "general_movsrc_operand"
4853          "r,I16C16,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4854   "TARGET_SHMEDIA_FPU
4855    && (register_operand (operands[0], SImode)
4856        || sh_register_operand (operands[1], SImode)
4857        || GET_CODE (operands[1]) == TRUNCATE)"
4858   "@
4859         add.l   %1, r63, %0
4860         movi    %1, %0
4861         #
4862         ld%M1.l %m1, %0
4863         st%M0.l %m0, %N1
4864         fld%M1.s        %m1, %0
4865         fst%M0.s        %m0, %1
4866         fmov.ls %N1, %0
4867         fmov.sl %1, %0
4868         fmov.s  %1, %0
4869         ptabs   %1, %0
4870         gettr   %1, %0
4871         pt      %1, %0"
4872   [(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")
4873    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4874    (set (attr "highpart")
4875         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4876                (const_string "user")]
4877               (const_string "ignore")))])
4879 (define_insn "*movsi_media_nofpu"
4880   [(set (match_operand:SI 0 "general_movdst_operand"
4881                 "=r,r,r,r,m,*b,r,*b")
4882         (match_operand:SI 1 "general_movsrc_operand"
4883          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
4884   "TARGET_SHMEDIA
4885    && (register_operand (operands[0], SImode)
4886        || sh_register_operand (operands[1], SImode)
4887        || GET_CODE (operands[1]) == TRUNCATE)"
4888   "@
4889         add.l   %1, r63, %0
4890         movi    %1, %0
4891         #
4892         ld%M1.l %m1, %0
4893         st%M0.l %m0, %N1
4894         ptabs   %1, %0
4895         gettr   %1, %0
4896         pt      %1, %0"
4897   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4898    (set_attr "length" "4,4,8,4,4,4,4,12")
4899    (set (attr "highpart")
4900         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4901                (const_string "user")]
4902               (const_string "ignore")))])
4904 (define_expand "movsi_const"
4905   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4906         (const:SI (sign_extend:SI
4907                    (truncate:HI
4908                     (ashiftrt:SI
4909                      (match_operand:DI 1 "immediate_operand" "s")
4910                      (const_int 16))))))
4911    (set (match_dup 0)
4912         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4913                 (zero_extend:SI
4914                  (truncate:HI
4915                   (const:SI
4916                    (sign_extend:SI
4917                     (truncate:HI (match_dup 1))))))))]
4918   "TARGET_SHMEDIA && reload_completed
4919    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4920   "
4922   if (GET_CODE (operands[1]) == LABEL_REF
4923       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4924     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4925   else if (GOTOFF_P (operands[1]))
4926     {
4927       rtx unspec = XEXP (operands[1], 0);
4929       if (! UNSPEC_GOTOFF_P (unspec))
4930         {
4931           unspec = XEXP (unspec, 0);
4932           if (! UNSPEC_GOTOFF_P (unspec))
4933             abort ();
4934         }
4935       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4936           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4937         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4938     }
4941 (define_expand "movsi_const_16bit"
4942   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4943         (const:SI (sign_extend:SI
4944                    (truncate:HI
4945                     (match_operand:DI 1 "immediate_operand" "s")))))]
4946   "TARGET_SHMEDIA && flag_pic && reload_completed
4947    && GET_CODE (operands[1]) == SYMBOL_REF"
4948   "")
4950 (define_split
4951   [(set (match_operand:SI 0 "arith_reg_dest" "")
4952         (match_operand:SI 1 "immediate_operand" ""))]
4953   "TARGET_SHMEDIA && reload_completed
4954    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4955   [(const_int 0)]
4956   "
4958   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4960   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4961                                         REG_NOTES (insn));
4963   DONE;
4966 (define_split
4967   [(set (match_operand:SI 0 "register_operand" "")
4968         (match_operand:SI 1 "immediate_operand" ""))]
4969   "TARGET_SHMEDIA && reload_completed
4970    && ((GET_CODE (operands[1]) == CONST_INT
4971         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4972        || GET_CODE (operands[1]) == CONST_DOUBLE)"
4973   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4975 (define_expand "movsi"
4976   [(set (match_operand:SI 0 "general_movdst_operand" "")
4977         (match_operand:SI 1 "general_movsrc_operand" ""))]
4978   ""
4979   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4981 (define_expand "ic_invalidate_line"
4982   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4983                                 (match_dup 1)] UNSPEC_ICACHE)
4984               (clobber (scratch:SI))])]
4985   "TARGET_HARD_SH4 || TARGET_SH5"
4986   "
4988   if (TARGET_SHMEDIA)
4989     {
4990       emit_insn (gen_ic_invalidate_line_media (operands[0]));
4991       DONE;
4992     }
4993   else if (TARGET_SHCOMPACT)
4994     {
4995       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4996       operands[1] = force_reg (Pmode, operands[1]);
4997       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
4998       DONE;
4999     }
5000   else if (TARGET_SH4A_ARCH)
5001     {
5002       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5003       DONE;
5004     }
5005   operands[0] = force_reg (Pmode, operands[0]);
5006   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5007                                                                Pmode)));
5010 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5011 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5012 ;; the requirement *1*00 for associative address writes.  The alignment of
5013 ;; %0 implies that its least significant bit is cleared,
5014 ;; thus we clear the V bit of a matching entry if there is one.
5015 (define_insn "ic_invalidate_line_i"
5016   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5017                      (match_operand:SI 1 "register_operand" "r")]
5018                      UNSPEC_ICACHE)
5019    (clobber (match_scratch:SI 2 "=&r"))]
5020   "TARGET_HARD_SH4"
5021   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5022   [(set_attr "length" "8")
5023    (set_attr "type" "cwb")])
5025 (define_insn "ic_invalidate_line_sh4a"
5026   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5027                     UNSPEC_ICACHE)]
5028   "TARGET_SH4A_ARCH"
5029   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5030   [(set_attr "length" "16")
5031    (set_attr "type" "cwb")])
5033 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5034 ;; an add in the code that calculates the address.
5035 (define_insn "ic_invalidate_line_media"
5036   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5037                     UNSPEC_ICACHE)]
5038   "TARGET_SHMEDIA"
5039   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5040   [(set_attr "length" "16")
5041    (set_attr "type" "invalidate_line_media")])
5043 (define_insn "ic_invalidate_line_compact"
5044   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5045                      (match_operand:SI 1 "register_operand" "r")]
5046                     UNSPEC_ICACHE)
5047    (clobber (reg:SI PR_REG))]
5048   "TARGET_SHCOMPACT"
5049   "jsr @%1%#"
5050   [(set_attr "type" "sfunc")
5051    (set_attr "needs_delay_slot" "yes")])
5053 (define_expand "initialize_trampoline"
5054   [(match_operand:SI 0 "" "")
5055    (match_operand:SI 1 "" "")
5056    (match_operand:SI 2 "" "")]
5057   "TARGET_SHCOMPACT"
5058   "
5060   rtx sfun, tramp;
5062   tramp = force_reg (Pmode, operands[0]);
5063   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5064                                             SFUNC_STATIC));
5065   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5066   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5068   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5069   DONE;
5072 (define_insn "initialize_trampoline_compact"
5073   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5074                      (match_operand:SI 1 "register_operand" "r")
5075                      (reg:SI R2_REG) (reg:SI R3_REG)]
5076                     UNSPEC_INIT_TRAMP)
5078    (clobber (reg:SI PR_REG))]
5079   "TARGET_SHCOMPACT"
5080   "jsr @%1%#"
5081   [(set_attr "type" "sfunc")
5082    (set_attr "needs_delay_slot" "yes")])
5084 (define_insn "movqi_i"
5085   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5086         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
5087   "TARGET_SH1
5088    && (arith_reg_operand (operands[0], QImode)
5089        || arith_reg_operand (operands[1], QImode))"
5090   "@
5091         mov     %1,%0
5092         mov.b   %1,%0
5093         mov.b   %1,%0
5094         movt    %0
5095         sts     %1,%0
5096         lds     %1,%0"
5097  [(set_attr "type" "move,load,store,move,move,move")])
5099 (define_insn "*movqi_media"
5100   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5101         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
5102   "TARGET_SHMEDIA
5103    && (arith_reg_operand (operands[0], QImode)
5104        || extend_reg_or_0_operand (operands[1], QImode))"
5105   "@
5106         add.l   %1, r63, %0
5107         movi    %1, %0
5108         ld%M1.ub        %m1, %0
5109         st%M0.b %m0, %N1"
5110   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5111    (set (attr "highpart")
5112         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5113                (const_string "user")]
5114               (const_string "ignore")))])
5116 (define_expand "movqi"
5117   [(set (match_operand:QI 0 "general_operand" "")
5118         (match_operand:QI 1 "general_operand"  ""))]
5119   ""
5120   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5122 (define_expand "reload_inqi"
5123   [(set (match_operand:SI 2 "" "=&r")
5124         (match_operand:QI 1 "inqhi_operand" ""))
5125    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5126         (truncate:QI (match_dup 3)))]
5127   "TARGET_SHMEDIA"
5128   "
5130   rtx inner = XEXP (operands[1], 0);
5131   int regno = REGNO (inner);
5133   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5134   operands[1] = gen_rtx_REG (SImode, regno);
5135   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5138 /* When storing r0, we have to avoid reg+reg addressing.  */
5139 (define_insn "movhi_i"
5140   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5141         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5142   "TARGET_SH1
5143    && (arith_reg_operand (operands[0], HImode)
5144        || arith_reg_operand (operands[1], HImode))
5145    && (GET_CODE (operands[0]) != MEM
5146        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5147        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5148        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5149   "@
5150         mov.w   %1,%0
5151         mov     %1,%0
5152         mov.w   %1,%0
5153         movt    %0
5154         mov.w   %1,%0
5155         sts     %1,%0
5156         lds     %1,%0
5157         fake    %1,%0"
5158   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5160 (define_insn "*movhi_media"
5161   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5162         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
5163   "TARGET_SHMEDIA
5164    && (arith_reg_operand (operands[0], HImode)
5165        || arith_reg_or_0_operand (operands[1], HImode))"
5166   "@
5167         add.l   %1, r63, %0
5168         movi    %1, %0
5169         #
5170         ld%M1.w %m1, %0
5171         st%M0.w %m0, %N1"
5172   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5173    (set (attr "highpart")
5174         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5175                (const_string "user")]
5176               (const_string "ignore")))])
5178 (define_split
5179   [(set (match_operand:HI 0 "register_operand" "")
5180         (match_operand:HI 1 "immediate_operand" ""))]
5181   "TARGET_SHMEDIA && reload_completed
5182    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5183   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5185 (define_expand "movhi"
5186   [(set (match_operand:HI 0 "general_movdst_operand" "")
5187         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5188   ""
5189   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5191 (define_expand "reload_inhi"
5192   [(set (match_operand:SI 2 "" "=&r")
5193         (match_operand:HI 1 "inqhi_operand" ""))
5194    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5195         (truncate:HI (match_dup 3)))]
5196   "TARGET_SHMEDIA"
5197   "
5199   rtx inner = XEXP (operands[1], 0);
5200   int regno = REGNO (inner);
5202   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5203   operands[1] = gen_rtx_REG (SImode, regno);
5204   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5207 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5208 ;; compiled with -m2 -ml -O3 -funroll-loops
5209 (define_insn "*movdi_i"
5210   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5211         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5212   "TARGET_SH1
5213    && (arith_reg_operand (operands[0], DImode)
5214        || arith_reg_operand (operands[1], DImode))"
5215   "* return output_movedouble (insn, operands, DImode);"
5216   [(set_attr "length" "4")
5217    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5219 ;; If the output is a register and the input is memory or a register, we have
5220 ;; to be careful and see which word needs to be loaded first.
5222 (define_split
5223   [(set (match_operand:DI 0 "general_movdst_operand" "")
5224         (match_operand:DI 1 "general_movsrc_operand" ""))]
5225   "TARGET_SH1 && reload_completed"
5226   [(set (match_dup 2) (match_dup 3))
5227    (set (match_dup 4) (match_dup 5))]
5228   "
5230   int regno;
5232   if ((GET_CODE (operands[0]) == MEM
5233        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5234       || (GET_CODE (operands[1]) == MEM
5235           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5236     FAIL;
5238   switch (GET_CODE (operands[0]))
5239     {
5240     case REG:
5241       regno = REGNO (operands[0]);
5242       break;
5243     case SUBREG:
5244       regno = subreg_regno (operands[0]);
5245       break;
5246     case MEM:
5247       regno = -1;
5248       break;
5249     default:
5250       gcc_unreachable ();
5251     }
5253   if (regno == -1
5254       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5255     {
5256       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5257       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5258       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5259       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5260     }
5261   else
5262     {
5263       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5264       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5265       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5266       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5267     }
5269   if (operands[2] == 0 || operands[3] == 0
5270       || operands[4] == 0 || operands[5] == 0)
5271     FAIL;
5274 ;; The '?'s in the following constraints may not reflect the time taken
5275 ;; to perform the move. They are there to discourage the use of floating-
5276 ;; point registers for storing integer values.
5277 (define_insn "*movdi_media"
5278   [(set (match_operand:DI 0 "general_movdst_operand"
5279                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5280         (match_operand:DI 1 "general_movsrc_operand"
5281          "r,I16C16,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5282   "TARGET_SHMEDIA_FPU
5283    && (register_operand (operands[0], DImode)
5284        || sh_register_operand (operands[1], DImode))"
5285   "@
5286         add     %1, r63, %0
5287         movi    %1, %0
5288         #
5289         ld%M1.q %m1, %0
5290         st%M0.q %m0, %N1
5291         fld%M1.d        %m1, %0
5292         fst%M0.d        %m0, %1
5293         fmov.qd %N1, %0
5294         fmov.dq %1, %0
5295         fmov.d  %1, %0
5296         ptabs   %1, %0
5297         gettr   %1, %0
5298         pt      %1, %0"
5299   [(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")
5300    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5302 (define_insn "*movdi_media_nofpu"
5303   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5304         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
5305   "TARGET_SHMEDIA
5306    && (register_operand (operands[0], DImode)
5307        || sh_register_operand (operands[1], DImode))"
5308   "@
5309         add     %1, r63, %0
5310         movi    %1, %0
5311         #
5312         ld%M1.q %m1, %0
5313         st%M0.q %m0, %N1
5314         ptabs   %1, %0
5315         gettr   %1, %0
5316         pt      %1, %0"
5317   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5318    (set_attr "length" "4,4,16,4,4,4,4,*")])
5320 (define_insn "*movdi_media_I16"
5321   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5322         (match_operand:DI 1 "const_int_operand" "I16"))]
5323   "TARGET_SHMEDIA && reload_completed"
5324   "movi %1, %0"
5325   [(set_attr "type" "arith_media")
5326    (set_attr "length" "4")])
5328 (define_split
5329   [(set (match_operand:DI 0 "arith_reg_dest" "")
5330         (match_operand:DI 1 "immediate_operand" ""))]
5331   "TARGET_SHMEDIA && reload_completed
5332    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5333   [(set (match_dup 0) (match_dup 1))]
5334   "
5336   rtx insn;
5338   if (TARGET_SHMEDIA64)
5339     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5340   else
5341     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5343   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5344                                         REG_NOTES (insn));
5346   DONE;
5349 (define_expand "movdi_const"
5350   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5351         (const:DI (sign_extend:DI
5352                    (truncate:HI
5353                     (ashiftrt:DI
5354                      (match_operand:DI 1 "immediate_operand" "s")
5355                      (const_int 48))))))
5356    (set (match_dup 0)
5357         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5358                 (zero_extend:DI
5359                  (truncate:HI
5360                   (const:DI
5361                    (sign_extend:DI
5362                     (truncate:HI
5363                      (ashiftrt:SI
5364                       (match_dup 1)
5365                       (const_int 32)))))))))
5366    (set (match_dup 0)
5367         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5368                 (zero_extend:DI
5369                  (truncate:HI
5370                   (const:DI
5371                    (sign_extend:DI
5372                     (truncate:HI
5373                      (ashiftrt:SI
5374                       (match_dup 1)
5375                       (const_int 16)))))))))
5376    (set (match_dup 0)
5377         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5378                 (zero_extend:DI
5379                  (truncate:HI
5380                   (const:DI
5381                    (sign_extend:DI
5382                     (truncate:HI
5383                      (match_dup 1))))))))]
5384   "TARGET_SHMEDIA64 && reload_completed
5385    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5386   "
5388   sh_mark_label (operands[1], 4);
5391 (define_expand "movdi_const_32bit"
5392   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5393         (const:DI (sign_extend:DI
5394                    (truncate:HI
5395                     (ashiftrt:DI
5396                      (match_operand:DI 1 "immediate_operand" "s")
5397                      (const_int 16))))))
5398    (set (match_dup 0)
5399         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5400                 (zero_extend:DI
5401                  (truncate:HI
5402                   (const:DI
5403                    (sign_extend:DI
5404                     (truncate:HI
5405                      (match_dup 1))))))))]
5406   "TARGET_SHMEDIA32 && reload_completed
5407    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5408   "
5410   sh_mark_label (operands[1], 2);
5413 (define_expand "movdi_const_16bit"
5414   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5415         (const:DI (sign_extend:DI
5416                    (truncate:HI
5417                     (match_operand:DI 1 "immediate_operand" "s")))))]
5418   "TARGET_SHMEDIA && flag_pic && reload_completed
5419    && GET_CODE (operands[1]) == SYMBOL_REF"
5420   "")
5422 (define_split
5423   [(set (match_operand:DI 0 "ext_dest_operand" "")
5424         (match_operand:DI 1 "immediate_operand" ""))]
5425   "TARGET_SHMEDIA && reload_completed
5426    && GET_CODE (operands[1]) == CONST_INT
5427    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5428   [(set (match_dup 0) (match_dup 2))
5429    (match_dup 1)]
5430   "
5432   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5433   unsigned HOST_WIDE_INT low = val;
5434   unsigned HOST_WIDE_INT high = val;
5435   unsigned HOST_WIDE_INT sign;
5436   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5438   /* Sign-extend the 16 least-significant bits.  */
5439   low &= 0xffff;
5440   low ^= 0x8000;
5441   low -= 0x8000;
5443   /* Arithmetic shift right the word by 16 bits.  */
5444   high >>= 16;
5445   if (GET_CODE (operands[0]) == SUBREG
5446       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5447     {
5448       high &= 0xffff;
5449       high ^= 0x8000;
5450       high -= 0x8000;
5451     }
5452   else
5453     {
5454       sign = 1;
5455       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5456       high ^= sign;
5457       high -= sign;
5458     }
5459   do
5460     {
5461       /* If we can't generate the constant with a two-insn movi / shori
5462          sequence, try some other strategies.  */
5463       if (! CONST_OK_FOR_I16 (high))
5464         {
5465           /* Try constant load / left shift.  We know VAL != 0.  */
5466           val2 = val ^ (val-1);
5467           if (val2 > 0x1ffff)
5468             {
5469               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5471               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5472                   || (! CONST_OK_FOR_I16 (high >> 16)
5473                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5474                 {
5475                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5476                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5477                                                    GEN_INT (trailing_zeroes));
5478                   break;
5479                 }
5480             }
5481           /* Try constant load / right shift.  */
5482           val2 = (val >> 15) + 1;
5483           if (val2 == (val2 & -val2))
5484             {
5485               int shift = 49 - exact_log2 (val2);
5487               val2 = trunc_int_for_mode (val << shift, DImode);
5488               if (CONST_OK_FOR_I16 (val2))
5489                 {
5490                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5491                                                    GEN_INT (shift));
5492                   break;
5493                 }
5494             }
5495           /* Try mperm.w .  */
5496           val2 = val & 0xffff;
5497           if ((val >> 16 & 0xffff) == val2
5498               && (val >> 32 & 0xffff) == val2
5499               && (val >> 48 & 0xffff) == val2)
5500             {
5501               val2 = (HOST_WIDE_INT) val >> 48;
5502               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5503               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5504               break;
5505             }
5506           /* Try movi / mshflo.l  */
5507           val2 = (HOST_WIDE_INT) val >> 32;
5508           if (val2 == ((unsigned HOST_WIDE_INT)
5509                         trunc_int_for_mode (val, SImode)))
5510             {
5511               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5512                                              operands[0]);
5513               break;
5514             }
5515           /* Try movi / mshflo.l w/ r63.  */
5516           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5517           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5518             {
5519               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5520                                              const0_rtx);
5521               break;
5522             }
5523         }
5524       val2 = high;
5525       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5526     }
5527   while (0);
5528   operands[2] = GEN_INT (val2);
5531 (define_split
5532   [(set (match_operand:DI 0 "ext_dest_operand" "")
5533         (match_operand:DI 1 "immediate_operand" ""))]
5534   "TARGET_SHMEDIA && reload_completed
5535    && GET_CODE (operands[1]) == CONST_DOUBLE"
5536   [(set (match_dup 0) (match_dup 2))
5537   (set (match_dup 0)
5538        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5539                (zero_extend:DI (truncate:HI (match_dup 1)))))]
5540   "
5542   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5543   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5544   unsigned HOST_WIDE_INT val = low;
5545   unsigned HOST_WIDE_INT sign;
5547   /* Sign-extend the 16 least-significant bits.  */
5548   val &= 0xffff;
5549   val ^= 0x8000;
5550   val -= 0x8000;
5551   operands[1] = GEN_INT (val);
5553   /* Arithmetic shift right the double-word by 16 bits.  */
5554   low >>= 16;
5555   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5556   high >>= 16;
5557   sign = 1;
5558   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5559   high ^= sign;
5560   high -= sign;
5562   /* This will only be true if high is a sign-extension of low, i.e.,
5563      it must be either 0 or (unsigned)-1, and be zero iff the
5564      most-significant bit of low is set.  */
5565   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5566     operands[2] = GEN_INT (low);
5567   else
5568     operands[2] = immed_double_const (low, high, DImode);
5571 (define_insn "shori_media"
5572   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5573         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5574                            (const_int 16))
5575                 (zero_extend:DI
5576                  (truncate:HI
5577                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
5578   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5579   "@
5580         shori   %u2, %0
5581         #"
5582   [(set_attr "type" "arith_media,*")])
5584 (define_insn "*shori_media_si"
5585   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5586         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5587                            (const_int 16))
5588                 (zero_extend:SI
5589                  (truncate:HI
5590                   (match_operand:SI 2 "immediate_operand" "I16C16")))))]
5591   "TARGET_SHMEDIA"
5592   "shori        %u2, %0")
5594 (define_expand "movdi"
5595   [(set (match_operand:DI 0 "general_movdst_operand" "")
5596         (match_operand:DI 1 "general_movsrc_operand" ""))]
5597   ""
5598   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5600 (define_insn "movdf_media"
5601   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5602         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5603   "TARGET_SHMEDIA_FPU
5604    && (register_operand (operands[0], DFmode)
5605        || sh_register_operand (operands[1], DFmode))"
5606   "@
5607         fmov.d  %1, %0
5608         fmov.qd %N1, %0
5609         fmov.dq %1, %0
5610         add     %1, r63, %0
5611         #
5612         fld%M1.d        %m1, %0
5613         fst%M0.d        %m0, %1
5614         ld%M1.q %m1, %0
5615         st%M0.q %m0, %N1"
5616   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5618 (define_insn "movdf_media_nofpu"
5619   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5620         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5621   "TARGET_SHMEDIA
5622    && (register_operand (operands[0], DFmode)
5623        || sh_register_operand (operands[1], DFmode))"
5624   "@
5625         add     %1, r63, %0
5626         #
5627         ld%M1.q %m1, %0
5628         st%M0.q %m0, %N1"
5629   [(set_attr "type" "arith_media,*,load_media,store_media")])
5631 (define_split
5632   [(set (match_operand:DF 0 "arith_reg_dest" "")
5633         (match_operand:DF 1 "immediate_operand" ""))]
5634   "TARGET_SHMEDIA && reload_completed"
5635   [(set (match_dup 3) (match_dup 2))]
5636   "
5638   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5639   long values[2];
5640   REAL_VALUE_TYPE value;
5642   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5643   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5645   if (HOST_BITS_PER_WIDE_INT >= 64)
5646     operands[2] = immed_double_const ((unsigned long) values[endian]
5647                                       | ((HOST_WIDE_INT) values[1 - endian]
5648                                          << 32), 0, DImode);
5649   else
5650     {
5651       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5652       operands[2] = immed_double_const (values[endian], values[1 - endian],
5653                                         DImode);
5654     }
5656   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5659 ;; ??? This should be a define expand.
5661 (define_insn "movdf_k"
5662   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5663         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5664   "TARGET_SH1
5665    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5666        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5667        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5668        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5669    && (arith_reg_operand (operands[0], DFmode)
5670        || arith_reg_operand (operands[1], DFmode))"
5671   "* return output_movedouble (insn, operands, DFmode);"
5672   [(set_attr "length" "4")
5673    (set_attr "type" "move,pcload,load,store")])
5675 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5676 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5677 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5678 ;; the d/m/c/X alternative, which is split later into single-precision
5679 ;; instructions.  And when not optimizing, no splits are done before fixing
5680 ;; up pcloads, so we need usable length information for that.
5681 (define_insn "movdf_i4"
5682   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5683         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5684    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5685    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5686   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5687    && (arith_reg_operand (operands[0], DFmode)
5688        || arith_reg_operand (operands[1], DFmode))"
5689   "@
5690         fmov    %1,%0
5691         #
5692         #
5693         fmov.d  %1,%0
5694         fmov.d  %1,%0
5695         #
5696         #
5697         #
5698         #
5699         #"
5700   [(set_attr_alternative "length"
5701      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5702       (const_int 4)
5703       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5704       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5705       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5706       (const_int 4)
5707       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5708       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5709       ;; increment or decrement r15 explicitly.
5710       (if_then_else
5711        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5712        (const_int 10) (const_int 8))
5713       (if_then_else
5714        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5715        (const_int 10) (const_int 8))])
5716    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5717    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5718    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5719                                            (const_string "double")
5720                                            (const_string "none")))])
5722 ;; Moving DFmode between fp/general registers through memory
5723 ;; (the top of the stack) is faster than moving through fpul even for
5724 ;; little endian.  Because the type of an instruction is important for its
5725 ;; scheduling,  it is beneficial to split these operations, rather than
5726 ;; emitting them in one single chunk, even if this will expose a stack
5727 ;; use that will prevent scheduling of other stack accesses beyond this
5728 ;; instruction.
5729 (define_split
5730   [(set (match_operand:DF 0 "register_operand" "")
5731         (match_operand:DF 1 "register_operand" ""))
5732    (use (match_operand:PSI 2 "fpscr_operand" ""))
5733    (clobber (match_scratch:SI 3 "=X"))]
5734   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5735    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5736   [(const_int 0)]
5737   "
5739   rtx insn, tos;
5741   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5742     {
5743       emit_move_insn (stack_pointer_rtx,
5744                       plus_constant (stack_pointer_rtx, -8));
5745       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5746     }
5747   else
5748     tos = gen_tmp_stack_mem (DFmode,
5749                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5750   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5751   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5752     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5753   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5754     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5755   else
5756     tos = gen_tmp_stack_mem (DFmode,
5757                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5758   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5759   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5760     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5761   else
5762     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5763   DONE;
5766 ;; local-alloc sometimes allocates scratch registers even when not required,
5767 ;; so we must be prepared to handle these.
5769 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5770 (define_split
5771   [(set (match_operand:DF 0 "general_movdst_operand" "")
5772         (match_operand:DF 1 "general_movsrc_operand"  ""))
5773    (use (match_operand:PSI 2 "fpscr_operand" ""))
5774    (clobber (match_scratch:SI 3 ""))]
5775   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5776    && reload_completed
5777    && true_regnum (operands[0]) < 16
5778    && true_regnum (operands[1]) < 16"
5779   [(set (match_dup 0) (match_dup 1))]
5780   "
5782   /* If this was a reg <-> mem operation with base + index reg addressing,
5783      we have to handle this in a special way.  */
5784   rtx mem = operands[0];
5785   int store_p = 1;
5786   if (! memory_operand (mem, DFmode))
5787     {
5788       mem = operands[1];
5789       store_p = 0;
5790     }
5791   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5792     mem = SUBREG_REG (mem);
5793   if (GET_CODE (mem) == MEM)
5794     {
5795       rtx addr = XEXP (mem, 0);
5796       if (GET_CODE (addr) == PLUS
5797           && GET_CODE (XEXP (addr, 0)) == REG
5798           && GET_CODE (XEXP (addr, 1)) == REG)
5799         {
5800           int offset;
5801           rtx reg0 = gen_rtx_REG (Pmode, 0);
5802           rtx regop = operands[store_p], word0 ,word1;
5804           if (GET_CODE (regop) == SUBREG)
5805             alter_subreg (&regop);
5806           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5807             offset = 2;
5808           else
5809             offset = 4;
5810           mem = copy_rtx (mem);
5811           PUT_MODE (mem, SImode);
5812           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5813           alter_subreg (&word0);
5814           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5815           alter_subreg (&word1);
5816           if (store_p || ! refers_to_regno_p (REGNO (word0),
5817                                               REGNO (word0) + 1, addr, 0))
5818             {
5819               emit_insn (store_p
5820                          ? gen_movsi_ie (mem, word0)
5821                          : gen_movsi_ie (word0, mem));
5822               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5823               mem = copy_rtx (mem);
5824               emit_insn (store_p
5825                          ? gen_movsi_ie (mem, word1)
5826                          : gen_movsi_ie (word1, mem));
5827               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5828             }
5829           else
5830             {
5831               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5832               emit_insn (gen_movsi_ie (word1, mem));
5833               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5834               mem = copy_rtx (mem);
5835               emit_insn (gen_movsi_ie (word0, mem));
5836             }
5837           DONE;
5838         }
5839     }
5842 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5843 (define_split
5844   [(set (match_operand:DF 0 "register_operand" "")
5845         (match_operand:DF 1 "memory_operand"  ""))
5846    (use (match_operand:PSI 2 "fpscr_operand" ""))
5847    (clobber (reg:SI R0_REG))]
5848   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5849   [(parallel [(set (match_dup 0) (match_dup 1))
5850               (use (match_dup 2))
5851               (clobber (scratch:SI))])]
5852   "")
5854 (define_expand "reload_indf"
5855   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
5856                    (match_operand:DF 1 "immediate_operand" "FQ"))
5857               (use (reg:PSI FPSCR_REG))
5858               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5859   "TARGET_SH1"
5860   "")
5862 (define_expand "reload_outdf"
5863   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5864                    (match_operand:DF 1 "register_operand" "af,r"))
5865               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5866   "TARGET_SH1"
5867   "")
5869 ;; Simplify no-op moves.
5870 (define_split
5871   [(set (match_operand:SF 0 "register_operand" "")
5872         (match_operand:SF 1 "register_operand" ""))
5873    (use (match_operand:PSI 2 "fpscr_operand" ""))
5874    (clobber (match_scratch:SI 3 ""))]
5875   "TARGET_SH2E && reload_completed
5876    && true_regnum (operands[0]) == true_regnum (operands[1])"
5877   [(set (match_dup 0) (match_dup 0))]
5878   "")
5880 ;; fmovd substitute post-reload splits
5881 (define_split
5882   [(set (match_operand:DF 0 "register_operand" "")
5883         (match_operand:DF 1 "register_operand" ""))
5884    (use (match_operand:PSI 2 "fpscr_operand" ""))
5885    (clobber (match_scratch:SI 3 ""))]
5886   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5887    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5888    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5889   [(const_int 0)]
5890   "
5892   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5893   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5894                            gen_rtx_REG (SFmode, src), operands[2]));
5895   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5896                            gen_rtx_REG (SFmode, src + 1), operands[2]));
5897   DONE;
5900 (define_split
5901   [(set (match_operand:DF 0 "register_operand" "")
5902         (mem:DF (match_operand:SI 1 "register_operand" "")))
5903    (use (match_operand:PSI 2 "fpscr_operand" ""))
5904    (clobber (match_scratch:SI 3 ""))]
5905   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5906    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5907    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5908   [(const_int 0)]
5909   "
5911   int regno = true_regnum (operands[0]);
5912   rtx insn;
5913   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5914   rtx mem2
5915     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5916   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5917                                            regno + !! TARGET_LITTLE_ENDIAN),
5918                                   mem2, operands[2]));
5919   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5920   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5921                                                regno + ! TARGET_LITTLE_ENDIAN),
5922                                   change_address (mem, SFmode, NULL_RTX),
5923                                   operands[2]));
5924   DONE;
5927 (define_split
5928   [(set (match_operand:DF 0 "register_operand" "")
5929         (match_operand:DF 1 "memory_operand" ""))
5930    (use (match_operand:PSI 2 "fpscr_operand" ""))
5931    (clobber (match_scratch:SI 3 ""))]
5932   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5933    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5934   [(const_int 0)]
5935   "
5937   int regno = true_regnum (operands[0]);
5938   rtx addr, insn, adjust = NULL_RTX;
5939   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
5940   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5941   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5943   operands[1] = copy_rtx (mem2);
5944   addr = XEXP (mem2, 0);
5945   if (GET_CODE (addr) != POST_INC)
5946     {
5947       /* If we have to modify the stack pointer, the value that we have
5948          read with post-increment might be modified by an interrupt,
5949          so write it back.  */
5950       if (REGNO (addr) == STACK_POINTER_REGNUM)
5951         adjust = gen_push_e (reg0);
5952       else
5953         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5954       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5955     }
5956   addr = XEXP (addr, 0);
5957   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5958   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5959   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5960   if (adjust)
5961     emit_insn (adjust);
5962   else
5963     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5964   DONE;
5967 (define_split
5968   [(set (match_operand:DF 0 "memory_operand" "")
5969         (match_operand:DF 1 "register_operand" ""))
5970    (use (match_operand:PSI 2 "fpscr_operand" ""))
5971    (clobber (match_scratch:SI 3 ""))]
5972   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5973    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5974   [(const_int 0)]
5975   "
5977   int regno = true_regnum (operands[1]);
5978   rtx insn, addr, adjust = NULL_RTX;
5980   operands[0] = copy_rtx (operands[0]);
5981   PUT_MODE (operands[0], SFmode);
5982   insn = emit_insn (gen_movsf_ie (operands[0],
5983                                   gen_rtx_REG (SFmode,
5984                                            regno + ! TARGET_LITTLE_ENDIAN),
5985                                   operands[2]));
5986   operands[0] = copy_rtx (operands[0]);
5987   addr = XEXP (operands[0], 0);
5988   if (GET_CODE (addr) != PRE_DEC)
5989     {
5990       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5991       emit_insn_before (adjust, insn);
5992       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5993     }
5994   addr = XEXP (addr, 0);
5995   if (! adjust)
5996     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5997   insn = emit_insn (gen_movsf_ie (operands[0],
5998                                   gen_rtx_REG (SFmode,
5999                                            regno + !! TARGET_LITTLE_ENDIAN),
6000                                   operands[2]));
6001   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6002   DONE;
6005 ;; If the output is a register and the input is memory or a register, we have
6006 ;; to be careful and see which word needs to be loaded first.
6008 (define_split
6009   [(set (match_operand:DF 0 "general_movdst_operand" "")
6010         (match_operand:DF 1 "general_movsrc_operand" ""))]
6011   "TARGET_SH1 && reload_completed"
6012   [(set (match_dup 2) (match_dup 3))
6013    (set (match_dup 4) (match_dup 5))]
6014   "
6016   int regno;
6018   if ((GET_CODE (operands[0]) == MEM
6019        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6020       || (GET_CODE (operands[1]) == MEM
6021           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6022     FAIL;
6024   switch (GET_CODE (operands[0]))
6025     {
6026     case REG:
6027       regno = REGNO (operands[0]);
6028       break;
6029     case SUBREG:
6030       regno = subreg_regno (operands[0]);
6031       break;
6032     case MEM:
6033       regno = -1;
6034       break;
6035     default:
6036       gcc_unreachable ();
6037     }
6039   if (regno == -1
6040       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6041     {
6042       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6043       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6044       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6045       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6046     }
6047   else
6048     {
6049       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6050       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6051       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6052       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6053     }
6055   if (operands[2] == 0 || operands[3] == 0
6056       || operands[4] == 0 || operands[5] == 0)
6057     FAIL;
6060 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6061 ;; used only once, let combine add in the index again.
6063 (define_split
6064   [(set (match_operand:SI 0 "register_operand" "")
6065         (match_operand:SI 1 "" ""))
6066    (clobber (match_operand 2 "register_operand" ""))]
6067   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6068    && ALLOW_INDEXED_ADDRESS"
6069   [(use (reg:SI R0_REG))]
6070   "
6072   rtx addr, reg, const_int;
6074   if (GET_CODE (operands[1]) != MEM)
6075     FAIL;
6076   addr = XEXP (operands[1], 0);
6077   if (GET_CODE (addr) != PLUS)
6078     FAIL;
6079   reg = XEXP (addr, 0);
6080   const_int = XEXP (addr, 1);
6081   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6082          && GET_CODE (const_int) == CONST_INT))
6083     FAIL;
6084   emit_move_insn (operands[2], const_int);
6085   emit_move_insn (operands[0],
6086                   change_address (operands[1], VOIDmode,
6087                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6088   DONE;
6091 (define_split
6092   [(set (match_operand:SI 1 "" "")
6093         (match_operand:SI 0 "register_operand" ""))
6094    (clobber (match_operand 2 "register_operand" ""))]
6095   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6096    && ALLOW_INDEXED_ADDRESS"
6097   [(use (reg:SI R0_REG))]
6098   "
6100   rtx addr, reg, const_int;
6102   if (GET_CODE (operands[1]) != MEM)
6103     FAIL;
6104   addr = XEXP (operands[1], 0);
6105   if (GET_CODE (addr) != PLUS)
6106     FAIL;
6107   reg = XEXP (addr, 0);
6108   const_int = XEXP (addr, 1);
6109   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6110          && GET_CODE (const_int) == CONST_INT))
6111     FAIL;
6112   emit_move_insn (operands[2], const_int);
6113   emit_move_insn (change_address (operands[1], VOIDmode,
6114                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6115                   operands[0]);
6116   DONE;
6119 (define_expand "movdf"
6120   [(set (match_operand:DF 0 "general_movdst_operand" "")
6121         (match_operand:DF 1 "general_movsrc_operand" ""))]
6122   ""
6123   "
6125   if (prepare_move_operands (operands, DFmode)) DONE;
6126   if (TARGET_SHMEDIA)
6127     {
6128       if (TARGET_SHMEDIA_FPU)
6129         emit_insn (gen_movdf_media (operands[0], operands[1]));
6130       else
6131         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6132       DONE;
6133     }
6134   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6135     {
6136       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6137       DONE;
6138     }
6141 ;;This is incompatible with the way gcc uses subregs.
6142 ;;(define_insn "movv2sf_i"
6143 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6144 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6145 ;;  "TARGET_SHMEDIA_FPU
6146 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6147 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6148 ;;  "@
6149 ;;      #
6150 ;;      fld%M1.p        %m1, %0
6151 ;;      fst%M0.p        %m0, %1"
6152 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6154 (define_insn_and_split "movv2sf_i"
6155   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6156         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6157   "TARGET_SHMEDIA_FPU"
6158   "#"
6159   "TARGET_SHMEDIA_FPU && reload_completed"
6160   [(set (match_dup 0) (match_dup 1))]
6161   "
6163   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6164   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6167 (define_expand "movv2sf"
6168   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6169         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6170   "TARGET_SHMEDIA_FPU"
6171   "
6173   if (prepare_move_operands (operands, V2SFmode))
6174     DONE;
6177 (define_expand "addv2sf3"
6178   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6179    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6180    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6181   "TARGET_SHMEDIA_FPU"
6182   "
6184   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6185   DONE;
6188 (define_expand "subv2sf3"
6189   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6190    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6191    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6192   "TARGET_SHMEDIA_FPU"
6193   "
6195   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6196   DONE;
6199 (define_expand "mulv2sf3"
6200   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6201    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6202    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6203   "TARGET_SHMEDIA_FPU"
6204   "
6206   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6207   DONE;
6210 (define_expand "divv2sf3"
6211   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6212    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6213    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6214   "TARGET_SHMEDIA_FPU"
6215   "
6217   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6218   DONE;
6221 (define_insn_and_split "*movv4sf_i"
6222   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6223         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6224   "TARGET_SHMEDIA_FPU"
6225   "#"
6226   "&& reload_completed"
6227   [(const_int 0)]
6228   "
6230   int i;
6232   for (i = 0; i < 4/2; i++)
6233     {
6234       rtx x, y;
6236       if (GET_CODE (operands[0]) == MEM)
6237         x = adjust_address (operands[0], V2SFmode,
6238                             i * GET_MODE_SIZE (V2SFmode));
6239       else
6240         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6242       if (GET_CODE (operands[1]) == MEM)
6243         y = adjust_address (operands[1], V2SFmode,
6244                             i * GET_MODE_SIZE (V2SFmode));
6245       else
6246         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6248       emit_insn (gen_movv2sf_i (x, y));
6249     }
6251   DONE;
6253   [(set_attr "length" "8")])
6255 (define_expand "movv4sf"
6256   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6257         (match_operand:V4SF 1 "general_operand" ""))]
6258   "TARGET_SHMEDIA_FPU"
6259   "
6261   if (prepare_move_operands (operands, V4SFmode))
6262     DONE;
6265 (define_insn_and_split "*movv16sf_i"
6266   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6267         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6268   "TARGET_SHMEDIA_FPU"
6269   "#"
6270   "&& reload_completed"
6271   [(const_int 0)]
6272   "
6274   int i;
6276   for (i = 0; i < 16/2; i++)
6277     {
6278       rtx x,y;
6280       if (GET_CODE (operands[0]) == MEM)
6281         x = adjust_address (operands[0], V2SFmode,
6282                             i * GET_MODE_SIZE (V2SFmode));
6283       else
6284         {
6285           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6286           alter_subreg (&x);
6287         }
6289       if (GET_CODE (operands[1]) == MEM)
6290         y = adjust_address (operands[1], V2SFmode,
6291                             i * GET_MODE_SIZE (V2SFmode));
6292       else
6293         {
6294           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6295           alter_subreg (&y);
6296         }
6298       emit_insn (gen_movv2sf_i (x, y));
6299     }
6301   DONE;
6303   [(set_attr "length" "32")])
6305 (define_expand "movv16sf"
6306   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6307         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6308   "TARGET_SHMEDIA_FPU"
6309   "
6311   if (prepare_move_operands (operands, V16SFmode))
6312     DONE;
6315 (define_insn "movsf_media"
6316   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6317         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6318   "TARGET_SHMEDIA_FPU
6319    && (register_operand (operands[0], SFmode)
6320        || sh_register_operand (operands[1], SFmode))"
6321   "@
6322         fmov.s  %1, %0
6323         fmov.ls %N1, %0
6324         fmov.sl %1, %0
6325         add.l   %1, r63, %0
6326         #
6327         fld%M1.s        %m1, %0
6328         fst%M0.s        %m0, %1
6329         ld%M1.l %m1, %0
6330         st%M0.l %m0, %N1"
6331   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6332    (set (attr "highpart")
6333         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6334                (const_string "user")]
6335               (const_string "ignore")))])
6337 (define_insn "movsf_media_nofpu"
6338   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6339         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6340   "TARGET_SHMEDIA
6341    && (register_operand (operands[0], SFmode)
6342        || sh_register_operand (operands[1], SFmode))"
6343   "@
6344         add.l   %1, r63, %0
6345         #
6346         ld%M1.l %m1, %0
6347         st%M0.l %m0, %N1"
6348   [(set_attr "type" "arith_media,*,load_media,store_media")
6349    (set (attr "highpart")
6350         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6351                (const_string "user")]
6352               (const_string "ignore")))])
6354 (define_split
6355   [(set (match_operand:SF 0 "arith_reg_dest" "")
6356         (match_operand:SF 1 "immediate_operand" ""))]
6357   "TARGET_SHMEDIA && reload_completed
6358    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6359   [(set (match_dup 3) (match_dup 2))]
6360   "
6362   long values;
6363   REAL_VALUE_TYPE value;
6365   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6366   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6367   operands[2] = GEN_INT (values);
6369   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6372 (define_insn "movsf_i"
6373   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6374         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6375   "TARGET_SH1
6376    && (! TARGET_SH2E
6377        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6378        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6379        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6380    && (arith_reg_operand (operands[0], SFmode)
6381        || arith_reg_operand (operands[1], SFmode))"
6382   "@
6383         mov     %1,%0
6384         mov     #0,%0
6385         mov.l   %1,%0
6386         mov.l   %1,%0
6387         mov.l   %1,%0
6388         lds     %1,%0
6389         sts     %1,%0"
6390   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6392 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6393 ;; update_flow_info would not know where to put REG_EQUAL notes
6394 ;; when the destination changes mode.
6395 (define_insn "movsf_ie"
6396   [(set (match_operand:SF 0 "general_movdst_operand"
6397          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6398         (match_operand:SF 1 "general_movsrc_operand"
6399           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6400    (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"))
6401    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6403   "TARGET_SH2E
6404    && (arith_reg_operand (operands[0], SFmode)
6405        || arith_reg_operand (operands[1], SFmode)
6406        || arith_reg_operand (operands[3], SImode)
6407        || (fpul_operand (operands[0], SFmode)
6408            && memory_operand (operands[1], SFmode)
6409            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6410        || (fpul_operand (operands[1], SFmode)
6411            && memory_operand (operands[0], SFmode)
6412            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6413   "@
6414         fmov    %1,%0
6415         mov     %1,%0
6416         fldi0   %0
6417         fldi1   %0
6418         #
6419         fmov.s  %1,%0
6420         fmov.s  %1,%0
6421         mov.l   %1,%0
6422         mov.l   %1,%0
6423         mov.l   %1,%0
6424         fsts    fpul,%0
6425         flds    %1,fpul
6426         lds.l   %1,%0
6427         #
6428         sts     %1,%0
6429         lds     %1,%0
6430         sts.l   %1,%0
6431         lds.l   %1,%0
6432         ! move optimized away"
6433   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6434    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6435    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6436    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6437                                            (const_string "single")
6438                                            (const_string "none")))])
6440 (define_split
6441   [(set (match_operand:SF 0 "register_operand" "")
6442         (match_operand:SF 1 "register_operand" ""))
6443    (use (match_operand:PSI 2 "fpscr_operand" ""))
6444    (clobber (reg:SI FPUL_REG))]
6445   "TARGET_SH1"
6446   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6447               (use (match_dup 2))
6448               (clobber (scratch:SI))])
6449    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6450               (use (match_dup 2))
6451               (clobber (scratch:SI))])]
6452   "")
6454 (define_expand "movsf"
6455   [(set (match_operand:SF 0 "general_movdst_operand" "")
6456         (match_operand:SF 1 "general_movsrc_operand" ""))]
6457   ""
6458   "
6460   if (prepare_move_operands (operands, SFmode))
6461     DONE;
6462   if (TARGET_SHMEDIA)
6463     {
6464       if (TARGET_SHMEDIA_FPU)
6465         emit_insn (gen_movsf_media (operands[0], operands[1]));
6466       else
6467         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6468       DONE;
6469     }
6470   if (TARGET_SH2E)
6471     {
6472       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6473       DONE;
6474     }
6477 (define_insn "mov_nop"
6478   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6479   "TARGET_SH2E"
6480   ""
6481   [(set_attr "length" "0")
6482    (set_attr "type" "nil")])
6484 (define_expand "reload_insf"
6485   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6486                    (match_operand:SF 1 "immediate_operand" "FQ"))
6487               (use (reg:PSI FPSCR_REG))
6488               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6489   "TARGET_SH1"
6490   "")
6492 (define_expand "reload_insi"
6493   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6494                    (match_operand:SI 1 "immediate_operand" "i"))
6495               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6496   "TARGET_SH1"
6497   "")
6499 (define_expand "ptabs"
6500   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6501   "TARGET_SHMEDIA"
6502   "
6504   if (!TARGET_PT_FIXED)
6505     {
6506       rtx eq = operands[1];
6508       /* ??? For canonical RTL we really should remove any CONST from EQ
6509          before wrapping it in the AND, and finally wrap the EQ into a
6510          const if is constant.  However, for reload we must expose the
6511          input register or symbolic constant, and we can't have
6512          different insn structures outside of the operands for different
6513          alternatives of the same pattern.  */
6514       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6515                        GEN_INT (3));
6516       operands[1]
6517         = (gen_rtx_IF_THEN_ELSE
6518             (PDImode,
6519              eq,
6520              gen_rtx_MEM (PDImode, operands[1]),
6521              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6522                             PDImode, operands[1])));
6523     }
6526 ;; expanded by ptabs expander.
6527 (define_insn "*extendsipdi_media"
6528   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6529         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6530                                                           "r,Csy")
6531                                       (const_int 3))
6532                               (const_int 3))
6533                           (mem:PDI (match_dup 1))
6534                           (sign_extend:PDI (match_dup 1))))]
6535   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6536   "@
6537         ptabs   %1, %0
6538         pt      %1, %0"
6539   [(set_attr "type"   "ptabs_media,pt_media")
6540    (set_attr "length" "4,*")])
6542 (define_insn "*truncdipdi_media"
6543   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6544         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6545                                                           "r,Csy")
6546                                       (const_int 3))
6547                               (const_int 3))
6548                           (mem:PDI (match_dup 1))
6549                           (truncate:PDI (match_dup 1))))]
6550   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6551   "@
6552         ptabs   %1, %0
6553         pt      %1, %0"
6554   [(set_attr "type"   "ptabs_media,pt_media")
6555    (set_attr "length" "4,*")])
6557 (define_insn "*movsi_y"
6558   [(set (match_operand:SI 0 "register_operand" "=y,y")
6559         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6560    (clobber (match_scratch:SI 2 "=&z,r"))]
6561   "TARGET_SH2E
6562    && (reload_in_progress || reload_completed)"
6563   "#"
6564   [(set_attr "length" "4")
6565    (set_attr "type" "pcload,move")])
6567 (define_split
6568   [(set (match_operand:SI 0 "register_operand" "")
6569         (match_operand:SI 1 "immediate_operand" ""))
6570    (clobber (match_operand:SI 2 "register_operand" ""))]
6571   "TARGET_SH1"
6572   [(set (match_dup 2) (match_dup 1))
6573    (set (match_dup 0) (match_dup 2))]
6574   "")
6576 (define_split
6577   [(set (match_operand:SI 0 "register_operand" "")
6578         (match_operand:SI 1 "memory_operand" ""))
6579    (clobber (reg:SI R0_REG))]
6580   "TARGET_SH1"
6581   [(set (match_dup 0) (match_dup 1))]
6582   "")
6584 ;; ------------------------------------------------------------------------
6585 ;; Define the real conditional branch instructions.
6586 ;; ------------------------------------------------------------------------
6588 (define_insn "branch_true"
6589   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6590                            (label_ref (match_operand 0 "" ""))
6591                            (pc)))]
6592   "TARGET_SH1"
6593   "* return output_branch (1, insn, operands);"
6594   [(set_attr "type" "cbranch")])
6596 (define_insn "branch_false"
6597   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6598                            (label_ref (match_operand 0 "" ""))
6599                            (pc)))]
6600   "TARGET_SH1"
6601   "* return output_branch (0, insn, operands);"
6602   [(set_attr "type" "cbranch")])
6604 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6605 ;; which destination is too far away.
6606 ;; The const_int_operand is distinct for each branch target; it avoids
6607 ;; unwanted matches with redundant_insn.
6608 (define_insn "block_branch_redirect"
6609   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6610   "TARGET_SH1"
6611   ""
6612   [(set_attr "length" "0")])
6614 ;; This one has the additional purpose to record a possible scratch register
6615 ;; for the following branch.
6616 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6617 ;; because the insn then might be deemed dead and deleted.  And we can't
6618 ;; make the use in the jump insn explicit because that would disable
6619 ;; delay slot scheduling from the target.
6620 (define_insn "indirect_jump_scratch"
6621   [(set (match_operand:SI 0 "register_operand" "=r")
6622         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6623    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6624   "TARGET_SH1"
6625   ""
6626   [(set_attr "length" "0")])
6628 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6629 ;; being pulled into the delay slot of a condbranch that has been made to
6630 ;; jump around the unconditional jump because it was out of range.
6631 (define_insn "stuff_delay_slot"
6632   [(set (pc)
6633         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6634    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6635   "TARGET_SH1"
6636   ""
6637   [(set_attr "length" "0")
6638    (set_attr "cond_delay_slot" "yes")])
6640 ;; Conditional branch insns
6642 (define_expand "beq_media"
6643   [(set (pc)
6644         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6645                           (match_operand:DI 2 "arith_operand" "r,I06"))
6646                       (match_operand 0 "" "")
6647                       (pc)))]
6648   "TARGET_SHMEDIA"
6649   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6651 (define_insn "*beq_media_i"
6652   [(set (pc)
6653         (if_then_else (match_operator 3 "equality_comparison_operator"
6654                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6655                          (match_operand:DI 2 "arith_operand" "r,I06")])
6656                       (match_operand 0 "target_operand" "b,b")
6657                       (pc)))]
6658   "TARGET_SHMEDIA"
6659   "@
6660         b%o3%'  %1, %2, %0%>
6661         b%o3i%' %1, %2, %0%>"
6662   [(set_attr "type" "cbranch_media")])
6664 (define_insn "*beq_media_i32"
6665   [(set (pc)
6666         (if_then_else (match_operator 3 "equality_comparison_operator"
6667                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6668                          (match_operand:SI 2 "arith_operand" "r,I06")])
6669                       (match_operand 0 "target_operand" "b,b")
6670                       (pc)))]
6671   "TARGET_SHMEDIA"
6672   "@
6673         b%o3%'  %1, %2, %0%>
6674         b%o3i%' %1, %2, %0%>"
6675   [(set_attr "type" "cbranch_media")])
6677 (define_expand "bne_media"
6678   [(set (pc)
6679         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6680                           (match_operand:DI 2 "arith_operand" "r,I06"))
6681                       (match_operand 0 "" "")
6682                       (pc)))]
6683   "TARGET_SHMEDIA"
6684   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6686 (define_expand "bgt_media"
6687   [(set (pc)
6688         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6689                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6690                       (match_operand 0 "" "")
6691                       (pc)))]
6692   "TARGET_SHMEDIA"
6693   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6695 (define_expand "bge_media"
6696   [(set (pc)
6697         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6698                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6699                       (match_operand 0 "" "")
6700                       (pc)))]
6701   "TARGET_SHMEDIA"
6702   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6704 (define_expand "bgtu_media"
6705   [(set (pc)
6706         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6707                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6708                       (match_operand 0 "" "")
6709                       (pc)))]
6710   "TARGET_SHMEDIA"
6711   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6713 (define_expand "bgeu_media"
6714   [(set (pc)
6715         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6716                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6717                       (match_operand 0 "" "")
6718                       (pc)))]
6719   "TARGET_SHMEDIA"
6720   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6722 (define_insn "*bgt_media_i"
6723   [(set (pc)
6724         (if_then_else (match_operator 3 "greater_comparison_operator"
6725                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6726                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6727                       (match_operand 0 "target_operand" "b")
6728                       (pc)))]
6729   "TARGET_SHMEDIA"
6730   "b%o3%'       %N1, %N2, %0%>"
6731   [(set_attr "type" "cbranch_media")])
6733 (define_insn "*bgt_media_i32"
6734   [(set (pc)
6735         (if_then_else (match_operator 3 "greater_comparison_operator"
6736                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6737                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6738                       (match_operand 0 "target_operand" "b")
6739                       (pc)))]
6740   "TARGET_SHMEDIA"
6741   "b%o3%'       %N1, %N2, %0%>"
6742   [(set_attr "type" "cbranch_media")])
6744 ;; These are only needed to make invert_jump() happy - otherwise, jump
6745 ;; optimization will be silently disabled.
6746 (define_insn "*blt_media_i"
6747   [(set (pc)
6748         (if_then_else (match_operator 3 "less_comparison_operator"
6749                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6750                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6751                       (match_operand 0 "target_operand" "b")
6752                       (pc)))]
6753   "TARGET_SHMEDIA"
6754   "b%o3%'       %N2, %N1, %0%>"
6755   [(set_attr "type" "cbranch_media")])
6757 (define_insn "*blt_media_i32"
6758   [(set (pc)
6759         (if_then_else (match_operator 3 "less_comparison_operator"
6760                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6761                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6762                       (match_operand 0 "target_operand" "b")
6763                       (pc)))]
6764   "TARGET_SHMEDIA"
6765   "b%o3%'       %N2, %N1, %0%>"
6766   [(set_attr "type" "cbranch_media")])
6768 (define_expand "beq"
6769   [(set (pc)
6770         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6771                       (label_ref (match_operand 0 "" ""))
6772                       (pc)))]
6773   ""
6774   "
6776   if (TARGET_SHMEDIA)
6777     {
6778       enum machine_mode mode = GET_MODE (sh_compare_op0);
6780       if (mode != DImode && mode != SImode)
6781         {
6782           rtx tmp = gen_reg_rtx (DImode);
6784           emit_insn (gen_seq (tmp));
6785           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6786           DONE;
6787         }
6789       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6790       if (CONSTANT_P (sh_compare_op1)
6791           && (GET_CODE (sh_compare_op1) != CONST_INT
6792               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6793         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6794       emit_jump_insn (gen_beq_media (operands[0],
6795                                      sh_compare_op0, sh_compare_op1));
6796       DONE;
6797     }
6799   from_compare (operands, EQ);
6802 (define_expand "bne"
6803   [(set (pc)
6804         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6805                       (label_ref (match_operand 0 "" ""))
6806                       (pc)))]
6807   ""
6808   "
6810   if (TARGET_SHMEDIA)
6811     {
6812       enum machine_mode mode = GET_MODE (sh_compare_op0);
6814       if (mode != DImode && mode != SImode)
6815         {
6816           rtx tmp = gen_reg_rtx (DImode);
6818           emit_insn (gen_seq (tmp));
6819           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6820           DONE;
6821         }
6823       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6824       if (CONSTANT_P (sh_compare_op1)
6825           && (GET_CODE (sh_compare_op1) != CONST_INT
6826               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6827         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6828       emit_jump_insn (gen_bne_media (operands[0],
6829                                      sh_compare_op0, sh_compare_op1));
6830       DONE;
6831     }
6833   from_compare (operands, EQ);
6836 (define_expand "bgt"
6837   [(set (pc)
6838         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6839                       (label_ref (match_operand 0 "" ""))
6840                       (pc)))]
6841   ""
6842   "
6844   if (TARGET_SHMEDIA)
6845     {
6846       enum machine_mode mode = GET_MODE (sh_compare_op0);
6848       if (mode != DImode && mode != SImode)
6849         {
6850           rtx tmp = gen_reg_rtx (DImode);
6852           emit_insn (gen_sgt (tmp));
6853           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6854           DONE;
6855         }
6857       if (sh_compare_op0 != const0_rtx)
6858         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6859       if (sh_compare_op1 != const0_rtx)
6860         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6861       emit_jump_insn (gen_bgt_media (operands[0],
6862                                      sh_compare_op0, sh_compare_op1));
6863       DONE;
6864     }
6866   from_compare (operands, GT);
6869 (define_expand "blt"
6870   [(set (pc)
6871         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6872                       (label_ref (match_operand 0 "" ""))
6873                       (pc)))]
6874   ""
6875   "
6877   if (TARGET_SHMEDIA)
6878     {
6879       enum machine_mode mode = GET_MODE (sh_compare_op0);
6881       if (mode != DImode && mode != SImode)
6882         {
6883           rtx tmp = gen_reg_rtx (DImode);
6885           emit_insn (gen_slt (tmp));
6886           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6887           DONE;
6888         }
6890       if (sh_compare_op0 != const0_rtx)
6891         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6892       if (sh_compare_op1 != const0_rtx)
6893         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6894       emit_jump_insn (gen_bgt_media (operands[0],
6895                                      sh_compare_op1, sh_compare_op0));
6896       DONE;
6897     }
6899   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6900     {
6901       rtx tmp = sh_compare_op0;
6902       sh_compare_op0 = sh_compare_op1;
6903       sh_compare_op1 = tmp;
6904       emit_insn (gen_bgt (operands[0]));
6905       DONE;
6906     }
6907   from_compare (operands, GE);
6910 (define_expand "ble"
6911   [(set (pc)
6912         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6913                       (label_ref (match_operand 0 "" ""))
6914                       (pc)))]
6915   ""
6916   "
6918   if (TARGET_SHMEDIA)
6919     {
6920       enum machine_mode mode = GET_MODE (sh_compare_op0);
6922       if (mode != DImode && mode != SImode)
6923         {
6924           rtx tmp = gen_reg_rtx (DImode);
6926           emit_insn (gen_sle (tmp));
6927           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6928           DONE;
6929         }
6931       if (sh_compare_op0 != const0_rtx)
6932         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6933       if (sh_compare_op1 != const0_rtx)
6934         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6935       emit_jump_insn (gen_bge_media (operands[0],
6936                                      sh_compare_op1, sh_compare_op0));
6937       DONE;
6938     }
6940   if (TARGET_SH2E
6941       && TARGET_IEEE
6942       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6943     {
6944       rtx tmp = sh_compare_op0;
6945       sh_compare_op0 = sh_compare_op1;
6946       sh_compare_op1 = tmp;
6947       emit_insn (gen_bge (operands[0]));
6948       DONE;
6949     }
6950   from_compare (operands, GT);
6953 (define_expand "bge"
6954   [(set (pc)
6955         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6956                       (label_ref (match_operand 0 "" ""))
6957                       (pc)))]
6958   ""
6959   "
6961   if (TARGET_SHMEDIA)
6962     {
6963       enum machine_mode mode = GET_MODE (sh_compare_op0);
6965       if (mode != DImode && mode != SImode)
6966         {
6967           rtx tmp = gen_reg_rtx (DImode);
6969           emit_insn (gen_sge (tmp));
6970           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6971           DONE;
6972         }
6974       if (sh_compare_op0 != const0_rtx)
6975         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6976       if (sh_compare_op1 != const0_rtx)
6977         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6978       emit_jump_insn (gen_bge_media (operands[0],
6979                                      sh_compare_op0, sh_compare_op1));
6980       DONE;
6981     }
6983   if (TARGET_SH2E
6984       && ! TARGET_IEEE
6985       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6986     {
6987       rtx tmp = sh_compare_op0;
6988       sh_compare_op0 = sh_compare_op1;
6989       sh_compare_op1 = tmp;
6990       emit_insn (gen_ble (operands[0]));
6991       DONE;
6992     }
6993   from_compare (operands, GE);
6996 (define_expand "bgtu"
6997   [(set (pc)
6998         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6999                       (label_ref (match_operand 0 "" ""))
7000                       (pc)))]
7001   ""
7002   "
7004   if (TARGET_SHMEDIA)
7005     {
7006       enum machine_mode mode = GET_MODE (sh_compare_op0);
7008       if (sh_compare_op0 != const0_rtx)
7009         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7010       if (sh_compare_op1 != const0_rtx)
7011         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7012       emit_jump_insn (gen_bgtu_media (operands[0],
7013                                       sh_compare_op0, sh_compare_op1));
7014       DONE;
7015     }
7017   from_compare (operands, GTU);
7020 (define_expand "bltu"
7021   [(set (pc)
7022         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7023                       (label_ref (match_operand 0 "" ""))
7024                       (pc)))]
7025   ""
7026   "
7028   if (TARGET_SHMEDIA)
7029     {
7030       enum machine_mode mode = GET_MODE (sh_compare_op0);
7032       if (sh_compare_op0 != const0_rtx)
7033         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7034       if (sh_compare_op1 != const0_rtx)
7035         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7036       emit_jump_insn (gen_bgtu_media (operands[0],
7037                                       sh_compare_op1, sh_compare_op0));
7038       DONE;
7039     }
7041   from_compare (operands, GEU);
7044 (define_expand "bgeu"
7045   [(set (pc)
7046         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7047                       (label_ref (match_operand 0 "" ""))
7048                       (pc)))]
7049   ""
7050   "
7052   if (TARGET_SHMEDIA)
7053     {
7054       enum machine_mode mode = GET_MODE (sh_compare_op0);
7056       if (sh_compare_op0 != const0_rtx)
7057         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7058       if (sh_compare_op1 != const0_rtx)
7059         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7060       emit_jump_insn (gen_bgeu_media (operands[0],
7061                                       sh_compare_op0, sh_compare_op1));
7062       DONE;
7063     }
7065   from_compare (operands, GEU);
7068 (define_expand "bleu"
7069   [(set (pc)
7070         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7071                       (label_ref (match_operand 0 "" ""))
7072                       (pc)))]
7073   ""
7074   "
7076   if (TARGET_SHMEDIA)
7077     {
7078       enum machine_mode mode = GET_MODE (sh_compare_op0);
7080       if (sh_compare_op0 != const0_rtx)
7081         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7082       if (sh_compare_op1 != const0_rtx)
7083         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7084       emit_jump_insn (gen_bgeu_media (operands[0],
7085                                       sh_compare_op1, sh_compare_op0));
7086       DONE;
7087     }
7089   from_compare (operands, GTU);
7092 (define_expand "bunordered"
7093   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7094    (set (pc)
7095         (if_then_else (ne (match_dup 1) (const_int 0))
7096                       (match_operand 0 "" "")
7097                       (pc)))]
7098   "TARGET_SHMEDIA"
7099   "
7101   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7102   operands[1] = gen_reg_rtx (DImode);
7103   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7104   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7107 ;; combiner splitter for test-and-branch on single bit in register.  This
7108 ;; is endian dependent because the non-paradoxical subreg looks different
7109 ;; on big endian.
7110 (define_split
7111   [(set (pc)
7112         (if_then_else
7113           (match_operator 3 "equality_comparison_operator"
7114             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7115                                                       "extend_reg_operand" "")
7116                                                     0)
7117                                          (const_int 1)
7118                                          (match_operand 2
7119                                           "const_int_operand" "")) 0)
7120              (const_int 0)])
7121           (match_operand 0 "target_operand" "")
7122           (pc)))
7123    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7124   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7125   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7126    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7128   "
7130   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7131   operands[6] = (GET_CODE (operands[3]) == EQ
7132                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7133                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7136 ;; ------------------------------------------------------------------------
7137 ;; Jump and linkage insns
7138 ;; ------------------------------------------------------------------------
7140 (define_insn "jump_compact"
7141   [(set (pc)
7142         (label_ref (match_operand 0 "" "")))]
7143   "TARGET_SH1"
7144   "*
7146   /* The length is 16 if the delay slot is unfilled.  */
7147   if (get_attr_length(insn) > 4)
7148     return output_far_jump(insn, operands[0]);
7149   else
7150     return   \"bra      %l0%#\";
7152   [(set_attr "type" "jump")
7153    (set_attr "needs_delay_slot" "yes")])
7155 ;; ??? It would be much saner to explicitly use the scratch register
7156 ;; in the jump insn, and have indirect_jump_scratch only set it,
7157 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7158 ;; from the target then, as it uses simplejump_p.
7159 ;;(define_insn "jump_compact_far"
7160 ;;  [(set (pc)
7161 ;;      (label_ref (match_operand 0 "" "")))
7162 ;;   (use (match_operand 1 "register_operand" "r")]
7163 ;;  "TARGET_SH1"
7164 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7165 ;;  [(set_attr "type" "jump")
7166 ;;   (set_attr "needs_delay_slot" "yes")])
7168 (define_insn "jump_media"
7169   [(set (pc)
7170         (match_operand 0 "target_operand" "b"))]
7171   "TARGET_SHMEDIA"
7172   "blink        %0, r63%>"
7173   [(set_attr "type" "jump_media")])
7175 (define_expand "jump"
7176   [(set (pc)
7177         (label_ref (match_operand 0 "" "")))]
7178   ""
7179   "
7181   if (TARGET_SH1)
7182     emit_jump_insn (gen_jump_compact (operands[0]));
7183   else if (TARGET_SHMEDIA)
7184     {
7185       if (reload_in_progress || reload_completed)
7186         FAIL;
7187       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7188                                                          operands[0])));
7189     }
7190   DONE;
7193 (define_insn "force_mode_for_call"
7194   [(use (reg:PSI FPSCR_REG))]
7195   "TARGET_SHCOMPACT"
7196   ""
7197   [(set_attr "length" "0")
7198    (set (attr "fp_mode")
7199         (if_then_else (eq_attr "fpu_single" "yes")
7200                       (const_string "single") (const_string "double")))])
7202 (define_insn "calli"
7203   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7204          (match_operand 1 "" ""))
7205    (use (reg:PSI FPSCR_REG))
7206    (clobber (reg:SI PR_REG))]
7207   "TARGET_SH1"
7208   "jsr  @%0%#"
7209   [(set_attr "type" "call")
7210    (set (attr "fp_mode")
7211         (if_then_else (eq_attr "fpu_single" "yes")
7212                       (const_string "single") (const_string "double")))
7213    (set_attr "needs_delay_slot" "yes")
7214    (set_attr "fp_set" "unknown")])
7216 ;; This is a pc-rel call, using bsrf, for use with PIC.
7218 (define_insn "calli_pcrel"
7219   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7220          (match_operand 1 "" ""))
7221    (use (reg:PSI FPSCR_REG))
7222    (use (reg:SI PIC_REG))
7223    (use (match_operand 2 "" ""))
7224    (clobber (reg:SI PR_REG))]
7225   "TARGET_SH2"
7226   "bsrf %0\\n%O2:%#"
7227   [(set_attr "type" "call")
7228    (set (attr "fp_mode")
7229         (if_then_else (eq_attr "fpu_single" "yes")
7230                       (const_string "single") (const_string "double")))
7231    (set_attr "needs_delay_slot" "yes")
7232    (set_attr "fp_set" "unknown")])
7234 (define_insn_and_split "call_pcrel"
7235   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7236          (match_operand 1 "" ""))
7237    (use (reg:PSI FPSCR_REG))
7238    (use (reg:SI PIC_REG))
7239    (clobber (reg:SI PR_REG))
7240    (clobber (match_scratch:SI 2 "=r"))]
7241   "TARGET_SH2"
7242   "#"
7243   "reload_completed"
7244   [(const_int 0)]
7245   "
7247   rtx lab = PATTERN (gen_call_site ());
7249   if (SYMBOL_REF_LOCAL_P (operands[0]))
7250     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7251   else
7252     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7253   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7254   DONE;
7256   [(set_attr "type" "call")
7257    (set (attr "fp_mode")
7258         (if_then_else (eq_attr "fpu_single" "yes")
7259                       (const_string "single") (const_string "double")))
7260    (set_attr "needs_delay_slot" "yes")
7261    (set_attr "fp_set" "unknown")])
7263 (define_insn "call_compact"
7264   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7265          (match_operand 1 "" ""))
7266    (match_operand 2 "immediate_operand" "n")
7267    (use (reg:SI R0_REG))
7268    (use (reg:SI R1_REG))
7269    (use (reg:PSI FPSCR_REG))
7270    (clobber (reg:SI PR_REG))]
7271   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7272   "jsr  @%0%#"
7273   [(set_attr "type" "call")
7274    (set (attr "fp_mode")
7275         (if_then_else (eq_attr "fpu_single" "yes")
7276                       (const_string "single") (const_string "double")))
7277    (set_attr "needs_delay_slot" "yes")])
7279 (define_insn "call_compact_rettramp"
7280   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7281          (match_operand 1 "" ""))
7282    (match_operand 2 "immediate_operand" "n")
7283    (use (reg:SI R0_REG))
7284    (use (reg:SI R1_REG))
7285    (use (reg:PSI FPSCR_REG))
7286    (clobber (reg:SI R10_REG))
7287    (clobber (reg:SI PR_REG))]
7288   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7289   "jsr  @%0%#"
7290   [(set_attr "type" "call")
7291    (set (attr "fp_mode")
7292         (if_then_else (eq_attr "fpu_single" "yes")
7293                       (const_string "single") (const_string "double")))
7294    (set_attr "needs_delay_slot" "yes")])
7296 (define_insn "call_media"
7297   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7298          (match_operand 1 "" ""))
7299    (clobber (reg:DI PR_MEDIA_REG))]
7300   "TARGET_SHMEDIA"
7301   "blink        %0, r18"
7302   [(set_attr "type" "jump_media")])
7304 (define_insn "call_valuei"
7305   [(set (match_operand 0 "" "=rf")
7306         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7307               (match_operand 2 "" "")))
7308    (use (reg:PSI FPSCR_REG))
7309    (clobber (reg:SI PR_REG))]
7310   "TARGET_SH1"
7311   "jsr  @%1%#"
7312   [(set_attr "type" "call")
7313    (set (attr "fp_mode")
7314         (if_then_else (eq_attr "fpu_single" "yes")
7315                       (const_string "single") (const_string "double")))
7316    (set_attr "needs_delay_slot" "yes")
7317    (set_attr "fp_set" "unknown")])
7319 (define_insn "call_valuei_pcrel"
7320   [(set (match_operand 0 "" "=rf")
7321         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7322               (match_operand 2 "" "")))
7323    (use (reg:PSI FPSCR_REG))
7324    (use (reg:SI PIC_REG))
7325    (use (match_operand 3 "" ""))
7326    (clobber (reg:SI PR_REG))]
7327   "TARGET_SH2"
7328   "bsrf %1\\n%O3:%#"
7329   [(set_attr "type" "call")
7330    (set (attr "fp_mode")
7331         (if_then_else (eq_attr "fpu_single" "yes")
7332                       (const_string "single") (const_string "double")))
7333    (set_attr "needs_delay_slot" "yes")
7334    (set_attr "fp_set" "unknown")])
7336 (define_insn_and_split "call_value_pcrel"
7337   [(set (match_operand 0 "" "=rf")
7338         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7339               (match_operand 2 "" "")))
7340    (use (reg:PSI FPSCR_REG))
7341    (use (reg:SI PIC_REG))
7342    (clobber (reg:SI PR_REG))
7343    (clobber (match_scratch:SI 3 "=r"))]
7344   "TARGET_SH2"
7345   "#"
7346   "reload_completed"
7347   [(const_int 0)]
7348   "
7350   rtx lab = PATTERN (gen_call_site ());
7352   if (SYMBOL_REF_LOCAL_P (operands[1]))
7353     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7354   else
7355     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7356   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7357                                          operands[2], lab));
7358   DONE;
7360   [(set_attr "type" "call")
7361    (set (attr "fp_mode")
7362         (if_then_else (eq_attr "fpu_single" "yes")
7363                       (const_string "single") (const_string "double")))
7364    (set_attr "needs_delay_slot" "yes")
7365    (set_attr "fp_set" "unknown")])
7367 (define_insn "call_value_compact"
7368   [(set (match_operand 0 "" "=rf")
7369         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7370               (match_operand 2 "" "")))
7371    (match_operand 3 "immediate_operand" "n")
7372    (use (reg:SI R0_REG))
7373    (use (reg:SI R1_REG))
7374    (use (reg:PSI FPSCR_REG))
7375    (clobber (reg:SI PR_REG))]
7376   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7377   "jsr  @%1%#"
7378   [(set_attr "type" "call")
7379    (set (attr "fp_mode")
7380         (if_then_else (eq_attr "fpu_single" "yes")
7381                       (const_string "single") (const_string "double")))
7382    (set_attr "needs_delay_slot" "yes")])
7384 (define_insn "call_value_compact_rettramp"
7385   [(set (match_operand 0 "" "=rf")
7386         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7387               (match_operand 2 "" "")))
7388    (match_operand 3 "immediate_operand" "n")
7389    (use (reg:SI R0_REG))
7390    (use (reg:SI R1_REG))
7391    (use (reg:PSI FPSCR_REG))
7392    (clobber (reg:SI R10_REG))
7393    (clobber (reg:SI PR_REG))]
7394   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7395   "jsr  @%1%#"
7396   [(set_attr "type" "call")
7397    (set (attr "fp_mode")
7398         (if_then_else (eq_attr "fpu_single" "yes")
7399                       (const_string "single") (const_string "double")))
7400    (set_attr "needs_delay_slot" "yes")])
7402 (define_insn "call_value_media"
7403   [(set (match_operand 0 "" "=rf")
7404         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7405               (match_operand 2 "" "")))
7406    (clobber (reg:DI PR_MEDIA_REG))]
7407   "TARGET_SHMEDIA"
7408   "blink        %1, r18"
7409   [(set_attr "type" "jump_media")])
7411 (define_expand "call"
7412   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7413                             (match_operand 1 "" ""))
7414               (match_operand 2 "" "")
7415               (use (reg:PSI FPSCR_REG))
7416               (clobber (reg:SI PR_REG))])]
7417   ""
7418   "
7420   if (TARGET_SHMEDIA)
7421     {
7422       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7423       emit_call_insn (gen_call_media (operands[0], operands[1]));
7424       DONE;
7425     }
7426   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7427     {
7428       rtx cookie_rtx = operands[2];
7429       long cookie = INTVAL (cookie_rtx);
7430       rtx func = XEXP (operands[0], 0);
7431       rtx r0, r1;
7433       if (flag_pic)
7434         {
7435           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7436             {
7437               rtx reg = gen_reg_rtx (Pmode);
7439               emit_insn (gen_symGOTPLT2reg (reg, func));
7440               func = reg;
7441             }
7442           else
7443             func = legitimize_pic_address (func, Pmode, 0);
7444         }
7446       r0 = gen_rtx_REG (SImode, R0_REG);
7447       r1 = gen_rtx_REG (SImode, R1_REG);
7449       /* Since such a call function may use all call-clobbered
7450          registers, we force a mode switch earlier, so that we don't
7451          run out of registers when adjusting fpscr for the call.  */
7452       emit_insn (gen_force_mode_for_call ());
7454       operands[0]
7455         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7456                            SFUNC_GOT);
7457       operands[0] = force_reg (SImode, operands[0]);
7459       emit_move_insn (r0, func);
7460       emit_move_insn (r1, cookie_rtx);
7462       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7463         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7464                                                    operands[2]));
7465       else
7466         emit_call_insn (gen_call_compact (operands[0], operands[1],
7467                                           operands[2]));
7469       DONE;
7470     }
7471   else if (TARGET_SHCOMPACT && flag_pic
7472            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7473            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7474     {
7475       rtx reg = gen_reg_rtx (Pmode);
7477       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7478       XEXP (operands[0], 0) = reg;
7479     }
7480   if (flag_pic && TARGET_SH2
7481       && GET_CODE (operands[0]) == MEM
7482       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7483     {
7484       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7485       DONE;
7486     }
7487   else
7488   {
7489     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7490     operands[1] = operands[2];
7491   }
7493   emit_call_insn (gen_calli (operands[0], operands[1]));
7494   DONE;
7497 (define_insn "call_pop_compact"
7498   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7499          (match_operand 1 "" ""))
7500    (match_operand 2 "immediate_operand" "n")
7501    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7502                                  (match_operand 3 "immediate_operand" "n")))
7503    (use (reg:SI R0_REG))
7504    (use (reg:SI R1_REG))
7505    (use (reg:PSI FPSCR_REG))
7506    (clobber (reg:SI PR_REG))]
7507   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7508   "jsr  @%0%#"
7509   [(set_attr "type" "call")
7510    (set (attr "fp_mode")
7511         (if_then_else (eq_attr "fpu_single" "yes")
7512                       (const_string "single") (const_string "double")))
7513    (set_attr "needs_delay_slot" "yes")])
7515 (define_insn "call_pop_compact_rettramp"
7516   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7517          (match_operand 1 "" ""))
7518    (match_operand 2 "immediate_operand" "n")
7519    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7520                                  (match_operand 3 "immediate_operand" "n")))
7521    (use (reg:SI R0_REG))
7522    (use (reg:SI R1_REG))
7523    (use (reg:PSI FPSCR_REG))
7524    (clobber (reg:SI R10_REG))
7525    (clobber (reg:SI PR_REG))]
7526   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7527   "jsr  @%0%#"
7528   [(set_attr "type" "call")
7529    (set (attr "fp_mode")
7530         (if_then_else (eq_attr "fpu_single" "yes")
7531                       (const_string "single") (const_string "double")))
7532    (set_attr "needs_delay_slot" "yes")])
7534 (define_expand "call_pop"
7535   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7536                     (match_operand 1 "" ""))
7537              (match_operand 2 "" "")
7538              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7539                                            (match_operand 3 "" "")))])]
7540   "TARGET_SHCOMPACT"
7541   "
7543   rtx cookie_rtx;
7544   long cookie;
7545   rtx func;
7546   rtx r0, r1;
7548   gcc_assert (operands[2] && INTVAL (operands[2]));
7549   cookie_rtx = operands[2];
7550   cookie = INTVAL (cookie_rtx);
7551   func = XEXP (operands[0], 0);
7553   if (flag_pic)
7554     {
7555       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7556         {
7557           rtx reg = gen_reg_rtx (Pmode);
7558           emit_insn (gen_symGOTPLT2reg (reg, func));
7559           func = reg;
7560         }
7561       else
7562         func = legitimize_pic_address (func, Pmode, 0);
7563     }
7565   r0 = gen_rtx_REG (SImode, R0_REG);
7566   r1 = gen_rtx_REG (SImode, R1_REG);
7568   /* Since such a call function may use all call-clobbered
7569      registers, we force a mode switch earlier, so that we don't
7570      run out of registers when adjusting fpscr for the call.  */
7571   emit_insn (gen_force_mode_for_call ());
7573   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7574                                  SFUNC_GOT);
7575   operands[0] = force_reg (SImode, operands[0]);
7577   emit_move_insn (r0, func);
7578   emit_move_insn (r1, cookie_rtx);
7580   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7581     emit_call_insn (gen_call_pop_compact_rettramp
7582                      (operands[0], operands[1], operands[2], operands[3]));
7583   else
7584     emit_call_insn (gen_call_pop_compact
7585                      (operands[0], operands[1], operands[2], operands[3]));
7587   DONE;
7590 (define_expand "call_value"
7591   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7592                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7593                                  (match_operand 2 "" "")))
7594               (match_operand 3 "" "")
7595               (use (reg:PSI FPSCR_REG))
7596               (clobber (reg:SI PR_REG))])]
7597   ""
7598   "
7600   if (TARGET_SHMEDIA)
7601     {
7602       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7603       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7604                                             operands[2]));
7605       DONE;
7606     }
7607   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7608     {
7609       rtx cookie_rtx = operands[3];
7610       long cookie = INTVAL (cookie_rtx);
7611       rtx func = XEXP (operands[1], 0);
7612       rtx r0, r1;
7614       if (flag_pic)
7615         {
7616           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7617             {
7618               rtx reg = gen_reg_rtx (Pmode);
7620               emit_insn (gen_symGOTPLT2reg (reg, func));
7621               func = reg;
7622             }
7623           else
7624             func = legitimize_pic_address (func, Pmode, 0);
7625         }
7627       r0 = gen_rtx_REG (SImode, R0_REG);
7628       r1 = gen_rtx_REG (SImode, R1_REG);
7630       /* Since such a call function may use all call-clobbered
7631          registers, we force a mode switch earlier, so that we don't
7632          run out of registers when adjusting fpscr for the call.  */
7633       emit_insn (gen_force_mode_for_call ());
7635       operands[1]
7636         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7637                            SFUNC_GOT);
7638       operands[1] = force_reg (SImode, operands[1]);
7640       emit_move_insn (r0, func);
7641       emit_move_insn (r1, cookie_rtx);
7643       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7644         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7645                                                          operands[1],
7646                                                          operands[2],
7647                                                          operands[3]));
7648       else
7649         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7650                                                 operands[2], operands[3]));
7652       DONE;
7653     }
7654   else if (TARGET_SHCOMPACT && flag_pic
7655            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7656            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7657     {
7658       rtx reg = gen_reg_rtx (Pmode);
7660       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7661       XEXP (operands[1], 0) = reg;
7662     }
7663   if (flag_pic && TARGET_SH2
7664       && GET_CODE (operands[1]) == MEM
7665       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7666     {
7667       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7668                                             operands[2]));
7669       DONE;
7670     }
7671   else
7672     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7674   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7675   DONE;
7678 (define_insn "sibcalli"
7679   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7680          (match_operand 1 "" ""))
7681    (use (reg:PSI FPSCR_REG))
7682    (return)]
7683   "TARGET_SH1"
7684   "jmp  @%0%#"
7685   [(set_attr "needs_delay_slot" "yes")
7686    (set (attr "fp_mode")
7687         (if_then_else (eq_attr "fpu_single" "yes")
7688                       (const_string "single") (const_string "double")))
7689    (set_attr "type" "jump_ind")])
7691 (define_insn "sibcalli_pcrel"
7692   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7693          (match_operand 1 "" ""))
7694    (use (match_operand 2 "" ""))
7695    (use (reg:PSI FPSCR_REG))
7696    (return)]
7697   "TARGET_SH2"
7698   "braf %0\\n%O2:%#"
7699   [(set_attr "needs_delay_slot" "yes")
7700    (set (attr "fp_mode")
7701         (if_then_else (eq_attr "fpu_single" "yes")
7702                       (const_string "single") (const_string "double")))
7703    (set_attr "type" "jump_ind")])
7705 ;; This uses an unspec to describe that the symbol_ref is very close.
7706 (define_insn "sibcalli_thunk"
7707   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7708                              UNSPEC_THUNK))
7709          (match_operand 1 "" ""))
7710    (use (reg:PSI FPSCR_REG))
7711    (return)]
7712   "TARGET_SH1"
7713   "bra  %O0"
7714   [(set_attr "needs_delay_slot" "yes")
7715    (set (attr "fp_mode")
7716         (if_then_else (eq_attr "fpu_single" "yes")
7717                       (const_string "single") (const_string "double")))
7718    (set_attr "type" "jump")
7719    (set_attr "length" "2")])
7721 (define_insn_and_split "sibcall_pcrel"
7722   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7723          (match_operand 1 "" ""))
7724    (use (reg:PSI FPSCR_REG))
7725    (clobber (match_scratch:SI 2 "=k"))
7726    (return)]
7727   "TARGET_SH2"
7728   "#"
7729   "reload_completed"
7730   [(const_int 0)]
7731   "
7733   rtx lab = PATTERN (gen_call_site ());
7734   rtx call_insn;
7736   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7737   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7738                                                   lab));
7739   SIBLING_CALL_P (call_insn) = 1;
7740   DONE;
7742   [(set_attr "needs_delay_slot" "yes")
7743    (set (attr "fp_mode")
7744         (if_then_else (eq_attr "fpu_single" "yes")
7745                       (const_string "single") (const_string "double")))
7746    (set_attr "type" "jump_ind")])
7748 (define_insn "sibcall_compact"
7749   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7750          (match_operand 1 "" ""))
7751    (return)
7752    (use (match_operand:SI 2 "register_operand" "z,x"))
7753    (use (reg:SI R1_REG))
7754    (use (reg:PSI FPSCR_REG))
7755    ;; We want to make sure the `x' above will only match MACH_REG
7756    ;; because sibcall_epilogue may clobber MACL_REG.
7757    (clobber (reg:SI MACL_REG))]
7758   "TARGET_SHCOMPACT"
7759   "@
7760         jmp     @%0%#
7761         jmp     @%0\\n  sts     %2, r0"
7762   [(set_attr "needs_delay_slot" "yes,no")
7763    (set_attr "length" "2,4")
7764    (set (attr "fp_mode") (const_string "single"))
7765    (set_attr "type" "jump_ind")])
7767 (define_insn "sibcall_media"
7768   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7769          (match_operand 1 "" ""))
7770    (use (reg:SI PR_MEDIA_REG))
7771    (return)]
7772   "TARGET_SHMEDIA"
7773   "blink        %0, r63"
7774   [(set_attr "type" "jump_media")])
7776 (define_expand "sibcall"
7777   [(parallel
7778     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7779            (match_operand 1 "" ""))
7780      (match_operand 2 "" "")
7781      (use (reg:PSI FPSCR_REG))
7782      (return)])]
7783   ""
7784   "
7786   if (TARGET_SHMEDIA)
7787     {
7788       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7789       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7790       DONE;
7791     }
7792   else if (TARGET_SHCOMPACT && operands[2]
7793            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7794     {
7795       rtx cookie_rtx = operands[2];
7796       long cookie = INTVAL (cookie_rtx);
7797       rtx func = XEXP (operands[0], 0);
7798       rtx mach, r1;
7800       if (flag_pic)
7801         {
7802           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7803             {
7804               rtx reg = gen_reg_rtx (Pmode);
7806               emit_insn (gen_symGOT2reg (reg, func));
7807               func = reg;
7808             }
7809           else
7810             func = legitimize_pic_address (func, Pmode, 0);
7811         }
7813       /* FIXME: if we could tell whether all argument registers are
7814          already taken, we could decide whether to force the use of
7815          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7816          simple way to tell.  We could use the CALL_COOKIE, but we
7817          can't currently tell a register used for regular argument
7818          passing from one that is unused.  If we leave it up to reload
7819          to decide which register to use, it seems to always choose
7820          R0_REG, which leaves no available registers in SIBCALL_REGS
7821          to hold the address of the trampoline.  */
7822       mach = gen_rtx_REG (SImode, MACH_REG);
7823       r1 = gen_rtx_REG (SImode, R1_REG);
7825       /* Since such a call function may use all call-clobbered
7826          registers, we force a mode switch earlier, so that we don't
7827          run out of registers when adjusting fpscr for the call.  */
7828       emit_insn (gen_force_mode_for_call ());
7830       operands[0]
7831         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7832                            SFUNC_GOT);
7833       operands[0] = force_reg (SImode, operands[0]);
7835       /* We don't need a return trampoline, since the callee will
7836          return directly to the upper caller.  */
7837       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7838         {
7839           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7840           cookie_rtx = GEN_INT (cookie);
7841         }
7843       emit_move_insn (mach, func);
7844       emit_move_insn (r1, cookie_rtx);
7846       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7847       DONE;
7848     }
7849   else if (TARGET_SHCOMPACT && flag_pic
7850            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7851            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7852     {
7853       rtx reg = gen_reg_rtx (Pmode);
7855       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7856       XEXP (operands[0], 0) = reg;
7857     }
7858   if (flag_pic && TARGET_SH2
7859       && GET_CODE (operands[0]) == MEM
7860       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7861       /* The PLT needs the PIC register, but the epilogue would have
7862          to restore it, so we can only use PC-relative PIC calls for
7863          static functions.  */
7864       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7865     {
7866       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7867       DONE;
7868     }
7869   else
7870     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7872   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7873   DONE;
7876 (define_expand "sibcall_value"
7877   [(set (match_operand 0 "" "")
7878         (call (match_operand 1 "" "")
7879               (match_operand 2 "" "")))
7880    (match_operand 3 "" "")]
7881   ""
7882   "
7884   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7885   DONE;
7888 (define_insn "call_value_pop_compact"
7889   [(set (match_operand 0 "" "=rf")
7890         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7891               (match_operand 2 "" "")))
7892    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7893                                  (match_operand 4 "immediate_operand" "n")))
7894    (match_operand 3 "immediate_operand" "n")
7895    (use (reg:SI R0_REG))
7896    (use (reg:SI R1_REG))
7897    (use (reg:PSI FPSCR_REG))
7898    (clobber (reg:SI PR_REG))]
7899   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7900   "jsr  @%1%#"
7901   [(set_attr "type" "call")
7902    (set (attr "fp_mode")
7903         (if_then_else (eq_attr "fpu_single" "yes")
7904                       (const_string "single") (const_string "double")))
7905    (set_attr "needs_delay_slot" "yes")])
7907 (define_insn "call_value_pop_compact_rettramp"
7908   [(set (match_operand 0 "" "=rf")
7909         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7910               (match_operand 2 "" "")))
7911    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7912                                  (match_operand 4 "immediate_operand" "n")))
7913    (match_operand 3 "immediate_operand" "n")
7914    (use (reg:SI R0_REG))
7915    (use (reg:SI R1_REG))
7916    (use (reg:PSI FPSCR_REG))
7917    (clobber (reg:SI R10_REG))
7918    (clobber (reg:SI PR_REG))]
7919   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7920   "jsr  @%1%#"
7921   [(set_attr "type" "call")
7922    (set (attr "fp_mode")
7923         (if_then_else (eq_attr "fpu_single" "yes")
7924                       (const_string "single") (const_string "double")))
7925    (set_attr "needs_delay_slot" "yes")])
7927 (define_expand "call_value_pop"
7928   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7929                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7930                                  (match_operand 2 "" "")))
7931               (match_operand 3 "" "")
7932               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7933                                             (match_operand 4 "" "")))])]
7934   "TARGET_SHCOMPACT"
7935   "
7937   rtx cookie_rtx;
7938   long cookie;
7939   rtx func;
7940   rtx r0, r1;
7942   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7943   cookie_rtx = operands[3];
7944   cookie = INTVAL (cookie_rtx);
7945   func = XEXP (operands[1], 0);
7947   if (flag_pic)
7948     {
7949       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7950         {
7951           rtx reg = gen_reg_rtx (Pmode);
7953           emit_insn (gen_symGOTPLT2reg (reg, func));
7954           func = reg;
7955         }
7956       else
7957         func = legitimize_pic_address (func, Pmode, 0);
7958     }
7960   r0 = gen_rtx_REG (SImode, R0_REG);
7961   r1 = gen_rtx_REG (SImode, R1_REG);
7963   /* Since such a call function may use all call-clobbered
7964      registers, we force a mode switch earlier, so that we don't
7965      run out of registers when adjusting fpscr for the call.  */
7966   emit_insn (gen_force_mode_for_call ());
7968   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7969                                  SFUNC_GOT);
7970   operands[1] = force_reg (SImode, operands[1]);
7972   emit_move_insn (r0, func);
7973   emit_move_insn (r1, cookie_rtx);
7975   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7976     emit_call_insn (gen_call_value_pop_compact_rettramp
7977                         (operands[0], operands[1], operands[2],
7978                          operands[3], operands[4]));
7979   else
7980     emit_call_insn (gen_call_value_pop_compact
7981                         (operands[0], operands[1], operands[2],
7982                          operands[3], operands[4]));
7984   DONE;
7987 (define_expand "sibcall_epilogue"
7988   [(return)]
7989   ""
7990   "
7992   sh_expand_epilogue (1);
7993   if (TARGET_SHCOMPACT)
7994     {
7995       rtx insn, set;
7997       /* If epilogue clobbers r0, preserve it in macl.  */
7998       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7999         if ((set = single_set (insn))
8000             && GET_CODE (SET_DEST (set)) == REG
8001             && REGNO (SET_DEST (set)) == R0_REG)
8002           {
8003             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8004             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8005             rtx i;
8007             /* We can't tell at this point whether the sibcall is a
8008                sibcall_compact and, if it is, whether it uses r0 or
8009                mach as operand 2, so let the instructions that
8010                preserve r0 be optimized away if r0 turns out to be
8011                dead.  */
8012             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8013             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8014                                                REG_NOTES (i));
8015             i = emit_move_insn (r0, tmp);
8016             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8017                                                REG_NOTES (i));
8018             break;
8019           }
8020     }
8021   DONE;
8024 (define_insn "indirect_jump_compact"
8025   [(set (pc)
8026         (match_operand:SI 0 "arith_reg_operand" "r"))]
8027   "TARGET_SH1"
8028   "jmp  @%0%#"
8029   [(set_attr "needs_delay_slot" "yes")
8030    (set_attr "type" "jump_ind")])
8032 (define_expand "indirect_jump"
8033   [(set (pc)
8034         (match_operand 0 "register_operand" ""))]
8035   ""
8036   "
8038   if (GET_MODE (operands[0]) != Pmode)
8039     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8042 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8043 ;; which can be present in structured code from indirect jumps which can not
8044 ;; be present in structured code.  This allows -fprofile-arcs to work.
8046 ;; For SH1 processors.
8047 (define_insn "casesi_jump_1"
8048   [(set (pc)
8049         (match_operand:SI 0 "register_operand" "r"))
8050    (use (label_ref (match_operand 1 "" "")))]
8051   "TARGET_SH1"
8052   "jmp  @%0%#"
8053   [(set_attr "needs_delay_slot" "yes")
8054    (set_attr "type" "jump_ind")])
8056 ;; For all later processors.
8057 (define_insn "casesi_jump_2"
8058   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8059                       (label_ref (match_operand 1 "" ""))))
8060    (use (label_ref (match_operand 2 "" "")))]
8061   "TARGET_SH2
8062    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8063   "braf %0%#"
8064   [(set_attr "needs_delay_slot" "yes")
8065    (set_attr "type" "jump_ind")])
8067 (define_insn "casesi_jump_media"
8068   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8069    (use (label_ref (match_operand 1 "" "")))]
8070   "TARGET_SHMEDIA"
8071   "blink        %0, r63"
8072   [(set_attr "type" "jump_media")])
8074 ;; Call subroutine returning any type.
8075 ;; ??? This probably doesn't work.
8077 (define_expand "untyped_call"
8078   [(parallel [(call (match_operand 0 "" "")
8079                     (const_int 0))
8080               (match_operand 1 "" "")
8081               (match_operand 2 "" "")])]
8082   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8083   "
8085   int i;
8087   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8089   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8090     {
8091       rtx set = XVECEXP (operands[2], 0, i);
8092       emit_move_insn (SET_DEST (set), SET_SRC (set));
8093     }
8095   /* The optimizer does not know that the call sets the function value
8096      registers we stored in the result block.  We avoid problems by
8097      claiming that all hard registers are used and clobbered at this
8098      point.  */
8099   emit_insn (gen_blockage ());
8101   DONE;
8104 ;; ------------------------------------------------------------------------
8105 ;; Misc insns
8106 ;; ------------------------------------------------------------------------
8108 (define_insn "dect"
8109   [(set (reg:SI T_REG)
8110         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8111    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8112   "TARGET_SH2"
8113   "dt   %0"
8114   [(set_attr "type" "arith")])
8116 (define_insn "nop"
8117   [(const_int 0)]
8118   ""
8119   "nop")
8121 ;; Load address of a label. This is only generated by the casesi expand,
8122 ;; and by machine_dependent_reorg (fixing up fp moves).
8123 ;; This must use unspec, because this only works for labels that are
8124 ;; within range,
8126 (define_insn "mova"
8127   [(set (reg:SI R0_REG)
8128         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8129   "TARGET_SH1"
8130   "mova %O0,r0"
8131   [(set_attr "in_delay_slot" "no")
8132    (set_attr "type" "arith")])
8134 ;; machine_dependent_reorg will make this a `mova'.
8135 (define_insn "mova_const"
8136   [(set (reg:SI R0_REG)
8137         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8138   "TARGET_SH1"
8139   "#"
8140   [(set_attr "in_delay_slot" "no")
8141    (set_attr "type" "arith")])
8143 (define_expand "GOTaddr2picreg"
8144   [(set (reg:SI R0_REG)
8145         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8146                    UNSPEC_MOVA))
8147    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8148    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8149   "" "
8151   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8152   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8154   if (TARGET_SHMEDIA)
8155     {
8156       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8157       rtx pic = operands[0];
8158       rtx lab = PATTERN (gen_call_site ());
8159       rtx insn, equiv;
8161       equiv = operands[1];
8162       operands[1] = gen_rtx_MINUS (Pmode,
8163                                    operands[1],
8164                                    gen_rtx_CONST
8165                                    (Pmode,
8166                                     gen_rtx_MINUS (Pmode,
8167                                                    gen_rtx_CONST (Pmode,
8168                                                                   lab),
8169                                                    pc_rtx)));
8170       operands[1] = gen_sym2PIC (operands[1]);
8171       PUT_MODE (operands[1], Pmode);
8173       if (Pmode == SImode)
8174         {
8175           emit_insn (gen_movsi_const (pic, operands[1]));
8176           emit_insn (gen_ptrel_si (tr, pic, lab));
8177         }
8178       else
8179         {
8180           emit_insn (gen_movdi_const (pic, operands[1]));
8181           emit_insn (gen_ptrel_di (tr, pic, lab));
8182         }
8184       insn = emit_move_insn (operands[0], tr);
8186       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8187                                             REG_NOTES (insn));
8189       DONE;
8190     }
8194 (define_insn "*ptb"
8195   [(set (match_operand 0 "target_reg_operand" "=b")
8196         (const (unspec [(match_operand 1 "" "Csy")]
8197                              UNSPEC_DATALABEL)))]
8198   "TARGET_SHMEDIA && flag_pic
8199    && EXTRA_CONSTRAINT_Csy (operands[1])"
8200   "ptb/u        datalabel %1, %0"
8201   [(set_attr "type" "ptabs_media")
8202    (set_attr "length" "*")])
8204 (define_insn "ptrel_si"
8205   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8206         (plus:SI (match_operand:SI 1 "register_operand" "r")
8207               (pc)))
8208    (match_operand:SI 2 "" "")]
8209   "TARGET_SHMEDIA"
8210   "%O2: ptrel/u %1, %0"
8211   [(set_attr "type" "ptabs_media")])
8213 (define_insn "ptrel_di"
8214   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8215         (plus:DI (match_operand:DI 1 "register_operand" "r")
8216               (pc)))
8217    (match_operand:DI 2 "" "")]
8218   "TARGET_SHMEDIA"
8219   "%O2: ptrel/u %1, %0"
8220   [(set_attr "type" "ptabs_media")])
8222 (define_expand "builtin_setjmp_receiver"
8223   [(match_operand 0 "" "")]
8224   "flag_pic"
8225   "
8227   emit_insn (gen_GOTaddr2picreg ());
8228   DONE;
8231 (define_expand "call_site"
8232   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8233   "TARGET_SH1"
8234   "
8236   static HOST_WIDE_INT i = 0;
8237   operands[0] = GEN_INT (i);
8238   i++;
8241 (define_expand "sym_label2reg"
8242   [(set (match_operand:SI 0 "" "")
8243         (const:SI (minus:SI
8244                    (const:SI
8245                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8246                    (const:SI
8247                     (plus:SI
8248                      (match_operand:SI 2 "" "")
8249                      (const_int 2))))))]
8250   "TARGET_SH1" "")
8252 (define_expand "symGOT_load"
8253   [(set (match_dup 2) (match_operand 1 "" ""))
8254    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8255    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8256   ""
8257   "
8259   rtx insn, mem;
8261   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8262   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8264   if (TARGET_SHMEDIA)
8265     {
8266       rtx reg = operands[2];
8268       if (Pmode == DImode)
8269         {      
8270           if (flag_pic > 1)
8271             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8272           else
8273             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8274         }
8275       else
8276         {
8277           if (flag_pic > 1)
8278             emit_insn (gen_movsi_const (reg, operands[1]));
8279           else
8280             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8281         }
8282     }
8283   else
8284     emit_move_insn (operands[2], operands[1]);
8286   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8287                                              operands[2],
8288                                              gen_rtx_REG (Pmode, PIC_REG)));
8290   /* When stack protector inserts codes after the result is set to
8291      R0, @(rX, r12) will cause a spill failure for R0.  Don't schedule
8292      insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8293      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8294      matter because this is a rare situation.  */
8295   if (!TARGET_SHMEDIA
8296       && flag_stack_protect
8297       && GET_CODE (operands[1]) == CONST
8298       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8299       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8300       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8301                  \"__stack_chk_guard\") == 0)
8302     emit_insn (gen_blockage ());
8304   /* N.B. This is not constant for a GOTPLT relocation.  */
8305   mem = gen_rtx_MEM (Pmode, operands[3]);
8306   MEM_NOTRAP_P (mem) = 1;
8307   /* ??? Should we have a special alias set for the GOT?  */
8308   insn = emit_move_insn (operands[0], mem);
8310   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8311                                                                   0), 0, 0),
8312                                         REG_NOTES (insn));
8314   DONE;
8317 (define_expand "sym2GOT"
8318   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8319   ""
8320   "")
8322 (define_expand "symGOT2reg"
8323   [(match_operand 0 "" "") (match_operand 1 "" "")]
8324   ""
8325   "
8327   rtx gotsym, insn;
8329   gotsym = gen_sym2GOT (operands[1]);
8330   PUT_MODE (gotsym, Pmode);
8331   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8333   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8335   DONE;
8338 (define_expand "sym2GOTPLT"
8339   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
8340   ""
8341   "")
8343 (define_expand "symGOTPLT2reg"
8344   [(match_operand 0 "" "") (match_operand 1 "" "")]
8345   ""
8346   "
8348   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
8349   DONE;
8352 (define_expand "sym2GOTOFF"
8353   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8354   ""
8355   "")
8357 (define_expand "symGOTOFF2reg"
8358   [(match_operand 0 "" "") (match_operand 1 "" "")]
8359   ""
8360   "
8362   rtx gotoffsym, insn;
8363   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8365   gotoffsym = gen_sym2GOTOFF (operands[1]);
8366   PUT_MODE (gotoffsym, Pmode);
8367   emit_move_insn (t, gotoffsym);
8368   insn = emit_move_insn (operands[0],
8369                          gen_rtx_PLUS (Pmode, t,
8370                                        gen_rtx_REG (Pmode, PIC_REG)));
8372   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8373                                         REG_NOTES (insn));
8375   DONE;
8378 (define_expand "symPLT_label2reg"
8379   [(set (match_operand:SI 0 "" "")
8380         (const:SI (minus:SI
8381                    (const:SI
8382                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8383                    (const:SI
8384                     (minus:SI
8385                      (const:SI (plus:SI
8386                                 (match_operand:SI 2 "" "")
8387                                 (const_int 2)))
8388                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8389    ;; Even though the PIC register is not really used by the call
8390    ;; sequence in which this is expanded, the PLT code assumes the PIC
8391    ;; register is set, so we must not skip its initialization.  Since
8392    ;; we only use this expand as part of calling sequences, and never
8393    ;; to take the address of a function, this is the best point to
8394    ;; insert the (use).  Using the PLT to take the address of a
8395    ;; function would be wrong, not only because the PLT entry could
8396    ;; then be called from a function that doesn't initialize the PIC
8397    ;; register to the proper GOT, but also because pointers to the
8398    ;; same function might not compare equal, should they be set by
8399    ;; different shared libraries.
8400    (use (reg:SI PIC_REG))]
8401   "TARGET_SH1"
8402   "")
8404 (define_expand "sym2PIC"
8405   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8406   ""
8407   "")
8409 ;; TLS code generation.
8410 ;; ??? this should be a define_insn_and_split
8411 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8412 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8413 ;; for details.
8415 (define_insn "tls_global_dynamic"
8416   [(set (match_operand:SI 0 "register_operand" "=&z")
8417         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8418                                   UNSPEC_TLSGD))
8419               (const_int 0)))
8420    (use (reg:PSI FPSCR_REG))
8421    (use (reg:SI PIC_REG))
8422    (clobber (reg:SI PR_REG))
8423    (clobber (scratch:SI))]
8424   "TARGET_SH1"
8425   "*
8427   return \"\\
8428 mov.l\\t1f,r4\\n\\
8429 \\tmova\\t2f,r0\\n\\
8430 \\tmov.l\\t2f,r1\\n\\
8431 \\tadd\\tr0,r1\\n\\
8432 \\tjsr\\t@r1\\n\\
8433 \\tadd\\tr12,r4\\n\\
8434 \\tbra\\t3f\\n\\
8435 \\tnop\\n\\
8436 \\t.align\\t2\\n\\
8437 1:\\t.long\\t%a1@TLSGD\\n\\
8438 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8439 3:\";
8441   [(set_attr "type" "tls_load")
8442    (set_attr "length" "26")])
8444 (define_insn "tls_local_dynamic"
8445   [(set (match_operand:SI 0 "register_operand" "=&z")
8446         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8447                                   UNSPEC_TLSLDM))
8448               (const_int 0)))
8449    (use (reg:PSI FPSCR_REG))
8450    (use (reg:SI PIC_REG))
8451    (clobber (reg:SI PR_REG))
8452    (clobber (scratch:SI))]
8453   "TARGET_SH1"
8454   "*
8456   return \"\\
8457 mov.l\\t1f,r4\\n\\
8458 \\tmova\\t2f,r0\\n\\
8459 \\tmov.l\\t2f,r1\\n\\
8460 \\tadd\\tr0,r1\\n\\
8461 \\tjsr\\t@r1\\n\\
8462 \\tadd\\tr12,r4\\n\\
8463 \\tbra\\t3f\\n\\
8464 \\tnop\\n\\
8465 \\t.align\\t2\\n\\
8466 1:\\t.long\\t%a1@TLSLDM\\n\\
8467 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8468 3:\";
8470   [(set_attr "type" "tls_load")
8471    (set_attr "length" "26")])
8473 (define_expand "sym2DTPOFF"
8474   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8475   ""
8476   "")
8478 (define_expand "symDTPOFF2reg"
8479   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8480   ""
8481   "
8483   rtx dtpoffsym, insn;
8484   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8486   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8487   PUT_MODE (dtpoffsym, Pmode);
8488   emit_move_insn (t, dtpoffsym);
8489   insn = emit_move_insn (operands[0],
8490                          gen_rtx_PLUS (Pmode, t, operands[2]));
8491   DONE;
8494 (define_expand "sym2GOTTPOFF"
8495   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8496   ""
8497   "")
8499 (define_insn "tls_initial_exec"
8500   [(set (match_operand:SI 0 "register_operand" "=&r")
8501         (unspec:SI [(match_operand:SI 1 "" "")]
8502                     UNSPEC_TLSIE))
8503    (use (reg:SI GBR_REG))
8504    (use (reg:SI PIC_REG))
8505    (clobber (reg:SI R0_REG))]
8506   ""
8507   "*
8509   return \"\\
8510 mov.l\\t1f,r0\\n\\
8511 \\tstc\\tgbr,%0\\n\\
8512 \\tmov.l\\t@(r0,r12),r0\\n\\
8513 \\tbra\\t2f\\n\\
8514 \\tadd\\tr0,%0\\n\\
8515 \\t.align\\t2\\n\\
8516 1:\\t.long\\t%a1\\n\\
8517 2:\";
8519   [(set_attr "type" "tls_load")
8520    (set_attr "length" "16")])
8522 (define_expand "sym2TPOFF"
8523   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8524   ""
8525   "")
8527 (define_expand "symTPOFF2reg"
8528   [(match_operand 0 "" "") (match_operand 1 "" "")]
8529   ""
8530   "
8532   rtx tpoffsym, insn;
8534   tpoffsym = gen_sym2TPOFF (operands[1]);
8535   PUT_MODE (tpoffsym, Pmode);
8536   insn = emit_move_insn (operands[0], tpoffsym);
8537   DONE;
8540 (define_insn "load_gbr"
8541   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8542    (use (reg:SI GBR_REG))]
8543   ""
8544   "stc  gbr,%0"
8545   [(set_attr "type" "tls_load")])
8547 ;; case instruction for switch statements.
8549 ;; Operand 0 is index
8550 ;; operand 1 is the minimum bound
8551 ;; operand 2 is the maximum bound - minimum bound + 1
8552 ;; operand 3 is CODE_LABEL for the table;
8553 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8555 (define_expand "casesi"
8556   [(match_operand:SI 0 "arith_reg_operand" "")
8557    (match_operand:SI 1 "arith_reg_operand" "")
8558    (match_operand:SI 2 "arith_reg_operand" "")
8559    (match_operand 3 "" "") (match_operand 4 "" "")]
8560   ""
8561   "
8563   rtx reg = gen_reg_rtx (SImode);
8564   rtx reg2 = gen_reg_rtx (SImode);
8565   if (TARGET_SHMEDIA)
8566     {
8567       rtx reg = gen_reg_rtx (DImode);
8568       rtx reg2 = gen_reg_rtx (DImode);
8569       rtx reg3 = gen_reg_rtx (Pmode);
8570       rtx reg4 = gen_reg_rtx (Pmode);
8571       rtx reg5 = gen_reg_rtx (Pmode);
8572       rtx load;
8574       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8575       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8576       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8578       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8579       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8580       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8581       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8582       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8583                                                (Pmode, operands[3])));
8584       /* Messy: can we subreg to clean this up? */
8585       if (Pmode == DImode)
8586         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8587       else
8588         load = gen_casesi_load_media (reg4,
8589                                       gen_rtx_SUBREG (DImode, reg3, 0),
8590                                       reg2, operands[3]);
8591       PUT_MODE (SET_SRC (load), Pmode);
8592       emit_insn (load);
8593       /* ??? The following add could be eliminated if we used ptrel.  */
8594       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8595       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8596       emit_barrier ();
8597       DONE;
8598     }
8599   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8600   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8601   /* If optimizing, casesi_worker depends on the mode of the instruction
8602      before label it 'uses' - operands[3].  */
8603   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8604                            reg));
8605   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8606   if (TARGET_SH2)
8607     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8608   else
8609     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8610   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8611      operands[3], but to lab.  We will fix this up in
8612      machine_dependent_reorg.  */
8613   emit_barrier ();
8614   DONE;
8617 (define_expand "casesi_0"
8618   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8619    (set (match_dup 4) (minus:SI (match_dup 4)
8620                                 (match_operand:SI 1 "arith_operand" "")))
8621    (set (reg:SI T_REG)
8622         (gtu:SI (match_dup 4)
8623                 (match_operand:SI 2 "arith_reg_operand" "")))
8624    (set (pc)
8625         (if_then_else (ne (reg:SI T_REG)
8626                           (const_int 0))
8627                       (label_ref (match_operand 3 "" ""))
8628                       (pc)))]
8629   "TARGET_SH1"
8630   "")
8632 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8633 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8634 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8636 (define_insn "casesi_worker_0"
8637   [(set (match_operand:SI 0 "register_operand" "=r,r")
8638         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8639                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8640    (clobber (match_scratch:SI 3 "=X,1"))
8641    (clobber (match_scratch:SI 4 "=&z,z"))]
8642   "TARGET_SH1"
8643   "#")
8645 (define_split
8646   [(set (match_operand:SI 0 "register_operand" "")
8647         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8648                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8649    (clobber (match_scratch:SI 3 ""))
8650    (clobber (match_scratch:SI 4 ""))]
8651   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8652   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8653    (parallel [(set (match_dup 0)
8654               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8655                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8656               (clobber (match_dup 3))])
8657    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8658   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8660 (define_split
8661   [(set (match_operand:SI 0 "register_operand" "")
8662         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8663                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8664    (clobber (match_scratch:SI 3 ""))
8665    (clobber (match_scratch:SI 4 ""))]
8666   "TARGET_SH2 && reload_completed"
8667   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8668    (parallel [(set (match_dup 0)
8669               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8670                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8671               (clobber (match_dup 3))])]
8672   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8674 (define_insn "casesi_worker_1"
8675   [(set (match_operand:SI 0 "register_operand" "=r,r")
8676         (unspec:SI [(reg:SI R0_REG)
8677                     (match_operand:SI 1 "register_operand" "0,r")
8678                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8679    (clobber (match_scratch:SI 3 "=X,1"))]
8680   "TARGET_SH1"
8681   "*
8683   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8685   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8687   switch (GET_MODE (diff_vec))
8688     {
8689     case SImode:
8690       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8691     case HImode:
8692       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8693     case QImode:
8694       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8695         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8696       return \"mov.b    @(r0,%1),%0\";
8697     default:
8698       gcc_unreachable ();
8699     }
8701   [(set_attr "length" "4")])
8703 (define_insn "casesi_worker_2"
8704   [(set (match_operand:SI 0 "register_operand" "=r,r")
8705         (unspec:SI [(reg:SI R0_REG)
8706                     (match_operand:SI 1 "register_operand" "0,r")
8707                     (label_ref (match_operand 2 "" ""))
8708                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8709    (clobber (match_operand:SI 4 "" "=X,1"))]
8710   "TARGET_SH2 && reload_completed && flag_pic"
8711   "*
8713   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8714   const char *load;
8716   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8718   switch (GET_MODE (diff_vec))
8719     {
8720     case SImode:
8721       output_asm_insn (\"shll2    %1\", operands);
8722       load = \"mov.l    @(r0,%1),%0\"; break;
8723     case HImode:
8724       output_asm_insn (\"add    %1,%1\", operands);
8725       load = \"mov.w    @(r0,%1),%0\"; break;
8726     case QImode:
8727       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8728         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8729       else
8730         load = \"mov.b  @(r0,%1),%0\";
8731       break;
8732     default:
8733       gcc_unreachable ();
8734     }
8735   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8736   return load;
8738   [(set_attr "length" "8")])
8740 (define_insn "casesi_shift_media"
8741   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8742         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8743                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8744                     UNSPEC_CASESI)))]
8745   "TARGET_SHMEDIA"
8746   "*
8748   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8750   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8752   switch (GET_MODE (diff_vec))
8753     {
8754     case SImode:
8755       return \"shlli    %1, 2, %0\";
8756     case HImode:
8757       return \"shlli    %1, 1, %0\";
8758     case QImode:
8759       if (rtx_equal_p (operands[0], operands[1]))
8760         return \"\";
8761       return \"add      %1, r63, %0\";
8762     default:
8763       gcc_unreachable ();
8764     }
8766   [(set_attr "type" "arith_media")])
8768 (define_insn "casesi_load_media"
8769   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8770         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8771                          (match_operand:DI 2 "arith_reg_operand" "r")
8772                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8773   "TARGET_SHMEDIA"
8774   "*
8776   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8778   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8780   switch (GET_MODE (diff_vec))
8781     {
8782     case SImode:
8783       return \"ldx.l    %1, %2, %0\";
8784     case HImode:
8785 #if 0
8786       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8787         return \"ldx.uw %1, %2, %0\";
8788 #endif
8789       return \"ldx.w    %1, %2, %0\";
8790     case QImode:
8791       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8792         return \"ldx.ub %1, %2, %0\";
8793       return \"ldx.b    %1, %2, %0\";
8794     default:
8795       gcc_unreachable ();
8796     }
8798   [(set_attr "type" "load_media")])
8800 (define_expand "return"
8801   [(return)]
8802   "reload_completed && ! sh_need_epilogue ()"
8803   "
8805   if (TARGET_SHMEDIA)
8806     {
8807       emit_jump_insn (gen_return_media ());
8808       DONE;
8809     }
8811   if (TARGET_SHCOMPACT
8812       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8813     {
8814       emit_jump_insn (gen_shcompact_return_tramp ());
8815       DONE;
8816     }
8819 (define_insn "*return_i"
8820   [(return)]
8821   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8822                     && (current_function_args_info.call_cookie
8823                         & CALL_COOKIE_RET_TRAMP (1)))
8824    && reload_completed
8825    && sh_cfun_trap_exit_p ()"
8826   "%@   %#"
8827   [(set_attr "type" "return")
8828    (set_attr "needs_delay_slot" "yes")])
8830 ;; trapa has no delay slot.
8831 (define_insn "*return_trapa"
8832   [(return)]
8833   "TARGET_SH1 && !TARGET_SHCOMPACT
8834    && reload_completed"
8835   "%@"
8836   [(set_attr "type" "return")])
8838 (define_expand "shcompact_return_tramp"
8839   [(return)]
8840   "TARGET_SHCOMPACT
8841    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8842   "
8844   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8846   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8847   emit_jump_insn (gen_shcompact_return_tramp_i ());
8848   DONE;
8851 (define_insn "shcompact_return_tramp_i"
8852   [(parallel [(return) (use (reg:SI R0_REG))])]
8853   "TARGET_SHCOMPACT
8854    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8855   "jmp  @r0%#"
8856   [(set_attr "type" "jump_ind")
8857    (set_attr "needs_delay_slot" "yes")])
8859 (define_insn "return_media_i"
8860   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8861   "TARGET_SHMEDIA && reload_completed"
8862   "blink        %0, r63"
8863   [(set_attr "type" "jump_media")])
8865 (define_insn "return_media_rte"
8866   [(return)]
8867   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8868   "rte"
8869   [(set_attr "type" "jump_media")])
8871 (define_expand "return_media"
8872   [(return)]
8873   "TARGET_SHMEDIA && reload_completed"
8874   "
8876   int tr_regno = sh_media_register_for_return ();
8877   rtx tr;
8879   if (current_function_interrupt)
8880     {
8881       emit_jump_insn (gen_return_media_rte ());
8882       DONE;
8883     }
8884   if (tr_regno < 0)
8885     {
8886       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8888       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8889       tr_regno = TR0_REG;
8890       tr = gen_rtx_REG (Pmode, tr_regno);
8891       emit_move_insn (tr, r18);
8892     }
8893   else
8894     tr = gen_rtx_REG (Pmode, tr_regno);
8896   emit_jump_insn (gen_return_media_i (tr));
8897   DONE;
8900 (define_insn "shcompact_preserve_incoming_args"
8901   [(set (match_operand:SI 0 "register_operand" "+r")
8902         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8903   "TARGET_SHCOMPACT"
8904   ""
8905   [(set_attr "length" "0")])
8907 (define_insn "shcompact_incoming_args"
8908   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8909    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8910    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8911    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8912    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8913    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8914    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8915    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8916    (set (mem:BLK (reg:SI MACL_REG))
8917         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8918    (use (reg:SI R0_REG))
8919    (clobber (reg:SI R0_REG))
8920    (clobber (reg:SI MACL_REG))
8921    (clobber (reg:SI MACH_REG))
8922    (clobber (reg:SI PR_REG))]
8923   "TARGET_SHCOMPACT"
8924   "jsr  @r0%#"
8925   [(set_attr "needs_delay_slot" "yes")])
8927 (define_insn "shmedia_save_restore_regs_compact"
8928   [(set (reg:SI SP_REG)
8929         (plus:SI (reg:SI SP_REG)
8930                  (match_operand:SI 0 "immediate_operand" "i")))
8931    (use (reg:SI R0_REG))
8932    (clobber (reg:SI PR_REG))]
8933   "TARGET_SHCOMPACT
8934    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8935        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8936   "jsr @r0%#"
8937   [(set_attr "needs_delay_slot" "yes")])
8939 (define_expand "prologue"
8940   [(const_int 0)]
8941   ""
8942   "sh_expand_prologue (); DONE;")
8944 (define_expand "epilogue"
8945   [(return)]
8946   ""
8947   "
8949   sh_expand_epilogue (0);
8950   emit_jump_insn (gen_return ());
8951   DONE;
8954 (define_expand "eh_return"
8955   [(use (match_operand 0 "register_operand" ""))]
8956   ""
8958   rtx ra = operands[0];
8960   if (TARGET_SHMEDIA64)
8961     emit_insn (gen_eh_set_ra_di (ra));
8962   else
8963     emit_insn (gen_eh_set_ra_si (ra));
8965   DONE;
8968 ;; Clobber the return address on the stack.  We can't expand this
8969 ;; until we know where it will be put in the stack frame.
8971 (define_insn "eh_set_ra_si"
8972   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8973    (clobber (match_scratch:SI 1 "=&r"))]
8974   "! TARGET_SHMEDIA64"
8975   "#")
8977 (define_insn "eh_set_ra_di"
8978   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8979    (clobber (match_scratch:DI 1 "=&r"))]
8980   "TARGET_SHMEDIA64"
8981   "#")
8983 (define_split
8984   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8985    (clobber (match_scratch 1 ""))]
8986   "reload_completed"
8987   [(const_int 0)]
8988   "
8990   sh_set_return_address (operands[0], operands[1]);
8991   DONE;
8994 (define_insn "blockage"
8995   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8996   ""
8997   ""
8998   [(set_attr "length" "0")])
9000 ;; ------------------------------------------------------------------------
9001 ;; Scc instructions
9002 ;; ------------------------------------------------------------------------
9004 (define_insn "movt"
9005   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9006         (eq:SI (reg:SI T_REG) (const_int 1)))]
9007   "TARGET_SH1"
9008   "movt %0"
9009   [(set_attr "type" "arith")])
9011 (define_expand "seq"
9012   [(set (match_operand:SI 0 "arith_reg_dest" "")
9013         (match_dup 1))]
9014   ""
9015   "
9017   if (TARGET_SHMEDIA)
9018     {
9019       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9020       if (sh_compare_op1 != const0_rtx)
9021         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9022                                     ? GET_MODE (sh_compare_op0)
9023                                     : GET_MODE (sh_compare_op1),
9024                                     sh_compare_op1);
9025       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9026         {
9027           if (GET_MODE (operands[0]) != SImode)
9028             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9030           switch (GET_MODE (sh_compare_op0))
9031             {
9032             case SImode:
9033               emit_insn (gen_cmpsieqsi_media (operands[0],
9034                                               sh_compare_op0, sh_compare_op1));
9035               break;
9037             case DImode:
9038               emit_insn (gen_cmpsieqdi_media (operands[0],
9039                                               sh_compare_op0, sh_compare_op1));
9040               break;
9042             case SFmode:
9043               if (! TARGET_SHMEDIA_FPU)
9044                 FAIL;
9045               emit_insn (gen_cmpsieqsf_media (operands[0],
9046                                               sh_compare_op0, sh_compare_op1));
9047               break;
9049             case DFmode:
9050               if (! TARGET_SHMEDIA_FPU)
9051                 FAIL;
9052               emit_insn (gen_cmpsieqdf_media (operands[0],
9053                                               sh_compare_op0, sh_compare_op1));
9054               break;
9056             default:
9057               FAIL;
9058             }
9059           DONE;
9060         }
9062       if (GET_MODE (operands[0]) != DImode)
9063         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9065       switch (GET_MODE (sh_compare_op0))
9066         {
9067         case SImode:
9068           emit_insn (gen_cmpeqsi_media (operands[0],
9069                                         sh_compare_op0, sh_compare_op1));
9070           break;
9072         case DImode:
9073           emit_insn (gen_cmpeqdi_media (operands[0],
9074                                         sh_compare_op0, sh_compare_op1));
9075           break;
9077         case SFmode:
9078           if (! TARGET_SHMEDIA_FPU)
9079             FAIL;
9080           emit_insn (gen_cmpeqsf_media (operands[0],
9081                                         sh_compare_op0, sh_compare_op1));
9082           break;
9084         case DFmode:
9085           if (! TARGET_SHMEDIA_FPU)
9086             FAIL;
9087           emit_insn (gen_cmpeqdf_media (operands[0],
9088                                         sh_compare_op0, sh_compare_op1));
9089           break;
9091         default:
9092           FAIL;
9093         }
9094       DONE;
9095     }
9096   if (sh_expand_t_scc (EQ, operands[0]))
9097     DONE;
9098   if (! currently_expanding_to_rtl)
9099     FAIL;
9100   operands[1] = prepare_scc_operands (EQ);
9103 (define_expand "slt"
9104   [(set (match_operand:SI 0 "arith_reg_operand" "")
9105         (match_dup 1))]
9106   ""
9107   "
9109   if (TARGET_SHMEDIA)
9110     {
9111       if (GET_MODE (operands[0]) != DImode)
9112         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9113       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9114       if (sh_compare_op1 != const0_rtx)
9115         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9116                                     ? GET_MODE (sh_compare_op0)
9117                                     : GET_MODE (sh_compare_op1),
9118                                     sh_compare_op1);
9120       switch (GET_MODE (sh_compare_op0))
9121         {
9122         case SImode:
9123           emit_insn (gen_cmpgtsi_media (operands[0],
9124                                         sh_compare_op1, sh_compare_op0));
9125           break;
9127         case DImode:
9128           emit_insn (gen_cmpgtdi_media (operands[0],
9129                                         sh_compare_op1, sh_compare_op0));
9130           break;
9132         case SFmode:
9133           if (! TARGET_SHMEDIA_FPU)
9134             FAIL;
9135           emit_insn (gen_cmpgtsf_media (operands[0],
9136                                         sh_compare_op1, sh_compare_op0));
9137           break;
9139         case DFmode:
9140           if (! TARGET_SHMEDIA_FPU)
9141             FAIL;
9142           emit_insn (gen_cmpgtdf_media (operands[0],
9143                                         sh_compare_op1, sh_compare_op0));
9144           break;
9146         default:
9147           FAIL;
9148         }
9149       DONE;
9150     }
9151   if (! currently_expanding_to_rtl)
9152     FAIL;
9153   operands[1] = prepare_scc_operands (LT);
9156 (define_expand "sle"
9157   [(match_operand:SI 0 "arith_reg_operand" "")]
9158   ""
9159   "
9161   rtx tmp = sh_compare_op0;
9163   if (TARGET_SHMEDIA)
9164     {
9165       if (GET_MODE (operands[0]) != DImode)
9166         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9167       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9168       if (sh_compare_op1 != const0_rtx)
9169         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9170                                     ? GET_MODE (sh_compare_op0)
9171                                     : GET_MODE (sh_compare_op1),
9172                                     sh_compare_op1);
9174       switch (GET_MODE (sh_compare_op0))
9175         {
9176         case SImode:
9177           {
9178             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9180             emit_insn (gen_cmpgtsi_media (tmp,
9181                                           sh_compare_op0, sh_compare_op1));
9182             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9183             break;
9184           }
9186         case DImode:
9187           {
9188             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9190             emit_insn (gen_cmpgtdi_media (tmp,
9191                                           sh_compare_op0, sh_compare_op1));
9192             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9193             break;
9194           }
9196         case SFmode:
9197           if (! TARGET_SHMEDIA_FPU)
9198             FAIL;
9199           emit_insn (gen_cmpgesf_media (operands[0],
9200                                         sh_compare_op1, sh_compare_op0));
9201           break;
9203         case DFmode:
9204           if (! TARGET_SHMEDIA_FPU)
9205             FAIL;
9206           emit_insn (gen_cmpgedf_media (operands[0],
9207                                         sh_compare_op1, sh_compare_op0));
9208           break;
9210         default:
9211           FAIL;
9212         }
9213       DONE;
9214     }
9216   sh_compare_op0 = sh_compare_op1;
9217   sh_compare_op1 = tmp;
9218   emit_insn (gen_sge (operands[0]));
9219   DONE;
9222 (define_expand "sgt"
9223   [(set (match_operand:SI 0 "arith_reg_operand" "")
9224         (match_dup 1))]
9225   ""
9226   "
9228   if (TARGET_SHMEDIA)
9229     {
9230       if (GET_MODE (operands[0]) != DImode)
9231         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9232       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9233       if (sh_compare_op1 != const0_rtx)
9234         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9235                                     ? GET_MODE (sh_compare_op0)
9236                                     : GET_MODE (sh_compare_op1),
9237                                     sh_compare_op1);
9239       switch (GET_MODE (sh_compare_op0))
9240         {
9241         case SImode:
9242           emit_insn (gen_cmpgtsi_media (operands[0],
9243                                         sh_compare_op0, sh_compare_op1));
9244           break;
9246         case DImode:
9247           emit_insn (gen_cmpgtdi_media (operands[0],
9248                                         sh_compare_op0, sh_compare_op1));
9249           break;
9251         case SFmode:
9252           if (! TARGET_SHMEDIA_FPU)
9253             FAIL;
9254           emit_insn (gen_cmpgtsf_media (operands[0],
9255                                         sh_compare_op0, sh_compare_op1));
9256           break;
9258         case DFmode:
9259           if (! TARGET_SHMEDIA_FPU)
9260             FAIL;
9261           emit_insn (gen_cmpgtdf_media (operands[0],
9262                                         sh_compare_op0, sh_compare_op1));
9263           break;
9265         default:
9266           FAIL;
9267         }
9268       DONE;
9269     }
9270   if (! currently_expanding_to_rtl)
9271     FAIL;
9272   operands[1] = prepare_scc_operands (GT);
9275 (define_expand "sge"
9276   [(set (match_operand:SI 0 "arith_reg_operand" "")
9277         (match_dup 1))]
9278   ""
9279   "
9281   if (TARGET_SHMEDIA)
9282     {
9283       enum machine_mode mode = GET_MODE (sh_compare_op0);
9285       if ((mode) == VOIDmode)
9286         mode = GET_MODE (sh_compare_op1);
9287       if (GET_MODE (operands[0]) != DImode)
9288         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9289       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9290       if (sh_compare_op1 != const0_rtx)
9291         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9293       switch (mode)
9294         {
9295         case SImode:
9296           {
9297             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9299             emit_insn (gen_cmpgtsi_media (tmp,
9300                                           sh_compare_op1, sh_compare_op0));
9301             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9302             break;
9303           }
9305         case DImode:
9306           {
9307             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9309             emit_insn (gen_cmpgtdi_media (tmp,
9310                                           sh_compare_op1, sh_compare_op0));
9311             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9312             break;
9313           }
9315         case SFmode:
9316           if (! TARGET_SHMEDIA_FPU)
9317             FAIL;
9318           emit_insn (gen_cmpgesf_media (operands[0],
9319                                         sh_compare_op0, sh_compare_op1));
9320           break;
9322         case DFmode:
9323           if (! TARGET_SHMEDIA_FPU)
9324             FAIL;
9325           emit_insn (gen_cmpgedf_media (operands[0],
9326                                         sh_compare_op0, sh_compare_op1));
9327           break;
9329         default:
9330           FAIL;
9331         }
9332       DONE;
9333     }
9335   if (! currently_expanding_to_rtl)
9336     FAIL;
9337   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9338     {
9339       if (TARGET_IEEE)
9340         {
9341           rtx lab = gen_label_rtx ();
9342           prepare_scc_operands (EQ);
9343           emit_jump_insn (gen_branch_true (lab));
9344           prepare_scc_operands (GT);
9345           emit_label (lab);
9346           emit_insn (gen_movt (operands[0]));
9347         }
9348       else
9349         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9350       DONE;
9351     }
9352   operands[1] = prepare_scc_operands (GE);
9355 (define_expand "sgtu"
9356   [(set (match_operand:SI 0 "arith_reg_operand" "")
9357         (match_dup 1))]
9358   ""
9359   "
9361   if (TARGET_SHMEDIA)
9362     {
9363       if (GET_MODE (operands[0]) != DImode)
9364         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9365       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9366       if (sh_compare_op1 != const0_rtx)
9367         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9368                                     ? GET_MODE (sh_compare_op0)
9369                                     : GET_MODE (sh_compare_op1),
9370                                     sh_compare_op1);
9372       emit_insn (gen_cmpgtudi_media (operands[0],
9373                                      sh_compare_op0, sh_compare_op1));
9374       DONE;
9375     }
9376   if (! currently_expanding_to_rtl)
9377     FAIL;
9378   operands[1] = prepare_scc_operands (GTU);
9381 (define_expand "sltu"
9382   [(set (match_operand:SI 0 "arith_reg_operand" "")
9383         (match_dup 1))]
9384   ""
9385   "
9387   if (TARGET_SHMEDIA)
9388     {
9389       if (GET_MODE (operands[0]) != DImode)
9390         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9391       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9392       if (sh_compare_op1 != const0_rtx)
9393         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9394                                     ? GET_MODE (sh_compare_op0)
9395                                     : GET_MODE (sh_compare_op1),
9396                                     sh_compare_op1);
9398       emit_insn (gen_cmpgtudi_media (operands[0],
9399                                      sh_compare_op1, sh_compare_op0));
9400       DONE;
9401     }
9402   if (! currently_expanding_to_rtl)
9403     FAIL;
9404   operands[1] = prepare_scc_operands (LTU);
9407 (define_expand "sleu"
9408   [(set (match_operand:SI 0 "arith_reg_operand" "")
9409         (match_dup 1))]
9410   ""
9411   "
9413   if (TARGET_SHMEDIA)
9414     {
9415       rtx tmp;
9417       if (GET_MODE (operands[0]) != DImode)
9418         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9419       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9420       if (sh_compare_op1 != const0_rtx)
9421         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9422                                     ? GET_MODE (sh_compare_op0)
9423                                     : GET_MODE (sh_compare_op1),
9424                                     sh_compare_op1);
9426       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9428       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9429       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9431       DONE;
9432     }
9433   if (! currently_expanding_to_rtl)
9434     FAIL;
9435   operands[1] = prepare_scc_operands (LEU);
9438 (define_expand "sgeu"
9439   [(set (match_operand:SI 0 "arith_reg_operand" "")
9440         (match_dup 1))]
9441   ""
9442   "
9444   if (TARGET_SHMEDIA)
9445     {
9446       rtx tmp;
9448       if (GET_MODE (operands[0]) != DImode)
9449         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9450       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9451       if (sh_compare_op1 != const0_rtx)
9452         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9453                                     ? GET_MODE (sh_compare_op0)
9454                                     : GET_MODE (sh_compare_op1),
9455                                     sh_compare_op1);
9457       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9459       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9460       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9462       DONE;
9463     }
9465   if (! currently_expanding_to_rtl)
9466     FAIL;
9467   operands[1] = prepare_scc_operands (GEU);
9470 ;; sne moves the complement of the T reg to DEST like this:
9471 ;;      cmp/eq ...
9472 ;;      mov    #-1,temp
9473 ;;      negc   temp,dest
9474 ;;   This is better than xoring compare result with 1 because it does
9475 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9476 ;;   loop.
9478 (define_expand "sne"
9479   [(set (match_dup 2) (const_int -1))
9480    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9481                    (neg:SI (plus:SI (match_dup 1)
9482                                     (match_dup 2))))
9483               (set (reg:SI T_REG)
9484                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9485                           (const_int 0)))])]
9486   ""
9487   "
9489   if (TARGET_SHMEDIA)
9490     {
9491       rtx tmp;
9493       if (GET_MODE (operands[0]) != DImode)
9494         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9496       if (! TARGET_SHMEDIA_FPU
9497           && GET_MODE (sh_compare_op0) != DImode
9498           && GET_MODE (sh_compare_op0) != SImode)
9499         FAIL;
9501       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9502       if (sh_compare_op1 != const0_rtx)
9503         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9504                                     ? GET_MODE (sh_compare_op0)
9505                                     : GET_MODE (sh_compare_op1),
9506                                     sh_compare_op1);
9508       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9510       emit_insn (gen_seq (tmp));
9511       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9513       DONE;
9514     }
9516   if (sh_expand_t_scc (NE, operands[0]))
9517     DONE;
9518   if (! currently_expanding_to_rtl)
9519     FAIL;
9520   operands[1] = prepare_scc_operands (EQ);
9521   operands[2] = gen_reg_rtx (SImode);
9524 (define_expand "sunordered"
9525   [(set (match_operand:DI 0 "arith_reg_operand" "")
9526         (unordered:DI (match_dup 1) (match_dup 2)))]
9527   "TARGET_SHMEDIA_FPU"
9528   "
9530   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9531   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9534 ;; Use the same trick for FP sle / sge
9536 ;; Apart from the constant use and the T setting, this is like movt,
9537 ;; except that it uses the logically negated value of T, i.e.
9538 ;; operand[0] := T ? 0 : 1.
9539 (define_expand "movnegt"
9540   [(set (match_dup 2) (const_int -1))
9541    (parallel [(set (match_operand 0 "" "")
9542                    (neg:SI (plus:SI (match_dup 1)
9543                                     (match_dup 2))))
9544               (set (reg:SI T_REG)
9545                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9546                           (const_int 0)))])]
9547   "TARGET_SH1"
9548   "operands[2] = gen_reg_rtx (SImode);")
9550 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9551 ;; This prevents a regression that occurred when we switched from xor to
9552 ;; mov/neg for sne.
9554 (define_split
9555   [(set (match_operand:SI 0 "arith_reg_dest" "")
9556         (plus:SI (reg:SI T_REG)
9557                  (const_int -1)))]
9558   "TARGET_SH1"
9559   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9560    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9561   "")
9563 ;; -------------------------------------------------------------------------
9564 ;; Instructions to cope with inline literal tables
9565 ;; -------------------------------------------------------------------------
9567 ; 2 byte integer in line
9569 (define_insn "consttable_2"
9570  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9571                     (match_operand 1 "" "")]
9572                    UNSPECV_CONST2)]
9573  ""
9574  "*
9576   if (operands[1] != const0_rtx)
9577     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9578   return \"\";
9580  [(set_attr "length" "2")
9581  (set_attr "in_delay_slot" "no")])
9583 ; 4 byte integer in line
9585 (define_insn "consttable_4"
9586  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9587                     (match_operand 1 "" "")]
9588                    UNSPECV_CONST4)]
9589  ""
9590  "*
9592   if (operands[1] != const0_rtx)
9593     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9594   return \"\";
9596  [(set_attr "length" "4")
9597   (set_attr "in_delay_slot" "no")])
9599 ; 8 byte integer in line
9601 (define_insn "consttable_8"
9602  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9603                     (match_operand 1 "" "")]
9604                    UNSPECV_CONST8)]
9605  ""
9606  "*
9608   if (operands[1] != const0_rtx)
9609     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9610   return \"\";
9612  [(set_attr "length" "8")
9613   (set_attr "in_delay_slot" "no")])
9615 ; 4 byte floating point
9617 (define_insn "consttable_sf"
9618  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9619                     (match_operand 1 "" "")]
9620                    UNSPECV_CONST4)]
9621  ""
9622  "*
9624   if (operands[1] != const0_rtx)
9625     {
9626       REAL_VALUE_TYPE d;
9627       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9628       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9629     }
9630   return \"\";
9632  [(set_attr "length" "4")
9633   (set_attr "in_delay_slot" "no")])
9635 ; 8 byte floating point
9637 (define_insn "consttable_df"
9638  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9639                     (match_operand 1 "" "")]
9640                    UNSPECV_CONST8)]
9641  ""
9642  "*
9644   if (operands[1] != const0_rtx)
9645     {
9646       REAL_VALUE_TYPE d;
9647       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9648       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9649     }
9650   return \"\";
9652  [(set_attr "length" "8")
9653   (set_attr "in_delay_slot" "no")])
9655 ;; Alignment is needed for some constant tables; it may also be added for
9656 ;; Instructions at the start of loops, or after unconditional branches.
9657 ;; ??? We would get more accurate lengths if we did instruction
9658 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9659 ;; here is too conservative.
9661 ; align to a two byte boundary
9663 (define_expand "align_2"
9664  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9665  ""
9666  "")
9668 ; align to a four byte boundary
9669 ;; align_4 and align_log are instructions for the starts of loops, or
9670 ;; after unconditional branches, which may take up extra room.
9672 (define_expand "align_4"
9673  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9674  ""
9675  "")
9677 ; align to a cache line boundary
9679 (define_insn "align_log"
9680  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9681  ""
9682  ""
9683  [(set_attr "length" "0")
9684   (set_attr "in_delay_slot" "no")])
9686 ; emitted at the end of the literal table, used to emit the
9687 ; 32bit branch labels if needed.
9689 (define_insn "consttable_end"
9690   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9691   ""
9692   "* return output_jump_label_table ();"
9693   [(set_attr "in_delay_slot" "no")])
9695 ; emitted at the end of the window in the literal table.
9697 (define_insn "consttable_window_end"
9698   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9699   ""
9700   ""
9701   [(set_attr "length" "0")
9702    (set_attr "in_delay_slot" "no")])
9704 ;; -------------------------------------------------------------------------
9705 ;; Misc
9706 ;; -------------------------------------------------------------------------
9708 ;; String/block move insn.
9710 (define_expand "movmemsi"
9711   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9712                    (mem:BLK (match_operand:BLK 1 "" "")))
9713               (use (match_operand:SI 2 "nonmemory_operand" ""))
9714               (use (match_operand:SI 3 "immediate_operand" ""))
9715               (clobber (reg:SI PR_REG))
9716               (clobber (reg:SI R4_REG))
9717               (clobber (reg:SI R5_REG))
9718               (clobber (reg:SI R0_REG))])]
9719   "TARGET_SH1 && ! TARGET_SH5"
9720   "
9722   if(expand_block_move (operands))
9723      DONE;
9724   else FAIL;
9727 (define_insn "block_move_real"
9728   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9729                    (mem:BLK (reg:SI R5_REG)))
9730               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9731               (clobber (reg:SI PR_REG))
9732               (clobber (reg:SI R0_REG))])]
9733   "TARGET_SH1 && ! TARGET_HARD_SH4"
9734   "jsr  @%0%#"
9735   [(set_attr "type" "sfunc")
9736    (set_attr "needs_delay_slot" "yes")])
9738 (define_insn "block_lump_real"
9739   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9740                    (mem:BLK (reg:SI R5_REG)))
9741               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9742               (use (reg:SI R6_REG))
9743               (clobber (reg:SI PR_REG))
9744               (clobber (reg:SI T_REG))
9745               (clobber (reg:SI R4_REG))
9746               (clobber (reg:SI R5_REG))
9747               (clobber (reg:SI R6_REG))
9748               (clobber (reg:SI R0_REG))])]
9749   "TARGET_SH1 && ! TARGET_HARD_SH4"
9750   "jsr  @%0%#"
9751   [(set_attr "type" "sfunc")
9752    (set_attr "needs_delay_slot" "yes")])
9754 (define_insn "block_move_real_i4"
9755   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9756                    (mem:BLK (reg:SI R5_REG)))
9757               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9758               (clobber (reg:SI PR_REG))
9759               (clobber (reg:SI R0_REG))
9760               (clobber (reg:SI R1_REG))
9761               (clobber (reg:SI R2_REG))])]
9762   "TARGET_HARD_SH4"
9763   "jsr  @%0%#"
9764   [(set_attr "type" "sfunc")
9765    (set_attr "needs_delay_slot" "yes")])
9767 (define_insn "block_lump_real_i4"
9768   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9769                    (mem:BLK (reg:SI R5_REG)))
9770               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9771               (use (reg:SI R6_REG))
9772               (clobber (reg:SI PR_REG))
9773               (clobber (reg:SI T_REG))
9774               (clobber (reg:SI R4_REG))
9775               (clobber (reg:SI R5_REG))
9776               (clobber (reg:SI R6_REG))
9777               (clobber (reg:SI R0_REG))
9778               (clobber (reg:SI R1_REG))
9779               (clobber (reg:SI R2_REG))
9780               (clobber (reg:SI R3_REG))])]
9781   "TARGET_HARD_SH4"
9782   "jsr  @%0%#"
9783   [(set_attr "type" "sfunc")
9784    (set_attr "needs_delay_slot" "yes")])
9786 ;; -------------------------------------------------------------------------
9787 ;; Floating point instructions.
9788 ;; -------------------------------------------------------------------------
9790 ;; ??? All patterns should have a type attribute.
9792 (define_expand "movpsi"
9793   [(set (match_operand:PSI 0 "register_operand" "")
9794         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9795   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9796   "")
9798 ;; The c / m alternative is a fake to guide reload to load directly into
9799 ;; fpscr, since reload doesn't know how to use post-increment.
9800 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9801 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9802 ;; predicate after reload.
9803 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9804 ;; like a mac -> gpr move.
9805 (define_insn "fpu_switch"
9806   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9807         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9808   "TARGET_SH2E
9809    && (! reload_completed
9810        || true_regnum (operands[0]) != FPSCR_REG
9811        || GET_CODE (operands[1]) != MEM
9812        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9813   "@
9814         ! precision stays the same
9815         lds.l   %1,fpscr
9816         mov.l   %1,%0
9817         #
9818         lds     %1,fpscr
9819         mov     %1,%0
9820         mov.l   %1,%0
9821         sts     fpscr,%0
9822         sts.l   fpscr,%0"
9823   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9824    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9826 (define_peephole2
9827   [(set (reg:PSI FPSCR_REG)
9828         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9829   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9830   [(const_int 0)]
9832   rtx fpscr, mem, new_insn;
9834   fpscr = SET_DEST (PATTERN (curr_insn));
9835   mem = SET_SRC (PATTERN (curr_insn));
9836   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9838   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9839   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9840   DONE;
9843 (define_split
9844   [(set (reg:PSI FPSCR_REG)
9845         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9846   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9847    && (flag_peephole2 ? flow2_completed : reload_completed)"
9848   [(const_int 0)]
9850   rtx fpscr, mem, new_insn;
9852   fpscr = SET_DEST (PATTERN (curr_insn));
9853   mem = SET_SRC (PATTERN (curr_insn));
9854   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9856   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9857   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9859   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9860     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9861   DONE;
9864 ;; ??? This uses the fp unit, but has no type indicating that.
9865 ;; If we did that, this would either give a bogus latency or introduce
9866 ;; a bogus FIFO constraint.
9867 ;; Since this insn is currently only used for prologues/epilogues,
9868 ;; it is probably best to claim no function unit, which matches the
9869 ;; current setting.
9870 (define_insn "toggle_sz"
9871   [(set (reg:PSI FPSCR_REG)
9872         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9873   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9874   "fschg"
9875   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9877 ;; There's no way we can use it today, since optimize mode switching
9878 ;; doesn't enable us to know from which mode we're switching to the
9879 ;; mode it requests, to tell whether we can use a relative mode switch
9880 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9881 ;; memory).
9882 (define_insn "toggle_pr"
9883   [(set (reg:PSI FPSCR_REG)
9884         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9885   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9886   "fpchg"
9887   [(set_attr "type" "fp")])
9889 (define_expand "addsf3"
9890   [(set (match_operand:SF 0 "arith_reg_operand" "")
9891         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9892                  (match_operand:SF 2 "arith_reg_operand" "")))]
9893   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9894   "
9896   if (TARGET_SH2E)
9897     {
9898       expand_sf_binop (&gen_addsf3_i, operands);
9899       DONE;
9900     }
9903 (define_insn "*addsf3_media"
9904   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9905         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9906                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9907   "TARGET_SHMEDIA_FPU"
9908   "fadd.s       %1, %2, %0"
9909   [(set_attr "type" "fparith_media")])
9911 (define_insn_and_split "unary_sf_op"
9912   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9913         (vec_select:V2SF
9914          (vec_concat:V2SF
9915           (vec_select:SF
9916            (match_dup 0)
9917            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9918           (match_operator:SF 2 "unary_float_operator"
9919             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9920                             (parallel [(match_operand 4
9921                                         "const_int_operand" "n")]))]))
9922          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9923   "TARGET_SHMEDIA_FPU"
9924   "#"
9925   "TARGET_SHMEDIA_FPU && reload_completed"
9926   [(set (match_dup 5) (match_dup 6))]
9927   "
9929   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9930   rtx op1 = gen_rtx_REG (SFmode,
9931                          (true_regnum (operands[1])
9932                           + (INTVAL (operands[4]) ^ endian)));
9934   operands[7] = gen_rtx_REG (SFmode,
9935                              (true_regnum (operands[0])
9936                               + (INTVAL (operands[3]) ^ endian)));
9937   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9939   [(set_attr "type" "fparith_media")])
9941 (define_insn_and_split "binary_sf_op"
9942   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9943         (vec_select:V2SF
9944          (vec_concat:V2SF
9945           (vec_select:SF
9946            (match_dup 0)
9947            (parallel [(match_operand 7 "const_int_operand" "n")]))
9948           (match_operator:SF 3 "binary_float_operator"
9949             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9950                             (parallel [(match_operand 5
9951                                         "const_int_operand" "n")]))
9952              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9953                             (parallel [(match_operand 6
9954                                         "const_int_operand" "n")]))]))
9955          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9956   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9957   "#"
9958   "&& reload_completed"
9959   [(set (match_dup 8) (match_dup 9))]
9960   "
9962   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9963   rtx op1 = gen_rtx_REG (SFmode,
9964                          (true_regnum (operands[1])
9965                           + (INTVAL (operands[5]) ^ endian)));
9966   rtx op2 = gen_rtx_REG (SFmode,
9967                          (true_regnum (operands[2])
9968                           + (INTVAL (operands[6]) ^ endian)));
9970   operands[8] = gen_rtx_REG (SFmode,
9971                              (true_regnum (operands[0])
9972                               + (INTVAL (operands[4]) ^ endian)));
9973   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9975   [(set_attr "type" "fparith_media")])
9977 (define_insn "addsf3_i"
9978   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9979         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9980                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9981    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9982   "TARGET_SH2E"
9983   "fadd %2,%0"
9984   [(set_attr "type" "fp")
9985    (set_attr "fp_mode" "single")])
9987 (define_expand "subsf3"
9988   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9989         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9990                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9991   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9992   "
9994   if (TARGET_SH2E)
9995     {
9996       expand_sf_binop (&gen_subsf3_i, operands);
9997       DONE;
9998     }
10001 (define_insn "*subsf3_media"
10002   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10003         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10004                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10005   "TARGET_SHMEDIA_FPU"
10006   "fsub.s       %1, %2, %0"
10007   [(set_attr "type" "fparith_media")])
10009 (define_insn "subsf3_i"
10010   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10011         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10012                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10013    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10014   "TARGET_SH2E"
10015   "fsub %2,%0"
10016   [(set_attr "type" "fp")
10017    (set_attr "fp_mode" "single")])
10019 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10020 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
10021 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
10022 ;; SH3E, we use a separate insn for SH3E mulsf3.
10024 (define_expand "mulsf3"
10025   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10026         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10027                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10028   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10029   "
10031   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10032     expand_sf_binop (&gen_mulsf3_i4, operands);
10033   else if (TARGET_SH2E)
10034     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10035   if (! TARGET_SHMEDIA)
10036     DONE;
10039 (define_insn "*mulsf3_media"
10040   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10041         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10042                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10043   "TARGET_SHMEDIA_FPU"
10044   "fmul.s       %1, %2, %0"
10045   [(set_attr "type" "fparith_media")])
10047 (define_insn "mulsf3_i4"
10048   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10049         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10050                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10051    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10052   "TARGET_SH2E"
10053   "fmul %2,%0"
10054   [(set_attr "type" "fp")
10055    (set_attr "fp_mode" "single")])
10057 (define_insn "mulsf3_ie"
10058   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10059         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10060                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10061   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10062   "fmul %2,%0"
10063   [(set_attr "type" "fp")])
10065 (define_insn "mac_media"
10066   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10067         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10068                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10069                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10070   "TARGET_SHMEDIA_FPU"
10071   "fmac.s %1, %2, %0"
10072   [(set_attr "type" "fparith_media")])
10074 (define_insn "*macsf3"
10075   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10076         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10077                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10078                  (match_operand:SF 3 "arith_reg_operand" "0")))
10079    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10080   "TARGET_SH2E && ! TARGET_SH4"
10081   "fmac fr0,%2,%0"
10082   [(set_attr "type" "fp")
10083    (set_attr "fp_mode" "single")])
10085 (define_expand "divsf3"
10086   [(set (match_operand:SF 0 "arith_reg_operand" "")
10087         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10088                 (match_operand:SF 2 "arith_reg_operand" "")))]
10089   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10090   "
10092   if (TARGET_SH2E)
10093     {
10094       expand_sf_binop (&gen_divsf3_i, operands);
10095       DONE;
10096     }
10099 (define_insn "*divsf3_media"
10100   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10101         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10102                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10103   "TARGET_SHMEDIA_FPU"
10104   "fdiv.s       %1, %2, %0"
10105   [(set_attr "type" "fdiv_media")])
10107 (define_insn "divsf3_i"
10108   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10109         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10110                  (match_operand:SF 2 "arith_reg_operand" "f")))
10111    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10112   "TARGET_SH2E"
10113   "fdiv %2,%0"
10114   [(set_attr "type" "fdiv")
10115    (set_attr "fp_mode" "single")])
10117 (define_insn "floatdisf2"
10118   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10119         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10120   "TARGET_SHMEDIA_FPU"
10121   "float.qs %1, %0"
10122   [(set_attr "type" "fpconv_media")])
10124 (define_expand "floatsisf2"
10125   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10126         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10127   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10128   "
10130   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10131     {
10132       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10133       DONE;
10134     }
10137 (define_insn "*floatsisf2_media"
10138   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10139         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10140   "TARGET_SHMEDIA_FPU"
10141   "float.ls     %1, %0"
10142   [(set_attr "type" "fpconv_media")])
10144 (define_insn "floatsisf2_i4"
10145   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10146         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10147    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10148   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10149   "float        %1,%0"
10150   [(set_attr "type" "fp")
10151    (set_attr "fp_mode" "single")])
10153 (define_insn "*floatsisf2_ie"
10154   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10155         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10156   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10157   "float        %1,%0"
10158   [(set_attr "type" "fp")])
10160 (define_insn "fix_truncsfdi2"
10161   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10162         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10163   "TARGET_SHMEDIA_FPU"
10164   "ftrc.sq %1, %0"
10165   [(set_attr "type" "fpconv_media")])
10167 (define_expand "fix_truncsfsi2"
10168   [(set (match_operand:SI 0 "fpul_operand" "=y")
10169         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10170   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10171   "
10173   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10174     {
10175       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10176       DONE;
10177     }
10180 (define_insn "*fix_truncsfsi2_media"
10181   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10182         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10183   "TARGET_SHMEDIA_FPU"
10184   "ftrc.sl      %1, %0"
10185   [(set_attr "type" "fpconv_media")])
10187 (define_insn "fix_truncsfsi2_i4"
10188   [(set (match_operand:SI 0 "fpul_operand" "=y")
10189         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10190    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10191   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10192   "ftrc %1,%0"
10193   [(set_attr "type" "ftrc_s")
10194    (set_attr "fp_mode" "single")])
10196 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10197 ;; fix_truncsfsi2_i4.
10198 ;; (define_insn "fix_truncsfsi2_i4_2"
10199 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10200 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10201 ;;   (use (reg:PSI FPSCR_REG))
10202 ;;   (clobber (reg:SI FPUL_REG))]
10203 ;;  "TARGET_SH4"
10204 ;;  "#"
10205 ;;  [(set_attr "length" "4")
10206 ;;   (set_attr "fp_mode" "single")])
10208 ;;(define_split
10209 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10210 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10211 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10212 ;;   (clobber (reg:SI FPUL_REG))]
10213 ;;  "TARGET_SH4"
10214 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10215 ;;            (use (match_dup 2))])
10216 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10218 (define_insn "*fixsfsi"
10219   [(set (match_operand:SI 0 "fpul_operand" "=y")
10220         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10221   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10222   "ftrc %1,%0"
10223   [(set_attr "type" "fp")])
10225 (define_insn "cmpgtsf_t"
10226   [(set (reg:SI T_REG)
10227         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10228                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10229   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10230   "fcmp/gt      %1,%0"
10231   [(set_attr "type" "fp")
10232    (set_attr "fp_mode" "single")])
10234 (define_insn "cmpeqsf_t"
10235   [(set (reg:SI T_REG)
10236         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10237                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10238   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10239   "fcmp/eq      %1,%0"
10240   [(set_attr "type" "fp")
10241    (set_attr "fp_mode" "single")])
10243 (define_insn "ieee_ccmpeqsf_t"
10244   [(set (reg:SI T_REG)
10245         (ior:SI (reg:SI T_REG)
10246                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10247                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10248   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10249   "* return output_ieee_ccmpeq (insn, operands);"
10250   [(set_attr "length" "4")])
10253 (define_insn "cmpgtsf_t_i4"
10254   [(set (reg:SI T_REG)
10255         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10256                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10257    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10258   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10259   "fcmp/gt      %1,%0"
10260   [(set_attr "type" "fp")
10261    (set_attr "fp_mode" "single")])
10263 (define_insn "cmpeqsf_t_i4"
10264   [(set (reg:SI T_REG)
10265         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10266                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10267    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10268   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10269   "fcmp/eq      %1,%0"
10270   [(set_attr "type" "fp")
10271    (set_attr "fp_mode" "single")])
10273 (define_insn "*ieee_ccmpeqsf_t_4"
10274   [(set (reg:SI T_REG)
10275         (ior:SI (reg:SI T_REG)
10276                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10277                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10278    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10279   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10280   "* return output_ieee_ccmpeq (insn, operands);"
10281   [(set_attr "length" "4")
10282    (set_attr "fp_mode" "single")])
10284 (define_insn "cmpeqsf_media"
10285   [(set (match_operand:DI 0 "register_operand" "=r")
10286         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10287                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10288   "TARGET_SHMEDIA_FPU"
10289   "fcmpeq.s     %1, %2, %0"
10290   [(set_attr "type" "fcmp_media")])
10292 (define_insn "cmpsieqsf_media"
10293   [(set (match_operand:SI 0 "register_operand" "=r")
10294         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10295                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10296   "TARGET_SHMEDIA_FPU"
10297   "fcmpeq.s     %1, %2, %0"
10298   [(set_attr "type" "fcmp_media")])
10300 (define_insn "cmpgtsf_media"
10301   [(set (match_operand:DI 0 "register_operand" "=r")
10302         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10303                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10304   "TARGET_SHMEDIA_FPU"
10305   "fcmpgt.s     %1, %2, %0"
10306   [(set_attr "type" "fcmp_media")])
10308 (define_insn "cmpgesf_media"
10309   [(set (match_operand:DI 0 "register_operand" "=r")
10310         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10311                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10312   "TARGET_SHMEDIA_FPU"
10313   "fcmpge.s     %1, %2, %0"
10314   [(set_attr "type" "fcmp_media")])
10316 (define_insn "cmpunsf_media"
10317   [(set (match_operand:DI 0 "register_operand" "=r")
10318         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10319                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10320   "TARGET_SHMEDIA_FPU"
10321   "fcmpun.s     %1, %2, %0"
10322   [(set_attr "type" "fcmp_media")])
10324 (define_expand "cmpsf"
10325   [(set (reg:SI T_REG)
10326         (compare (match_operand:SF 0 "arith_operand" "")
10327                  (match_operand:SF 1 "arith_operand" "")))]
10328   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10329   "
10331   sh_compare_op0 = operands[0];
10332   sh_compare_op1 = operands[1];
10333   DONE;
10336 (define_expand "negsf2"
10337   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10338         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10339   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10340   "
10342   if (TARGET_SH2E)
10343     {
10344       expand_sf_unop (&gen_negsf2_i, operands);
10345       DONE;
10346     }
10349 (define_insn "*negsf2_media"
10350   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10351         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10352   "TARGET_SHMEDIA_FPU"
10353   "fneg.s       %1, %0"
10354   [(set_attr "type" "fmove_media")])
10356 (define_insn "negsf2_i"
10357   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10358         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10359    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10360   "TARGET_SH2E"
10361   "fneg %0"
10362   [(set_attr "type" "fmove")
10363    (set_attr "fp_mode" "single")])
10365 (define_expand "sqrtsf2"
10366   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10367         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10368   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10369   "
10371   if (TARGET_SH3E)
10372     {
10373       expand_sf_unop (&gen_sqrtsf2_i, operands);
10374       DONE;
10375     }
10378 (define_insn "*sqrtsf2_media"
10379   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10380         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10381   "TARGET_SHMEDIA_FPU"
10382   "fsqrt.s      %1, %0"
10383   [(set_attr "type" "fdiv_media")])
10385 (define_insn "sqrtsf2_i"
10386   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10387         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10388    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10389   "TARGET_SH3E"
10390   "fsqrt        %0"
10391   [(set_attr "type" "fdiv")
10392    (set_attr "fp_mode" "single")])
10394 (define_insn "rsqrtsf2"
10395   [(set (match_operand:SF 0 "register_operand" "=f")
10396         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10397                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10398    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10399   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10400    && operands[1] == CONST1_RTX (SFmode)"
10401   "fsrra        %0"
10402   [(set_attr "type" "fsrra")
10403    (set_attr "fp_mode" "single")])
10405 (define_insn "fsca"
10406   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10407         (vec_concat:V2SF
10408          (unspec:SF [(mult:SF
10409                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10410                       (match_operand:SF 2 "immediate_operand" "i"))
10411                     ] UNSPEC_FSINA)
10412          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10413                     ] UNSPEC_FCOSA)))
10414    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10415   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10416    && operands[2] == sh_fsca_int2sf ()"
10417   "fsca fpul,%d0"
10418   [(set_attr "type" "fsca")
10419    (set_attr "fp_mode" "single")])
10421 (define_expand "sinsf2"
10422   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10423         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10424                    UNSPEC_FSINA))]
10425   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10426   "
10428   rtx scaled = gen_reg_rtx (SFmode);
10429   rtx truncated = gen_reg_rtx (SImode);
10430   rtx fsca = gen_reg_rtx (V2SFmode);
10431   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10433   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10434   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10435   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10436                           get_fpscr_rtx ()));
10437   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10438   DONE;
10441 (define_expand "cossf2"
10442   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10443         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10444                    UNSPEC_FCOSA))]
10445   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10446   "
10448   rtx scaled = gen_reg_rtx (SFmode);
10449   rtx truncated = gen_reg_rtx (SImode);
10450   rtx fsca = gen_reg_rtx (V2SFmode);
10451   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10453   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10454   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10455   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10456                           get_fpscr_rtx ()));
10457   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10458   DONE;
10461 (define_expand "sindf2"
10462   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10463         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10464                    UNSPEC_FSINA))]
10465   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10466   "
10468   rtx scaled = gen_reg_rtx (DFmode);
10469   rtx truncated = gen_reg_rtx (SImode);
10470   rtx fsca = gen_reg_rtx (V2SFmode);
10471   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10472   rtx sfresult = gen_reg_rtx (SFmode);
10474   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10475   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10476   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10477                           get_fpscr_rtx ()));
10478   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10479   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10480   DONE;
10483 (define_expand "cosdf2"
10484   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10485         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10486                    UNSPEC_FCOSA))]
10487   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10488   "
10490   rtx scaled = gen_reg_rtx (DFmode);
10491   rtx truncated = gen_reg_rtx (SImode);
10492   rtx fsca = gen_reg_rtx (V2SFmode);
10493   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10494   rtx sfresult = gen_reg_rtx (SFmode);
10496   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10497   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10498   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10499                           get_fpscr_rtx ()));
10500   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10501   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10502   DONE;
10505 (define_expand "abssf2"
10506   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10507         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10508   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10509   "
10511   if (TARGET_SH2E)
10512     {
10513       expand_sf_unop (&gen_abssf2_i, operands);
10514       DONE;
10515     }
10518 (define_insn "*abssf2_media"
10519   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10520         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10521   "TARGET_SHMEDIA_FPU"
10522   "fabs.s       %1, %0"
10523   [(set_attr "type" "fmove_media")])
10525 (define_insn "abssf2_i"
10526   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10527         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10528    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10529   "TARGET_SH2E"
10530   "fabs %0"
10531   [(set_attr "type" "fmove")
10532    (set_attr "fp_mode" "single")])
10534 (define_expand "adddf3"
10535   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10536         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10537                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10538   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10539   "
10541   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10542     {
10543       expand_df_binop (&gen_adddf3_i, operands);
10544       DONE;
10545     }
10548 (define_insn "*adddf3_media"
10549   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10550         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10551                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10552   "TARGET_SHMEDIA_FPU"
10553   "fadd.d       %1, %2, %0"
10554   [(set_attr "type" "dfparith_media")])
10556 (define_insn "adddf3_i"
10557   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10558         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10559                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10560    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10561   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10562   "fadd %2,%0"
10563   [(set_attr "type" "dfp_arith")
10564    (set_attr "fp_mode" "double")])
10566 (define_expand "subdf3"
10567   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10568         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10569                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10570   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10571   "
10573   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10574     {
10575       expand_df_binop (&gen_subdf3_i, operands);
10576       DONE;
10577     }
10580 (define_insn "*subdf3_media"
10581   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10582         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10583                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10584   "TARGET_SHMEDIA_FPU"
10585   "fsub.d       %1, %2, %0"
10586   [(set_attr "type" "dfparith_media")])
10588 (define_insn "subdf3_i"
10589   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10590         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10591                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10592    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10593   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10594   "fsub %2,%0"
10595   [(set_attr "type" "dfp_arith")
10596    (set_attr "fp_mode" "double")])
10598 (define_expand "muldf3"
10599   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10600         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10601                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10602   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10603   "
10605   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10606     {
10607       expand_df_binop (&gen_muldf3_i, operands);
10608       DONE;
10609     }
10612 (define_insn "*muldf3_media"
10613   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10614         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10615                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10616   "TARGET_SHMEDIA_FPU"
10617   "fmul.d       %1, %2, %0"
10618   [(set_attr "type" "dfmul_media")])
10620 (define_insn "muldf3_i"
10621   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10622         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10623                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10624    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10625   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10626   "fmul %2,%0"
10627   [(set_attr "type" "dfp_arith")
10628    (set_attr "fp_mode" "double")])
10630 (define_expand "divdf3"
10631   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10632         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10633                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10634   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10635   "
10637   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10638     {
10639       expand_df_binop (&gen_divdf3_i, operands);
10640       DONE;
10641     }
10644 (define_insn "*divdf3_media"
10645   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10646         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10647                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10648   "TARGET_SHMEDIA_FPU"
10649   "fdiv.d       %1, %2, %0"
10650   [(set_attr "type" "dfdiv_media")])
10652 (define_insn "divdf3_i"
10653   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10654         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10655                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10656    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10657   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10658   "fdiv %2,%0"
10659   [(set_attr "type" "dfdiv")
10660    (set_attr "fp_mode" "double")])
10662 (define_insn "floatdidf2"
10663   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10664         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10665   "TARGET_SHMEDIA_FPU"
10666   "float.qd     %1, %0"
10667   [(set_attr "type" "dfpconv_media")])
10669 (define_expand "floatsidf2"
10670   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10671         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10672   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10673   "
10675   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10676     {
10677       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10678                                       get_fpscr_rtx ()));
10679       DONE;
10680     }
10683 (define_insn "*floatsidf2_media"
10684   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10685         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10686   "TARGET_SHMEDIA_FPU"
10687   "float.ld     %1, %0"
10688   [(set_attr "type" "dfpconv_media")])
10690 (define_insn "floatsidf2_i"
10691   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10692         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10693    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10694   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10695   "float        %1,%0"
10696   [(set_attr "type" "dfp_conv")
10697    (set_attr "fp_mode" "double")])
10699 (define_insn "fix_truncdfdi2"
10700   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10701         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10702   "TARGET_SHMEDIA_FPU"
10703   "ftrc.dq      %1, %0"
10704   [(set_attr "type" "dfpconv_media")])
10706 (define_expand "fix_truncdfsi2"
10707   [(set (match_operand:SI 0 "fpul_operand" "")
10708         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10709   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10710   "
10712   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10713     {
10714       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10715                                           get_fpscr_rtx ()));
10716       DONE;
10717     }
10720 (define_insn "*fix_truncdfsi2_media"
10721   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10722         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10723   "TARGET_SHMEDIA_FPU"
10724   "ftrc.dl      %1, %0"
10725   [(set_attr "type" "dfpconv_media")])
10727 (define_insn "fix_truncdfsi2_i"
10728   [(set (match_operand:SI 0 "fpul_operand" "=y")
10729         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10730    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10731   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10732   "ftrc %1,%0"
10733   [(set_attr "type" "dfp_conv")
10734    (set_attr "dfp_comp" "no")
10735    (set_attr "fp_mode" "double")])
10737 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10738 ;; fix_truncdfsi2_i.
10739 ;; (define_insn "fix_truncdfsi2_i4"
10740 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10741 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10742 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10743 ;;    (clobber (reg:SI FPUL_REG))]
10744 ;;   "TARGET_SH4"
10745 ;;   "#"
10746 ;;   [(set_attr "length" "4")
10747 ;;    (set_attr "fp_mode" "double")])
10749 ;; (define_split
10750 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10751 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10752 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10753 ;;    (clobber (reg:SI FPUL_REG))]
10754 ;;   "TARGET_SH4"
10755 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10756 ;;            (use (match_dup 2))])
10757 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10759 (define_insn "cmpgtdf_t"
10760   [(set (reg:SI T_REG)
10761         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10762                (match_operand:DF 1 "arith_reg_operand" "f")))
10763    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10764   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10765   "fcmp/gt      %1,%0"
10766   [(set_attr "type" "dfp_cmp")
10767    (set_attr "fp_mode" "double")])
10769 (define_insn "cmpeqdf_t"
10770   [(set (reg:SI T_REG)
10771         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10772                (match_operand:DF 1 "arith_reg_operand" "f")))
10773    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10774   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10775   "fcmp/eq      %1,%0"
10776   [(set_attr "type" "dfp_cmp")
10777    (set_attr "fp_mode" "double")])
10779 (define_insn "*ieee_ccmpeqdf_t"
10780   [(set (reg:SI T_REG)
10781         (ior:SI (reg:SI T_REG)
10782                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10783                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10784    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10785   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10786   "* return output_ieee_ccmpeq (insn, operands);"
10787   [(set_attr "length" "4")
10788    (set_attr "fp_mode" "double")])
10790 (define_insn "cmpeqdf_media"
10791   [(set (match_operand:DI 0 "register_operand" "=r")
10792         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10793                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10794   "TARGET_SHMEDIA_FPU"
10795   "fcmpeq.d     %1,%2,%0"
10796   [(set_attr "type" "fcmp_media")])
10798 (define_insn "cmpsieqdf_media"
10799   [(set (match_operand:SI 0 "register_operand" "=r")
10800         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10801                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10802   "TARGET_SHMEDIA_FPU"
10803   "fcmpeq.d     %1,%2,%0"
10804   [(set_attr "type" "fcmp_media")])
10806 (define_insn "cmpgtdf_media"
10807   [(set (match_operand:DI 0 "register_operand" "=r")
10808         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10809                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10810   "TARGET_SHMEDIA_FPU"
10811   "fcmpgt.d     %1,%2,%0"
10812   [(set_attr "type" "fcmp_media")])
10814 (define_insn "cmpgedf_media"
10815   [(set (match_operand:DI 0 "register_operand" "=r")
10816         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10817                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10818   "TARGET_SHMEDIA_FPU"
10819   "fcmpge.d     %1,%2,%0"
10820   [(set_attr "type" "fcmp_media")])
10822 (define_insn "cmpundf_media"
10823   [(set (match_operand:DI 0 "register_operand" "=r")
10824         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10825                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10826   "TARGET_SHMEDIA_FPU"
10827   "fcmpun.d     %1,%2,%0"
10828   [(set_attr "type" "fcmp_media")])
10830 (define_expand "cmpdf"
10831   [(set (reg:SI T_REG)
10832         (compare (match_operand:DF 0 "arith_operand" "")
10833                  (match_operand:DF 1 "arith_operand" "")))]
10834   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10835   "
10837   sh_compare_op0 = operands[0];
10838   sh_compare_op1 = operands[1];
10839   DONE;
10842 (define_expand "negdf2"
10843   [(set (match_operand:DF 0 "arith_reg_operand" "")
10844         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10845   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10846   "
10848   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10849     {
10850       expand_df_unop (&gen_negdf2_i, operands);
10851       DONE;
10852     }
10855 (define_insn "*negdf2_media"
10856   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10857         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10858   "TARGET_SHMEDIA_FPU"
10859   "fneg.d       %1, %0"
10860   [(set_attr "type" "fmove_media")])
10862 (define_insn "negdf2_i"
10863   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10864         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10865    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10866   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10867   "fneg %0"
10868   [(set_attr "type" "fmove")
10869    (set_attr "fp_mode" "double")])
10871 (define_expand "sqrtdf2"
10872   [(set (match_operand:DF 0 "arith_reg_operand" "")
10873         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10874   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10875   "
10877   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10878     {
10879       expand_df_unop (&gen_sqrtdf2_i, operands);
10880       DONE;
10881     }
10884 (define_insn "*sqrtdf2_media"
10885   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10886         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10887   "TARGET_SHMEDIA_FPU"
10888   "fsqrt.d      %1, %0"
10889   [(set_attr "type" "dfdiv_media")])
10891 (define_insn "sqrtdf2_i"
10892   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10893         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10894    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10895   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10896   "fsqrt        %0"
10897   [(set_attr "type" "dfdiv")
10898    (set_attr "fp_mode" "double")])
10900 (define_expand "absdf2"
10901   [(set (match_operand:DF 0 "arith_reg_operand" "")
10902         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10903   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10904   "
10906   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10907     {
10908       expand_df_unop (&gen_absdf2_i, operands);
10909       DONE;
10910     }
10913 (define_insn "*absdf2_media"
10914   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10915         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10916   "TARGET_SHMEDIA_FPU"
10917   "fabs.d       %1, %0"
10918   [(set_attr "type" "fmove_media")])
10920 (define_insn "absdf2_i"
10921   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10922         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10923    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10924   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10925   "fabs %0"
10926   [(set_attr "type" "fmove")
10927    (set_attr "fp_mode" "double")])
10929 (define_expand "extendsfdf2"
10930   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10931         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10932   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10933   "
10935   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10936     {
10937       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10938                                         get_fpscr_rtx ()));
10939       DONE;
10940     }
10943 (define_insn "*extendsfdf2_media"
10944   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10945         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10946   "TARGET_SHMEDIA_FPU"
10947   "fcnv.sd      %1, %0"
10948   [(set_attr "type" "dfpconv_media")])
10950 (define_insn "extendsfdf2_i4"
10951   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10952         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10953    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10954   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10955   "fcnvsd  %1,%0"
10956   [(set_attr "type" "fp")
10957    (set_attr "fp_mode" "double")])
10959 (define_expand "truncdfsf2"
10960   [(set (match_operand:SF 0 "fpul_operand" "")
10961         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10962   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10963   "
10965   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10966     {
10967       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10968                                        get_fpscr_rtx ()));
10969       DONE;
10970     }
10973 (define_insn "*truncdfsf2_media"
10974   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10975         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10976   "TARGET_SHMEDIA_FPU"
10977   "fcnv.ds      %1, %0"
10978   [(set_attr "type" "dfpconv_media")])
10980 (define_insn "truncdfsf2_i4"
10981   [(set (match_operand:SF 0 "fpul_operand" "=y")
10982         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10983    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10984   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10985   "fcnvds  %1,%0"
10986   [(set_attr "type" "fp")
10987    (set_attr "fp_mode" "double")])
10989 ;; Bit field extract patterns.  These give better code for packed bitfields,
10990 ;; because they allow auto-increment addresses to be generated.
10992 (define_expand "insv"
10993   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10994                          (match_operand:SI 1 "immediate_operand" "")
10995                          (match_operand:SI 2 "immediate_operand" ""))
10996         (match_operand:SI 3 "general_operand" ""))]
10997   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10998   "
11000   rtx addr_target, orig_address, shift_reg, qi_val;
11001   HOST_WIDE_INT bitsize, size, v = 0;
11002   rtx x = operands[3];
11004   /* ??? expmed doesn't care for non-register predicates.  */
11005   if (! memory_operand (operands[0], VOIDmode)
11006       || ! immediate_operand (operands[1], VOIDmode)
11007       || ! immediate_operand (operands[2], VOIDmode)
11008       || ! general_operand (x, VOIDmode))
11009     FAIL;
11010   /* If this isn't a 16 / 24 / 32 bit field, or if
11011      it doesn't start on a byte boundary, then fail.  */
11012   bitsize = INTVAL (operands[1]);
11013   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11014       || (INTVAL (operands[2]) % 8) != 0)
11015     FAIL;
11017   size = bitsize / 8;
11018   orig_address = XEXP (operands[0], 0);
11019   shift_reg = gen_reg_rtx (SImode);
11020   if (GET_CODE (x) == CONST_INT)
11021     {
11022       v = INTVAL (x);
11023       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11024     }
11025   else
11026     {
11027       emit_insn (gen_movsi (shift_reg, operands[3]));
11028       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11029     }
11030   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11032   operands[0] = replace_equiv_address (operands[0], addr_target);
11033   emit_insn (gen_movqi (operands[0], qi_val));
11035   while (size -= 1)
11036     {
11037       if (GET_CODE (x) == CONST_INT)
11038         qi_val
11039           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11040       else
11041         {
11042           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11043           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11044         }
11045       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11046       emit_insn (gen_movqi (operands[0], qi_val));
11047     }
11049   DONE;
11052 (define_insn "movua"
11053   [(set (match_operand:SI 0 "register_operand" "=z")
11054         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11055                          (const_int 32) (const_int 0)))]
11056   "TARGET_SH4A_ARCH"
11057   "movua.l      %1,%0"
11058   [(set_attr "type" "movua")])
11060 ;; We shouldn't need this, but cse replaces increments with references
11061 ;; to other regs before flow has a chance to create post_inc
11062 ;; addressing modes, and only postreload's cse_move2add brings the
11063 ;; increments back to a usable form.
11064 (define_peephole2
11065   [(set (match_operand:SI 0 "register_operand" "")
11066         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11067                          (const_int 32) (const_int 0)))
11068    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11069   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11070   [(set (match_operand:SI 0 "register_operand" "")
11071         (sign_extract:SI (mem:SI (post_inc:SI
11072                                   (match_operand:SI 1 "register_operand" "")))
11073                          (const_int 32) (const_int 0)))]
11074   "")
11076 (define_expand "extv"
11077   [(set (match_operand:SI 0 "register_operand" "")
11078         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11079                          (match_operand 2 "const_int_operand" "")
11080                          (match_operand 3 "const_int_operand" "")))]
11081   "TARGET_SH4A_ARCH"
11083   if (TARGET_SH4A_ARCH
11084       && INTVAL (operands[2]) == 32
11085       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11086       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11087     {
11088       emit_insn (gen_movua (operands[0],
11089                             adjust_address (operands[1], SImode, 0)));
11090       DONE;
11091     }
11093   FAIL;
11096 (define_expand "extzv"
11097   [(set (match_operand:SI 0 "register_operand" "")
11098         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11099                          (match_operand 2 "const_int_operand" "")
11100                          (match_operand 3 "const_int_operand" "")))]
11101   "TARGET_SH4A_ARCH"
11103   if (TARGET_SH4A_ARCH
11104       && INTVAL (operands[2]) == 32
11105       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11106       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11107     {
11108       emit_insn (gen_movua (operands[0],
11109                             adjust_address (operands[1], SImode, 0)));
11110       DONE;
11111     }
11113   FAIL;
11117 ;; -------------------------------------------------------------------------
11118 ;; Peepholes
11119 ;; -------------------------------------------------------------------------
11121 ;; This matches cases where a stack pointer increment at the start of the
11122 ;; epilogue combines with a stack slot read loading the return value.
11124 (define_peephole
11125   [(set (match_operand:SI 0 "arith_reg_operand" "")
11126         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11127    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11128   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11129   "mov.l        @%1+,%0")
11131 ;; See the comment on the dt combiner pattern above.
11133 (define_peephole
11134   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11135         (plus:SI (match_dup 0)
11136                  (const_int -1)))
11137    (set (reg:SI T_REG)
11138         (eq:SI (match_dup 0)
11139                (const_int 0)))]
11140   "TARGET_SH2"
11141   "dt   %0")
11143 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11144 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11145 ;; reload when the constant is too large for a reg+offset address.
11147 ;; ??? We would get much better code if this was done in reload.  This would
11148 ;; require modifying find_reloads_address to recognize that if the constant
11149 ;; is out-of-range for an immediate add, then we get better code by reloading
11150 ;; the constant into a register than by reloading the sum into a register,
11151 ;; since the former is one instruction shorter if the address does not need
11152 ;; to be offsettable.  Unfortunately this does not work, because there is
11153 ;; only one register, r0, that can be used as an index register.  This register
11154 ;; is also the function return value register.  So, if we try to force reload
11155 ;; to use double-reg addresses, then we end up with some instructions that
11156 ;; need to use r0 twice.  The only way to fix this is to change the calling
11157 ;; convention so that r0 is not used to return values.
11159 (define_peephole
11160   [(set (match_operand:SI 0 "register_operand" "=r")
11161         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11162    (set (mem:SI (match_dup 0))
11163         (match_operand:SI 2 "general_movsrc_operand" ""))]
11164   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11165   "mov.l        %2,@(%0,%1)")
11167 (define_peephole
11168   [(set (match_operand:SI 0 "register_operand" "=r")
11169         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11170    (set (match_operand:SI 2 "general_movdst_operand" "")
11171         (mem:SI (match_dup 0)))]
11172   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11173   "mov.l        @(%0,%1),%2")
11175 (define_peephole
11176   [(set (match_operand:SI 0 "register_operand" "=r")
11177         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11178    (set (mem:HI (match_dup 0))
11179         (match_operand:HI 2 "general_movsrc_operand" ""))]
11180   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11181   "mov.w        %2,@(%0,%1)")
11183 (define_peephole
11184   [(set (match_operand:SI 0 "register_operand" "=r")
11185         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11186    (set (match_operand:HI 2 "general_movdst_operand" "")
11187         (mem:HI (match_dup 0)))]
11188   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11189   "mov.w        @(%0,%1),%2")
11191 (define_peephole
11192   [(set (match_operand:SI 0 "register_operand" "=r")
11193         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11194    (set (mem:QI (match_dup 0))
11195         (match_operand:QI 2 "general_movsrc_operand" ""))]
11196   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11197   "mov.b        %2,@(%0,%1)")
11199 (define_peephole
11200   [(set (match_operand:SI 0 "register_operand" "=r")
11201         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11202    (set (match_operand:QI 2 "general_movdst_operand" "")
11203         (mem:QI (match_dup 0)))]
11204   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11205   "mov.b        @(%0,%1),%2")
11207 (define_peephole
11208   [(set (match_operand:SI 0 "register_operand" "=r")
11209         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11210    (set (mem:SF (match_dup 0))
11211         (match_operand:SF 2 "general_movsrc_operand" ""))]
11212   "TARGET_SH1 && REGNO (operands[0]) == 0
11213    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11214        || (GET_CODE (operands[2]) == SUBREG
11215            && REGNO (SUBREG_REG (operands[2])) < 16))
11216    && reg_unused_after (operands[0], insn)"
11217   "mov.l        %2,@(%0,%1)")
11219 (define_peephole
11220   [(set (match_operand:SI 0 "register_operand" "=r")
11221         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11222    (set (match_operand:SF 2 "general_movdst_operand" "")
11224         (mem:SF (match_dup 0)))]
11225   "TARGET_SH1 && REGNO (operands[0]) == 0
11226    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11227        || (GET_CODE (operands[2]) == SUBREG
11228            && REGNO (SUBREG_REG (operands[2])) < 16))
11229    && reg_unused_after (operands[0], insn)"
11230   "mov.l        @(%0,%1),%2")
11232 (define_peephole
11233   [(set (match_operand:SI 0 "register_operand" "=r")
11234         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11235    (set (mem:SF (match_dup 0))
11236         (match_operand:SF 2 "general_movsrc_operand" ""))]
11237   "TARGET_SH2E && REGNO (operands[0]) == 0
11238    && ((GET_CODE (operands[2]) == REG
11239         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11240        || (GET_CODE (operands[2]) == SUBREG
11241            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11242    && reg_unused_after (operands[0], insn)"
11243   "fmov{.s|}    %2,@(%0,%1)")
11245 (define_peephole
11246   [(set (match_operand:SI 0 "register_operand" "=r")
11247         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11248    (set (match_operand:SF 2 "general_movdst_operand" "")
11250         (mem:SF (match_dup 0)))]
11251   "TARGET_SH2E && REGNO (operands[0]) == 0
11252    && ((GET_CODE (operands[2]) == REG
11253         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11254        || (GET_CODE (operands[2]) == SUBREG
11255            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11256    && reg_unused_after (operands[0], insn)"
11257   "fmov{.s|}    @(%0,%1),%2")
11259 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11260 (define_insn "sp_switch_1"
11261   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11262   "TARGET_SH1"
11263   "*
11265   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11266   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11267   return \"mov r0,r15\";
11269   [(set_attr "length" "10")])
11271 ;; Switch back to the original stack for interrupt functions with the
11272 ;; sp_switch attribute.  */
11273 (define_insn "sp_switch_2"
11274   [(const_int 2)]
11275   "TARGET_SH1"
11276   "mov.l @r15+,r15\;mov.l @r15+,r0"
11277   [(set_attr "length" "4")])
11279 ;; Integer vector moves
11281 (define_expand "movv8qi"
11282   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11283         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11284   "TARGET_SHMEDIA"
11285   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11287 (define_insn "movv8qi_i"
11288   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11289         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11290   "TARGET_SHMEDIA
11291    && (register_operand (operands[0], V8QImode)
11292        || sh_register_operand (operands[1], V8QImode))"
11293   "@
11294         add     %1, r63, %0
11295         movi    %1, %0
11296         #
11297         ld%M1.q %m1, %0
11298         st%M0.q %m0, %N1"
11299   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11300    (set_attr "length" "4,4,16,4,4")])
11302 (define_split
11303   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11304         (subreg:V8QI (const_int 0) 0))]
11305   "TARGET_SHMEDIA"
11306   [(set (match_dup 0)
11307         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11308                             (const_int 0) (const_int 0) (const_int 0)
11309                             (const_int 0) (const_int 0)]))])
11311 (define_split
11312   [(set (match_operand 0 "arith_reg_dest" "")
11313         (match_operand 1 "sh_rep_vec" ""))]
11314   "TARGET_SHMEDIA && reload_completed
11315    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11316    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11317    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11318    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11319        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11320    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11321        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11322   [(set (match_dup 0) (match_dup 1))
11323    (match_dup 2)]
11324   "
11326   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11327   rtx elt1 = XVECEXP (operands[1], 0, 1);
11329   if (unit_size > 2)
11330     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11331   else
11332     {
11333       if (unit_size < 2)
11334         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11335       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11336     }
11337   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11338   operands[1] = XVECEXP (operands[1], 0, 0);
11339   if (unit_size < 2)
11340     {
11341       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11342         operands[1]
11343           = GEN_INT (TARGET_LITTLE_ENDIAN
11344                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11345                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11346       else
11347         {
11348           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11349           operands[1]
11350             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11351         }
11352     }
11355 (define_split
11356   [(set (match_operand 0 "arith_reg_dest" "")
11357         (match_operand 1 "sh_const_vec" ""))]
11358   "TARGET_SHMEDIA && reload_completed
11359    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11360    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11361   [(set (match_dup 0) (match_dup 1))]
11362   "
11364   rtx v = operands[1];
11365   enum machine_mode new_mode
11366     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11368   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11369   operands[1]
11370     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11373 (define_expand "movv2hi"
11374   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11375         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11376   "TARGET_SHMEDIA"
11377   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11379 (define_insn "movv2hi_i"
11380   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11381         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11382   "TARGET_SHMEDIA
11383    && (register_operand (operands[0], V2HImode)
11384        || sh_register_operand (operands[1], V2HImode))"
11385   "@
11386         add.l   %1, r63, %0
11387         movi    %1, %0
11388         #
11389         ld%M1.l %m1, %0
11390         st%M0.l %m0, %N1"
11391   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11392    (set_attr "length" "4,4,16,4,4")
11393    (set (attr "highpart")
11394         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11395                (const_string "user")]
11396               (const_string "ignore")))])
11398 (define_expand "movv4hi"
11399   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11400         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11401   "TARGET_SHMEDIA"
11402   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11404 (define_insn "movv4hi_i"
11405   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11406         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11407   "TARGET_SHMEDIA
11408    && (register_operand (operands[0], V4HImode)
11409        || sh_register_operand (operands[1], V4HImode))"
11410   "@
11411         add     %1, r63, %0
11412         movi    %1, %0
11413         #
11414         ld%M1.q %m1, %0
11415         st%M0.q %m0, %N1"
11416   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11417    (set_attr "length" "4,4,16,4,4")
11418    (set_attr "highpart" "depend")])
11420 (define_expand "movv2si"
11421   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11422         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11423   "TARGET_SHMEDIA"
11424   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11426 (define_insn "movv2si_i"
11427   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11428         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11429   "TARGET_SHMEDIA
11430    && (register_operand (operands[0], V2SImode)
11431        || sh_register_operand (operands[1], V2SImode))"
11432   "@
11433         add     %1, r63, %0
11434         #
11435         #
11436         ld%M1.q %m1, %0
11437         st%M0.q %m0, %N1"
11438   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11439    (set_attr "length" "4,4,16,4,4")
11440    (set_attr "highpart" "depend")])
11442 ;; Multimedia Intrinsics
11444 (define_insn "absv2si2"
11445   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11446         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11447   "TARGET_SHMEDIA"
11448   "mabs.l       %1, %0"
11449   [(set_attr "type" "mcmp_media")
11450    (set_attr "highpart" "depend")])
11452 (define_insn "absv4hi2"
11453   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11454         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11455   "TARGET_SHMEDIA"
11456   "mabs.w       %1, %0"
11457   [(set_attr "type" "mcmp_media")
11458    (set_attr "highpart" "depend")])
11460 (define_insn "addv2si3"
11461   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11462         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11463                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11464   "TARGET_SHMEDIA"
11465   "madd.l       %1, %2, %0"
11466   [(set_attr "type" "arith_media")
11467    (set_attr "highpart" "depend")])
11469 (define_insn "addv4hi3"
11470   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11471         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11472                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11473   "TARGET_SHMEDIA"
11474   "madd.w       %1, %2, %0"
11475   [(set_attr "type" "arith_media")
11476    (set_attr "highpart" "depend")])
11478 (define_insn_and_split "addv2hi3"
11479   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11480         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11481                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11482   "TARGET_SHMEDIA"
11483   "#"
11484   "TARGET_SHMEDIA"
11485   [(const_int 0)]
11486   "
11488   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11489   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11490   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11491   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11492   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11494   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11495   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11496   DONE;
11498   [(set_attr "highpart" "must_split")])
11500 (define_insn "ssaddv2si3"
11501   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11502         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11503                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11504   "TARGET_SHMEDIA"
11505   "madds.l      %1, %2, %0"
11506   [(set_attr "type" "mcmp_media")
11507    (set_attr "highpart" "depend")])
11509 (define_insn "usaddv8qi3"
11510   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11511         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11512                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11513   "TARGET_SHMEDIA"
11514   "madds.ub     %1, %2, %0"
11515   [(set_attr "type" "mcmp_media")
11516    (set_attr "highpart" "depend")])
11518 (define_insn "ssaddv4hi3"
11519   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11520         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11521                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11522   "TARGET_SHMEDIA"
11523   "madds.w      %1, %2, %0"
11524   [(set_attr "type" "mcmp_media")
11525    (set_attr "highpart" "depend")])
11527 (define_insn "negcmpeqv8qi"
11528   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11529         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11530                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11531   "TARGET_SHMEDIA"
11532   "mcmpeq.b     %N1, %N2, %0"
11533   [(set_attr "type" "mcmp_media")
11534    (set_attr "highpart" "depend")])
11536 (define_insn "negcmpeqv2si"
11537   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11538         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11539                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11540   "TARGET_SHMEDIA"
11541   "mcmpeq.l     %N1, %N2, %0"
11542   [(set_attr "type" "mcmp_media")
11543    (set_attr "highpart" "depend")])
11545 (define_insn "negcmpeqv4hi"
11546   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11547         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11548                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11549   "TARGET_SHMEDIA"
11550   "mcmpeq.w     %N1, %N2, %0"
11551   [(set_attr "type" "mcmp_media")
11552    (set_attr "highpart" "depend")])
11554 (define_insn "negcmpgtuv8qi"
11555   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11556         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11557                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11558   "TARGET_SHMEDIA"
11559   "mcmpgt.ub    %N1, %N2, %0"
11560   [(set_attr "type" "mcmp_media")
11561    (set_attr "highpart" "depend")])
11563 (define_insn "negcmpgtv2si"
11564   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11565         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11566                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11567   "TARGET_SHMEDIA"
11568   "mcmpgt.l     %N1, %N2, %0"
11569   [(set_attr "type" "mcmp_media")
11570    (set_attr "highpart" "depend")])
11572 (define_insn "negcmpgtv4hi"
11573   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11574         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11575                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11576   "TARGET_SHMEDIA"
11577   "mcmpgt.w     %N1, %N2, %0"
11578   [(set_attr "type" "mcmp_media")
11579    (set_attr "highpart" "depend")])
11581 (define_insn "mcmv"
11582   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11583         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11584                         (match_operand:DI 2 "arith_reg_operand" "r"))
11585                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11586                         (not:DI (match_dup 2)))))]
11587   "TARGET_SHMEDIA"
11588   "mcmv %N1, %2, %0"
11589   [(set_attr "type" "arith_media")
11590    (set_attr "highpart" "depend")])
11592 (define_insn "mcnvs_lw"
11593   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11594         (vec_concat:V4HI
11595          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11596          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11597   "TARGET_SHMEDIA"
11598   "mcnvs.lw     %N1, %N2, %0"
11599   [(set_attr "type" "mcmp_media")])
11601 (define_insn "mcnvs_wb"
11602   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11603         (vec_concat:V8QI
11604          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11605          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11606   "TARGET_SHMEDIA"
11607   "mcnvs.wb     %N1, %N2, %0"
11608   [(set_attr "type" "mcmp_media")])
11610 (define_insn "mcnvs_wub"
11611   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11612         (vec_concat:V8QI
11613          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11614          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11615   "TARGET_SHMEDIA"
11616   "mcnvs.wub    %N1, %N2, %0"
11617   [(set_attr "type" "mcmp_media")])
11619 (define_insn "mextr_rl"
11620   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11621         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11622                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11623                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11624                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11625   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11626   "*
11628   static char templ[21];
11630   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11631            (int) INTVAL (operands[3]) >> 3);
11632   return templ;
11634   [(set_attr "type" "arith_media")])
11636 (define_insn "*mextr_lr"
11637   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11638         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11639                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11640                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11641                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11642   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11643   "*
11645   static char templ[21];
11647   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11648            (int) INTVAL (operands[4]) >> 3);
11649   return templ;
11651   [(set_attr "type" "arith_media")])
11653 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11654 ; vector then varies depending on endianness.
11655 (define_expand "mextr1"
11656   [(match_operand:DI 0 "arith_reg_dest" "")
11657    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11658    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11659   "TARGET_SHMEDIA"
11660   "
11662   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11663                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11664   DONE;
11667 (define_expand "mextr2"
11668   [(match_operand:DI 0 "arith_reg_dest" "")
11669    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11670    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11671   "TARGET_SHMEDIA"
11672   "
11674   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11675                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11676   DONE;
11679 (define_expand "mextr3"
11680   [(match_operand:DI 0 "arith_reg_dest" "")
11681    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11682    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11683   "TARGET_SHMEDIA"
11684   "
11686   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11687                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11688   DONE;
11691 (define_expand "mextr4"
11692   [(match_operand:DI 0 "arith_reg_dest" "")
11693    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11694    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11695   "TARGET_SHMEDIA"
11696   "
11698   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11699                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11700   DONE;
11703 (define_expand "mextr5"
11704   [(match_operand:DI 0 "arith_reg_dest" "")
11705    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11706    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11707   "TARGET_SHMEDIA"
11708   "
11710   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11711                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11712   DONE;
11715 (define_expand "mextr6"
11716   [(match_operand:DI 0 "arith_reg_dest" "")
11717    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11718    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11719   "TARGET_SHMEDIA"
11720   "
11722   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11723                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11724   DONE;
11727 (define_expand "mextr7"
11728   [(match_operand:DI 0 "arith_reg_dest" "")
11729    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11730    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11731   "TARGET_SHMEDIA"
11732   "
11734   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11735                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11736   DONE;
11739 (define_expand "mmacfx_wl"
11740   [(match_operand:V2SI 0 "arith_reg_dest" "")
11741    (match_operand:V2HI 1 "extend_reg_operand" "")
11742    (match_operand:V2HI 2 "extend_reg_operand" "")
11743    (match_operand:V2SI 3 "arith_reg_operand" "")]
11744   "TARGET_SHMEDIA"
11745   "
11747   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11748                               operands[1], operands[2]));
11749   DONE;
11752 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11753 ;; is depend
11754 (define_insn "mmacfx_wl_i"
11755   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11756         (ss_plus:V2SI
11757          (match_operand:V2SI 1 "arith_reg_operand" "0")
11758          (ss_truncate:V2SI
11759           (ashift:V2DI
11760            (sign_extend:V2DI
11761             (mult:V2SI
11762              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11763              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11764            (const_int 1)))))]
11765   "TARGET_SHMEDIA"
11766   "mmacfx.wl    %2, %3, %0"
11767   [(set_attr "type" "mac_media")
11768    (set_attr "highpart" "depend")])
11770 (define_expand "mmacnfx_wl"
11771   [(match_operand:V2SI 0 "arith_reg_dest" "")
11772    (match_operand:V2HI 1 "extend_reg_operand" "")
11773    (match_operand:V2HI 2 "extend_reg_operand" "")
11774    (match_operand:V2SI 3 "arith_reg_operand" "")]
11775   "TARGET_SHMEDIA"
11776   "
11778   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11779                                operands[1], operands[2]));
11780   DONE;
11783 (define_insn "mmacnfx_wl_i"
11784   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11785         (ss_minus:V2SI
11786          (match_operand:V2SI 1 "arith_reg_operand" "0")
11787          (ss_truncate:V2SI
11788           (ashift:V2DI
11789            (sign_extend:V2DI
11790             (mult:V2SI
11791              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11792              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11793            (const_int 1)))))]
11794   "TARGET_SHMEDIA"
11795   "mmacnfx.wl   %2, %3, %0"
11796   [(set_attr "type" "mac_media")
11797    (set_attr "highpart" "depend")])
11799 (define_insn "mulv2si3"
11800   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11801         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11802                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11803   "TARGET_SHMEDIA"
11804   "mmul.l       %1, %2, %0"
11805   [(set_attr "type" "d2mpy_media")
11806    (set_attr "highpart" "depend")])
11808 (define_insn "mulv4hi3"
11809   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11810         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11811                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11812   "TARGET_SHMEDIA"
11813   "mmul.w       %1, %2, %0"
11814   [(set_attr "type" "dmpy_media")
11815    (set_attr "highpart" "depend")])
11817 (define_insn "mmulfx_l"
11818   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11819         (ss_truncate:V2SI
11820          (ashiftrt:V2DI
11821           (mult:V2DI
11822            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11823            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11824           (const_int 31))))]
11825   "TARGET_SHMEDIA"
11826   "mmulfx.l     %1, %2, %0"
11827   [(set_attr "type" "d2mpy_media")
11828    (set_attr "highpart" "depend")])
11830 (define_insn "mmulfx_w"
11831   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11832         (ss_truncate:V4HI
11833          (ashiftrt:V4SI
11834           (mult:V4SI
11835            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11836            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11837           (const_int 15))))]
11838   "TARGET_SHMEDIA"
11839   "mmulfx.w     %1, %2, %0"
11840   [(set_attr "type" "dmpy_media")
11841    (set_attr "highpart" "depend")])
11843 (define_insn "mmulfxrp_w"
11844   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11845         (ss_truncate:V4HI
11846          (ashiftrt:V4SI
11847           (plus:V4SI
11848            (mult:V4SI
11849             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11850             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11851            (const_int 16384))
11852           (const_int 15))))]
11853   "TARGET_SHMEDIA"
11854   "mmulfxrp.w   %1, %2, %0"
11855   [(set_attr "type" "dmpy_media")
11856    (set_attr "highpart" "depend")])
11859 (define_expand "mmulhi_wl"
11860   [(match_operand:V2SI 0 "arith_reg_dest" "")
11861    (match_operand:V4HI 1 "arith_reg_operand" "")
11862    (match_operand:V4HI 2 "arith_reg_operand" "")]
11863   "TARGET_SHMEDIA"
11864   "
11866   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11867              (operands[0], operands[1], operands[2]));
11868   DONE;
11871 (define_expand "mmullo_wl"
11872   [(match_operand:V2SI 0 "arith_reg_dest" "")
11873    (match_operand:V4HI 1 "arith_reg_operand" "")
11874    (match_operand:V4HI 2 "arith_reg_operand" "")]
11875   "TARGET_SHMEDIA"
11876   "
11878   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11879              (operands[0], operands[1], operands[2]));
11880   DONE;
11883 (define_insn "mmul23_wl"
11884   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11885         (vec_select:V2SI
11886          (mult:V4SI
11887           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11888           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11889          (parallel [(const_int 2) (const_int 3)])))]
11890   "TARGET_SHMEDIA"
11891   "* return (TARGET_LITTLE_ENDIAN
11892              ? \"mmulhi.wl      %1, %2, %0\"
11893              : \"mmullo.wl      %1, %2, %0\");"
11894   [(set_attr "type" "dmpy_media")
11895    (set (attr "highpart")
11896         (cond [(eq_attr "endian" "big") (const_string "ignore")]
11897          (const_string "user")))])
11899 (define_insn "mmul01_wl"
11900   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11901         (vec_select:V2SI
11902          (mult:V4SI
11903           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11904           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11905          (parallel [(const_int 0) (const_int 1)])))]
11906   "TARGET_SHMEDIA"
11907   "* return (TARGET_LITTLE_ENDIAN
11908              ? \"mmullo.wl      %1, %2, %0\"
11909              : \"mmulhi.wl      %1, %2, %0\");"
11910   [(set_attr "type" "dmpy_media")
11911    (set (attr "highpart")
11912         (cond [(eq_attr "endian" "little") (const_string "ignore")]
11913          (const_string "user")))])
11916 (define_expand "mmulsum_wq"
11917   [(match_operand:DI 0 "arith_reg_dest" "")
11918    (match_operand:V4HI 1 "arith_reg_operand" "")
11919    (match_operand:V4HI 2 "arith_reg_operand" "")
11920    (match_operand:DI 3 "arith_reg_operand" "")]
11921   "TARGET_SHMEDIA"
11922   "
11924   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11925                                operands[1], operands[2]));
11926   DONE;
11929 (define_insn "mmulsum_wq_i"
11930   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11931         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11932          (plus:DI
11933           (plus:DI
11934            (vec_select:DI
11935             (mult:V4DI
11936              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11937              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11938             (parallel [(const_int 0)]))
11939            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11940                                      (sign_extend:V4DI (match_dup 3)))
11941                           (parallel [(const_int 1)])))
11942           (plus:DI
11943            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11944                                      (sign_extend:V4DI (match_dup 3)))
11945                           (parallel [(const_int 2)]))
11946            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11947                                      (sign_extend:V4DI (match_dup 3)))
11948                           (parallel [(const_int 3)]))))))]
11949   "TARGET_SHMEDIA"
11950   "mmulsum.wq   %2, %3, %0"
11951   [(set_attr "type" "mac_media")])
11953 (define_expand "mperm_w"
11954   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11955    (match_operand:V4HI 1 "arith_reg_operand" "r")
11956    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11957   "TARGET_SHMEDIA"
11958   "
11960   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11961              (operands[0], operands[1], operands[2]));
11962   DONE;
11965 ; This use of vec_select isn't exactly correct according to rtl.texi
11966 ; (because not constant), but it seems a straightforward extension.
11967 (define_insn "mperm_w_little"
11968   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11969         (vec_select:V4HI
11970          (match_operand:V4HI 1 "arith_reg_operand" "r")
11971          (parallel
11972           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11973                             (const_int 2) (const_int 0))
11974            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11975            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11976            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11977   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11978   "mperm.w      %1, %N2, %0"
11979   [(set_attr "type" "arith_media")])
11981 (define_insn "mperm_w_big"
11982   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11983         (vec_select:V4HI
11984          (match_operand:V4HI 1 "arith_reg_operand" "r")
11985          (parallel
11986           [(zero_extract:QI (not:QI (match_operand:QI 2
11987                                      "extend_reg_or_0_operand" "rZ"))
11988                             (const_int 2) (const_int 0))
11989            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11990            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11991            (zero_extract:QI (not:QI (match_dup 2))
11992                             (const_int 2) (const_int 6))])))]
11993   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11994   "mperm.w      %1, %N2, %0"
11995   [(set_attr "type" "arith_media")])
11997 (define_insn "mperm_w0"
11998   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11999         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12000                                           "trunc_hi_operand" "r"))))]
12001   "TARGET_SHMEDIA"
12002   "mperm.w      %1, r63, %0"
12003   [(set_attr "type" "arith_media")
12004    (set_attr "highpart" "ignore")])
12006 (define_expand "msad_ubq"
12007   [(match_operand:DI 0 "arith_reg_dest" "")
12008    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12009    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12010    (match_operand:DI 3 "arith_reg_operand" "")]
12011   "TARGET_SHMEDIA"
12012   "
12014   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12015                              operands[1], operands[2]));
12016   DONE;
12019 (define_insn "msad_ubq_i"
12020   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12021         (plus:DI
12022          (plus:DI
12023           (plus:DI
12024            (plus:DI
12025             (match_operand:DI 1 "arith_reg_operand" "0")
12026             (abs:DI (vec_select:DI
12027                      (minus:V8DI
12028                       (zero_extend:V8DI
12029                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12030                       (zero_extend:V8DI
12031                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12032                      (parallel [(const_int 0)]))))
12033            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12034                                               (zero_extend:V8DI (match_dup 3)))
12035                                   (parallel [(const_int 1)]))))
12036           (plus:DI
12037            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12038                                               (zero_extend:V8DI (match_dup 3)))
12039                                   (parallel [(const_int 2)])))
12040            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12041                                               (zero_extend:V8DI (match_dup 3)))
12042                                   (parallel [(const_int 3)])))))
12043          (plus:DI
12044           (plus:DI
12045            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12046                                               (zero_extend:V8DI (match_dup 3)))
12047                                   (parallel [(const_int 4)])))
12048            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12049                                               (zero_extend:V8DI (match_dup 3)))
12050                                   (parallel [(const_int 5)]))))
12051           (plus:DI
12052            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12053                                               (zero_extend:V8DI (match_dup 3)))
12054                                   (parallel [(const_int 6)])))
12055            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12056                                               (zero_extend:V8DI (match_dup 3)))
12057                                   (parallel [(const_int 7)])))))))]
12058   "TARGET_SHMEDIA"
12059   "msad.ubq     %N2, %N3, %0"
12060   [(set_attr "type" "mac_media")])
12062 (define_insn "mshalds_l"
12063   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12064         (ss_truncate:V2SI
12065          (ashift:V2DI
12066           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12067           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12068                   (const_int 31)))))]
12069   "TARGET_SHMEDIA"
12070   "mshalds.l    %1, %2, %0"
12071   [(set_attr "type" "mcmp_media")
12072    (set_attr "highpart" "depend")])
12074 (define_insn "mshalds_w"
12075   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12076         (ss_truncate:V4HI
12077          (ashift:V4SI
12078           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12079           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12080                   (const_int 15)))))]
12081   "TARGET_SHMEDIA"
12082   "mshalds.w    %1, %2, %0"
12083   [(set_attr "type" "mcmp_media")
12084    (set_attr "highpart" "depend")])
12086 (define_insn "ashrv2si3"
12087   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12088         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12089                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12090   "TARGET_SHMEDIA"
12091   "mshard.l     %1, %2, %0"
12092   [(set_attr "type" "arith_media")
12093    (set_attr "highpart" "depend")])
12095 (define_insn "ashrv4hi3"
12096   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12097         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12098                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12099   "TARGET_SHMEDIA"
12100   "mshard.w     %1, %2, %0"
12101   [(set_attr "type" "arith_media")
12102    (set_attr "highpart" "depend")])
12104 (define_insn "mshards_q"
12105   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12106         (ss_truncate:HI
12107          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12108                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12109   "TARGET_SHMEDIA"
12110   "mshards.q    %1, %N2, %0"
12111   [(set_attr "type" "mcmp_media")])
12113 (define_expand "mshfhi_b"
12114   [(match_operand:V8QI 0 "arith_reg_dest" "")
12115    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12116    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12117   "TARGET_SHMEDIA"
12118   "
12120   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12121              (operands[0], operands[1], operands[2]));
12122   DONE;
12125 (define_expand "mshflo_b"
12126   [(match_operand:V8QI 0 "arith_reg_dest" "")
12127    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12128    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12129   "TARGET_SHMEDIA"
12130   "
12132   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12133              (operands[0], operands[1], operands[2]));
12134   DONE;
12137 (define_insn "mshf4_b"
12138   [(set
12139     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12140     (vec_select:V8QI
12141      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12142                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12143      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12144                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12145   "TARGET_SHMEDIA"
12146   "* return (TARGET_LITTLE_ENDIAN
12147              ? \"mshfhi.b       %N1, %N2, %0\"
12148              : \"mshflo.b       %N1, %N2, %0\");"
12149   [(set_attr "type" "arith_media")
12150    (set (attr "highpart")
12151         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12152          (const_string "user")))])
12154 (define_insn "mshf0_b"
12155   [(set
12156     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12157     (vec_select:V8QI
12158      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12159                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12160      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12161                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12162   "TARGET_SHMEDIA"
12163   "* return (TARGET_LITTLE_ENDIAN
12164              ? \"mshflo.b       %N1, %N2, %0\"
12165              : \"mshfhi.b       %N1, %N2, %0\");"
12166   [(set_attr "type" "arith_media")
12167    (set (attr "highpart")
12168         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12169          (const_string "user")))])
12171 (define_expand "mshfhi_l"
12172   [(match_operand:V2SI 0 "arith_reg_dest" "")
12173    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12174    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12175   "TARGET_SHMEDIA"
12176   "
12178   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12179              (operands[0], operands[1], operands[2]));
12180   DONE;
12183 (define_expand "mshflo_l"
12184   [(match_operand:V2SI 0 "arith_reg_dest" "")
12185    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12186    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12187   "TARGET_SHMEDIA"
12188   "
12190   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12191              (operands[0], operands[1], operands[2]));
12192   DONE;
12195 (define_insn "mshf4_l"
12196   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12197         (vec_select:V2SI
12198          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12199                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12200          (parallel [(const_int 1) (const_int 3)])))]
12201   "TARGET_SHMEDIA"
12202   "* return (TARGET_LITTLE_ENDIAN
12203              ? \"mshfhi.l       %N1, %N2, %0\"
12204              : \"mshflo.l       %N1, %N2, %0\");"
12205   [(set_attr "type" "arith_media")
12206    (set (attr "highpart")
12207         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12208          (const_string "user")))])
12210 (define_insn "mshf0_l"
12211   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12212         (vec_select:V2SI
12213          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12214                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12215          (parallel [(const_int 0) (const_int 2)])))]
12216   "TARGET_SHMEDIA"
12217   "* return (TARGET_LITTLE_ENDIAN
12218              ? \"mshflo.l       %N1, %N2, %0\"
12219              : \"mshfhi.l       %N1, %N2, %0\");"
12220   [(set_attr "type" "arith_media")
12221    (set (attr "highpart")
12222         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12223          (const_string "user")))])
12225 (define_expand "mshfhi_w"
12226   [(match_operand:V4HI 0 "arith_reg_dest" "")
12227    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12228    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12229   "TARGET_SHMEDIA"
12230   "
12232   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12233              (operands[0], operands[1], operands[2]));
12234   DONE;
12237 (define_expand "mshflo_w"
12238   [(match_operand:V4HI 0 "arith_reg_dest" "")
12239    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12240    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12241   "TARGET_SHMEDIA"
12242   "
12244   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12245              (operands[0], operands[1], operands[2]));
12246   DONE;
12249 (define_insn "mshf4_w"
12250   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12251         (vec_select:V4HI
12252          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12253                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12254          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12255   "TARGET_SHMEDIA"
12256   "* return (TARGET_LITTLE_ENDIAN
12257              ? \"mshfhi.w       %N1, %N2, %0\"
12258              : \"mshflo.w       %N1, %N2, %0\");"
12259   [(set_attr "type" "arith_media")
12260    (set (attr "highpart")
12261         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12262          (const_string "user")))])
12264 (define_insn "mshf0_w"
12265   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12266         (vec_select:V4HI
12267          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12268                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12269          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12270   "TARGET_SHMEDIA"
12271   "* return (TARGET_LITTLE_ENDIAN
12272              ? \"mshflo.w       %N1, %N2, %0\"
12273              : \"mshfhi.w       %N1, %N2, %0\");"
12274   [(set_attr "type" "arith_media")
12275    (set (attr "highpart")
12276         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12277          (const_string "user")))])
12279 (define_insn "mshflo_w_x"
12280   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12281         (vec_select:V4HI
12282          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12283                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12284          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12285   "TARGET_SHMEDIA"
12286   "mshflo.w     %N1, %N2, %0"
12287   [(set_attr "type" "arith_media")
12288    (set_attr "highpart" "ignore")])
12290 /* These are useful to expand ANDs and as combiner patterns.  */
12291 (define_insn_and_split "mshfhi_l_di"
12292   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12293         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12294                              (const_int 32))
12295                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12296                         (const_int -4294967296))))]
12297   "TARGET_SHMEDIA"
12298   "@
12299         mshfhi.l        %N1, %N2, %0
12300         #"
12301   "TARGET_SHMEDIA && reload_completed
12302    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12303   [(set (match_dup 3) (match_dup 4))
12304    (set (match_dup 5) (match_dup 6))]
12305   "
12307   operands[3] = gen_lowpart (SImode, operands[0]);
12308   operands[4] = gen_highpart (SImode, operands[1]);
12309   operands[5] = gen_highpart (SImode, operands[0]);
12310   operands[6] = gen_highpart (SImode, operands[2]);
12312   [(set_attr "type" "arith_media")])
12314 (define_insn "*mshfhi_l_di_rev"
12315   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12316         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12317                         (const_int -4294967296))
12318                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12319                              (const_int 32))))]
12320   "TARGET_SHMEDIA"
12321   "mshfhi.l     %N2, %N1, %0"
12322   [(set_attr "type" "arith_media")])
12324 (define_split
12325   [(set (match_operand:DI 0 "arith_reg_dest" "")
12326         (ior:DI (zero_extend:DI (match_operand:SI 1
12327                                               "extend_reg_or_0_operand" ""))
12328                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12329                         (const_int -4294967296))))
12330    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12331   "TARGET_SHMEDIA"
12332   [(const_int 0)]
12333   "
12335   emit_insn (gen_ashldi3_media (operands[3],
12336                                 simplify_gen_subreg (DImode, operands[1],
12337                                                      SImode, 0),
12338                                 GEN_INT (32)));
12339   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12340   DONE;
12343 (define_insn "mshflo_l_di"
12344   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12345         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12346                         (const_int 4294967295))
12347                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12348                            (const_int 32))))]
12350   "TARGET_SHMEDIA"
12351   "mshflo.l     %N1, %N2, %0"
12352   [(set_attr "type" "arith_media")
12353    (set_attr "highpart" "ignore")])
12355 (define_insn "*mshflo_l_di_rev"
12356   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12357         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12358                            (const_int 32))
12359                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12360                         (const_int 4294967295))))]
12362   "TARGET_SHMEDIA"
12363   "mshflo.l     %N2, %N1, %0"
12364   [(set_attr "type" "arith_media")
12365    (set_attr "highpart" "ignore")])
12367 ;; Combiner pattern for trampoline initialization.
12368 (define_insn_and_split "*double_shori"
12369   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12370         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12371                            (const_int 32))
12372                 (match_operand:DI 2 "const_int_operand" "n")))]
12373   "TARGET_SHMEDIA
12374    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
12375   "#"
12376   "rtx_equal_p (operands[0], operands[1])"
12377   [(const_int 0)]
12378   "
12380   HOST_WIDE_INT v = INTVAL (operands[2]);
12382   emit_insn (gen_shori_media (operands[0], operands[0],
12383              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
12384   emit_insn (gen_shori_media (operands[0], operands[0],
12385                               gen_int_mode (v, HImode)));
12386   DONE;
12388   [(set_attr "highpart" "ignore")])
12391 (define_insn "*mshflo_l_di_x"
12392   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12393         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12394                                  "rZ"))
12395                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12396                            (const_int 32))))]
12398   "TARGET_SHMEDIA"
12399   "mshflo.l     %N1, %N2, %0"
12400   [(set_attr "type" "arith_media")
12401    (set_attr "highpart" "ignore")])
12403 (define_insn_and_split "concat_v2sf"
12404   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12405 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12406         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12407                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12409   "TARGET_SHMEDIA"
12410   "@
12411         mshflo.l        %N1, %N2, %0
12412         #
12413         #"
12414   "TARGET_SHMEDIA && reload_completed
12415    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12416   [(set (match_dup 3) (match_dup 1))
12417    (set (match_dup 4) (match_dup 2))]
12418   "
12420   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12421   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12423   [(set_attr "type" "arith_media")
12424    (set_attr "highpart" "ignore")])
12426 (define_insn "*mshflo_l_di_x_rev"
12427   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12428         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12429                            (const_int 32))
12430                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12432   "TARGET_SHMEDIA"
12433   "mshflo.l     %N2, %N1, %0"
12434   [(set_attr "type" "arith_media")
12435    (set_attr "highpart" "ignore")])
12437 (define_insn "ashlv2si3"
12438   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12439         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12440                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12441   "TARGET_SHMEDIA"
12442   "mshlld.l     %1, %2, %0"
12443   [(set_attr "type" "arith_media")
12444    (set_attr "highpart" "depend")])
12446 (define_split
12447   [(set (match_operand 0 "any_register_operand" "")
12448         (match_operator 3 "shift_operator"
12449           [(match_operand 1 "any_register_operand" "")
12450            (match_operand 2 "shift_count_reg_operand" "")]))]
12451   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12452   [(set (match_dup 0) (match_dup 3))]
12453   "
12455   rtx count = operands[2];
12456   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12458   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12459          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12460          || GET_CODE (count) == TRUNCATE)
12461     count = XEXP (count, 0);
12462   inner_mode = GET_MODE (count);
12463   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12464                                subreg_lowpart_offset (outer_mode, inner_mode));
12465   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12466                                 operands[1], count);
12469 (define_insn "ashlv4hi3"
12470   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12471         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12472                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12473   "TARGET_SHMEDIA"
12474   "mshlld.w     %1, %2, %0"
12475   [(set_attr "type" "arith_media")
12476    (set_attr "highpart" "depend")])
12478 (define_insn "lshrv2si3"
12479   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12480         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12481                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12482   "TARGET_SHMEDIA"
12483   "mshlrd.l     %1, %2, %0"
12484   [(set_attr "type" "arith_media")
12485    (set_attr "highpart" "depend")])
12487 (define_insn "lshrv4hi3"
12488   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12489         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12490                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12491   "TARGET_SHMEDIA"
12492   "mshlrd.w     %1, %2, %0"
12493   [(set_attr "type" "arith_media")
12494    (set_attr "highpart" "depend")])
12496 (define_insn "subv2si3"
12497   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12498         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12499                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12500   "TARGET_SHMEDIA"
12501   "msub.l       %N1, %2, %0"
12502   [(set_attr "type" "arith_media")
12503    (set_attr "highpart" "depend")])
12505 (define_insn "subv4hi3"
12506   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12507         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12508                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12509   "TARGET_SHMEDIA"
12510   "msub.w       %N1, %2, %0"
12511   [(set_attr "type" "arith_media")
12512    (set_attr "highpart" "depend")])
12514 (define_insn_and_split "subv2hi3"
12515   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12516         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12517                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12518   "TARGET_SHMEDIA"
12519   "#"
12520   "TARGET_SHMEDIA"
12521   [(const_int 0)]
12522   "
12524   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12525   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12526   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12527   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12528   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12530   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12531   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12532   DONE;
12534   [(set_attr "highpart" "must_split")])
12536 (define_insn "sssubv2si3"
12537   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12538         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12539                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12540   "TARGET_SHMEDIA"
12541   "msubs.l      %N1, %2, %0"
12542   [(set_attr "type" "mcmp_media")
12543    (set_attr "highpart" "depend")])
12545 (define_insn "ussubv8qi3"
12546   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12547         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12548                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12549   "TARGET_SHMEDIA"
12550   "msubs.ub     %N1, %2, %0"
12551   [(set_attr "type" "mcmp_media")
12552    (set_attr "highpart" "depend")])
12554 (define_insn "sssubv4hi3"
12555   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12556         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12557                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12558   "TARGET_SHMEDIA"
12559   "msubs.w      %N1, %2, %0"
12560   [(set_attr "type" "mcmp_media")
12561    (set_attr "highpart" "depend")])
12563 ;; Floating Point Intrinsics
12565 (define_insn "fcosa_s"
12566   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12567         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12568                    UNSPEC_FCOSA))]
12569   "TARGET_SHMEDIA"
12570   "fcosa.s      %1, %0"
12571   [(set_attr "type" "atrans_media")])
12573 (define_insn "fsina_s"
12574   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12575         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12576                    UNSPEC_FSINA))]
12577   "TARGET_SHMEDIA"
12578   "fsina.s      %1, %0"
12579   [(set_attr "type" "atrans_media")])
12581 (define_insn "fipr"
12582   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12583         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12584                                                     "fp_arith_reg_operand" "f")
12585                                                    (match_operand:V4SF 2
12586                                                     "fp_arith_reg_operand" "f"))
12587                                          (parallel [(const_int 0)]))
12588                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12589                                          (parallel [(const_int 1)])))
12590                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12591                                          (parallel [(const_int 2)]))
12592                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12593                                          (parallel [(const_int 3)])))))]
12594   "TARGET_SHMEDIA"
12595   "fipr.s       %1, %2, %0"
12596   [(set_attr "type" "fparith_media")])
12598 (define_insn "fsrra_s"
12599   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12600         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12601                    UNSPEC_FSRRA))]
12602   "TARGET_SHMEDIA"
12603   "fsrra.s      %1, %0"
12604   [(set_attr "type" "atrans_media")])
12606 (define_insn "ftrv"
12607   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12608         (plus:V4SF
12609          (plus:V4SF
12610           (mult:V4SF
12611            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12612                             (parallel [(const_int 0) (const_int 5)
12613                                        (const_int 10) (const_int 15)]))
12614            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12615           (mult:V4SF
12616            (vec_select:V4SF (match_dup 1)
12617                             (parallel [(const_int 4) (const_int 9)
12618                                        (const_int 14) (const_int 3)]))
12619            (vec_select:V4SF (match_dup 2)
12620                             (parallel [(const_int 1) (const_int 2)
12621                                        (const_int 3) (const_int 0)]))))
12622          (plus:V4SF
12623           (mult:V4SF
12624            (vec_select:V4SF (match_dup 1)
12625                             (parallel [(const_int 8) (const_int 13)
12626                                        (const_int 2) (const_int 7)]))
12627            (vec_select:V4SF (match_dup 2)
12628                             (parallel [(const_int 2) (const_int 3)
12629                                        (const_int 0) (const_int 1)])))
12630           (mult:V4SF
12631            (vec_select:V4SF (match_dup 1)
12632                             (parallel [(const_int 12) (const_int 1)
12633                                        (const_int 6) (const_int 11)]))
12634            (vec_select:V4SF (match_dup 2)
12635                             (parallel [(const_int 3) (const_int 0)
12636                                        (const_int 1) (const_int 2)]))))))]
12637   "TARGET_SHMEDIA"
12638   "ftrv.s %1, %2, %0"
12639   [(set_attr "type" "fparith_media")])
12641 (define_insn "ldhi_l"
12642   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12643         (zero_extract:SI
12644          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12645                                   (const_int 3))
12646                           (const_int -3)))
12647          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12648          (const_int 0)))]
12649   "TARGET_SHMEDIA32"
12650   "ldhi.l       %U1, %0"
12651   [(set_attr "type" "load_media")])
12653 (define_insn "ldhi_q"
12654   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12655         (zero_extract:DI
12656          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12657                                   (const_int 7))
12658                           (const_int -7)))
12659          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12660          (const_int 0)))]
12661   "TARGET_SHMEDIA32"
12662   "ldhi.q       %U1, %0"
12663   [(set_attr "type" "load_media")])
12665 (define_insn_and_split "*ldhi_q_comb0"
12666   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12667         (zero_extract:DI
12668          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12669                                             "register_operand" "r")
12670                                            (match_operand:SI 2
12671                                             "ua_offset" "I06"))
12672                                   (const_int 7))
12673                           (const_int -7)))
12674          (plus:SI (and:SI (match_dup 1) (const_int 7))
12675                   (const_int 1))
12676          (const_int 0)))]
12677   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12678   "#"
12679   ""
12680   [(pc)]
12681   "emit_insn (gen_ldhi_q (operands[0],
12682                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12683    DONE;")
12686 (define_insn_and_split "*ldhi_q_comb1"
12687   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12688         (zero_extract:DI
12689          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12690                                             "register_operand" "r")
12691                                            (match_operand:SI 2
12692                                             "ua_offset" "I06"))
12693                                   (const_int 7))
12694                           (const_int -7)))
12695          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12696                                                    "ua_offset" "I06"))
12697                           (const_int 7))
12698                   (const_int 1))
12699          (const_int 0)))]
12700   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12701    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12702   "#"
12703   ""
12704   [(pc)]
12705   "emit_insn (gen_ldhi_q (operands[0],
12706                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12707    DONE;")
12710 (define_insn "ldlo_l"
12711   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12712         (zero_extract:SI
12713          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12714                          (const_int -4)))
12715          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12716          (and:SI (match_dup 1) (const_int 3))))]
12717   "TARGET_SHMEDIA32"
12718   "ldlo.l       %U1, %0"
12719   [(set_attr "type" "load_media")])
12721 (define_insn "ldlo_q"
12722   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12723         (zero_extract:DI
12724          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12725                          (const_int -8)))
12726          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12727          (and:SI (match_dup 1) (const_int 7))))]
12728   "TARGET_SHMEDIA32"
12729   "ldlo.q       %U1, %0"
12730   [(set_attr "type" "load_media")])
12732 (define_insn_and_split "*ldlo_q_comb0"
12733   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12734         (zero_extract:DI
12735          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12736                                   (match_operand:SI 2 "ua_offset" "I06"))
12737                          (const_int -8)))
12738          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12739          (and:SI (match_dup 1) (const_int 7))))]
12740   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12741   "#"
12742   ""
12743   [(pc)]
12744   "emit_insn (gen_ldlo_q (operands[0],
12745                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12746    DONE;")
12748 (define_insn_and_split "*ldlo_q_comb1"
12749   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12750         (zero_extract:DI
12751          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12752                                   (match_operand:SI 2 "ua_offset" "I06"))
12753                          (const_int -8)))
12754          (minus:SI (const_int 8)
12755                    (and:SI (plus:SI (match_dup 1)
12756                                     (match_operand:SI 3 "ua_offset" "I06"))
12757                            (const_int 7)))
12758          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12759   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12760    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12761   "#"
12762   ""
12763   [(pc)]
12764   "emit_insn (gen_ldlo_q (operands[0],
12765                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12766    DONE;")
12768 (define_insn "sthi_l"
12769   [(set (zero_extract:SI
12770          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12771                                   (const_int 3))
12772                           (const_int -3)))
12773          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12774          (const_int 0))
12775         (match_operand:SI 1 "arith_reg_operand" "r"))]
12776   "TARGET_SHMEDIA32"
12777   "sthi.l       %U0, %1"
12778   [(set_attr "type" "ustore_media")])
12780 ;; All unaligned stores are considered to be 'narrow' because they typically
12781 ;; operate on less that a quadword, and when they operate on a full quadword,
12782 ;; the vanilla store high / store low sequence will cause a stall if not
12783 ;; scheduled apart.
12784 (define_insn "sthi_q"
12785   [(set (zero_extract:DI
12786          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12787                                   (const_int 7))
12788                           (const_int -7)))
12789          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12790          (const_int 0))
12791         (match_operand:DI 1 "arith_reg_operand" "r"))]
12792   "TARGET_SHMEDIA32"
12793   "sthi.q       %U0, %1"
12794   [(set_attr "type" "ustore_media")])
12796 (define_insn_and_split "*sthi_q_comb0"
12797   [(set (zero_extract:DI
12798          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12799                                             "register_operand" "r")
12800                                            (match_operand:SI 1 "ua_offset"
12801                                             "I06"))
12802                                   (const_int 7))
12803                           (const_int -7)))
12804          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12805          (const_int 0))
12806         (match_operand:DI 2 "arith_reg_operand" "r"))]
12807   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12808   "#"
12809   ""
12810   [(pc)]
12811   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12812                           operands[2]));
12813    DONE;")
12815 (define_insn_and_split "*sthi_q_comb1"
12816   [(set (zero_extract:DI
12817          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12818                                             "register_operand" "r")
12819                                            (match_operand:SI 1 "ua_offset"
12820                                             "I06"))
12821                                   (const_int 7))
12822                           (const_int -7)))
12823          (plus:SI (and:SI (plus:SI (match_dup 0)
12824                                    (match_operand:SI 2 "ua_offset" "I06"))
12825                           (const_int 7))
12826                   (const_int 1))
12827          (const_int 0))
12828         (match_operand:DI 3 "arith_reg_operand" "r"))]
12829   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12830    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12831   "#"
12832   ""
12833   [(pc)]
12834   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12835                           operands[3]));
12836    DONE;")
12838 ;; This is highpart user because the address is used as full 64 bit.
12839 (define_insn "stlo_l"
12840   [(set (zero_extract:SI
12841          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12842                          (const_int -4)))
12843          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12844          (and:SI (match_dup 0) (const_int 3)))
12845         (match_operand:SI 1 "arith_reg_operand" "r"))]
12846   "TARGET_SHMEDIA32"
12847   "stlo.l       %U0, %1"
12848   [(set_attr "type" "ustore_media")])
12850 (define_insn "stlo_q"
12851   [(set (zero_extract:DI
12852          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12853                          (const_int -8)))
12854          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12855          (and:SI (match_dup 0) (const_int 7)))
12856         (match_operand:DI 1 "arith_reg_operand" "r"))]
12857   "TARGET_SHMEDIA32"
12858   "stlo.q       %U0, %1"
12859   [(set_attr "type" "ustore_media")])
12861 (define_insn_and_split "*stlo_q_comb0"
12862   [(set (zero_extract:DI
12863          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12864                                   (match_operand:SI 1 "ua_offset" "I06"))
12865                          (const_int -8)))
12866          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12867          (and:SI (match_dup 0) (const_int 7)))
12868         (match_operand:DI 2 "arith_reg_operand" "r"))]
12869   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12870   "#"
12871   ""
12872   [(pc)]
12873   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12874                           operands[2]));
12875    DONE;")
12877 (define_insn_and_split "*stlo_q_comb1"
12878   [(set (zero_extract:DI
12879          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12880                                   (match_operand:SI 1 "ua_offset" "I06"))
12881                          (const_int -8)))
12882          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12883                                                   (match_operand:SI 2
12884                                                    "ua_offset" "I06"))
12885                                          (const_int 7)))
12886          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12887         (match_operand:DI 3 "arith_reg_operand" "r"))]
12888   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12889   "#"
12890   ""
12891   [(pc)]
12892   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12893                           operands[3]));
12894    DONE;")
12896 (define_insn "ldhi_l64"
12897   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12898         (zero_extract:SI
12899          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12900                                   (const_int 3))
12901                           (const_int -3)))
12902          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12903          (const_int 0)))]
12904   "TARGET_SHMEDIA64"
12905   "ldhi.l       %U1, %0"
12906   [(set_attr "type" "load_media")])
12908 (define_insn "ldhi_q64"
12909   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12910         (zero_extract:DI
12911          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12912                                   (const_int 7))
12913                           (const_int -7)))
12914          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12915          (const_int 0)))]
12916   "TARGET_SHMEDIA64"
12917   "ldhi.q       %U1, %0"
12918   [(set_attr "type" "load_media")])
12920 (define_insn "ldlo_l64"
12921   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12922         (zero_extract:SI
12923          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12924                          (const_int -4)))
12925          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12926          (and:DI (match_dup 1) (const_int 3))))]
12927   "TARGET_SHMEDIA64"
12928   "ldlo.l       %U1, %0"
12929   [(set_attr "type" "load_media")])
12931 (define_insn "ldlo_q64"
12932   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12933         (zero_extract:DI
12934          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12935                          (const_int -8)))
12936          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12937          (and:DI (match_dup 1) (const_int 7))))]
12938   "TARGET_SHMEDIA64"
12939   "ldlo.q       %U1, %0"
12940   [(set_attr "type" "load_media")])
12942 (define_insn "sthi_l64"
12943   [(set (zero_extract:SI
12944          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12945                                   (const_int 3))
12946                           (const_int -3)))
12947          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12948          (const_int 0))
12949         (match_operand:SI 1 "arith_reg_operand" "r"))]
12950   "TARGET_SHMEDIA64"
12951   "sthi.l       %U0, %1"
12952   [(set_attr "type" "ustore_media")])
12954 (define_insn "sthi_q64"
12955   [(set (zero_extract:DI
12956          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12957                                   (const_int 7))
12958                           (const_int -7)))
12959          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12960          (const_int 0))
12961         (match_operand:DI 1 "arith_reg_operand" "r"))]
12962   "TARGET_SHMEDIA64"
12963   "sthi.q       %U0, %1"
12964   [(set_attr "type" "ustore_media")])
12966 (define_insn "stlo_l64"
12967   [(set (zero_extract:SI
12968          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12969                          (const_int -4)))
12970          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12971          (and:DI (match_dup 0) (const_int 3)))
12972         (match_operand:SI 1 "arith_reg_operand" "r"))]
12973   "TARGET_SHMEDIA64"
12974   "stlo.l       %U0, %1"
12975   [(set_attr "type" "ustore_media")])
12977 (define_insn "stlo_q64"
12978   [(set (zero_extract:DI
12979          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12980                          (const_int -8)))
12981          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12982          (and:DI (match_dup 0) (const_int 7)))
12983         (match_operand:DI 1 "arith_reg_operand" "r"))]
12984   "TARGET_SHMEDIA64"
12985   "stlo.q       %U0, %1"
12986   [(set_attr "type" "ustore_media")])
12988 (define_insn "nsb"
12989   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12990         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12991                    UNSPEC_NSB))]
12992   "TARGET_SHMEDIA"
12993   "nsb  %1, %0"
12994   [(set_attr "type" "arith_media")])
12996 (define_insn "nsbsi"
12997   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12998         (zero_extend:SI
12999          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13000                     UNSPEC_NSB)))]
13001   "TARGET_SHMEDIA"
13002   "nsb  %1, %0"
13003   [(set_attr "type" "arith_media")])
13005 (define_insn "nsbdi"
13006   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13007         (zero_extend:DI
13008          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13009                     UNSPEC_NSB)))]
13010   "TARGET_SHMEDIA"
13011   "nsb  %1, %0"
13012   [(set_attr "type" "arith_media")])
13014 (define_expand "ffsdi2"
13015   [(set (match_operand:DI 0 "arith_reg_dest" "")
13016         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13017   "TARGET_SHMEDIA"
13018   "
13020   rtx scratch = gen_reg_rtx (DImode);
13021   rtx last;
13023   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13024   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13025   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13026   emit_insn (gen_nsbdi (scratch, scratch));
13027   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13028   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13029   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13030   REG_NOTES (last)
13031     = gen_rtx_EXPR_LIST (REG_EQUAL,
13032                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13033   DONE;
13036 (define_expand "ffssi2"
13037   [(set (match_operand:SI 0 "arith_reg_dest" "")
13038         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13039   "TARGET_SHMEDIA"
13040   "
13042   rtx scratch = gen_reg_rtx (SImode);
13043   rtx discratch = gen_reg_rtx (DImode);
13044   rtx last;
13046   emit_insn (gen_adddi3 (discratch,
13047                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13048                          constm1_rtx));
13049   emit_insn (gen_andcdi3 (discratch,
13050                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13051                           discratch));
13052   emit_insn (gen_nsbsi (scratch, discratch));
13053   last = emit_insn (gen_subsi3 (operands[0],
13054                                 force_reg (SImode, GEN_INT (63)), scratch));
13055   REG_NOTES (last)
13056     = gen_rtx_EXPR_LIST (REG_EQUAL,
13057                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13058   DONE;
13061 (define_insn "byterev"
13062   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13063         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13064                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13065                                     (const_int 4) (const_int 3) (const_int 2)
13066                                     (const_int 1) (const_int 0)])))]
13067   "TARGET_SHMEDIA"
13068   "byterev      %1, %0"
13069   [(set_attr "type" "arith_media")])
13071 (define_insn "*prefetch_media"
13072   [(prefetch (match_operand:QI 0 "address_operand" "p")
13073              (match_operand:SI 1 "const_int_operand" "n")
13074              (match_operand:SI 2 "const_int_operand" "n"))]
13075   "TARGET_SHMEDIA"
13076   "*
13078   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13079   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13080   return \"\";
13082   [(set_attr "type" "other")])
13084 (define_insn "*prefetch_i4"
13085   [(prefetch (match_operand:SI 0 "register_operand" "r")
13086              (match_operand:SI 1 "const_int_operand" "n")
13087              (match_operand:SI 2 "const_int_operand" "n"))]
13088   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13089   "*
13091   return \"pref @%0\";
13093   [(set_attr "type" "other")])
13095 (define_expand "prefetch"
13096   [(prefetch (match_operand 0 "address_operand" "p")
13097              (match_operand:SI 1 "const_int_operand" "n")
13098              (match_operand:SI 2 "const_int_operand" "n"))]
13099   "TARGET_HARD_SH4 || TARGET_SH5"
13100   "
13102   if (GET_MODE (operands[0]) != Pmode
13103       || GET_CODE (operands[1]) != CONST_INT
13104       || GET_CODE (operands[2]) != CONST_INT)
13105     FAIL;
13106   if (! TARGET_SHMEDIA)
13107     operands[0] = force_reg (Pmode, operands[0]);
13110 (define_insn "alloco_i"
13111   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13112         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13113   "TARGET_SHMEDIA32"
13114   "*
13116   rtx xops[2];
13118   if (GET_CODE (operands[0]) == PLUS)
13119     {
13120       xops[0] = XEXP (operands[0], 0);
13121       xops[1] = XEXP (operands[0], 1);
13122     }
13123   else
13124     {
13125       xops[0] = operands[0];
13126       xops[1] = const0_rtx;
13127     }
13128   output_asm_insn (\"alloco   %0, %1\", xops);
13129   return \"\";
13131   [(set_attr "type" "other")])
13133 (define_split
13134   [(set (match_operand 0 "any_register_operand" "")
13135         (match_operand 1 "" ""))]
13136   "TARGET_SHMEDIA && reload_completed"
13137   [(set (match_dup 0) (match_dup 1))]
13138   "
13140   int n_changes = 0;
13142   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13143   if (!n_changes)
13144     FAIL;
13147 ; Stack Protector Patterns
13149 (define_expand "stack_protect_set"
13150   [(set (match_operand 0 "memory_operand" "")
13151         (match_operand 1 "memory_operand" ""))]
13152   ""
13154   if (TARGET_SHMEDIA)
13155     {
13156       if (TARGET_SHMEDIA64)
13157         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13158       else
13159         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13160     }
13161   else
13162     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13164   DONE;
13167 (define_insn "stack_protect_set_si"
13168   [(set (match_operand:SI 0 "memory_operand" "=m")
13169         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13170    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13171   "!TARGET_SHMEDIA"
13172   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13173   [(set_attr "type" "other")
13174    (set_attr "length" "6")])
13176 (define_insn "stack_protect_set_si_media"
13177   [(set (match_operand:SI 0 "memory_operand" "=m")
13178         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13179    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13180   "TARGET_SHMEDIA"
13181   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13182   [(set_attr "type" "other")
13183    (set_attr "length" "12")])
13185 (define_insn "stack_protect_set_di_media"
13186   [(set (match_operand:DI 0 "memory_operand" "=m")
13187         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13188    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13189   "TARGET_SHMEDIA64"
13190   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13191   [(set_attr "type" "other")
13192    (set_attr "length" "12")])
13194 (define_expand "stack_protect_test"
13195   [(match_operand 0 "memory_operand" "")
13196    (match_operand 1 "memory_operand" "")
13197    (match_operand 2 "" "")]
13198   ""
13200   if (TARGET_SHMEDIA)
13201     {
13202       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13204       if (TARGET_SHMEDIA64)
13205         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13206                                                     operands[1]));
13207       else
13208         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13209                                                     operands[1]));
13211       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13212     }
13213   else
13214     {
13215       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13216       emit_jump_insn (gen_branch_true (operands[2]));
13217     }
13219   DONE;
13222 (define_insn "stack_protect_test_si"
13223   [(set (reg:SI T_REG)
13224         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13225                     (match_operand:SI 1 "memory_operand" "m")]
13226                    UNSPEC_SP_TEST))
13227   (set (match_scratch:SI 2 "=&r") (const_int 0))
13228   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13229   "!TARGET_SHMEDIA"
13230   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13231   [(set_attr "type" "other")
13232    (set_attr "length" "10")])
13234 (define_insn "stack_protect_test_si_media"
13235   [(set (match_operand:SI 0 "register_operand" "=&r")
13236         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13237                     (match_operand:SI 2 "memory_operand" "m")]
13238                    UNSPEC_SP_TEST))
13239   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13240   "TARGET_SHMEDIA"
13241   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13242   [(set_attr "type" "other")
13243    (set_attr "length" "16")])
13245 (define_insn "stack_protect_test_di_media"
13246   [(set (match_operand:DI 0 "register_operand" "=&r")
13247         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13248                     (match_operand:DI 2 "memory_operand" "m")]
13249                    UNSPEC_SP_TEST))
13250   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13251   "TARGET_SHMEDIA64"
13252   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13253   [(set_attr "type" "other")
13254    (set_attr "length" "16")])