2006-01-30 Marcin Dalecki <martin@dalecki.de>
[official-gcc.git] / gcc / config / sh / sh.md
blobe2e477f2a572ebe561d4cfbec7af3512cc2930ad
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 (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
416                          (symbol_ref "INSN"))
417                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
418                          (symbol_ref "code_for_indirect_jump_scratch")))
419                 (cond [(eq_attr "braf_branch_p" "yes")
420                        (const_int 6)
421                        (eq (symbol_ref "flag_pic") (const_int 0))
422                        (const_int 10)
423                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
424                        (const_int 10)] (const_int 18))
425                 (eq_attr "braf_branch_p" "yes")
426                 (const_int 10)
427 ;; ??? using pc is not computed transitively.
428                 (ne (match_dup 0) (match_dup 0))
429                 (const_int 12)
430                 (ne (symbol_ref ("flag_pic")) (const_int 0))
431                 (const_int 22)
432                 ] (const_int 14))
433          (eq_attr "type" "pt_media")
434          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
435                        (const_int 20) (const_int 12))
436          (and (eq_attr "type" "jump_media")
437               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
438          (const_int 8)
439          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
440                          (const_int 4)
441                          (const_int 2))))
443 ;; DFA descriptions for the pipelines
445 (include "sh1.md")
446 (include "shmedia.md")
447 (include "sh4.md")
449 (include "predicates.md")
451 ;; Definitions for filling delay slots
453 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
455 ;; ??? This should be (nil) instead of (const_int 0)
456 (define_attr "hit_stack" "yes,no"
457         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
458                    (const_int 0))
459                (const_string "no")]
460               (const_string "yes")))
462 (define_attr "interrupt_function" "no,yes"
463   (const (symbol_ref "current_function_interrupt")))
465 (define_attr "in_delay_slot" "yes,no"
466   (cond [(eq_attr "type" "cbranch") (const_string "no")
467          (eq_attr "type" "pcload,pcload_si") (const_string "no")
468          (eq_attr "needs_delay_slot" "yes") (const_string "no")
469          (eq_attr "length" "2") (const_string "yes")
470          ] (const_string "no")))
472 (define_attr "cond_delay_slot" "yes,no"
473   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
474          ] (const_string "no")))
476 (define_attr "is_sfunc" ""
477   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
479 (define_attr "is_mac_media" ""
480   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
482 (define_attr "branch_zero" "yes,no"
483   (cond [(eq_attr "type" "!cbranch") (const_string "no")
484          (ne (symbol_ref "(next_active_insn (insn)\
485                            == (prev_active_insn\
486                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
487                           && get_attr_length (next_active_insn (insn)) == 2")
488              (const_int 0))
489          (const_string "yes")]
490         (const_string "no")))
492 ;; SH4 Double-precision computation with double-precision result -
493 ;; the two halves are ready at different times.
494 (define_attr "dfp_comp" "yes,no"
495   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
496         (const_string "no")))
498 ;; Insns for which the latency of a preceding fp insn is decreased by one.
499 (define_attr "late_fp_use" "yes,no" (const_string "no"))
500 ;; And feeding insns for which this relevant.
501 (define_attr "any_fp_comp" "yes,no"
502   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
503          (const_string "yes")]
504         (const_string "no")))
506 (define_attr "any_int_load" "yes,no"
507   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
508          (const_string "yes")]
509         (const_string "no")))
511 (define_attr "highpart" "user, ignore, extend, depend, must_split"
512   (const_string "user"))
514 (define_delay
515   (eq_attr "needs_delay_slot" "yes")
516   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
518 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
519 ;; and thus we can't put a pop instruction in its delay slot.
520 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
521 ;; instruction can go in the delay slot.
523 ;; Since a normal return (rts) implicitly uses the PR register,
524 ;; we can't allow PR register loads in an rts delay slot.
526 (define_delay
527   (eq_attr "type" "return")
528   [(and (eq_attr "in_delay_slot" "yes")
529         (ior (and (eq_attr "interrupt_function" "no")
530                   (eq_attr "type" "!pload,prset"))
531              (and (eq_attr "interrupt_function" "yes")
532                   (ior
533                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
534                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
536 ;; Since a call implicitly uses the PR register, we can't allow
537 ;; a PR register store in a jsr delay slot.
539 (define_delay
540   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
541   [(and (eq_attr "in_delay_slot" "yes")
542         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
544 ;; Say that we have annulled true branches, since this gives smaller and
545 ;; faster code when branches are predicted as not taken.
547 ;; ??? The non-annulled condition should really be "in_delay_slot",
548 ;; but insns that can be filled in non-annulled get priority over insns
549 ;; that can only be filled in anulled.
551 (define_delay
552   (and (eq_attr "type" "cbranch")
553        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
554   ;; SH2e has a hardware bug that pretty much prohibits the use of
555   ;; annuled delay slots.
556   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
557                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
559 ;; -------------------------------------------------------------------------
560 ;; SImode signed integer comparisons
561 ;; -------------------------------------------------------------------------
563 (define_insn ""
564   [(set (reg:SI T_REG)
565         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
566                        (match_operand:SI 1 "arith_operand" "K08,r"))
567                (const_int 0)))]
568   "TARGET_SH1"
569   "tst  %1,%0"
570   [(set_attr "type" "mt_group")])
572 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
573 ;; That would still allow reload to create cmpi instructions, but would
574 ;; perhaps allow forcing the constant into a register when that is better.
575 ;; Probably should use r0 for mem/imm compares, but force constant into a
576 ;; register for pseudo/imm compares.
578 (define_insn "cmpeqsi_t"
579   [(set (reg:SI T_REG)
580         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
581                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
582   "TARGET_SH1"
583   "@
584         tst     %0,%0
585         cmp/eq  %1,%0
586         cmp/eq  %1,%0"
587    [(set_attr "type" "mt_group")])
589 (define_insn "cmpgtsi_t"
590   [(set (reg:SI T_REG)
591         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
592                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
593   "TARGET_SH1"
594   "@
595         cmp/gt  %1,%0
596         cmp/pl  %0"
597    [(set_attr "type" "mt_group")])
599 (define_insn "cmpgesi_t"
600   [(set (reg:SI T_REG)
601         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
602                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
603   "TARGET_SH1"
604   "@
605         cmp/ge  %1,%0
606         cmp/pz  %0"
607    [(set_attr "type" "mt_group")])
609 ;; -------------------------------------------------------------------------
610 ;; SImode unsigned integer comparisons
611 ;; -------------------------------------------------------------------------
613 (define_insn "cmpgeusi_t"
614   [(set (reg:SI T_REG)
615         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
616                 (match_operand:SI 1 "arith_reg_operand" "r")))]
617   "TARGET_SH1"
618   "cmp/hs       %1,%0"
619    [(set_attr "type" "mt_group")])
621 (define_insn "cmpgtusi_t"
622   [(set (reg:SI T_REG)
623         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
624                 (match_operand:SI 1 "arith_reg_operand" "r")))]
625   "TARGET_SH1"
626   "cmp/hi       %1,%0"
627    [(set_attr "type" "mt_group")])
629 ;; We save the compare operands in the cmpxx patterns and use them when
630 ;; we generate the branch.
632 (define_expand "cmpsi"
633   [(set (reg:SI T_REG)
634         (compare (match_operand:SI 0 "cmpsi_operand" "")
635                  (match_operand:SI 1 "arith_operand" "")))]
636   "TARGET_SH1 || TARGET_SHMEDIA"
637   "
639   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
640       && GET_CODE (operands[1]) != CONST_INT)
641     operands[0] = copy_to_mode_reg (SImode, operands[0]);
642   sh_compare_op0 = operands[0];
643   sh_compare_op1 = operands[1];
644   DONE;
647 ;; -------------------------------------------------------------------------
648 ;; DImode signed integer comparisons
649 ;; -------------------------------------------------------------------------
651 ;; ??? Could get better scheduling by splitting the initial test from the
652 ;; rest of the insn after reload.  However, the gain would hardly justify
653 ;; the sh.md size increase necessary to do that.
655 (define_insn ""
656   [(set (reg:SI T_REG)
657         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
658                        (match_operand:DI 1 "arith_operand" "r"))
659                (const_int 0)))]
660   "TARGET_SH1"
661   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
662                                  insn, operands);"
663   [(set_attr "length" "6")
664    (set_attr "type" "arith3b")])
666 (define_insn "cmpeqdi_t"
667   [(set (reg:SI T_REG)
668         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
669                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
670   "TARGET_SH1"
671   "@
672         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
673         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
674   [(set_attr "length" "6")
675    (set_attr "type" "arith3b")])
677 (define_split
678   [(set (reg:SI T_REG)
679         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
680                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
681 ;; If we applied this split when not optimizing, it would only be
682 ;; applied during the machine-dependent reorg, when no new basic blocks
683 ;; may be created.
684   "TARGET_SH1 && reload_completed && optimize"
685   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
686    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
687                            (label_ref (match_dup 6))
688                            (pc)))
689    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
690    (match_dup 6)]
691   "
693   operands[2]
694     = gen_rtx_REG (SImode,
695                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
696   operands[3]
697     = (operands[1] == const0_rtx
698        ? const0_rtx
699        : gen_rtx_REG (SImode,
700                       true_regnum (operands[1])
701                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
702   operands[4] = gen_lowpart (SImode, operands[0]);
703   operands[5] = gen_lowpart (SImode, operands[1]);
704   operands[6] = gen_label_rtx ();
707 (define_insn "cmpgtdi_t"
708   [(set (reg:SI T_REG)
709         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
710                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
711   "TARGET_SH2"
712   "@
713         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
714         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
715   [(set_attr "length" "8")
716    (set_attr "type" "arith3")])
718 (define_insn "cmpgedi_t"
719   [(set (reg:SI T_REG)
720         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
722   "TARGET_SH2"
723   "@
724         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
725         cmp/pz\\t%S0"
726   [(set_attr "length" "8,2")
727    (set_attr "type" "arith3,mt_group")])
729 ;; -------------------------------------------------------------------------
730 ;; DImode unsigned integer comparisons
731 ;; -------------------------------------------------------------------------
733 (define_insn "cmpgeudi_t"
734   [(set (reg:SI T_REG)
735         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
736                 (match_operand:DI 1 "arith_reg_operand" "r")))]
737   "TARGET_SH2"
738   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
739   [(set_attr "length" "8")
740    (set_attr "type" "arith3")])
742 (define_insn "cmpgtudi_t"
743   [(set (reg:SI T_REG)
744         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
745                 (match_operand:DI 1 "arith_reg_operand" "r")))]
746   "TARGET_SH2"
747   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
748   [(set_attr "length" "8")
749    (set_attr "type" "arith3")])
751 (define_insn "cmpeqsi_media"
752   [(set (match_operand:DI 0 "register_operand" "=r")
753         (eq:DI (match_operand:SI 1 "logical_operand" "%r")
754                (match_operand:SI 2 "cmp_operand" "Nr")))]
755   "TARGET_SHMEDIA"
756   "cmpeq        %1, %N2, %0"
757   [(set_attr "type" "cmp_media")])
759 (define_insn "cmpeqdi_media"
760   [(set (match_operand:DI 0 "register_operand" "=r")
761         (eq:DI (match_operand:DI 1 "register_operand" "%r")
762                (match_operand:DI 2 "cmp_operand" "Nr")))]
763   "TARGET_SHMEDIA"
764   "cmpeq        %1, %N2, %0"
765   [(set_attr "type" "cmp_media")])
767 (define_insn "cmpgtsi_media"
768   [(set (match_operand:DI 0 "register_operand" "=r")
769         (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
770                (match_operand:SI 2 "cmp_operand" "rN")))]
771   "TARGET_SHMEDIA"
772   "cmpgt        %N1, %N2, %0"
773   [(set_attr "type" "cmp_media")])
775 (define_insn "cmpgtdi_media"
776   [(set (match_operand:DI 0 "register_operand" "=r")
777         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
778                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
779   "TARGET_SHMEDIA"
780   "cmpgt        %N1, %N2, %0"
781   [(set_attr "type" "cmp_media")])
783 (define_insn "cmpgtusi_media"
784   [(set (match_operand:DI 0 "register_operand" "=r")
785         (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
786                 (match_operand:SI 2 "cmp_operand" "rN")))]
787   "TARGET_SHMEDIA"
788   "cmpgtu       %N1, %N2, %0"
789   [(set_attr "type" "cmp_media")])
791 (define_insn "cmpgtudi_media"
792   [(set (match_operand:DI 0 "register_operand" "=r")
793         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
794                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
795   "TARGET_SHMEDIA"
796   "cmpgtu       %N1, %N2, %0"
797   [(set_attr "type" "cmp_media")])
799 (define_insn "cmpsieqsi_media"
800   [(set (match_operand:SI 0 "register_operand" "=r")
801         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
802                (match_operand:SI 2 "cmp_operand" "Nr")))]
803   "TARGET_SHMEDIA"
804   "cmpeq        %1, %N2, %0"
805   [(set_attr "type" "cmp_media")])
807 (define_insn "cmpsieqdi_media"
808   [(set (match_operand:SI 0 "register_operand" "=r")
809         (eq:SI (match_operand:DI 1 "register_operand" "%r")
810                (match_operand:DI 2 "cmp_operand" "Nr")))]
811   "TARGET_SHMEDIA"
812   "cmpeq        %1, %N2, %0"
813   [(set_attr "type" "cmp_media")])
815 (define_insn "cmpsigtsi_media"
816   [(set (match_operand:SI 0 "register_operand" "=r")
817         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
818                (match_operand:SI 2 "cmp_operand" "rN")))]
819   "TARGET_SHMEDIA"
820   "cmpgt        %N1, %N2, %0"
821   [(set_attr "type" "cmp_media")])
823 (define_insn "cmpsigtdi_media"
824   [(set (match_operand:SI 0 "register_operand" "=r")
825         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
826                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
827   "TARGET_SHMEDIA"
828   "cmpgt        %N1, %N2, %0"
829   [(set_attr "type" "cmp_media")])
831 (define_insn "cmpsigtusi_media"
832   [(set (match_operand:SI 0 "register_operand" "=r")
833         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
834                 (match_operand:SI 2 "cmp_operand" "rN")))]
835   "TARGET_SHMEDIA"
836   "cmpgtu       %N1, %N2, %0"
837   [(set_attr "type" "cmp_media")])
839 (define_insn "cmpsigtudi_media"
840   [(set (match_operand:SI 0 "register_operand" "=r")
841         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
842                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
843   "TARGET_SHMEDIA"
844   "cmpgtu       %N1, %N2, %0"
845   [(set_attr "type" "cmp_media")])
847 ; These two patterns are for combine.
848 (define_insn "*cmpne0si_media"
849   [(set (match_operand:DI 0 "register_operand" "=r")
850         (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
851   "TARGET_SHMEDIA"
852   "cmpgtu       %1,r63,%0"
853   [(set_attr "type" "cmp_media")])
855 (define_insn "*cmpne0sisi_media"
856   [(set (match_operand:SI 0 "register_operand" "=r")
857         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
858   "TARGET_SHMEDIA"
859   "cmpgtu       %1,r63,%0"
860   [(set_attr "type" "cmp_media")])
862 ;; We save the compare operands in the cmpxx patterns and use them when
863 ;; we generate the branch.
865 (define_expand "cmpdi"
866   [(set (reg:SI T_REG)
867         (compare (match_operand:DI 0 "arith_operand" "")
868                  (match_operand:DI 1 "arith_operand" "")))]
869   "TARGET_SH2 || TARGET_SHMEDIA"
870   "
872   sh_compare_op0 = operands[0];
873   sh_compare_op1 = operands[1];
874   DONE;
876 ;; -------------------------------------------------------------------------
877 ;; Conditional move instructions
878 ;; -------------------------------------------------------------------------
880 ;; The insn names may seem reversed, but note that cmveq performs the move
881 ;; if op1 == 0, and cmvne does it if op1 != 0.
883 (define_insn "movdicc_false"
884   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
885         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
886                              (const_int 0))
887          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
888          (match_operand:DI 3 "arith_reg_operand" "0")))]
889   "TARGET_SHMEDIA"
890   "cmveq        %1, %N2, %0"
891   [(set_attr "type" "arith_media")])
893 (define_insn "movdicc_true"
894   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
895         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
896                              (const_int 0))
897          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
898          (match_operand:DI 3 "arith_reg_operand" "0")))]
899   "TARGET_SHMEDIA"
900   "cmvne        %1, %N2, %0"
901   [(set_attr "type" "arith_media")])
903 (define_peephole2
904   [(set (match_operand:DI 0 "arith_reg_dest" "")
905         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
906                            [(match_operand:DI 1 "arith_reg_operand" "")
907                             (const_int 0)])
908          (match_operand:DI 2 "arith_reg_dest" "")
909          (match_dup 0)))
910    (set (match_dup 2) (match_dup 0))]
911   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
912   [(set (match_dup 2)
913         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
914   "
916   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
917                                 VOIDmode, operands[1], CONST0_RTX (DImode));
920 (define_peephole2
921   [(set (match_operand:DI 0 "general_movdst_operand" "")
922         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
923    (set (match_operand:DI 2 "arith_reg_dest" "")
924         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
925                            [(match_operand:DI 3 "arith_reg_operand" "")
926                             (const_int 0)])
927          (match_dup 0)
928          (match_dup 2)))]
929   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
930   [(set (match_dup 2)
931         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
932   "")
934 (define_expand "movdicc"
935   [(set (match_operand:DI 0 "register_operand" "")
936         (if_then_else:DI (match_operand 1 "comparison_operator" "")
937                          (match_operand:DI 2 "register_operand" "")
938                          (match_operand:DI 3 "register_operand" "")))]
939   "TARGET_SHMEDIA"
940   "
942   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
943       && GET_MODE (sh_compare_op0) == DImode
944       && sh_compare_op1 == const0_rtx)
945     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
946                                   sh_compare_op0, sh_compare_op1);
947   else
948     {
949       rtx tmp;
951       if (no_new_pseudos)
952         FAIL;
954       tmp = gen_reg_rtx (DImode);
956       switch (GET_CODE (operands[1]))
957         {
958         case EQ:
959           emit_insn (gen_seq (tmp));
960           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
961           break;
963         case NE:
964           emit_insn (gen_seq (tmp));
965           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
966           break;
968         case GT:
969           emit_insn (gen_sgt (tmp));
970           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
971           break;
973         case LT:
974           emit_insn (gen_slt (tmp));
975           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
976           break;
978         case GE:
979           emit_insn (gen_slt (tmp));
980           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
981           break;
983         case LE:
984           emit_insn (gen_sgt (tmp));
985           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
986           break;
988         case GTU:
989           emit_insn (gen_sgtu (tmp));
990           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
991           break;
993         case LTU:
994           emit_insn (gen_sltu (tmp));
995           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
996           break;
998         case GEU:
999           emit_insn (gen_sltu (tmp));
1000           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1001           break;
1003         case LEU:
1004           emit_insn (gen_sgtu (tmp));
1005           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1006           break;
1008         case UNORDERED:
1009           emit_insn (gen_sunordered (tmp));
1010           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1011           break;
1013         case ORDERED:
1014           emit_insn (gen_sunordered (tmp));
1015           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1016           break;
1018         case UNEQ:
1019         case UNGE:
1020         case UNGT:
1021         case UNLE:
1022         case UNLT:
1023         case LTGT:
1024           FAIL;
1026         default:
1027           gcc_unreachable ();
1028         }
1029     }
1032 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1033 ;; SImode to DImode.
1034 (define_insn "movsicc_false"
1035   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1036         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1037                           (const_int 0))
1038          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1039          (match_operand:SI 3 "arith_reg_operand" "0")))]
1040   "TARGET_SHMEDIA"
1041   "cmveq        %1, %N2, %0"
1042   [(set_attr "type" "arith_media")])
1044 (define_insn "movsicc_true"
1045   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1046         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1047                           (const_int 0))
1048          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1049          (match_operand:SI 3 "arith_reg_operand" "0")))]
1050   "TARGET_SHMEDIA"
1051   "cmvne        %1, %N2, %0"
1052   [(set_attr "type" "arith_media")])
1054 (define_peephole2
1055   [(set (match_operand:SI 0 "arith_reg_dest" "")
1056         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1057                            [(match_operand:SI 1 "arith_reg_operand" "")
1058                             (const_int 0)])
1059          (match_operand:SI 2 "arith_reg_dest" "")
1060          (match_dup 0)))
1061    (set (match_dup 2) (match_dup 0))]
1062   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1063   [(set (match_dup 2)
1064         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1065   "
1067   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1068                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1071 (define_peephole2
1072   [(set (match_operand:SI 0 "general_movdst_operand" "")
1073         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1074    (set (match_operand:SI 2 "arith_reg_dest" "")
1075         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1076                            [(match_operand:SI 3 "arith_reg_operand" "")
1077                             (const_int 0)])
1078          (match_dup 0)
1079          (match_dup 2)))]
1080   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1081    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1082   [(set (match_dup 2)
1083         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1084   "
1086   replace_rtx (operands[4], operands[0], operands[1]);
1089 (define_peephole2
1090   [(set (match_operand 0 "any_register_operand" "")
1091         (match_operand 1 "any_register_operand" ""))
1092    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1093    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1094   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1095     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1096    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1097    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1098    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1099    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1100    && (REGNO_REG_CLASS (REGNO (operands[0]))
1101        == REGNO_REG_CLASS (REGNO (operands[2])))
1102    && (REGNO_REG_CLASS (REGNO (operands[1]))
1103        == REGNO_REG_CLASS (REGNO (operands[0])))"
1104   [(set (match_dup 0) (match_dup 3))
1105    (set (match_dup 4) (match_dup 5))]
1106   "
1108   rtx set1, set2;
1109   rtx replacements[4];
1111   /* We want to replace occurrences of operands[0] with operands[1] and
1112      operands[2] with operands[0] in operands[4]/operands[5].
1113      Doing just two replace_rtx calls naively would result in the second
1114      replacement undoing all that the first did if operands[1] and operands[2]
1115      are identical, so we must do this simultaneously.  */
1116   replacements[0] = operands[0];
1117   replacements[1] = operands[1];
1118   replacements[2] = operands[2];
1119   replacements[3] = operands[0];
1120   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1121       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1122       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1123     FAIL;
1125   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1126   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1127   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1128   /* The operands array is aliased to recog_data.operand, which gets
1129      clobbered by extract_insn, so finish with it now.  */
1130   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1131   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1132   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1133      always uses emit_insn.  */
1134   /* Check that we don't violate matching constraints or earlyclobbers.  */
1135   extract_insn (emit_insn (set1));
1136   if (! constrain_operands (1))
1137     goto failure;
1138   extract_insn (emit (set2));
1139   if (! constrain_operands (1))
1140     {
1141       rtx tmp;
1142     failure:
1143       tmp = replacements[0];
1144       replacements[0] = replacements[1];
1145       replacements[1] = tmp;
1146       tmp = replacements[2];
1147       replacements[2] = replacements[3];
1148       replacements[3] = tmp;
1149       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1150       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1151       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1152       FAIL;
1153     }
1154   DONE;
1157 ;; The register allocator is rather clumsy in handling multi-way conditional
1158 ;; moves, so allow the combiner to make them, and we split them up after
1159 ;; reload.  */
1160 (define_insn_and_split "*movsicc_umin"
1161   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1162         (umin:SI (if_then_else:SI
1163                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1164                        (const_int 0))
1165                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1166                    (match_operand:SI 3 "register_operand" "0"))
1167                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1168    (clobber (match_scratch:SI 5 "=&r"))]
1169   "TARGET_SHMEDIA && no_new_pseudos"
1170   "#"
1171   "TARGET_SHMEDIA && reload_completed"
1172   [(pc)]
1173   "
1175   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1176                                 operands[3]));
1177   emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1178   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1179                                 operands[0]));
1180   DONE;
1183 (define_expand "movsicc"
1184   [(set (match_operand:SI 0 "register_operand" "")
1185         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1186                          (match_operand:SI 2 "register_operand" "")
1187                          (match_operand:SI 3 "register_operand" "")))]
1188   "TARGET_SHMEDIA"
1189   "
1191   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1192       && GET_MODE (sh_compare_op0) == SImode
1193       && sh_compare_op1 == const0_rtx)
1194     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1195                                   sh_compare_op0, sh_compare_op1);
1196   else
1197     {
1198       rtx tmp;
1200       if (no_new_pseudos)
1201         FAIL;
1203       tmp = gen_reg_rtx (SImode);
1205       switch (GET_CODE (operands[1]))
1206         {
1207         case EQ:
1208           emit_insn (gen_seq (tmp));
1209           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1210           break;
1212         case NE:
1213           emit_insn (gen_seq (tmp));
1214           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1215           break;
1217         case GT:
1218           emit_insn (gen_sgt (tmp));
1219           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1220           break;
1222         case LT:
1223           emit_insn (gen_slt (tmp));
1224           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1225           break;
1227         case GE:
1228           emit_insn (gen_slt (tmp));
1229           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1230           break;
1232         case LE:
1233           emit_insn (gen_sgt (tmp));
1234           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1235           break;
1237         case GTU:
1238           emit_insn (gen_sgtu (tmp));
1239           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1240           break;
1242         case LTU:
1243           emit_insn (gen_sltu (tmp));
1244           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1245           break;
1247         case GEU:
1248           emit_insn (gen_sltu (tmp));
1249           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1250           break;
1252         case LEU:
1253           emit_insn (gen_sgtu (tmp));
1254           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1255           break;
1257         case UNORDERED:
1258           emit_insn (gen_sunordered (tmp));
1259           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1260           break;
1262         case ORDERED:
1263           emit_insn (gen_sunordered (tmp));
1264           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1265           break;
1267         case UNEQ:
1268         case UNGE:
1269         case UNGT:
1270         case UNLE:
1271         case UNLT:
1272         case LTGT:
1273           FAIL;
1275         default:
1276           abort ();
1277         }
1278     }
1281 (define_expand "movqicc"
1282   [(set (match_operand:QI 0 "register_operand" "")
1283         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1284                          (match_operand:QI 2 "register_operand" "")
1285                          (match_operand:QI 3 "register_operand" "")))]
1286   "TARGET_SHMEDIA"
1287   "
1289   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1290   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1291   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1292   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1293   DONE;
1296 ;; -------------------------------------------------------------------------
1297 ;; Addition instructions
1298 ;; -------------------------------------------------------------------------
1300 (define_expand "adddi3"
1301   [(set (match_operand:DI 0 "arith_reg_operand" "")
1302         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1303                  (match_operand:DI 2 "arith_operand" "")))]
1304   ""
1305   "
1307   if (TARGET_SH1)
1308     {
1309       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1310         FAIL;
1311       operands[2] = force_reg (DImode, operands[2]);
1312       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1313       DONE;
1314     }
1317 (define_insn "*adddi3_media"
1318   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1319         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1320                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1321   "TARGET_SHMEDIA"
1322   "@
1323         add     %1, %2, %0
1324         addi    %1, %2, %0"
1325   [(set_attr "type" "arith_media")])
1327 (define_insn "*adddisi3_media"
1328   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1329         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1330                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1331   "TARGET_SHMEDIA"
1332   "@
1333         add.l   %1, %2, %0
1334         addi.l  %1, %2, %0"
1335   [(set_attr "type" "arith_media")
1336    (set_attr "highpart" "ignore")])
1338 (define_insn "adddi3z_media"
1339   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1340         (zero_extend:DI
1341          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1342                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1343   "TARGET_SHMEDIA"
1344   "addz.l       %1, %N2, %0"
1345   [(set_attr "type" "arith_media")
1346    (set_attr "highpart" "ignore")])
1348 (define_insn "adddi3_compact"
1349   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1350         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1351                  (match_operand:DI 2 "arith_reg_operand" "r")))
1352    (clobber (reg:SI T_REG))]
1353   "TARGET_SH1"
1354   "#"
1355   [(set_attr "length" "6")])
1357 (define_split
1358   [(set (match_operand:DI 0 "arith_reg_dest" "")
1359         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1360                  (match_operand:DI 2 "arith_reg_operand" "")))
1361    (clobber (reg:SI T_REG))]
1362   "TARGET_SH1 && reload_completed"
1363   [(const_int 0)]
1364   "
1366   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1367   high0 = gen_rtx_REG (SImode,
1368                        true_regnum (operands[0])
1369                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1370   high2 = gen_rtx_REG (SImode,
1371                        true_regnum (operands[2])
1372                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1373   emit_insn (gen_clrt ());
1374   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1375   emit_insn (gen_addc1 (high0, high0, high2));
1376   DONE;
1379 (define_insn "addc"
1380   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1381         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1382                           (match_operand:SI 2 "arith_reg_operand" "r"))
1383                  (reg:SI T_REG)))
1384    (set (reg:SI T_REG)
1385         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1386   "TARGET_SH1"
1387   "addc %2,%0"
1388   [(set_attr "type" "arith")])
1390 (define_insn "addc1"
1391   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1392         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1393                           (match_operand:SI 2 "arith_reg_operand" "r"))
1394                  (reg:SI T_REG)))
1395    (clobber (reg:SI T_REG))]
1396   "TARGET_SH1"
1397   "addc %2,%0"
1398   [(set_attr "type" "arith")])
1400 (define_expand "addsi3"
1401   [(set (match_operand:SI 0 "arith_reg_operand" "")
1402         (plus:SI (match_operand:SI 1 "arith_operand" "")
1403                  (match_operand:SI 2 "arith_operand" "")))]
1404   ""
1405   "
1407   if (TARGET_SHMEDIA)
1408     operands[1] = force_reg (SImode, operands[1]);
1411 (define_insn "addsi3_media"
1412   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1413         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1414                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1415   "TARGET_SHMEDIA"
1416   "@
1417         add.l   %1, %2, %0
1418         addi.l  %1, %2, %0"
1419   [(set_attr "type" "arith_media")
1420    (set_attr "highpart" "ignore")])
1422 (define_insn "addsidi3_media"
1423   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1424         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1425                                   "%r,r")
1426                                  (match_operand:SI 2 "arith_operand"
1427                                   "r,I10"))))]
1428   "TARGET_SHMEDIA"
1429   "@
1430         add.l   %1, %2, %0
1431         addi.l  %1, %2, %0"
1432   [(set_attr "type" "arith_media")
1433    (set_attr "highpart" "ignore")])
1435 (define_insn "*addsi3_compact"
1436   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1437         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1438                  (match_operand:SI 2 "arith_operand" "rI08")))]
1439   "TARGET_SH1"
1440   "add  %2,%0"
1441   [(set_attr "type" "arith")])
1443 ;; -------------------------------------------------------------------------
1444 ;; Subtraction instructions
1445 ;; -------------------------------------------------------------------------
1447 (define_expand "subdi3"
1448   [(set (match_operand:DI 0 "arith_reg_operand" "")
1449         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1450                   (match_operand:DI 2 "arith_reg_operand" "")))]
1451   ""
1452   "
1454   if (TARGET_SH1)
1455     {
1456       operands[1] = force_reg (DImode, operands[1]);
1457       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1458       DONE;
1459     }
1462 (define_insn "*subdi3_media"
1463   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1464         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1465                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1466   "TARGET_SHMEDIA"
1467   "sub  %N1, %2, %0"
1468   [(set_attr "type" "arith_media")])
1469   
1470 (define_insn "subdisi3_media"
1471   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1472         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1473                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1474   "TARGET_SHMEDIA"
1475   "sub.l        %N1, %2, %0"
1476   [(set_attr "type" "arith_media")
1477    (set_attr "highpart" "ignore")])
1479 (define_insn "subdi3_compact"
1480   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1481         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1482                  (match_operand:DI 2 "arith_reg_operand" "r")))
1483    (clobber (reg:SI T_REG))]
1484   "TARGET_SH1"
1485   "#"
1486   [(set_attr "length" "6")])
1488 (define_split
1489   [(set (match_operand:DI 0 "arith_reg_dest" "")
1490         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1491                   (match_operand:DI 2 "arith_reg_operand" "")))
1492    (clobber (reg:SI T_REG))]
1493   "TARGET_SH1 && reload_completed"
1494   [(const_int 0)]
1495   "
1497   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1498   high0 = gen_rtx_REG (SImode,
1499                        true_regnum (operands[0])
1500                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1501   high2 = gen_rtx_REG (SImode,
1502                        true_regnum (operands[2])
1503                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1504   emit_insn (gen_clrt ());
1505   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1506   emit_insn (gen_subc1 (high0, high0, high2));
1507   DONE;
1510 (define_insn "subc"
1511   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1512         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1513                             (match_operand:SI 2 "arith_reg_operand" "r"))
1514                   (reg:SI T_REG)))
1515    (set (reg:SI T_REG)
1516         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1517                           (reg:SI T_REG))
1518                 (match_dup 1)))]
1519   "TARGET_SH1"
1520   "subc %2,%0"
1521   [(set_attr "type" "arith")])
1523 (define_insn "subc1"
1524   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1525         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1526                             (match_operand:SI 2 "arith_reg_operand" "r"))
1527                   (reg:SI T_REG)))
1528    (clobber (reg:SI T_REG))]
1529   "TARGET_SH1"
1530   "subc %2,%0"
1531   [(set_attr "type" "arith")])
1533 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1534 ;; pattern for this case.  This helps multimedia applications that compute
1535 ;; the sum of absolute differences.
1536 (define_insn "mov_neg_si_t"
1537   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1538   "TARGET_SH1"
1539   "subc %0,%0"
1540   [(set_attr "type" "arith")])
1542 (define_insn "*subsi3_internal"
1543   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1544         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1545                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1546   "TARGET_SH1"
1547   "sub  %2,%0"
1548   [(set_attr "type" "arith")])
1550 (define_insn_and_split "*subsi3_media"
1551   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1552         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1553                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1554   "TARGET_SHMEDIA
1555    && (operands[1] != constm1_rtx
1556        || (GET_CODE (operands[2]) != TRUNCATE
1557            && GET_CODE (operands[2]) != SUBREG))"
1558   "sub.l        %N1, %2, %0"
1559   "operands[1] == constm1_rtx"
1560   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1561   ""
1562   [(set_attr "type" "arith_media")
1563    (set_attr "highpart" "ignore")])
1565 (define_split
1566   [(set (match_operand:SI 0 "arith_reg_dest" "")
1567         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1568                                                        "general_extend_operand"
1569                                                        "") 0)) 0)))]
1570   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1571   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1572    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1573   "")
1575 (define_split
1576   [(set (match_operand:SI 0 "arith_reg_dest" "")
1577         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1578                                                        "general_extend_operand"
1579                                                        "") 0)) 3)))]
1580   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1581   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1582    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1583   "")
1584 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1585 ;; will sometimes save one instruction.  Otherwise we might get
1586 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1587 ;; are the same.
1589 (define_expand "subsi3"
1590   [(set (match_operand:SI 0 "arith_reg_operand" "")
1591         (minus:SI (match_operand:SI 1 "arith_operand" "")
1592                   (match_operand:SI 2 "arith_reg_operand" "")))]
1593   ""
1594   "
1596   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1597     {
1598       emit_insn (gen_negsi2 (operands[0], operands[2]));
1599       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1600       DONE;
1601     }
1602   if (TARGET_SHMEDIA)
1603     {
1604       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1605         FAIL;
1606       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1607         operands[1] = force_reg (SImode, operands[1]);
1608     }
1611 ;; -------------------------------------------------------------------------
1612 ;; Division instructions
1613 ;; -------------------------------------------------------------------------
1615 ;; We take advantage of the library routines which don't clobber as many
1616 ;; registers as a normal function call would.
1618 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1619 ;; also has an effect on the register that holds the address of the sfunc.
1620 ;; To make this work, we have an extra dummy insn that shows the use
1621 ;; of this register for reorg.
1623 (define_insn "use_sfunc_addr"
1624   [(set (reg:SI PR_REG)
1625         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1626   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1627   ""
1628   [(set_attr "length" "0")])
1630 (define_insn "udivsi3_sh2a"
1631   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1632         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1633                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1634   "TARGET_SH2A"
1635   "divu %2,%1"
1636   [(set_attr "type" "arith")
1637    (set_attr "in_delay_slot" "no")])
1639 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1640 ;; hard register 0.  If we used hard register 0, then the next instruction
1641 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1642 ;; gets allocated to a stack slot that needs its address reloaded, then
1643 ;; there is nothing to prevent reload from using r0 to reload the address.
1644 ;; This reload would clobber the value in r0 we are trying to store.
1645 ;; If we let reload allocate r0, then this problem can never happen.
1647 (define_insn "udivsi3_i1"
1648   [(set (match_operand:SI 0 "register_operand" "=z")
1649         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1650    (clobber (reg:SI T_REG))
1651    (clobber (reg:SI PR_REG))
1652    (clobber (reg:SI R4_REG))
1653    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1654   "TARGET_SH1 && ! TARGET_SH4"
1655   "jsr  @%1%#"
1656   [(set_attr "type" "sfunc")
1657    (set_attr "needs_delay_slot" "yes")])
1659 ; Since shmedia-nofpu code could be linked against shcompact code, and
1660 ; the udivsi3 libcall has the same name, we must consider all registers
1661 ; clobbered that are in the union of the registers clobbered by the
1662 ; shmedia and the shcompact implementation.  Note, if the shcompact
1663 ; implementation actually used shcompact code, we'd need to clobber
1664 ; also r23 and fr23.
1665 (define_insn "udivsi3_i1_media"
1666   [(set (match_operand:SI 0 "register_operand" "=z")
1667         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1668    (clobber (reg:SI T_MEDIA_REG))
1669    (clobber (reg:SI PR_MEDIA_REG))
1670    (clobber (reg:SI R20_REG))
1671    (clobber (reg:SI R21_REG))
1672    (clobber (reg:SI R22_REG))
1673    (clobber (reg:DI TR0_REG))
1674    (clobber (reg:DI TR1_REG))
1675    (clobber (reg:DI TR2_REG))
1676    (use (match_operand 1 "target_operand" "b"))]
1677   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1678   "blink        %1, r18"
1679   [(set_attr "type" "sfunc")
1680    (set_attr "needs_delay_slot" "yes")])
1682 (define_expand "udivsi3_i4_media"
1683   [(set (match_dup 3)
1684         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1685    (set (match_dup 4)
1686         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1687    (set (match_dup 5) (float:DF (match_dup 3)))
1688    (set (match_dup 6) (float:DF (match_dup 4)))
1689    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1690    (set (match_dup 8) (fix:DI (match_dup 7)))
1691    (set (match_operand:SI 0 "register_operand" "")
1692         (truncate:SI (match_dup 8)))]
1693   "TARGET_SHMEDIA_FPU"
1694   "
1696   operands[3] = gen_reg_rtx (DImode);
1697   operands[4] = gen_reg_rtx (DImode);
1698   operands[5] = gen_reg_rtx (DFmode);
1699   operands[6] = gen_reg_rtx (DFmode);
1700   operands[7] = gen_reg_rtx (DFmode);
1701   operands[8] = gen_reg_rtx (DImode);
1704 (define_insn "udivsi3_i4"
1705   [(set (match_operand:SI 0 "register_operand" "=y")
1706         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1707    (clobber (reg:SI T_REG))
1708    (clobber (reg:SI PR_REG))
1709    (clobber (reg:DF DR0_REG))
1710    (clobber (reg:DF DR2_REG))
1711    (clobber (reg:DF DR4_REG))
1712    (clobber (reg:SI R0_REG))
1713    (clobber (reg:SI R1_REG))
1714    (clobber (reg:SI R4_REG))
1715    (clobber (reg:SI R5_REG))
1716    (use (reg:PSI FPSCR_REG))
1717    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1718   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1719   "jsr  @%1%#"
1720   [(set_attr "type" "sfunc")
1721    (set_attr "fp_mode" "double")
1722    (set_attr "needs_delay_slot" "yes")])
1724 (define_insn "udivsi3_i4_single"
1725   [(set (match_operand:SI 0 "register_operand" "=y")
1726         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1727    (clobber (reg:SI T_REG))
1728    (clobber (reg:SI PR_REG))
1729    (clobber (reg:DF DR0_REG))
1730    (clobber (reg:DF DR2_REG))
1731    (clobber (reg:DF DR4_REG))
1732    (clobber (reg:SI R0_REG))
1733    (clobber (reg:SI R1_REG))
1734    (clobber (reg:SI R4_REG))
1735    (clobber (reg:SI R5_REG))
1736    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1737   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1738   "jsr  @%1%#"
1739   [(set_attr "type" "sfunc")
1740    (set_attr "needs_delay_slot" "yes")])
1742 (define_expand "udivsi3"
1743   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1744    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1745    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1746    (parallel [(set (match_operand:SI 0 "register_operand" "")
1747                    (udiv:SI (reg:SI R4_REG)
1748                             (reg:SI R5_REG)))
1749               (clobber (reg:SI T_REG))
1750               (clobber (reg:SI PR_REG))
1751               (clobber (reg:SI R4_REG))
1752               (use (match_dup 3))])]
1753   ""
1754   "
1756   rtx first, last;
1758   operands[3] = gen_reg_rtx (Pmode);
1759   /* Emit the move of the address to a pseudo outside of the libcall.  */
1760   if (TARGET_HARD_SH4 && TARGET_SH2E)
1761     {
1762       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1763       if (TARGET_FPU_SINGLE)
1764         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1765       else
1766         last = gen_udivsi3_i4 (operands[0], operands[3]);
1767     }
1768   else if (TARGET_SHMEDIA_FPU)
1769     {
1770       operands[1] = force_reg (SImode, operands[1]);
1771       operands[2] = force_reg (SImode, operands[2]);
1772       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1773       DONE;
1774     }
1775   else if (TARGET_SH2A)
1776     {
1777       operands[1] = force_reg (SImode, operands[1]);
1778       operands[2] = force_reg (SImode, operands[2]);
1779       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1780       DONE;
1781     }
1782   else if (TARGET_SH5)
1783     {
1784       function_symbol (operands[3],
1785                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1786                        SFUNC_STATIC);
1788       if (TARGET_SHMEDIA)
1789         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1790       else if (TARGET_FPU_ANY)
1791         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1792       else
1793         last = gen_udivsi3_i1 (operands[0], operands[3]);
1794     }
1795   else
1796     {
1797       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1798       last = gen_udivsi3_i1 (operands[0], operands[3]);
1799     }
1800   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1801   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1802   last = emit_insn (last);
1803   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1804      invariant code motion can move it.  */
1805   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1806   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1807   DONE;
1810 (define_insn "divsi3_sh2a"
1811   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1812         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1813                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1814   "TARGET_SH2A"
1815   "divs %2,%1"
1816   [(set_attr "type" "arith")
1817    (set_attr "in_delay_slot" "no")])
1819 (define_insn "divsi3_i1"
1820   [(set (match_operand:SI 0 "register_operand" "=z")
1821         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1822    (clobber (reg:SI T_REG))
1823    (clobber (reg:SI PR_REG))
1824    (clobber (reg:SI R1_REG))
1825    (clobber (reg:SI R2_REG))
1826    (clobber (reg:SI R3_REG))
1827    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1828   "TARGET_SH1 && ! TARGET_SH4"
1829   "jsr  @%1%#"
1830   [(set_attr "type" "sfunc")
1831    (set_attr "needs_delay_slot" "yes")])
1833 (define_insn "divsi3_i1_media"
1834   [(set (match_operand:SI 0 "register_operand" "=z")
1835         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1836    (clobber (reg:SI T_MEDIA_REG))
1837    (clobber (reg:SI PR_MEDIA_REG))
1838    (clobber (reg:SI R1_REG))
1839    (clobber (reg:SI R20_REG))
1840    (clobber (reg:SI R21_REG))
1841    (clobber (reg:SI TR0_REG))
1842    (use (match_operand 1 "target_operand" "b"))]
1843   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1844   "blink        %1, r18"
1845   [(set_attr "type" "sfunc")])
1847 (define_insn "divsi3_media_2"
1848   [(set (match_operand:SI 0 "register_operand" "=z")
1849         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1850    (clobber (reg:SI T_MEDIA_REG))
1851    (clobber (reg:SI PR_MEDIA_REG))
1852    (clobber (reg:SI R1_REG))
1853    (clobber (reg:SI R21_REG))
1854    (clobber (reg:SI TR0_REG))
1855    (use (reg:SI R20_REG))
1856    (use (match_operand 1 "target_operand" "b"))]
1857   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1858   "blink        %1, r18"
1859   [(set_attr "type" "sfunc")])
1861 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1862 ;; hard reg clobbers and data dependencies that we need when we want
1863 ;; to rematerialize the division into a call.
1864 (define_insn_and_split "divsi_inv_call"
1865   [(set (match_operand:SI 0 "register_operand" "=r")
1866         (div:SI (match_operand:SI 1 "register_operand" "r")
1867                 (match_operand:SI 2 "register_operand" "r")))
1868    (clobber (reg:SI R4_REG))
1869    (clobber (reg:SI R5_REG))
1870    (clobber (reg:SI T_MEDIA_REG))
1871    (clobber (reg:SI PR_MEDIA_REG))
1872    (clobber (reg:SI R1_REG))
1873    (clobber (reg:SI R21_REG))
1874    (clobber (reg:SI TR0_REG))
1875    (clobber (reg:SI R20_REG))
1876    (use (match_operand:SI 3 "register_operand" "r"))]
1877   "TARGET_SHMEDIA"
1878   "#"
1879   "&& (high_life_started || reload_completed)"
1880   [(set (match_dup 0) (match_dup 3))]
1881   ""
1882   [(set_attr "highpart" "must_split")])
1884 ;; This is the combiner pattern for -mdiv=inv:call .
1885 (define_insn_and_split "*divsi_inv_call_combine"
1886   [(set (match_operand:SI 0 "register_operand" "=z")
1887         (div:SI (match_operand:SI 1 "register_operand" "r")
1888                 (match_operand:SI 2 "register_operand" "r")))
1889    (clobber (reg:SI R4_REG))
1890    (clobber (reg:SI R5_REG))
1891    (clobber (reg:SI T_MEDIA_REG))
1892    (clobber (reg:SI PR_MEDIA_REG))
1893    (clobber (reg:SI R1_REG))
1894    (clobber (reg:SI R21_REG))
1895    (clobber (reg:SI TR0_REG))
1896    (clobber (reg:SI R20_REG))
1897    (use (unspec:SI [(match_dup 1)
1898                     (match_operand:SI 3 "" "")
1899                     (unspec:SI [(match_operand:SI 4 "" "")
1900                                 (match_dup 3)
1901                                 (match_operand:DI 5 "" "")]
1902                      UNSPEC_DIV_INV_M2)
1903                     (match_operand:DI 6 "" "")
1904                     (const_int 0)
1905                     (const_int 0)]
1906          UNSPEC_DIV_INV_M3))]
1907   "TARGET_SHMEDIA"
1908   "#"
1909   "&& (high_life_started || reload_completed)"
1910   [(pc)]
1911   "
1913   const char *name = sh_divsi3_libfunc;
1914   enum sh_function_kind kind = SFUNC_GOT;
1915   rtx sym;
1917   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1918   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1919   while (TARGET_DIVIDE_INV_CALL2)
1920     {
1921       rtx x = operands[3];
1923       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1924         break;
1925       x = XVECEXP (x, 0, 0);
1926       name = \"__sdivsi3_2\";
1927       kind = SFUNC_STATIC;
1928       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1929       break;
1930     }
1931   sym = function_symbol (NULL, name, kind);
1932   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1933   DONE;
1935   [(set_attr "highpart" "must_split")])
1937 (define_expand "divsi3_i4_media"
1938   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1939    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1940    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1941    (set (match_operand:SI 0 "register_operand" "=r")
1942         (fix:SI (match_dup 5)))]
1943   "TARGET_SHMEDIA_FPU"
1944   "
1946   operands[3] = gen_reg_rtx (DFmode);
1947   operands[4] = gen_reg_rtx (DFmode);
1948   operands[5] = gen_reg_rtx (DFmode);
1951 (define_insn "divsi3_i4"
1952   [(set (match_operand:SI 0 "register_operand" "=y")
1953         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1954    (clobber (reg:SI PR_REG))
1955    (clobber (reg:DF DR0_REG))
1956    (clobber (reg:DF DR2_REG))
1957    (use (reg:PSI FPSCR_REG))
1958    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1959   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1960   "jsr  @%1%#"
1961   [(set_attr "type" "sfunc")
1962    (set_attr "fp_mode" "double")
1963    (set_attr "needs_delay_slot" "yes")])
1965 (define_insn "divsi3_i4_single"
1966   [(set (match_operand:SI 0 "register_operand" "=y")
1967         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1968    (clobber (reg:SI PR_REG))
1969    (clobber (reg:DF DR0_REG))
1970    (clobber (reg:DF DR2_REG))
1971    (clobber (reg:SI R2_REG))
1972    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1973   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1974   "jsr  @%1%#"
1975   [(set_attr "type" "sfunc")
1976    (set_attr "needs_delay_slot" "yes")])
1978 (define_expand "divsi3"
1979   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1980    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1981    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1982    (parallel [(set (match_operand:SI 0 "register_operand" "")
1983                    (div:SI (reg:SI R4_REG)
1984                            (reg:SI R5_REG)))
1985               (clobber (reg:SI T_REG))
1986               (clobber (reg:SI PR_REG))
1987               (clobber (reg:SI R1_REG))
1988               (clobber (reg:SI R2_REG))
1989               (clobber (reg:SI R3_REG))
1990               (use (match_dup 3))])]
1991   ""
1992   "
1994   rtx first, last;
1996   operands[3] = gen_reg_rtx (Pmode);
1997   /* Emit the move of the address to a pseudo outside of the libcall.  */
1998   if (TARGET_HARD_SH4 && TARGET_SH2E)
1999     {
2000       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2001       if (TARGET_FPU_SINGLE)
2002         last = gen_divsi3_i4_single (operands[0], operands[3]);
2003       else
2004         last = gen_divsi3_i4 (operands[0], operands[3]);
2005     }
2006   else if (TARGET_SH2A)
2007     {
2008       operands[1] = force_reg (SImode, operands[1]);
2009       operands[2] = force_reg (SImode, operands[2]);
2010       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2011       DONE;
2012     }
2013   else if (TARGET_DIVIDE_INV)
2014     {
2015       rtx dividend = operands[1];
2016       rtx divisor = operands[2];
2017       rtx tab_base;
2018       rtx nsb_res = gen_reg_rtx (DImode);
2019       rtx norm64 = gen_reg_rtx (DImode);
2020       rtx tab_ix = gen_reg_rtx (DImode);
2021       rtx norm32 = gen_reg_rtx (SImode);
2022       rtx i92 = force_reg (DImode, GEN_INT (92));
2023       rtx scratch0a = gen_reg_rtx (DImode);
2024       rtx scratch0b = gen_reg_rtx (DImode);
2025       rtx inv0 = gen_reg_rtx (SImode);
2026       rtx scratch1a = gen_reg_rtx (DImode);
2027       rtx scratch1b = gen_reg_rtx (DImode);
2028       rtx shift = gen_reg_rtx (DImode);
2029       rtx i2p27, i43;
2030       rtx inv1 = gen_reg_rtx (SImode);
2031       rtx scratch2a = gen_reg_rtx (DImode);
2032       rtx scratch2b = gen_reg_rtx (SImode);
2033       rtx inv2 = gen_reg_rtx (SImode);
2034       rtx scratch3a = gen_reg_rtx (DImode);
2035       rtx scratch3b = gen_reg_rtx (DImode);
2036       rtx scratch3c = gen_reg_rtx (DImode);
2037       rtx scratch3d = gen_reg_rtx (SImode);
2038       rtx scratch3e = gen_reg_rtx (DImode);
2039       rtx result = gen_reg_rtx (SImode);
2041       if (! arith_reg_or_0_operand (dividend, SImode))
2042         dividend = force_reg (SImode, dividend);
2043       if (! arith_reg_operand (divisor, SImode))
2044         divisor = force_reg (SImode, divisor);
2045       if (flag_pic && Pmode != DImode)
2046         {
2047           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2048           tab_base = gen_datalabel_ref (tab_base);
2049           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2050         }
2051       else
2052         {
2053           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2054           tab_base = gen_datalabel_ref (tab_base);
2055           tab_base = force_reg (DImode, tab_base);
2056         }
2057       if (TARGET_DIVIDE_INV20U)
2058         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2059       else
2060         i2p27 = GEN_INT (0);
2061       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2062         i43 = force_reg (DImode, GEN_INT (43));
2063       else
2064         i43 = GEN_INT (0);
2065       emit_insn (gen_nsbdi (nsb_res,
2066                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2067       emit_insn (gen_ashldi3_media (norm64,
2068                                     gen_rtx_SUBREG (DImode, divisor, 0),
2069                                     nsb_res));
2070       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2071       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2072       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2073                                    inv0, scratch0a, scratch0b,
2074                                    scratch1a, scratch1b));
2075       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2076       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2077                                    scratch2a));
2078       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2079                                    i2p27, i43,
2080                                    scratch3a, scratch3b, scratch3c,
2081                                    scratch2a, scratch2b, scratch3d, scratch3e));
2082       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2083         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2084       else if (TARGET_DIVIDE_INV_FP)
2085         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2086                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2087                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2088                                      gen_reg_rtx (DFmode)));
2089       else
2090         emit_move_insn (operands[0], result);
2091       DONE;
2092     }
2093   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2094     {
2095       operands[1] = force_reg (SImode, operands[1]);
2096       operands[2] = force_reg (SImode, operands[2]);
2097       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2098       DONE;
2099     }
2100   else if (TARGET_SH5)
2101     {
2102       if (TARGET_DIVIDE_CALL2)
2103         {
2104           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2105           tab_base = gen_datalabel_ref (tab_base);
2106           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2107         }
2108       if (TARGET_FPU_ANY && TARGET_SH1)
2109         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2110       else if (TARGET_DIVIDE_CALL2)
2111         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2112       else
2113         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2115       if (TARGET_SHMEDIA)
2116         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2117                 (operands[0], operands[3]));
2118       else if (TARGET_FPU_ANY)
2119         last = gen_divsi3_i4_single (operands[0], operands[3]);
2120       else
2121         last = gen_divsi3_i1 (operands[0], operands[3]);
2122     }
2123   else
2124     {
2125       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2126       last = gen_divsi3_i1 (operands[0], operands[3]);
2127     }
2128   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2129   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2130   last = emit_insn (last);
2131   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2132      invariant code motion can move it.  */
2133   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2134   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2135   DONE;
2138 ;; operands: inv0, tab_base, tab_ix, norm32
2139 ;; scratch equiv in sdivsi3_2: r19, r21
2140 (define_expand "divsi_inv_m0"
2141   [(set (match_operand:SI 0 "register_operand" "=r")
2142         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2143                     (match_operand:DI 2 "register_operand" "r")
2144                     (match_operand:SI 3 "register_operand" "r")]
2145          UNSPEC_DIV_INV_M0))
2146    (clobber (match_operand:DI 4 "register_operand" "=r"))
2147    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2148   "TARGET_SHMEDIA"
2149   "
2152 tab_base: r20
2153 tab_ix: r21
2154 norm32: r25
2155  ldx.ub r20, r21, r19 // u0.8
2156  shlli r21, 1, r21
2157  muls.l r25, r19, r19 // s2.38
2158  ldx.w r20, r21, r21  // s2.14
2159  shari r19, 24, r19   // truncate to s2.14
2160  sub r21, r19, r19    // some 11 bit inverse in s1.14
2163   rtx inv0 = operands[0];
2164   rtx tab_base = operands[1];
2165   rtx tab_ix = operands[2];
2166   rtx norm32 = operands[3];
2167   rtx scratch0 = operands[4];
2168   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2169   rtx scratch1 = operands[5];
2170   rtx mem;
2172   mem = gen_const_mem (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2173   emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2174   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2175   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2176   mem = gen_const_mem (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2177   emit_insn (gen_extendhidi2 (scratch1, mem));
2178   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2179   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2180   DONE;
2183 ;; operands: inv1, tab_base, tab_ix, norm32
2184 (define_insn_and_split "divsi_inv_m1"
2185   [(set (match_operand:SI 0 "register_operand" "=r")
2186         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2187                     (match_operand:DI 2 "register_operand" "r")
2188                     (match_operand:SI 3 "register_operand" "r")]
2189          UNSPEC_DIV_INV_M1))
2190    (clobber (match_operand:SI 4 "register_operand" "=r"))
2191    (clobber (match_operand:DI 5 "register_operand" "=r"))
2192    (clobber (match_operand:DI 6 "register_operand" "=r"))
2193    (clobber (match_operand:DI 7 "register_operand" "=r"))
2194    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2195   "TARGET_SHMEDIA"
2196   "#"
2197   "&& no_new_pseudos"
2198   [(pc)]
2199   "
2201 /* inv0: r19
2202  muls.l r19, r19, r18 // u0.28
2203  muls.l r25, r18, r18 // s2.58
2204  shlli r19, 45, r0    // multiply by two and convert to s2.58
2205  sub r0, r18, r18
2206  shari r18, 28, r18   // some 18 bit inverse in s1.30
2209   rtx inv1 = operands[0];
2210   rtx tab_base = operands[1];
2211   rtx tab_ix = operands[2];
2212   rtx norm32 = operands[3];
2213   rtx inv0 = operands[4];
2214   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2215   rtx scratch0a = operands[5];
2216   rtx scratch0b = operands[6];
2217   rtx scratch0 = operands[7];
2218   rtx scratch1 = operands[8];
2219   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2221   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2222                                scratch0a, scratch0b));
2223   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2224   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2225   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2226   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2227   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2228   DONE;
2231 ;; operands: inv2, norm32, inv1, i92
2232 (define_insn_and_split "divsi_inv_m2"
2233   [(set (match_operand:SI 0 "register_operand" "=r")
2234         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2235                     (match_operand:SI 2 "register_operand" "r")
2236                     (match_operand:DI 3 "register_operand" "r")]
2237          UNSPEC_DIV_INV_M2))
2238    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2239   "TARGET_SHMEDIA"
2240   "#"
2241   "&& no_new_pseudos"
2242   [(pc)]
2243   "
2246  muls.l r18, r25, r0  // s2.60
2247  shari r0, 16, r0     // s-16.44
2248   sub
2249  muls.l r0, r18, r19  // s-16.74
2250  shari r19, 30, r19   // s-16.44
2252   rtx inv2 = operands[0];
2253   rtx norm32 = operands[1];
2254   rtx inv1 = operands[2];
2255   rtx i92 = operands[3];
2256   rtx scratch0 = operands[4];
2257   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2259   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2260   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2261   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2262   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2263   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2264   DONE;
2267 (define_insn_and_split "divsi_inv_m3"
2268   [(set (match_operand:SI 0 "register_operand" "=r")
2269         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2270                     (match_operand:SI 2 "register_operand" "r")
2271                     (match_operand:SI 3 "register_operand" "r")
2272                     (match_operand:DI 4 "register_operand" "r")
2273                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2274                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2275          UNSPEC_DIV_INV_M3))
2276    (clobber (match_operand:DI 7 "register_operand" "=r"))
2277    (clobber (match_operand:DI 8 "register_operand" "=r"))
2278    (clobber (match_operand:DI 9 "register_operand" "=r"))
2279    (clobber (match_operand:DI 10 "register_operand" "=r"))
2280    (clobber (match_operand:SI 11 "register_operand" "=r"))
2281    (clobber (match_operand:SI 12 "register_operand" "=r"))
2282    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2283   "TARGET_SHMEDIA"
2284   "#"
2285   "&& no_new_pseudos"
2286   [(pc)]
2287   "
2290   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2291   r0: scratch0  r19: scratch1 r21: scratch2
2293   muls.l r18, r4, r25 // s32.30
2294  muls.l r19, r4, r19  // s15.30
2295  shari r25, 63, r21
2296   shari r19, 14, r19  // s18.-14
2297  sub r25, r19, r0
2298  shard r0, r1, r0
2299  sub r0, r21, r0
2302   rtx result = operands[0];
2303   rtx dividend = operands[1];
2304   rtx inv1 = operands[2];
2305   rtx inv2 = operands[3];
2306   rtx shift = operands[4];
2307   rtx scratch0 = operands[7];
2308   rtx scratch1 = operands[8];
2309   rtx scratch2 = operands[9];
2311   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2312   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2313   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2314   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2315   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2316   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2317   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2318   DONE;
2321 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2322 ;; inv1: tab_base, tab_ix, norm32
2323 ;; inv2: norm32, inv1, i92
2324 (define_insn_and_split "divsi_inv_m1_3"
2325   [(set (match_operand:SI 0 "register_operand" "=r")
2326         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2327                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2328                                 (match_operand:DI 3 "register_operand" "r")
2329                                 (match_operand:SI 4 "register_operand" "r")]
2330                      UNSPEC_DIV_INV_M1)
2331                     (unspec:SI [(match_dup 4)
2332                                 (unspec:SI [(match_dup 2)
2333                                             (match_dup 3)
2334                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2335                                 (match_operand:SI 5 "" "")]
2336                      UNSPEC_DIV_INV_M2)
2337                     (match_operand:DI 6 "register_operand" "r")
2338                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2339                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2340          UNSPEC_DIV_INV_M3))
2341    (clobber (match_operand:DI 9 "register_operand" "=r"))
2342    (clobber (match_operand:DI 10 "register_operand" "=r"))
2343    (clobber (match_operand:DI 11 "register_operand" "=r"))
2344    (clobber (match_operand:DI 12 "register_operand" "=r"))
2345    (clobber (match_operand:SI 13 "register_operand" "=r"))
2346    (clobber (match_operand:SI 14 "register_operand" "=r"))
2347    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2348   "TARGET_SHMEDIA
2349    && (TARGET_DIVIDE_INV_MINLAT
2350        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2351   "#"
2352   "&& no_new_pseudos"
2353   [(pc)]
2354   "
2356   rtx result = operands[0];
2357   rtx dividend = operands[1];
2358   rtx tab_base = operands[2];
2359   rtx tab_ix = operands[3];
2360   rtx norm32 = operands[4];
2361   /* rtx i92 = operands[5]; */
2362   rtx shift = operands[6];
2363   rtx i2p27 = operands[7];
2364   rtx i43 = operands[8];
2365   rtx scratch0 = operands[9];
2366   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2367   rtx scratch1 = operands[10];
2368   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2369   rtx scratch2 = operands[11];
2370   rtx scratch3 = operands[12];
2371   rtx scratch4 = operands[13];
2372   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2373   rtx scratch5 = operands[14];
2374   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2375   rtx scratch6 = operands[15];
2377   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2378                                scratch0, scratch1));
2379   /* inv0 == scratch4 */
2380   if (! TARGET_DIVIDE_INV20U)
2381     {
2382       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2383       i2p27 = scratch0;
2384       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2385     }
2386   else
2387     {
2388       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2389       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2390     }
2391   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2392   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2393   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2394   /* inv1 == scratch4 */
2396   if (TARGET_DIVIDE_INV_MINLAT)
2397     {
2398       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2399       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2400       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2401       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2402       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2403       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2404       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2405       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2406       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2407       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2408       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2409     }
2410   else
2411     {
2412       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2413       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2414       emit_insn (gen_nsbdi (scratch6,
2415                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2416       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2417       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2418       emit_insn (gen_divsi_inv20 (scratch2,
2419                                   norm32, scratch4, dividend,
2420                                   scratch6, scratch3, i43,
2421                                   /* scratch0 may be shared with i2p27.  */
2422                                   scratch0, scratch1, scratch5,
2423                                   label, label, i2p27));
2424     }
2425   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2426   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2427   DONE;
2430 (define_insn "divsi_inv20"
2431   [(set (match_operand:DI 0 "register_operand" "=&r")
2432         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2433                     (match_operand:SI 2 "register_operand" "r")
2434                     (match_operand:SI 3 "register_operand" "r")
2435                     (match_operand:DI 4 "register_operand" "r")
2436                     (match_operand:DI 5 "register_operand" "r")
2437                     (match_operand:DI 6 "register_operand" "r")
2438                     (match_operand:DI 12 "register_operand" "r")
2439                     (match_operand 10 "target_operand" "b")
2440                     (match_operand 11 "immediate_operand" "i")]
2441          UNSPEC_DIV_INV20))
2442    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2443    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2444    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2445   "TARGET_SHMEDIA
2446    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2447   "*
2449 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2450              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2451              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2452              %10 label (tr), %11 label (imm)
2454  muls.l inv1, norm32, scratch0  // s2.60
2455   muls.l inv1, dividend, result // s32.30
2456   xor i2p27, result_sign, round_scratch
2457  bge/u dividend_nsb, i43, tr.. (label)
2458  shari scratch0, 16, scratch0   // s-16.44
2459  muls.l sratch0_si, inv1, scratch0 // s-16.74
2460   sub result, round_scratch, result
2461   shari dividend, 14, scratch1   // s19.-14
2462  shari scratch0, 30, scratch0   // s-16.44
2463  muls.l scratch0, scratch1, round_scratch // s15.30
2464 label:
2465  sub result, round_scratch, result */
2467   int likely = TARGET_DIVIDE_INV20L;
2469   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2470   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2471   output_asm_insn (likely
2472                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2473                    : \"bge/u\t%4, %6, %10\", operands);
2474   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2475   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2476   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2477   return (likely
2478           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2479           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2482 (define_insn_and_split "divsi_inv_fp"
2483   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2484         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2485                 (match_operand:SI 2 "register_operand" "rf")))
2486    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2487    (clobber (match_operand:SI 4 "register_operand" "=r"))
2488    (clobber (match_operand:SI 5 "register_operand" "=r"))
2489    (clobber (match_operand:DF 6 "register_operand" "=r"))
2490    (clobber (match_operand:DF 7 "register_operand" "=r"))
2491    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2492   "TARGET_SHMEDIA_FPU"
2493   "#"
2494   "&& (high_life_started || reload_completed)"
2495   [(set (match_dup 0) (match_dup 3))]
2496   ""
2497   [(set_attr "highpart" "must_split")])
2499 ;; If a matching group of divide-by-inverse instructions is in the same
2500 ;; basic block after gcse & loop optimizations, we want to transform them
2501 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2502 (define_insn_and_split "*divsi_inv_fp_combine"
2503   [(set (match_operand:SI 0 "register_operand" "=f")
2504         (div:SI (match_operand:SI 1 "register_operand" "f")
2505                 (match_operand:SI 2 "register_operand" "f")))
2506    (use (unspec:SI [(match_dup 1)
2507                     (match_operand:SI 3 "" "")
2508                     (unspec:SI [(match_operand:SI 4 "" "")
2509                                 (match_dup 3)
2510                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2511                     (match_operand:DI 6 "" "")
2512                     (const_int 0)
2513                     (const_int 0)] UNSPEC_DIV_INV_M3))
2514    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2515    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2516    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2517    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2518    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2519   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2520   "#"
2521   "&& 1"
2522   [(set (match_dup 9) (float:DF (match_dup 1)))
2523    (set (match_dup 10) (float:DF (match_dup 2)))
2524    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2525    (set (match_dup 8)
2526         (fix:SI (match_dup 11)))
2527    (set (match_dup 0) (match_dup 8))]
2528   "
2530   if (! fp_arith_reg_operand (operands[1], SImode))
2531     {
2532       emit_move_insn (operands[7], operands[1]);
2533       operands[1] = operands[7];
2534     }
2535   if (! fp_arith_reg_operand (operands[2], SImode))
2536     {
2537       emit_move_insn (operands[8], operands[2]);
2538       operands[2] = operands[8];
2539     }
2541   [(set_attr "highpart" "must_split")])
2543 ;; -------------------------------------------------------------------------
2544 ;; Multiplication instructions
2545 ;; -------------------------------------------------------------------------
2547 (define_insn "umulhisi3_i"
2548   [(set (reg:SI MACL_REG)
2549         (mult:SI (zero_extend:SI
2550                   (match_operand:HI 0 "arith_reg_operand" "r"))
2551                  (zero_extend:SI
2552                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2553   "TARGET_SH1"
2554   "mulu.w       %1,%0"
2555   [(set_attr "type" "smpy")])
2557 (define_insn "mulhisi3_i"
2558   [(set (reg:SI MACL_REG)
2559         (mult:SI (sign_extend:SI
2560                   (match_operand:HI 0 "arith_reg_operand" "r"))
2561                  (sign_extend:SI
2562                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2563   "TARGET_SH1"
2564   "muls.w       %1,%0"
2565   [(set_attr "type" "smpy")])
2567 (define_expand "mulhisi3"
2568   [(set (reg:SI MACL_REG)
2569         (mult:SI (sign_extend:SI
2570                   (match_operand:HI 1 "arith_reg_operand" ""))
2571                  (sign_extend:SI
2572                   (match_operand:HI 2 "arith_reg_operand" ""))))
2573    (set (match_operand:SI 0 "arith_reg_operand" "")
2574         (reg:SI MACL_REG))]
2575   "TARGET_SH1"
2576   "
2578   rtx first, last;
2580   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2581   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2582   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2583      invariant code motion can move it.  */
2584   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2585   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2586   /* expand_binop can't find a suitable code in umul_widen_optab to
2587      make a REG_EQUAL note from, so make one here.
2588      See also smulsi3_highpart.
2589      ??? Alternatively, we could put this at the calling site of expand_binop,
2590      i.e. expand_expr.  */
2591   REG_NOTES (last)
2592     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2593                          REG_NOTES (last));
2594   DONE;
2597 (define_expand "umulhisi3"
2598   [(set (reg:SI MACL_REG)
2599         (mult:SI (zero_extend:SI
2600                   (match_operand:HI 1 "arith_reg_operand" ""))
2601                  (zero_extend:SI
2602                   (match_operand:HI 2 "arith_reg_operand" ""))))
2603    (set (match_operand:SI 0 "arith_reg_operand" "")
2604         (reg:SI MACL_REG))]
2605   "TARGET_SH1"
2606   "
2608   rtx first, last;
2610   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2611   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2612   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2613      invariant code motion can move it.  */
2614   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2615   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2616   /* expand_binop can't find a suitable code in umul_widen_optab to
2617      make a REG_EQUAL note from, so make one here.
2618      See also smulsi3_highpart.
2619      ??? Alternatively, we could put this at the calling site of expand_binop,
2620      i.e. expand_expr.  */
2621   REG_NOTES (last)
2622     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2623                          REG_NOTES (last));
2624   DONE;
2627 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2628 ;; a call to a routine which clobbers known registers.
2630 (define_insn ""
2631   [(set (match_operand:SI 1 "register_operand" "=z")
2632         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2633    (clobber (reg:SI MACL_REG))
2634    (clobber (reg:SI T_REG))
2635    (clobber (reg:SI PR_REG))
2636    (clobber (reg:SI R3_REG))
2637    (clobber (reg:SI R2_REG))
2638    (clobber (reg:SI R1_REG))
2639    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2640   "TARGET_SH1"
2641   "jsr  @%0%#"
2642   [(set_attr "type" "sfunc")
2643    (set_attr "needs_delay_slot" "yes")])
2645 (define_expand "mulsi3_call"
2646   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2647    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2648    (parallel[(set (match_operand:SI 0 "register_operand" "")
2649                   (mult:SI (reg:SI R4_REG)
2650                            (reg:SI R5_REG)))
2651              (clobber (reg:SI MACL_REG))
2652              (clobber (reg:SI T_REG))
2653              (clobber (reg:SI PR_REG))
2654              (clobber (reg:SI R3_REG))
2655              (clobber (reg:SI R2_REG))
2656              (clobber (reg:SI R1_REG))
2657              (use (match_operand:SI 3 "register_operand" ""))])]
2658   "TARGET_SH1"
2659   "")
2661 (define_insn "mul_r"
2662   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2663         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2664                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2665   "TARGET_SH2A"
2666   "mulr %2,%0"
2667   [(set_attr "type" "dmpy")])
2669 (define_insn "mul_l"
2670   [(set (reg:SI MACL_REG)
2671         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2672                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2673   "TARGET_SH2"
2674   "mul.l        %1,%0"
2675   [(set_attr "type" "dmpy")])
2677 (define_expand "mulsi3"
2678   [(set (reg:SI MACL_REG)
2679         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2680                   (match_operand:SI 2 "arith_reg_operand" "")))
2681    (set (match_operand:SI 0 "arith_reg_operand" "")
2682         (reg:SI MACL_REG))]
2683   "TARGET_SH1"
2684   "
2686   rtx first, last;
2688   if (!TARGET_SH2)
2689     {
2690       /* The address must be set outside the libcall,
2691          since it goes into a pseudo.  */
2692       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2693       rtx addr = force_reg (SImode, sym);
2694       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2695                                    operands[2], addr);
2696       first = insns;
2697       last = emit_insn (insns);
2698     }
2699   else
2700     {
2701       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2703       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2704       /* consec_sets_giv can only recognize the first insn that sets a
2705          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2706          note.  */
2707       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2708     }
2709   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2710      invariant code motion can move it.  */
2711   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2712   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2713   DONE;
2716 (define_insn "mulsidi3_i"
2717   [(set (reg:SI MACH_REG)
2718         (truncate:SI
2719          (lshiftrt:DI
2720           (mult:DI
2721            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2722            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2723           (const_int 32))))
2724    (set (reg:SI MACL_REG)
2725         (mult:SI (match_dup 0)
2726                  (match_dup 1)))]
2727   "TARGET_SH2"
2728   "dmuls.l      %1,%0"
2729   [(set_attr "type" "dmpy")])
2731 (define_expand "mulsidi3"
2732   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2733         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2734                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2735   "TARGET_SH2 || TARGET_SHMEDIA"
2736   "
2738   if (TARGET_SH2)
2739     {
2740        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2741                                         operands[2]));
2742        DONE;
2743     }
2746 (define_insn "mulsidi3_media"
2747   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2748         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2749                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2750   "TARGET_SHMEDIA"
2751   "muls.l       %1, %2, %0"
2752   [(set_attr "type" "dmpy_media")
2753    (set_attr "highpart" "ignore")])
2755 (define_insn "mulsidi3_compact"
2756   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2757         (mult:DI
2758          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2759          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2760    (clobber (reg:SI MACH_REG))
2761    (clobber (reg:SI MACL_REG))]
2762   "TARGET_SH2"
2763   "#")
2765 (define_split
2766   [(set (match_operand:DI 0 "arith_reg_dest" "")
2767         (mult:DI
2768          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2769          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2770    (clobber (reg:SI MACH_REG))
2771    (clobber (reg:SI MACL_REG))]
2772   "TARGET_SH2"
2773   [(const_int 0)]
2774   "
2776   rtx low_dst = gen_lowpart (SImode, operands[0]);
2777   rtx high_dst = gen_highpart (SImode, operands[0]);
2779   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2781   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2782   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2783   /* We need something to tag the possible REG_EQUAL notes on to.  */
2784   emit_move_insn (operands[0], operands[0]);
2785   DONE;
2788 (define_insn "umulsidi3_i"
2789   [(set (reg:SI MACH_REG)
2790         (truncate:SI
2791          (lshiftrt:DI
2792           (mult:DI
2793            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2794            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2795           (const_int 32))))
2796    (set (reg:SI MACL_REG)
2797         (mult:SI (match_dup 0)
2798                  (match_dup 1)))]
2799   "TARGET_SH2"
2800   "dmulu.l      %1,%0"
2801   [(set_attr "type" "dmpy")])
2803 (define_expand "umulsidi3"
2804   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2805         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2806                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2807   "TARGET_SH2 || TARGET_SHMEDIA"
2808   "
2810   if (TARGET_SH2)
2811     {
2812        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2813                                          operands[2]));
2814        DONE;
2815     }
2818 (define_insn "umulsidi3_media"
2819   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2820         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2821                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2822   "TARGET_SHMEDIA"
2823   "mulu.l       %1, %2, %0"
2824   [(set_attr "type" "dmpy_media")
2825    (set_attr "highpart" "ignore")])
2827 (define_insn "umulsidi3_compact"
2828   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2829         (mult:DI
2830          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2831          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2832    (clobber (reg:SI MACH_REG))
2833    (clobber (reg:SI MACL_REG))]
2834   "TARGET_SH2"
2835   "#")
2837 (define_split
2838   [(set (match_operand:DI 0 "arith_reg_dest" "")
2839         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2840                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2841    (clobber (reg:SI MACH_REG))
2842    (clobber (reg:SI MACL_REG))]
2843   "TARGET_SH2"
2844   [(const_int 0)]
2845   "
2847   rtx low_dst = gen_lowpart (SImode, operands[0]);
2848   rtx high_dst = gen_highpart (SImode, operands[0]);
2850   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2852   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2853   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2854   /* We need something to tag the possible REG_EQUAL notes on to.  */
2855   emit_move_insn (operands[0], operands[0]);
2856   DONE;
2859 (define_insn "smulsi3_highpart_i"
2860   [(set (reg:SI MACH_REG)
2861         (truncate:SI
2862          (lshiftrt:DI
2863           (mult:DI
2864            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2865            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2866           (const_int 32))))
2867    (clobber (reg:SI MACL_REG))]
2868   "TARGET_SH2"
2869   "dmuls.l      %1,%0"
2870   [(set_attr "type" "dmpy")])
2872 (define_expand "smulsi3_highpart"
2873   [(parallel
2874     [(set (reg:SI MACH_REG)
2875           (truncate:SI
2876            (lshiftrt:DI
2877             (mult:DI
2878              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2879              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2880             (const_int 32))))
2881     (clobber (reg:SI MACL_REG))])
2882    (set (match_operand:SI 0 "arith_reg_operand" "")
2883         (reg:SI MACH_REG))]
2884   "TARGET_SH2"
2885   "
2887   rtx first, last;
2889   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2890   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2891   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2892      invariant code motion can move it.  */
2893   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2894   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2895   /* expand_binop can't find a suitable code in mul_highpart_optab to
2896      make a REG_EQUAL note from, so make one here.
2897      See also {,u}mulhisi.
2898      ??? Alternatively, we could put this at the calling site of expand_binop,
2899      i.e. expand_mult_highpart.  */
2900   REG_NOTES (last)
2901     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2902                          REG_NOTES (last));
2903   DONE;
2906 (define_insn "umulsi3_highpart_i"
2907   [(set (reg:SI MACH_REG)
2908         (truncate:SI
2909          (lshiftrt:DI
2910           (mult:DI
2911            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2912            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2913           (const_int 32))))
2914    (clobber (reg:SI MACL_REG))]
2915   "TARGET_SH2"
2916   "dmulu.l      %1,%0"
2917   [(set_attr "type" "dmpy")])
2919 (define_expand "umulsi3_highpart"
2920   [(parallel
2921     [(set (reg:SI MACH_REG)
2922           (truncate:SI
2923            (lshiftrt:DI
2924             (mult:DI
2925              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2926              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2927             (const_int 32))))
2928     (clobber (reg:SI MACL_REG))])
2929    (set (match_operand:SI 0 "arith_reg_operand" "")
2930         (reg:SI MACH_REG))]
2931   "TARGET_SH2"
2932   "
2934   rtx first, last;
2936   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2937   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2938   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2939      invariant code motion can move it.  */
2940   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2941   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2942   DONE;
2945 (define_insn_and_split "muldi3"
2946   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2947         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2948                  (match_operand:DI 2 "arith_reg_operand" "r")))
2949    (clobber (match_scratch:DI 3 "=&r"))
2950    (clobber (match_scratch:DI 4 "=r"))]
2951   "TARGET_SHMEDIA"
2952   "#"
2953   "reload_completed"
2954   [(const_int 0)]
2955   "
2957   rtx op3_v2si, op2_v2si;
2959   op3_v2si = operands[3];
2960   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2961     {
2962       op3_v2si = XEXP (op3_v2si, 0);
2963       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2964     }
2965   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2966   op2_v2si = operands[2];
2967   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2968     {
2969       op2_v2si = XEXP (op2_v2si, 0);
2970       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2971     }
2972   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2973   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2974   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2975   emit_insn (gen_umulsidi3_media (operands[4],
2976                                  sh_gen_truncate (SImode, operands[1], 0),
2977                                  sh_gen_truncate (SImode, operands[2], 0)));
2978   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2979   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2980   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2981   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2982   DONE;
2986 ;; -------------------------------------------------------------------------
2987 ;; Logical operations
2988 ;; -------------------------------------------------------------------------
2990 (define_insn "*andsi3_compact"
2991   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2992         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2993                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2994   "TARGET_SH1"
2995   "and  %2,%0"
2996   [(set_attr "type" "arith")])
2998 (define_insn "*andsi3_media"
2999   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3000         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3001                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3002   "TARGET_SHMEDIA"
3003   "@
3004         and     %1, %2, %0
3005         andi    %1, %2, %0"
3006   [(set_attr "type" "arith_media")])
3008 ;; If the constant is 255, then emit an extu.b instruction instead of an
3009 ;; and, since that will give better code.
3011 (define_expand "andsi3"
3012   [(set (match_operand:SI 0 "arith_reg_operand" "")
3013         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3014                 (match_operand:SI 2 "logical_operand" "")))]
3015   ""
3016   "
3018   if (TARGET_SH1
3019       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3020     {
3021       emit_insn (gen_zero_extendqisi2 (operands[0],
3022                                        gen_lowpart (QImode, operands[1])));
3023       DONE;
3024     }
3027 (define_insn_and_split "anddi3"
3028   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3029         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3030                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3031   "TARGET_SHMEDIA"
3032   "@
3033         and     %1, %2, %0
3034         andi    %1, %2, %0
3035         #"
3036   "reload_completed
3037    && ! logical_operand (operands[2], DImode)"
3038   [(const_int 0)]
3039   "
3041   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3042     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3043   else
3044     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3045   DONE;
3047   [(set_attr "type" "arith_media")])
3049 (define_insn "andcsi3"
3050   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3051         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3052                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3053   "TARGET_SHMEDIA"
3054   "andc %1,%2,%0"
3055   [(set_attr "type" "arith_media")])
3057 (define_insn "andcdi3"
3058   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3059         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3060                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3061   "TARGET_SHMEDIA"
3062   "andc %1,%2,%0"
3063   [(set_attr "type" "arith_media")])
3065 (define_expand "iorsi3"
3066   [(set (match_operand:SI 0 "arith_reg_operand" "")
3067         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3068                 (match_operand:SI 2 "logical_operand" "")))]
3069   ""
3070   "")
3072 (define_insn "*iorsi3_compact"
3073   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3074         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3075                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3076   "TARGET_SH1"
3077   "or   %2,%0"
3078   [(set_attr "type" "arith")])
3080 (define_insn "*iorsi3_media"
3081   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3082         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3083                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3084   "TARGET_SHMEDIA"
3085   "@
3086         or      %1, %2, %0
3087         ori     %1, %2, %0"
3088   [(set_attr "type" "arith_media")])
3090 (define_insn "iordi3"
3091   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3092         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3093                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3094   "TARGET_SHMEDIA"
3095   "@
3096         or      %1, %2, %0
3097         ori     %1, %2, %0"
3098   [(set_attr "type" "arith_media")])
3100 (define_insn_and_split "*logical_sidi3"
3101   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3102         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3103                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3104                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3105   "TARGET_SHMEDIA"
3106   "#"
3107   "&& reload_completed"
3108   [(set (match_dup 0) (match_dup 3))]
3109   "
3111   operands[3]
3112     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3113                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3114                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3117 (define_insn_and_split "*logical_sidisi3"
3118   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3119         (truncate:SI (sign_extend:DI
3120                         (match_operator:SI 3 "logical_operator"
3121                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3122                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3123   "TARGET_SHMEDIA"
3124   "#"
3125   "&& 1"
3126   [(set (match_dup 0) (match_dup 3))])
3128 (define_insn_and_split "*logical_sidi3_2"
3129   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3130         (sign_extend:DI (truncate:SI (sign_extend:DI
3131                         (match_operator:SI 3 "logical_operator"
3132                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3133                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3134   "TARGET_SHMEDIA"
3135   "#"
3136   "&& 1"
3137   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3139 (define_expand "xorsi3"
3140   [(set (match_operand:SI 0 "arith_reg_operand" "")
3141         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3142                 (match_operand:SI 2 "xor_operand" "")))]
3143   ""
3144   "")
3146 (define_insn "*xorsi3_compact"
3147   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3148         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3149                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3150   "TARGET_SH1"
3151   "xor  %2,%0"
3152   [(set_attr "type" "arith")])
3154 (define_insn "*xorsi3_media"
3155   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3156         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3157                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3158   "TARGET_SHMEDIA"
3159   "@
3160         xor     %1, %2, %0
3161         xori    %1, %2, %0"
3162   [(set_attr "type" "arith_media")])
3164 (define_insn "xordi3"
3165   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3166         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3167                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3168   "TARGET_SHMEDIA"
3169   "@
3170         xor     %1, %2, %0
3171         xori    %1, %2, %0"
3172   [(set_attr "type" "arith_media")])
3174 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3175 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3176 (define_split
3177   [(set (match_operand:DI 0 "arith_reg_dest" "")
3178         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3179                           [(match_operand 1 "any_register_operand" "")
3180                            (match_operand 2 "any_register_operand" "")])))]
3181   "TARGET_SHMEDIA"
3182   [(set (match_dup 5) (match_dup 4))
3183    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3186   enum machine_mode inmode = GET_MODE (operands[1]);
3187   int offset = 0;
3189   if (GET_CODE (operands[0]) == SUBREG)
3190     {
3191       offset = SUBREG_BYTE (operands[0]);
3192       operands[0] = SUBREG_REG (operands[0]);
3193     }
3194   gcc_assert (GET_CODE (operands[0]) == REG);
3195   if (! TARGET_LITTLE_ENDIAN)
3196     offset += 8 - GET_MODE_SIZE (inmode);
3197   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3200 ;; -------------------------------------------------------------------------
3201 ;; Shifts and rotates
3202 ;; -------------------------------------------------------------------------
3204 (define_expand "rotldi3"
3205   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3206         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3207                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3208   "TARGET_SHMEDIA"
3209   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3211 (define_insn "rotldi3_mextr"
3212   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3213         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3214                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3215   "TARGET_SHMEDIA"
3216   "*
3218   static char templ[16];
3220   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3221            8 - (int) (INTVAL (operands[2]) >> 3));
3222   return templ;
3224   [(set_attr "type" "arith_media")])
3226 (define_expand "rotrdi3"
3227   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3228         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3229                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3230   "TARGET_SHMEDIA"
3231   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3233 (define_insn "rotrdi3_mextr"
3234   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3235         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3236                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3237   "TARGET_SHMEDIA"
3238   "*
3240   static char templ[16];
3242   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3243   return templ;
3245   [(set_attr "type" "arith_media")])
3247 (define_split
3248   [(set (match_operand:DI 0 "arith_reg_dest" "")
3249         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3250                                          "ua_address_operand" "")))
3251                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3252                            (const_int 8))))
3253    (clobber (match_operand:DI 3 "register_operand" ""))]
3254   "TARGET_SHMEDIA"
3255   [(match_dup 4) (match_dup 5)]
3256   "
3258   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3259                  (operands[3], operands[1]));
3260   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3261                               GEN_INT (56), GEN_INT (8));
3264 (define_insn "rotlsi3_1"
3265   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3266         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3267                    (const_int 1)))
3268    (set (reg:SI T_REG)
3269         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3270   "TARGET_SH1"
3271   "rotl %0"
3272   [(set_attr "type" "arith")])
3274 (define_insn "rotlsi3_31"
3275   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3276         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3277                    (const_int 31)))
3278    (clobber (reg:SI T_REG))]
3279   "TARGET_SH1"
3280   "rotr %0"
3281   [(set_attr "type" "arith")])
3283 (define_insn "rotlsi3_16"
3284   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3285         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3286                    (const_int 16)))]
3287   "TARGET_SH1"
3288   "swap.w       %1,%0"
3289   [(set_attr "type" "arith")])
3291 (define_expand "rotlsi3"
3292   [(set (match_operand:SI 0 "arith_reg_dest" "")
3293         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3294                    (match_operand:SI 2 "immediate_operand" "")))]
3295   "TARGET_SH1"
3296   "
3298   static const char rot_tab[] = {
3299     000, 000, 000, 000, 000, 000, 010, 001,
3300     001, 001, 011, 013, 003, 003, 003, 003,
3301     003, 003, 003, 003, 003, 013, 012, 002,
3302     002, 002, 010, 000, 000, 000, 000, 000,
3303   };
3305   int count, choice;
3307   if (GET_CODE (operands[2]) != CONST_INT)
3308     FAIL;
3309   count = INTVAL (operands[2]);
3310   choice = rot_tab[count];
3311   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3312     FAIL;
3313   choice &= 7;
3314   switch (choice)
3315     {
3316     case 0:
3317       emit_move_insn (operands[0], operands[1]);
3318       count -= (count & 16) * 2;
3319       break;
3320     case 3:
3321      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3322      count -= 16;
3323      break;
3324     case 1:
3325     case 2:
3326       {
3327         rtx parts[2];
3328         parts[0] = gen_reg_rtx (SImode);
3329         parts[1] = gen_reg_rtx (SImode);
3330         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3331         emit_move_insn (parts[choice-1], operands[1]);
3332         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3333         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3334         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3335         count = (count & ~16) - 8;
3336       }
3337     }
3339   for (; count > 0; count--)
3340     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3341   for (; count < 0; count++)
3342     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3344   DONE;
3347 (define_insn "*rotlhi3_8"
3348   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3349         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3350                    (const_int 8)))]
3351   "TARGET_SH1"
3352   "swap.b       %1,%0"
3353   [(set_attr "type" "arith")])
3355 (define_expand "rotlhi3"
3356   [(set (match_operand:HI 0 "arith_reg_operand" "")
3357         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3358                    (match_operand:HI 2 "immediate_operand" "")))]
3359   "TARGET_SH1"
3360   "
3362   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3363     FAIL;
3367 ;; shift left
3369 (define_insn "ashlsi3_sh2a"
3370   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3371         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3372                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3373   "TARGET_SH2A"
3374   "shad %2,%0"
3375   [(set_attr "type" "arith")
3376    (set_attr "length" "4")])
3378 ;; This pattern is used by init_expmed for computing the costs of shift
3379 ;; insns.
3381 (define_insn_and_split "ashlsi3_std"
3382   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3383         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3384                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3385    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3386   "TARGET_SH3
3387    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3388        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3389   "@
3390    shld %2,%0
3391    add  %0,%0
3392    shll%O2      %0
3393    #"
3394   "TARGET_SH3
3395    && reload_completed
3396    && GET_CODE (operands[2]) == CONST_INT
3397    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3398   [(set (match_dup 3) (match_dup 2))
3399    (parallel
3400     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3401      (clobber (match_dup 4))])]
3402   "operands[4] = gen_rtx_SCRATCH (SImode);"
3403   [(set_attr "length" "*,*,*,4")
3404    (set_attr "type" "dyn_shift,arith,arith,arith")])
3406 (define_insn "ashlhi3_k"
3407   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3408         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3409                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3410   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3411   "@
3412         add     %0,%0
3413         shll%O2 %0"
3414   [(set_attr "type" "arith")])
3416 (define_insn "ashlsi3_n"
3417   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3418         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3419                    (match_operand:SI 2 "const_int_operand" "n")))
3420    (clobber (reg:SI T_REG))]
3421   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3422   "#"
3423   [(set (attr "length")
3424         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3425                (const_string "2")
3426                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3427                (const_string "4")
3428                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3429                (const_string "6")]
3430               (const_string "8")))
3431    (set_attr "type" "arith")])
3433 (define_split
3434   [(set (match_operand:SI 0 "arith_reg_dest" "")
3435         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3436                    (match_operand:SI 2 "const_int_operand" "")))
3437    (clobber (reg:SI T_REG))]
3438   "TARGET_SH1 && reload_completed"
3439   [(use (reg:SI R0_REG))]
3440   "
3442   gen_shifty_op (ASHIFT, operands);
3443   DONE;
3446 (define_insn "ashlsi3_media"
3447   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3448         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3449                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3450   "TARGET_SHMEDIA"
3451   "@
3452         shlld.l %1, %2, %0
3453         shlli.l %1, %2, %0"
3454   [(set_attr "type" "arith_media")
3455    (set_attr "highpart" "ignore")])
3457 (define_expand "ashlsi3"
3458   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3459                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3460                               (match_operand:SI 2 "nonmemory_operand" "")))
3461               (clobber (reg:SI T_REG))])]
3462   ""
3463   "
3465   if (TARGET_SHMEDIA)
3466     {
3467       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3468       DONE;
3469     }
3470   if (GET_CODE (operands[2]) == CONST_INT
3471       && sh_dynamicalize_shift_p (operands[2]))
3472     operands[2] = force_reg (SImode, operands[2]);
3473   if (TARGET_SH3)
3474     {
3475       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3476       DONE;
3477     }
3478   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3479     FAIL;
3482 (define_insn "*ashlhi3_n"
3483   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3484         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3485                    (match_operand:HI 2 "const_int_operand" "n")))
3486    (clobber (reg:SI T_REG))]
3487   "TARGET_SH1"
3488   "#"
3489   [(set (attr "length")
3490         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3491                (const_string "2")
3492                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3493                (const_string "4")]
3494               (const_string "6")))
3495    (set_attr "type" "arith")])
3497 (define_expand "ashlhi3"
3498   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3499                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3500                               (match_operand:SI 2 "nonmemory_operand" "")))
3501               (clobber (reg:SI T_REG))])]
3502   "TARGET_SH1"
3503   "
3505   if (GET_CODE (operands[2]) != CONST_INT)
3506     FAIL;
3507   /* It may be possible to call gen_ashlhi3 directly with more generic
3508      operands.  Make sure operands[1] is a HImode register here.  */
3509   if (!arith_reg_operand (operands[1], HImode))
3510     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3513 (define_split
3514   [(set (match_operand:HI 0 "arith_reg_dest" "")
3515         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3516                    (match_operand:HI 2 "const_int_operand" "")))
3517    (clobber (reg:SI T_REG))]
3518   "TARGET_SH1 && reload_completed"
3519   [(use (reg:SI R0_REG))]
3520   "
3522   gen_shifty_hi_op (ASHIFT, operands);
3523   DONE;
3527 ; arithmetic shift right
3530 (define_insn "ashrsi3_sh2a"
3531   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3532         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3533                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3534   "TARGET_SH2A"
3535   "shad %2,%0"
3536   [(set_attr "type" "dyn_shift")
3537    (set_attr "length" "4")])
3539 (define_insn "ashrsi3_k"
3540   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3541         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3542                      (match_operand:SI 2 "const_int_operand" "M")))
3543    (clobber (reg:SI T_REG))]
3544   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3545   "shar %0"
3546   [(set_attr "type" "arith")])
3548 ;; We can't do HImode right shifts correctly unless we start out with an
3549 ;; explicit zero / sign extension; doing that would result in worse overall
3550 ;; code, so just let the machine independent code widen the mode.
3551 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3554 ;; ??? This should be a define expand.
3556 (define_insn "ashrsi2_16"
3557   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3558         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3559                      (const_int 16)))]
3560   "TARGET_SH1"
3561   "#"
3562   [(set_attr "length" "4")])
3564 (define_split
3565   [(set (match_operand:SI 0 "arith_reg_dest" "")
3566         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3567                      (const_int 16)))]
3568   "TARGET_SH1"
3569   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3570    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3571   "operands[2] = gen_lowpart (HImode, operands[0]);")
3573 ;; ??? This should be a define expand.
3575 (define_insn "ashrsi2_31"
3576   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3577         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3578                      (const_int 31)))
3579    (clobber (reg:SI T_REG))]
3580   "TARGET_SH1"
3581   "#"
3582   [(set_attr "length" "4")])
3584 (define_split
3585   [(set (match_operand:SI 0 "arith_reg_dest" "")
3586         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3587                      (const_int 31)))
3588    (clobber (reg:SI T_REG))]
3589   "TARGET_SH1"
3590   [(const_int 0)]
3591   "
3593   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3594   emit_insn (gen_mov_neg_si_t (operands[0]));
3595   DONE;
3598 (define_peephole2
3599   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3600    (set (reg:SI T_REG)
3601         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3602   "TARGET_SH1
3603    && peep2_reg_dead_p (2, operands[0])
3604    && peep2_reg_dead_p (2, operands[1])"
3605   [(const_int 0)]
3606   "
3608   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3609   DONE;
3612 (define_insn "ashlsi_c"
3613   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3614         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3615    (set (reg:SI T_REG)
3616         (lt:SI (match_dup 1) (const_int 0)))]
3617   "TARGET_SH1"
3618   "shll %0"
3619   [(set_attr "type" "arith")])
3621 (define_insn "*ashlsi_c_void"
3622   [(set (reg:SI T_REG)
3623         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3624    (clobber (match_scratch:SI 1 "=0"))]
3625   "TARGET_SH1 && cse_not_expected"
3626   "shll %0"
3627   [(set_attr "type" "arith")])
3629 (define_insn "ashrsi3_d"
3630   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3631         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3632                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3633   "TARGET_SH3"
3634   "shad %2,%0"
3635   [(set_attr "type" "dyn_shift")])
3637 (define_insn "ashrsi3_n"
3638   [(set (reg:SI R4_REG)
3639         (ashiftrt:SI (reg:SI R4_REG)
3640                      (match_operand:SI 0 "const_int_operand" "i")))
3641    (clobber (reg:SI T_REG))
3642    (clobber (reg:SI PR_REG))
3643    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3644   "TARGET_SH1"
3645   "jsr  @%1%#"
3646   [(set_attr "type" "sfunc")
3647    (set_attr "needs_delay_slot" "yes")])
3649 (define_insn "ashrsi3_media"
3650   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3651         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3652                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3653   "TARGET_SHMEDIA"
3654   "@
3655         shard.l %1, %2, %0
3656         shari.l %1, %2, %0"
3657   [(set_attr "type" "arith_media")
3658    (set_attr "highpart" "ignore")])
3660 (define_expand "ashrsi3"
3661   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3662                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3663                                 (match_operand:SI 2 "nonmemory_operand" "")))
3664               (clobber (reg:SI T_REG))])]
3665   ""
3666   "
3668   if (TARGET_SHMEDIA)
3669     {
3670       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3671       DONE;
3672     }
3673   if (expand_ashiftrt (operands))
3674     DONE;
3675   else
3676     FAIL;
3679 ;; logical shift right
3681 (define_insn "lshrsi3_sh2a"
3682   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3683         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3684                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3685   "TARGET_SH2A"
3686   "shld %2,%0"
3687   [(set_attr "type" "dyn_shift")
3688    (set_attr "length" "4")])
3690 (define_insn "lshrsi3_d"
3691   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3692         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3693                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3694   "TARGET_SH3"
3695   "shld %2,%0"
3696   [(set_attr "type" "dyn_shift")])
3698 ;;  Only the single bit shift clobbers the T bit.
3700 (define_insn "lshrsi3_m"
3701   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3702         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3703                      (match_operand:SI 2 "const_int_operand" "M")))
3704    (clobber (reg:SI T_REG))]
3705   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3706   "shlr %0"
3707   [(set_attr "type" "arith")])
3709 (define_insn "lshrsi3_k"
3710   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3711         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3712                      (match_operand:SI 2 "const_int_operand" "P27")))]
3713   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3714    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3715   "shlr%O2      %0"
3716   [(set_attr "type" "arith")])
3718 (define_insn "lshrsi3_n"
3719   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3720         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3721                      (match_operand:SI 2 "const_int_operand" "n")))
3722    (clobber (reg:SI T_REG))]
3723   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3724   "#"
3725   [(set (attr "length")
3726         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3727                (const_string "2")
3728                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3729                (const_string "4")
3730                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3731                (const_string "6")]
3732               (const_string "8")))
3733    (set_attr "type" "arith")])
3735 (define_split
3736   [(set (match_operand:SI 0 "arith_reg_dest" "")
3737         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3738                      (match_operand:SI 2 "const_int_operand" "")))
3739    (clobber (reg:SI T_REG))]
3740   "TARGET_SH1 && reload_completed"
3741   [(use (reg:SI R0_REG))]
3742   "
3744   gen_shifty_op (LSHIFTRT, operands);
3745   DONE;
3748 (define_insn "lshrsi3_media"
3749   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3750         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3751                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3752   "TARGET_SHMEDIA"
3753   "@
3754         shlrd.l %1, %2, %0
3755         shlri.l %1, %2, %0"
3756   [(set_attr "type" "arith_media")
3757    (set_attr "highpart" "ignore")])
3759 (define_expand "lshrsi3"
3760   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3761                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3762                                 (match_operand:SI 2 "nonmemory_operand" "")))
3763               (clobber (reg:SI T_REG))])]
3764   ""
3765   "
3767   if (TARGET_SHMEDIA)
3768     {
3769       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3770       DONE;
3771     }
3772   if (GET_CODE (operands[2]) == CONST_INT
3773       && sh_dynamicalize_shift_p (operands[2]))
3774     operands[2] = force_reg (SImode, operands[2]);
3775   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3776     {
3777       rtx count = copy_to_mode_reg (SImode, operands[2]);
3778       emit_insn (gen_negsi2 (count, count));
3779       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3780       DONE;
3781     }
3782   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3783     FAIL;
3786 ;; ??? This should be a define expand.
3788 (define_insn "ashldi3_k"
3789   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3790         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3791                    (const_int 1)))
3792    (clobber (reg:SI T_REG))]
3793   "TARGET_SH1"
3794   "shll %R0\;rotcl      %S0"
3795   [(set_attr "length" "4")
3796    (set_attr "type" "arith")])
3798 (define_insn "ashldi3_media"
3799   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3800         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3801                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3802   "TARGET_SHMEDIA"
3803   "@
3804         shlld   %1, %2, %0
3805         shlli   %1, %2, %0"
3806   [(set_attr "type" "arith_media")])
3808 (define_insn "*ashldisi3_media"
3809   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3810         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3811                    (match_operand:DI 2 "const_int_operand" "n")))]
3812   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3813   "shlli.l      %1, %2, %0"
3814   [(set_attr "type" "arith_media")
3815    (set_attr "highpart" "ignore")])
3817 (define_expand "ashldi3"
3818   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3819                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3820                               (match_operand:DI 2 "immediate_operand" "")))
3821               (clobber (reg:SI T_REG))])]
3822   ""
3823   "
3825   if (TARGET_SHMEDIA)
3826     {
3827       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3828       DONE;
3829     }
3830   if (GET_CODE (operands[2]) != CONST_INT
3831       || INTVAL (operands[2]) != 1)
3832     FAIL;
3835 ;; ??? This should be a define expand.
3837 (define_insn "lshrdi3_k"
3838   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3839         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3840                      (const_int 1)))
3841    (clobber (reg:SI T_REG))]
3842   "TARGET_SH1"
3843   "shlr %S0\;rotcr      %R0"
3844   [(set_attr "length" "4")
3845    (set_attr "type" "arith")])
3847 (define_insn "lshrdi3_media"
3848   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3849         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3850                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3851   "TARGET_SHMEDIA
3852    && (arith_reg_dest (operands[0], DImode)
3853        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3854   "@
3855         shlrd   %1, %2, %0
3856         shlri   %1, %2, %0"
3857   [(set_attr "type" "arith_media")])
3859 (define_insn "*lshrdisi3_media"
3860   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3861         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3862                      (match_operand:DI 2 "const_int_operand" "n")))]
3863   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3864   "shlri.l      %1, %2, %0"
3865   [(set_attr "type" "arith_media")
3866    (set_attr "highpart" "ignore")])
3868 (define_expand "lshrdi3"
3869   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3870                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3871                                (match_operand:DI 2 "immediate_operand" "")))
3872              (clobber (reg:SI T_REG))])]
3873   ""
3874   "
3876   if (TARGET_SHMEDIA)
3877     {
3878       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3879       DONE;
3880     }
3881   if (GET_CODE (operands[2]) != CONST_INT
3882       || INTVAL (operands[2]) != 1)
3883     FAIL;
3886 ;; ??? This should be a define expand.
3888 (define_insn "ashrdi3_k"
3889   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3890         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3891                      (const_int 1)))
3892    (clobber (reg:SI T_REG))]
3893   "TARGET_SH1"
3894   "shar %S0\;rotcr      %R0"
3895   [(set_attr "length" "4")
3896    (set_attr "type" "arith")])
3898 (define_insn "ashrdi3_media"
3899   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3900         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3901                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3902   "TARGET_SHMEDIA
3903    && (arith_reg_dest (operands[0], DImode)
3904        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3905   "@
3906         shard   %1, %2, %0
3907         shari   %1, %2, %0"
3908   [(set_attr "type" "arith_media")])
3910 (define_insn "*ashrdisi3_media"
3911   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3912         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3913                      (match_operand:DI 2 "const_int_operand" "n")))]
3914   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3915   "shari.l      %1, %2, %0"
3916   [(set_attr "type" "arith_media")
3917    (set_attr "highpart" "ignore")])
3919 (define_insn "ashrdisi3_media_high"
3920   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3921         (truncate:SI
3922            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3923                         (match_operand:DI 2 "const_int_operand" "n"))))]
3924   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3925   "shari        %1, %2, %0"
3926   [(set_attr "type" "arith_media")])
3928 (define_insn "ashrdisi3_media_opaque"
3929   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3930         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3931                     (match_operand:DI 2 "const_int_operand" "n")]
3932          UNSPEC_ASHIFTRT))]
3933   "TARGET_SHMEDIA"
3934   "shari        %1, %2, %0"
3935   [(set_attr "type" "arith_media")])
3937 (define_expand "ashrdi3"
3938   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3939                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3940                                 (match_operand:DI 2 "immediate_operand" "")))
3941               (clobber (reg:SI T_REG))])]
3942   ""
3943   "
3945   if (TARGET_SHMEDIA)
3946     {
3947       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3948       DONE;
3949     }
3950   if (GET_CODE (operands[2]) != CONST_INT
3951       || INTVAL (operands[2]) != 1)
3952     FAIL;
3955 ;; combined left/right shift
3957 (define_split
3958   [(set (match_operand:SI 0 "register_operand" "")
3959         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3960                            (match_operand:SI 2 "const_int_operand" ""))
3961                 (match_operand:SI 3 "const_int_operand" "")))]
3962   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3963   [(use (reg:SI R0_REG))]
3964   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3965    DONE;")
3967 (define_split
3968   [(set (match_operand:SI 0 "register_operand" "")
3969         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3970                            (match_operand:SI 2 "const_int_operand" ""))
3971                 (match_operand:SI 3 "const_int_operand" "")))
3972    (clobber (reg:SI T_REG))]
3973   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3974   [(use (reg:SI R0_REG))]
3975   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3976    DONE;")
3978 (define_insn ""
3979   [(set (match_operand:SI 0 "register_operand" "=r")
3980         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3981                            (match_operand:SI 2 "const_int_operand" "n"))
3982                 (match_operand:SI 3 "const_int_operand" "n")))
3983    (clobber (reg:SI T_REG))]
3984   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3985  "#"
3986   [(set (attr "length")
3987         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3988                (const_string "4")
3989                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3990                (const_string "6")
3991                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3992                (const_string "8")
3993                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
3994                (const_string "10")
3995                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
3996                (const_string "12")
3997                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
3998                (const_string "14")
3999                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4000                (const_string "16")]
4001               (const_string "18")))
4002    (set_attr "type" "arith")])
4004 (define_insn ""
4005   [(set (match_operand:SI 0 "register_operand" "=z")
4006         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4007                            (match_operand:SI 2 "const_int_operand" "n"))
4008                 (match_operand:SI 3 "const_int_operand" "n")))
4009    (clobber (reg:SI T_REG))]
4010   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4011  "#"
4012   [(set (attr "length")
4013         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4014                (const_string "4")
4015                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4016                (const_string "6")
4017                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4018                (const_string "8")]
4019               (const_string "10")))
4020    (set_attr "type" "arith")])
4022 ;; shift left / and combination with a scratch register: The combine pass
4023 ;; does not accept the individual instructions, even though they are
4024 ;; cheap.  But it needs a precise description so that it is usable after
4025 ;; reload.
4026 (define_insn "and_shl_scratch"
4027   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4028         (lshiftrt:SI
4029          (ashift:SI
4030           (and:SI
4031            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4032                         (match_operand:SI 2 "const_int_operand" "N,n"))
4033            (match_operand:SI 3 "" "0,r"))
4034           (match_operand:SI 4 "const_int_operand" "n,n"))
4035          (match_operand:SI 5 "const_int_operand" "n,n")))
4036    (clobber (reg:SI T_REG))]
4037   "TARGET_SH1"
4038   "#"
4039   [(set (attr "length")
4040         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4041                (const_string "4")
4042                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4043                (const_string "6")
4044                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4045                (const_string "8")
4046                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4047                (const_string "10")]
4048               (const_string "12")))
4049    (set_attr "type" "arith")])
4051 (define_split
4052   [(set (match_operand:SI 0 "register_operand" "")
4053         (lshiftrt:SI
4054          (ashift:SI
4055           (and:SI
4056            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4057                         (match_operand:SI 2 "const_int_operand" ""))
4058            (match_operand:SI 3 "register_operand" ""))
4059           (match_operand:SI 4 "const_int_operand" ""))
4060          (match_operand:SI 5 "const_int_operand" "")))
4061    (clobber (reg:SI T_REG))]
4062   "TARGET_SH1"
4063   [(use (reg:SI R0_REG))]
4064   "
4066   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4068   if (INTVAL (operands[2]))
4069     {
4070       gen_shifty_op (LSHIFTRT, operands);
4071     }
4072   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4073   operands[2] = operands[4];
4074   gen_shifty_op (ASHIFT, operands);
4075   if (INTVAL (operands[5]))
4076     {
4077       operands[2] = operands[5];
4078       gen_shifty_op (LSHIFTRT, operands);
4079     }
4080   DONE;
4083 ;; signed left/right shift combination.
4084 (define_split
4085   [(set (match_operand:SI 0 "register_operand" "")
4086         (sign_extract:SI
4087          (ashift:SI (match_operand:SI 1 "register_operand" "")
4088                     (match_operand:SI 2 "const_int_operand" ""))
4089          (match_operand:SI 3 "const_int_operand" "")
4090          (const_int 0)))
4091    (clobber (reg:SI T_REG))]
4092   "TARGET_SH1"
4093   [(use (reg:SI R0_REG))]
4094   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4095    DONE;")
4097 (define_insn "shl_sext_ext"
4098   [(set (match_operand:SI 0 "register_operand" "=r")
4099         (sign_extract:SI
4100          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4101                     (match_operand:SI 2 "const_int_operand" "n"))
4102          (match_operand:SI 3 "const_int_operand" "n")
4103          (const_int 0)))
4104    (clobber (reg:SI T_REG))]
4105   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4106   "#"
4107   [(set (attr "length")
4108         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4109                (const_string "2")
4110                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4111                (const_string "4")
4112                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4113                (const_string "6")
4114                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4115                (const_string "8")
4116                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4117                (const_string "10")
4118                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4119                (const_string "12")
4120                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4121                (const_string "14")
4122                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4123                (const_string "16")]
4124               (const_string "18")))
4125     (set_attr "type" "arith")])
4127 (define_insn "shl_sext_sub"
4128   [(set (match_operand:SI 0 "register_operand" "=z")
4129         (sign_extract:SI
4130          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4131                     (match_operand:SI 2 "const_int_operand" "n"))
4132          (match_operand:SI 3 "const_int_operand" "n")
4133          (const_int 0)))
4134    (clobber (reg:SI T_REG))]
4135   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4136   "#"
4137   [(set (attr "length")
4138         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4139                (const_string "6")
4140                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4141                (const_string "8")
4142                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4143                (const_string "10")
4144                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4145                (const_string "12")]
4146               (const_string "14")))
4147     (set_attr "type" "arith")])
4149 ;; These patterns are found in expansions of DImode shifts by 16, and
4150 ;; allow the xtrct instruction to be generated from C source.
4152 (define_insn "xtrct_left"
4153   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4154         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4155                            (const_int 16))
4156                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4157                              (const_int 16))))]
4158   "TARGET_SH1"
4159   "xtrct        %1,%0"
4160   [(set_attr "type" "arith")])
4162 (define_insn "xtrct_right"
4163   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4164         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4165                              (const_int 16))
4166                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4167                            (const_int 16))))]
4168   "TARGET_SH1"
4169   "xtrct        %2,%0"
4170   [(set_attr "type" "arith")])
4172 ;; -------------------------------------------------------------------------
4173 ;; Unary arithmetic
4174 ;; -------------------------------------------------------------------------
4176 (define_insn "negc"
4177   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4178         (neg:SI (plus:SI (reg:SI T_REG)
4179                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4180    (set (reg:SI T_REG)
4181         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4182                (const_int 0)))]
4183   "TARGET_SH1"
4184   "negc %1,%0"
4185   [(set_attr "type" "arith")])
4187 (define_insn "*negdi_media"
4188   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4189         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4190   "TARGET_SHMEDIA"
4191   "sub  r63, %1, %0"
4192   [(set_attr "type" "arith_media")])
4194 (define_expand "negdi2"
4195   [(set (match_operand:DI 0 "arith_reg_operand" "")
4196         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4197   ""
4198   "
4200   if (TARGET_SH1)
4201     {
4202       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4203       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4205       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4206       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4208       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4209       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4211       emit_insn (gen_clrt ());
4212       emit_insn (gen_negc (low_dst, low_src));
4213       emit_insn (gen_negc (high_dst, high_src));
4214       DONE;
4215     }
4218 (define_insn "negsi2"
4219   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4220         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4221   "TARGET_SH1"
4222   "neg  %1,%0"
4223   [(set_attr "type" "arith")])
4225 (define_insn "one_cmplsi2"
4226   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4227         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4228   "TARGET_SH1"
4229   "not  %1,%0"
4230   [(set_attr "type" "arith")])
4232 (define_expand "one_cmpldi2"
4233   [(set (match_operand:DI 0 "arith_reg_dest" "")
4234         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4235                 (const_int -1)))]
4236   "TARGET_SHMEDIA" "")
4238 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4239    This can be used as some kind of conditional execution, which is useful
4240    for abs.  */
4241 (define_split
4242   [(set (match_operand:SI 0 "arith_reg_dest" "")
4243         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4244                          (match_operand:SI 1 "arith_reg_operand" ""))
4245                  (reg:SI T_REG)))]
4246   "TARGET_HARD_SH4"
4247   [(const_int 0)]
4248   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4249    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4250    DONE;")
4252 (define_insn "cneg"
4253   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4254         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4255                       (match_operand:SI 1 "arith_reg_operand" "0")
4256                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4257   "TARGET_HARD_SH4"
4258   "bf 0f\;neg %2,%0\\n0:"
4259   [(set_attr "type" "arith") ;; poor approximation
4260    (set_attr "length" "4")])
4263 ;; -------------------------------------------------------------------------
4264 ;; Zero extension instructions
4265 ;; -------------------------------------------------------------------------
4267 (define_insn "zero_extendsidi2"
4268   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4269         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4270   "TARGET_SHMEDIA"
4271   "addz.l       %1, r63, %0"
4272   [(set_attr "type" "arith_media")
4273    (set_attr "highpart" "extend")])
4275 (define_insn "zero_extendhidi2"
4276   [(set (match_operand:DI 0 "register_operand" "=r,r")
4277         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4278   "TARGET_SHMEDIA"
4279   "@
4280         #
4281         ld%M1.uw        %m1, %0"
4282   [(set_attr "type" "*,load_media")
4283    (set (attr "highpart")
4284         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4285                (const_string "user")]
4286               (const_string "ignore")))])
4288 (define_split
4289   [(set (match_operand:DI 0 "register_operand" "")
4290         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4291   "TARGET_SHMEDIA && reload_completed"
4292   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4293    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4294   "
4296   if (GET_CODE (operands[1]) == TRUNCATE)
4297     operands[1] = XEXP (operands[1], 0);
4300 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4301 ;; reload the entire truncate expression.
4302 (define_insn_and_split "*loaddi_trunc"
4303   [(set (match_operand 0 "any_register_operand" "=r")
4304         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4305   "TARGET_SHMEDIA && reload_completed"
4306   "#"
4307   "TARGET_SHMEDIA && reload_completed"
4308   [(set (match_dup 0) (match_dup 1))]
4309   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4311 (define_insn "zero_extendqidi2"
4312   [(set (match_operand:DI 0 "register_operand" "=r,r")
4313         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4314   "TARGET_SHMEDIA"
4315   "@
4316         andi    %1, 255, %0
4317         ld%M1.ub        %m1, %0"
4318   [(set_attr "type" "arith_media,load_media")
4319    (set (attr "highpart")
4320         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4321                (const_string "user")]
4322               (const_string "ignore")))])
4324 (define_expand "zero_extendhisi2"
4325   [(set (match_operand:SI 0 "arith_reg_operand" "")
4326         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4327   ""
4328   "
4330   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4331     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4334 (define_insn "*zero_extendhisi2_compact"
4335   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4336         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4337   "TARGET_SH1"
4338   "extu.w       %1,%0"
4339   [(set_attr "type" "arith")])
4341 (define_insn "*zero_extendhisi2_media"
4342   [(set (match_operand:SI 0 "register_operand" "=r,r")
4343         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4344   "TARGET_SHMEDIA"
4345   "@
4346         #
4347         ld%M1.uw        %m1, %0"
4348   [(set_attr "type" "arith_media,load_media")
4349    (set (attr "highpart")
4350         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4351                (const_string "user")]
4352               (const_string "ignore")))])
4354 (define_split
4355   [(set (match_operand:SI 0 "register_operand" "")
4356         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4357   "TARGET_SHMEDIA && reload_completed"
4358   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4359    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4360   "
4362   rtx op1 = operands[1];
4364   if (GET_CODE (op1) == TRUNCATE)
4365     op1 = XEXP (op1, 0);
4366   operands[2]
4367     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4368                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4371 (define_expand "zero_extendqisi2"
4372   [(set (match_operand:SI 0 "arith_reg_operand" "")
4373         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4374   ""
4375   "
4377   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4378     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4381 (define_insn "*zero_extendqisi2_compact"
4382   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4383         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4384   "TARGET_SH1"
4385   "extu.b       %1,%0"
4386   [(set_attr "type" "arith")])
4388 (define_insn "*zero_extendqisi2_media"
4389   [(set (match_operand:SI 0 "register_operand" "=r,r")
4390         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4391   "TARGET_SHMEDIA"
4392   "@
4393         andi    %1, 255, %0
4394         ld%M1.ub        %m1, %0"
4395   [(set_attr "type" "arith_media,load_media")
4396    (set (attr "highpart")
4397         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4398                (const_string "user")]
4399               (const_string "ignore")))])
4401 (define_insn "zero_extendqihi2"
4402   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4403         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4404   "TARGET_SH1"
4405   "extu.b       %1,%0"
4406   [(set_attr "type" "arith")])
4408 ;; -------------------------------------------------------------------------
4409 ;; Sign extension instructions
4410 ;; -------------------------------------------------------------------------
4412 ;; ??? This should be a define expand.
4413 ;; ??? Or perhaps it should be dropped?
4415 ;; convert_move generates good code for SH[1-4].
4416 (define_insn "extendsidi2"
4417   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4418         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4419   "TARGET_SHMEDIA"
4420   "@
4421         add.l   %1, r63, %0
4422         ld%M1.l %m1, %0
4423         fmov.sl %1, %0"
4424   [(set_attr "type" "arith_media,load_media,fpconv_media")
4425    (set (attr "highpart")
4426         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4427                (const_string "user")]
4428               (const_string "extend")))])
4430 (define_insn "extendhidi2"
4431   [(set (match_operand:DI 0 "register_operand" "=r,r")
4432         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4433   "TARGET_SHMEDIA"
4434   "@
4435         #
4436         ld%M1.w %m1, %0"
4437   [(set_attr "type" "*,load_media")
4438    (set (attr "highpart")
4439         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4440                (const_string "user")]
4441               (const_string "ignore")))])
4443 (define_split
4444   [(set (match_operand:DI 0 "register_operand" "")
4445         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4446   "TARGET_SHMEDIA && reload_completed"
4447   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4448    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4449   "
4451   if (GET_CODE (operands[1]) == TRUNCATE)
4452     operands[1] = XEXP (operands[1], 0);
4455 (define_insn "extendqidi2"
4456   [(set (match_operand:DI 0 "register_operand" "=r,r")
4457         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4458   "TARGET_SHMEDIA"
4459   "@
4460         #
4461         ld%M1.b %m1, %0"
4462   [(set_attr "type" "*,load_media")
4463    (set (attr "highpart")
4464         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4465                (const_string "user")]
4466               (const_string "ignore")))])
4468 (define_split
4469   [(set (match_operand:DI 0 "register_operand" "")
4470         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4471   "TARGET_SHMEDIA && reload_completed"
4472   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4473    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4474   "
4476   if (GET_CODE (operands[1]) == TRUNCATE)
4477     operands[1] = XEXP (operands[1], 0);
4480 (define_expand "extendhisi2"
4481   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4482         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4483   ""
4484   "")
4486 (define_insn "*extendhisi2_compact"
4487   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4488         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4489   "TARGET_SH1"
4490   "@
4491         exts.w  %1,%0
4492         mov.w   %1,%0"
4493   [(set_attr "type" "arith,load")])
4495 (define_insn "*extendhisi2_media"
4496   [(set (match_operand:SI 0 "register_operand" "=r,r")
4497         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4498   "TARGET_SHMEDIA"
4499   "@
4500         #
4501         ld%M1.w %m1, %0"
4502   [(set_attr "type" "arith_media,load_media")
4503    (set (attr "highpart")
4504         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4505                (const_string "user")]
4506               (const_string "ignore")))])
4508 (define_split
4509   [(set (match_operand:SI 0 "register_operand" "")
4510         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4511   "TARGET_SHMEDIA && reload_completed"
4512   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4513    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4514   "
4516   rtx op1 = operands[1];
4517   if (GET_CODE (op1) == TRUNCATE)
4518     op1 = XEXP (op1, 0);
4519   operands[2]
4520     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4521                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4524 (define_expand "extendqisi2"
4525   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4526         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4527   ""
4528   "")
4530 (define_insn "*extendqisi2_compact"
4531   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4532         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4533   "TARGET_SH1"
4534   "@
4535         exts.b  %1,%0
4536         mov.b   %1,%0"
4537   [(set_attr "type" "arith,load")])
4539 (define_insn "*extendqisi2_media"
4540   [(set (match_operand:SI 0 "register_operand" "=r,r")
4541         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4542   "TARGET_SHMEDIA"
4543   "@
4544         #
4545         ld%M1.b %m1, %0"
4546   [(set_attr "type" "arith_media,load_media")
4547    (set (attr "highpart")
4548         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4549                (const_string "user")]
4550               (const_string "ignore")))])
4552 (define_split
4553   [(set (match_operand:SI 0 "register_operand" "")
4554         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4555   "TARGET_SHMEDIA && reload_completed"
4556   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4557    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4558    "
4560   rtx op1 = operands[1];
4561   if (GET_CODE (op1) == TRUNCATE)
4562     op1 = XEXP (op1, 0);
4563   operands[2]
4564     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4565                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4568 (define_insn "extendqihi2"
4569   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4570         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4571   "TARGET_SH1"
4572   "@
4573         exts.b  %1,%0
4574         mov.b   %1,%0"
4575   [(set_attr "type" "arith,load")])
4577 /* It would seem useful to combine the truncXi patterns into the movXi
4578    patterns, but unary operators are ignored when matching constraints,
4579    so we need separate patterns.  */
4580 (define_insn "truncdisi2"
4581   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4582         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4583   "TARGET_SHMEDIA"
4584   "@
4585         add.l   %1, r63, %0
4586         st%M0.l %m0, %1
4587         fst%M0.s        %m0, %T1
4588         fmov.ls %1, %0
4589         fmov.sl %T1, %0
4590         fmov.s  %T1, %0"
4591   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4592    (set (attr "highpart")
4593         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4594                (const_string "user")]
4595               (const_string "extend")))])
4597 (define_insn "truncdihi2"
4598   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4599         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4600   "TARGET_SHMEDIA"
4601   "@
4602         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4603         st%M0.w %m0, %1"
4604   [(set_attr "type"   "arith_media,store_media")
4605    (set_attr "length" "8,4")
4606    (set (attr "highpart")
4607         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4608                (const_string "user")]
4609               (const_string "extend")))])
4611 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4612 ; Because we use zero extension, we can't provide signed QImode compares
4613 ; using a simple compare or conditional banch insn.
4614 (define_insn "truncdiqi2"
4615   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4616         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4617   "TARGET_SHMEDIA"
4618   "@
4619         andi    %1, 255, %0
4620         st%M0.b %m0, %1"
4621   [(set_attr "type"   "arith_media,store")
4622    (set (attr "highpart")
4623         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4624                (const_string "user")]
4625               (const_string "extend")))])
4626 ;; -------------------------------------------------------------------------
4627 ;; Move instructions
4628 ;; -------------------------------------------------------------------------
4630 ;; define push and pop so it is easy for sh.c
4631 ;; We can't use push and pop on SHcompact because the stack must always
4632 ;; be 8-byte aligned.
4634 (define_expand "push"
4635   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4636         (match_operand:SI 0 "register_operand" "r,l,x"))]
4637   "TARGET_SH1 && ! TARGET_SH5"
4638   "")
4640 (define_expand "pop"
4641   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4642         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4643   "TARGET_SH1 && ! TARGET_SH5"
4644   "")
4646 (define_expand "push_e"
4647   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4648                    (match_operand:SF 0 "" ""))
4649               (use (reg:PSI FPSCR_REG))
4650               (clobber (scratch:SI))])]
4651   "TARGET_SH1 && ! TARGET_SH5"
4652   "")
4654 (define_insn "push_fpul"
4655   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4656   "TARGET_SH2E && ! TARGET_SH5"
4657   "sts.l        fpul,@-r15"
4658   [(set_attr "type" "store")
4659    (set_attr "late_fp_use" "yes")
4660    (set_attr "hit_stack" "yes")])
4662 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4663 ;; so use that.
4664 (define_expand "push_4"
4665   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4666                    (match_operand:DF 0 "" ""))
4667               (use (reg:PSI FPSCR_REG))
4668               (clobber (scratch:SI))])]
4669   "TARGET_SH1 && ! TARGET_SH5"
4670   "")
4672 (define_expand "pop_e"
4673   [(parallel [(set (match_operand:SF 0 "" "")
4674               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4675               (use (reg:PSI FPSCR_REG))
4676               (clobber (scratch:SI))])]
4677   "TARGET_SH1 && ! TARGET_SH5"
4678   "")
4680 (define_insn "pop_fpul"
4681   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4682   "TARGET_SH2E && ! TARGET_SH5"
4683   "lds.l        @r15+,fpul"
4684   [(set_attr "type" "load")
4685    (set_attr "hit_stack" "yes")])
4687 (define_expand "pop_4"
4688   [(parallel [(set (match_operand:DF 0 "" "")
4689                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4690               (use (reg:PSI FPSCR_REG))
4691               (clobber (scratch:SI))])]
4692   "TARGET_SH1 && ! TARGET_SH5"
4693   "")
4695 (define_expand "push_fpscr"
4696   [(const_int 0)]
4697   "TARGET_SH2E"
4698   "
4700   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4701                                                  gen_rtx_PRE_DEC (Pmode,
4702                                                           stack_pointer_rtx)),
4703                                         get_fpscr_rtx ()));
4704   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4705   DONE;
4708 (define_expand "pop_fpscr"
4709   [(const_int 0)]
4710   "TARGET_SH2E"
4711   "
4713   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4714                                         gen_frame_mem (PSImode,
4715                                                  gen_rtx_POST_INC (Pmode,
4716                                                           stack_pointer_rtx))));
4717   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4718   DONE;
4721 ;; These two patterns can happen as the result of optimization, when
4722 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4723 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4725 (define_insn "clrt"
4726   [(set (reg:SI T_REG) (const_int 0))]
4727   "TARGET_SH1"
4728   "clrt")
4730 (define_insn "sett"
4731   [(set (reg:SI T_REG) (const_int 1))]
4732   "TARGET_SH1"
4733   "sett")
4735 ;; t/r must come after r/r, lest reload will try to reload stuff like
4736 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4737 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4738 (define_insn "movsi_i"
4739   [(set (match_operand:SI 0 "general_movdst_operand"
4740             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4741         (match_operand:SI 1 "general_movsrc_operand"
4742          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4743   "TARGET_SH1
4744    && ! TARGET_SH2E
4745    && ! TARGET_SH2A
4746    && (register_operand (operands[0], SImode)
4747        || register_operand (operands[1], SImode))"
4748   "@
4749         mov.l   %1,%0
4750         mov     %1,%0
4751         cmp/pl  %1
4752         mov.l   %1,%0
4753         sts     %1,%0
4754         sts     %1,%0
4755         movt    %0
4756         mov.l   %1,%0
4757         sts.l   %1,%0
4758         sts.l   %1,%0
4759         lds     %1,%0
4760         lds     %1,%0
4761         lds.l   %1,%0
4762         lds.l   %1,%0
4763         fake    %1,%0"
4764   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4765    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4767 ;; t/r must come after r/r, lest reload will try to reload stuff like
4768 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4769 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4770 ;; will require a reload.
4771 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4772 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4773 (define_insn "movsi_ie"
4774   [(set (match_operand:SI 0 "general_movdst_operand"
4775             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4776         (match_operand:SI 1 "general_movsrc_operand"
4777          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4778   "(TARGET_SH2E || TARGET_SH2A)
4779    && (register_operand (operands[0], SImode)
4780        || register_operand (operands[1], SImode))"
4781   "@
4782         mov.l   %1,%0
4783         mov     %1,%0
4784         movi20  %1,%0
4785         cmp/pl  %1
4786         mov.l   %1,%0
4787         sts     %1,%0
4788         sts     %1,%0
4789         movt    %0
4790         mov.l   %1,%0
4791         sts.l   %1,%0
4792         sts.l   %1,%0
4793         lds     %1,%0
4794         lds     %1,%0
4795         lds.l   %1,%0
4796         lds.l   %1,%0
4797         lds.l   %1,%0
4798         sts.l   %1,%0
4799         fake    %1,%0
4800         lds     %1,%0
4801         sts     %1,%0
4802         fsts    fpul,%0
4803         flds    %1,fpul
4804         fmov    %1,%0
4805         ! move optimized away"
4806   [(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")
4807    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4808    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4810 (define_insn "movsi_i_lowpart"
4811   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4812         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4813    "TARGET_SH1
4814     && (register_operand (operands[0], SImode)
4815         || register_operand (operands[1], SImode))"
4816   "@
4817         mov.l   %1,%0
4818         mov     %1,%0
4819         mov.l   %1,%0
4820         sts     %1,%0
4821         sts     %1,%0
4822         movt    %0
4823         mov.l   %1,%0
4824         fake    %1,%0"
4825   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4827 (define_insn_and_split "load_ra"
4828   [(set (match_operand:SI 0 "general_movdst_operand" "")
4829         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4830   "TARGET_SH1"
4831   "#"
4832   "&& ! currently_expanding_to_rtl"
4833   [(set (match_dup 0) (match_dup 1))]
4834   "
4836   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4837     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4840 ;; The '?'s in the following constraints may not reflect the time taken
4841 ;; to perform the move. They are there to discourage the use of floating-
4842 ;; point registers for storing integer values.
4843 (define_insn "*movsi_media"
4844   [(set (match_operand:SI 0 "general_movdst_operand"
4845                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4846         (match_operand:SI 1 "general_movsrc_operand"
4847          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4848   "TARGET_SHMEDIA_FPU
4849    && (register_operand (operands[0], SImode)
4850        || sh_register_operand (operands[1], SImode)
4851        || GET_CODE (operands[1]) == TRUNCATE)"
4852   "@
4853         add.l   %1, r63, %0
4854         movi    %1, %0
4855         #
4856         ld%M1.l %m1, %0
4857         st%M0.l %m0, %N1
4858         fld%M1.s        %m1, %0
4859         fst%M0.s        %m0, %1
4860         fmov.ls %N1, %0
4861         fmov.sl %1, %0
4862         fmov.s  %1, %0
4863         ptabs   %1, %0
4864         gettr   %1, %0
4865         pt      %1, %0"
4866   [(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")
4867    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4868    (set (attr "highpart")
4869         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4870                (const_string "user")]
4871               (const_string "ignore")))])
4873 (define_insn "*movsi_media_nofpu"
4874   [(set (match_operand:SI 0 "general_movdst_operand"
4875                 "=r,r,r,r,m,*b,r,*b")
4876         (match_operand:SI 1 "general_movsrc_operand"
4877          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
4878   "TARGET_SHMEDIA
4879    && (register_operand (operands[0], SImode)
4880        || sh_register_operand (operands[1], SImode)
4881        || GET_CODE (operands[1]) == TRUNCATE)"
4882   "@
4883         add.l   %1, r63, %0
4884         movi    %1, %0
4885         #
4886         ld%M1.l %m1, %0
4887         st%M0.l %m0, %N1
4888         ptabs   %1, %0
4889         gettr   %1, %0
4890         pt      %1, %0"
4891   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4892    (set_attr "length" "4,4,8,4,4,4,4,12")
4893    (set (attr "highpart")
4894         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4895                (const_string "user")]
4896               (const_string "ignore")))])
4898 (define_expand "movsi_const"
4899   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4900         (const:SI (sign_extend:SI
4901                    (truncate:HI
4902                     (ashiftrt:SI
4903                      (match_operand:DI 1 "immediate_operand" "s")
4904                      (const_int 16))))))
4905    (set (match_dup 0)
4906         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4907                 (const:SI
4908                   (zero_extend:SI
4909                    (truncate:HI (match_dup 1))))))]
4910   "TARGET_SHMEDIA && reload_completed
4911    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4912   "
4914   if (GET_CODE (operands[1]) == LABEL_REF
4915       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4916     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4917   else if (GOTOFF_P (operands[1]))
4918     {
4919       rtx unspec = XEXP (operands[1], 0);
4921       if (! UNSPEC_GOTOFF_P (unspec))
4922         {
4923           unspec = XEXP (unspec, 0);
4924           if (! UNSPEC_GOTOFF_P (unspec))
4925             abort ();
4926         }
4927       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4928           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4929         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4930     }
4933 (define_expand "movsi_const_16bit"
4934   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4935         (const:SI (sign_extend:SI
4936                    (truncate:HI
4937                     (match_operand:DI 1 "immediate_operand" "s")))))]
4938   "TARGET_SHMEDIA && flag_pic && reload_completed
4939    && GET_CODE (operands[1]) == SYMBOL_REF"
4940   "")
4942 (define_split
4943   [(set (match_operand:SI 0 "arith_reg_dest" "")
4944         (match_operand:SI 1 "immediate_operand" ""))]
4945   "TARGET_SHMEDIA && reload_completed
4946    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4947   [(const_int 0)]
4948   "
4950   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4952   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4953                                         REG_NOTES (insn));
4955   DONE;
4958 (define_split
4959   [(set (match_operand:SI 0 "register_operand" "")
4960         (match_operand:SI 1 "immediate_operand" ""))]
4961   "TARGET_SHMEDIA && reload_completed
4962    && ((GET_CODE (operands[1]) == CONST_INT
4963         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4964        || GET_CODE (operands[1]) == CONST_DOUBLE)"
4965   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4967 (define_expand "movsi"
4968   [(set (match_operand:SI 0 "general_movdst_operand" "")
4969         (match_operand:SI 1 "general_movsrc_operand" ""))]
4970   ""
4971   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4973 (define_expand "ic_invalidate_line"
4974   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4975                                 (match_dup 1)] UNSPEC_ICACHE)
4976               (clobber (scratch:SI))])]
4977   "TARGET_HARD_SH4 || TARGET_SH5"
4978   "
4980   if (TARGET_SHMEDIA)
4981     {
4982       emit_insn (gen_ic_invalidate_line_media (operands[0]));
4983       DONE;
4984     }
4985   else if (TARGET_SHCOMPACT)
4986     {
4987       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4988       operands[1] = force_reg (Pmode, operands[1]);
4989       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
4990       DONE;
4991     }
4992   else if (TARGET_SH4A_ARCH)
4993     {
4994       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
4995       DONE;
4996     }
4997   operands[0] = force_reg (Pmode, operands[0]);
4998   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
4999                                                                Pmode)));
5002 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5003 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5004 ;; the requirement *1*00 for associative address writes.  The alignment of
5005 ;; %0 implies that its least significant bit is cleared,
5006 ;; thus we clear the V bit of a matching entry if there is one.
5007 (define_insn "ic_invalidate_line_i"
5008   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5009                      (match_operand:SI 1 "register_operand" "r")]
5010                      UNSPEC_ICACHE)
5011    (clobber (match_scratch:SI 2 "=&r"))]
5012   "TARGET_HARD_SH4"
5013   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5014   [(set_attr "length" "8")
5015    (set_attr "type" "cwb")])
5017 (define_insn "ic_invalidate_line_sh4a"
5018   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5019                     UNSPEC_ICACHE)]
5020   "TARGET_SH4A_ARCH"
5021   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5022   [(set_attr "length" "16")
5023    (set_attr "type" "cwb")])
5025 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5026 ;; an add in the code that calculates the address.
5027 (define_insn "ic_invalidate_line_media"
5028   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5029                     UNSPEC_ICACHE)]
5030   "TARGET_SHMEDIA"
5031   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5032   [(set_attr "length" "16")
5033    (set_attr "type" "invalidate_line_media")])
5035 (define_insn "ic_invalidate_line_compact"
5036   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5037                      (match_operand:SI 1 "register_operand" "r")]
5038                     UNSPEC_ICACHE)
5039    (clobber (reg:SI PR_REG))]
5040   "TARGET_SHCOMPACT"
5041   "jsr @%1%#"
5042   [(set_attr "type" "sfunc")
5043    (set_attr "needs_delay_slot" "yes")])
5045 (define_expand "initialize_trampoline"
5046   [(match_operand:SI 0 "" "")
5047    (match_operand:SI 1 "" "")
5048    (match_operand:SI 2 "" "")]
5049   "TARGET_SHCOMPACT"
5050   "
5052   rtx sfun, tramp;
5054   tramp = force_reg (Pmode, operands[0]);
5055   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5056                                             SFUNC_STATIC));
5057   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5058   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5060   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5061   DONE;
5064 (define_insn "initialize_trampoline_compact"
5065   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5066                      (match_operand:SI 1 "register_operand" "r")
5067                      (reg:SI R2_REG) (reg:SI R3_REG)]
5068                     UNSPEC_INIT_TRAMP)
5070    (clobber (reg:SI PR_REG))]
5071   "TARGET_SHCOMPACT"
5072   "jsr @%1%#"
5073   [(set_attr "type" "sfunc")
5074    (set_attr "needs_delay_slot" "yes")])
5076 (define_insn "movqi_i"
5077   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5078         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
5079   "TARGET_SH1
5080    && (arith_reg_operand (operands[0], QImode)
5081        || arith_reg_operand (operands[1], QImode))"
5082   "@
5083         mov     %1,%0
5084         mov.b   %1,%0
5085         mov.b   %1,%0
5086         movt    %0
5087         sts     %1,%0
5088         lds     %1,%0"
5089  [(set_attr "type" "move,load,store,move,move,move")])
5091 (define_insn "*movqi_media"
5092   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5093         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5094   "TARGET_SHMEDIA
5095    && (arith_reg_operand (operands[0], QImode)
5096        || extend_reg_or_0_operand (operands[1], QImode))"
5097   "@
5098         add.l   %1, r63, %0
5099         movi    %1, %0
5100         ld%M1.ub        %m1, %0
5101         st%M0.b %m0, %N1"
5102   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5103    (set (attr "highpart")
5104         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5105                (const_string "user")]
5106               (const_string "ignore")))])
5108 (define_expand "movqi"
5109   [(set (match_operand:QI 0 "general_operand" "")
5110         (match_operand:QI 1 "general_operand"  ""))]
5111   ""
5112   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5114 (define_expand "reload_inqi"
5115   [(set (match_operand:SI 2 "" "=&r")
5116         (match_operand:QI 1 "inqhi_operand" ""))
5117    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5118         (truncate:QI (match_dup 3)))]
5119   "TARGET_SHMEDIA"
5120   "
5122   rtx inner = XEXP (operands[1], 0);
5123   int regno = REGNO (inner);
5125   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5126   operands[1] = gen_rtx_REG (SImode, regno);
5127   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5130 /* When storing r0, we have to avoid reg+reg addressing.  */
5131 (define_insn "movhi_i"
5132   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5133         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5134   "TARGET_SH1
5135    && (arith_reg_operand (operands[0], HImode)
5136        || arith_reg_operand (operands[1], HImode))
5137    && (GET_CODE (operands[0]) != MEM
5138        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5139        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5140        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5141   "@
5142         mov.w   %1,%0
5143         mov     %1,%0
5144         mov.w   %1,%0
5145         movt    %0
5146         mov.w   %1,%0
5147         sts     %1,%0
5148         lds     %1,%0
5149         fake    %1,%0"
5150   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5152 (define_insn "*movhi_media"
5153   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5154         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5155   "TARGET_SHMEDIA
5156    && (arith_reg_operand (operands[0], HImode)
5157        || arith_reg_or_0_operand (operands[1], HImode))"
5158   "@
5159         add.l   %1, r63, %0
5160         movi    %1, %0
5161         #
5162         ld%M1.w %m1, %0
5163         st%M0.w %m0, %N1"
5164   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5165    (set (attr "highpart")
5166         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5167                (const_string "user")]
5168               (const_string "ignore")))])
5170 (define_split
5171   [(set (match_operand:HI 0 "register_operand" "")
5172         (match_operand:HI 1 "immediate_operand" ""))]
5173   "TARGET_SHMEDIA && reload_completed
5174    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5175   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5177 (define_expand "movhi"
5178   [(set (match_operand:HI 0 "general_movdst_operand" "")
5179         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5180   ""
5181   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5183 (define_expand "reload_inhi"
5184   [(set (match_operand:SI 2 "" "=&r")
5185         (match_operand:HI 1 "inqhi_operand" ""))
5186    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5187         (truncate:HI (match_dup 3)))]
5188   "TARGET_SHMEDIA"
5189   "
5191   rtx inner = XEXP (operands[1], 0);
5192   int regno = REGNO (inner);
5194   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5195   operands[1] = gen_rtx_REG (SImode, regno);
5196   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5199 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5200 ;; compiled with -m2 -ml -O3 -funroll-loops
5201 (define_insn "*movdi_i"
5202   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5203         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5204   "TARGET_SH1
5205    && (arith_reg_operand (operands[0], DImode)
5206        || arith_reg_operand (operands[1], DImode))"
5207   "* return output_movedouble (insn, operands, DImode);"
5208   [(set_attr "length" "4")
5209    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5211 ;; If the output is a register and the input is memory or a register, we have
5212 ;; to be careful and see which word needs to be loaded first.
5214 (define_split
5215   [(set (match_operand:DI 0 "general_movdst_operand" "")
5216         (match_operand:DI 1 "general_movsrc_operand" ""))]
5217   "TARGET_SH1 && reload_completed"
5218   [(set (match_dup 2) (match_dup 3))
5219    (set (match_dup 4) (match_dup 5))]
5220   "
5222   int regno;
5224   if ((GET_CODE (operands[0]) == MEM
5225        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5226       || (GET_CODE (operands[1]) == MEM
5227           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5228     FAIL;
5230   switch (GET_CODE (operands[0]))
5231     {
5232     case REG:
5233       regno = REGNO (operands[0]);
5234       break;
5235     case SUBREG:
5236       regno = subreg_regno (operands[0]);
5237       break;
5238     case MEM:
5239       regno = -1;
5240       break;
5241     default:
5242       gcc_unreachable ();
5243     }
5245   if (regno == -1
5246       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5247     {
5248       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5249       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5250       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5251       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5252     }
5253   else
5254     {
5255       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5256       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5257       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5258       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5259     }
5261   if (operands[2] == 0 || operands[3] == 0
5262       || operands[4] == 0 || operands[5] == 0)
5263     FAIL;
5266 ;; The '?'s in the following constraints may not reflect the time taken
5267 ;; to perform the move. They are there to discourage the use of floating-
5268 ;; point registers for storing integer values.
5269 (define_insn "*movdi_media"
5270   [(set (match_operand:DI 0 "general_movdst_operand"
5271                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5272         (match_operand:DI 1 "general_movsrc_operand"
5273          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5274   "TARGET_SHMEDIA_FPU
5275    && (register_operand (operands[0], DImode)
5276        || sh_register_operand (operands[1], DImode))"
5277   "@
5278         add     %1, r63, %0
5279         movi    %1, %0
5280         #
5281         ld%M1.q %m1, %0
5282         st%M0.q %m0, %N1
5283         fld%M1.d        %m1, %0
5284         fst%M0.d        %m0, %1
5285         fmov.qd %N1, %0
5286         fmov.dq %1, %0
5287         fmov.d  %1, %0
5288         ptabs   %1, %0
5289         gettr   %1, %0
5290         pt      %1, %0"
5291   [(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")
5292    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5294 (define_insn "*movdi_media_nofpu"
5295   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5296         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5297   "TARGET_SHMEDIA
5298    && (register_operand (operands[0], DImode)
5299        || sh_register_operand (operands[1], DImode))"
5300   "@
5301         add     %1, r63, %0
5302         movi    %1, %0
5303         #
5304         ld%M1.q %m1, %0
5305         st%M0.q %m0, %N1
5306         ptabs   %1, %0
5307         gettr   %1, %0
5308         pt      %1, %0"
5309   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5310    (set_attr "length" "4,4,16,4,4,4,4,*")])
5312 (define_insn "*movdi_media_I16"
5313   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5314         (match_operand:DI 1 "const_int_operand" "I16"))]
5315   "TARGET_SHMEDIA && reload_completed"
5316   "movi %1, %0"
5317   [(set_attr "type" "arith_media")
5318    (set_attr "length" "4")])
5320 (define_split
5321   [(set (match_operand:DI 0 "arith_reg_dest" "")
5322         (match_operand:DI 1 "immediate_operand" ""))]
5323   "TARGET_SHMEDIA && reload_completed
5324    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5325   [(set (match_dup 0) (match_dup 1))]
5326   "
5328   rtx insn;
5330   if (TARGET_SHMEDIA64)
5331     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5332   else
5333     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5335   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5336                                         REG_NOTES (insn));
5338   DONE;
5341 (define_expand "movdi_const"
5342   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5343         (const:DI (sign_extend:DI
5344                    (truncate:HI
5345                     (ashiftrt:DI
5346                      (match_operand:DI 1 "immediate_operand" "s")
5347                      (const_int 48))))))
5348    (set (match_dup 0)
5349         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5350                 (const:DI
5351                  (zero_extend:DI
5352                   (truncate:HI
5353                    (ashiftrt:SI
5354                     (match_dup 1)
5355                     (const_int 32)))))))
5356    (set (match_dup 0)
5357         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5358                 (const:DI
5359                  (zero_extend:DI
5360                   (truncate:HI
5361                    (ashiftrt:SI
5362                     (match_dup 1)
5363                     (const_int 16)))))))
5364    (set (match_dup 0)
5365         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5366                 (const:DI
5367                  (zero_extend:DI
5368                   (truncate:HI
5369                    (match_dup 1))))))]
5370   "TARGET_SHMEDIA64 && reload_completed
5371    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5372   "
5374   sh_mark_label (operands[1], 4);
5377 (define_expand "movdi_const_32bit"
5378   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5379         (const:DI (sign_extend:DI
5380                    (truncate:HI
5381                     (ashiftrt:DI
5382                      (match_operand:DI 1 "immediate_operand" "s")
5383                      (const_int 16))))))
5384    (set (match_dup 0)
5385         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5386                 (const:DI
5387                  (zero_extend:DI
5388                   (truncate:HI
5389                    (match_dup 1))))))]
5390   "TARGET_SHMEDIA32 && reload_completed
5391    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5392   "
5394   sh_mark_label (operands[1], 2);
5397 (define_expand "movdi_const_16bit"
5398   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5399         (const:DI (sign_extend:DI
5400                    (truncate:HI
5401                     (match_operand:DI 1 "immediate_operand" "s")))))]
5402   "TARGET_SHMEDIA && flag_pic && reload_completed
5403    && GET_CODE (operands[1]) == SYMBOL_REF"
5404   "")
5406 (define_split
5407   [(set (match_operand:DI 0 "ext_dest_operand" "")
5408         (match_operand:DI 1 "immediate_operand" ""))]
5409   "TARGET_SHMEDIA && reload_completed
5410    && GET_CODE (operands[1]) == CONST_INT
5411    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5412   [(set (match_dup 0) (match_dup 2))
5413    (match_dup 1)]
5414   "
5416   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5417   unsigned HOST_WIDE_INT low = val;
5418   unsigned HOST_WIDE_INT high = val;
5419   unsigned HOST_WIDE_INT sign;
5420   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5422   /* Zero-extend the 16 least-significant bits.  */
5423   low &= 0xffff;
5425   /* Arithmetic shift right the word by 16 bits.  */
5426   high >>= 16;
5427   if (GET_CODE (operands[0]) == SUBREG
5428       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5429     {
5430       high &= 0xffff;
5431       high ^= 0x8000;
5432       high -= 0x8000;
5433     }
5434   else
5435     {
5436       sign = 1;
5437       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5438       high ^= sign;
5439       high -= sign;
5440     }
5441   do
5442     {
5443       /* If we can't generate the constant with a two-insn movi / shori
5444          sequence, try some other strategies.  */
5445       if (! CONST_OK_FOR_I16 (high))
5446         {
5447           /* Try constant load / left shift.  We know VAL != 0.  */
5448           val2 = val ^ (val-1);
5449           if (val2 > 0x1ffff)
5450             {
5451               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5453               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5454                   || (! CONST_OK_FOR_I16 (high >> 16)
5455                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5456                 {
5457                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5458                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5459                                                    GEN_INT (trailing_zeroes));
5460                   break;
5461                 }
5462             }
5463           /* Try constant load / right shift.  */
5464           val2 = (val >> 15) + 1;
5465           if (val2 == (val2 & -val2))
5466             {
5467               int shift = 49 - exact_log2 (val2);
5469               val2 = trunc_int_for_mode (val << shift, DImode);
5470               if (CONST_OK_FOR_I16 (val2))
5471                 {
5472                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5473                                                    GEN_INT (shift));
5474                   break;
5475                 }
5476             }
5477           /* Try mperm.w .  */
5478           val2 = val & 0xffff;
5479           if ((val >> 16 & 0xffff) == val2
5480               && (val >> 32 & 0xffff) == val2
5481               && (val >> 48 & 0xffff) == val2)
5482             {
5483               val2 = (HOST_WIDE_INT) val >> 48;
5484               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5485               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5486               break;
5487             }
5488           /* Try movi / mshflo.l  */
5489           val2 = (HOST_WIDE_INT) val >> 32;
5490           if (val2 == ((unsigned HOST_WIDE_INT)
5491                         trunc_int_for_mode (val, SImode)))
5492             {
5493               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5494                                              operands[0]);
5495               break;
5496             }
5497           /* Try movi / mshflo.l w/ r63.  */
5498           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5499           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5500             {
5501               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5502                                              const0_rtx);
5503               break;
5504             }
5505         }
5506       val2 = high;
5507       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5508     }
5509   while (0);
5510   operands[2] = GEN_INT (val2);
5513 (define_split
5514   [(set (match_operand:DI 0 "ext_dest_operand" "")
5515         (match_operand:DI 1 "immediate_operand" ""))]
5516   "TARGET_SHMEDIA && reload_completed
5517    && GET_CODE (operands[1]) == CONST_DOUBLE"
5518   [(set (match_dup 0) (match_dup 2))
5519   (set (match_dup 0)
5520        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5521   "
5523   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5524   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5525   unsigned HOST_WIDE_INT val = low;
5526   unsigned HOST_WIDE_INT sign;
5528   /* Zero-extend the 16 least-significant bits.  */
5529   val &= 0xffff;
5530   operands[1] = GEN_INT (val);
5532   /* Arithmetic shift right the double-word by 16 bits.  */
5533   low >>= 16;
5534   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5535   high >>= 16;
5536   sign = 1;
5537   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5538   high ^= sign;
5539   high -= sign;
5541   /* This will only be true if high is a sign-extension of low, i.e.,
5542      it must be either 0 or (unsigned)-1, and be zero iff the
5543      most-significant bit of low is set.  */
5544   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5545     operands[2] = GEN_INT (low);
5546   else
5547     operands[2] = immed_double_const (low, high, DImode);
5550 (define_insn "shori_media"
5551   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5552         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5553                            (const_int 16))
5554                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5555   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5556   "@
5557         shori   %u2, %0
5558         #"
5559   [(set_attr "type" "arith_media,*")])
5561 (define_insn "*shori_media_si"
5562   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5563         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5564                            (const_int 16))
5565                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5566   "TARGET_SHMEDIA"
5567   "shori        %u2, %0")
5569 (define_expand "movdi"
5570   [(set (match_operand:DI 0 "general_movdst_operand" "")
5571         (match_operand:DI 1 "general_movsrc_operand" ""))]
5572   ""
5573   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5575 (define_insn "movdf_media"
5576   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5577         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5578   "TARGET_SHMEDIA_FPU
5579    && (register_operand (operands[0], DFmode)
5580        || sh_register_operand (operands[1], DFmode))"
5581   "@
5582         fmov.d  %1, %0
5583         fmov.qd %N1, %0
5584         fmov.dq %1, %0
5585         add     %1, r63, %0
5586         #
5587         fld%M1.d        %m1, %0
5588         fst%M0.d        %m0, %1
5589         ld%M1.q %m1, %0
5590         st%M0.q %m0, %N1"
5591   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5593 (define_insn "movdf_media_nofpu"
5594   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5595         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5596   "TARGET_SHMEDIA
5597    && (register_operand (operands[0], DFmode)
5598        || sh_register_operand (operands[1], DFmode))"
5599   "@
5600         add     %1, r63, %0
5601         #
5602         ld%M1.q %m1, %0
5603         st%M0.q %m0, %N1"
5604   [(set_attr "type" "arith_media,*,load_media,store_media")])
5606 (define_split
5607   [(set (match_operand:DF 0 "arith_reg_dest" "")
5608         (match_operand:DF 1 "immediate_operand" ""))]
5609   "TARGET_SHMEDIA && reload_completed"
5610   [(set (match_dup 3) (match_dup 2))]
5611   "
5613   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5614   long values[2];
5615   REAL_VALUE_TYPE value;
5617   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5618   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5620   if (HOST_BITS_PER_WIDE_INT >= 64)
5621     operands[2] = immed_double_const ((unsigned long) values[endian]
5622                                       | ((HOST_WIDE_INT) values[1 - endian]
5623                                          << 32), 0, DImode);
5624   else
5625     {
5626       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5627       operands[2] = immed_double_const (values[endian], values[1 - endian],
5628                                         DImode);
5629     }
5631   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5634 ;; ??? This should be a define expand.
5636 (define_insn "movdf_k"
5637   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5638         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5639   "TARGET_SH1
5640    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5641        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5642        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5643        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5644    && (arith_reg_operand (operands[0], DFmode)
5645        || arith_reg_operand (operands[1], DFmode))"
5646   "* return output_movedouble (insn, operands, DFmode);"
5647   [(set_attr "length" "4")
5648    (set_attr "type" "move,pcload,load,store")])
5650 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5651 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5652 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5653 ;; the d/m/c/X alternative, which is split later into single-precision
5654 ;; instructions.  And when not optimizing, no splits are done before fixing
5655 ;; up pcloads, so we need usable length information for that.
5656 (define_insn "movdf_i4"
5657   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5658         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5659    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5660    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5661   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5662    && (arith_reg_operand (operands[0], DFmode)
5663        || arith_reg_operand (operands[1], DFmode))"
5664   "@
5665         fmov    %1,%0
5666         #
5667         #
5668         fmov.d  %1,%0
5669         fmov.d  %1,%0
5670         #
5671         #
5672         #
5673         #
5674         #"
5675   [(set_attr_alternative "length"
5676      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5677       (const_int 4)
5678       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5679       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5680       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5681       (const_int 4)
5682       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5683       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5684       ;; increment or decrement r15 explicitly.
5685       (if_then_else
5686        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5687        (const_int 10) (const_int 8))
5688       (if_then_else
5689        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5690        (const_int 10) (const_int 8))])
5691    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5692    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5693    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5694                                            (const_string "double")
5695                                            (const_string "none")))])
5697 ;; Moving DFmode between fp/general registers through memory
5698 ;; (the top of the stack) is faster than moving through fpul even for
5699 ;; little endian.  Because the type of an instruction is important for its
5700 ;; scheduling,  it is beneficial to split these operations, rather than
5701 ;; emitting them in one single chunk, even if this will expose a stack
5702 ;; use that will prevent scheduling of other stack accesses beyond this
5703 ;; instruction.
5704 (define_split
5705   [(set (match_operand:DF 0 "register_operand" "")
5706         (match_operand:DF 1 "register_operand" ""))
5707    (use (match_operand:PSI 2 "fpscr_operand" ""))
5708    (clobber (match_scratch:SI 3 "=X"))]
5709   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5710    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5711   [(const_int 0)]
5712   "
5714   rtx insn, tos;
5716   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5717     {
5718       emit_move_insn (stack_pointer_rtx,
5719                       plus_constant (stack_pointer_rtx, -8));
5720       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5721     }
5722   else
5723     tos = gen_tmp_stack_mem (DFmode,
5724                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5725   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5726   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5727     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5728   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5729     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5730   else
5731     tos = gen_tmp_stack_mem (DFmode,
5732                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5733   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5734   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5735     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5736   else
5737     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5738   DONE;
5741 ;; local-alloc sometimes allocates scratch registers even when not required,
5742 ;; so we must be prepared to handle these.
5744 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5745 (define_split
5746   [(set (match_operand:DF 0 "general_movdst_operand" "")
5747         (match_operand:DF 1 "general_movsrc_operand"  ""))
5748    (use (match_operand:PSI 2 "fpscr_operand" ""))
5749    (clobber (match_scratch:SI 3 ""))]
5750   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5751    && reload_completed
5752    && true_regnum (operands[0]) < 16
5753    && true_regnum (operands[1]) < 16"
5754   [(set (match_dup 0) (match_dup 1))]
5755   "
5757   /* If this was a reg <-> mem operation with base + index reg addressing,
5758      we have to handle this in a special way.  */
5759   rtx mem = operands[0];
5760   int store_p = 1;
5761   if (! memory_operand (mem, DFmode))
5762     {
5763       mem = operands[1];
5764       store_p = 0;
5765     }
5766   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5767     mem = SUBREG_REG (mem);
5768   if (GET_CODE (mem) == MEM)
5769     {
5770       rtx addr = XEXP (mem, 0);
5771       if (GET_CODE (addr) == PLUS
5772           && GET_CODE (XEXP (addr, 0)) == REG
5773           && GET_CODE (XEXP (addr, 1)) == REG)
5774         {
5775           int offset;
5776           rtx reg0 = gen_rtx_REG (Pmode, 0);
5777           rtx regop = operands[store_p], word0 ,word1;
5779           if (GET_CODE (regop) == SUBREG)
5780             alter_subreg (&regop);
5781           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5782             offset = 2;
5783           else
5784             offset = 4;
5785           mem = copy_rtx (mem);
5786           PUT_MODE (mem, SImode);
5787           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5788           alter_subreg (&word0);
5789           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5790           alter_subreg (&word1);
5791           if (store_p || ! refers_to_regno_p (REGNO (word0),
5792                                               REGNO (word0) + 1, addr, 0))
5793             {
5794               emit_insn (store_p
5795                          ? gen_movsi_ie (mem, word0)
5796                          : gen_movsi_ie (word0, mem));
5797               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5798               mem = copy_rtx (mem);
5799               emit_insn (store_p
5800                          ? gen_movsi_ie (mem, word1)
5801                          : gen_movsi_ie (word1, mem));
5802               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5803             }
5804           else
5805             {
5806               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5807               emit_insn (gen_movsi_ie (word1, mem));
5808               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5809               mem = copy_rtx (mem);
5810               emit_insn (gen_movsi_ie (word0, mem));
5811             }
5812           DONE;
5813         }
5814     }
5817 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5818 (define_split
5819   [(set (match_operand:DF 0 "register_operand" "")
5820         (match_operand:DF 1 "memory_operand"  ""))
5821    (use (match_operand:PSI 2 "fpscr_operand" ""))
5822    (clobber (reg:SI R0_REG))]
5823   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5824   [(parallel [(set (match_dup 0) (match_dup 1))
5825               (use (match_dup 2))
5826               (clobber (scratch:SI))])]
5827   "")
5829 (define_expand "reload_indf__frn"
5830   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5831                    (match_operand:DF 1 "immediate_operand" "FQ"))
5832               (use (reg:PSI FPSCR_REG))
5833               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5834   "TARGET_SH1"
5835   "")
5837 (define_expand "reload_outdf__RnFRm"
5838   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5839                    (match_operand:DF 1 "register_operand" "af,r"))
5840               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5841   "TARGET_SH1"
5842   "")
5844 ;; Simplify no-op moves.
5845 (define_split
5846   [(set (match_operand:SF 0 "register_operand" "")
5847         (match_operand:SF 1 "register_operand" ""))
5848    (use (match_operand:PSI 2 "fpscr_operand" ""))
5849    (clobber (match_scratch:SI 3 ""))]
5850   "TARGET_SH2E && reload_completed
5851    && true_regnum (operands[0]) == true_regnum (operands[1])"
5852   [(set (match_dup 0) (match_dup 0))]
5853   "")
5855 ;; fmovd substitute post-reload splits
5856 (define_split
5857   [(set (match_operand:DF 0 "register_operand" "")
5858         (match_operand:DF 1 "register_operand" ""))
5859    (use (match_operand:PSI 2 "fpscr_operand" ""))
5860    (clobber (match_scratch:SI 3 ""))]
5861   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5862    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5863    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5864   [(const_int 0)]
5865   "
5867   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5868   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5869                            gen_rtx_REG (SFmode, src), operands[2]));
5870   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5871                            gen_rtx_REG (SFmode, src + 1), operands[2]));
5872   DONE;
5875 (define_split
5876   [(set (match_operand:DF 0 "register_operand" "")
5877         (mem:DF (match_operand:SI 1 "register_operand" "")))
5878    (use (match_operand:PSI 2 "fpscr_operand" ""))
5879    (clobber (match_scratch:SI 3 ""))]
5880   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5881    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5882    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5883   [(const_int 0)]
5884   "
5886   int regno = true_regnum (operands[0]);
5887   rtx insn;
5888   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
5889   rtx mem2
5890     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5891   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5892                                            regno + !! TARGET_LITTLE_ENDIAN),
5893                                   mem2, operands[2]));
5894   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5895   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5896                                                regno + ! TARGET_LITTLE_ENDIAN),
5897                                   change_address (mem, SFmode, NULL_RTX),
5898                                   operands[2]));
5899   DONE;
5902 (define_split
5903   [(set (match_operand:DF 0 "register_operand" "")
5904         (match_operand:DF 1 "memory_operand" ""))
5905    (use (match_operand:PSI 2 "fpscr_operand" ""))
5906    (clobber (match_scratch:SI 3 ""))]
5907   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5908    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5909   [(const_int 0)]
5910   "
5912   int regno = true_regnum (operands[0]);
5913   rtx addr, insn, adjust = NULL_RTX;
5914   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
5915   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5916   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5918   operands[1] = copy_rtx (mem2);
5919   addr = XEXP (mem2, 0);
5920   if (GET_CODE (addr) != POST_INC)
5921     {
5922       /* If we have to modify the stack pointer, the value that we have
5923          read with post-increment might be modified by an interrupt,
5924          so write it back.  */
5925       if (REGNO (addr) == STACK_POINTER_REGNUM)
5926         adjust = gen_push_e (reg0);
5927       else
5928         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5929       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5930     }
5931   addr = XEXP (addr, 0);
5932   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5933   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5934   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5935   if (adjust)
5936     emit_insn (adjust);
5937   else
5938     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5939   DONE;
5942 (define_split
5943   [(set (match_operand:DF 0 "memory_operand" "")
5944         (match_operand:DF 1 "register_operand" ""))
5945    (use (match_operand:PSI 2 "fpscr_operand" ""))
5946    (clobber (match_scratch:SI 3 ""))]
5947   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5948    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5949   [(const_int 0)]
5950   "
5952   int regno = true_regnum (operands[1]);
5953   rtx insn, addr, adjust = NULL_RTX;
5955   operands[0] = copy_rtx (operands[0]);
5956   PUT_MODE (operands[0], SFmode);
5957   insn = emit_insn (gen_movsf_ie (operands[0],
5958                                   gen_rtx_REG (SFmode,
5959                                            regno + ! TARGET_LITTLE_ENDIAN),
5960                                   operands[2]));
5961   operands[0] = copy_rtx (operands[0]);
5962   addr = XEXP (operands[0], 0);
5963   if (GET_CODE (addr) != PRE_DEC)
5964     {
5965       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5966       emit_insn_before (adjust, insn);
5967       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5968     }
5969   addr = XEXP (addr, 0);
5970   if (! adjust)
5971     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5972   insn = emit_insn (gen_movsf_ie (operands[0],
5973                                   gen_rtx_REG (SFmode,
5974                                            regno + !! TARGET_LITTLE_ENDIAN),
5975                                   operands[2]));
5976   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5977   DONE;
5980 ;; If the output is a register and the input is memory or a register, we have
5981 ;; to be careful and see which word needs to be loaded first.
5983 (define_split
5984   [(set (match_operand:DF 0 "general_movdst_operand" "")
5985         (match_operand:DF 1 "general_movsrc_operand" ""))]
5986   "TARGET_SH1 && reload_completed"
5987   [(set (match_dup 2) (match_dup 3))
5988    (set (match_dup 4) (match_dup 5))]
5989   "
5991   int regno;
5993   if ((GET_CODE (operands[0]) == MEM
5994        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5995       || (GET_CODE (operands[1]) == MEM
5996           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5997     FAIL;
5999   switch (GET_CODE (operands[0]))
6000     {
6001     case REG:
6002       regno = REGNO (operands[0]);
6003       break;
6004     case SUBREG:
6005       regno = subreg_regno (operands[0]);
6006       break;
6007     case MEM:
6008       regno = -1;
6009       break;
6010     default:
6011       gcc_unreachable ();
6012     }
6014   if (regno == -1
6015       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6016     {
6017       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6018       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6019       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6020       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6021     }
6022   else
6023     {
6024       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6025       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6026       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6027       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6028     }
6030   if (operands[2] == 0 || operands[3] == 0
6031       || operands[4] == 0 || operands[5] == 0)
6032     FAIL;
6035 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6036 ;; used only once, let combine add in the index again.
6038 (define_split
6039   [(set (match_operand:SI 0 "register_operand" "")
6040         (match_operand:SI 1 "" ""))
6041    (clobber (match_operand 2 "register_operand" ""))]
6042   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6043    && ALLOW_INDEXED_ADDRESS"
6044   [(use (reg:SI R0_REG))]
6045   "
6047   rtx addr, reg, const_int;
6049   if (GET_CODE (operands[1]) != MEM)
6050     FAIL;
6051   addr = XEXP (operands[1], 0);
6052   if (GET_CODE (addr) != PLUS)
6053     FAIL;
6054   reg = XEXP (addr, 0);
6055   const_int = XEXP (addr, 1);
6056   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6057          && GET_CODE (const_int) == CONST_INT))
6058     FAIL;
6059   emit_move_insn (operands[2], const_int);
6060   emit_move_insn (operands[0],
6061                   change_address (operands[1], VOIDmode,
6062                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6063   DONE;
6066 (define_split
6067   [(set (match_operand:SI 1 "" "")
6068         (match_operand:SI 0 "register_operand" ""))
6069    (clobber (match_operand 2 "register_operand" ""))]
6070   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6071    && ALLOW_INDEXED_ADDRESS"
6072   [(use (reg:SI R0_REG))]
6073   "
6075   rtx addr, reg, const_int;
6077   if (GET_CODE (operands[1]) != MEM)
6078     FAIL;
6079   addr = XEXP (operands[1], 0);
6080   if (GET_CODE (addr) != PLUS)
6081     FAIL;
6082   reg = XEXP (addr, 0);
6083   const_int = XEXP (addr, 1);
6084   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6085          && GET_CODE (const_int) == CONST_INT))
6086     FAIL;
6087   emit_move_insn (operands[2], const_int);
6088   emit_move_insn (change_address (operands[1], VOIDmode,
6089                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6090                   operands[0]);
6091   DONE;
6094 (define_expand "movdf"
6095   [(set (match_operand:DF 0 "general_movdst_operand" "")
6096         (match_operand:DF 1 "general_movsrc_operand" ""))]
6097   ""
6098   "
6100   if (prepare_move_operands (operands, DFmode)) DONE;
6101   if (TARGET_SHMEDIA)
6102     {
6103       if (TARGET_SHMEDIA_FPU)
6104         emit_insn (gen_movdf_media (operands[0], operands[1]));
6105       else
6106         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6107       DONE;
6108     }
6109   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6110     {
6111       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6112       DONE;
6113     }
6116 ;;This is incompatible with the way gcc uses subregs.
6117 ;;(define_insn "movv2sf_i"
6118 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6119 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6120 ;;  "TARGET_SHMEDIA_FPU
6121 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6122 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6123 ;;  "@
6124 ;;      #
6125 ;;      fld%M1.p        %m1, %0
6126 ;;      fst%M0.p        %m0, %1"
6127 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6129 (define_insn_and_split "movv2sf_i"
6130   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6131         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6132   "TARGET_SHMEDIA_FPU"
6133   "#"
6134   "TARGET_SHMEDIA_FPU && reload_completed"
6135   [(set (match_dup 0) (match_dup 1))]
6136   "
6138   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6139   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6142 (define_expand "movv2sf"
6143   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6144         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6145   "TARGET_SHMEDIA_FPU"
6146   "
6148   if (prepare_move_operands (operands, V2SFmode))
6149     DONE;
6152 (define_expand "addv2sf3"
6153   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6154    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6155    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6156   "TARGET_SHMEDIA_FPU"
6157   "
6159   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6160   DONE;
6163 (define_expand "subv2sf3"
6164   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6165    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6166    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6167   "TARGET_SHMEDIA_FPU"
6168   "
6170   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6171   DONE;
6174 (define_expand "mulv2sf3"
6175   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6176    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6177    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6178   "TARGET_SHMEDIA_FPU"
6179   "
6181   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6182   DONE;
6185 (define_expand "divv2sf3"
6186   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6187    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6188    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6189   "TARGET_SHMEDIA_FPU"
6190   "
6192   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6193   DONE;
6196 (define_insn_and_split "*movv4sf_i"
6197   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6198         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6199   "TARGET_SHMEDIA_FPU"
6200   "#"
6201   "&& reload_completed"
6202   [(const_int 0)]
6203   "
6205   int i;
6207   for (i = 0; i < 4/2; i++)
6208     {
6209       rtx x, y;
6211       if (GET_CODE (operands[0]) == MEM)
6212         x = adjust_address (operands[0], V2SFmode,
6213                             i * GET_MODE_SIZE (V2SFmode));
6214       else
6215         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6217       if (GET_CODE (operands[1]) == MEM)
6218         y = adjust_address (operands[1], V2SFmode,
6219                             i * GET_MODE_SIZE (V2SFmode));
6220       else
6221         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6223       emit_insn (gen_movv2sf_i (x, y));
6224     }
6226   DONE;
6228   [(set_attr "length" "8")])
6230 (define_expand "movv4sf"
6231   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6232         (match_operand:V4SF 1 "general_operand" ""))]
6233   "TARGET_SHMEDIA_FPU"
6234   "
6236   if (prepare_move_operands (operands, V4SFmode))
6237     DONE;
6240 (define_insn_and_split "*movv16sf_i"
6241   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6242         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6243   "TARGET_SHMEDIA_FPU"
6244   "#"
6245   "&& reload_completed"
6246   [(const_int 0)]
6247   "
6249   int i;
6251   for (i = 0; i < 16/2; i++)
6252     {
6253       rtx x,y;
6255       if (GET_CODE (operands[0]) == MEM)
6256         x = adjust_address (operands[0], V2SFmode,
6257                             i * GET_MODE_SIZE (V2SFmode));
6258       else
6259         {
6260           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6261           alter_subreg (&x);
6262         }
6264       if (GET_CODE (operands[1]) == MEM)
6265         y = adjust_address (operands[1], V2SFmode,
6266                             i * GET_MODE_SIZE (V2SFmode));
6267       else
6268         {
6269           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6270           alter_subreg (&y);
6271         }
6273       emit_insn (gen_movv2sf_i (x, y));
6274     }
6276   DONE;
6278   [(set_attr "length" "32")])
6280 (define_expand "movv16sf"
6281   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6282         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6283   "TARGET_SHMEDIA_FPU"
6284   "
6286   if (prepare_move_operands (operands, V16SFmode))
6287     DONE;
6290 (define_insn "movsf_media"
6291   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6292         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6293   "TARGET_SHMEDIA_FPU
6294    && (register_operand (operands[0], SFmode)
6295        || sh_register_operand (operands[1], SFmode))"
6296   "@
6297         fmov.s  %1, %0
6298         fmov.ls %N1, %0
6299         fmov.sl %1, %0
6300         add.l   %1, r63, %0
6301         #
6302         fld%M1.s        %m1, %0
6303         fst%M0.s        %m0, %1
6304         ld%M1.l %m1, %0
6305         st%M0.l %m0, %N1"
6306   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6307    (set (attr "highpart")
6308         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6309                (const_string "user")]
6310               (const_string "ignore")))])
6312 (define_insn "movsf_media_nofpu"
6313   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6314         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6315   "TARGET_SHMEDIA
6316    && (register_operand (operands[0], SFmode)
6317        || sh_register_operand (operands[1], SFmode))"
6318   "@
6319         add.l   %1, r63, %0
6320         #
6321         ld%M1.l %m1, %0
6322         st%M0.l %m0, %N1"
6323   [(set_attr "type" "arith_media,*,load_media,store_media")
6324    (set (attr "highpart")
6325         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6326                (const_string "user")]
6327               (const_string "ignore")))])
6329 (define_split
6330   [(set (match_operand:SF 0 "arith_reg_dest" "")
6331         (match_operand:SF 1 "immediate_operand" ""))]
6332   "TARGET_SHMEDIA && reload_completed
6333    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6334   [(set (match_dup 3) (match_dup 2))]
6335   "
6337   long values;
6338   REAL_VALUE_TYPE value;
6340   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6341   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6342   operands[2] = GEN_INT (values);
6344   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6347 (define_insn "movsf_i"
6348   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6349         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6350   "TARGET_SH1
6351    && (! TARGET_SH2E
6352        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6353        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6354        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6355    && (arith_reg_operand (operands[0], SFmode)
6356        || arith_reg_operand (operands[1], SFmode))"
6357   "@
6358         mov     %1,%0
6359         mov     #0,%0
6360         mov.l   %1,%0
6361         mov.l   %1,%0
6362         mov.l   %1,%0
6363         lds     %1,%0
6364         sts     %1,%0"
6365   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6367 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6368 ;; update_flow_info would not know where to put REG_EQUAL notes
6369 ;; when the destination changes mode.
6370 (define_insn "movsf_ie"
6371   [(set (match_operand:SF 0 "general_movdst_operand"
6372          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6373         (match_operand:SF 1 "general_movsrc_operand"
6374           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6375    (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"))
6376    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6378   "TARGET_SH2E
6379    && (arith_reg_operand (operands[0], SFmode)
6380        || arith_reg_operand (operands[1], SFmode)
6381        || arith_reg_operand (operands[3], SImode)
6382        || (fpul_operand (operands[0], SFmode)
6383            && memory_operand (operands[1], SFmode)
6384            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6385        || (fpul_operand (operands[1], SFmode)
6386            && memory_operand (operands[0], SFmode)
6387            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6388   "@
6389         fmov    %1,%0
6390         mov     %1,%0
6391         fldi0   %0
6392         fldi1   %0
6393         #
6394         fmov.s  %1,%0
6395         fmov.s  %1,%0
6396         mov.l   %1,%0
6397         mov.l   %1,%0
6398         mov.l   %1,%0
6399         fsts    fpul,%0
6400         flds    %1,fpul
6401         lds.l   %1,%0
6402         #
6403         sts     %1,%0
6404         lds     %1,%0
6405         sts.l   %1,%0
6406         lds.l   %1,%0
6407         ! move optimized away"
6408   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6409    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6410    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6411    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6412                                            (const_string "single")
6413                                            (const_string "none")))])
6415 (define_split
6416   [(set (match_operand:SF 0 "register_operand" "")
6417         (match_operand:SF 1 "register_operand" ""))
6418    (use (match_operand:PSI 2 "fpscr_operand" ""))
6419    (clobber (reg:SI FPUL_REG))]
6420   "TARGET_SH1"
6421   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6422               (use (match_dup 2))
6423               (clobber (scratch:SI))])
6424    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6425               (use (match_dup 2))
6426               (clobber (scratch:SI))])]
6427   "")
6429 (define_expand "movsf"
6430   [(set (match_operand:SF 0 "general_movdst_operand" "")
6431         (match_operand:SF 1 "general_movsrc_operand" ""))]
6432   ""
6433   "
6435   if (prepare_move_operands (operands, SFmode))
6436     DONE;
6437   if (TARGET_SHMEDIA)
6438     {
6439       if (TARGET_SHMEDIA_FPU)
6440         emit_insn (gen_movsf_media (operands[0], operands[1]));
6441       else
6442         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6443       DONE;
6444     }
6445   if (TARGET_SH2E)
6446     {
6447       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6448       DONE;
6449     }
6452 (define_insn "mov_nop"
6453   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6454   "TARGET_SH2E"
6455   ""
6456   [(set_attr "length" "0")
6457    (set_attr "type" "nil")])
6459 (define_expand "reload_insf__frn"
6460   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6461                    (match_operand:SF 1 "immediate_operand" "FQ"))
6462               (use (reg:PSI FPSCR_REG))
6463               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6464   "TARGET_SH1"
6465   "")
6467 (define_expand "reload_insi__i_fpul"
6468   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6469                    (match_operand:SI 1 "immediate_operand" "i"))
6470               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6471   "TARGET_SH1"
6472   "")
6474 (define_expand "ptabs"
6475   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6476   "TARGET_SHMEDIA"
6477   "
6479   if (!TARGET_PT_FIXED)
6480     {
6481       rtx eq = operands[1];
6483       /* ??? For canonical RTL we really should remove any CONST from EQ
6484          before wrapping it in the AND, and finally wrap the EQ into a
6485          const if is constant.  However, for reload we must expose the
6486          input register or symbolic constant, and we can't have
6487          different insn structures outside of the operands for different
6488          alternatives of the same pattern.  */
6489       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6490                        GEN_INT (3));
6491       operands[1]
6492         = (gen_rtx_IF_THEN_ELSE
6493             (PDImode,
6494              eq,
6495              gen_rtx_MEM (PDImode, operands[1]),
6496              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6497                             PDImode, operands[1])));
6498     }
6501 ;; expanded by ptabs expander.
6502 (define_insn "*extendsipdi_media"
6503   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6504         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6505                                                           "r,Csy")
6506                                       (const_int 3))
6507                               (const_int 3))
6508                           (mem:PDI (match_dup 1))
6509                           (sign_extend:PDI (match_dup 1))))]
6510   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6511   "@
6512         ptabs   %1, %0
6513         pt      %1, %0"
6514   [(set_attr "type"   "ptabs_media,pt_media")
6515    (set_attr "length" "4,*")])
6517 (define_insn "*truncdipdi_media"
6518   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6519         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6520                                                           "r,Csy")
6521                                       (const_int 3))
6522                               (const_int 3))
6523                           (mem:PDI (match_dup 1))
6524                           (truncate:PDI (match_dup 1))))]
6525   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6526   "@
6527         ptabs   %1, %0
6528         pt      %1, %0"
6529   [(set_attr "type"   "ptabs_media,pt_media")
6530    (set_attr "length" "4,*")])
6532 (define_insn "*movsi_y"
6533   [(set (match_operand:SI 0 "register_operand" "=y,y")
6534         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6535    (clobber (match_scratch:SI 2 "=&z,r"))]
6536   "TARGET_SH2E
6537    && (reload_in_progress || reload_completed)"
6538   "#"
6539   [(set_attr "length" "4")
6540    (set_attr "type" "pcload,move")])
6542 (define_split
6543   [(set (match_operand:SI 0 "register_operand" "")
6544         (match_operand:SI 1 "immediate_operand" ""))
6545    (clobber (match_operand:SI 2 "register_operand" ""))]
6546   "TARGET_SH1"
6547   [(set (match_dup 2) (match_dup 1))
6548    (set (match_dup 0) (match_dup 2))]
6549   "")
6551 (define_split
6552   [(set (match_operand:SI 0 "register_operand" "")
6553         (match_operand:SI 1 "memory_operand" ""))
6554    (clobber (reg:SI R0_REG))]
6555   "TARGET_SH1"
6556   [(set (match_dup 0) (match_dup 1))]
6557   "")
6559 ;; ------------------------------------------------------------------------
6560 ;; Define the real conditional branch instructions.
6561 ;; ------------------------------------------------------------------------
6563 (define_insn "branch_true"
6564   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6565                            (label_ref (match_operand 0 "" ""))
6566                            (pc)))]
6567   "TARGET_SH1"
6568   "* return output_branch (1, insn, operands);"
6569   [(set_attr "type" "cbranch")])
6571 (define_insn "branch_false"
6572   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6573                            (label_ref (match_operand 0 "" ""))
6574                            (pc)))]
6575   "TARGET_SH1"
6576   "* return output_branch (0, insn, operands);"
6577   [(set_attr "type" "cbranch")])
6579 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6580 ;; which destination is too far away.
6581 ;; The const_int_operand is distinct for each branch target; it avoids
6582 ;; unwanted matches with redundant_insn.
6583 (define_insn "block_branch_redirect"
6584   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6585   "TARGET_SH1"
6586   ""
6587   [(set_attr "length" "0")])
6589 ;; This one has the additional purpose to record a possible scratch register
6590 ;; for the following branch.
6591 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6592 ;; because the insn then might be deemed dead and deleted.  And we can't
6593 ;; make the use in the jump insn explicit because that would disable
6594 ;; delay slot scheduling from the target.
6595 (define_insn "indirect_jump_scratch"
6596   [(set (match_operand:SI 0 "register_operand" "=r")
6597         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6598    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6599   "TARGET_SH1"
6600   ""
6601   [(set_attr "length" "0")])
6603 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6604 ;; being pulled into the delay slot of a condbranch that has been made to
6605 ;; jump around the unconditional jump because it was out of range.
6606 (define_insn "stuff_delay_slot"
6607   [(set (pc)
6608         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6609    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6610   "TARGET_SH1"
6611   ""
6612   [(set_attr "length" "0")
6613    (set_attr "cond_delay_slot" "yes")])
6615 ;; Conditional branch insns
6617 (define_expand "beq_media"
6618   [(set (pc)
6619         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6620                           (match_operand:DI 2 "arith_operand" "r,I06"))
6621                       (match_operand 0 "" "")
6622                       (pc)))]
6623   "TARGET_SHMEDIA"
6624   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6626 (define_insn "*beq_media_i"
6627   [(set (pc)
6628         (if_then_else (match_operator 3 "equality_comparison_operator"
6629                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6630                          (match_operand:DI 2 "arith_operand" "r,I06")])
6631                       (match_operand 0 "target_operand" "b,b")
6632                       (pc)))]
6633   "TARGET_SHMEDIA"
6634   "@
6635         b%o3%'  %1, %2, %0%>
6636         b%o3i%' %1, %2, %0%>"
6637   [(set_attr "type" "cbranch_media")])
6639 (define_insn "*beq_media_i32"
6640   [(set (pc)
6641         (if_then_else (match_operator 3 "equality_comparison_operator"
6642                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6643                          (match_operand:SI 2 "arith_operand" "r,I06")])
6644                       (match_operand 0 "target_operand" "b,b")
6645                       (pc)))]
6646   "TARGET_SHMEDIA"
6647   "@
6648         b%o3%'  %1, %2, %0%>
6649         b%o3i%' %1, %2, %0%>"
6650   [(set_attr "type" "cbranch_media")])
6652 (define_expand "bne_media"
6653   [(set (pc)
6654         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6655                           (match_operand:DI 2 "arith_operand" "r,I06"))
6656                       (match_operand 0 "" "")
6657                       (pc)))]
6658   "TARGET_SHMEDIA"
6659   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6661 (define_expand "bgt_media"
6662   [(set (pc)
6663         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6664                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6665                       (match_operand 0 "" "")
6666                       (pc)))]
6667   "TARGET_SHMEDIA"
6668   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6670 (define_expand "bge_media"
6671   [(set (pc)
6672         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6673                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6674                       (match_operand 0 "" "")
6675                       (pc)))]
6676   "TARGET_SHMEDIA"
6677   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6679 (define_expand "bgtu_media"
6680   [(set (pc)
6681         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6682                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6683                       (match_operand 0 "" "")
6684                       (pc)))]
6685   "TARGET_SHMEDIA"
6686   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6688 (define_expand "bgeu_media"
6689   [(set (pc)
6690         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6691                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6692                       (match_operand 0 "" "")
6693                       (pc)))]
6694   "TARGET_SHMEDIA"
6695   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6697 (define_insn "*bgt_media_i"
6698   [(set (pc)
6699         (if_then_else (match_operator 3 "greater_comparison_operator"
6700                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6701                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6702                       (match_operand 0 "target_operand" "b")
6703                       (pc)))]
6704   "TARGET_SHMEDIA"
6705   "b%o3%'       %N1, %N2, %0%>"
6706   [(set_attr "type" "cbranch_media")])
6708 (define_insn "*bgt_media_i32"
6709   [(set (pc)
6710         (if_then_else (match_operator 3 "greater_comparison_operator"
6711                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6712                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6713                       (match_operand 0 "target_operand" "b")
6714                       (pc)))]
6715   "TARGET_SHMEDIA"
6716   "b%o3%'       %N1, %N2, %0%>"
6717   [(set_attr "type" "cbranch_media")])
6719 ;; These are only needed to make invert_jump() happy - otherwise, jump
6720 ;; optimization will be silently disabled.
6721 (define_insn "*blt_media_i"
6722   [(set (pc)
6723         (if_then_else (match_operator 3 "less_comparison_operator"
6724                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6725                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6726                       (match_operand 0 "target_operand" "b")
6727                       (pc)))]
6728   "TARGET_SHMEDIA"
6729   "b%o3%'       %N2, %N1, %0%>"
6730   [(set_attr "type" "cbranch_media")])
6732 (define_insn "*blt_media_i32"
6733   [(set (pc)
6734         (if_then_else (match_operator 3 "less_comparison_operator"
6735                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6736                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6737                       (match_operand 0 "target_operand" "b")
6738                       (pc)))]
6739   "TARGET_SHMEDIA"
6740   "b%o3%'       %N2, %N1, %0%>"
6741   [(set_attr "type" "cbranch_media")])
6743 (define_expand "beq"
6744   [(set (pc)
6745         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6746                       (label_ref (match_operand 0 "" ""))
6747                       (pc)))]
6748   ""
6749   "
6751   if (TARGET_SHMEDIA)
6752     {
6753       enum machine_mode mode = GET_MODE (sh_compare_op0);
6755       if (mode != DImode && mode != SImode)
6756         {
6757           rtx tmp = gen_reg_rtx (DImode);
6759           emit_insn (gen_seq (tmp));
6760           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6761           DONE;
6762         }
6764       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6765       if (CONSTANT_P (sh_compare_op1)
6766           && (GET_CODE (sh_compare_op1) != CONST_INT
6767               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6768         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6769       emit_jump_insn (gen_beq_media (operands[0],
6770                                      sh_compare_op0, sh_compare_op1));
6771       DONE;
6772     }
6774   from_compare (operands, EQ);
6777 (define_expand "bne"
6778   [(set (pc)
6779         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6780                       (label_ref (match_operand 0 "" ""))
6781                       (pc)))]
6782   ""
6783   "
6785   if (TARGET_SHMEDIA)
6786     {
6787       enum machine_mode mode = GET_MODE (sh_compare_op0);
6789       if (mode != DImode && mode != SImode)
6790         {
6791           rtx tmp = gen_reg_rtx (DImode);
6793           emit_insn (gen_seq (tmp));
6794           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6795           DONE;
6796         }
6798       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6799       if (CONSTANT_P (sh_compare_op1)
6800           && (GET_CODE (sh_compare_op1) != CONST_INT
6801               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6802         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6803       emit_jump_insn (gen_bne_media (operands[0],
6804                                      sh_compare_op0, sh_compare_op1));
6805       DONE;
6806     }
6808   from_compare (operands, EQ);
6811 (define_expand "bgt"
6812   [(set (pc)
6813         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6814                       (label_ref (match_operand 0 "" ""))
6815                       (pc)))]
6816   ""
6817   "
6819   if (TARGET_SHMEDIA)
6820     {
6821       enum machine_mode mode = GET_MODE (sh_compare_op0);
6823       if (mode != DImode && mode != SImode)
6824         {
6825           rtx tmp = gen_reg_rtx (DImode);
6827           emit_insn (gen_sgt (tmp));
6828           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6829           DONE;
6830         }
6832       if (sh_compare_op0 != const0_rtx)
6833         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6834       if (sh_compare_op1 != const0_rtx)
6835         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6836       emit_jump_insn (gen_bgt_media (operands[0],
6837                                      sh_compare_op0, sh_compare_op1));
6838       DONE;
6839     }
6841   from_compare (operands, GT);
6844 (define_expand "blt"
6845   [(set (pc)
6846         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6847                       (label_ref (match_operand 0 "" ""))
6848                       (pc)))]
6849   ""
6850   "
6852   if (TARGET_SHMEDIA)
6853     {
6854       enum machine_mode mode = GET_MODE (sh_compare_op0);
6856       if (mode != DImode && mode != SImode)
6857         {
6858           rtx tmp = gen_reg_rtx (DImode);
6860           emit_insn (gen_slt (tmp));
6861           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6862           DONE;
6863         }
6865       if (sh_compare_op0 != const0_rtx)
6866         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6867       if (sh_compare_op1 != const0_rtx)
6868         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6869       emit_jump_insn (gen_bgt_media (operands[0],
6870                                      sh_compare_op1, sh_compare_op0));
6871       DONE;
6872     }
6874   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6875     {
6876       rtx tmp = sh_compare_op0;
6877       sh_compare_op0 = sh_compare_op1;
6878       sh_compare_op1 = tmp;
6879       emit_insn (gen_bgt (operands[0]));
6880       DONE;
6881     }
6882   from_compare (operands, GE);
6885 (define_expand "ble"
6886   [(set (pc)
6887         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6888                       (label_ref (match_operand 0 "" ""))
6889                       (pc)))]
6890   ""
6891   "
6893   if (TARGET_SHMEDIA)
6894     {
6895       enum machine_mode mode = GET_MODE (sh_compare_op0);
6897       if (mode != DImode && mode != SImode)
6898         {
6899           rtx tmp = gen_reg_rtx (DImode);
6901           emit_insn (gen_sle (tmp));
6902           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6903           DONE;
6904         }
6906       if (sh_compare_op0 != const0_rtx)
6907         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6908       if (sh_compare_op1 != const0_rtx)
6909         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6910       emit_jump_insn (gen_bge_media (operands[0],
6911                                      sh_compare_op1, sh_compare_op0));
6912       DONE;
6913     }
6915   if (TARGET_SH2E
6916       && TARGET_IEEE
6917       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6918     {
6919       rtx tmp = sh_compare_op0;
6920       sh_compare_op0 = sh_compare_op1;
6921       sh_compare_op1 = tmp;
6922       emit_insn (gen_bge (operands[0]));
6923       DONE;
6924     }
6925   from_compare (operands, GT);
6928 (define_expand "bge"
6929   [(set (pc)
6930         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6931                       (label_ref (match_operand 0 "" ""))
6932                       (pc)))]
6933   ""
6934   "
6936   if (TARGET_SHMEDIA)
6937     {
6938       enum machine_mode mode = GET_MODE (sh_compare_op0);
6940       if (mode != DImode && mode != SImode)
6941         {
6942           rtx tmp = gen_reg_rtx (DImode);
6944           emit_insn (gen_sge (tmp));
6945           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6946           DONE;
6947         }
6949       if (sh_compare_op0 != const0_rtx)
6950         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6951       if (sh_compare_op1 != const0_rtx)
6952         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6953       emit_jump_insn (gen_bge_media (operands[0],
6954                                      sh_compare_op0, sh_compare_op1));
6955       DONE;
6956     }
6958   if (TARGET_SH2E
6959       && ! TARGET_IEEE
6960       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6961     {
6962       rtx tmp = sh_compare_op0;
6963       sh_compare_op0 = sh_compare_op1;
6964       sh_compare_op1 = tmp;
6965       emit_insn (gen_ble (operands[0]));
6966       DONE;
6967     }
6968   from_compare (operands, GE);
6971 (define_expand "bgtu"
6972   [(set (pc)
6973         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6974                       (label_ref (match_operand 0 "" ""))
6975                       (pc)))]
6976   ""
6977   "
6979   if (TARGET_SHMEDIA)
6980     {
6981       enum machine_mode mode = GET_MODE (sh_compare_op0);
6983       if (sh_compare_op0 != const0_rtx)
6984         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6985       if (sh_compare_op1 != const0_rtx)
6986         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6987       emit_jump_insn (gen_bgtu_media (operands[0],
6988                                       sh_compare_op0, sh_compare_op1));
6989       DONE;
6990     }
6992   from_compare (operands, GTU);
6995 (define_expand "bltu"
6996   [(set (pc)
6997         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6998                       (label_ref (match_operand 0 "" ""))
6999                       (pc)))]
7000   ""
7001   "
7003   if (TARGET_SHMEDIA)
7004     {
7005       enum machine_mode mode = GET_MODE (sh_compare_op0);
7007       if (sh_compare_op0 != const0_rtx)
7008         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7009       if (sh_compare_op1 != const0_rtx)
7010         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7011       emit_jump_insn (gen_bgtu_media (operands[0],
7012                                       sh_compare_op1, sh_compare_op0));
7013       DONE;
7014     }
7016   from_compare (operands, GEU);
7019 (define_expand "bgeu"
7020   [(set (pc)
7021         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7022                       (label_ref (match_operand 0 "" ""))
7023                       (pc)))]
7024   ""
7025   "
7027   if (TARGET_SHMEDIA)
7028     {
7029       enum machine_mode mode = GET_MODE (sh_compare_op0);
7031       if (sh_compare_op0 != const0_rtx)
7032         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7033       if (sh_compare_op1 != const0_rtx)
7034         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7035       emit_jump_insn (gen_bgeu_media (operands[0],
7036                                       sh_compare_op0, sh_compare_op1));
7037       DONE;
7038     }
7040   from_compare (operands, GEU);
7043 (define_expand "bleu"
7044   [(set (pc)
7045         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7046                       (label_ref (match_operand 0 "" ""))
7047                       (pc)))]
7048   ""
7049   "
7051   if (TARGET_SHMEDIA)
7052     {
7053       enum machine_mode mode = GET_MODE (sh_compare_op0);
7055       if (sh_compare_op0 != const0_rtx)
7056         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7057       if (sh_compare_op1 != const0_rtx)
7058         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7059       emit_jump_insn (gen_bgeu_media (operands[0],
7060                                       sh_compare_op1, sh_compare_op0));
7061       DONE;
7062     }
7064   from_compare (operands, GTU);
7067 (define_expand "bunordered"
7068   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7069    (set (pc)
7070         (if_then_else (ne (match_dup 1) (const_int 0))
7071                       (match_operand 0 "" "")
7072                       (pc)))]
7073   "TARGET_SHMEDIA"
7074   "
7076   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7077   operands[1] = gen_reg_rtx (DImode);
7078   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7079   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7082 ;; combiner splitter for test-and-branch on single bit in register.  This
7083 ;; is endian dependent because the non-paradoxical subreg looks different
7084 ;; on big endian.
7085 (define_split
7086   [(set (pc)
7087         (if_then_else
7088           (match_operator 3 "equality_comparison_operator"
7089             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7090                                                       "extend_reg_operand" "")
7091                                                     0)
7092                                          (const_int 1)
7093                                          (match_operand 2
7094                                           "const_int_operand" "")) 0)
7095              (const_int 0)])
7096           (match_operand 0 "target_operand" "")
7097           (pc)))
7098    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7099   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7100   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7101    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7103   "
7105   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7106   operands[6] = (GET_CODE (operands[3]) == EQ
7107                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7108                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7111 ;; ------------------------------------------------------------------------
7112 ;; Jump and linkage insns
7113 ;; ------------------------------------------------------------------------
7115 (define_insn "jump_compact"
7116   [(set (pc)
7117         (label_ref (match_operand 0 "" "")))]
7118   "TARGET_SH1"
7119   "*
7121   /* The length is 16 if the delay slot is unfilled.  */
7122   if (get_attr_length(insn) > 4)
7123     return output_far_jump(insn, operands[0]);
7124   else
7125     return   \"bra      %l0%#\";
7127   [(set_attr "type" "jump")
7128    (set_attr "needs_delay_slot" "yes")])
7130 ;; ??? It would be much saner to explicitly use the scratch register
7131 ;; in the jump insn, and have indirect_jump_scratch only set it,
7132 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7133 ;; from the target then, as it uses simplejump_p.
7134 ;;(define_insn "jump_compact_far"
7135 ;;  [(set (pc)
7136 ;;      (label_ref (match_operand 0 "" "")))
7137 ;;   (use (match_operand 1 "register_operand" "r")]
7138 ;;  "TARGET_SH1"
7139 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7140 ;;  [(set_attr "type" "jump")
7141 ;;   (set_attr "needs_delay_slot" "yes")])
7143 (define_insn "jump_media"
7144   [(set (pc)
7145         (match_operand 0 "target_operand" "b"))]
7146   "TARGET_SHMEDIA"
7147   "blink        %0, r63%>"
7148   [(set_attr "type" "jump_media")])
7150 (define_expand "jump"
7151   [(set (pc)
7152         (label_ref (match_operand 0 "" "")))]
7153   ""
7154   "
7156   if (TARGET_SH1)
7157     emit_jump_insn (gen_jump_compact (operands[0]));
7158   else if (TARGET_SHMEDIA)
7159     {
7160       if (reload_in_progress || reload_completed)
7161         FAIL;
7162       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7163                                                          operands[0])));
7164     }
7165   DONE;
7168 (define_insn "force_mode_for_call"
7169   [(use (reg:PSI FPSCR_REG))]
7170   "TARGET_SHCOMPACT"
7171   ""
7172   [(set_attr "length" "0")
7173    (set (attr "fp_mode")
7174         (if_then_else (eq_attr "fpu_single" "yes")
7175                       (const_string "single") (const_string "double")))])
7177 (define_insn "calli"
7178   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7179          (match_operand 1 "" ""))
7180    (use (reg:PSI FPSCR_REG))
7181    (clobber (reg:SI PR_REG))]
7182   "TARGET_SH1"
7183   "jsr  @%0%#"
7184   [(set_attr "type" "call")
7185    (set (attr "fp_mode")
7186         (if_then_else (eq_attr "fpu_single" "yes")
7187                       (const_string "single") (const_string "double")))
7188    (set_attr "needs_delay_slot" "yes")
7189    (set_attr "fp_set" "unknown")])
7191 ;; This is a pc-rel call, using bsrf, for use with PIC.
7193 (define_insn "calli_pcrel"
7194   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7195          (match_operand 1 "" ""))
7196    (use (reg:PSI FPSCR_REG))
7197    (use (reg:SI PIC_REG))
7198    (use (match_operand 2 "" ""))
7199    (clobber (reg:SI PR_REG))]
7200   "TARGET_SH2"
7201   "bsrf %0\\n%O2:%#"
7202   [(set_attr "type" "call")
7203    (set (attr "fp_mode")
7204         (if_then_else (eq_attr "fpu_single" "yes")
7205                       (const_string "single") (const_string "double")))
7206    (set_attr "needs_delay_slot" "yes")
7207    (set_attr "fp_set" "unknown")])
7209 (define_insn_and_split "call_pcrel"
7210   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7211          (match_operand 1 "" ""))
7212    (use (reg:PSI FPSCR_REG))
7213    (use (reg:SI PIC_REG))
7214    (clobber (reg:SI PR_REG))
7215    (clobber (match_scratch:SI 2 "=r"))]
7216   "TARGET_SH2"
7217   "#"
7218   "reload_completed"
7219   [(const_int 0)]
7220   "
7222   rtx lab = PATTERN (gen_call_site ());
7224   if (SYMBOL_REF_LOCAL_P (operands[0]))
7225     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7226   else
7227     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7228   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7229   DONE;
7231   [(set_attr "type" "call")
7232    (set (attr "fp_mode")
7233         (if_then_else (eq_attr "fpu_single" "yes")
7234                       (const_string "single") (const_string "double")))
7235    (set_attr "needs_delay_slot" "yes")
7236    (set_attr "fp_set" "unknown")])
7238 (define_insn "call_compact"
7239   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7240          (match_operand 1 "" ""))
7241    (match_operand 2 "immediate_operand" "n")
7242    (use (reg:SI R0_REG))
7243    (use (reg:SI R1_REG))
7244    (use (reg:PSI FPSCR_REG))
7245    (clobber (reg:SI PR_REG))]
7246   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7247   "jsr  @%0%#"
7248   [(set_attr "type" "call")
7249    (set (attr "fp_mode")
7250         (if_then_else (eq_attr "fpu_single" "yes")
7251                       (const_string "single") (const_string "double")))
7252    (set_attr "needs_delay_slot" "yes")])
7254 (define_insn "call_compact_rettramp"
7255   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7256          (match_operand 1 "" ""))
7257    (match_operand 2 "immediate_operand" "n")
7258    (use (reg:SI R0_REG))
7259    (use (reg:SI R1_REG))
7260    (use (reg:PSI FPSCR_REG))
7261    (clobber (reg:SI R10_REG))
7262    (clobber (reg:SI PR_REG))]
7263   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7264   "jsr  @%0%#"
7265   [(set_attr "type" "call")
7266    (set (attr "fp_mode")
7267         (if_then_else (eq_attr "fpu_single" "yes")
7268                       (const_string "single") (const_string "double")))
7269    (set_attr "needs_delay_slot" "yes")])
7271 (define_insn "call_media"
7272   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7273          (match_operand 1 "" ""))
7274    (clobber (reg:DI PR_MEDIA_REG))]
7275   "TARGET_SHMEDIA"
7276   "blink        %0, r18"
7277   [(set_attr "type" "jump_media")])
7279 (define_insn "call_valuei"
7280   [(set (match_operand 0 "" "=rf")
7281         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7282               (match_operand 2 "" "")))
7283    (use (reg:PSI FPSCR_REG))
7284    (clobber (reg:SI PR_REG))]
7285   "TARGET_SH1"
7286   "jsr  @%1%#"
7287   [(set_attr "type" "call")
7288    (set (attr "fp_mode")
7289         (if_then_else (eq_attr "fpu_single" "yes")
7290                       (const_string "single") (const_string "double")))
7291    (set_attr "needs_delay_slot" "yes")
7292    (set_attr "fp_set" "unknown")])
7294 (define_insn "call_valuei_pcrel"
7295   [(set (match_operand 0 "" "=rf")
7296         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7297               (match_operand 2 "" "")))
7298    (use (reg:PSI FPSCR_REG))
7299    (use (reg:SI PIC_REG))
7300    (use (match_operand 3 "" ""))
7301    (clobber (reg:SI PR_REG))]
7302   "TARGET_SH2"
7303   "bsrf %1\\n%O3:%#"
7304   [(set_attr "type" "call")
7305    (set (attr "fp_mode")
7306         (if_then_else (eq_attr "fpu_single" "yes")
7307                       (const_string "single") (const_string "double")))
7308    (set_attr "needs_delay_slot" "yes")
7309    (set_attr "fp_set" "unknown")])
7311 (define_insn_and_split "call_value_pcrel"
7312   [(set (match_operand 0 "" "=rf")
7313         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7314               (match_operand 2 "" "")))
7315    (use (reg:PSI FPSCR_REG))
7316    (use (reg:SI PIC_REG))
7317    (clobber (reg:SI PR_REG))
7318    (clobber (match_scratch:SI 3 "=r"))]
7319   "TARGET_SH2"
7320   "#"
7321   "reload_completed"
7322   [(const_int 0)]
7323   "
7325   rtx lab = PATTERN (gen_call_site ());
7327   if (SYMBOL_REF_LOCAL_P (operands[1]))
7328     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7329   else
7330     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7331   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7332                                          operands[2], lab));
7333   DONE;
7335   [(set_attr "type" "call")
7336    (set (attr "fp_mode")
7337         (if_then_else (eq_attr "fpu_single" "yes")
7338                       (const_string "single") (const_string "double")))
7339    (set_attr "needs_delay_slot" "yes")
7340    (set_attr "fp_set" "unknown")])
7342 (define_insn "call_value_compact"
7343   [(set (match_operand 0 "" "=rf")
7344         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7345               (match_operand 2 "" "")))
7346    (match_operand 3 "immediate_operand" "n")
7347    (use (reg:SI R0_REG))
7348    (use (reg:SI R1_REG))
7349    (use (reg:PSI FPSCR_REG))
7350    (clobber (reg:SI PR_REG))]
7351   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7352   "jsr  @%1%#"
7353   [(set_attr "type" "call")
7354    (set (attr "fp_mode")
7355         (if_then_else (eq_attr "fpu_single" "yes")
7356                       (const_string "single") (const_string "double")))
7357    (set_attr "needs_delay_slot" "yes")])
7359 (define_insn "call_value_compact_rettramp"
7360   [(set (match_operand 0 "" "=rf")
7361         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7362               (match_operand 2 "" "")))
7363    (match_operand 3 "immediate_operand" "n")
7364    (use (reg:SI R0_REG))
7365    (use (reg:SI R1_REG))
7366    (use (reg:PSI FPSCR_REG))
7367    (clobber (reg:SI R10_REG))
7368    (clobber (reg:SI PR_REG))]
7369   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7370   "jsr  @%1%#"
7371   [(set_attr "type" "call")
7372    (set (attr "fp_mode")
7373         (if_then_else (eq_attr "fpu_single" "yes")
7374                       (const_string "single") (const_string "double")))
7375    (set_attr "needs_delay_slot" "yes")])
7377 (define_insn "call_value_media"
7378   [(set (match_operand 0 "" "=rf")
7379         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7380               (match_operand 2 "" "")))
7381    (clobber (reg:DI PR_MEDIA_REG))]
7382   "TARGET_SHMEDIA"
7383   "blink        %1, r18"
7384   [(set_attr "type" "jump_media")])
7386 (define_expand "call"
7387   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7388                             (match_operand 1 "" ""))
7389               (match_operand 2 "" "")
7390               (use (reg:PSI FPSCR_REG))
7391               (clobber (reg:SI PR_REG))])]
7392   ""
7393   "
7395   if (TARGET_SHMEDIA)
7396     {
7397       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7398       emit_call_insn (gen_call_media (operands[0], operands[1]));
7399       DONE;
7400     }
7401   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7402     {
7403       rtx cookie_rtx = operands[2];
7404       long cookie = INTVAL (cookie_rtx);
7405       rtx func = XEXP (operands[0], 0);
7406       rtx r0, r1;
7408       if (flag_pic)
7409         {
7410           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7411             {
7412               rtx reg = gen_reg_rtx (Pmode);
7414               emit_insn (gen_symGOTPLT2reg (reg, func));
7415               func = reg;
7416             }
7417           else
7418             func = legitimize_pic_address (func, Pmode, 0);
7419         }
7421       r0 = gen_rtx_REG (SImode, R0_REG);
7422       r1 = gen_rtx_REG (SImode, R1_REG);
7424       /* Since such a call function may use all call-clobbered
7425          registers, we force a mode switch earlier, so that we don't
7426          run out of registers when adjusting fpscr for the call.  */
7427       emit_insn (gen_force_mode_for_call ());
7429       operands[0]
7430         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7431                            SFUNC_GOT);
7432       operands[0] = force_reg (SImode, operands[0]);
7434       emit_move_insn (r0, func);
7435       emit_move_insn (r1, cookie_rtx);
7437       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7438         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7439                                                    operands[2]));
7440       else
7441         emit_call_insn (gen_call_compact (operands[0], operands[1],
7442                                           operands[2]));
7444       DONE;
7445     }
7446   else if (TARGET_SHCOMPACT && flag_pic
7447            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7448            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7449     {
7450       rtx reg = gen_reg_rtx (Pmode);
7452       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7453       XEXP (operands[0], 0) = reg;
7454     }
7455   if (flag_pic && TARGET_SH2
7456       && GET_CODE (operands[0]) == MEM
7457       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7458     {
7459       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7460       DONE;
7461     }
7462   else
7463   {
7464     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7465     operands[1] = operands[2];
7466   }
7468   emit_call_insn (gen_calli (operands[0], operands[1]));
7469   DONE;
7472 (define_insn "call_pop_compact"
7473   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7474          (match_operand 1 "" ""))
7475    (match_operand 2 "immediate_operand" "n")
7476    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7477                                  (match_operand 3 "immediate_operand" "n")))
7478    (use (reg:SI R0_REG))
7479    (use (reg:SI R1_REG))
7480    (use (reg:PSI FPSCR_REG))
7481    (clobber (reg:SI PR_REG))]
7482   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7483   "jsr  @%0%#"
7484   [(set_attr "type" "call")
7485    (set (attr "fp_mode")
7486         (if_then_else (eq_attr "fpu_single" "yes")
7487                       (const_string "single") (const_string "double")))
7488    (set_attr "needs_delay_slot" "yes")])
7490 (define_insn "call_pop_compact_rettramp"
7491   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7492          (match_operand 1 "" ""))
7493    (match_operand 2 "immediate_operand" "n")
7494    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7495                                  (match_operand 3 "immediate_operand" "n")))
7496    (use (reg:SI R0_REG))
7497    (use (reg:SI R1_REG))
7498    (use (reg:PSI FPSCR_REG))
7499    (clobber (reg:SI R10_REG))
7500    (clobber (reg:SI PR_REG))]
7501   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7502   "jsr  @%0%#"
7503   [(set_attr "type" "call")
7504    (set (attr "fp_mode")
7505         (if_then_else (eq_attr "fpu_single" "yes")
7506                       (const_string "single") (const_string "double")))
7507    (set_attr "needs_delay_slot" "yes")])
7509 (define_expand "call_pop"
7510   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7511                     (match_operand 1 "" ""))
7512              (match_operand 2 "" "")
7513              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7514                                            (match_operand 3 "" "")))])]
7515   "TARGET_SHCOMPACT"
7516   "
7518   rtx cookie_rtx;
7519   long cookie;
7520   rtx func;
7521   rtx r0, r1;
7523   gcc_assert (operands[2] && INTVAL (operands[2]));
7524   cookie_rtx = operands[2];
7525   cookie = INTVAL (cookie_rtx);
7526   func = XEXP (operands[0], 0);
7528   if (flag_pic)
7529     {
7530       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7531         {
7532           rtx reg = gen_reg_rtx (Pmode);
7533           emit_insn (gen_symGOTPLT2reg (reg, func));
7534           func = reg;
7535         }
7536       else
7537         func = legitimize_pic_address (func, Pmode, 0);
7538     }
7540   r0 = gen_rtx_REG (SImode, R0_REG);
7541   r1 = gen_rtx_REG (SImode, R1_REG);
7543   /* Since such a call function may use all call-clobbered
7544      registers, we force a mode switch earlier, so that we don't
7545      run out of registers when adjusting fpscr for the call.  */
7546   emit_insn (gen_force_mode_for_call ());
7548   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7549                                  SFUNC_GOT);
7550   operands[0] = force_reg (SImode, operands[0]);
7552   emit_move_insn (r0, func);
7553   emit_move_insn (r1, cookie_rtx);
7555   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7556     emit_call_insn (gen_call_pop_compact_rettramp
7557                      (operands[0], operands[1], operands[2], operands[3]));
7558   else
7559     emit_call_insn (gen_call_pop_compact
7560                      (operands[0], operands[1], operands[2], operands[3]));
7562   DONE;
7565 (define_expand "call_value"
7566   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7567                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7568                                  (match_operand 2 "" "")))
7569               (match_operand 3 "" "")
7570               (use (reg:PSI FPSCR_REG))
7571               (clobber (reg:SI PR_REG))])]
7572   ""
7573   "
7575   if (TARGET_SHMEDIA)
7576     {
7577       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7578       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7579                                             operands[2]));
7580       DONE;
7581     }
7582   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7583     {
7584       rtx cookie_rtx = operands[3];
7585       long cookie = INTVAL (cookie_rtx);
7586       rtx func = XEXP (operands[1], 0);
7587       rtx r0, r1;
7589       if (flag_pic)
7590         {
7591           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7592             {
7593               rtx reg = gen_reg_rtx (Pmode);
7595               emit_insn (gen_symGOTPLT2reg (reg, func));
7596               func = reg;
7597             }
7598           else
7599             func = legitimize_pic_address (func, Pmode, 0);
7600         }
7602       r0 = gen_rtx_REG (SImode, R0_REG);
7603       r1 = gen_rtx_REG (SImode, R1_REG);
7605       /* Since such a call function may use all call-clobbered
7606          registers, we force a mode switch earlier, so that we don't
7607          run out of registers when adjusting fpscr for the call.  */
7608       emit_insn (gen_force_mode_for_call ());
7610       operands[1]
7611         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7612                            SFUNC_GOT);
7613       operands[1] = force_reg (SImode, operands[1]);
7615       emit_move_insn (r0, func);
7616       emit_move_insn (r1, cookie_rtx);
7618       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7619         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7620                                                          operands[1],
7621                                                          operands[2],
7622                                                          operands[3]));
7623       else
7624         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7625                                                 operands[2], operands[3]));
7627       DONE;
7628     }
7629   else if (TARGET_SHCOMPACT && flag_pic
7630            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7631            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7632     {
7633       rtx reg = gen_reg_rtx (Pmode);
7635       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7636       XEXP (operands[1], 0) = reg;
7637     }
7638   if (flag_pic && TARGET_SH2
7639       && GET_CODE (operands[1]) == MEM
7640       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7641     {
7642       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7643                                             operands[2]));
7644       DONE;
7645     }
7646   else
7647     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7649   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7650   DONE;
7653 (define_insn "sibcalli"
7654   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7655          (match_operand 1 "" ""))
7656    (use (reg:PSI FPSCR_REG))
7657    (return)]
7658   "TARGET_SH1"
7659   "jmp  @%0%#"
7660   [(set_attr "needs_delay_slot" "yes")
7661    (set (attr "fp_mode")
7662         (if_then_else (eq_attr "fpu_single" "yes")
7663                       (const_string "single") (const_string "double")))
7664    (set_attr "type" "jump_ind")])
7666 (define_insn "sibcalli_pcrel"
7667   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7668          (match_operand 1 "" ""))
7669    (use (match_operand 2 "" ""))
7670    (use (reg:PSI FPSCR_REG))
7671    (return)]
7672   "TARGET_SH2"
7673   "braf %0\\n%O2:%#"
7674   [(set_attr "needs_delay_slot" "yes")
7675    (set (attr "fp_mode")
7676         (if_then_else (eq_attr "fpu_single" "yes")
7677                       (const_string "single") (const_string "double")))
7678    (set_attr "type" "jump_ind")])
7680 ;; This uses an unspec to describe that the symbol_ref is very close.
7681 (define_insn "sibcalli_thunk"
7682   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7683                              UNSPEC_THUNK))
7684          (match_operand 1 "" ""))
7685    (use (reg:PSI FPSCR_REG))
7686    (return)]
7687   "TARGET_SH1"
7688   "bra  %O0"
7689   [(set_attr "needs_delay_slot" "yes")
7690    (set (attr "fp_mode")
7691         (if_then_else (eq_attr "fpu_single" "yes")
7692                       (const_string "single") (const_string "double")))
7693    (set_attr "type" "jump")
7694    (set_attr "length" "2")])
7696 (define_insn_and_split "sibcall_pcrel"
7697   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7698          (match_operand 1 "" ""))
7699    (use (reg:PSI FPSCR_REG))
7700    (clobber (match_scratch:SI 2 "=k"))
7701    (return)]
7702   "TARGET_SH2"
7703   "#"
7704   "reload_completed"
7705   [(const_int 0)]
7706   "
7708   rtx lab = PATTERN (gen_call_site ());
7709   rtx call_insn;
7711   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7712   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7713                                                   lab));
7714   SIBLING_CALL_P (call_insn) = 1;
7715   DONE;
7717   [(set_attr "needs_delay_slot" "yes")
7718    (set (attr "fp_mode")
7719         (if_then_else (eq_attr "fpu_single" "yes")
7720                       (const_string "single") (const_string "double")))
7721    (set_attr "type" "jump_ind")])
7723 (define_insn "sibcall_compact"
7724   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7725          (match_operand 1 "" ""))
7726    (return)
7727    (use (match_operand:SI 2 "register_operand" "z,x"))
7728    (use (reg:SI R1_REG))
7729    (use (reg:PSI FPSCR_REG))
7730    ;; We want to make sure the `x' above will only match MACH_REG
7731    ;; because sibcall_epilogue may clobber MACL_REG.
7732    (clobber (reg:SI MACL_REG))]
7733   "TARGET_SHCOMPACT"
7734   "@
7735         jmp     @%0%#
7736         jmp     @%0\\n  sts     %2, r0"
7737   [(set_attr "needs_delay_slot" "yes,no")
7738    (set_attr "length" "2,4")
7739    (set (attr "fp_mode") (const_string "single"))
7740    (set_attr "type" "jump_ind")])
7742 (define_insn "sibcall_media"
7743   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7744          (match_operand 1 "" ""))
7745    (use (reg:SI PR_MEDIA_REG))
7746    (return)]
7747   "TARGET_SHMEDIA"
7748   "blink        %0, r63"
7749   [(set_attr "type" "jump_media")])
7751 (define_expand "sibcall"
7752   [(parallel
7753     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7754            (match_operand 1 "" ""))
7755      (match_operand 2 "" "")
7756      (use (reg:PSI FPSCR_REG))
7757      (return)])]
7758   ""
7759   "
7761   if (TARGET_SHMEDIA)
7762     {
7763       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7764       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7765       DONE;
7766     }
7767   else if (TARGET_SHCOMPACT && operands[2]
7768            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7769     {
7770       rtx cookie_rtx = operands[2];
7771       long cookie = INTVAL (cookie_rtx);
7772       rtx func = XEXP (operands[0], 0);
7773       rtx mach, r1;
7775       if (flag_pic)
7776         {
7777           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7778             {
7779               rtx reg = gen_reg_rtx (Pmode);
7781               emit_insn (gen_symGOT2reg (reg, func));
7782               func = reg;
7783             }
7784           else
7785             func = legitimize_pic_address (func, Pmode, 0);
7786         }
7788       /* FIXME: if we could tell whether all argument registers are
7789          already taken, we could decide whether to force the use of
7790          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7791          simple way to tell.  We could use the CALL_COOKIE, but we
7792          can't currently tell a register used for regular argument
7793          passing from one that is unused.  If we leave it up to reload
7794          to decide which register to use, it seems to always choose
7795          R0_REG, which leaves no available registers in SIBCALL_REGS
7796          to hold the address of the trampoline.  */
7797       mach = gen_rtx_REG (SImode, MACH_REG);
7798       r1 = gen_rtx_REG (SImode, R1_REG);
7800       /* Since such a call function may use all call-clobbered
7801          registers, we force a mode switch earlier, so that we don't
7802          run out of registers when adjusting fpscr for the call.  */
7803       emit_insn (gen_force_mode_for_call ());
7805       operands[0]
7806         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7807                            SFUNC_GOT);
7808       operands[0] = force_reg (SImode, operands[0]);
7810       /* We don't need a return trampoline, since the callee will
7811          return directly to the upper caller.  */
7812       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7813         {
7814           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7815           cookie_rtx = GEN_INT (cookie);
7816         }
7818       emit_move_insn (mach, func);
7819       emit_move_insn (r1, cookie_rtx);
7821       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7822       DONE;
7823     }
7824   else if (TARGET_SHCOMPACT && flag_pic
7825            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7826            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7827     {
7828       rtx reg = gen_reg_rtx (Pmode);
7830       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7831       XEXP (operands[0], 0) = reg;
7832     }
7833   if (flag_pic && TARGET_SH2
7834       && GET_CODE (operands[0]) == MEM
7835       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7836       /* The PLT needs the PIC register, but the epilogue would have
7837          to restore it, so we can only use PC-relative PIC calls for
7838          static functions.  */
7839       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7840     {
7841       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7842       DONE;
7843     }
7844   else
7845     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7847   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7848   DONE;
7851 (define_expand "sibcall_value"
7852   [(set (match_operand 0 "" "")
7853         (call (match_operand 1 "" "")
7854               (match_operand 2 "" "")))
7855    (match_operand 3 "" "")]
7856   ""
7857   "
7859   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7860   DONE;
7863 (define_insn "call_value_pop_compact"
7864   [(set (match_operand 0 "" "=rf")
7865         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7866               (match_operand 2 "" "")))
7867    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7868                                  (match_operand 4 "immediate_operand" "n")))
7869    (match_operand 3 "immediate_operand" "n")
7870    (use (reg:SI R0_REG))
7871    (use (reg:SI R1_REG))
7872    (use (reg:PSI FPSCR_REG))
7873    (clobber (reg:SI PR_REG))]
7874   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7875   "jsr  @%1%#"
7876   [(set_attr "type" "call")
7877    (set (attr "fp_mode")
7878         (if_then_else (eq_attr "fpu_single" "yes")
7879                       (const_string "single") (const_string "double")))
7880    (set_attr "needs_delay_slot" "yes")])
7882 (define_insn "call_value_pop_compact_rettramp"
7883   [(set (match_operand 0 "" "=rf")
7884         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7885               (match_operand 2 "" "")))
7886    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7887                                  (match_operand 4 "immediate_operand" "n")))
7888    (match_operand 3 "immediate_operand" "n")
7889    (use (reg:SI R0_REG))
7890    (use (reg:SI R1_REG))
7891    (use (reg:PSI FPSCR_REG))
7892    (clobber (reg:SI R10_REG))
7893    (clobber (reg:SI PR_REG))]
7894   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7895   "jsr  @%1%#"
7896   [(set_attr "type" "call")
7897    (set (attr "fp_mode")
7898         (if_then_else (eq_attr "fpu_single" "yes")
7899                       (const_string "single") (const_string "double")))
7900    (set_attr "needs_delay_slot" "yes")])
7902 (define_expand "call_value_pop"
7903   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7904                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7905                                  (match_operand 2 "" "")))
7906               (match_operand 3 "" "")
7907               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7908                                             (match_operand 4 "" "")))])]
7909   "TARGET_SHCOMPACT"
7910   "
7912   rtx cookie_rtx;
7913   long cookie;
7914   rtx func;
7915   rtx r0, r1;
7917   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7918   cookie_rtx = operands[3];
7919   cookie = INTVAL (cookie_rtx);
7920   func = XEXP (operands[1], 0);
7922   if (flag_pic)
7923     {
7924       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7925         {
7926           rtx reg = gen_reg_rtx (Pmode);
7928           emit_insn (gen_symGOTPLT2reg (reg, func));
7929           func = reg;
7930         }
7931       else
7932         func = legitimize_pic_address (func, Pmode, 0);
7933     }
7935   r0 = gen_rtx_REG (SImode, R0_REG);
7936   r1 = gen_rtx_REG (SImode, R1_REG);
7938   /* Since such a call function may use all call-clobbered
7939      registers, we force a mode switch earlier, so that we don't
7940      run out of registers when adjusting fpscr for the call.  */
7941   emit_insn (gen_force_mode_for_call ());
7943   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7944                                  SFUNC_GOT);
7945   operands[1] = force_reg (SImode, operands[1]);
7947   emit_move_insn (r0, func);
7948   emit_move_insn (r1, cookie_rtx);
7950   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7951     emit_call_insn (gen_call_value_pop_compact_rettramp
7952                         (operands[0], operands[1], operands[2],
7953                          operands[3], operands[4]));
7954   else
7955     emit_call_insn (gen_call_value_pop_compact
7956                         (operands[0], operands[1], operands[2],
7957                          operands[3], operands[4]));
7959   DONE;
7962 (define_expand "sibcall_epilogue"
7963   [(return)]
7964   ""
7965   "
7967   sh_expand_epilogue (1);
7968   if (TARGET_SHCOMPACT)
7969     {
7970       rtx insn, set;
7972       /* If epilogue clobbers r0, preserve it in macl.  */
7973       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7974         if ((set = single_set (insn))
7975             && GET_CODE (SET_DEST (set)) == REG
7976             && REGNO (SET_DEST (set)) == R0_REG)
7977           {
7978             rtx r0 = gen_rtx_REG (SImode, R0_REG);
7979             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
7980             rtx i;
7982             /* We can't tell at this point whether the sibcall is a
7983                sibcall_compact and, if it is, whether it uses r0 or
7984                mach as operand 2, so let the instructions that
7985                preserve r0 be optimized away if r0 turns out to be
7986                dead.  */
7987             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
7988             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
7989                                                REG_NOTES (i));
7990             i = emit_move_insn (r0, tmp);
7991             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
7992                                                REG_NOTES (i));
7993             break;
7994           }
7995     }
7996   DONE;
7999 (define_insn "indirect_jump_compact"
8000   [(set (pc)
8001         (match_operand:SI 0 "arith_reg_operand" "r"))]
8002   "TARGET_SH1"
8003   "jmp  @%0%#"
8004   [(set_attr "needs_delay_slot" "yes")
8005    (set_attr "type" "jump_ind")])
8007 (define_expand "indirect_jump"
8008   [(set (pc)
8009         (match_operand 0 "register_operand" ""))]
8010   ""
8011   "
8013   if (GET_MODE (operands[0]) != Pmode)
8014     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8017 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8018 ;; which can be present in structured code from indirect jumps which can not
8019 ;; be present in structured code.  This allows -fprofile-arcs to work.
8021 ;; For SH1 processors.
8022 (define_insn "casesi_jump_1"
8023   [(set (pc)
8024         (match_operand:SI 0 "register_operand" "r"))
8025    (use (label_ref (match_operand 1 "" "")))]
8026   "TARGET_SH1"
8027   "jmp  @%0%#"
8028   [(set_attr "needs_delay_slot" "yes")
8029    (set_attr "type" "jump_ind")])
8031 ;; For all later processors.
8032 (define_insn "casesi_jump_2"
8033   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8034                       (label_ref (match_operand 1 "" ""))))
8035    (use (label_ref (match_operand 2 "" "")))]
8036   "TARGET_SH2
8037    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8038   "braf %0%#"
8039   [(set_attr "needs_delay_slot" "yes")
8040    (set_attr "type" "jump_ind")])
8042 (define_insn "casesi_jump_media"
8043   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8044    (use (label_ref (match_operand 1 "" "")))]
8045   "TARGET_SHMEDIA"
8046   "blink        %0, r63"
8047   [(set_attr "type" "jump_media")])
8049 ;; Call subroutine returning any type.
8050 ;; ??? This probably doesn't work.
8052 (define_expand "untyped_call"
8053   [(parallel [(call (match_operand 0 "" "")
8054                     (const_int 0))
8055               (match_operand 1 "" "")
8056               (match_operand 2 "" "")])]
8057   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8058   "
8060   int i;
8062   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8064   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8065     {
8066       rtx set = XVECEXP (operands[2], 0, i);
8067       emit_move_insn (SET_DEST (set), SET_SRC (set));
8068     }
8070   /* The optimizer does not know that the call sets the function value
8071      registers we stored in the result block.  We avoid problems by
8072      claiming that all hard registers are used and clobbered at this
8073      point.  */
8074   emit_insn (gen_blockage ());
8076   DONE;
8079 ;; ------------------------------------------------------------------------
8080 ;; Misc insns
8081 ;; ------------------------------------------------------------------------
8083 (define_insn "dect"
8084   [(set (reg:SI T_REG)
8085         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8086    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8087   "TARGET_SH2"
8088   "dt   %0"
8089   [(set_attr "type" "arith")])
8091 (define_insn "nop"
8092   [(const_int 0)]
8093   ""
8094   "nop")
8096 ;; Load address of a label. This is only generated by the casesi expand,
8097 ;; and by machine_dependent_reorg (fixing up fp moves).
8098 ;; This must use unspec, because this only works for labels that are
8099 ;; within range,
8101 (define_insn "mova"
8102   [(set (reg:SI R0_REG)
8103         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8104   "TARGET_SH1"
8105   "mova %O0,r0"
8106   [(set_attr "in_delay_slot" "no")
8107    (set_attr "type" "arith")])
8109 ;; machine_dependent_reorg will make this a `mova'.
8110 (define_insn "mova_const"
8111   [(set (reg:SI R0_REG)
8112         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8113   "TARGET_SH1"
8114   "#"
8115   [(set_attr "in_delay_slot" "no")
8116    (set_attr "type" "arith")])
8118 (define_expand "GOTaddr2picreg"
8119   [(set (reg:SI R0_REG)
8120         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8121                    UNSPEC_MOVA))
8122    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8123    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8124   "" "
8126   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8127   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8129   if (TARGET_SHMEDIA)
8130     {
8131       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8132       rtx pic = operands[0];
8133       rtx lab = PATTERN (gen_call_site ());
8134       rtx insn, equiv;
8136       equiv = operands[1];
8137       operands[1] = gen_rtx_MINUS (Pmode,
8138                                    operands[1],
8139                                    gen_rtx_CONST
8140                                    (Pmode,
8141                                     gen_rtx_MINUS (Pmode,
8142                                                    gen_rtx_CONST (Pmode,
8143                                                                   lab),
8144                                                    pc_rtx)));
8145       operands[1] = gen_sym2PIC (operands[1]);
8146       PUT_MODE (operands[1], Pmode);
8148       if (Pmode == SImode)
8149         {
8150           emit_insn (gen_movsi_const (pic, operands[1]));
8151           emit_insn (gen_ptrel_si (tr, pic, lab));
8152         }
8153       else
8154         {
8155           emit_insn (gen_movdi_const (pic, operands[1]));
8156           emit_insn (gen_ptrel_di (tr, pic, lab));
8157         }
8159       insn = emit_move_insn (operands[0], tr);
8161       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8162                                             REG_NOTES (insn));
8164       DONE;
8165     }
8169 (define_insn "*ptb"
8170   [(set (match_operand 0 "target_reg_operand" "=b")
8171         (const (unspec [(match_operand 1 "" "Csy")]
8172                              UNSPEC_DATALABEL)))]
8173   "TARGET_SHMEDIA && flag_pic
8174    && EXTRA_CONSTRAINT_Csy (operands[1])"
8175   "ptb/u        datalabel %1, %0"
8176   [(set_attr "type" "ptabs_media")
8177    (set_attr "length" "*")])
8179 (define_insn "ptrel_si"
8180   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8181         (plus:SI (match_operand:SI 1 "register_operand" "r")
8182               (pc)))
8183    (match_operand:SI 2 "" "")]
8184   "TARGET_SHMEDIA"
8185   "%O2: ptrel/u %1, %0"
8186   [(set_attr "type" "ptabs_media")])
8188 (define_insn "ptrel_di"
8189   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8190         (plus:DI (match_operand:DI 1 "register_operand" "r")
8191               (pc)))
8192    (match_operand:DI 2 "" "")]
8193   "TARGET_SHMEDIA"
8194   "%O2: ptrel/u %1, %0"
8195   [(set_attr "type" "ptabs_media")])
8197 (define_expand "builtin_setjmp_receiver"
8198   [(match_operand 0 "" "")]
8199   "flag_pic"
8200   "
8202   emit_insn (gen_GOTaddr2picreg ());
8203   DONE;
8206 (define_expand "call_site"
8207   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8208   "TARGET_SH1"
8209   "
8211   static HOST_WIDE_INT i = 0;
8212   operands[0] = GEN_INT (i);
8213   i++;
8216 (define_expand "sym_label2reg"
8217   [(set (match_operand:SI 0 "" "")
8218         (const:SI (minus:SI
8219                    (const:SI
8220                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8221                    (const:SI
8222                     (plus:SI
8223                      (match_operand:SI 2 "" "")
8224                      (const_int 2))))))]
8225   "TARGET_SH1" "")
8227 (define_expand "symGOT_load"
8228   [(set (match_dup 2) (match_operand 1 "" ""))
8229    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8230    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8231   ""
8232   "
8234   rtx insn, mem;
8236   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8237   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8239   if (TARGET_SHMEDIA)
8240     {
8241       rtx reg = operands[2];
8243       if (Pmode == DImode)
8244         {      
8245           if (flag_pic > 1)
8246             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8247           else
8248             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8249         }
8250       else
8251         {
8252           if (flag_pic > 1)
8253             emit_insn (gen_movsi_const (reg, operands[1]));
8254           else
8255             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8256         }
8257     }
8258   else
8259     emit_move_insn (operands[2], operands[1]);
8261   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8262                                              operands[2],
8263                                              gen_rtx_REG (Pmode, PIC_REG)));
8265   /* N.B. This is not constant for a GOTPLT relocation.  */
8266   mem = gen_rtx_MEM (Pmode, operands[3]);
8267   MEM_NOTRAP_P (mem) = 1;
8268   /* ??? Should we have a special alias set for the GOT?  */
8269   insn = emit_move_insn (operands[0], mem);
8271   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8272                                                                   0), 0, 0),
8273                                         REG_NOTES (insn));
8275   DONE;
8278 (define_expand "sym2GOT"
8279   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8280   ""
8281   "")
8283 (define_expand "symGOT2reg"
8284   [(match_operand 0 "" "") (match_operand 1 "" "")]
8285   ""
8286   "
8288   rtx gotsym, insn;
8290   gotsym = gen_sym2GOT (operands[1]);
8291   PUT_MODE (gotsym, Pmode);
8292   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8294   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8296   DONE;
8299 (define_expand "symGOTPLT2reg"
8300   [(match_operand 0 "" "") (match_operand 1 "" "")]
8301   ""
8302   "
8304   rtx pltsym = gen_rtx_CONST (Pmode,
8305                               gen_rtx_UNSPEC (Pmode,
8306                                               gen_rtvec (1, operands[1]),
8307                                               UNSPEC_GOTPLT));
8308   emit_insn (gen_symGOT_load (operands[0], pltsym));
8309   DONE;
8312 (define_expand "sym2GOTOFF"
8313   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8314   ""
8315   "")
8317 (define_expand "symGOTOFF2reg"
8318   [(match_operand 0 "" "") (match_operand 1 "" "")]
8319   ""
8320   "
8322   rtx gotoffsym, insn;
8323   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8325   gotoffsym = gen_sym2GOTOFF (operands[1]);
8326   PUT_MODE (gotoffsym, Pmode);
8327   emit_move_insn (t, gotoffsym);
8328   insn = emit_move_insn (operands[0],
8329                          gen_rtx_PLUS (Pmode, t,
8330                                        gen_rtx_REG (Pmode, PIC_REG)));
8332   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8333                                         REG_NOTES (insn));
8335   DONE;
8338 (define_expand "symPLT_label2reg"
8339   [(set (match_operand:SI 0 "" "")
8340         (const:SI (minus:SI
8341                    (const:SI
8342                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8343                    (const:SI
8344                     (minus:SI
8345                      (const:SI (plus:SI
8346                                 (match_operand:SI 2 "" "")
8347                                 (const_int 2)))
8348                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8349    ;; Even though the PIC register is not really used by the call
8350    ;; sequence in which this is expanded, the PLT code assumes the PIC
8351    ;; register is set, so we must not skip its initialization.  Since
8352    ;; we only use this expand as part of calling sequences, and never
8353    ;; to take the address of a function, this is the best point to
8354    ;; insert the (use).  Using the PLT to take the address of a
8355    ;; function would be wrong, not only because the PLT entry could
8356    ;; then be called from a function that doesn't initialize the PIC
8357    ;; register to the proper GOT, but also because pointers to the
8358    ;; same function might not compare equal, should they be set by
8359    ;; different shared libraries.
8360    (use (reg:SI PIC_REG))]
8361   "TARGET_SH1"
8362   "")
8364 (define_expand "sym2PIC"
8365   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8366   ""
8367   "")
8369 ;; TLS code generation.
8370 ;; ??? this should be a define_insn_and_split
8371 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8372 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8373 ;; for details.
8375 (define_insn "tls_global_dynamic"
8376   [(set (match_operand:SI 0 "register_operand" "=&z")
8377         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8378                                   UNSPEC_TLSGD))
8379               (const_int 0)))
8380    (use (reg:PSI FPSCR_REG))
8381    (use (reg:SI PIC_REG))
8382    (clobber (reg:SI PR_REG))
8383    (clobber (scratch:SI))]
8384   "TARGET_SH1"
8385   "*
8387   return \"\\
8388 mov.l\\t1f,r4\\n\\
8389 \\tmova\\t2f,r0\\n\\
8390 \\tmov.l\\t2f,r1\\n\\
8391 \\tadd\\tr0,r1\\n\\
8392 \\tjsr\\t@r1\\n\\
8393 \\tadd\\tr12,r4\\n\\
8394 \\tbra\\t3f\\n\\
8395 \\tnop\\n\\
8396 \\t.align\\t2\\n\\
8397 1:\\t.long\\t%a1@TLSGD\\n\\
8398 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8399 3:\";
8401   [(set_attr "type" "tls_load")
8402    (set_attr "length" "26")])
8404 (define_insn "tls_local_dynamic"
8405   [(set (match_operand:SI 0 "register_operand" "=&z")
8406         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8407                                   UNSPEC_TLSLDM))
8408               (const_int 0)))
8409    (use (reg:PSI FPSCR_REG))
8410    (use (reg:SI PIC_REG))
8411    (clobber (reg:SI PR_REG))
8412    (clobber (scratch:SI))]
8413   "TARGET_SH1"
8414   "*
8416   return \"\\
8417 mov.l\\t1f,r4\\n\\
8418 \\tmova\\t2f,r0\\n\\
8419 \\tmov.l\\t2f,r1\\n\\
8420 \\tadd\\tr0,r1\\n\\
8421 \\tjsr\\t@r1\\n\\
8422 \\tadd\\tr12,r4\\n\\
8423 \\tbra\\t3f\\n\\
8424 \\tnop\\n\\
8425 \\t.align\\t2\\n\\
8426 1:\\t.long\\t%a1@TLSLDM\\n\\
8427 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8428 3:\";
8430   [(set_attr "type" "tls_load")
8431    (set_attr "length" "26")])
8433 (define_expand "sym2DTPOFF"
8434   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8435   ""
8436   "")
8438 (define_expand "symDTPOFF2reg"
8439   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8440   ""
8441   "
8443   rtx dtpoffsym, insn;
8444   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8446   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8447   PUT_MODE (dtpoffsym, Pmode);
8448   emit_move_insn (t, dtpoffsym);
8449   insn = emit_move_insn (operands[0],
8450                          gen_rtx_PLUS (Pmode, t, operands[2]));
8451   DONE;
8454 (define_expand "sym2GOTTPOFF"
8455   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8456   ""
8457   "")
8459 (define_insn "tls_initial_exec"
8460   [(set (match_operand:SI 0 "register_operand" "=&r")
8461         (unspec:SI [(match_operand:SI 1 "" "")]
8462                     UNSPEC_TLSIE))
8463    (use (reg:SI GBR_REG))
8464    (use (reg:SI PIC_REG))
8465    (clobber (reg:SI R0_REG))]
8466   ""
8467   "*
8469   return \"\\
8470 mov.l\\t1f,r0\\n\\
8471 \\tstc\\tgbr,%0\\n\\
8472 \\tmov.l\\t@(r0,r12),r0\\n\\
8473 \\tbra\\t2f\\n\\
8474 \\tadd\\tr0,%0\\n\\
8475 \\t.align\\t2\\n\\
8476 1:\\t.long\\t%a1\\n\\
8477 2:\";
8479   [(set_attr "type" "tls_load")
8480    (set_attr "length" "16")])
8482 (define_expand "sym2TPOFF"
8483   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8484   ""
8485   "")
8487 (define_expand "symTPOFF2reg"
8488   [(match_operand 0 "" "") (match_operand 1 "" "")]
8489   ""
8490   "
8492   rtx tpoffsym, insn;
8494   tpoffsym = gen_sym2TPOFF (operands[1]);
8495   PUT_MODE (tpoffsym, Pmode);
8496   insn = emit_move_insn (operands[0], tpoffsym);
8497   DONE;
8500 (define_insn "load_gbr"
8501   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8502    (use (reg:SI GBR_REG))]
8503   ""
8504   "stc  gbr,%0"
8505   [(set_attr "type" "tls_load")])
8507 ;; case instruction for switch statements.
8509 ;; Operand 0 is index
8510 ;; operand 1 is the minimum bound
8511 ;; operand 2 is the maximum bound - minimum bound + 1
8512 ;; operand 3 is CODE_LABEL for the table;
8513 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8515 (define_expand "casesi"
8516   [(match_operand:SI 0 "arith_reg_operand" "")
8517    (match_operand:SI 1 "arith_reg_operand" "")
8518    (match_operand:SI 2 "arith_reg_operand" "")
8519    (match_operand 3 "" "") (match_operand 4 "" "")]
8520   ""
8521   "
8523   rtx reg = gen_reg_rtx (SImode);
8524   rtx reg2 = gen_reg_rtx (SImode);
8525   if (TARGET_SHMEDIA)
8526     {
8527       rtx reg = gen_reg_rtx (DImode);
8528       rtx reg2 = gen_reg_rtx (DImode);
8529       rtx reg3 = gen_reg_rtx (Pmode);
8530       rtx reg4 = gen_reg_rtx (Pmode);
8531       rtx reg5 = gen_reg_rtx (Pmode);
8532       rtx load;
8534       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8535       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8536       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8538       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8539       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8540       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8541       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8542       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8543                                                (Pmode, operands[3])));
8544       /* Messy: can we subreg to clean this up? */
8545       if (Pmode == DImode)
8546         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8547       else
8548         load = gen_casesi_load_media (reg4,
8549                                       gen_rtx_SUBREG (DImode, reg3, 0),
8550                                       reg2, operands[3]);
8551       PUT_MODE (SET_SRC (load), Pmode);
8552       emit_insn (load);
8553       /* ??? The following add could be eliminated if we used ptrel.  */
8554       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8555       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8556       emit_barrier ();
8557       DONE;
8558     }
8559   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8560   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8561   /* If optimizing, casesi_worker depends on the mode of the instruction
8562      before label it 'uses' - operands[3].  */
8563   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8564                            reg));
8565   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8566   if (TARGET_SH2)
8567     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8568   else
8569     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8570   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8571      operands[3], but to lab.  We will fix this up in
8572      machine_dependent_reorg.  */
8573   emit_barrier ();
8574   DONE;
8577 (define_expand "casesi_0"
8578   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8579    (set (match_dup 4) (minus:SI (match_dup 4)
8580                                 (match_operand:SI 1 "arith_operand" "")))
8581    (set (reg:SI T_REG)
8582         (gtu:SI (match_dup 4)
8583                 (match_operand:SI 2 "arith_reg_operand" "")))
8584    (set (pc)
8585         (if_then_else (ne (reg:SI T_REG)
8586                           (const_int 0))
8587                       (label_ref (match_operand 3 "" ""))
8588                       (pc)))]
8589   "TARGET_SH1"
8590   "")
8592 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8593 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8594 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8596 (define_insn "casesi_worker_0"
8597   [(set (match_operand:SI 0 "register_operand" "=r,r")
8598         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8599                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8600    (clobber (match_scratch:SI 3 "=X,1"))
8601    (clobber (match_scratch:SI 4 "=&z,z"))]
8602   "TARGET_SH1"
8603   "#")
8605 (define_split
8606   [(set (match_operand:SI 0 "register_operand" "")
8607         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8608                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8609    (clobber (match_scratch:SI 3 ""))
8610    (clobber (match_scratch:SI 4 ""))]
8611   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8612   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8613    (parallel [(set (match_dup 0)
8614               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8615                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8616               (clobber (match_dup 3))])
8617    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8618   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8620 (define_split
8621   [(set (match_operand:SI 0 "register_operand" "")
8622         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8623                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8624    (clobber (match_scratch:SI 3 ""))
8625    (clobber (match_scratch:SI 4 ""))]
8626   "TARGET_SH2 && reload_completed"
8627   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8628    (parallel [(set (match_dup 0)
8629               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8630                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8631               (clobber (match_dup 3))])]
8632   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8634 (define_insn "casesi_worker_1"
8635   [(set (match_operand:SI 0 "register_operand" "=r,r")
8636         (unspec:SI [(reg:SI R0_REG)
8637                     (match_operand:SI 1 "register_operand" "0,r")
8638                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8639    (clobber (match_scratch:SI 3 "=X,1"))]
8640   "TARGET_SH1"
8641   "*
8643   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8645   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8647   switch (GET_MODE (diff_vec))
8648     {
8649     case SImode:
8650       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8651     case HImode:
8652       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8653     case QImode:
8654       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8655         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8656       return \"mov.b    @(r0,%1),%0\";
8657     default:
8658       gcc_unreachable ();
8659     }
8661   [(set_attr "length" "4")])
8663 (define_insn "casesi_worker_2"
8664   [(set (match_operand:SI 0 "register_operand" "=r,r")
8665         (unspec:SI [(reg:SI R0_REG)
8666                     (match_operand:SI 1 "register_operand" "0,r")
8667                     (label_ref (match_operand 2 "" ""))
8668                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8669    (clobber (match_operand:SI 4 "" "=X,1"))]
8670   "TARGET_SH2 && reload_completed && flag_pic"
8671   "*
8673   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8674   const char *load;
8676   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8678   switch (GET_MODE (diff_vec))
8679     {
8680     case SImode:
8681       output_asm_insn (\"shll2    %1\", operands);
8682       load = \"mov.l    @(r0,%1),%0\"; break;
8683     case HImode:
8684       output_asm_insn (\"add    %1,%1\", operands);
8685       load = \"mov.w    @(r0,%1),%0\"; break;
8686     case QImode:
8687       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8688         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8689       else
8690         load = \"mov.b  @(r0,%1),%0\";
8691       break;
8692     default:
8693       gcc_unreachable ();
8694     }
8695   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8696   return load;
8698   [(set_attr "length" "8")])
8700 (define_insn "casesi_shift_media"
8701   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8702         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8703                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8704                     UNSPEC_CASESI)))]
8705   "TARGET_SHMEDIA"
8706   "*
8708   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8710   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8712   switch (GET_MODE (diff_vec))
8713     {
8714     case SImode:
8715       return \"shlli    %1, 2, %0\";
8716     case HImode:
8717       return \"shlli    %1, 1, %0\";
8718     case QImode:
8719       if (rtx_equal_p (operands[0], operands[1]))
8720         return \"\";
8721       return \"add      %1, r63, %0\";
8722     default:
8723       gcc_unreachable ();
8724     }
8726   [(set_attr "type" "arith_media")])
8728 (define_insn "casesi_load_media"
8729   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8730         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8731                          (match_operand:DI 2 "arith_reg_operand" "r")
8732                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8733   "TARGET_SHMEDIA"
8734   "*
8736   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8738   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8740   switch (GET_MODE (diff_vec))
8741     {
8742     case SImode:
8743       return \"ldx.l    %1, %2, %0\";
8744     case HImode:
8745 #if 0
8746       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8747         return \"ldx.uw %1, %2, %0\";
8748 #endif
8749       return \"ldx.w    %1, %2, %0\";
8750     case QImode:
8751       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8752         return \"ldx.ub %1, %2, %0\";
8753       return \"ldx.b    %1, %2, %0\";
8754     default:
8755       gcc_unreachable ();
8756     }
8758   [(set_attr "type" "load_media")])
8760 (define_expand "return"
8761   [(return)]
8762   "reload_completed && ! sh_need_epilogue ()"
8763   "
8765   if (TARGET_SHMEDIA)
8766     {
8767       emit_jump_insn (gen_return_media ());
8768       DONE;
8769     }
8771   if (TARGET_SHCOMPACT
8772       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8773     {
8774       emit_jump_insn (gen_shcompact_return_tramp ());
8775       DONE;
8776     }
8779 (define_insn "*return_i"
8780   [(return)]
8781   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8782                     && (current_function_args_info.call_cookie
8783                         & CALL_COOKIE_RET_TRAMP (1)))
8784    && reload_completed
8785    && lookup_attribute (\"trap_exit\",
8786                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
8787   "%@   %#"
8788   [(set_attr "type" "return")
8789    (set_attr "needs_delay_slot" "yes")])
8791 ;; trapa has no delay slot.
8792 (define_insn "*return_trapa"
8793   [(return)]
8794   "TARGET_SH1 && !TARGET_SHCOMPACT
8795    && reload_completed"
8796   "%@"
8797   [(set_attr "type" "return")])
8799 (define_expand "shcompact_return_tramp"
8800   [(return)]
8801   "TARGET_SHCOMPACT
8802    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8803   "
8805   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8807   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8808   emit_jump_insn (gen_shcompact_return_tramp_i ());
8809   DONE;
8812 (define_insn "shcompact_return_tramp_i"
8813   [(parallel [(return) (use (reg:SI R0_REG))])]
8814   "TARGET_SHCOMPACT
8815    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8816   "jmp  @r0%#"
8817   [(set_attr "type" "jump_ind")
8818    (set_attr "needs_delay_slot" "yes")])
8820 (define_insn "return_media_i"
8821   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8822   "TARGET_SHMEDIA && reload_completed"
8823   "blink        %0, r63"
8824   [(set_attr "type" "jump_media")])
8826 (define_insn "return_media_rte"
8827   [(return)]
8828   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8829   "rte"
8830   [(set_attr "type" "jump_media")])
8832 (define_expand "return_media"
8833   [(return)]
8834   "TARGET_SHMEDIA && reload_completed"
8835   "
8837   int tr_regno = sh_media_register_for_return ();
8838   rtx tr;
8840   if (current_function_interrupt)
8841     {
8842       emit_jump_insn (gen_return_media_rte ());
8843       DONE;
8844     }
8845   if (tr_regno < 0)
8846     {
8847       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8849       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8850       tr_regno = TR0_REG;
8851       tr = gen_rtx_REG (Pmode, tr_regno);
8852       emit_move_insn (tr, r18);
8853     }
8854   else
8855     tr = gen_rtx_REG (Pmode, tr_regno);
8857   emit_jump_insn (gen_return_media_i (tr));
8858   DONE;
8861 (define_insn "shcompact_preserve_incoming_args"
8862   [(set (match_operand:SI 0 "register_operand" "+r")
8863         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8864   "TARGET_SHCOMPACT"
8865   ""
8866   [(set_attr "length" "0")])
8868 (define_insn "shcompact_incoming_args"
8869   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8870    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8871    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8872    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8873    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8874    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8875    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8876    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8877    (set (mem:BLK (reg:SI MACL_REG))
8878         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8879    (use (reg:SI R0_REG))
8880    (clobber (reg:SI R0_REG))
8881    (clobber (reg:SI MACL_REG))
8882    (clobber (reg:SI MACH_REG))
8883    (clobber (reg:SI PR_REG))]
8884   "TARGET_SHCOMPACT"
8885   "jsr  @r0%#"
8886   [(set_attr "needs_delay_slot" "yes")])
8888 (define_insn "shmedia_save_restore_regs_compact"
8889   [(set (reg:SI SP_REG)
8890         (plus:SI (reg:SI SP_REG)
8891                  (match_operand:SI 0 "immediate_operand" "i")))
8892    (use (reg:SI R0_REG))
8893    (clobber (reg:SI PR_REG))]
8894   "TARGET_SHCOMPACT
8895    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8896        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8897   "jsr @r0%#"
8898   [(set_attr "needs_delay_slot" "yes")])
8900 (define_expand "prologue"
8901   [(const_int 0)]
8902   ""
8903   "sh_expand_prologue (); DONE;")
8905 (define_expand "epilogue"
8906   [(return)]
8907   ""
8908   "
8910   sh_expand_epilogue (0);
8911   emit_jump_insn (gen_return ());
8912   DONE;
8915 (define_expand "eh_return"
8916   [(use (match_operand 0 "register_operand" ""))]
8917   ""
8919   rtx ra = operands[0];
8921   if (TARGET_SHMEDIA64)
8922     emit_insn (gen_eh_set_ra_di (ra));
8923   else
8924     emit_insn (gen_eh_set_ra_si (ra));
8926   DONE;
8929 ;; Clobber the return address on the stack.  We can't expand this
8930 ;; until we know where it will be put in the stack frame.
8932 (define_insn "eh_set_ra_si"
8933   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8934    (clobber (match_scratch:SI 1 "=&r"))]
8935   "! TARGET_SHMEDIA64"
8936   "#")
8938 (define_insn "eh_set_ra_di"
8939   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8940    (clobber (match_scratch:DI 1 "=&r"))]
8941   "TARGET_SHMEDIA64"
8942   "#")
8944 (define_split
8945   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8946    (clobber (match_scratch 1 ""))]
8947   "reload_completed"
8948   [(const_int 0)]
8949   "
8951   sh_set_return_address (operands[0], operands[1]);
8952   DONE;
8955 (define_insn "blockage"
8956   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8957   ""
8958   ""
8959   [(set_attr "length" "0")])
8961 ;; ------------------------------------------------------------------------
8962 ;; Scc instructions
8963 ;; ------------------------------------------------------------------------
8965 (define_insn "movt"
8966   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
8967         (eq:SI (reg:SI T_REG) (const_int 1)))]
8968   "TARGET_SH1"
8969   "movt %0"
8970   [(set_attr "type" "arith")])
8972 (define_expand "seq"
8973   [(set (match_operand:SI 0 "arith_reg_dest" "")
8974         (match_dup 1))]
8975   ""
8976   "
8978   if (TARGET_SHMEDIA)
8979     {
8980       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
8981       if (sh_compare_op1 != const0_rtx)
8982         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
8983                                     ? GET_MODE (sh_compare_op0)
8984                                     : GET_MODE (sh_compare_op1),
8985                                     sh_compare_op1);
8986       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
8987         {
8988           if (GET_MODE (operands[0]) != SImode)
8989             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
8991           switch (GET_MODE (sh_compare_op0))
8992             {
8993             case SImode:
8994               emit_insn (gen_cmpsieqsi_media (operands[0],
8995                                               sh_compare_op0, sh_compare_op1));
8996               break;
8998             case DImode:
8999               emit_insn (gen_cmpsieqdi_media (operands[0],
9000                                               sh_compare_op0, sh_compare_op1));
9001               break;
9003             case SFmode:
9004               if (! TARGET_SHMEDIA_FPU)
9005                 FAIL;
9006               emit_insn (gen_cmpsieqsf_media (operands[0],
9007                                               sh_compare_op0, sh_compare_op1));
9008               break;
9010             case DFmode:
9011               if (! TARGET_SHMEDIA_FPU)
9012                 FAIL;
9013               emit_insn (gen_cmpsieqdf_media (operands[0],
9014                                               sh_compare_op0, sh_compare_op1));
9015               break;
9017             default:
9018               FAIL;
9019             }
9020           DONE;
9021         }
9023       if (GET_MODE (operands[0]) != DImode)
9024         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9026       switch (GET_MODE (sh_compare_op0))
9027         {
9028         case SImode:
9029           emit_insn (gen_cmpeqsi_media (operands[0],
9030                                         sh_compare_op0, sh_compare_op1));
9031           break;
9033         case DImode:
9034           emit_insn (gen_cmpeqdi_media (operands[0],
9035                                         sh_compare_op0, sh_compare_op1));
9036           break;
9038         case SFmode:
9039           if (! TARGET_SHMEDIA_FPU)
9040             FAIL;
9041           emit_insn (gen_cmpeqsf_media (operands[0],
9042                                         sh_compare_op0, sh_compare_op1));
9043           break;
9045         case DFmode:
9046           if (! TARGET_SHMEDIA_FPU)
9047             FAIL;
9048           emit_insn (gen_cmpeqdf_media (operands[0],
9049                                         sh_compare_op0, sh_compare_op1));
9050           break;
9052         default:
9053           FAIL;
9054         }
9055       DONE;
9056     }
9057   if (sh_expand_t_scc (EQ, operands[0]))
9058     DONE;
9059   if (! currently_expanding_to_rtl)
9060     FAIL;
9061   operands[1] = prepare_scc_operands (EQ);
9064 (define_expand "slt"
9065   [(set (match_operand:SI 0 "arith_reg_operand" "")
9066         (match_dup 1))]
9067   ""
9068   "
9070   if (TARGET_SHMEDIA)
9071     {
9072       if (GET_MODE (operands[0]) != DImode)
9073         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9074       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9075       if (sh_compare_op1 != const0_rtx)
9076         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9077                                     ? GET_MODE (sh_compare_op0)
9078                                     : GET_MODE (sh_compare_op1),
9079                                     sh_compare_op1);
9081       switch (GET_MODE (sh_compare_op0))
9082         {
9083         case SImode:
9084           emit_insn (gen_cmpgtsi_media (operands[0],
9085                                         sh_compare_op1, sh_compare_op0));
9086           break;
9088         case DImode:
9089           emit_insn (gen_cmpgtdi_media (operands[0],
9090                                         sh_compare_op1, sh_compare_op0));
9091           break;
9093         case SFmode:
9094           if (! TARGET_SHMEDIA_FPU)
9095             FAIL;
9096           emit_insn (gen_cmpgtsf_media (operands[0],
9097                                         sh_compare_op1, sh_compare_op0));
9098           break;
9100         case DFmode:
9101           if (! TARGET_SHMEDIA_FPU)
9102             FAIL;
9103           emit_insn (gen_cmpgtdf_media (operands[0],
9104                                         sh_compare_op1, sh_compare_op0));
9105           break;
9107         default:
9108           FAIL;
9109         }
9110       DONE;
9111     }
9112   if (! currently_expanding_to_rtl)
9113     FAIL;
9114   operands[1] = prepare_scc_operands (LT);
9117 (define_expand "sle"
9118   [(match_operand:SI 0 "arith_reg_operand" "")]
9119   ""
9120   "
9122   rtx tmp = sh_compare_op0;
9124   if (TARGET_SHMEDIA)
9125     {
9126       if (GET_MODE (operands[0]) != DImode)
9127         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9128       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9129       if (sh_compare_op1 != const0_rtx)
9130         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9131                                     ? GET_MODE (sh_compare_op0)
9132                                     : GET_MODE (sh_compare_op1),
9133                                     sh_compare_op1);
9135       switch (GET_MODE (sh_compare_op0))
9136         {
9137         case SImode:
9138           {
9139             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9141             emit_insn (gen_cmpgtsi_media (tmp,
9142                                           sh_compare_op0, sh_compare_op1));
9143             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9144             break;
9145           }
9147         case DImode:
9148           {
9149             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9151             emit_insn (gen_cmpgtdi_media (tmp,
9152                                           sh_compare_op0, sh_compare_op1));
9153             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9154             break;
9155           }
9157         case SFmode:
9158           if (! TARGET_SHMEDIA_FPU)
9159             FAIL;
9160           emit_insn (gen_cmpgesf_media (operands[0],
9161                                         sh_compare_op1, sh_compare_op0));
9162           break;
9164         case DFmode:
9165           if (! TARGET_SHMEDIA_FPU)
9166             FAIL;
9167           emit_insn (gen_cmpgedf_media (operands[0],
9168                                         sh_compare_op1, sh_compare_op0));
9169           break;
9171         default:
9172           FAIL;
9173         }
9174       DONE;
9175     }
9177   sh_compare_op0 = sh_compare_op1;
9178   sh_compare_op1 = tmp;
9179   emit_insn (gen_sge (operands[0]));
9180   DONE;
9183 (define_expand "sgt"
9184   [(set (match_operand:SI 0 "arith_reg_operand" "")
9185         (match_dup 1))]
9186   ""
9187   "
9189   if (TARGET_SHMEDIA)
9190     {
9191       if (GET_MODE (operands[0]) != DImode)
9192         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9193       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9194       if (sh_compare_op1 != const0_rtx)
9195         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9196                                     ? GET_MODE (sh_compare_op0)
9197                                     : GET_MODE (sh_compare_op1),
9198                                     sh_compare_op1);
9200       switch (GET_MODE (sh_compare_op0))
9201         {
9202         case SImode:
9203           emit_insn (gen_cmpgtsi_media (operands[0],
9204                                         sh_compare_op0, sh_compare_op1));
9205           break;
9207         case DImode:
9208           emit_insn (gen_cmpgtdi_media (operands[0],
9209                                         sh_compare_op0, sh_compare_op1));
9210           break;
9212         case SFmode:
9213           if (! TARGET_SHMEDIA_FPU)
9214             FAIL;
9215           emit_insn (gen_cmpgtsf_media (operands[0],
9216                                         sh_compare_op0, sh_compare_op1));
9217           break;
9219         case DFmode:
9220           if (! TARGET_SHMEDIA_FPU)
9221             FAIL;
9222           emit_insn (gen_cmpgtdf_media (operands[0],
9223                                         sh_compare_op0, sh_compare_op1));
9224           break;
9226         default:
9227           FAIL;
9228         }
9229       DONE;
9230     }
9231   if (! currently_expanding_to_rtl)
9232     FAIL;
9233   operands[1] = prepare_scc_operands (GT);
9236 (define_expand "sge"
9237   [(set (match_operand:SI 0 "arith_reg_operand" "")
9238         (match_dup 1))]
9239   ""
9240   "
9242   if (TARGET_SHMEDIA)
9243     {
9244       enum machine_mode mode = GET_MODE (sh_compare_op0);
9246       if ((mode) == VOIDmode)
9247         mode = GET_MODE (sh_compare_op1);
9248       if (GET_MODE (operands[0]) != DImode)
9249         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9250       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9251       if (sh_compare_op1 != const0_rtx)
9252         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9254       switch (mode)
9255         {
9256         case SImode:
9257           {
9258             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9260             emit_insn (gen_cmpgtsi_media (tmp,
9261                                           sh_compare_op1, sh_compare_op0));
9262             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9263             break;
9264           }
9266         case DImode:
9267           {
9268             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9270             emit_insn (gen_cmpgtdi_media (tmp,
9271                                           sh_compare_op1, sh_compare_op0));
9272             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9273             break;
9274           }
9276         case SFmode:
9277           if (! TARGET_SHMEDIA_FPU)
9278             FAIL;
9279           emit_insn (gen_cmpgesf_media (operands[0],
9280                                         sh_compare_op0, sh_compare_op1));
9281           break;
9283         case DFmode:
9284           if (! TARGET_SHMEDIA_FPU)
9285             FAIL;
9286           emit_insn (gen_cmpgedf_media (operands[0],
9287                                         sh_compare_op0, sh_compare_op1));
9288           break;
9290         default:
9291           FAIL;
9292         }
9293       DONE;
9294     }
9296   if (! currently_expanding_to_rtl)
9297     FAIL;
9298   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9299     {
9300       if (TARGET_IEEE)
9301         {
9302           rtx lab = gen_label_rtx ();
9303           prepare_scc_operands (EQ);
9304           emit_jump_insn (gen_branch_true (lab));
9305           prepare_scc_operands (GT);
9306           emit_label (lab);
9307           emit_insn (gen_movt (operands[0]));
9308         }
9309       else
9310         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9311       DONE;
9312     }
9313   operands[1] = prepare_scc_operands (GE);
9316 (define_expand "sgtu"
9317   [(set (match_operand:SI 0 "arith_reg_operand" "")
9318         (match_dup 1))]
9319   ""
9320   "
9322   if (TARGET_SHMEDIA)
9323     {
9324       if (GET_MODE (operands[0]) != DImode)
9325         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9326       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9327       if (sh_compare_op1 != const0_rtx)
9328         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9329                                     ? GET_MODE (sh_compare_op0)
9330                                     : GET_MODE (sh_compare_op1),
9331                                     sh_compare_op1);
9333       emit_insn (gen_cmpgtudi_media (operands[0],
9334                                      sh_compare_op0, sh_compare_op1));
9335       DONE;
9336     }
9337   if (! currently_expanding_to_rtl)
9338     FAIL;
9339   operands[1] = prepare_scc_operands (GTU);
9342 (define_expand "sltu"
9343   [(set (match_operand:SI 0 "arith_reg_operand" "")
9344         (match_dup 1))]
9345   ""
9346   "
9348   if (TARGET_SHMEDIA)
9349     {
9350       if (GET_MODE (operands[0]) != DImode)
9351         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9352       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9353       if (sh_compare_op1 != const0_rtx)
9354         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9355                                     ? GET_MODE (sh_compare_op0)
9356                                     : GET_MODE (sh_compare_op1),
9357                                     sh_compare_op1);
9359       emit_insn (gen_cmpgtudi_media (operands[0],
9360                                      sh_compare_op1, sh_compare_op0));
9361       DONE;
9362     }
9363   if (! currently_expanding_to_rtl)
9364     FAIL;
9365   operands[1] = prepare_scc_operands (LTU);
9368 (define_expand "sleu"
9369   [(set (match_operand:SI 0 "arith_reg_operand" "")
9370         (match_dup 1))]
9371   ""
9372   "
9374   if (TARGET_SHMEDIA)
9375     {
9376       rtx tmp;
9378       if (GET_MODE (operands[0]) != DImode)
9379         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9380       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9381       if (sh_compare_op1 != const0_rtx)
9382         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9383                                     ? GET_MODE (sh_compare_op0)
9384                                     : GET_MODE (sh_compare_op1),
9385                                     sh_compare_op1);
9387       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9389       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9390       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9392       DONE;
9393     }
9394   if (! currently_expanding_to_rtl)
9395     FAIL;
9396   operands[1] = prepare_scc_operands (LEU);
9399 (define_expand "sgeu"
9400   [(set (match_operand:SI 0 "arith_reg_operand" "")
9401         (match_dup 1))]
9402   ""
9403   "
9405   if (TARGET_SHMEDIA)
9406     {
9407       rtx tmp;
9409       if (GET_MODE (operands[0]) != DImode)
9410         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9411       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9412       if (sh_compare_op1 != const0_rtx)
9413         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9414                                     ? GET_MODE (sh_compare_op0)
9415                                     : GET_MODE (sh_compare_op1),
9416                                     sh_compare_op1);
9418       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9420       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9421       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9423       DONE;
9424     }
9426   if (! currently_expanding_to_rtl)
9427     FAIL;
9428   operands[1] = prepare_scc_operands (GEU);
9431 ;; sne moves the complement of the T reg to DEST like this:
9432 ;;      cmp/eq ...
9433 ;;      mov    #-1,temp
9434 ;;      negc   temp,dest
9435 ;;   This is better than xoring compare result with 1 because it does
9436 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9437 ;;   loop.
9439 (define_expand "sne"
9440   [(set (match_dup 2) (const_int -1))
9441    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9442                    (neg:SI (plus:SI (match_dup 1)
9443                                     (match_dup 2))))
9444               (set (reg:SI T_REG)
9445                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9446                           (const_int 0)))])]
9447   ""
9448   "
9450   if (TARGET_SHMEDIA)
9451     {
9452       rtx tmp;
9454       if (GET_MODE (operands[0]) != DImode)
9455         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9457       if (! TARGET_SHMEDIA_FPU
9458           && GET_MODE (sh_compare_op0) != DImode
9459           && GET_MODE (sh_compare_op0) != SImode)
9460         FAIL;
9462       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9463       if (sh_compare_op1 != const0_rtx)
9464         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9465                                     ? GET_MODE (sh_compare_op0)
9466                                     : GET_MODE (sh_compare_op1),
9467                                     sh_compare_op1);
9469       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9471       emit_insn (gen_seq (tmp));
9472       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9474       DONE;
9475     }
9477   if (sh_expand_t_scc (NE, operands[0]))
9478     DONE;
9479   if (! currently_expanding_to_rtl)
9480     FAIL;
9481   operands[1] = prepare_scc_operands (EQ);
9482   operands[2] = gen_reg_rtx (SImode);
9485 (define_expand "sunordered"
9486   [(set (match_operand:DI 0 "arith_reg_operand" "")
9487         (unordered:DI (match_dup 1) (match_dup 2)))]
9488   "TARGET_SHMEDIA_FPU"
9489   "
9491   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9492   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9495 ;; Use the same trick for FP sle / sge
9497 ;; Apart from the constant use and the T setting, this is like movt,
9498 ;; except that it uses the logically negated value of T, i.e.
9499 ;; operand[0] := T ? 0 : 1.
9500 (define_expand "movnegt"
9501   [(set (match_dup 2) (const_int -1))
9502    (parallel [(set (match_operand 0 "" "")
9503                    (neg:SI (plus:SI (match_dup 1)
9504                                     (match_dup 2))))
9505               (set (reg:SI T_REG)
9506                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9507                           (const_int 0)))])]
9508   "TARGET_SH1"
9509   "operands[2] = gen_reg_rtx (SImode);")
9511 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9512 ;; This prevents a regression that occurred when we switched from xor to
9513 ;; mov/neg for sne.
9515 (define_split
9516   [(set (match_operand:SI 0 "arith_reg_dest" "")
9517         (plus:SI (reg:SI T_REG)
9518                  (const_int -1)))]
9519   "TARGET_SH1"
9520   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9521    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9522   "")
9524 ;; -------------------------------------------------------------------------
9525 ;; Instructions to cope with inline literal tables
9526 ;; -------------------------------------------------------------------------
9528 ; 2 byte integer in line
9530 (define_insn "consttable_2"
9531  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9532                     (match_operand 1 "" "")]
9533                    UNSPECV_CONST2)]
9534  ""
9535  "*
9537   if (operands[1] != const0_rtx)
9538     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9539   return \"\";
9541  [(set_attr "length" "2")
9542  (set_attr "in_delay_slot" "no")])
9544 ; 4 byte integer in line
9546 (define_insn "consttable_4"
9547  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9548                     (match_operand 1 "" "")]
9549                    UNSPECV_CONST4)]
9550  ""
9551  "*
9553   if (operands[1] != const0_rtx)
9554     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9555   return \"\";
9557  [(set_attr "length" "4")
9558   (set_attr "in_delay_slot" "no")])
9560 ; 8 byte integer in line
9562 (define_insn "consttable_8"
9563  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9564                     (match_operand 1 "" "")]
9565                    UNSPECV_CONST8)]
9566  ""
9567  "*
9569   if (operands[1] != const0_rtx)
9570     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9571   return \"\";
9573  [(set_attr "length" "8")
9574   (set_attr "in_delay_slot" "no")])
9576 ; 4 byte floating point
9578 (define_insn "consttable_sf"
9579  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9580                     (match_operand 1 "" "")]
9581                    UNSPECV_CONST4)]
9582  ""
9583  "*
9585   if (operands[1] != const0_rtx)
9586     {
9587       REAL_VALUE_TYPE d;
9588       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9589       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9590     }
9591   return \"\";
9593  [(set_attr "length" "4")
9594   (set_attr "in_delay_slot" "no")])
9596 ; 8 byte floating point
9598 (define_insn "consttable_df"
9599  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9600                     (match_operand 1 "" "")]
9601                    UNSPECV_CONST8)]
9602  ""
9603  "*
9605   if (operands[1] != const0_rtx)
9606     {
9607       REAL_VALUE_TYPE d;
9608       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9609       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9610     }
9611   return \"\";
9613  [(set_attr "length" "8")
9614   (set_attr "in_delay_slot" "no")])
9616 ;; Alignment is needed for some constant tables; it may also be added for
9617 ;; Instructions at the start of loops, or after unconditional branches.
9618 ;; ??? We would get more accurate lengths if we did instruction
9619 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9620 ;; here is too conservative.
9622 ; align to a two byte boundary
9624 (define_expand "align_2"
9625  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9626  ""
9627  "")
9629 ; align to a four byte boundary
9630 ;; align_4 and align_log are instructions for the starts of loops, or
9631 ;; after unconditional branches, which may take up extra room.
9633 (define_expand "align_4"
9634  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9635  ""
9636  "")
9638 ; align to a cache line boundary
9640 (define_insn "align_log"
9641  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9642  ""
9643  ""
9644  [(set_attr "length" "0")
9645   (set_attr "in_delay_slot" "no")])
9647 ; emitted at the end of the literal table, used to emit the
9648 ; 32bit branch labels if needed.
9650 (define_insn "consttable_end"
9651   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9652   ""
9653   "* return output_jump_label_table ();"
9654   [(set_attr "in_delay_slot" "no")])
9656 ; emitted at the end of the window in the literal table.
9658 (define_insn "consttable_window_end"
9659   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9660   ""
9661   ""
9662   [(set_attr "length" "0")
9663    (set_attr "in_delay_slot" "no")])
9665 ;; -------------------------------------------------------------------------
9666 ;; Misc
9667 ;; -------------------------------------------------------------------------
9669 ;; String/block move insn.
9671 (define_expand "movmemsi"
9672   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9673                    (mem:BLK (match_operand:BLK 1 "" "")))
9674               (use (match_operand:SI 2 "nonmemory_operand" ""))
9675               (use (match_operand:SI 3 "immediate_operand" ""))
9676               (clobber (reg:SI PR_REG))
9677               (clobber (reg:SI R4_REG))
9678               (clobber (reg:SI R5_REG))
9679               (clobber (reg:SI R0_REG))])]
9680   "TARGET_SH1 && ! TARGET_SH5"
9681   "
9683   if(expand_block_move (operands))
9684      DONE;
9685   else FAIL;
9688 (define_insn "block_move_real"
9689   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9690                    (mem:BLK (reg:SI R5_REG)))
9691               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9692               (clobber (reg:SI PR_REG))
9693               (clobber (reg:SI R0_REG))])]
9694   "TARGET_SH1 && ! TARGET_HARD_SH4"
9695   "jsr  @%0%#"
9696   [(set_attr "type" "sfunc")
9697    (set_attr "needs_delay_slot" "yes")])
9699 (define_insn "block_lump_real"
9700   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9701                    (mem:BLK (reg:SI R5_REG)))
9702               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9703               (use (reg:SI R6_REG))
9704               (clobber (reg:SI PR_REG))
9705               (clobber (reg:SI T_REG))
9706               (clobber (reg:SI R4_REG))
9707               (clobber (reg:SI R5_REG))
9708               (clobber (reg:SI R6_REG))
9709               (clobber (reg:SI R0_REG))])]
9710   "TARGET_SH1 && ! TARGET_HARD_SH4"
9711   "jsr  @%0%#"
9712   [(set_attr "type" "sfunc")
9713    (set_attr "needs_delay_slot" "yes")])
9715 (define_insn "block_move_real_i4"
9716   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9717                    (mem:BLK (reg:SI R5_REG)))
9718               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9719               (clobber (reg:SI PR_REG))
9720               (clobber (reg:SI R0_REG))
9721               (clobber (reg:SI R1_REG))
9722               (clobber (reg:SI R2_REG))])]
9723   "TARGET_HARD_SH4"
9724   "jsr  @%0%#"
9725   [(set_attr "type" "sfunc")
9726    (set_attr "needs_delay_slot" "yes")])
9728 (define_insn "block_lump_real_i4"
9729   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9730                    (mem:BLK (reg:SI R5_REG)))
9731               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9732               (use (reg:SI R6_REG))
9733               (clobber (reg:SI PR_REG))
9734               (clobber (reg:SI T_REG))
9735               (clobber (reg:SI R4_REG))
9736               (clobber (reg:SI R5_REG))
9737               (clobber (reg:SI R6_REG))
9738               (clobber (reg:SI R0_REG))
9739               (clobber (reg:SI R1_REG))
9740               (clobber (reg:SI R2_REG))
9741               (clobber (reg:SI R3_REG))])]
9742   "TARGET_HARD_SH4"
9743   "jsr  @%0%#"
9744   [(set_attr "type" "sfunc")
9745    (set_attr "needs_delay_slot" "yes")])
9747 ;; -------------------------------------------------------------------------
9748 ;; Floating point instructions.
9749 ;; -------------------------------------------------------------------------
9751 ;; ??? All patterns should have a type attribute.
9753 (define_expand "movpsi"
9754   [(set (match_operand:PSI 0 "register_operand" "")
9755         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9756   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9757   "")
9759 ;; The c / m alternative is a fake to guide reload to load directly into
9760 ;; fpscr, since reload doesn't know how to use post-increment.
9761 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9762 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9763 ;; predicate after reload.
9764 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9765 ;; like a mac -> gpr move.
9766 (define_insn "fpu_switch"
9767   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9768         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9769   "TARGET_SH2E
9770    && (! reload_completed
9771        || true_regnum (operands[0]) != FPSCR_REG
9772        || GET_CODE (operands[1]) != MEM
9773        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9774   "@
9775         ! precision stays the same
9776         lds.l   %1,fpscr
9777         mov.l   %1,%0
9778         #
9779         lds     %1,fpscr
9780         mov     %1,%0
9781         mov.l   %1,%0
9782         sts     fpscr,%0
9783         sts.l   fpscr,%0"
9784   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9785    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9787 (define_peephole2
9788   [(set (reg:PSI FPSCR_REG)
9789         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9790   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9791   [(const_int 0)]
9793   rtx fpscr, mem, new_insn;
9795   fpscr = SET_DEST (PATTERN (curr_insn));
9796   mem = SET_SRC (PATTERN (curr_insn));
9797   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9799   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9800   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9801   DONE;
9804 (define_split
9805   [(set (reg:PSI FPSCR_REG)
9806         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9807   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9808    && (flag_peephole2 ? flow2_completed : reload_completed)"
9809   [(const_int 0)]
9811   rtx fpscr, mem, new_insn;
9813   fpscr = SET_DEST (PATTERN (curr_insn));
9814   mem = SET_SRC (PATTERN (curr_insn));
9815   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9817   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9818   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9820   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9821     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9822   DONE;
9825 ;; ??? This uses the fp unit, but has no type indicating that.
9826 ;; If we did that, this would either give a bogus latency or introduce
9827 ;; a bogus FIFO constraint.
9828 ;; Since this insn is currently only used for prologues/epilogues,
9829 ;; it is probably best to claim no function unit, which matches the
9830 ;; current setting.
9831 (define_insn "toggle_sz"
9832   [(set (reg:PSI FPSCR_REG)
9833         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9834   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9835   "fschg"
9836   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9838 ;; There's no way we can use it today, since optimize mode switching
9839 ;; doesn't enable us to know from which mode we're switching to the
9840 ;; mode it requests, to tell whether we can use a relative mode switch
9841 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9842 ;; memory).
9843 (define_insn "toggle_pr"
9844   [(set (reg:PSI FPSCR_REG)
9845         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9846   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9847   "fpchg"
9848   [(set_attr "type" "fp")])
9850 (define_expand "addsf3"
9851   [(set (match_operand:SF 0 "arith_reg_operand" "")
9852         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9853                  (match_operand:SF 2 "arith_reg_operand" "")))]
9854   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9855   "
9857   if (TARGET_SH2E)
9858     {
9859       expand_sf_binop (&gen_addsf3_i, operands);
9860       DONE;
9861     }
9864 (define_insn "*addsf3_media"
9865   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9866         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9867                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9868   "TARGET_SHMEDIA_FPU"
9869   "fadd.s       %1, %2, %0"
9870   [(set_attr "type" "fparith_media")])
9872 (define_insn_and_split "unary_sf_op"
9873   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9874         (vec_select:V2SF
9875          (vec_concat:V2SF
9876           (vec_select:SF
9877            (match_dup 0)
9878            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9879           (match_operator:SF 2 "unary_float_operator"
9880             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9881                             (parallel [(match_operand 4
9882                                         "const_int_operand" "n")]))]))
9883          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9884   "TARGET_SHMEDIA_FPU"
9885   "#"
9886   "TARGET_SHMEDIA_FPU && reload_completed"
9887   [(set (match_dup 5) (match_dup 6))]
9888   "
9890   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9891   rtx op1 = gen_rtx_REG (SFmode,
9892                          (true_regnum (operands[1])
9893                           + (INTVAL (operands[4]) ^ endian)));
9895   operands[7] = gen_rtx_REG (SFmode,
9896                              (true_regnum (operands[0])
9897                               + (INTVAL (operands[3]) ^ endian)));
9898   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9900   [(set_attr "type" "fparith_media")])
9902 (define_insn_and_split "binary_sf_op"
9903   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9904         (vec_select:V2SF
9905          (vec_concat:V2SF
9906           (vec_select:SF
9907            (match_dup 0)
9908            (parallel [(match_operand 7 "const_int_operand" "n")]))
9909           (match_operator:SF 3 "binary_float_operator"
9910             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9911                             (parallel [(match_operand 5
9912                                         "const_int_operand" "n")]))
9913              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9914                             (parallel [(match_operand 6
9915                                         "const_int_operand" "n")]))]))
9916          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9917   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9918   "#"
9919   "&& reload_completed"
9920   [(set (match_dup 8) (match_dup 9))]
9921   "
9923   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9924   rtx op1 = gen_rtx_REG (SFmode,
9925                          (true_regnum (operands[1])
9926                           + (INTVAL (operands[5]) ^ endian)));
9927   rtx op2 = gen_rtx_REG (SFmode,
9928                          (true_regnum (operands[2])
9929                           + (INTVAL (operands[6]) ^ endian)));
9931   operands[8] = gen_rtx_REG (SFmode,
9932                              (true_regnum (operands[0])
9933                               + (INTVAL (operands[4]) ^ endian)));
9934   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9936   [(set_attr "type" "fparith_media")])
9938 (define_insn "addsf3_i"
9939   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9940         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9941                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9942    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9943   "TARGET_SH2E"
9944   "fadd %2,%0"
9945   [(set_attr "type" "fp")
9946    (set_attr "fp_mode" "single")])
9948 (define_expand "subsf3"
9949   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9950         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9951                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9952   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9953   "
9955   if (TARGET_SH2E)
9956     {
9957       expand_sf_binop (&gen_subsf3_i, operands);
9958       DONE;
9959     }
9962 (define_insn "*subsf3_media"
9963   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9964         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9965                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9966   "TARGET_SHMEDIA_FPU"
9967   "fsub.s       %1, %2, %0"
9968   [(set_attr "type" "fparith_media")])
9970 (define_insn "subsf3_i"
9971   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9972         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9973                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9974    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9975   "TARGET_SH2E"
9976   "fsub %2,%0"
9977   [(set_attr "type" "fp")
9978    (set_attr "fp_mode" "single")])
9980 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9981 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
9982 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
9983 ;; SH3E, we use a separate insn for SH3E mulsf3.
9985 (define_expand "mulsf3"
9986   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9987         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9988                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9989   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9990   "
9992   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
9993     expand_sf_binop (&gen_mulsf3_i4, operands);
9994   else if (TARGET_SH2E)
9995     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
9996   if (! TARGET_SHMEDIA)
9997     DONE;
10000 (define_insn "*mulsf3_media"
10001   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10002         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10003                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10004   "TARGET_SHMEDIA_FPU"
10005   "fmul.s       %1, %2, %0"
10006   [(set_attr "type" "fparith_media")])
10008 (define_insn "mulsf3_i4"
10009   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10010         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10011                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10012    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10013   "TARGET_SH2E"
10014   "fmul %2,%0"
10015   [(set_attr "type" "fp")
10016    (set_attr "fp_mode" "single")])
10018 (define_insn "mulsf3_ie"
10019   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10020         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10021                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10022   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10023   "fmul %2,%0"
10024   [(set_attr "type" "fp")])
10026 (define_insn "mac_media"
10027   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10028         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10029                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10030                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10031   "TARGET_SHMEDIA_FPU"
10032   "fmac.s %1, %2, %0"
10033   [(set_attr "type" "fparith_media")])
10035 (define_insn "*macsf3"
10036   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10037         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10038                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10039                  (match_operand:SF 3 "arith_reg_operand" "0")))
10040    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10041   "TARGET_SH2E && ! TARGET_SH4"
10042   "fmac fr0,%2,%0"
10043   [(set_attr "type" "fp")
10044    (set_attr "fp_mode" "single")])
10046 (define_expand "divsf3"
10047   [(set (match_operand:SF 0 "arith_reg_operand" "")
10048         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10049                 (match_operand:SF 2 "arith_reg_operand" "")))]
10050   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10051   "
10053   if (TARGET_SH2E)
10054     {
10055       expand_sf_binop (&gen_divsf3_i, operands);
10056       DONE;
10057     }
10060 (define_insn "*divsf3_media"
10061   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10062         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10063                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10064   "TARGET_SHMEDIA_FPU"
10065   "fdiv.s       %1, %2, %0"
10066   [(set_attr "type" "fdiv_media")])
10068 (define_insn "divsf3_i"
10069   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10070         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10071                  (match_operand:SF 2 "arith_reg_operand" "f")))
10072    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10073   "TARGET_SH2E"
10074   "fdiv %2,%0"
10075   [(set_attr "type" "fdiv")
10076    (set_attr "fp_mode" "single")])
10078 (define_insn "floatdisf2"
10079   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10080         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10081   "TARGET_SHMEDIA_FPU"
10082   "float.qs %1, %0"
10083   [(set_attr "type" "fpconv_media")])
10085 (define_expand "floatsisf2"
10086   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10087         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10088   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10089   "
10091   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10092     {
10093       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10094       DONE;
10095     }
10098 (define_insn "*floatsisf2_media"
10099   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10100         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10101   "TARGET_SHMEDIA_FPU"
10102   "float.ls     %1, %0"
10103   [(set_attr "type" "fpconv_media")])
10105 (define_insn "floatsisf2_i4"
10106   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10107         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10108    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10109   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10110   "float        %1,%0"
10111   [(set_attr "type" "fp")
10112    (set_attr "fp_mode" "single")])
10114 (define_insn "*floatsisf2_ie"
10115   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10116         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10117   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10118   "float        %1,%0"
10119   [(set_attr "type" "fp")])
10121 (define_insn "fix_truncsfdi2"
10122   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10123         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10124   "TARGET_SHMEDIA_FPU"
10125   "ftrc.sq %1, %0"
10126   [(set_attr "type" "fpconv_media")])
10128 (define_expand "fix_truncsfsi2"
10129   [(set (match_operand:SI 0 "fpul_operand" "=y")
10130         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10131   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10132   "
10134   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10135     {
10136       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10137       DONE;
10138     }
10141 (define_insn "*fix_truncsfsi2_media"
10142   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10143         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10144   "TARGET_SHMEDIA_FPU"
10145   "ftrc.sl      %1, %0"
10146   [(set_attr "type" "fpconv_media")])
10148 (define_insn "fix_truncsfsi2_i4"
10149   [(set (match_operand:SI 0 "fpul_operand" "=y")
10150         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10151    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10152   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10153   "ftrc %1,%0"
10154   [(set_attr "type" "ftrc_s")
10155    (set_attr "fp_mode" "single")])
10157 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10158 ;; fix_truncsfsi2_i4.
10159 ;; (define_insn "fix_truncsfsi2_i4_2"
10160 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10161 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10162 ;;   (use (reg:PSI FPSCR_REG))
10163 ;;   (clobber (reg:SI FPUL_REG))]
10164 ;;  "TARGET_SH4"
10165 ;;  "#"
10166 ;;  [(set_attr "length" "4")
10167 ;;   (set_attr "fp_mode" "single")])
10169 ;;(define_split
10170 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10171 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10172 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10173 ;;   (clobber (reg:SI FPUL_REG))]
10174 ;;  "TARGET_SH4"
10175 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10176 ;;            (use (match_dup 2))])
10177 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10179 (define_insn "*fixsfsi"
10180   [(set (match_operand:SI 0 "fpul_operand" "=y")
10181         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10182   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10183   "ftrc %1,%0"
10184   [(set_attr "type" "fp")])
10186 (define_insn "cmpgtsf_t"
10187   [(set (reg:SI T_REG)
10188         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10189                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10190   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10191   "fcmp/gt      %1,%0"
10192   [(set_attr "type" "fp")
10193    (set_attr "fp_mode" "single")])
10195 (define_insn "cmpeqsf_t"
10196   [(set (reg:SI T_REG)
10197         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10198                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10199   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10200   "fcmp/eq      %1,%0"
10201   [(set_attr "type" "fp")
10202    (set_attr "fp_mode" "single")])
10204 (define_insn "ieee_ccmpeqsf_t"
10205   [(set (reg:SI T_REG)
10206         (ior:SI (reg:SI T_REG)
10207                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10208                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10209   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10210   "* return output_ieee_ccmpeq (insn, operands);"
10211   [(set_attr "length" "4")])
10214 (define_insn "cmpgtsf_t_i4"
10215   [(set (reg:SI T_REG)
10216         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10217                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10218    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10219   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10220   "fcmp/gt      %1,%0"
10221   [(set_attr "type" "fp")
10222    (set_attr "fp_mode" "single")])
10224 (define_insn "cmpeqsf_t_i4"
10225   [(set (reg:SI T_REG)
10226         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10227                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10228    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10229   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10230   "fcmp/eq      %1,%0"
10231   [(set_attr "type" "fp")
10232    (set_attr "fp_mode" "single")])
10234 (define_insn "*ieee_ccmpeqsf_t_4"
10235   [(set (reg:SI T_REG)
10236         (ior:SI (reg:SI T_REG)
10237                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10238                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10239    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10240   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10241   "* return output_ieee_ccmpeq (insn, operands);"
10242   [(set_attr "length" "4")
10243    (set_attr "fp_mode" "single")])
10245 (define_insn "cmpeqsf_media"
10246   [(set (match_operand:DI 0 "register_operand" "=r")
10247         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10248                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10249   "TARGET_SHMEDIA_FPU"
10250   "fcmpeq.s     %1, %2, %0"
10251   [(set_attr "type" "fcmp_media")])
10253 (define_insn "cmpsieqsf_media"
10254   [(set (match_operand:SI 0 "register_operand" "=r")
10255         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10256                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10257   "TARGET_SHMEDIA_FPU"
10258   "fcmpeq.s     %1, %2, %0"
10259   [(set_attr "type" "fcmp_media")])
10261 (define_insn "cmpgtsf_media"
10262   [(set (match_operand:DI 0 "register_operand" "=r")
10263         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10264                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10265   "TARGET_SHMEDIA_FPU"
10266   "fcmpgt.s     %1, %2, %0"
10267   [(set_attr "type" "fcmp_media")])
10269 (define_insn "cmpgesf_media"
10270   [(set (match_operand:DI 0 "register_operand" "=r")
10271         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10272                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10273   "TARGET_SHMEDIA_FPU"
10274   "fcmpge.s     %1, %2, %0"
10275   [(set_attr "type" "fcmp_media")])
10277 (define_insn "cmpunsf_media"
10278   [(set (match_operand:DI 0 "register_operand" "=r")
10279         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10280                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10281   "TARGET_SHMEDIA_FPU"
10282   "fcmpun.s     %1, %2, %0"
10283   [(set_attr "type" "fcmp_media")])
10285 (define_expand "cmpsf"
10286   [(set (reg:SI T_REG)
10287         (compare (match_operand:SF 0 "arith_operand" "")
10288                  (match_operand:SF 1 "arith_operand" "")))]
10289   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10290   "
10292   sh_compare_op0 = operands[0];
10293   sh_compare_op1 = operands[1];
10294   DONE;
10297 (define_expand "negsf2"
10298   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10299         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10300   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10301   "
10303   if (TARGET_SH2E)
10304     {
10305       expand_sf_unop (&gen_negsf2_i, operands);
10306       DONE;
10307     }
10310 (define_insn "*negsf2_media"
10311   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10312         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10313   "TARGET_SHMEDIA_FPU"
10314   "fneg.s       %1, %0"
10315   [(set_attr "type" "fmove_media")])
10317 (define_insn "negsf2_i"
10318   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10319         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10320    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10321   "TARGET_SH2E"
10322   "fneg %0"
10323   [(set_attr "type" "fmove")
10324    (set_attr "fp_mode" "single")])
10326 (define_expand "sqrtsf2"
10327   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10328         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10329   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10330   "
10332   if (TARGET_SH3E)
10333     {
10334       expand_sf_unop (&gen_sqrtsf2_i, operands);
10335       DONE;
10336     }
10339 (define_insn "*sqrtsf2_media"
10340   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10341         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10342   "TARGET_SHMEDIA_FPU"
10343   "fsqrt.s      %1, %0"
10344   [(set_attr "type" "fdiv_media")])
10346 (define_insn "sqrtsf2_i"
10347   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10348         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10349    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10350   "TARGET_SH3E"
10351   "fsqrt        %0"
10352   [(set_attr "type" "fdiv")
10353    (set_attr "fp_mode" "single")])
10355 (define_insn "rsqrtsf2"
10356   [(set (match_operand:SF 0 "register_operand" "=f")
10357         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10358                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10359    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10360   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10361    && operands[1] == CONST1_RTX (SFmode)"
10362   "fsrra        %0"
10363   [(set_attr "type" "fsrra")
10364    (set_attr "fp_mode" "single")])
10366 (define_insn "fsca"
10367   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10368         (vec_concat:V2SF
10369          (unspec:SF [(mult:SF
10370                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10371                       (match_operand:SF 2 "immediate_operand" "i"))
10372                     ] UNSPEC_FSINA)
10373          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10374                     ] UNSPEC_FCOSA)))
10375    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10376   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10377    && operands[2] == sh_fsca_int2sf ()"
10378   "fsca fpul,%d0"
10379   [(set_attr "type" "fsca")
10380    (set_attr "fp_mode" "single")])
10382 (define_expand "sinsf2"
10383   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10384         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10385                    UNSPEC_FSINA))]
10386   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10387   "
10389   rtx scaled = gen_reg_rtx (SFmode);
10390   rtx truncated = gen_reg_rtx (SImode);
10391   rtx fsca = gen_reg_rtx (V2SFmode);
10392   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10394   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10395   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10396   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10397                           get_fpscr_rtx ()));
10398   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10399   DONE;
10402 (define_expand "cossf2"
10403   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10404         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10405                    UNSPEC_FCOSA))]
10406   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10407   "
10409   rtx scaled = gen_reg_rtx (SFmode);
10410   rtx truncated = gen_reg_rtx (SImode);
10411   rtx fsca = gen_reg_rtx (V2SFmode);
10412   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10414   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10415   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10416   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10417                           get_fpscr_rtx ()));
10418   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10419   DONE;
10422 (define_expand "sindf2"
10423   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10424         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10425                    UNSPEC_FSINA))]
10426   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10427   "
10429   rtx scaled = gen_reg_rtx (DFmode);
10430   rtx truncated = gen_reg_rtx (SImode);
10431   rtx fsca = gen_reg_rtx (V2SFmode);
10432   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10433   rtx sfresult = gen_reg_rtx (SFmode);
10435   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10436   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10437   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10438                           get_fpscr_rtx ()));
10439   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10440   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10441   DONE;
10444 (define_expand "cosdf2"
10445   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10446         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10447                    UNSPEC_FCOSA))]
10448   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10449   "
10451   rtx scaled = gen_reg_rtx (DFmode);
10452   rtx truncated = gen_reg_rtx (SImode);
10453   rtx fsca = gen_reg_rtx (V2SFmode);
10454   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10455   rtx sfresult = gen_reg_rtx (SFmode);
10457   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10458   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10459   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10460                           get_fpscr_rtx ()));
10461   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10462   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10463   DONE;
10466 (define_expand "abssf2"
10467   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10468         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10469   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10470   "
10472   if (TARGET_SH2E)
10473     {
10474       expand_sf_unop (&gen_abssf2_i, operands);
10475       DONE;
10476     }
10479 (define_insn "*abssf2_media"
10480   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10481         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10482   "TARGET_SHMEDIA_FPU"
10483   "fabs.s       %1, %0"
10484   [(set_attr "type" "fmove_media")])
10486 (define_insn "abssf2_i"
10487   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10488         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10489    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10490   "TARGET_SH2E"
10491   "fabs %0"
10492   [(set_attr "type" "fmove")
10493    (set_attr "fp_mode" "single")])
10495 (define_expand "adddf3"
10496   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10497         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10498                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10499   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10500   "
10502   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10503     {
10504       expand_df_binop (&gen_adddf3_i, operands);
10505       DONE;
10506     }
10509 (define_insn "*adddf3_media"
10510   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10511         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10512                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10513   "TARGET_SHMEDIA_FPU"
10514   "fadd.d       %1, %2, %0"
10515   [(set_attr "type" "dfparith_media")])
10517 (define_insn "adddf3_i"
10518   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10519         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10520                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10521    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10522   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10523   "fadd %2,%0"
10524   [(set_attr "type" "dfp_arith")
10525    (set_attr "fp_mode" "double")])
10527 (define_expand "subdf3"
10528   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10529         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10530                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10531   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10532   "
10534   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10535     {
10536       expand_df_binop (&gen_subdf3_i, operands);
10537       DONE;
10538     }
10541 (define_insn "*subdf3_media"
10542   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10543         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10544                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10545   "TARGET_SHMEDIA_FPU"
10546   "fsub.d       %1, %2, %0"
10547   [(set_attr "type" "dfparith_media")])
10549 (define_insn "subdf3_i"
10550   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10551         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10552                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10553    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10554   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10555   "fsub %2,%0"
10556   [(set_attr "type" "dfp_arith")
10557    (set_attr "fp_mode" "double")])
10559 (define_expand "muldf3"
10560   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10561         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10562                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10563   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10564   "
10566   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10567     {
10568       expand_df_binop (&gen_muldf3_i, operands);
10569       DONE;
10570     }
10573 (define_insn "*muldf3_media"
10574   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10575         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10576                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10577   "TARGET_SHMEDIA_FPU"
10578   "fmul.d       %1, %2, %0"
10579   [(set_attr "type" "dfmul_media")])
10581 (define_insn "muldf3_i"
10582   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10583         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10584                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10585    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10586   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10587   "fmul %2,%0"
10588   [(set_attr "type" "dfp_arith")
10589    (set_attr "fp_mode" "double")])
10591 (define_expand "divdf3"
10592   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10593         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10594                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10595   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10596   "
10598   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10599     {
10600       expand_df_binop (&gen_divdf3_i, operands);
10601       DONE;
10602     }
10605 (define_insn "*divdf3_media"
10606   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10607         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10608                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10609   "TARGET_SHMEDIA_FPU"
10610   "fdiv.d       %1, %2, %0"
10611   [(set_attr "type" "dfdiv_media")])
10613 (define_insn "divdf3_i"
10614   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10615         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10616                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10617    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10618   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10619   "fdiv %2,%0"
10620   [(set_attr "type" "dfdiv")
10621    (set_attr "fp_mode" "double")])
10623 (define_insn "floatdidf2"
10624   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10625         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10626   "TARGET_SHMEDIA_FPU"
10627   "float.qd     %1, %0"
10628   [(set_attr "type" "dfpconv_media")])
10630 (define_expand "floatsidf2"
10631   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10632         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10633   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10634   "
10636   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10637     {
10638       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10639                                       get_fpscr_rtx ()));
10640       DONE;
10641     }
10644 (define_insn "*floatsidf2_media"
10645   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10646         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10647   "TARGET_SHMEDIA_FPU"
10648   "float.ld     %1, %0"
10649   [(set_attr "type" "dfpconv_media")])
10651 (define_insn "floatsidf2_i"
10652   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10653         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10654    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10655   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10656   "float        %1,%0"
10657   [(set_attr "type" "dfp_conv")
10658    (set_attr "fp_mode" "double")])
10660 (define_insn "fix_truncdfdi2"
10661   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10662         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10663   "TARGET_SHMEDIA_FPU"
10664   "ftrc.dq      %1, %0"
10665   [(set_attr "type" "dfpconv_media")])
10667 (define_expand "fix_truncdfsi2"
10668   [(set (match_operand:SI 0 "fpul_operand" "")
10669         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10670   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10671   "
10673   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10674     {
10675       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10676                                           get_fpscr_rtx ()));
10677       DONE;
10678     }
10681 (define_insn "*fix_truncdfsi2_media"
10682   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10683         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10684   "TARGET_SHMEDIA_FPU"
10685   "ftrc.dl      %1, %0"
10686   [(set_attr "type" "dfpconv_media")])
10688 (define_insn "fix_truncdfsi2_i"
10689   [(set (match_operand:SI 0 "fpul_operand" "=y")
10690         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10691    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10692   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10693   "ftrc %1,%0"
10694   [(set_attr "type" "dfp_conv")
10695    (set_attr "dfp_comp" "no")
10696    (set_attr "fp_mode" "double")])
10698 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10699 ;; fix_truncdfsi2_i.
10700 ;; (define_insn "fix_truncdfsi2_i4"
10701 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10702 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10703 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10704 ;;    (clobber (reg:SI FPUL_REG))]
10705 ;;   "TARGET_SH4"
10706 ;;   "#"
10707 ;;   [(set_attr "length" "4")
10708 ;;    (set_attr "fp_mode" "double")])
10710 ;; (define_split
10711 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10712 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10713 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10714 ;;    (clobber (reg:SI FPUL_REG))]
10715 ;;   "TARGET_SH4"
10716 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10717 ;;            (use (match_dup 2))])
10718 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10720 (define_insn "cmpgtdf_t"
10721   [(set (reg:SI T_REG)
10722         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10723                (match_operand:DF 1 "arith_reg_operand" "f")))
10724    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10725   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10726   "fcmp/gt      %1,%0"
10727   [(set_attr "type" "dfp_cmp")
10728    (set_attr "fp_mode" "double")])
10730 (define_insn "cmpeqdf_t"
10731   [(set (reg:SI T_REG)
10732         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10733                (match_operand:DF 1 "arith_reg_operand" "f")))
10734    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10735   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10736   "fcmp/eq      %1,%0"
10737   [(set_attr "type" "dfp_cmp")
10738    (set_attr "fp_mode" "double")])
10740 (define_insn "*ieee_ccmpeqdf_t"
10741   [(set (reg:SI T_REG)
10742         (ior:SI (reg:SI T_REG)
10743                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10744                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10745    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10746   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10747   "* return output_ieee_ccmpeq (insn, operands);"
10748   [(set_attr "length" "4")
10749    (set_attr "fp_mode" "double")])
10751 (define_insn "cmpeqdf_media"
10752   [(set (match_operand:DI 0 "register_operand" "=r")
10753         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10754                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10755   "TARGET_SHMEDIA_FPU"
10756   "fcmpeq.d     %1,%2,%0"
10757   [(set_attr "type" "fcmp_media")])
10759 (define_insn "cmpsieqdf_media"
10760   [(set (match_operand:SI 0 "register_operand" "=r")
10761         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10762                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10763   "TARGET_SHMEDIA_FPU"
10764   "fcmpeq.d     %1,%2,%0"
10765   [(set_attr "type" "fcmp_media")])
10767 (define_insn "cmpgtdf_media"
10768   [(set (match_operand:DI 0 "register_operand" "=r")
10769         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10770                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10771   "TARGET_SHMEDIA_FPU"
10772   "fcmpgt.d     %1,%2,%0"
10773   [(set_attr "type" "fcmp_media")])
10775 (define_insn "cmpgedf_media"
10776   [(set (match_operand:DI 0 "register_operand" "=r")
10777         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10778                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10779   "TARGET_SHMEDIA_FPU"
10780   "fcmpge.d     %1,%2,%0"
10781   [(set_attr "type" "fcmp_media")])
10783 (define_insn "cmpundf_media"
10784   [(set (match_operand:DI 0 "register_operand" "=r")
10785         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10786                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10787   "TARGET_SHMEDIA_FPU"
10788   "fcmpun.d     %1,%2,%0"
10789   [(set_attr "type" "fcmp_media")])
10791 (define_expand "cmpdf"
10792   [(set (reg:SI T_REG)
10793         (compare (match_operand:DF 0 "arith_operand" "")
10794                  (match_operand:DF 1 "arith_operand" "")))]
10795   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10796   "
10798   sh_compare_op0 = operands[0];
10799   sh_compare_op1 = operands[1];
10800   DONE;
10803 (define_expand "negdf2"
10804   [(set (match_operand:DF 0 "arith_reg_operand" "")
10805         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10806   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10807   "
10809   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10810     {
10811       expand_df_unop (&gen_negdf2_i, operands);
10812       DONE;
10813     }
10816 (define_insn "*negdf2_media"
10817   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10818         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10819   "TARGET_SHMEDIA_FPU"
10820   "fneg.d       %1, %0"
10821   [(set_attr "type" "fmove_media")])
10823 (define_insn "negdf2_i"
10824   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10825         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10826    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10827   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10828   "fneg %0"
10829   [(set_attr "type" "fmove")
10830    (set_attr "fp_mode" "double")])
10832 (define_expand "sqrtdf2"
10833   [(set (match_operand:DF 0 "arith_reg_operand" "")
10834         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10835   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10836   "
10838   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10839     {
10840       expand_df_unop (&gen_sqrtdf2_i, operands);
10841       DONE;
10842     }
10845 (define_insn "*sqrtdf2_media"
10846   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10847         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10848   "TARGET_SHMEDIA_FPU"
10849   "fsqrt.d      %1, %0"
10850   [(set_attr "type" "dfdiv_media")])
10852 (define_insn "sqrtdf2_i"
10853   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10854         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10855    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10856   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10857   "fsqrt        %0"
10858   [(set_attr "type" "dfdiv")
10859    (set_attr "fp_mode" "double")])
10861 (define_expand "absdf2"
10862   [(set (match_operand:DF 0 "arith_reg_operand" "")
10863         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10864   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10865   "
10867   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10868     {
10869       expand_df_unop (&gen_absdf2_i, operands);
10870       DONE;
10871     }
10874 (define_insn "*absdf2_media"
10875   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10876         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10877   "TARGET_SHMEDIA_FPU"
10878   "fabs.d       %1, %0"
10879   [(set_attr "type" "fmove_media")])
10881 (define_insn "absdf2_i"
10882   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10883         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10884    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10885   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10886   "fabs %0"
10887   [(set_attr "type" "fmove")
10888    (set_attr "fp_mode" "double")])
10890 (define_expand "extendsfdf2"
10891   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10892         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10893   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10894   "
10896   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10897     {
10898       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10899                                         get_fpscr_rtx ()));
10900       DONE;
10901     }
10904 (define_insn "*extendsfdf2_media"
10905   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10906         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10907   "TARGET_SHMEDIA_FPU"
10908   "fcnv.sd      %1, %0"
10909   [(set_attr "type" "dfpconv_media")])
10911 (define_insn "extendsfdf2_i4"
10912   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10913         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10914    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10915   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10916   "fcnvsd  %1,%0"
10917   [(set_attr "type" "fp")
10918    (set_attr "fp_mode" "double")])
10920 (define_expand "truncdfsf2"
10921   [(set (match_operand:SF 0 "fpul_operand" "")
10922         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10923   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10924   "
10926   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10927     {
10928       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10929                                        get_fpscr_rtx ()));
10930       DONE;
10931     }
10934 (define_insn "*truncdfsf2_media"
10935   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10936         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10937   "TARGET_SHMEDIA_FPU"
10938   "fcnv.ds      %1, %0"
10939   [(set_attr "type" "dfpconv_media")])
10941 (define_insn "truncdfsf2_i4"
10942   [(set (match_operand:SF 0 "fpul_operand" "=y")
10943         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10944    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10945   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10946   "fcnvds  %1,%0"
10947   [(set_attr "type" "fp")
10948    (set_attr "fp_mode" "double")])
10950 ;; Bit field extract patterns.  These give better code for packed bitfields,
10951 ;; because they allow auto-increment addresses to be generated.
10953 (define_expand "insv"
10954   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10955                          (match_operand:SI 1 "immediate_operand" "")
10956                          (match_operand:SI 2 "immediate_operand" ""))
10957         (match_operand:SI 3 "general_operand" ""))]
10958   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10959   "
10961   rtx addr_target, orig_address, shift_reg, qi_val;
10962   HOST_WIDE_INT bitsize, size, v = 0;
10963   rtx x = operands[3];
10965   /* ??? expmed doesn't care for non-register predicates.  */
10966   if (! memory_operand (operands[0], VOIDmode)
10967       || ! immediate_operand (operands[1], VOIDmode)
10968       || ! immediate_operand (operands[2], VOIDmode)
10969       || ! general_operand (x, VOIDmode))
10970     FAIL;
10971   /* If this isn't a 16 / 24 / 32 bit field, or if
10972      it doesn't start on a byte boundary, then fail.  */
10973   bitsize = INTVAL (operands[1]);
10974   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10975       || (INTVAL (operands[2]) % 8) != 0)
10976     FAIL;
10978   size = bitsize / 8;
10979   orig_address = XEXP (operands[0], 0);
10980   shift_reg = gen_reg_rtx (SImode);
10981   if (GET_CODE (x) == CONST_INT)
10982     {
10983       v = INTVAL (x);
10984       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10985     }
10986   else
10987     {
10988       emit_insn (gen_movsi (shift_reg, operands[3]));
10989       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10990     }
10991   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10993   operands[0] = replace_equiv_address (operands[0], addr_target);
10994   emit_insn (gen_movqi (operands[0], qi_val));
10996   while (size -= 1)
10997     {
10998       if (GET_CODE (x) == CONST_INT)
10999         qi_val
11000           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11001       else
11002         {
11003           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11004           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11005         }
11006       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11007       emit_insn (gen_movqi (operands[0], qi_val));
11008     }
11010   DONE;
11013 (define_insn "movua"
11014   [(set (match_operand:SI 0 "register_operand" "=z")
11015         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11016                          (const_int 32) (const_int 0)))]
11017   "TARGET_SH4A_ARCH"
11018   "movua.l      %1,%0"
11019   [(set_attr "type" "movua")])
11021 ;; We shouldn't need this, but cse replaces increments with references
11022 ;; to other regs before flow has a chance to create post_inc
11023 ;; addressing modes, and only postreload's cse_move2add brings the
11024 ;; increments back to a usable form.
11025 (define_peephole2
11026   [(set (match_operand:SI 0 "register_operand" "")
11027         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11028                          (const_int 32) (const_int 0)))
11029    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11030   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11031   [(set (match_operand:SI 0 "register_operand" "")
11032         (sign_extract:SI (mem:SI (post_inc:SI
11033                                   (match_operand:SI 1 "register_operand" "")))
11034                          (const_int 32) (const_int 0)))]
11035   "")
11037 (define_expand "extv"
11038   [(set (match_operand:SI 0 "register_operand" "")
11039         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11040                          (match_operand 2 "const_int_operand" "")
11041                          (match_operand 3 "const_int_operand" "")))]
11042   "TARGET_SH4A_ARCH"
11044   if (TARGET_SH4A_ARCH
11045       && INTVAL (operands[2]) == 32
11046       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11047       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11048     {
11049       emit_insn (gen_movua (operands[0],
11050                             adjust_address (operands[1], SImode, 0)));
11051       DONE;
11052     }
11054   FAIL;
11057 (define_expand "extzv"
11058   [(set (match_operand:SI 0 "register_operand" "")
11059         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11060                          (match_operand 2 "const_int_operand" "")
11061                          (match_operand 3 "const_int_operand" "")))]
11062   "TARGET_SH4A_ARCH"
11064   if (TARGET_SH4A_ARCH
11065       && INTVAL (operands[2]) == 32
11066       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11067       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11068     {
11069       emit_insn (gen_movua (operands[0],
11070                             adjust_address (operands[1], SImode, 0)));
11071       DONE;
11072     }
11074   FAIL;
11078 ;; -------------------------------------------------------------------------
11079 ;; Peepholes
11080 ;; -------------------------------------------------------------------------
11082 ;; This matches cases where a stack pointer increment at the start of the
11083 ;; epilogue combines with a stack slot read loading the return value.
11085 (define_peephole
11086   [(set (match_operand:SI 0 "arith_reg_operand" "")
11087         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11088    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11089   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11090   "mov.l        @%1+,%0")
11092 ;; See the comment on the dt combiner pattern above.
11094 (define_peephole
11095   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11096         (plus:SI (match_dup 0)
11097                  (const_int -1)))
11098    (set (reg:SI T_REG)
11099         (eq:SI (match_dup 0)
11100                (const_int 0)))]
11101   "TARGET_SH2"
11102   "dt   %0")
11104 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11105 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11106 ;; reload when the constant is too large for a reg+offset address.
11108 ;; ??? We would get much better code if this was done in reload.  This would
11109 ;; require modifying find_reloads_address to recognize that if the constant
11110 ;; is out-of-range for an immediate add, then we get better code by reloading
11111 ;; the constant into a register than by reloading the sum into a register,
11112 ;; since the former is one instruction shorter if the address does not need
11113 ;; to be offsettable.  Unfortunately this does not work, because there is
11114 ;; only one register, r0, that can be used as an index register.  This register
11115 ;; is also the function return value register.  So, if we try to force reload
11116 ;; to use double-reg addresses, then we end up with some instructions that
11117 ;; need to use r0 twice.  The only way to fix this is to change the calling
11118 ;; convention so that r0 is not used to return values.
11120 (define_peephole
11121   [(set (match_operand:SI 0 "register_operand" "=r")
11122         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11123    (set (mem:SI (match_dup 0))
11124         (match_operand:SI 2 "general_movsrc_operand" ""))]
11125   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11126   "mov.l        %2,@(%0,%1)")
11128 (define_peephole
11129   [(set (match_operand:SI 0 "register_operand" "=r")
11130         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11131    (set (match_operand:SI 2 "general_movdst_operand" "")
11132         (mem:SI (match_dup 0)))]
11133   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11134   "mov.l        @(%0,%1),%2")
11136 (define_peephole
11137   [(set (match_operand:SI 0 "register_operand" "=r")
11138         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11139    (set (mem:HI (match_dup 0))
11140         (match_operand:HI 2 "general_movsrc_operand" ""))]
11141   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11142   "mov.w        %2,@(%0,%1)")
11144 (define_peephole
11145   [(set (match_operand:SI 0 "register_operand" "=r")
11146         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11147    (set (match_operand:HI 2 "general_movdst_operand" "")
11148         (mem:HI (match_dup 0)))]
11149   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11150   "mov.w        @(%0,%1),%2")
11152 (define_peephole
11153   [(set (match_operand:SI 0 "register_operand" "=r")
11154         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11155    (set (mem:QI (match_dup 0))
11156         (match_operand:QI 2 "general_movsrc_operand" ""))]
11157   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11158   "mov.b        %2,@(%0,%1)")
11160 (define_peephole
11161   [(set (match_operand:SI 0 "register_operand" "=r")
11162         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11163    (set (match_operand:QI 2 "general_movdst_operand" "")
11164         (mem:QI (match_dup 0)))]
11165   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11166   "mov.b        @(%0,%1),%2")
11168 (define_peephole
11169   [(set (match_operand:SI 0 "register_operand" "=r")
11170         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11171    (set (mem:SF (match_dup 0))
11172         (match_operand:SF 2 "general_movsrc_operand" ""))]
11173   "TARGET_SH1 && REGNO (operands[0]) == 0
11174    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11175        || (GET_CODE (operands[2]) == SUBREG
11176            && REGNO (SUBREG_REG (operands[2])) < 16))
11177    && reg_unused_after (operands[0], insn)"
11178   "mov.l        %2,@(%0,%1)")
11180 (define_peephole
11181   [(set (match_operand:SI 0 "register_operand" "=r")
11182         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11183    (set (match_operand:SF 2 "general_movdst_operand" "")
11185         (mem:SF (match_dup 0)))]
11186   "TARGET_SH1 && REGNO (operands[0]) == 0
11187    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11188        || (GET_CODE (operands[2]) == SUBREG
11189            && REGNO (SUBREG_REG (operands[2])) < 16))
11190    && reg_unused_after (operands[0], insn)"
11191   "mov.l        @(%0,%1),%2")
11193 (define_peephole
11194   [(set (match_operand:SI 0 "register_operand" "=r")
11195         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11196    (set (mem:SF (match_dup 0))
11197         (match_operand:SF 2 "general_movsrc_operand" ""))]
11198   "TARGET_SH2E && REGNO (operands[0]) == 0
11199    && ((GET_CODE (operands[2]) == REG
11200         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11201        || (GET_CODE (operands[2]) == SUBREG
11202            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11203    && reg_unused_after (operands[0], insn)"
11204   "fmov{.s|}    %2,@(%0,%1)")
11206 (define_peephole
11207   [(set (match_operand:SI 0 "register_operand" "=r")
11208         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11209    (set (match_operand:SF 2 "general_movdst_operand" "")
11211         (mem:SF (match_dup 0)))]
11212   "TARGET_SH2E && REGNO (operands[0]) == 0
11213    && ((GET_CODE (operands[2]) == REG
11214         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11215        || (GET_CODE (operands[2]) == SUBREG
11216            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11217    && reg_unused_after (operands[0], insn)"
11218   "fmov{.s|}    @(%0,%1),%2")
11220 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11221 (define_insn "sp_switch_1"
11222   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11223   "TARGET_SH1"
11224   "*
11226   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11227   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11228   return \"mov r0,r15\";
11230   [(set_attr "length" "10")])
11232 ;; Switch back to the original stack for interrupt functions with the
11233 ;; sp_switch attribute.  */
11234 (define_insn "sp_switch_2"
11235   [(const_int 2)]
11236   "TARGET_SH1"
11237   "mov.l @r15+,r15\;mov.l @r15+,r0"
11238   [(set_attr "length" "4")])
11240 ;; Integer vector moves
11242 (define_expand "movv8qi"
11243   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11244         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11245   "TARGET_SHMEDIA"
11246   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11248 (define_insn "movv8qi_i"
11249   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11250         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11251   "TARGET_SHMEDIA
11252    && (register_operand (operands[0], V8QImode)
11253        || sh_register_operand (operands[1], V8QImode))"
11254   "@
11255         add     %1, r63, %0
11256         movi    %1, %0
11257         #
11258         ld%M1.q %m1, %0
11259         st%M0.q %m0, %N1"
11260   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11261    (set_attr "length" "4,4,16,4,4")])
11263 (define_split
11264   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11265         (subreg:V8QI (const_int 0) 0))]
11266   "TARGET_SHMEDIA"
11267   [(set (match_dup 0)
11268         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11269                             (const_int 0) (const_int 0) (const_int 0)
11270                             (const_int 0) (const_int 0)]))])
11272 (define_split
11273   [(set (match_operand 0 "arith_reg_dest" "")
11274         (match_operand 1 "sh_rep_vec" ""))]
11275   "TARGET_SHMEDIA && reload_completed
11276    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11277    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11278    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11279    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11280        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11281    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11282        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11283   [(set (match_dup 0) (match_dup 1))
11284    (match_dup 2)]
11285   "
11287   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11288   rtx elt1 = XVECEXP (operands[1], 0, 1);
11290   if (unit_size > 2)
11291     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11292   else
11293     {
11294       if (unit_size < 2)
11295         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11296       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11297     }
11298   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11299   operands[1] = XVECEXP (operands[1], 0, 0);
11300   if (unit_size < 2)
11301     {
11302       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11303         operands[1]
11304           = GEN_INT (TARGET_LITTLE_ENDIAN
11305                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11306                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11307       else
11308         {
11309           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11310           operands[1]
11311             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11312         }
11313     }
11316 (define_split
11317   [(set (match_operand 0 "arith_reg_dest" "")
11318         (match_operand 1 "sh_const_vec" ""))]
11319   "TARGET_SHMEDIA && reload_completed
11320    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11321    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11322   [(set (match_dup 0) (match_dup 1))]
11323   "
11325   rtx v = operands[1];
11326   enum machine_mode new_mode
11327     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11329   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11330   operands[1]
11331     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11334 (define_expand "movv2hi"
11335   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11336         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11337   "TARGET_SHMEDIA"
11338   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11340 (define_insn "movv2hi_i"
11341   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11342         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11343   "TARGET_SHMEDIA
11344    && (register_operand (operands[0], V2HImode)
11345        || sh_register_operand (operands[1], V2HImode))"
11346   "@
11347         add.l   %1, r63, %0
11348         movi    %1, %0
11349         #
11350         ld%M1.l %m1, %0
11351         st%M0.l %m0, %N1"
11352   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11353    (set_attr "length" "4,4,16,4,4")
11354    (set (attr "highpart")
11355         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11356                (const_string "user")]
11357               (const_string "ignore")))])
11359 (define_expand "movv4hi"
11360   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11361         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11362   "TARGET_SHMEDIA"
11363   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11365 (define_insn "movv4hi_i"
11366   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11367         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11368   "TARGET_SHMEDIA
11369    && (register_operand (operands[0], V4HImode)
11370        || sh_register_operand (operands[1], V4HImode))"
11371   "@
11372         add     %1, r63, %0
11373         movi    %1, %0
11374         #
11375         ld%M1.q %m1, %0
11376         st%M0.q %m0, %N1"
11377   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11378    (set_attr "length" "4,4,16,4,4")
11379    (set_attr "highpart" "depend")])
11381 (define_expand "movv2si"
11382   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11383         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11384   "TARGET_SHMEDIA"
11385   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11387 (define_insn "movv2si_i"
11388   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11389         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11390   "TARGET_SHMEDIA
11391    && (register_operand (operands[0], V2SImode)
11392        || sh_register_operand (operands[1], V2SImode))"
11393   "@
11394         add     %1, r63, %0
11395         #
11396         #
11397         ld%M1.q %m1, %0
11398         st%M0.q %m0, %N1"
11399   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11400    (set_attr "length" "4,4,16,4,4")
11401    (set_attr "highpart" "depend")])
11403 ;; Multimedia Intrinsics
11405 (define_insn "absv2si2"
11406   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11407         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11408   "TARGET_SHMEDIA"
11409   "mabs.l       %1, %0"
11410   [(set_attr "type" "mcmp_media")
11411    (set_attr "highpart" "depend")])
11413 (define_insn "absv4hi2"
11414   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11415         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11416   "TARGET_SHMEDIA"
11417   "mabs.w       %1, %0"
11418   [(set_attr "type" "mcmp_media")
11419    (set_attr "highpart" "depend")])
11421 (define_insn "addv2si3"
11422   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11423         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11424                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11425   "TARGET_SHMEDIA"
11426   "madd.l       %1, %2, %0"
11427   [(set_attr "type" "arith_media")
11428    (set_attr "highpart" "depend")])
11430 (define_insn "addv4hi3"
11431   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11432         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11433                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11434   "TARGET_SHMEDIA"
11435   "madd.w       %1, %2, %0"
11436   [(set_attr "type" "arith_media")
11437    (set_attr "highpart" "depend")])
11439 (define_insn_and_split "addv2hi3"
11440   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11441         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11442                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11443   "TARGET_SHMEDIA"
11444   "#"
11445   "TARGET_SHMEDIA"
11446   [(const_int 0)]
11447   "
11449   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11450   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11451   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11452   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11453   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11455   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11456   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11457   DONE;
11459   [(set_attr "highpart" "must_split")])
11461 (define_insn "ssaddv2si3"
11462   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11463         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11464                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11465   "TARGET_SHMEDIA"
11466   "madds.l      %1, %2, %0"
11467   [(set_attr "type" "mcmp_media")
11468    (set_attr "highpart" "depend")])
11470 (define_insn "usaddv8qi3"
11471   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11472         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11473                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11474   "TARGET_SHMEDIA"
11475   "madds.ub     %1, %2, %0"
11476   [(set_attr "type" "mcmp_media")
11477    (set_attr "highpart" "depend")])
11479 (define_insn "ssaddv4hi3"
11480   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11481         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11482                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11483   "TARGET_SHMEDIA"
11484   "madds.w      %1, %2, %0"
11485   [(set_attr "type" "mcmp_media")
11486    (set_attr "highpart" "depend")])
11488 (define_insn "negcmpeqv8qi"
11489   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11490         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11491                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11492   "TARGET_SHMEDIA"
11493   "mcmpeq.b     %N1, %N2, %0"
11494   [(set_attr "type" "mcmp_media")
11495    (set_attr "highpart" "depend")])
11497 (define_insn "negcmpeqv2si"
11498   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11499         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11500                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11501   "TARGET_SHMEDIA"
11502   "mcmpeq.l     %N1, %N2, %0"
11503   [(set_attr "type" "mcmp_media")
11504    (set_attr "highpart" "depend")])
11506 (define_insn "negcmpeqv4hi"
11507   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11508         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11509                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11510   "TARGET_SHMEDIA"
11511   "mcmpeq.w     %N1, %N2, %0"
11512   [(set_attr "type" "mcmp_media")
11513    (set_attr "highpart" "depend")])
11515 (define_insn "negcmpgtuv8qi"
11516   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11517         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11518                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11519   "TARGET_SHMEDIA"
11520   "mcmpgt.ub    %N1, %N2, %0"
11521   [(set_attr "type" "mcmp_media")
11522    (set_attr "highpart" "depend")])
11524 (define_insn "negcmpgtv2si"
11525   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11526         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11527                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11528   "TARGET_SHMEDIA"
11529   "mcmpgt.l     %N1, %N2, %0"
11530   [(set_attr "type" "mcmp_media")
11531    (set_attr "highpart" "depend")])
11533 (define_insn "negcmpgtv4hi"
11534   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11535         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11536                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11537   "TARGET_SHMEDIA"
11538   "mcmpgt.w     %N1, %N2, %0"
11539   [(set_attr "type" "mcmp_media")
11540    (set_attr "highpart" "depend")])
11542 (define_insn "mcmv"
11543   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11544         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11545                         (match_operand:DI 2 "arith_reg_operand" "r"))
11546                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11547                         (not:DI (match_dup 2)))))]
11548   "TARGET_SHMEDIA"
11549   "mcmv %N1, %2, %0"
11550   [(set_attr "type" "arith_media")
11551    (set_attr "highpart" "depend")])
11553 (define_insn "mcnvs_lw"
11554   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11555         (vec_concat:V4HI
11556          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11557          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11558   "TARGET_SHMEDIA"
11559   "mcnvs.lw     %N1, %N2, %0"
11560   [(set_attr "type" "mcmp_media")])
11562 (define_insn "mcnvs_wb"
11563   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11564         (vec_concat:V8QI
11565          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11566          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11567   "TARGET_SHMEDIA"
11568   "mcnvs.wb     %N1, %N2, %0"
11569   [(set_attr "type" "mcmp_media")])
11571 (define_insn "mcnvs_wub"
11572   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11573         (vec_concat:V8QI
11574          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11575          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11576   "TARGET_SHMEDIA"
11577   "mcnvs.wub    %N1, %N2, %0"
11578   [(set_attr "type" "mcmp_media")])
11580 (define_insn "mextr_rl"
11581   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11582         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11583                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11584                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11585                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11586   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11587   "*
11589   static char templ[21];
11591   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11592            (int) INTVAL (operands[3]) >> 3);
11593   return templ;
11595   [(set_attr "type" "arith_media")])
11597 (define_insn "*mextr_lr"
11598   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11599         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11600                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11601                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11602                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11603   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11604   "*
11606   static char templ[21];
11608   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11609            (int) INTVAL (operands[4]) >> 3);
11610   return templ;
11612   [(set_attr "type" "arith_media")])
11614 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11615 ; vector then varies depending on endianness.
11616 (define_expand "mextr1"
11617   [(match_operand:DI 0 "arith_reg_dest" "")
11618    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11619    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11620   "TARGET_SHMEDIA"
11621   "
11623   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11624                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11625   DONE;
11628 (define_expand "mextr2"
11629   [(match_operand:DI 0 "arith_reg_dest" "")
11630    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11631    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11632   "TARGET_SHMEDIA"
11633   "
11635   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11636                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11637   DONE;
11640 (define_expand "mextr3"
11641   [(match_operand:DI 0 "arith_reg_dest" "")
11642    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11643    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11644   "TARGET_SHMEDIA"
11645   "
11647   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11648                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11649   DONE;
11652 (define_expand "mextr4"
11653   [(match_operand:DI 0 "arith_reg_dest" "")
11654    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11655    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11656   "TARGET_SHMEDIA"
11657   "
11659   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11660                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11661   DONE;
11664 (define_expand "mextr5"
11665   [(match_operand:DI 0 "arith_reg_dest" "")
11666    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11667    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11668   "TARGET_SHMEDIA"
11669   "
11671   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11672                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11673   DONE;
11676 (define_expand "mextr6"
11677   [(match_operand:DI 0 "arith_reg_dest" "")
11678    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11679    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11680   "TARGET_SHMEDIA"
11681   "
11683   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11684                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11685   DONE;
11688 (define_expand "mextr7"
11689   [(match_operand:DI 0 "arith_reg_dest" "")
11690    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11691    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11692   "TARGET_SHMEDIA"
11693   "
11695   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11696                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11697   DONE;
11700 (define_expand "mmacfx_wl"
11701   [(match_operand:V2SI 0 "arith_reg_dest" "")
11702    (match_operand:V2HI 1 "extend_reg_operand" "")
11703    (match_operand:V2HI 2 "extend_reg_operand" "")
11704    (match_operand:V2SI 3 "arith_reg_operand" "")]
11705   "TARGET_SHMEDIA"
11706   "
11708   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11709                               operands[1], operands[2]));
11710   DONE;
11713 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11714 ;; is depend
11715 (define_insn "mmacfx_wl_i"
11716   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11717         (ss_plus:V2SI
11718          (match_operand:V2SI 1 "arith_reg_operand" "0")
11719          (ss_truncate:V2SI
11720           (ashift:V2DI
11721            (sign_extend:V2DI
11722             (mult:V2SI
11723              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11724              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11725            (const_int 1)))))]
11726   "TARGET_SHMEDIA"
11727   "mmacfx.wl    %2, %3, %0"
11728   [(set_attr "type" "mac_media")
11729    (set_attr "highpart" "depend")])
11731 (define_expand "mmacnfx_wl"
11732   [(match_operand:V2SI 0 "arith_reg_dest" "")
11733    (match_operand:V2HI 1 "extend_reg_operand" "")
11734    (match_operand:V2HI 2 "extend_reg_operand" "")
11735    (match_operand:V2SI 3 "arith_reg_operand" "")]
11736   "TARGET_SHMEDIA"
11737   "
11739   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11740                                operands[1], operands[2]));
11741   DONE;
11744 (define_insn "mmacnfx_wl_i"
11745   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11746         (ss_minus:V2SI
11747          (match_operand:V2SI 1 "arith_reg_operand" "0")
11748          (ss_truncate:V2SI
11749           (ashift:V2DI
11750            (sign_extend:V2DI
11751             (mult:V2SI
11752              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11753              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11754            (const_int 1)))))]
11755   "TARGET_SHMEDIA"
11756   "mmacnfx.wl   %2, %3, %0"
11757   [(set_attr "type" "mac_media")
11758    (set_attr "highpart" "depend")])
11760 (define_insn "mulv2si3"
11761   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11762         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11763                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11764   "TARGET_SHMEDIA"
11765   "mmul.l       %1, %2, %0"
11766   [(set_attr "type" "d2mpy_media")
11767    (set_attr "highpart" "depend")])
11769 (define_insn "mulv4hi3"
11770   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11771         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11772                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11773   "TARGET_SHMEDIA"
11774   "mmul.w       %1, %2, %0"
11775   [(set_attr "type" "dmpy_media")
11776    (set_attr "highpart" "depend")])
11778 (define_insn "mmulfx_l"
11779   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11780         (ss_truncate:V2SI
11781          (ashiftrt:V2DI
11782           (mult:V2DI
11783            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11784            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11785           (const_int 31))))]
11786   "TARGET_SHMEDIA"
11787   "mmulfx.l     %1, %2, %0"
11788   [(set_attr "type" "d2mpy_media")
11789    (set_attr "highpart" "depend")])
11791 (define_insn "mmulfx_w"
11792   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11793         (ss_truncate:V4HI
11794          (ashiftrt:V4SI
11795           (mult:V4SI
11796            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11797            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11798           (const_int 15))))]
11799   "TARGET_SHMEDIA"
11800   "mmulfx.w     %1, %2, %0"
11801   [(set_attr "type" "dmpy_media")
11802    (set_attr "highpart" "depend")])
11804 (define_insn "mmulfxrp_w"
11805   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11806         (ss_truncate:V4HI
11807          (ashiftrt:V4SI
11808           (plus:V4SI
11809            (mult:V4SI
11810             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11811             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11812            (const_int 16384))
11813           (const_int 15))))]
11814   "TARGET_SHMEDIA"
11815   "mmulfxrp.w   %1, %2, %0"
11816   [(set_attr "type" "dmpy_media")
11817    (set_attr "highpart" "depend")])
11820 (define_expand "mmulhi_wl"
11821   [(match_operand:V2SI 0 "arith_reg_dest" "")
11822    (match_operand:V4HI 1 "arith_reg_operand" "")
11823    (match_operand:V4HI 2 "arith_reg_operand" "")]
11824   "TARGET_SHMEDIA"
11825   "
11827   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11828              (operands[0], operands[1], operands[2]));
11829   DONE;
11832 (define_expand "mmullo_wl"
11833   [(match_operand:V2SI 0 "arith_reg_dest" "")
11834    (match_operand:V4HI 1 "arith_reg_operand" "")
11835    (match_operand:V4HI 2 "arith_reg_operand" "")]
11836   "TARGET_SHMEDIA"
11837   "
11839   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11840              (operands[0], operands[1], operands[2]));
11841   DONE;
11844 (define_insn "mmul23_wl"
11845   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11846         (vec_select:V2SI
11847          (mult:V4SI
11848           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11849           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11850          (parallel [(const_int 2) (const_int 3)])))]
11851   "TARGET_SHMEDIA"
11852   "* return (TARGET_LITTLE_ENDIAN
11853              ? \"mmulhi.wl      %1, %2, %0\"
11854              : \"mmullo.wl      %1, %2, %0\");"
11855   [(set_attr "type" "dmpy_media")
11856    (set (attr "highpart")
11857         (cond [(eq_attr "endian" "big") (const_string "ignore")]
11858          (const_string "user")))])
11860 (define_insn "mmul01_wl"
11861   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11862         (vec_select:V2SI
11863          (mult:V4SI
11864           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11865           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11866          (parallel [(const_int 0) (const_int 1)])))]
11867   "TARGET_SHMEDIA"
11868   "* return (TARGET_LITTLE_ENDIAN
11869              ? \"mmullo.wl      %1, %2, %0\"
11870              : \"mmulhi.wl      %1, %2, %0\");"
11871   [(set_attr "type" "dmpy_media")
11872    (set (attr "highpart")
11873         (cond [(eq_attr "endian" "little") (const_string "ignore")]
11874          (const_string "user")))])
11877 (define_expand "mmulsum_wq"
11878   [(match_operand:DI 0 "arith_reg_dest" "")
11879    (match_operand:V4HI 1 "arith_reg_operand" "")
11880    (match_operand:V4HI 2 "arith_reg_operand" "")
11881    (match_operand:DI 3 "arith_reg_operand" "")]
11882   "TARGET_SHMEDIA"
11883   "
11885   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11886                                operands[1], operands[2]));
11887   DONE;
11890 (define_insn "mmulsum_wq_i"
11891   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11892         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11893          (plus:DI
11894           (plus:DI
11895            (vec_select:DI
11896             (mult:V4DI
11897              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11898              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11899             (parallel [(const_int 0)]))
11900            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11901                                      (sign_extend:V4DI (match_dup 3)))
11902                           (parallel [(const_int 1)])))
11903           (plus:DI
11904            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11905                                      (sign_extend:V4DI (match_dup 3)))
11906                           (parallel [(const_int 2)]))
11907            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11908                                      (sign_extend:V4DI (match_dup 3)))
11909                           (parallel [(const_int 3)]))))))]
11910   "TARGET_SHMEDIA"
11911   "mmulsum.wq   %2, %3, %0"
11912   [(set_attr "type" "mac_media")])
11914 (define_expand "mperm_w"
11915   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11916    (match_operand:V4HI 1 "arith_reg_operand" "r")
11917    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11918   "TARGET_SHMEDIA"
11919   "
11921   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11922              (operands[0], operands[1], operands[2]));
11923   DONE;
11926 ; This use of vec_select isn't exactly correct according to rtl.texi
11927 ; (because not constant), but it seems a straightforward extension.
11928 (define_insn "mperm_w_little"
11929   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11930         (vec_select:V4HI
11931          (match_operand:V4HI 1 "arith_reg_operand" "r")
11932          (parallel
11933           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11934                             (const_int 2) (const_int 0))
11935            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11936            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11937            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11938   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11939   "mperm.w      %1, %N2, %0"
11940   [(set_attr "type" "arith_media")])
11942 (define_insn "mperm_w_big"
11943   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11944         (vec_select:V4HI
11945          (match_operand:V4HI 1 "arith_reg_operand" "r")
11946          (parallel
11947           [(zero_extract:QI (not:QI (match_operand:QI 2
11948                                      "extend_reg_or_0_operand" "rZ"))
11949                             (const_int 2) (const_int 0))
11950            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11951            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11952            (zero_extract:QI (not:QI (match_dup 2))
11953                             (const_int 2) (const_int 6))])))]
11954   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11955   "mperm.w      %1, %N2, %0"
11956   [(set_attr "type" "arith_media")])
11958 (define_insn "mperm_w0"
11959   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11960         (vec_duplicate:V4HI (truncate:HI (match_operand 1
11961                                           "trunc_hi_operand" "r"))))]
11962   "TARGET_SHMEDIA"
11963   "mperm.w      %1, r63, %0"
11964   [(set_attr "type" "arith_media")
11965    (set_attr "highpart" "ignore")])
11967 (define_expand "msad_ubq"
11968   [(match_operand:DI 0 "arith_reg_dest" "")
11969    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
11970    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
11971    (match_operand:DI 3 "arith_reg_operand" "")]
11972   "TARGET_SHMEDIA"
11973   "
11975   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
11976                              operands[1], operands[2]));
11977   DONE;
11980 (define_insn "msad_ubq_i"
11981   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11982         (plus:DI
11983          (plus:DI
11984           (plus:DI
11985            (plus:DI
11986             (match_operand:DI 1 "arith_reg_operand" "0")
11987             (abs:DI (vec_select:DI
11988                      (minus:V8DI
11989                       (zero_extend:V8DI
11990                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
11991                       (zero_extend:V8DI
11992                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
11993                      (parallel [(const_int 0)]))))
11994            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
11995                                               (zero_extend:V8DI (match_dup 3)))
11996                                   (parallel [(const_int 1)]))))
11997           (plus:DI
11998            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
11999                                               (zero_extend:V8DI (match_dup 3)))
12000                                   (parallel [(const_int 2)])))
12001            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12002                                               (zero_extend:V8DI (match_dup 3)))
12003                                   (parallel [(const_int 3)])))))
12004          (plus:DI
12005           (plus:DI
12006            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12007                                               (zero_extend:V8DI (match_dup 3)))
12008                                   (parallel [(const_int 4)])))
12009            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12010                                               (zero_extend:V8DI (match_dup 3)))
12011                                   (parallel [(const_int 5)]))))
12012           (plus:DI
12013            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12014                                               (zero_extend:V8DI (match_dup 3)))
12015                                   (parallel [(const_int 6)])))
12016            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12017                                               (zero_extend:V8DI (match_dup 3)))
12018                                   (parallel [(const_int 7)])))))))]
12019   "TARGET_SHMEDIA"
12020   "msad.ubq     %N2, %N3, %0"
12021   [(set_attr "type" "mac_media")])
12023 (define_insn "mshalds_l"
12024   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12025         (ss_truncate:V2SI
12026          (ashift:V2DI
12027           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12028           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12029                   (const_int 31)))))]
12030   "TARGET_SHMEDIA"
12031   "mshalds.l    %1, %2, %0"
12032   [(set_attr "type" "mcmp_media")
12033    (set_attr "highpart" "depend")])
12035 (define_insn "mshalds_w"
12036   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12037         (ss_truncate:V4HI
12038          (ashift:V4SI
12039           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12040           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12041                   (const_int 15)))))]
12042   "TARGET_SHMEDIA"
12043   "mshalds.w    %1, %2, %0"
12044   [(set_attr "type" "mcmp_media")
12045    (set_attr "highpart" "depend")])
12047 (define_insn "ashrv2si3"
12048   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12049         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12050                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12051   "TARGET_SHMEDIA"
12052   "mshard.l     %1, %2, %0"
12053   [(set_attr "type" "arith_media")
12054    (set_attr "highpart" "depend")])
12056 (define_insn "ashrv4hi3"
12057   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12058         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12059                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12060   "TARGET_SHMEDIA"
12061   "mshard.w     %1, %2, %0"
12062   [(set_attr "type" "arith_media")
12063    (set_attr "highpart" "depend")])
12065 (define_insn "mshards_q"
12066   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12067         (ss_truncate:HI
12068          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12069                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12070   "TARGET_SHMEDIA"
12071   "mshards.q    %1, %N2, %0"
12072   [(set_attr "type" "mcmp_media")])
12074 (define_expand "mshfhi_b"
12075   [(match_operand:V8QI 0 "arith_reg_dest" "")
12076    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12077    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12078   "TARGET_SHMEDIA"
12079   "
12081   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12082              (operands[0], operands[1], operands[2]));
12083   DONE;
12086 (define_expand "mshflo_b"
12087   [(match_operand:V8QI 0 "arith_reg_dest" "")
12088    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12089    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12090   "TARGET_SHMEDIA"
12091   "
12093   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12094              (operands[0], operands[1], operands[2]));
12095   DONE;
12098 (define_insn "mshf4_b"
12099   [(set
12100     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12101     (vec_select:V8QI
12102      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12103                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12104      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12105                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12106   "TARGET_SHMEDIA"
12107   "* return (TARGET_LITTLE_ENDIAN
12108              ? \"mshfhi.b       %N1, %N2, %0\"
12109              : \"mshflo.b       %N1, %N2, %0\");"
12110   [(set_attr "type" "arith_media")
12111    (set (attr "highpart")
12112         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12113          (const_string "user")))])
12115 (define_insn "mshf0_b"
12116   [(set
12117     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12118     (vec_select:V8QI
12119      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12120                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12121      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12122                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12123   "TARGET_SHMEDIA"
12124   "* return (TARGET_LITTLE_ENDIAN
12125              ? \"mshflo.b       %N1, %N2, %0\"
12126              : \"mshfhi.b       %N1, %N2, %0\");"
12127   [(set_attr "type" "arith_media")
12128    (set (attr "highpart")
12129         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12130          (const_string "user")))])
12132 (define_expand "mshfhi_l"
12133   [(match_operand:V2SI 0 "arith_reg_dest" "")
12134    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12135    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12136   "TARGET_SHMEDIA"
12137   "
12139   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12140              (operands[0], operands[1], operands[2]));
12141   DONE;
12144 (define_expand "mshflo_l"
12145   [(match_operand:V2SI 0 "arith_reg_dest" "")
12146    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12147    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12148   "TARGET_SHMEDIA"
12149   "
12151   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12152              (operands[0], operands[1], operands[2]));
12153   DONE;
12156 (define_insn "mshf4_l"
12157   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12158         (vec_select:V2SI
12159          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12160                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12161          (parallel [(const_int 1) (const_int 3)])))]
12162   "TARGET_SHMEDIA"
12163   "* return (TARGET_LITTLE_ENDIAN
12164              ? \"mshfhi.l       %N1, %N2, %0\"
12165              : \"mshflo.l       %N1, %N2, %0\");"
12166   [(set_attr "type" "arith_media")
12167    (set (attr "highpart")
12168         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12169          (const_string "user")))])
12171 (define_insn "mshf0_l"
12172   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12173         (vec_select:V2SI
12174          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12175                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12176          (parallel [(const_int 0) (const_int 2)])))]
12177   "TARGET_SHMEDIA"
12178   "* return (TARGET_LITTLE_ENDIAN
12179              ? \"mshflo.l       %N1, %N2, %0\"
12180              : \"mshfhi.l       %N1, %N2, %0\");"
12181   [(set_attr "type" "arith_media")
12182    (set (attr "highpart")
12183         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12184          (const_string "user")))])
12186 (define_expand "mshfhi_w"
12187   [(match_operand:V4HI 0 "arith_reg_dest" "")
12188    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12189    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12190   "TARGET_SHMEDIA"
12191   "
12193   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12194              (operands[0], operands[1], operands[2]));
12195   DONE;
12198 (define_expand "mshflo_w"
12199   [(match_operand:V4HI 0 "arith_reg_dest" "")
12200    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12201    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12202   "TARGET_SHMEDIA"
12203   "
12205   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12206              (operands[0], operands[1], operands[2]));
12207   DONE;
12210 (define_insn "mshf4_w"
12211   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12212         (vec_select:V4HI
12213          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12214                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12215          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12216   "TARGET_SHMEDIA"
12217   "* return (TARGET_LITTLE_ENDIAN
12218              ? \"mshfhi.w       %N1, %N2, %0\"
12219              : \"mshflo.w       %N1, %N2, %0\");"
12220   [(set_attr "type" "arith_media")
12221    (set (attr "highpart")
12222         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12223          (const_string "user")))])
12225 (define_insn "mshf0_w"
12226   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12227         (vec_select:V4HI
12228          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12229                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12230          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12231   "TARGET_SHMEDIA"
12232   "* return (TARGET_LITTLE_ENDIAN
12233              ? \"mshflo.w       %N1, %N2, %0\"
12234              : \"mshfhi.w       %N1, %N2, %0\");"
12235   [(set_attr "type" "arith_media")
12236    (set (attr "highpart")
12237         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12238          (const_string "user")))])
12240 (define_insn "mshflo_w_x"
12241   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12242         (vec_select:V4HI
12243          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12244                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12245          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12246   "TARGET_SHMEDIA"
12247   "mshflo.w     %N1, %N2, %0"
12248   [(set_attr "type" "arith_media")
12249    (set_attr "highpart" "ignore")])
12251 /* These are useful to expand ANDs and as combiner patterns.  */
12252 (define_insn_and_split "mshfhi_l_di"
12253   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12254         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12255                              (const_int 32))
12256                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12257                         (const_int -4294967296))))]
12258   "TARGET_SHMEDIA"
12259   "@
12260         mshfhi.l        %N1, %N2, %0
12261         #"
12262   "TARGET_SHMEDIA && reload_completed
12263    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12264   [(set (match_dup 3) (match_dup 4))
12265    (set (match_dup 5) (match_dup 6))]
12266   "
12268   operands[3] = gen_lowpart (SImode, operands[0]);
12269   operands[4] = gen_highpart (SImode, operands[1]);
12270   operands[5] = gen_highpart (SImode, operands[0]);
12271   operands[6] = gen_highpart (SImode, operands[2]);
12273   [(set_attr "type" "arith_media")])
12275 (define_insn "*mshfhi_l_di_rev"
12276   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12277         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12278                         (const_int -4294967296))
12279                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12280                              (const_int 32))))]
12281   "TARGET_SHMEDIA"
12282   "mshfhi.l     %N2, %N1, %0"
12283   [(set_attr "type" "arith_media")])
12285 (define_split
12286   [(set (match_operand:DI 0 "arith_reg_dest" "")
12287         (ior:DI (zero_extend:DI (match_operand:SI 1
12288                                               "extend_reg_or_0_operand" ""))
12289                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12290                         (const_int -4294967296))))
12291    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12292   "TARGET_SHMEDIA"
12293   [(const_int 0)]
12294   "
12296   emit_insn (gen_ashldi3_media (operands[3],
12297                                 simplify_gen_subreg (DImode, operands[1],
12298                                                      SImode, 0),
12299                                 GEN_INT (32)));
12300   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12301   DONE;
12304 (define_insn "mshflo_l_di"
12305   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12306         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12307                         (const_int 4294967295))
12308                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12309                            (const_int 32))))]
12311   "TARGET_SHMEDIA"
12312   "mshflo.l     %N1, %N2, %0"
12313   [(set_attr "type" "arith_media")
12314    (set_attr "highpart" "ignore")])
12316 (define_insn "*mshflo_l_di_rev"
12317   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12318         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12319                            (const_int 32))
12320                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12321                         (const_int 4294967295))))]
12323   "TARGET_SHMEDIA"
12324   "mshflo.l     %N2, %N1, %0"
12325   [(set_attr "type" "arith_media")
12326    (set_attr "highpart" "ignore")])
12328 ;; Combiner pattern for trampoline initialization.
12329 (define_insn_and_split "*double_shori"
12330   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12331         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12332                            (const_int 32))
12333                 (match_operand:DI 2 "const_int_operand" "n")))]
12334   "TARGET_SHMEDIA
12335    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12336   "#"
12337   "rtx_equal_p (operands[0], operands[1])"
12338   [(const_int 0)]
12339   "
12341   HOST_WIDE_INT v = INTVAL (operands[2]);
12343   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12344   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12345   DONE;
12347   [(set_attr "highpart" "ignore")])
12350 (define_insn "*mshflo_l_di_x"
12351   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12352         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12353                                  "rZ"))
12354                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12355                            (const_int 32))))]
12357   "TARGET_SHMEDIA"
12358   "mshflo.l     %N1, %N2, %0"
12359   [(set_attr "type" "arith_media")
12360    (set_attr "highpart" "ignore")])
12362 (define_insn_and_split "concat_v2sf"
12363   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12364 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12365         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12366                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12368   "TARGET_SHMEDIA"
12369   "@
12370         mshflo.l        %N1, %N2, %0
12371         #
12372         #"
12373   "TARGET_SHMEDIA && reload_completed
12374    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12375   [(set (match_dup 3) (match_dup 1))
12376    (set (match_dup 4) (match_dup 2))]
12377   "
12379   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12380   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12382   [(set_attr "type" "arith_media")
12383    (set_attr "highpart" "ignore")])
12385 (define_insn "*mshflo_l_di_x_rev"
12386   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12387         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12388                            (const_int 32))
12389                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12391   "TARGET_SHMEDIA"
12392   "mshflo.l     %N2, %N1, %0"
12393   [(set_attr "type" "arith_media")
12394    (set_attr "highpart" "ignore")])
12396 (define_insn "ashlv2si3"
12397   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12398         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12399                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12400   "TARGET_SHMEDIA"
12401   "mshlld.l     %1, %2, %0"
12402   [(set_attr "type" "arith_media")
12403    (set_attr "highpart" "depend")])
12405 (define_split
12406   [(set (match_operand 0 "any_register_operand" "")
12407         (match_operator 3 "shift_operator"
12408           [(match_operand 1 "any_register_operand" "")
12409            (match_operand 2 "shift_count_reg_operand" "")]))]
12410   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12411   [(set (match_dup 0) (match_dup 3))]
12412   "
12414   rtx count = operands[2];
12415   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12417   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12418          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12419          || GET_CODE (count) == TRUNCATE)
12420     count = XEXP (count, 0);
12421   inner_mode = GET_MODE (count);
12422   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12423                                subreg_lowpart_offset (outer_mode, inner_mode));
12424   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12425                                 operands[1], count);
12428 (define_insn "ashlv4hi3"
12429   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12430         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12431                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12432   "TARGET_SHMEDIA"
12433   "mshlld.w     %1, %2, %0"
12434   [(set_attr "type" "arith_media")
12435    (set_attr "highpart" "depend")])
12437 (define_insn "lshrv2si3"
12438   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12439         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12440                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12441   "TARGET_SHMEDIA"
12442   "mshlrd.l     %1, %2, %0"
12443   [(set_attr "type" "arith_media")
12444    (set_attr "highpart" "depend")])
12446 (define_insn "lshrv4hi3"
12447   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12448         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12449                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12450   "TARGET_SHMEDIA"
12451   "mshlrd.w     %1, %2, %0"
12452   [(set_attr "type" "arith_media")
12453    (set_attr "highpart" "depend")])
12455 (define_insn "subv2si3"
12456   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12457         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12458                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12459   "TARGET_SHMEDIA"
12460   "msub.l       %N1, %2, %0"
12461   [(set_attr "type" "arith_media")
12462    (set_attr "highpart" "depend")])
12464 (define_insn "subv4hi3"
12465   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12466         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12467                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12468   "TARGET_SHMEDIA"
12469   "msub.w       %N1, %2, %0"
12470   [(set_attr "type" "arith_media")
12471    (set_attr "highpart" "depend")])
12473 (define_insn_and_split "subv2hi3"
12474   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12475         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12476                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12477   "TARGET_SHMEDIA"
12478   "#"
12479   "TARGET_SHMEDIA"
12480   [(const_int 0)]
12481   "
12483   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12484   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12485   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12486   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12487   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12489   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12490   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12491   DONE;
12493   [(set_attr "highpart" "must_split")])
12495 (define_insn "sssubv2si3"
12496   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12497         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12498                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12499   "TARGET_SHMEDIA"
12500   "msubs.l      %N1, %2, %0"
12501   [(set_attr "type" "mcmp_media")
12502    (set_attr "highpart" "depend")])
12504 (define_insn "ussubv8qi3"
12505   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12506         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12507                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12508   "TARGET_SHMEDIA"
12509   "msubs.ub     %N1, %2, %0"
12510   [(set_attr "type" "mcmp_media")
12511    (set_attr "highpart" "depend")])
12513 (define_insn "sssubv4hi3"
12514   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12515         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12516                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12517   "TARGET_SHMEDIA"
12518   "msubs.w      %N1, %2, %0"
12519   [(set_attr "type" "mcmp_media")
12520    (set_attr "highpart" "depend")])
12522 ;; Floating Point Intrinsics
12524 (define_insn "fcosa_s"
12525   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12526         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12527                    UNSPEC_FCOSA))]
12528   "TARGET_SHMEDIA"
12529   "fcosa.s      %1, %0"
12530   [(set_attr "type" "atrans_media")])
12532 (define_insn "fsina_s"
12533   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12534         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12535                    UNSPEC_FSINA))]
12536   "TARGET_SHMEDIA"
12537   "fsina.s      %1, %0"
12538   [(set_attr "type" "atrans_media")])
12540 (define_insn "fipr"
12541   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12542         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12543                                                     "fp_arith_reg_operand" "f")
12544                                                    (match_operand:V4SF 2
12545                                                     "fp_arith_reg_operand" "f"))
12546                                          (parallel [(const_int 0)]))
12547                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12548                                          (parallel [(const_int 1)])))
12549                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12550                                          (parallel [(const_int 2)]))
12551                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12552                                          (parallel [(const_int 3)])))))]
12553   "TARGET_SHMEDIA"
12554   "fipr.s       %1, %2, %0"
12555   [(set_attr "type" "fparith_media")])
12557 (define_insn "fsrra_s"
12558   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12559         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12560                    UNSPEC_FSRRA))]
12561   "TARGET_SHMEDIA"
12562   "fsrra.s      %1, %0"
12563   [(set_attr "type" "atrans_media")])
12565 (define_insn "ftrv"
12566   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12567         (plus:V4SF
12568          (plus:V4SF
12569           (mult:V4SF
12570            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12571                             (parallel [(const_int 0) (const_int 5)
12572                                        (const_int 10) (const_int 15)]))
12573            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12574           (mult:V4SF
12575            (vec_select:V4SF (match_dup 1)
12576                             (parallel [(const_int 4) (const_int 9)
12577                                        (const_int 14) (const_int 3)]))
12578            (vec_select:V4SF (match_dup 2)
12579                             (parallel [(const_int 1) (const_int 2)
12580                                        (const_int 3) (const_int 0)]))))
12581          (plus:V4SF
12582           (mult:V4SF
12583            (vec_select:V4SF (match_dup 1)
12584                             (parallel [(const_int 8) (const_int 13)
12585                                        (const_int 2) (const_int 7)]))
12586            (vec_select:V4SF (match_dup 2)
12587                             (parallel [(const_int 2) (const_int 3)
12588                                        (const_int 0) (const_int 1)])))
12589           (mult:V4SF
12590            (vec_select:V4SF (match_dup 1)
12591                             (parallel [(const_int 12) (const_int 1)
12592                                        (const_int 6) (const_int 11)]))
12593            (vec_select:V4SF (match_dup 2)
12594                             (parallel [(const_int 3) (const_int 0)
12595                                        (const_int 1) (const_int 2)]))))))]
12596   "TARGET_SHMEDIA"
12597   "ftrv.s %1, %2, %0"
12598   [(set_attr "type" "fparith_media")])
12600 (define_insn "ldhi_l"
12601   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12602         (zero_extract:SI
12603          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12604                                   (const_int 3))
12605                           (const_int -3)))
12606          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12607          (const_int 0)))]
12608   "TARGET_SHMEDIA32"
12609   "ldhi.l       %U1, %0"
12610   [(set_attr "type" "load_media")])
12612 (define_insn "ldhi_q"
12613   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12614         (zero_extract:DI
12615          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12616                                   (const_int 7))
12617                           (const_int -7)))
12618          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12619          (const_int 0)))]
12620   "TARGET_SHMEDIA32"
12621   "ldhi.q       %U1, %0"
12622   [(set_attr "type" "load_media")])
12624 (define_insn_and_split "*ldhi_q_comb0"
12625   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12626         (zero_extract:DI
12627          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12628                                             "register_operand" "r")
12629                                            (match_operand:SI 2
12630                                             "ua_offset" "I06"))
12631                                   (const_int 7))
12632                           (const_int -7)))
12633          (plus:SI (and:SI (match_dup 1) (const_int 7))
12634                   (const_int 1))
12635          (const_int 0)))]
12636   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12637   "#"
12638   ""
12639   [(pc)]
12640   "emit_insn (gen_ldhi_q (operands[0],
12641                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12642    DONE;")
12645 (define_insn_and_split "*ldhi_q_comb1"
12646   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12647         (zero_extract:DI
12648          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12649                                             "register_operand" "r")
12650                                            (match_operand:SI 2
12651                                             "ua_offset" "I06"))
12652                                   (const_int 7))
12653                           (const_int -7)))
12654          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12655                                                    "ua_offset" "I06"))
12656                           (const_int 7))
12657                   (const_int 1))
12658          (const_int 0)))]
12659   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12660    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12661   "#"
12662   ""
12663   [(pc)]
12664   "emit_insn (gen_ldhi_q (operands[0],
12665                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12666    DONE;")
12669 (define_insn "ldlo_l"
12670   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12671         (zero_extract:SI
12672          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12673                          (const_int -4)))
12674          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12675          (and:SI (match_dup 1) (const_int 3))))]
12676   "TARGET_SHMEDIA32"
12677   "ldlo.l       %U1, %0"
12678   [(set_attr "type" "load_media")])
12680 (define_insn "ldlo_q"
12681   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12682         (zero_extract:DI
12683          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12684                          (const_int -8)))
12685          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12686          (and:SI (match_dup 1) (const_int 7))))]
12687   "TARGET_SHMEDIA32"
12688   "ldlo.q       %U1, %0"
12689   [(set_attr "type" "load_media")])
12691 (define_insn_and_split "*ldlo_q_comb0"
12692   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12693         (zero_extract:DI
12694          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12695                                   (match_operand:SI 2 "ua_offset" "I06"))
12696                          (const_int -8)))
12697          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12698          (and:SI (match_dup 1) (const_int 7))))]
12699   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12700   "#"
12701   ""
12702   [(pc)]
12703   "emit_insn (gen_ldlo_q (operands[0],
12704                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12705    DONE;")
12707 (define_insn_and_split "*ldlo_q_comb1"
12708   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12709         (zero_extract:DI
12710          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12711                                   (match_operand:SI 2 "ua_offset" "I06"))
12712                          (const_int -8)))
12713          (minus:SI (const_int 8)
12714                    (and:SI (plus:SI (match_dup 1)
12715                                     (match_operand:SI 3 "ua_offset" "I06"))
12716                            (const_int 7)))
12717          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12718   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12719    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12720   "#"
12721   ""
12722   [(pc)]
12723   "emit_insn (gen_ldlo_q (operands[0],
12724                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12725    DONE;")
12727 (define_insn "sthi_l"
12728   [(set (zero_extract:SI
12729          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12730                                   (const_int 3))
12731                           (const_int -3)))
12732          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12733          (const_int 0))
12734         (match_operand:SI 1 "arith_reg_operand" "r"))]
12735   "TARGET_SHMEDIA32"
12736   "sthi.l       %U0, %1"
12737   [(set_attr "type" "ustore_media")])
12739 ;; All unaligned stores are considered to be 'narrow' because they typically
12740 ;; operate on less that a quadword, and when they operate on a full quadword,
12741 ;; the vanilla store high / store low sequence will cause a stall if not
12742 ;; scheduled apart.
12743 (define_insn "sthi_q"
12744   [(set (zero_extract:DI
12745          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12746                                   (const_int 7))
12747                           (const_int -7)))
12748          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12749          (const_int 0))
12750         (match_operand:DI 1 "arith_reg_operand" "r"))]
12751   "TARGET_SHMEDIA32"
12752   "sthi.q       %U0, %1"
12753   [(set_attr "type" "ustore_media")])
12755 (define_insn_and_split "*sthi_q_comb0"
12756   [(set (zero_extract:DI
12757          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12758                                             "register_operand" "r")
12759                                            (match_operand:SI 1 "ua_offset"
12760                                             "I06"))
12761                                   (const_int 7))
12762                           (const_int -7)))
12763          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12764          (const_int 0))
12765         (match_operand:DI 2 "arith_reg_operand" "r"))]
12766   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12767   "#"
12768   ""
12769   [(pc)]
12770   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12771                           operands[2]));
12772    DONE;")
12774 (define_insn_and_split "*sthi_q_comb1"
12775   [(set (zero_extract:DI
12776          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12777                                             "register_operand" "r")
12778                                            (match_operand:SI 1 "ua_offset"
12779                                             "I06"))
12780                                   (const_int 7))
12781                           (const_int -7)))
12782          (plus:SI (and:SI (plus:SI (match_dup 0)
12783                                    (match_operand:SI 2 "ua_offset" "I06"))
12784                           (const_int 7))
12785                   (const_int 1))
12786          (const_int 0))
12787         (match_operand:DI 3 "arith_reg_operand" "r"))]
12788   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12789    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12790   "#"
12791   ""
12792   [(pc)]
12793   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12794                           operands[3]));
12795    DONE;")
12797 ;; This is highpart user because the address is used as full 64 bit.
12798 (define_insn "stlo_l"
12799   [(set (zero_extract:SI
12800          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12801                          (const_int -4)))
12802          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12803          (and:SI (match_dup 0) (const_int 3)))
12804         (match_operand:SI 1 "arith_reg_operand" "r"))]
12805   "TARGET_SHMEDIA32"
12806   "stlo.l       %U0, %1"
12807   [(set_attr "type" "ustore_media")])
12809 (define_insn "stlo_q"
12810   [(set (zero_extract:DI
12811          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12812                          (const_int -8)))
12813          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12814          (and:SI (match_dup 0) (const_int 7)))
12815         (match_operand:DI 1 "arith_reg_operand" "r"))]
12816   "TARGET_SHMEDIA32"
12817   "stlo.q       %U0, %1"
12818   [(set_attr "type" "ustore_media")])
12820 (define_insn_and_split "*stlo_q_comb0"
12821   [(set (zero_extract:DI
12822          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12823                                   (match_operand:SI 1 "ua_offset" "I06"))
12824                          (const_int -8)))
12825          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12826          (and:SI (match_dup 0) (const_int 7)))
12827         (match_operand:DI 2 "arith_reg_operand" "r"))]
12828   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12829   "#"
12830   ""
12831   [(pc)]
12832   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12833                           operands[2]));
12834    DONE;")
12836 (define_insn_and_split "*stlo_q_comb1"
12837   [(set (zero_extract:DI
12838          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12839                                   (match_operand:SI 1 "ua_offset" "I06"))
12840                          (const_int -8)))
12841          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12842                                                   (match_operand:SI 2
12843                                                    "ua_offset" "I06"))
12844                                          (const_int 7)))
12845          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12846         (match_operand:DI 3 "arith_reg_operand" "r"))]
12847   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12848   "#"
12849   ""
12850   [(pc)]
12851   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12852                           operands[3]));
12853    DONE;")
12855 (define_insn "ldhi_l64"
12856   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12857         (zero_extract:SI
12858          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12859                                   (const_int 3))
12860                           (const_int -3)))
12861          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12862          (const_int 0)))]
12863   "TARGET_SHMEDIA64"
12864   "ldhi.l       %U1, %0"
12865   [(set_attr "type" "load_media")])
12867 (define_insn "ldhi_q64"
12868   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12869         (zero_extract:DI
12870          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12871                                   (const_int 7))
12872                           (const_int -7)))
12873          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12874          (const_int 0)))]
12875   "TARGET_SHMEDIA64"
12876   "ldhi.q       %U1, %0"
12877   [(set_attr "type" "load_media")])
12879 (define_insn "ldlo_l64"
12880   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12881         (zero_extract:SI
12882          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12883                          (const_int -4)))
12884          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12885          (and:DI (match_dup 1) (const_int 3))))]
12886   "TARGET_SHMEDIA64"
12887   "ldlo.l       %U1, %0"
12888   [(set_attr "type" "load_media")])
12890 (define_insn "ldlo_q64"
12891   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12892         (zero_extract:DI
12893          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12894                          (const_int -8)))
12895          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12896          (and:DI (match_dup 1) (const_int 7))))]
12897   "TARGET_SHMEDIA64"
12898   "ldlo.q       %U1, %0"
12899   [(set_attr "type" "load_media")])
12901 (define_insn "sthi_l64"
12902   [(set (zero_extract:SI
12903          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12904                                   (const_int 3))
12905                           (const_int -3)))
12906          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12907          (const_int 0))
12908         (match_operand:SI 1 "arith_reg_operand" "r"))]
12909   "TARGET_SHMEDIA64"
12910   "sthi.l       %U0, %1"
12911   [(set_attr "type" "ustore_media")])
12913 (define_insn "sthi_q64"
12914   [(set (zero_extract:DI
12915          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12916                                   (const_int 7))
12917                           (const_int -7)))
12918          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12919          (const_int 0))
12920         (match_operand:DI 1 "arith_reg_operand" "r"))]
12921   "TARGET_SHMEDIA64"
12922   "sthi.q       %U0, %1"
12923   [(set_attr "type" "ustore_media")])
12925 (define_insn "stlo_l64"
12926   [(set (zero_extract:SI
12927          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12928                          (const_int -4)))
12929          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12930          (and:DI (match_dup 0) (const_int 3)))
12931         (match_operand:SI 1 "arith_reg_operand" "r"))]
12932   "TARGET_SHMEDIA64"
12933   "stlo.l       %U0, %1"
12934   [(set_attr "type" "ustore_media")])
12936 (define_insn "stlo_q64"
12937   [(set (zero_extract:DI
12938          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12939                          (const_int -8)))
12940          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12941          (and:DI (match_dup 0) (const_int 7)))
12942         (match_operand:DI 1 "arith_reg_operand" "r"))]
12943   "TARGET_SHMEDIA64"
12944   "stlo.q       %U0, %1"
12945   [(set_attr "type" "ustore_media")])
12947 (define_insn "nsb"
12948   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12949         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12950                    UNSPEC_NSB))]
12951   "TARGET_SHMEDIA"
12952   "nsb  %1, %0"
12953   [(set_attr "type" "arith_media")])
12955 (define_insn "nsbsi"
12956   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12957         (zero_extend:SI
12958          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12959                     UNSPEC_NSB)))]
12960   "TARGET_SHMEDIA"
12961   "nsb  %1, %0"
12962   [(set_attr "type" "arith_media")])
12964 (define_insn "nsbdi"
12965   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12966         (zero_extend:DI
12967          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12968                     UNSPEC_NSB)))]
12969   "TARGET_SHMEDIA"
12970   "nsb  %1, %0"
12971   [(set_attr "type" "arith_media")])
12973 (define_expand "ffsdi2"
12974   [(set (match_operand:DI 0 "arith_reg_dest" "")
12975         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
12976   "TARGET_SHMEDIA"
12977   "
12979   rtx scratch = gen_reg_rtx (DImode);
12980   rtx last;
12982   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
12983   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
12984   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
12985   emit_insn (gen_nsbdi (scratch, scratch));
12986   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
12987   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
12988   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
12989   REG_NOTES (last)
12990     = gen_rtx_EXPR_LIST (REG_EQUAL,
12991                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
12992   DONE;
12995 (define_expand "ffssi2"
12996   [(set (match_operand:SI 0 "arith_reg_dest" "")
12997         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
12998   "TARGET_SHMEDIA"
12999   "
13001   rtx scratch = gen_reg_rtx (SImode);
13002   rtx discratch = gen_reg_rtx (DImode);
13003   rtx last;
13005   emit_insn (gen_adddi3 (discratch,
13006                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13007                          constm1_rtx));
13008   emit_insn (gen_andcdi3 (discratch,
13009                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13010                           discratch));
13011   emit_insn (gen_nsbsi (scratch, discratch));
13012   last = emit_insn (gen_subsi3 (operands[0],
13013                                 force_reg (SImode, GEN_INT (63)), scratch));
13014   REG_NOTES (last)
13015     = gen_rtx_EXPR_LIST (REG_EQUAL,
13016                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13017   DONE;
13020 (define_insn "byterev"
13021   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13022         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13023                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13024                                     (const_int 4) (const_int 3) (const_int 2)
13025                                     (const_int 1) (const_int 0)])))]
13026   "TARGET_SHMEDIA"
13027   "byterev      %1, %0"
13028   [(set_attr "type" "arith_media")])
13030 (define_insn "*prefetch_media"
13031   [(prefetch (match_operand:QI 0 "address_operand" "p")
13032              (match_operand:SI 1 "const_int_operand" "n")
13033              (match_operand:SI 2 "const_int_operand" "n"))]
13034   "TARGET_SHMEDIA"
13035   "*
13037   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13038   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13039   return \"\";
13041   [(set_attr "type" "other")])
13043 (define_insn "*prefetch_i4"
13044   [(prefetch (match_operand:SI 0 "register_operand" "r")
13045              (match_operand:SI 1 "const_int_operand" "n")
13046              (match_operand:SI 2 "const_int_operand" "n"))]
13047   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13048   "*
13050   return \"pref @%0\";
13052   [(set_attr "type" "other")])
13054 (define_expand "prefetch"
13055   [(prefetch (match_operand 0 "address_operand" "p")
13056              (match_operand:SI 1 "const_int_operand" "n")
13057              (match_operand:SI 2 "const_int_operand" "n"))]
13058   "TARGET_HARD_SH4 || TARGET_SH5"
13059   "
13061   if (GET_MODE (operands[0]) != Pmode
13062       || GET_CODE (operands[1]) != CONST_INT
13063       || GET_CODE (operands[2]) != CONST_INT)
13064     FAIL;
13065   if (! TARGET_SHMEDIA)
13066     operands[0] = force_reg (Pmode, operands[0]);
13069 (define_insn "alloco_i"
13070   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13071         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13072   "TARGET_SHMEDIA32"
13073   "*
13075   rtx xops[2];
13077   if (GET_CODE (operands[0]) == PLUS)
13078     {
13079       xops[0] = XEXP (operands[0], 0);
13080       xops[1] = XEXP (operands[0], 1);
13081     }
13082   else
13083     {
13084       xops[0] = operands[0];
13085       xops[1] = const0_rtx;
13086     }
13087   output_asm_insn (\"alloco   %0, %1\", xops);
13088   return \"\";
13090   [(set_attr "type" "other")])
13092 (define_split
13093   [(set (match_operand 0 "any_register_operand" "")
13094         (match_operand 1 "" ""))]
13095   "TARGET_SHMEDIA && reload_completed"
13096   [(set (match_dup 0) (match_dup 1))]
13097   "
13099   int n_changes = 0;
13101   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13102   if (!n_changes)
13103     FAIL;
13106 ; Stack Protector Patterns
13108 (define_expand "stack_protect_set"
13109   [(set (match_operand 0 "memory_operand" "")
13110         (match_operand 1 "memory_operand" ""))]
13111   ""
13113   if (TARGET_SHMEDIA)
13114     {
13115       if (TARGET_SHMEDIA64)
13116         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13117       else
13118         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13119     }
13120   else
13121     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13123   DONE;
13126 (define_insn "stack_protect_set_si"
13127   [(set (match_operand:SI 0 "memory_operand" "=m")
13128         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13129    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13130   "!TARGET_SHMEDIA"
13131   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13132   [(set_attr "type" "other")
13133    (set_attr "length" "6")])
13135 (define_insn "stack_protect_set_si_media"
13136   [(set (match_operand:SI 0 "memory_operand" "=m")
13137         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13138    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13139   "TARGET_SHMEDIA"
13140   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13141   [(set_attr "type" "other")
13142    (set_attr "length" "12")])
13144 (define_insn "stack_protect_set_di_media"
13145   [(set (match_operand:DI 0 "memory_operand" "=m")
13146         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13147    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13148   "TARGET_SHMEDIA64"
13149   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13150   [(set_attr "type" "other")
13151    (set_attr "length" "12")])
13153 (define_expand "stack_protect_test"
13154   [(match_operand 0 "memory_operand" "")
13155    (match_operand 1 "memory_operand" "")
13156    (match_operand 2 "" "")]
13157   ""
13159   if (TARGET_SHMEDIA)
13160     {
13161       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13163       if (TARGET_SHMEDIA64)
13164         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13165                                                     operands[1]));
13166       else
13167         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13168                                                     operands[1]));
13170       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13171     }
13172   else
13173     {
13174       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13175       emit_jump_insn (gen_branch_true (operands[2]));
13176     }
13178   DONE;
13181 (define_insn "stack_protect_test_si"
13182   [(set (reg:SI T_REG)
13183         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13184                     (match_operand:SI 1 "memory_operand" "m")]
13185                    UNSPEC_SP_TEST))
13186   (set (match_scratch:SI 2 "=&r") (const_int 0))
13187   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13188   "!TARGET_SHMEDIA"
13189   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13190   [(set_attr "type" "other")
13191    (set_attr "length" "10")])
13193 (define_insn "stack_protect_test_si_media"
13194   [(set (match_operand:SI 0 "register_operand" "=&r")
13195         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13196                     (match_operand:SI 2 "memory_operand" "m")]
13197                    UNSPEC_SP_TEST))
13198   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13199   "TARGET_SHMEDIA"
13200   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13201   [(set_attr "type" "other")
13202    (set_attr "length" "16")])
13204 (define_insn "stack_protect_test_di_media"
13205   [(set (match_operand:DI 0 "register_operand" "=&r")
13206         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13207                     (match_operand:DI 2 "memory_operand" "m")]
13208                    UNSPEC_SP_TEST))
13209   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13210   "TARGET_SHMEDIA64"
13211   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13212   [(set_attr "type" "other")
13213    (set_attr "length" "16")])