PR target/52479
[official-gcc.git] / gcc / config / sh / sh.md
blobf5bcae219c30e7032cb4c9ef619ea56d8b022393
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, 2007, 2008, 2009, 2010, 2011, 2012
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;;  Improved by Jim Wilson (wilson@cygnus.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
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_TLSGD         20)
139   (UNSPEC_TLSLDM        21)
140   (UNSPEC_TLSIE         22)
141   (UNSPEC_DTPOFF        23)
142   (UNSPEC_GOTTPOFF      24)
143   (UNSPEC_TPOFF         25)
144   (UNSPEC_RA            26)
145   (UNSPEC_DIV_INV_M0    30)
146   (UNSPEC_DIV_INV_M1    31)
147   (UNSPEC_DIV_INV_M2    32)
148   (UNSPEC_DIV_INV_M3    33)
149   (UNSPEC_DIV_INV20     34)
150   (UNSPEC_DIV_INV_TABLE 37)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153   (UNSPEC_CHKADD        38)
154   (UNSPEC_SP_SET        40)
155   (UNSPEC_SP_TEST       41)
156   (UNSPEC_MOVUA         42)
158   ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
159   ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
160   (UNSPEC_EXTRACT_S16   43)
161   (UNSPEC_EXTRACT_U16   44)
163   ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
164   (UNSPEC_SYMOFF        45)
166   ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
167   (UNSPEC_PCREL_SYMOFF  46)
169   ;; These are used with unspec_volatile.
170   (UNSPECV_BLOCKAGE     0)
171   (UNSPECV_ALIGN        1)
172   (UNSPECV_CONST2       2)
173   (UNSPECV_CONST4       4)
174   (UNSPECV_CONST8       6)
175   (UNSPECV_WINDOW_END   10)
176   (UNSPECV_CONST_END    11)
177   (UNSPECV_EH_RETURN    12)
180 ;; -------------------------------------------------------------------------
181 ;; Attributes
182 ;; -------------------------------------------------------------------------
184 ;; Target CPU.
186 (define_attr "cpu"
187  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
188   (const (symbol_ref "sh_cpu_attr")))
190 (define_attr "endian" "big,little"
191  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
192                       (const_string "little") (const_string "big"))))
194 ;; Indicate if the default fpu mode is single precision.
195 (define_attr "fpu_single" "yes,no"
196   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
197                          (const_string "yes") (const_string "no"))))
199 (define_attr "fmovd" "yes,no"
200   (const (if_then_else (symbol_ref "TARGET_FMOVD")
201                        (const_string "yes") (const_string "no"))))
202 ;; pipeline model
203 (define_attr "pipe_model" "sh1,sh4,sh5media"
204   (const
205    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
206           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
207          (const_string "sh1"))))
209 ;; cbranch      conditional branch instructions
210 ;; jump         unconditional jumps
211 ;; arith        ordinary arithmetic
212 ;; arith3       a compound insn that behaves similarly to a sequence of
213 ;;              three insns of type arith
214 ;; arith3b      like above, but might end with a redirected branch
215 ;; load         from memory
216 ;; load_si      Likewise, SImode variant for general register.
217 ;; fload        Likewise, but load to fp register.
218 ;; store        to memory
219 ;; fstore       floating point register to memory
220 ;; move         general purpose register to register
221 ;; movi8        8-bit immediate to general purpose register
222 ;; mt_group     other sh4 mt instructions
223 ;; fmove        register to register, floating point
224 ;; smpy         word precision integer multiply
225 ;; dmpy         longword or doublelongword precision integer multiply
226 ;; return       rts
227 ;; pload        load of pr reg, which can't be put into delay slot of rts
228 ;; prset        copy register to pr reg, ditto
229 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
230 ;; prget        copy pr to register, ditto
231 ;; pcload       pc relative load of constant value
232 ;; pcfload      Likewise, but load to fp register.
233 ;; pcload_si    Likewise, SImode variant for general register.
234 ;; rte          return from exception
235 ;; sfunc        special function call with known used registers
236 ;; call         function call
237 ;; fp           floating point
238 ;; fpscr_toggle toggle a bit in the fpscr
239 ;; fdiv         floating point divide (or square root)
240 ;; gp_fpul      move from general purpose register to fpul
241 ;; fpul_gp      move from fpul to general purpose register
242 ;; mac_gp       move from mac[lh] to general purpose register
243 ;; gp_mac       move from general purpose register to mac[lh]
244 ;; mac_mem      move from mac[lh] to memory
245 ;; mem_mac      move from memory to mac[lh]
246 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
247 ;; ftrc_s       fix_truncsfsi2_i4
248 ;; dfdiv        double precision floating point divide (or square root)
249 ;; cwb          ic_invalidate_line_i
250 ;; movua        SH4a unaligned load
251 ;; fsrra        square root reciprocal approximate
252 ;; fsca         sine and cosine approximate
253 ;; tls_load     load TLS related address
254 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
255 ;; cbranch_media SHmedia conditional branch instructions
256 ;; cmp_media    SHmedia compare instructions
257 ;; dfdiv_media  SHmedia double precision divide and square root
258 ;; dfmul_media  SHmedia double precision multiply instruction
259 ;; dfparith_media SHmedia double precision floating point arithmetic
260 ;; dfpconv_media SHmedia double precision floating point conversions
261 ;; dmpy_media   SHmedia longword multiply
262 ;; fcmp_media   SHmedia floating point compare instructions
263 ;; fdiv_media   SHmedia single precision divide and square root
264 ;; fload_media  SHmedia floating point register load instructions
265 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
266 ;; fparith_media SHmedia single precision floating point arithmetic
267 ;; fpconv_media SHmedia single precision floating point conversions
268 ;; fstore_media SHmedia floating point register store instructions
269 ;; gettr_media  SHmedia gettr instruction
270 ;; invalidate_line_media SHmedia invalidate_line sequence
271 ;; jump_media   SHmedia unconditional branch instructions
272 ;; load_media   SHmedia general register load instructions
273 ;; pt_media     SHmedia pt instruction (expanded by assembler)
274 ;; ptabs_media  SHmedia ptabs instruction
275 ;; store_media  SHmedia general register store instructions
276 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
277 ;; mac_media    SHmedia mac-style fixed point operations
278 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
279 ;; atrans_media SHmedia approximate transcendental functions
280 ;; ustore_media SHmedia unaligned stores
281 ;; nil          no-op move, will be deleted.
283 (define_attr "type"
284  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,fstore,move,movi8,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fpscr_toggle,fdiv,ftrc_s,dfp_arith,dfp_mul,fp_cmp,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,gp_mac,mac_mem,mem_mac,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"
285   (const_string "other"))
287 ;; We define a new attribute namely "insn_class".We use
288 ;; this for the DFA based pipeline description.
290 ;; mt_group      SH4 "mt" group instructions.
292 ;; ex_group      SH4 "ex" group instructions.
294 ;; ls_group      SH4 "ls" group instructions.
297 (define_attr "insn_class"
298   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
299   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
300          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
301          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
302          (eq_attr "type" "cbranch,jump") (const_string "br_group")
303          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
304            (const_string "fe_group")
305          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb,gp_mac,mac_mem,mem_mac") (const_string "co_group")]
306         (const_string "none")))
307 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
308 ;; so these do not belong in an insn group, although they are modeled
309 ;; with their own define_insn_reservations.
311 ;; Indicate what precision must be selected in fpscr for this insn, if any.
313 (define_attr "fp_mode" "single,double,none" (const_string "none"))
315 ;; Indicate if the fpu mode is set by this instruction
316 ;; "unknown" must have the value as "none" in fp_mode, and means
317 ;; that the instruction/abi has left the processor in an unknown
318 ;; state.
319 ;; "none" means that nothing has changed and no mode is set.
320 ;; This attribute is only used for the Renesas ABI.
321 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
323 ; If a conditional branch destination is within -252..258 bytes away
324 ; from the instruction it can be 2 bytes long.  Something in the
325 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
326 ; branches are initially assumed to be 16 bytes long.
327 ; In machine_dependent_reorg, we split all branches that are longer than
328 ; 2 bytes.
330 ;; The maximum range used for SImode constant pool entries is 1018.  A final
331 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
332 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
333 ;; instruction around the pool table, 2 bytes of alignment before the table,
334 ;; and 30 bytes of alignment after the table.  That gives a maximum total
335 ;; pool size of 1058 bytes.
336 ;; Worst case code/pool content size ratio is 1:2 (using asms).
337 ;; Thus, in the worst case, there is one instruction in front of a maximum
338 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
339 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
340 ;; If we have a forward branch, the initial table will be put after the
341 ;; unconditional branch.
343 ;; ??? We could do much better by keeping track of the actual pcloads within
344 ;; the branch range and in the pcload range in front of the branch range.
346 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
347 ;; inside an le.
348 (define_attr "short_cbranch_p" "no,yes"
349   (cond [(match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
350          (const_string "no")
351          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
352          (const_string "yes")
353          (match_test "NEXT_INSN (PREV_INSN (insn)) != insn")
354          (const_string "no")
355          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
356          (const_string "yes")
357          ] (const_string "no")))
359 (define_attr "med_branch_p" "no,yes"
360   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
361               (const_int 1988))
362          (const_string "yes")
363          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
364          (const_string "no")
365          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
366               (const_int 8186))
367          (const_string "yes")
368          ] (const_string "no")))
370 (define_attr "med_cbranch_p" "no,yes"
371   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
372               (const_int 1986))
373          (const_string "yes")
374          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
375          (const_string "no")
376          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
377                (const_int 8184))
378          (const_string "yes")
379          ] (const_string "no")))
381 (define_attr "braf_branch_p" "no,yes"
382   (cond [(match_test "! TARGET_SH2")
383          (const_string "no")
384          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
385               (const_int 20660))
386          (const_string "yes")
387          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
388          (const_string "no")
389          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
390               (const_int 65530))
391          (const_string "yes")
392          ] (const_string "no")))
394 (define_attr "braf_cbranch_p" "no,yes"
395   (cond [(match_test "! TARGET_SH2")
396          (const_string "no")
397          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
398               (const_int 20658))
399          (const_string "yes")
400          (match_test "mdep_reorg_phase <= SH_FIXUP_PCLOAD")
401          (const_string "no")
402          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
403               (const_int 65528))
404          (const_string "yes")
405          ] (const_string "no")))
407 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
408 ; For wider ranges, we need a combination of a code and a data part.
409 ; If we can get a scratch register for a long range jump, the code
410 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
411 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
412 ; long; otherwise, it must be 6 bytes long.
414 ; All other instructions are two bytes long by default.
416 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
417 ;; but getattrtab doesn't understand this.
418 (define_attr "length" ""
419   (cond [(eq_attr "type" "cbranch")
420          (cond [(eq_attr "short_cbranch_p" "yes")
421                 (const_int 2)
422                 (eq_attr "med_cbranch_p" "yes")
423                 (const_int 6)
424                 (eq_attr "braf_cbranch_p" "yes")
425                 (const_int 12)
426 ;; ??? using pc is not computed transitively.
427                 (ne (match_dup 0) (match_dup 0))
428                 (const_int 14)
429                 (match_test "flag_pic")
430                 (const_int 24)
431                 ] (const_int 16))
432          (eq_attr "type" "jump")
433          (cond [(eq_attr "med_branch_p" "yes")
434                 (const_int 2)
435                 (and (match_test "prev_nonnote_insn (insn)")
436                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")                              (symbol_ref "INSN"))
437                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")                             (symbol_ref "code_for_indirect_jump_scratch"))))
438                 (cond [(eq_attr "braf_branch_p" "yes")
439                        (const_int 6)
440                        (not (match_test "flag_pic"))
441                        (const_int 10)
442                        (match_test "TARGET_SH2")
443                        (const_int 10)] (const_int 18))
444                 (eq_attr "braf_branch_p" "yes")
445                 (const_int 10)
446 ;; ??? using pc is not computed transitively.
447                 (ne (match_dup 0) (match_dup 0))
448                 (const_int 12)
449                 (match_test "flag_pic")
450                 (const_int 22)
451                 ] (const_int 14))
452          (eq_attr "type" "pt_media")
453          (if_then_else (match_test "TARGET_SHMEDIA64")
454                        (const_int 20) (const_int 12))
455          (and (eq_attr "type" "jump_media")
456               (match_test "TARGET_SH5_CUT2_WORKAROUND"))
457          (const_int 8)
458          ] (if_then_else (match_test "TARGET_SHMEDIA")
459                          (const_int 4)
460                          (const_int 2))))
462 ;; DFA descriptions for the pipelines
464 (include "sh1.md")
465 (include "shmedia.md")
466 (include "sh4.md")
468 (include "predicates.md")
469 (include "constraints.md")
471 ;; Definitions for filling delay slots
473 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
475 (define_attr "banked" "yes,no" 
476         (cond [(match_test "sh_loads_bankedreg_p (insn)")
477                (const_string "yes")]
478               (const_string "no")))
480 ;; ??? This should be (nil) instead of (const_int 0)
481 (define_attr "hit_stack" "yes,no"
482         (cond [(not (match_test "find_regno_note (insn, REG_INC, SP_REG)"))
483                (const_string "no")]
484               (const_string "yes")))
486 (define_attr "interrupt_function" "no,yes"
487   (const (symbol_ref "current_function_interrupt")))
489 (define_attr "in_delay_slot" "yes,no"
490   (cond [(eq_attr "type" "cbranch") (const_string "no")
491          (eq_attr "type" "pcload,pcload_si") (const_string "no")
492          (eq_attr "needs_delay_slot" "yes") (const_string "no")
493          (eq_attr "length" "2") (const_string "yes")
494          ] (const_string "no")))
496 (define_attr "cond_delay_slot" "yes,no"
497   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
498          ] (const_string "no")))
500 (define_attr "is_sfunc" ""
501   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
503 (define_attr "is_mac_media" ""
504   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
506 (define_attr "branch_zero" "yes,no"
507   (cond [(eq_attr "type" "!cbranch") (const_string "no")
508          (ne (symbol_ref "(next_active_insn (insn)\
509                            == (prev_active_insn\
510                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
511                           && get_attr_length (next_active_insn (insn)) == 2")
512              (const_int 0))
513          (const_string "yes")]
514         (const_string "no")))
516 ;; SH4 Double-precision computation with double-precision result -
517 ;; the two halves are ready at different times.
518 (define_attr "dfp_comp" "yes,no"
519   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
520         (const_string "no")))
522 ;; Insns for which the latency of a preceding fp insn is decreased by one.
523 (define_attr "late_fp_use" "yes,no" (const_string "no"))
524 ;; And feeding insns for which this relevant.
525 (define_attr "any_fp_comp" "yes,no"
526   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
527          (const_string "yes")]
528         (const_string "no")))
530 (define_attr "any_int_load" "yes,no"
531   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
532          (const_string "yes")]
533         (const_string "no")))
535 (define_attr "highpart" "user, ignore, extend, depend, must_split"
536   (const_string "user"))
538 (define_delay
539   (eq_attr "needs_delay_slot" "yes")
540   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
542 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
543 ;; and thus we can't put a pop instruction in its delay slot.
544 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
545 ;; instruction can go in the delay slot.
547 ;; Since a normal return (rts) implicitly uses the PR register,
548 ;; we can't allow PR register loads in an rts delay slot.
550 (define_delay
551   (eq_attr "type" "return")
552   [(and (eq_attr "in_delay_slot" "yes")
553         (ior (and (eq_attr "interrupt_function" "no")
554                   (eq_attr "type" "!pload,prset"))
555              (and (eq_attr "interrupt_function" "yes")
556                   (ior
557                    (not (match_test "TARGET_SH3"))
558                    (eq_attr "hit_stack" "no")
559                    (eq_attr "banked" "no"))))) (nil) (nil)])
561 ;; Since a call implicitly uses the PR register, we can't allow
562 ;; a PR register store in a jsr delay slot.
564 (define_delay
565   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
566   [(and (eq_attr "in_delay_slot" "yes")
567         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
569 ;; Say that we have annulled true branches, since this gives smaller and
570 ;; faster code when branches are predicted as not taken.
572 ;; ??? The non-annulled condition should really be "in_delay_slot",
573 ;; but insns that can be filled in non-annulled get priority over insns
574 ;; that can only be filled in anulled.
576 (define_delay
577   (and (eq_attr "type" "cbranch")
578        (match_test "TARGET_SH2"))
579   ;; SH2e has a hardware bug that pretty much prohibits the use of
580   ;; annuled delay slots.
581   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
582                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
584 ;; -------------------------------------------------------------------------
585 ;; SImode signed integer comparisons
586 ;; -------------------------------------------------------------------------
588 ;; Various patterns to generate the TST #imm, R0 instruction.
589 ;; Although this adds some pressure on the R0 register, it can potentially
590 ;; result in faster code, even if the operand has to be moved to R0 first.
591 ;; This is because on SH4 TST #imm, R0 and MOV Rm, Rn are both MT group 
592 ;; instructions and thus will be executed in parallel.  On SH4A TST #imm, R0
593 ;; is an EX group instruction but still can be executed in parallel with the
594 ;; MT group MOV Rm, Rn instruction.
596 ;; Usual TST #imm, R0 patterns for SI, HI and QI
597 ;; This is usually used for bit patterns other than contiguous bits 
598 ;; and single bits.
600 (define_insn "tstsi_t"
601   [(set (reg:SI T_REG)
602         (eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
603                        (match_operand:SI 1 "logical_operand" "K08,r"))
604                (const_int 0)))]
605   "TARGET_SH1"
606   "tst  %1,%0"
607   [(set_attr "type" "mt_group")])
609 (define_insn "tsthi_t"
610   [(set (reg:SI T_REG)
611         (eq:SI (subreg:SI (and:HI (match_operand:HI 0 "logical_operand" "%z")
612                                   (match_operand 1 "const_int_operand")) 0)
613                (const_int 0)))]
614   "TARGET_SH1
615    && CONST_OK_FOR_K08 (INTVAL (operands[1]))"
616   "tst  %1,%0"
617   [(set_attr "type" "mt_group")])
619 (define_insn "tstqi_t"
620   [(set (reg:SI T_REG)
621         (eq:SI (subreg:SI (and:QI (match_operand:QI 0 "logical_operand" "%z")
622                                   (match_operand 1 "const_int_operand")) 0)
623                (const_int 0)))]
624   "TARGET_SH1
625    && (CONST_OK_FOR_K08 (INTVAL (operands[1])) 
626        || CONST_OK_FOR_I08 (INTVAL (operands[1])))"
628   operands[1] = GEN_INT (INTVAL (operands[1]) & 255);
629   return "tst   %1,%0";
631   [(set_attr "type" "mt_group")])
633 ;; Test low QI subreg against zero.
634 ;; This avoids unecessary zero extension before the test.
636 (define_insn "tstqi_t_zero"
637   [(set (reg:SI T_REG)
638         (eq:SI (match_operand:QI 0 "logical_operand" "z") (const_int 0)))]
639   "TARGET_SH1"
640   "tst  #255,%0"
641   [(set_attr "type" "mt_group")])
643 ;; Extract LSB, negate and store in T bit.
645 (define_insn "tstsi_t_and_not"
646   [(set (reg:SI T_REG)
647          (and:SI (not:SI (match_operand:SI 0 "logical_operand" "z"))
648                  (const_int 1)))]
649   "TARGET_SH1"
650   "tst  #1,%0"
651   [(set_attr "type" "mt_group")])
653 ;; Extract contiguous bits and compare them against zero.
655 (define_insn "tstsi_t_zero_extract_eq"
656   [(set (reg:SI T_REG)
657         (eq:SI (zero_extract:SI (match_operand 0 "logical_operand" "z")
658                 (match_operand:SI 1 "const_int_operand")
659                 (match_operand:SI 2 "const_int_operand"))
660          (const_int 0)))]
661   "TARGET_SH1
662    && CONST_OK_FOR_K08 (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]))"
664   operands[1] = GEN_INT (ZERO_EXTRACT_ANDMASK (operands[1], operands[2]));
665   return "tst   %1,%0";
667   [(set_attr "type" "mt_group")])
669 ;; This split is required when testing bits in a QI subreg.
671 (define_split
672   [(set (reg:SI T_REG)
673    (eq:SI (if_then_else:SI (zero_extract:SI
674                             (match_operand 0 "logical_operand" "")
675                             (match_operand 1 "const_int_operand")
676                             (match_operand 2 "const_int_operand"))
677                            (match_operand 3 "const_int_operand")
678                            (const_int 0))
679           (const_int 0)))]
680   "TARGET_SH1
681    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
682    && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
683   [(set (reg:SI T_REG) (eq:SI (and:SI (match_dup 0) (match_dup 3))
684                               (const_int 0)))]
686   if (GET_MODE (operands[0]) == QImode)
687     operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
690 ;; Extract single bit, negate and store it in the T bit.
691 ;; Not used for SH4A.
693 (define_insn "tstsi_t_zero_extract_xor"
694   [(set (reg:SI T_REG)
695         (zero_extract:SI (xor:SI (match_operand:SI 0 "logical_operand" "z")
696                           (match_operand:SI 3 "const_int_operand"))
697                          (match_operand:SI 1 "const_int_operand")
698                          (match_operand:SI 2 "const_int_operand")))]
699   "TARGET_SH1
700    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2]) == INTVAL (operands[3])
701    && CONST_OK_FOR_K08 (INTVAL (operands[3]))"
702   "tst  %3,%0"
703   [(set_attr "type" "mt_group")])
705 ;; Extract single bit, negate and store it in the T bit.
706 ;; Used for SH4A little endian.
708 (define_insn "tstsi_t_zero_extract_subreg_xor_little"
709   [(set (reg:SI T_REG)
710         (zero_extract:SI
711          (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
712                             (match_operand:SI 3 "const_int_operand")) 0)
713          (match_operand:SI 1 "const_int_operand")
714          (match_operand:SI 2 "const_int_operand")))]
715   "TARGET_SH1 && TARGET_LITTLE_ENDIAN
716    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
717       == (INTVAL (operands[3]) & 255)
718    && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
720   operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
721   return "tst   %3,%0";
723   [(set_attr "type" "mt_group")])
725 ;; Extract single bit, negate and store it in the T bit.
726 ;; Used for SH4A big endian.
728 (define_insn "tstsi_t_zero_extract_subreg_xor_big"
729   [(set (reg:SI T_REG)
730         (zero_extract:SI
731          (subreg:QI (xor:SI (match_operand:SI 0 "logical_operand" "z")
732                             (match_operand:SI 3 "const_int_operand")) 3)
733          (match_operand:SI 1 "const_int_operand")
734          (match_operand:SI 2 "const_int_operand")))]
735   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN
736    && ZERO_EXTRACT_ANDMASK (operands[1], operands[2])
737       == (INTVAL (operands[3]) & 255)
738    && CONST_OK_FOR_K08 (INTVAL (operands[3]) & 255)"
740   operands[3] = GEN_INT (INTVAL (operands[3]) & 255);
741   return "tst   %3,%0";
743   [(set_attr "type" "mt_group")])
745 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
746 ;; That would still allow reload to create cmpi instructions, but would
747 ;; perhaps allow forcing the constant into a register when that is better.
748 ;; Probably should use r0 for mem/imm compares, but force constant into a
749 ;; register for pseudo/imm compares.
751 (define_insn "cmpeqsi_t"
752   [(set (reg:SI T_REG)
753         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
754                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
755   "TARGET_SH1"
756   "@
757         tst     %0,%0
758         cmp/eq  %1,%0
759         cmp/eq  %1,%0"
760    [(set_attr "type" "mt_group")])
762 (define_insn "cmpgtsi_t"
763   [(set (reg:SI T_REG)
764         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
765                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
766   "TARGET_SH1"
767   "@
768         cmp/gt  %1,%0
769         cmp/pl  %0"
770    [(set_attr "type" "mt_group")])
772 (define_insn "cmpgesi_t"
773   [(set (reg:SI T_REG)
774         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
775                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
776   "TARGET_SH1"
777   "@
778         cmp/ge  %1,%0
779         cmp/pz  %0"
780    [(set_attr "type" "mt_group")])
782 ;; -------------------------------------------------------------------------
783 ;; SImode compare and branch
784 ;; -------------------------------------------------------------------------
786 (define_expand "cbranchsi4"
787   [(set (pc)
788         (if_then_else (match_operator 0 "comparison_operator"
789                         [(match_operand:SI 1 "arith_operand" "")
790                          (match_operand:SI 2 "arith_operand" "")])
791                       (label_ref (match_operand 3 "" ""))
792                       (pc)))
793    (clobber (reg:SI T_REG))]
794   ""
796   if (TARGET_SHMEDIA)
797     emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
798                                            operands[2], operands[3]));
799   else if (TARGET_CBRANCHDI4)
800     expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
801   else
802     sh_emit_compare_and_branch (operands, SImode);
803   DONE;
806 ;; -------------------------------------------------------------------------
807 ;; SImode unsigned integer comparisons
808 ;; -------------------------------------------------------------------------
810 (define_insn_and_split "cmpgeusi_t"
811   [(set (reg:SI T_REG)
812         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
813                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
814   "TARGET_SH1"
815   "cmp/hs       %1,%0"
816   "&& operands[1] == CONST0_RTX (SImode)"
817   [(pc)]
819   emit_insn (gen_sett ());
820   DONE;
822    [(set_attr "type" "mt_group")])
824 (define_insn "cmpgtusi_t"
825   [(set (reg:SI T_REG)
826         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
827                 (match_operand:SI 1 "arith_reg_operand" "r")))]
828   "TARGET_SH1"
829   "cmp/hi       %1,%0"
830    [(set_attr "type" "mt_group")])
833 ;; -------------------------------------------------------------------------
834 ;; DImode compare and branch
835 ;; -------------------------------------------------------------------------
838 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
839 ;; Therefore, we aim to have a set of three branches that go straight to the
840 ;; destination, i.e. only one of them is taken at any one time.
841 ;; This mechanism should also be slightly better for the sh4-200.
843 (define_expand "cbranchdi4"
844   [(set (pc)
845         (if_then_else (match_operator 0 "comparison_operator"
846                         [(match_operand:DI 1 "arith_operand" "")
847                          (match_operand:DI 2 "arith_operand" "")])
848                       (label_ref (match_operand 3 "" ""))
849                       (pc)))
850    (clobber (match_dup 4))
851    (clobber (reg:SI T_REG))]
852   "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
854   enum rtx_code comparison;
856   if (TARGET_SHMEDIA)
857     {
858       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
859                                              operands[2], operands[3]));
860       DONE;
861     }
863   else if (!TARGET_CBRANCHDI4)
864     {
865       sh_emit_compare_and_branch (operands, DImode);
866       DONE;
867     }
869   else
870     {
871       if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
872         DONE;
874       comparison = prepare_cbranch_operands (operands, DImode,
875                                              LAST_AND_UNUSED_RTX_CODE);
876       if (comparison != GET_CODE (operands[0]))
877         operands[0]
878           = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
879        operands[4] = gen_rtx_SCRATCH (SImode);
880     }
883 (define_insn_and_split "cbranchdi4_i"
884   [(set (pc)
885         (if_then_else (match_operator 0 "comparison_operator"
886                         [(match_operand:DI 1 "arith_operand" "r,r")
887                          (match_operand:DI 2 "arith_operand" "rN,I08")])
888                       (label_ref (match_operand 3 "" ""))
889                       (pc)))
890    (clobber (match_scratch:SI 4 "=X,&r"))
891    (clobber (reg:SI T_REG))]
892   "TARGET_CBRANCHDI4"
893   "#"
894   "&& reload_completed"
895   [(pc)]
897   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
898     FAIL;
899   DONE;
902 ;; -------------------------------------------------------------------------
903 ;; DImode signed integer comparisons
904 ;; -------------------------------------------------------------------------
906 (define_insn ""
907   [(set (reg:SI T_REG)
908         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
909                        (match_operand:DI 1 "arith_operand" "r"))
910                (const_int 0)))]
911   "TARGET_SH1"
912   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
913                                  insn, operands);"
914   [(set_attr "length" "6")
915    (set_attr "type" "arith3b")])
917 (define_insn "cmpeqdi_t"
918   [(set (reg:SI T_REG)
919         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
920                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
921   "TARGET_SH1"
922   "@
923         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
924         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
925   [(set_attr "length" "6")
926    (set_attr "type" "arith3b")])
928 (define_split
929   [(set (reg:SI T_REG)
930         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
931                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
932 ;; If we applied this split when not optimizing, it would only be
933 ;; applied during the machine-dependent reorg, when no new basic blocks
934 ;; may be created.
935   "TARGET_SH1 && reload_completed && optimize"
936   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
937    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
938                            (label_ref (match_dup 6))
939                            (pc)))
940    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
941    (match_dup 6)]
943   operands[2]
944     = gen_rtx_REG (SImode,
945                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
946   operands[3]
947     = (operands[1] == const0_rtx
948        ? const0_rtx
949        : gen_rtx_REG (SImode,
950                       true_regnum (operands[1])
951                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
952   operands[4] = gen_lowpart (SImode, operands[0]);
953   operands[5] = gen_lowpart (SImode, operands[1]);
954   operands[6] = gen_label_rtx ();
957 (define_insn "cmpgtdi_t"
958   [(set (reg:SI T_REG)
959         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
960                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
961   "TARGET_SH2"
962   "@
963         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
964         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
965   [(set_attr "length" "8")
966    (set_attr "type" "arith3")])
968 (define_insn "cmpgedi_t"
969   [(set (reg:SI T_REG)
970         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
971                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
972   "TARGET_SH2"
973   "@
974         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
975         cmp/pz\\t%S0"
976   [(set_attr "length" "8,2")
977    (set_attr "type" "arith3,mt_group")])
979 ;; -------------------------------------------------------------------------
980 ;; DImode unsigned integer comparisons
981 ;; -------------------------------------------------------------------------
983 (define_insn "cmpgeudi_t"
984   [(set (reg:SI T_REG)
985         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
986                 (match_operand:DI 1 "arith_reg_operand" "r")))]
987   "TARGET_SH2"
988   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
989   [(set_attr "length" "8")
990    (set_attr "type" "arith3")])
992 (define_insn "cmpgtudi_t"
993   [(set (reg:SI T_REG)
994         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
995                 (match_operand:DI 1 "arith_reg_operand" "r")))]
996   "TARGET_SH2"
997   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
998   [(set_attr "length" "8")
999    (set_attr "type" "arith3")])
1001 (define_insn "cmpeqsi_media"
1002   [(set (match_operand:SI 0 "register_operand" "=r")
1003         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
1004                (match_operand:SI 2 "cmp_operand" "Nr")))]
1005   "TARGET_SHMEDIA"
1006   "cmpeq        %1, %N2, %0"
1007   [(set_attr "type" "cmp_media")])
1009 (define_insn "cmpeqdi_media"
1010   [(set (match_operand:SI 0 "register_operand" "=r")
1011         (eq:SI (match_operand:DI 1 "register_operand" "%r")
1012                (match_operand:DI 2 "cmp_operand" "Nr")))]
1013   "TARGET_SHMEDIA"
1014   "cmpeq        %1, %N2, %0"
1015   [(set_attr "type" "cmp_media")])
1017 (define_insn "cmpgtsi_media"
1018   [(set (match_operand:SI 0 "register_operand" "=r")
1019         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
1020                (match_operand:SI 2 "cmp_operand" "rN")))]
1021   "TARGET_SHMEDIA"
1022   "cmpgt        %N1, %N2, %0"
1023   [(set_attr "type" "cmp_media")])
1025 (define_insn "cmpgtdi_media"
1026   [(set (match_operand:SI 0 "register_operand" "=r")
1027         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1028                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1029   "TARGET_SHMEDIA"
1030   "cmpgt        %N1, %N2, %0"
1031   [(set_attr "type" "cmp_media")])
1033 (define_insn "cmpgtusi_media"
1034   [(set (match_operand:SI 0 "register_operand" "=r")
1035         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
1036                 (match_operand:SI 2 "cmp_operand" "rN")))]
1037   "TARGET_SHMEDIA"
1038   "cmpgtu       %N1, %N2, %0"
1039   [(set_attr "type" "cmp_media")])
1041 (define_insn "cmpgtudi_media"
1042   [(set (match_operand:SI 0 "register_operand" "=r")
1043         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
1044                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
1045   "TARGET_SHMEDIA"
1046   "cmpgtu       %N1, %N2, %0"
1047   [(set_attr "type" "cmp_media")])
1049 ; These two patterns are for combine.
1050 (define_insn "*cmpne0sisi_media"
1051   [(set (match_operand:SI 0 "register_operand" "=r")
1052         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
1053   "TARGET_SHMEDIA"
1054   "cmpgtu       %1,r63,%0"
1055   [(set_attr "type" "cmp_media")])
1057 ;; -------------------------------------------------------------------------
1058 ;; Conditional move instructions
1059 ;; -------------------------------------------------------------------------
1061 ;; The insn names may seem reversed, but note that cmveq performs the move
1062 ;; if op1 == 0, and cmvne does it if op1 != 0.
1064 (define_insn "movdicc_false"
1065   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1066         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
1067                              (const_int 0))
1068          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1069          (match_operand:DI 3 "arith_reg_operand" "0")))]
1070   "TARGET_SHMEDIA"
1071   "cmveq        %1, %N2, %0"
1072   [(set_attr "type" "arith_media")])
1074 (define_insn "movdicc_true"
1075   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1076         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
1077                              (const_int 0))
1078          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
1079          (match_operand:DI 3 "arith_reg_operand" "0")))]
1080   "TARGET_SHMEDIA"
1081   "cmvne        %1, %N2, %0"
1082   [(set_attr "type" "arith_media")])
1084 (define_peephole2
1085   [(set (match_operand:DI 0 "arith_reg_dest" "")
1086         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
1087                            [(match_operand:DI 1 "arith_reg_operand" "")
1088                             (const_int 0)])
1089          (match_operand:DI 2 "arith_reg_dest" "")
1090          (match_dup 0)))
1091    (set (match_dup 2) (match_dup 0))]
1092   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1093   [(set (match_dup 2)
1094         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
1096   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1097                                 VOIDmode, operands[1], CONST0_RTX (DImode));
1100 (define_peephole2
1101   [(set (match_operand:DI 0 "general_movdst_operand" "")
1102         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
1103    (set (match_operand:DI 2 "arith_reg_dest" "")
1104         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
1105                            [(match_operand:DI 3 "arith_reg_operand" "")
1106                             (const_int 0)])
1107          (match_dup 0)
1108          (match_dup 2)))]
1109   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1110   [(set (match_dup 2)
1111         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
1112   "")
1114 (define_expand "movdicc"
1115   [(set (match_operand:DI 0 "register_operand" "")
1116         (if_then_else:DI (match_operand 1 "comparison_operator" "")
1117                          (match_operand:DI 2 "register_operand" "")
1118                          (match_operand:DI 3 "register_operand" "")))]
1119   "TARGET_SHMEDIA"
1121   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1122       && GET_MODE (XEXP (operands[1], 0)) == DImode
1123       && XEXP (operands[1], 1) == const0_rtx)
1124     ;
1125   else
1126     {
1127       if (!can_create_pseudo_p ())
1128         FAIL;
1130       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1131                                               GET_CODE (operands[1]),
1132                                               XEXP (operands[1], 0),
1133                                               XEXP (operands[1], 1));
1134       if (!operands[1])
1135         FAIL;
1136     }
1139 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1140 ;; SImode to DImode.
1141 (define_insn "movsicc_false"
1142   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1143         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1144                           (const_int 0))
1145          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1146          (match_operand:SI 3 "arith_reg_operand" "0")))]
1147   "TARGET_SHMEDIA"
1148   "cmveq        %1, %N2, %0"
1149   [(set_attr "type" "arith_media")])
1151 (define_insn "movsicc_true"
1152   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1153         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1154                           (const_int 0))
1155          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1156          (match_operand:SI 3 "arith_reg_operand" "0")))]
1157   "TARGET_SHMEDIA"
1158   "cmvne        %1, %N2, %0"
1159   [(set_attr "type" "arith_media")])
1161 (define_peephole2
1162   [(set (match_operand:SI 0 "arith_reg_dest" "")
1163         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1164                            [(match_operand:SI 1 "arith_reg_operand" "")
1165                             (const_int 0)])
1166          (match_operand:SI 2 "arith_reg_dest" "")
1167          (match_dup 0)))
1168    (set (match_dup 2) (match_dup 0))]
1169   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1170   [(set (match_dup 2)
1171         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1173   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1174                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1177 (define_peephole2
1178   [(set (match_operand:SI 0 "general_movdst_operand" "")
1179         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1180    (set (match_operand:SI 2 "arith_reg_dest" "")
1181         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1182                            [(match_operand:SI 3 "arith_reg_operand" "")
1183                             (const_int 0)])
1184          (match_dup 0)
1185          (match_dup 2)))]
1186   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1187    && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1188   [(set (match_dup 2)
1189         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1191   replace_rtx (operands[4], operands[0], operands[1]);
1194 (define_peephole2
1195   [(set (match_operand 0 "any_register_operand" "")
1196         (match_operand 1 "any_register_operand" ""))
1197    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1198    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1199   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1200     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1201    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1202    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1203    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1204    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1205    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1206    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1207    && (REGNO_REG_CLASS (REGNO (operands[0]))
1208        == REGNO_REG_CLASS (REGNO (operands[2])))
1209    && (REGNO_REG_CLASS (REGNO (operands[1]))
1210        == REGNO_REG_CLASS (REGNO (operands[0])))"
1211   [(set (match_dup 0) (match_dup 3))
1212    (set (match_dup 4) (match_dup 5))]
1214   rtx set1, set2, insn2;
1215   rtx replacements[4];
1217   /* We want to replace occurrences of operands[0] with operands[1] and
1218      operands[2] with operands[0] in operands[4]/operands[5].
1219      Doing just two replace_rtx calls naively would result in the second
1220      replacement undoing all that the first did if operands[1] and operands[2]
1221      are identical, so we must do this simultaneously.  */
1222   replacements[0] = operands[0];
1223   replacements[1] = operands[1];
1224   replacements[2] = operands[2];
1225   replacements[3] = operands[0];
1226   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1227       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1228       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1229     FAIL;
1231   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1232   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1233   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1234   /* The operands array is aliased to recog_data.operand, which gets
1235      clobbered by extract_insn, so finish with it now.  */
1236   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1237   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1238   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1239      always uses emit_insn.  */
1240   /* Check that we don't violate matching constraints or earlyclobbers.  */
1241   extract_insn (emit_insn (set1));
1242   if (! constrain_operands (1))
1243     goto failure;
1244   insn2 = emit (set2);
1245   if (GET_CODE (insn2) == BARRIER)
1246     goto failure;
1247   extract_insn (insn2);
1248   if (! constrain_operands (1))
1249     {
1250       rtx tmp;
1251     failure:
1252       tmp = replacements[0];
1253       replacements[0] = replacements[1];
1254       replacements[1] = tmp;
1255       tmp = replacements[2];
1256       replacements[2] = replacements[3];
1257       replacements[3] = tmp;
1258       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1259       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1260       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1261       FAIL;
1262     }
1263   DONE;
1266 ;; The register allocator is rather clumsy in handling multi-way conditional
1267 ;; moves, so allow the combiner to make them, and we split them up after
1268 ;; reload.  */
1269 (define_insn_and_split "*movsicc_umin"
1270   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1271         (umin:SI (if_then_else:SI
1272                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1273                        (const_int 0))
1274                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1275                    (match_operand:SI 3 "register_operand" "0"))
1276                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1277    (clobber (match_scratch:SI 5 "=&r"))]
1278   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1279   "#"
1280   "TARGET_SHMEDIA && reload_completed"
1281   [(pc)]
1283   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1284                                 operands[3]));
1285   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1286   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1287                                 operands[0]));
1288   DONE;
1291 (define_insn "*movsicc_t_false"
1292   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1293         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1294                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1295                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1296   "TARGET_PRETEND_CMOVE
1297    && (arith_reg_operand (operands[1], SImode)
1298        || (immediate_operand (operands[1], SImode)
1299            && satisfies_constraint_I08 (operands[1])))"
1300   "bt   0f\;mov %1,%0\\n0:"
1301   [(set_attr "type" "mt_group,arith") ;; poor approximation
1302    (set_attr "length" "4")])
1304 (define_insn "*movsicc_t_true"
1305   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1306         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1307                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1308                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1309   "TARGET_PRETEND_CMOVE
1310    && (arith_reg_operand (operands[1], SImode)
1311        || (immediate_operand (operands[1], SImode)
1312            && satisfies_constraint_I08 (operands[1])))"
1313   "bf   0f\;mov %1,%0\\n0:"
1314   [(set_attr "type" "mt_group,arith") ;; poor approximation
1315    (set_attr "length" "4")])
1317 (define_expand "movsicc"
1318   [(set (match_operand:SI 0 "arith_reg_dest" "")
1319         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1320                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1321                          (match_operand:SI 3 "arith_reg_operand" "")))]
1322   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1324   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1325       && GET_MODE (XEXP (operands[1], 0)) == SImode
1326       && (TARGET_SHMEDIA
1327           || (REG_P (XEXP (operands[1], 0))
1328               && REGNO (XEXP (operands[1], 0)) == T_REG))
1329       && XEXP (operands[1], 1) == const0_rtx)
1330     ;
1332   else if (TARGET_PRETEND_CMOVE)
1333     {
1334       enum rtx_code code = GET_CODE (operands[1]);
1335       enum rtx_code new_code = code;
1336       rtx op0 = XEXP (operands[1], 0);
1337       rtx op1 = XEXP (operands[1], 1);
1339       if (! currently_expanding_to_rtl)
1340         FAIL;
1341       switch (code)
1342         {
1343         case LT: case LE: case LEU: case LTU:
1344           if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1345             break;
1346         case NE:
1347           new_code = reverse_condition (code);
1348           break;
1349         case EQ: case GT: case GE: case GEU: case GTU:
1350           break;
1351         default:
1352           FAIL;
1353         }
1354       sh_emit_scc_to_t (new_code, op0, op1);
1355       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1356                                     gen_rtx_REG (SImode, T_REG), const0_rtx);
1357     }
1358   else
1359     {
1360       if (!can_create_pseudo_p ())
1361         FAIL;
1363       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1364                                               GET_CODE (operands[1]),
1365                                               XEXP (operands[1], 0),
1366                                               XEXP (operands[1], 1));
1367       if (!operands[1])
1368         FAIL;
1369     }
1372 (define_expand "movqicc"
1373   [(set (match_operand:QI 0 "register_operand" "")
1374         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1375                          (match_operand:QI 2 "register_operand" "")
1376                          (match_operand:QI 3 "register_operand" "")))]
1377   "TARGET_SHMEDIA"
1379   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1380   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1381   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1382   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1383   DONE;
1386 ;; -------------------------------------------------------------------------
1387 ;; Addition instructions
1388 ;; -------------------------------------------------------------------------
1390 (define_expand "adddi3"
1391   [(set (match_operand:DI 0 "arith_reg_operand" "")
1392         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1393                  (match_operand:DI 2 "arith_operand" "")))]
1394   ""
1396   if (TARGET_SH1)
1397     {
1398       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1399         FAIL;
1400       operands[2] = force_reg (DImode, operands[2]);
1401       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1402       DONE;
1403     }
1406 (define_insn "*adddi3_media"
1407   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1408         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1409                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1410   "TARGET_SHMEDIA"
1411   "@
1412         add     %1, %2, %0
1413         addi    %1, %2, %0"
1414   [(set_attr "type" "arith_media")])
1416 (define_insn "*adddisi3_media"
1417   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1418         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1419                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1420   "TARGET_SHMEDIA"
1421   "@
1422         add.l   %1, %2, %0
1423         addi.l  %1, %2, %0"
1424   [(set_attr "type" "arith_media")
1425    (set_attr "highpart" "ignore")])
1427 (define_insn "adddi3z_media"
1428   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1429         (zero_extend:DI
1430          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1431                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1432   "TARGET_SHMEDIA"
1433   "addz.l       %1, %N2, %0"
1434   [(set_attr "type" "arith_media")
1435    (set_attr "highpart" "ignore")])
1437 (define_insn "adddi3_compact"
1438   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1439         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1440                  (match_operand:DI 2 "arith_reg_operand" "r")))
1441    (clobber (reg:SI T_REG))]
1442   "TARGET_SH1"
1443   "#"
1444   [(set_attr "length" "6")])
1446 (define_split
1447   [(set (match_operand:DI 0 "arith_reg_dest" "")
1448         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1449                  (match_operand:DI 2 "arith_reg_operand" "")))
1450    (clobber (reg:SI T_REG))]
1451   "TARGET_SH1 && reload_completed"
1452   [(const_int 0)]
1454   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1455   high0 = gen_rtx_REG (SImode,
1456                        true_regnum (operands[0])
1457                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1458   high2 = gen_rtx_REG (SImode,
1459                        true_regnum (operands[2])
1460                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1461   emit_insn (gen_clrt ());
1462   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1463   emit_insn (gen_addc1 (high0, high0, high2));
1464   DONE;
1467 (define_insn "addc"
1468   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1469         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1470                           (match_operand:SI 2 "arith_reg_operand" "r"))
1471                  (reg:SI T_REG)))
1472    (set (reg:SI T_REG)
1473         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1474   "TARGET_SH1"
1475   "addc %2,%0"
1476   [(set_attr "type" "arith")])
1478 (define_insn "addc1"
1479   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1480         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1481                           (match_operand:SI 2 "arith_reg_operand" "r"))
1482                  (reg:SI T_REG)))
1483    (clobber (reg:SI T_REG))]
1484   "TARGET_SH1"
1485   "addc %2,%0"
1486   [(set_attr "type" "arith")])
1488 (define_expand "addsi3"
1489   [(set (match_operand:SI 0 "arith_reg_operand" "")
1490         (plus:SI (match_operand:SI 1 "arith_operand" "")
1491                  (match_operand:SI 2 "arith_operand" "")))]
1492   ""
1494   if (TARGET_SHMEDIA)
1495     operands[1] = force_reg (SImode, operands[1]);
1498 (define_insn "addsi3_media"
1499   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1500         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1501                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1502   "TARGET_SHMEDIA"
1503   "@
1504         add.l   %1, %2, %0
1505         addi.l  %1, %2, %0"
1506   [(set_attr "type" "arith_media")
1507    (set_attr "highpart" "ignore")])
1509 (define_insn "addsidi3_media"
1510   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1511         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1512                                   "%r,r")
1513                                  (match_operand:SI 2 "arith_operand"
1514                                   "r,I10"))))]
1515   "TARGET_SHMEDIA"
1516   "@
1517         add.l   %1, %2, %0
1518         addi.l  %1, %2, %0"
1519   [(set_attr "type" "arith_media")
1520    (set_attr "highpart" "ignore")])
1522 (define_insn "*addsi3_compact"
1523   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1524         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1525                  (match_operand:SI 2 "arith_operand" "rI08")))]
1526   "TARGET_SH1"
1527   "add  %2,%0"
1528   [(set_attr "type" "arith")])
1530 ;; -------------------------------------------------------------------------
1531 ;; Subtraction instructions
1532 ;; -------------------------------------------------------------------------
1534 (define_expand "subdi3"
1535   [(set (match_operand:DI 0 "arith_reg_operand" "")
1536         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1537                   (match_operand:DI 2 "arith_reg_operand" "")))]
1538   ""
1540   if (TARGET_SH1)
1541     {
1542       operands[1] = force_reg (DImode, operands[1]);
1543       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1544       DONE;
1545     }
1548 (define_insn "*subdi3_media"
1549   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1550         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1551                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1552   "TARGET_SHMEDIA"
1553   "sub  %N1, %2, %0"
1554   [(set_attr "type" "arith_media")])
1555   
1556 (define_insn "subdisi3_media"
1557   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1558         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1559                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1560   "TARGET_SHMEDIA"
1561   "sub.l        %N1, %2, %0"
1562   [(set_attr "type" "arith_media")
1563    (set_attr "highpart" "ignore")])
1565 (define_insn "subdi3_compact"
1566   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1567         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1568                  (match_operand:DI 2 "arith_reg_operand" "r")))
1569    (clobber (reg:SI T_REG))]
1570   "TARGET_SH1"
1571   "#"
1572   [(set_attr "length" "6")])
1574 (define_split
1575   [(set (match_operand:DI 0 "arith_reg_dest" "")
1576         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1577                   (match_operand:DI 2 "arith_reg_operand" "")))
1578    (clobber (reg:SI T_REG))]
1579   "TARGET_SH1 && reload_completed"
1580   [(const_int 0)]
1582   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1583   high0 = gen_rtx_REG (SImode,
1584                        true_regnum (operands[0])
1585                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1586   high2 = gen_rtx_REG (SImode,
1587                        true_regnum (operands[2])
1588                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1589   emit_insn (gen_clrt ());
1590   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1591   emit_insn (gen_subc1 (high0, high0, high2));
1592   DONE;
1595 (define_insn "subc"
1596   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1597         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1598                             (match_operand:SI 2 "arith_reg_operand" "r"))
1599                   (reg:SI T_REG)))
1600    (set (reg:SI T_REG)
1601         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1602                           (reg:SI T_REG))
1603                 (match_dup 1)))]
1604   "TARGET_SH1"
1605   "subc %2,%0"
1606   [(set_attr "type" "arith")])
1608 (define_insn "subc1"
1609   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1610         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1611                             (match_operand:SI 2 "arith_reg_operand" "r"))
1612                   (reg:SI T_REG)))
1613    (clobber (reg:SI T_REG))]
1614   "TARGET_SH1"
1615   "subc %2,%0"
1616   [(set_attr "type" "arith")])
1618 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1619 ;; pattern for this case.  This helps multimedia applications that compute
1620 ;; the sum of absolute differences.
1621 (define_insn "mov_neg_si_t"
1622   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1623   "TARGET_SH1"
1624   "subc %0,%0"
1625   [(set_attr "type" "arith")])
1627 (define_insn "*subsi3_internal"
1628   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1629         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1630                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1631   "TARGET_SH1"
1632   "sub  %2,%0"
1633   [(set_attr "type" "arith")])
1635 (define_insn_and_split "*subsi3_media"
1636   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1637         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1638                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1639   "TARGET_SHMEDIA
1640    && (operands[1] != constm1_rtx
1641        || (GET_CODE (operands[2]) != TRUNCATE
1642            && GET_CODE (operands[2]) != SUBREG))"
1643   "sub.l        %N1, %2, %0"
1644   "operands[1] == constm1_rtx"
1645   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1646   ""
1647   [(set_attr "type" "arith_media")
1648    (set_attr "highpart" "ignore")])
1650 (define_split
1651   [(set (match_operand:SI 0 "arith_reg_dest" "")
1652         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1653                                                        "general_extend_operand"
1654                                                        "") 0)) 0)))]
1655   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1656   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1657    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1658   "")
1660 (define_split
1661   [(set (match_operand:SI 0 "arith_reg_dest" "")
1662         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1663                                                        "general_extend_operand"
1664                                                        "") 0)) 3)))]
1665   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1666   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1667    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1668   "")
1669 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1670 ;; will sometimes save one instruction.  Otherwise we might get
1671 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1672 ;; are the same.
1674 (define_expand "subsi3"
1675   [(set (match_operand:SI 0 "arith_reg_operand" "")
1676         (minus:SI (match_operand:SI 1 "arith_operand" "")
1677                   (match_operand:SI 2 "arith_reg_operand" "")))]
1678   ""
1680   if (TARGET_SH1 && CONST_INT_P (operands[1]))
1681     {
1682       emit_insn (gen_negsi2 (operands[0], operands[2]));
1683       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1684       DONE;
1685     }
1686   if (TARGET_SHMEDIA)
1687     {
1688       if (!can_create_pseudo_p ()
1689           && ! arith_reg_or_0_operand (operands[1], SImode))
1690         FAIL;
1691       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1692         operands[1] = force_reg (SImode, operands[1]);
1693     }
1696 ;; -------------------------------------------------------------------------
1697 ;; Division instructions
1698 ;; -------------------------------------------------------------------------
1700 ;; We take advantage of the library routines which don't clobber as many
1701 ;; registers as a normal function call would.
1703 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1704 ;; also has an effect on the register that holds the address of the sfunc.
1705 ;; To make this work, we have an extra dummy insn that shows the use
1706 ;; of this register for reorg.
1708 (define_insn "use_sfunc_addr"
1709   [(set (reg:SI PR_REG)
1710         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1711   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1712   ""
1713   [(set_attr "length" "0")])
1715 (define_insn "udivsi3_sh2a"
1716   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1717         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1718                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1719   "TARGET_SH2A"
1720   "divu %2,%1"
1721   [(set_attr "type" "arith")
1722    (set_attr "in_delay_slot" "no")])
1724 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1725 ;; hard register 0.  If we used hard register 0, then the next instruction
1726 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1727 ;; gets allocated to a stack slot that needs its address reloaded, then
1728 ;; there is nothing to prevent reload from using r0 to reload the address.
1729 ;; This reload would clobber the value in r0 we are trying to store.
1730 ;; If we let reload allocate r0, then this problem can never happen.
1732 (define_insn "udivsi3_i1"
1733   [(set (match_operand:SI 0 "register_operand" "=z")
1734         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1735    (clobber (reg:SI T_REG))
1736    (clobber (reg:SI PR_REG))
1737    (clobber (reg:SI R4_REG))
1738    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1739   "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1740   "jsr  @%1%#"
1741   [(set_attr "type" "sfunc")
1742    (set_attr "needs_delay_slot" "yes")])
1744 ; Since shmedia-nofpu code could be linked against shcompact code, and
1745 ; the udivsi3 libcall has the same name, we must consider all registers
1746 ; clobbered that are in the union of the registers clobbered by the
1747 ; shmedia and the shcompact implementation.  Note, if the shcompact
1748 ; implementation actually used shcompact code, we'd need to clobber
1749 ; also r23 and fr23.
1750 (define_insn "udivsi3_i1_media"
1751   [(set (match_operand:SI 0 "register_operand" "=z")
1752         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1753    (clobber (reg:SI T_MEDIA_REG))
1754    (clobber (reg:SI PR_MEDIA_REG))
1755    (clobber (reg:SI R20_REG))
1756    (clobber (reg:SI R21_REG))
1757    (clobber (reg:SI R22_REG))
1758    (clobber (reg:DI TR0_REG))
1759    (clobber (reg:DI TR1_REG))
1760    (clobber (reg:DI TR2_REG))
1761    (use (match_operand 1 "target_reg_operand" "b"))]
1762   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1763   "blink        %1, r18"
1764   [(set_attr "type" "sfunc")
1765    (set_attr "needs_delay_slot" "yes")])
1767 (define_expand "udivsi3_i4_media"
1768   [(set (match_dup 3)
1769         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1770    (set (match_dup 4)
1771         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1772    (set (match_dup 5) (float:DF (match_dup 3)))
1773    (set (match_dup 6) (float:DF (match_dup 4)))
1774    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1775    (set (match_dup 8) (fix:DI (match_dup 7)))
1776    (set (match_operand:SI 0 "register_operand" "")
1777         (truncate:SI (match_dup 8)))]
1778   "TARGET_SHMEDIA_FPU"
1780   operands[3] = gen_reg_rtx (DImode);
1781   operands[4] = gen_reg_rtx (DImode);
1782   operands[5] = gen_reg_rtx (DFmode);
1783   operands[6] = gen_reg_rtx (DFmode);
1784   operands[7] = gen_reg_rtx (DFmode);
1785   operands[8] = gen_reg_rtx (DImode);
1788 (define_insn "udivsi3_i4"
1789   [(set (match_operand:SI 0 "register_operand" "=y")
1790         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1791    (clobber (reg:SI T_REG))
1792    (clobber (reg:SI PR_REG))
1793    (clobber (reg:DF DR0_REG))
1794    (clobber (reg:DF DR2_REG))
1795    (clobber (reg:DF DR4_REG))
1796    (clobber (reg:SI R0_REG))
1797    (clobber (reg:SI R1_REG))
1798    (clobber (reg:SI R4_REG))
1799    (clobber (reg:SI R5_REG))
1800    (use (reg:PSI FPSCR_REG))
1801    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1802   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1803   "jsr  @%1%#"
1804   [(set_attr "type" "sfunc")
1805    (set_attr "fp_mode" "double")
1806    (set_attr "needs_delay_slot" "yes")])
1808 (define_insn "udivsi3_i4_single"
1809   [(set (match_operand:SI 0 "register_operand" "=y")
1810         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1811    (clobber (reg:SI T_REG))
1812    (clobber (reg:SI PR_REG))
1813    (clobber (reg:DF DR0_REG))
1814    (clobber (reg:DF DR2_REG))
1815    (clobber (reg:DF DR4_REG))
1816    (clobber (reg:SI R0_REG))
1817    (clobber (reg:SI R1_REG))
1818    (clobber (reg:SI R4_REG))
1819    (clobber (reg:SI R5_REG))
1820    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1821   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1822   "jsr  @%1%#"
1823   [(set_attr "type" "sfunc")
1824    (set_attr "needs_delay_slot" "yes")])
1826 (define_insn "udivsi3_i4_int"
1827   [(set (match_operand:SI 0 "register_operand" "=z")
1828         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1829    (clobber (reg:SI T_REG))
1830    (clobber (reg:SI R1_REG))
1831    (clobber (reg:SI PR_REG))
1832    (clobber (reg:SI MACH_REG))
1833    (clobber (reg:SI MACL_REG))
1834    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1835   "TARGET_SH1"
1836   "jsr  @%1%#"
1837   [(set_attr "type" "sfunc")
1838    (set_attr "needs_delay_slot" "yes")])
1841 (define_expand "udivsi3"
1842   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1843    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1844    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1845    (parallel [(set (match_operand:SI 0 "register_operand" "")
1846                    (udiv:SI (reg:SI R4_REG)
1847                             (reg:SI R5_REG)))
1848               (clobber (reg:SI T_REG))
1849               (clobber (reg:SI PR_REG))
1850               (clobber (reg:SI R4_REG))
1851               (use (match_dup 3))])]
1852   ""
1854   rtx last;
1856   operands[3] = gen_reg_rtx (Pmode);
1857   /* Emit the move of the address to a pseudo outside of the libcall.  */
1858   if (TARGET_DIVIDE_CALL_TABLE)
1859     {
1860       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1861          that causes problems when the divide code is supposed to come from a
1862          separate library.  Division by zero is undefined, so dividing 1 can be
1863          implemented by comparing with the divisor.  */
1864       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1865         {
1866           rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1867           emit_insn (gen_cstoresi4 (operands[0], test,
1868                                     operands[1], operands[2]));
1869           DONE;
1870         }
1871       else if (operands[2] == const0_rtx)
1872         {
1873           emit_move_insn (operands[0], operands[2]);
1874           DONE;
1875         }
1876       function_symbol (operands[3], "__udivsi3_i4i", SFUNC_GOT);
1877       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1878     }
1879   else if (TARGET_DIVIDE_CALL_FP)
1880     {
1881       function_symbol (operands[3], "__udivsi3_i4", SFUNC_STATIC);
1882       if (TARGET_FPU_SINGLE)
1883         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1884       else
1885         last = gen_udivsi3_i4 (operands[0], operands[3]);
1886     }
1887   else if (TARGET_SHMEDIA_FPU)
1888     {
1889       operands[1] = force_reg (SImode, operands[1]);
1890       operands[2] = force_reg (SImode, operands[2]);
1891       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1892       DONE;
1893     }
1894   else if (TARGET_SH2A)
1895     {
1896       operands[1] = force_reg (SImode, operands[1]);
1897       operands[2] = force_reg (SImode, operands[2]);
1898       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1899       DONE;
1900     }
1901   else if (TARGET_SH5)
1902     {
1903       function_symbol (operands[3],
1904                        TARGET_FPU_ANY ? "__udivsi3_i4" : "__udivsi3",
1905                        SFUNC_STATIC);
1907       if (TARGET_SHMEDIA)
1908         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1909       else if (TARGET_FPU_ANY)
1910         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1911       else
1912         last = gen_udivsi3_i1 (operands[0], operands[3]);
1913     }
1914   else
1915     {
1916       function_symbol (operands[3], "__udivsi3", SFUNC_STATIC);
1917       last = gen_udivsi3_i1 (operands[0], operands[3]);
1918     }
1919   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1920   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1921   emit_insn (last);
1922   DONE;
1925 (define_insn "divsi3_sh2a"
1926   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1927         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1928                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1929   "TARGET_SH2A"
1930   "divs %2,%1"
1931   [(set_attr "type" "arith")
1932    (set_attr "in_delay_slot" "no")])
1934 (define_insn "divsi3_i1"
1935   [(set (match_operand:SI 0 "register_operand" "=z")
1936         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1937    (clobber (reg:SI T_REG))
1938    (clobber (reg:SI PR_REG))
1939    (clobber (reg:SI R1_REG))
1940    (clobber (reg:SI R2_REG))
1941    (clobber (reg:SI R3_REG))
1942    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1943   "TARGET_SH1 && (! TARGET_SH4 || TARGET_DIVIDE_CALL_DIV1)"
1944   "jsr  @%1%#"
1945   [(set_attr "type" "sfunc")
1946    (set_attr "needs_delay_slot" "yes")])
1948 (define_insn "divsi3_i1_media"
1949   [(set (match_operand:SI 0 "register_operand" "=z")
1950         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1951    (clobber (reg:SI T_MEDIA_REG))
1952    (clobber (reg:SI PR_MEDIA_REG))
1953    (clobber (reg:SI R1_REG))
1954    (clobber (reg:SI R20_REG))
1955    (clobber (reg:SI R21_REG))
1956    (clobber (reg:SI TR0_REG))
1957    (use (match_operand 1 "target_reg_operand" "b"))]
1958   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1959   "blink        %1, r18"
1960   [(set_attr "type" "sfunc")])
1962 (define_insn "divsi3_media_2"
1963   [(set (match_operand:SI 0 "register_operand" "=z")
1964         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1965    (clobber (reg:SI T_MEDIA_REG))
1966    (clobber (reg:SI PR_MEDIA_REG))
1967    (clobber (reg:SI R1_REG))
1968    (clobber (reg:SI R21_REG))
1969    (clobber (reg:SI TR0_REG))
1970    (use (reg:SI R20_REG))
1971    (use (match_operand 1 "target_reg_operand" "b"))]
1972   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1973   "blink        %1, r18"
1974   [(set_attr "type" "sfunc")])
1976 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1977 ;; hard reg clobbers and data dependencies that we need when we want
1978 ;; to rematerialize the division into a call.
1979 (define_insn_and_split "divsi_inv_call"
1980   [(set (match_operand:SI 0 "register_operand" "=r")
1981         (div:SI (match_operand:SI 1 "register_operand" "r")
1982                 (match_operand:SI 2 "register_operand" "r")))
1983    (clobber (reg:SI R4_REG))
1984    (clobber (reg:SI R5_REG))
1985    (clobber (reg:SI T_MEDIA_REG))
1986    (clobber (reg:SI PR_MEDIA_REG))
1987    (clobber (reg:SI R1_REG))
1988    (clobber (reg:SI R21_REG))
1989    (clobber (reg:SI TR0_REG))
1990    (clobber (reg:SI R20_REG))
1991    (use (match_operand:SI 3 "register_operand" "r"))]
1992   "TARGET_SHMEDIA"
1993   "#"
1994   "&& (high_life_started || reload_completed)"
1995   [(set (match_dup 0) (match_dup 3))]
1996   ""
1997   [(set_attr "highpart" "must_split")])
1999 ;; This is the combiner pattern for -mdiv=inv:call .
2000 (define_insn_and_split "*divsi_inv_call_combine"
2001   [(set (match_operand:SI 0 "register_operand" "=z")
2002         (div:SI (match_operand:SI 1 "register_operand" "r")
2003                 (match_operand:SI 2 "register_operand" "r")))
2004    (clobber (reg:SI R4_REG))
2005    (clobber (reg:SI R5_REG))
2006    (clobber (reg:SI T_MEDIA_REG))
2007    (clobber (reg:SI PR_MEDIA_REG))
2008    (clobber (reg:SI R1_REG))
2009    (clobber (reg:SI R21_REG))
2010    (clobber (reg:SI TR0_REG))
2011    (clobber (reg:SI R20_REG))
2012    (use (unspec:SI [(match_dup 1)
2013                     (match_operand:SI 3 "" "")
2014                     (unspec:SI [(match_operand:SI 4 "" "")
2015                                 (match_dup 3)
2016                                 (match_operand:DI 5 "" "")]
2017                      UNSPEC_DIV_INV_M2)
2018                     (match_operand:DI 6 "" "")
2019                     (const_int 0)
2020                     (const_int 0)]
2021          UNSPEC_DIV_INV_M3))]
2022   "TARGET_SHMEDIA"
2023   "#"
2024   "&& (high_life_started || reload_completed)"
2025   [(pc)]
2027   const char *name = sh_divsi3_libfunc;
2028   enum sh_function_kind kind = SFUNC_GOT;
2029   rtx sym;
2031   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2032   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2033   while (TARGET_DIVIDE_INV_CALL2)
2034     {
2035       rtx x = operands[3];
2037       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2038         break;
2039       x = XVECEXP (x, 0, 0);
2040       name = "__sdivsi3_2";
2041       kind = SFUNC_STATIC;
2042       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2043       break;
2044     }
2045   sym = function_symbol (NULL, name, kind);
2046   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2047   DONE;
2049   [(set_attr "highpart" "must_split")])
2051 (define_expand "divsi3_i4_media"
2052   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2053    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2054    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2055    (set (match_operand:SI 0 "register_operand" "=r")
2056         (fix:SI (match_dup 5)))]
2057   "TARGET_SHMEDIA_FPU"
2059   operands[3] = gen_reg_rtx (DFmode);
2060   operands[4] = gen_reg_rtx (DFmode);
2061   operands[5] = gen_reg_rtx (DFmode);
2064 (define_insn "divsi3_i4"
2065   [(set (match_operand:SI 0 "register_operand" "=y")
2066         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2067    (clobber (reg:SI PR_REG))
2068    (clobber (reg:DF DR0_REG))
2069    (clobber (reg:DF DR2_REG))
2070    (use (reg:PSI FPSCR_REG))
2071    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2072   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2073   "jsr  @%1%#"
2074   [(set_attr "type" "sfunc")
2075    (set_attr "fp_mode" "double")
2076    (set_attr "needs_delay_slot" "yes")])
2078 (define_insn "divsi3_i4_single"
2079   [(set (match_operand:SI 0 "register_operand" "=y")
2080         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2081    (clobber (reg:SI PR_REG))
2082    (clobber (reg:DF DR0_REG))
2083    (clobber (reg:DF DR2_REG))
2084    (clobber (reg:SI R2_REG))
2085    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2086   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2087   "jsr  @%1%#"
2088   [(set_attr "type" "sfunc")
2089    (set_attr "needs_delay_slot" "yes")])
2091 (define_insn "divsi3_i4_int"
2092   [(set (match_operand:SI 0 "register_operand" "=z")
2093         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2094    (clobber (reg:SI T_REG))
2095    (clobber (reg:SI PR_REG))
2096    (clobber (reg:SI R1_REG))
2097    (clobber (reg:SI MACH_REG))
2098    (clobber (reg:SI MACL_REG))
2099    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2100   "TARGET_SH1"
2101   "jsr  @%1%#"
2102   [(set_attr "type" "sfunc")
2103    (set_attr "needs_delay_slot" "yes")])
2105 (define_expand "divsi3"
2106   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2107    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2108    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2109    (parallel [(set (match_operand:SI 0 "register_operand" "")
2110                    (div:SI (reg:SI R4_REG)
2111                            (reg:SI R5_REG)))
2112               (clobber (reg:SI T_REG))
2113               (clobber (reg:SI PR_REG))
2114               (clobber (reg:SI R1_REG))
2115               (clobber (reg:SI R2_REG))
2116               (clobber (reg:SI R3_REG))
2117               (use (match_dup 3))])]
2118   ""
2120   rtx last;
2122   operands[3] = gen_reg_rtx (Pmode);
2123   /* Emit the move of the address to a pseudo outside of the libcall.  */
2124   if (TARGET_DIVIDE_CALL_TABLE)
2125     {
2126       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2127       last = gen_divsi3_i4_int (operands[0], operands[3]);
2128     }
2129   else if (TARGET_DIVIDE_CALL_FP)
2130     {
2131       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2132       if (TARGET_FPU_SINGLE)
2133         last = gen_divsi3_i4_single (operands[0], operands[3]);
2134       else
2135         last = gen_divsi3_i4 (operands[0], operands[3]);
2136     }
2137   else if (TARGET_SH2A)
2138     {
2139       operands[1] = force_reg (SImode, operands[1]);
2140       operands[2] = force_reg (SImode, operands[2]);
2141       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2142       DONE;
2143     }
2144   else if (TARGET_DIVIDE_INV)
2145     {
2146       rtx dividend = operands[1];
2147       rtx divisor = operands[2];
2148       rtx tab_base;
2149       rtx nsb_res = gen_reg_rtx (DImode);
2150       rtx norm64 = gen_reg_rtx (DImode);
2151       rtx tab_ix = gen_reg_rtx (DImode);
2152       rtx norm32 = gen_reg_rtx (SImode);
2153       rtx i92 = force_reg (DImode, GEN_INT (92));
2154       rtx scratch0a = gen_reg_rtx (DImode);
2155       rtx scratch0b = gen_reg_rtx (DImode);
2156       rtx inv0 = gen_reg_rtx (SImode);
2157       rtx scratch1a = gen_reg_rtx (DImode);
2158       rtx scratch1b = gen_reg_rtx (DImode);
2159       rtx shift = gen_reg_rtx (DImode);
2160       rtx i2p27, i43;
2161       rtx inv1 = gen_reg_rtx (SImode);
2162       rtx scratch2a = gen_reg_rtx (DImode);
2163       rtx scratch2b = gen_reg_rtx (SImode);
2164       rtx inv2 = gen_reg_rtx (SImode);
2165       rtx scratch3a = gen_reg_rtx (DImode);
2166       rtx scratch3b = gen_reg_rtx (DImode);
2167       rtx scratch3c = gen_reg_rtx (DImode);
2168       rtx scratch3d = gen_reg_rtx (SImode);
2169       rtx scratch3e = gen_reg_rtx (DImode);
2170       rtx result = gen_reg_rtx (SImode);
2172       if (! arith_reg_or_0_operand (dividend, SImode))
2173         dividend = force_reg (SImode, dividend);
2174       if (! arith_reg_operand (divisor, SImode))
2175         divisor = force_reg (SImode, divisor);
2176       if (flag_pic && Pmode != DImode)
2177         {
2178           tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2179           tab_base = gen_datalabel_ref (tab_base);
2180           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2181         }
2182       else
2183         {
2184           tab_base = gen_rtx_SYMBOL_REF (DImode, "__div_table");
2185           tab_base = gen_datalabel_ref (tab_base);
2186           tab_base = force_reg (DImode, tab_base);
2187         }
2188       if (TARGET_DIVIDE_INV20U)
2189         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2190       else
2191         i2p27 = GEN_INT (0);
2192       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2193         i43 = force_reg (DImode, GEN_INT (43));
2194       else
2195         i43 = GEN_INT (0);
2196       emit_insn (gen_nsbdi (nsb_res,
2197                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2198       emit_insn (gen_ashldi3_media (norm64,
2199                                     gen_rtx_SUBREG (DImode, divisor, 0),
2200                                     nsb_res));
2201       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2202       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2203       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2204                                    inv0, scratch0a, scratch0b,
2205                                    scratch1a, scratch1b));
2206       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2207       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2208                                    scratch2a));
2209       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2210                                    i2p27, i43,
2211                                    scratch3a, scratch3b, scratch3c,
2212                                    scratch2a, scratch2b, scratch3d, scratch3e));
2213       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2214         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2215       else if (TARGET_DIVIDE_INV_FP)
2216         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2217                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2218                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2219                                      gen_reg_rtx (DFmode)));
2220       else
2221         emit_move_insn (operands[0], result);
2222       DONE;
2223     }
2224   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2225     {
2226       operands[1] = force_reg (SImode, operands[1]);
2227       operands[2] = force_reg (SImode, operands[2]);
2228       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2229       DONE;
2230     }
2231   else if (TARGET_SH5)
2232     {
2233       if (TARGET_DIVIDE_CALL2)
2234         {
2235           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, "__div_table");
2236           tab_base = gen_datalabel_ref (tab_base);
2237           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2238         }
2239       if (TARGET_FPU_ANY && TARGET_SH1)
2240         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2241       else if (TARGET_DIVIDE_CALL2)
2242         function_symbol (operands[3], "__sdivsi3_2", SFUNC_STATIC);
2243       else
2244         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2246       if (TARGET_SHMEDIA)
2247         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2248                 (operands[0], operands[3]));
2249       else if (TARGET_FPU_ANY)
2250         last = gen_divsi3_i4_single (operands[0], operands[3]);
2251       else
2252         last = gen_divsi3_i1 (operands[0], operands[3]);
2253     }
2254   else
2255     {
2256       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2257       last = gen_divsi3_i1 (operands[0], operands[3]);
2258     }
2259   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2260   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2261   emit_insn (last);
2262   DONE;
2265 ;; operands: scratch, tab_base, tab_ix
2266 ;; These are unspecs because we could generate an indexed addressing mode
2267 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2268 ;; confuse reload.  See PR27117.
2270 (define_insn "divsi_inv_qitable"
2271   [(set (match_operand:DI 0 "register_operand" "=r")
2272         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2273                                     (match_operand:DI 2 "register_operand" "r")]
2274                          UNSPEC_DIV_INV_TABLE)))]
2275   "TARGET_SHMEDIA"
2276   "@
2277         ldx.ub  %1, %2, %0"
2278   [(set_attr "type" "load_media")
2279    (set_attr "highpart" "user")])
2281 ;; operands: scratch, tab_base, tab_ix
2282 (define_insn "divsi_inv_hitable"
2283   [(set (match_operand:DI 0 "register_operand" "=r")
2284         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2285                                     (match_operand:DI 2 "register_operand" "r")]
2286                          UNSPEC_DIV_INV_TABLE)))]
2287   "TARGET_SHMEDIA"
2288   "@
2289         ldx.w   %1, %2, %0"
2290   [(set_attr "type" "load_media")
2291    (set_attr "highpart" "user")])
2293 ;; operands: inv0, tab_base, tab_ix, norm32
2294 ;; scratch equiv in sdivsi3_2: r19, r21
2295 (define_expand "divsi_inv_m0"
2296   [(set (match_operand:SI 0 "register_operand" "=r")
2297         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2298                     (match_operand:DI 2 "register_operand" "r")
2299                     (match_operand:SI 3 "register_operand" "r")]
2300          UNSPEC_DIV_INV_M0))
2301    (clobber (match_operand:DI 4 "register_operand" "=r"))
2302    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2303   "TARGET_SHMEDIA"
2306 tab_base: r20
2307 tab_ix: r21
2308 norm32: r25
2309  ldx.ub r20, r21, r19 // u0.8
2310  shlli r21, 1, r21
2311  muls.l r25, r19, r19 // s2.38
2312  ldx.w r20, r21, r21  // s2.14
2313  shari r19, 24, r19   // truncate to s2.14
2314  sub r21, r19, r19    // some 11 bit inverse in s1.14
2317   rtx inv0 = operands[0];
2318   rtx tab_base = operands[1];
2319   rtx tab_ix = operands[2];
2320   rtx norm32 = operands[3];
2321   rtx scratch0 = operands[4];
2322   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2323   rtx scratch1 = operands[5];
2325   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2326   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2327   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2328   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2329   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2330   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2331   DONE;
2334 ;; operands: inv1, tab_base, tab_ix, norm32
2335 (define_insn_and_split "divsi_inv_m1"
2336   [(set (match_operand:SI 0 "register_operand" "=r")
2337         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2338                     (match_operand:DI 2 "register_operand" "r")
2339                     (match_operand:SI 3 "register_operand" "r")]
2340          UNSPEC_DIV_INV_M1))
2341    (clobber (match_operand:SI 4 "register_operand" "=r"))
2342    (clobber (match_operand:DI 5 "register_operand" "=r"))
2343    (clobber (match_operand:DI 6 "register_operand" "=r"))
2344    (clobber (match_operand:DI 7 "register_operand" "=r"))
2345    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2346   "TARGET_SHMEDIA"
2347   "#"
2348   "&& !can_create_pseudo_p ()"
2349   [(pc)]
2351 /* inv0: r19
2352  muls.l r19, r19, r18 // u0.28
2353  muls.l r25, r18, r18 // s2.58
2354  shlli r19, 45, r0    // multiply by two and convert to s2.58
2355  sub r0, r18, r18
2356  shari r18, 28, r18   // some 18 bit inverse in s1.30
2359   rtx inv1 = operands[0];
2360   rtx tab_base = operands[1];
2361   rtx tab_ix = operands[2];
2362   rtx norm32 = operands[3];
2363   rtx inv0 = operands[4];
2364   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2365   rtx scratch0a = operands[5];
2366   rtx scratch0b = operands[6];
2367   rtx scratch0 = operands[7];
2368   rtx scratch1 = operands[8];
2369   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2371   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2372                                scratch0a, scratch0b));
2373   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2374   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2375   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2376   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2377   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2378   DONE;
2381 ;; operands: inv2, norm32, inv1, i92
2382 (define_insn_and_split "divsi_inv_m2"
2383   [(set (match_operand:SI 0 "register_operand" "=r")
2384         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2385                     (match_operand:SI 2 "register_operand" "r")
2386                     (match_operand:DI 3 "register_operand" "r")]
2387          UNSPEC_DIV_INV_M2))
2388    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2389   "TARGET_SHMEDIA"
2390   "#"
2391   "&& !can_create_pseudo_p ()"
2392   [(pc)]
2395  muls.l r18, r25, r0  // s2.60
2396  shari r0, 16, r0     // s-16.44
2397   sub
2398  muls.l r0, r18, r19  // s-16.74
2399  shari r19, 30, r19   // s-16.44
2401   rtx inv2 = operands[0];
2402   rtx norm32 = operands[1];
2403   rtx inv1 = operands[2];
2404   rtx i92 = operands[3];
2405   rtx scratch0 = operands[4];
2406   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2408   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2409   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2410   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2411   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2412   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2413   DONE;
2416 (define_insn_and_split "divsi_inv_m3"
2417   [(set (match_operand:SI 0 "register_operand" "=r")
2418         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2419                     (match_operand:SI 2 "register_operand" "r")
2420                     (match_operand:SI 3 "register_operand" "r")
2421                     (match_operand:DI 4 "register_operand" "r")
2422                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2423                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2424          UNSPEC_DIV_INV_M3))
2425    (clobber (match_operand:DI 7 "register_operand" "=r"))
2426    (clobber (match_operand:DI 8 "register_operand" "=r"))
2427    (clobber (match_operand:DI 9 "register_operand" "=r"))
2428    (clobber (match_operand:DI 10 "register_operand" "=r"))
2429    (clobber (match_operand:SI 11 "register_operand" "=r"))
2430    (clobber (match_operand:SI 12 "register_operand" "=r"))
2431    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2432   "TARGET_SHMEDIA"
2433   "#"
2434   "&& !can_create_pseudo_p ()"
2435   [(pc)]
2438   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2439   r0: scratch0  r19: scratch1 r21: scratch2
2441   muls.l r18, r4, r25 // s32.30
2442  muls.l r19, r4, r19  // s15.30
2443  shari r25, 63, r21
2444   shari r19, 14, r19  // s18.-14
2445  sub r25, r19, r0
2446  shard r0, r1, r0
2447  sub r0, r21, r0
2450   rtx result = operands[0];
2451   rtx dividend = operands[1];
2452   rtx inv1 = operands[2];
2453   rtx inv2 = operands[3];
2454   rtx shift = operands[4];
2455   rtx scratch0 = operands[7];
2456   rtx scratch1 = operands[8];
2457   rtx scratch2 = operands[9];
2459   if (satisfies_constraint_N (dividend))
2460     {
2461       emit_move_insn (result, dividend);
2462       DONE;
2463     }
2465   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2466   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2467   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2468   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2469   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2470   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2471   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2472   DONE;
2475 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2476 ;; inv1: tab_base, tab_ix, norm32
2477 ;; inv2: norm32, inv1, i92
2478 (define_insn_and_split "divsi_inv_m1_3"
2479   [(set (match_operand:SI 0 "register_operand" "=r")
2480         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2481                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2482                                 (match_operand:DI 3 "register_operand" "r")
2483                                 (match_operand:SI 4 "register_operand" "r")]
2484                      UNSPEC_DIV_INV_M1)
2485                     (unspec:SI [(match_dup 4)
2486                                 (unspec:SI [(match_dup 2)
2487                                             (match_dup 3)
2488                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2489                                 (match_operand:SI 5 "" "")]
2490                      UNSPEC_DIV_INV_M2)
2491                     (match_operand:DI 6 "register_operand" "r")
2492                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2493                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2494          UNSPEC_DIV_INV_M3))
2495    (clobber (match_operand:DI 9 "register_operand" "=r"))
2496    (clobber (match_operand:DI 10 "register_operand" "=r"))
2497    (clobber (match_operand:DI 11 "register_operand" "=r"))
2498    (clobber (match_operand:DI 12 "register_operand" "=r"))
2499    (clobber (match_operand:SI 13 "register_operand" "=r"))
2500    (clobber (match_operand:SI 14 "register_operand" "=r"))
2501    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2502   "TARGET_SHMEDIA
2503    && (TARGET_DIVIDE_INV_MINLAT
2504        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2505   "#"
2506   "&& !can_create_pseudo_p ()"
2507   [(pc)]
2509   rtx result = operands[0];
2510   rtx dividend = operands[1];
2511   rtx tab_base = operands[2];
2512   rtx tab_ix = operands[3];
2513   rtx norm32 = operands[4];
2514   /* rtx i92 = operands[5]; */
2515   rtx shift = operands[6];
2516   rtx i2p27 = operands[7];
2517   rtx i43 = operands[8];
2518   rtx scratch0 = operands[9];
2519   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2520   rtx scratch1 = operands[10];
2521   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2522   rtx scratch2 = operands[11];
2523   rtx scratch3 = operands[12];
2524   rtx scratch4 = operands[13];
2525   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2526   rtx scratch5 = operands[14];
2527   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2528   rtx scratch6 = operands[15];
2530   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2531                                scratch0, scratch1));
2532   /* inv0 == scratch4 */
2533   if (! TARGET_DIVIDE_INV20U)
2534     {
2535       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2536       i2p27 = scratch0;
2537       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2538     }
2539   else
2540     {
2541       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2542       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2543     }
2544   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2545   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2546   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2547   /* inv1 == scratch4 */
2549   if (TARGET_DIVIDE_INV_MINLAT)
2550     {
2551       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2552       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2553       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2554       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2555       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2556       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2557       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2558       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2559       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2560       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2561       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2562     }
2563   else
2564     {
2565       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2566       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2567       emit_insn (gen_nsbdi (scratch6,
2568                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2569       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2570       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2571       emit_insn (gen_divsi_inv20 (scratch2,
2572                                   norm32, scratch4, dividend,
2573                                   scratch6, scratch3, i43,
2574                                   /* scratch0 may be shared with i2p27.  */
2575                                   scratch0, scratch1, scratch5,
2576                                   label, label, i2p27));
2577     }
2578   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2579   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2580   DONE;
2583 (define_insn "divsi_inv20"
2584   [(set (match_operand:DI 0 "register_operand" "=&r")
2585         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2586                     (match_operand:SI 2 "register_operand" "r")
2587                     (match_operand:SI 3 "register_operand" "r")
2588                     (match_operand:DI 4 "register_operand" "r")
2589                     (match_operand:DI 5 "register_operand" "r")
2590                     (match_operand:DI 6 "register_operand" "r")
2591                     (match_operand:DI 12 "register_operand" "r")
2592                     (match_operand 10 "target_operand" "b")
2593                     (match_operand 11 "immediate_operand" "i")]
2594          UNSPEC_DIV_INV20))
2595    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2596    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2597    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2598   "TARGET_SHMEDIA
2599    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2601 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2602              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2603              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2604              %10 label (tr), %11 label (imm)
2606  muls.l inv1, norm32, scratch0  // s2.60
2607   muls.l inv1, dividend, result // s32.30
2608   xor i2p27, result_sign, round_scratch
2609  bge/u dividend_nsb, i43, tr.. (label)
2610  shari scratch0, 16, scratch0   // s-16.44
2611  muls.l sratch0_si, inv1, scratch0 // s-16.74
2612   sub result, round_scratch, result
2613   shari dividend, 14, scratch1   // s19.-14
2614  shari scratch0, 30, scratch0   // s-16.44
2615  muls.l scratch0, scratch1, round_scratch // s15.30
2616 label:
2617  sub result, round_scratch, result */
2619   int likely = TARGET_DIVIDE_INV20L;
2621   if (! likely) output_asm_insn ("muls.l\t%2, %1 , %8", operands);
2622   output_asm_insn ("muls.l\t%2, %3, %0\;xor\t%12, %5, %7", operands);
2623   output_asm_insn (likely
2624                    ? "bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8"
2625                    : "bge/u\t%4, %6, %10", operands);
2626   output_asm_insn ("shari\t%8, 16, %8\;muls.l\t%8, %2, %8", operands);
2627   if (! likely) output_asm_insn ("sub\t%0, %7, %0", operands);
2628   output_asm_insn ("shari\t%3, 14, %9\;shari\t%8, 30, %8", operands);
2629   return (likely
2630           ? "muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0"
2631           : "muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0");
2634 (define_insn_and_split "divsi_inv_fp"
2635   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2636         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2637                 (match_operand:SI 2 "register_operand" "rf")))
2638    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2639    (clobber (match_operand:SI 4 "register_operand" "=r"))
2640    (clobber (match_operand:SI 5 "register_operand" "=r"))
2641    (clobber (match_operand:DF 6 "register_operand" "=r"))
2642    (clobber (match_operand:DF 7 "register_operand" "=r"))
2643    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2644   "TARGET_SHMEDIA_FPU"
2645   "#"
2646   "&& (high_life_started || reload_completed)"
2647   [(set (match_dup 0) (match_dup 3))]
2648   ""
2649   [(set_attr "highpart" "must_split")])
2651 ;; If a matching group of divide-by-inverse instructions is in the same
2652 ;; basic block after gcse & loop optimizations, we want to transform them
2653 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2654 (define_insn_and_split "*divsi_inv_fp_combine"
2655   [(set (match_operand:SI 0 "register_operand" "=f")
2656         (div:SI (match_operand:SI 1 "register_operand" "f")
2657                 (match_operand:SI 2 "register_operand" "f")))
2658    (use (unspec:SI [(match_dup 1)
2659                     (match_operand:SI 3 "" "")
2660                     (unspec:SI [(match_operand:SI 4 "" "")
2661                                 (match_dup 3)
2662                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2663                     (match_operand:DI 6 "" "")
2664                     (const_int 0)
2665                     (const_int 0)] UNSPEC_DIV_INV_M3))
2666    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2667    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2668    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2669    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2670    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2671   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2672   "#"
2673   "&& 1"
2674   [(set (match_dup 9) (float:DF (match_dup 1)))
2675    (set (match_dup 10) (float:DF (match_dup 2)))
2676    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2677    (set (match_dup 8)
2678         (fix:SI (match_dup 11)))
2679    (set (match_dup 0) (match_dup 8))]
2681   if (! fp_arith_reg_operand (operands[1], SImode))
2682     {
2683       emit_move_insn (operands[7], operands[1]);
2684       operands[1] = operands[7];
2685     }
2686   if (! fp_arith_reg_operand (operands[2], SImode))
2687     {
2688       emit_move_insn (operands[8], operands[2]);
2689       operands[2] = operands[8];
2690     }
2692   [(set_attr "highpart" "must_split")])
2694 ;; -------------------------------------------------------------------------
2695 ;; Multiplication instructions
2696 ;; -------------------------------------------------------------------------
2698 (define_insn "umulhisi3_i"
2699   [(set (reg:SI MACL_REG)
2700         (mult:SI (zero_extend:SI
2701                   (match_operand:HI 0 "arith_reg_operand" "r"))
2702                  (zero_extend:SI
2703                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2704   "TARGET_SH1"
2705   "mulu.w       %1,%0"
2706   [(set_attr "type" "smpy")])
2708 (define_insn "mulhisi3_i"
2709   [(set (reg:SI MACL_REG)
2710         (mult:SI (sign_extend:SI
2711                   (match_operand:HI 0 "arith_reg_operand" "r"))
2712                  (sign_extend:SI
2713                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2714   "TARGET_SH1"
2715   "muls.w       %1,%0"
2716   [(set_attr "type" "smpy")])
2718 (define_expand "mulhisi3"
2719   [(set (reg:SI MACL_REG)
2720         (mult:SI (sign_extend:SI
2721                   (match_operand:HI 1 "arith_reg_operand" ""))
2722                  (sign_extend:SI
2723                   (match_operand:HI 2 "arith_reg_operand" ""))))
2724    (set (match_operand:SI 0 "arith_reg_operand" "")
2725         (reg:SI MACL_REG))]
2726   "TARGET_SH1"
2728   rtx insn, macl;
2730   macl = gen_rtx_REG (SImode, MACL_REG);
2731   start_sequence ();
2732   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2733   insn = get_insns ();  
2734   end_sequence ();
2735   /* expand_binop can't find a suitable code in umul_widen_optab to
2736      make a REG_EQUAL note from, so make one here.
2737      See also smulsi3_highpart.
2738      ??? Alternatively, we could put this at the calling site of expand_binop,
2739      i.e. expand_expr.  */
2740   /* Use emit_libcall_block for loop invariant code motion and to make
2741      a REG_EQUAL note.  */
2742   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2744   DONE;
2747 (define_expand "umulhisi3"
2748   [(set (reg:SI MACL_REG)
2749         (mult:SI (zero_extend:SI
2750                   (match_operand:HI 1 "arith_reg_operand" ""))
2751                  (zero_extend:SI
2752                   (match_operand:HI 2 "arith_reg_operand" ""))))
2753    (set (match_operand:SI 0 "arith_reg_operand" "")
2754         (reg:SI MACL_REG))]
2755   "TARGET_SH1"
2757   rtx insn, macl;
2759   macl = gen_rtx_REG (SImode, MACL_REG);
2760   start_sequence ();
2761   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2762   insn = get_insns ();  
2763   end_sequence ();
2764   /* expand_binop can't find a suitable code in umul_widen_optab to
2765      make a REG_EQUAL note from, so make one here.
2766      See also smulsi3_highpart.
2767      ??? Alternatively, we could put this at the calling site of expand_binop,
2768      i.e. expand_expr.  */
2769   /* Use emit_libcall_block for loop invariant code motion and to make
2770      a REG_EQUAL note.  */
2771   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2773   DONE;
2776 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2777 ;; a call to a routine which clobbers known registers.
2779 (define_insn ""
2780   [(set (match_operand:SI 1 "register_operand" "=z")
2781         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2782    (clobber (reg:SI MACL_REG))
2783    (clobber (reg:SI T_REG))
2784    (clobber (reg:SI PR_REG))
2785    (clobber (reg:SI R3_REG))
2786    (clobber (reg:SI R2_REG))
2787    (clobber (reg:SI R1_REG))
2788    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2789   "TARGET_SH1"
2790   "jsr  @%0%#"
2791   [(set_attr "type" "sfunc")
2792    (set_attr "needs_delay_slot" "yes")])
2794 (define_expand "mulsi3_call"
2795   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2796    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2797    (parallel[(set (match_operand:SI 0 "register_operand" "")
2798                   (mult:SI (reg:SI R4_REG)
2799                            (reg:SI R5_REG)))
2800              (clobber (reg:SI MACL_REG))
2801              (clobber (reg:SI T_REG))
2802              (clobber (reg:SI PR_REG))
2803              (clobber (reg:SI R3_REG))
2804              (clobber (reg:SI R2_REG))
2805              (clobber (reg:SI R1_REG))
2806              (use (match_operand:SI 3 "register_operand" ""))])]
2807   "TARGET_SH1"
2808   "")
2810 (define_insn "mul_r"
2811   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2812         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2813                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2814   "TARGET_SH2A"
2815   "mulr %2,%0"
2816   [(set_attr "type" "dmpy")])
2818 (define_insn "mul_l"
2819   [(set (reg:SI MACL_REG)
2820         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2821                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2822   "TARGET_SH2"
2823   "mul.l        %1,%0"
2824   [(set_attr "type" "dmpy")])
2826 (define_expand "mulsi3"
2827   [(set (reg:SI MACL_REG)
2828         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2829                   (match_operand:SI 2 "arith_reg_operand" "")))
2830    (set (match_operand:SI 0 "arith_reg_operand" "")
2831         (reg:SI MACL_REG))]
2832   "TARGET_SH1"
2834   if (!TARGET_SH2)
2835     {
2836       /* The address must be set outside the libcall,
2837          since it goes into a pseudo.  */
2838       rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC);
2839       rtx addr = force_reg (SImode, sym);
2840       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2841                                    operands[2], addr);
2842       emit_insn (insns);
2843     }
2844   else
2845     {
2846       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2848       emit_insn (gen_mul_l (operands[1], operands[2]));
2849       /* consec_sets_giv can only recognize the first insn that sets a
2850          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2851          note.  */
2852       emit_insn (gen_movsi_i ((operands[0]), macl));
2853     }
2854   DONE;
2857 (define_insn "mulsidi3_i"
2858   [(set (reg:SI MACH_REG)
2859         (truncate:SI
2860          (lshiftrt:DI
2861           (mult:DI
2862            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2863            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2864           (const_int 32))))
2865    (set (reg:SI MACL_REG)
2866         (mult:SI (match_dup 0)
2867                  (match_dup 1)))]
2868   "TARGET_SH2"
2869   "dmuls.l      %1,%0"
2870   [(set_attr "type" "dmpy")])
2872 (define_expand "mulsidi3"
2873   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2874         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2875                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2876   "TARGET_SH2 || TARGET_SHMEDIA"
2878   if (TARGET_SH2)
2879     {
2880       emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
2881       DONE;
2882     }
2885 (define_insn "mulsidi3_media"
2886   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2887         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2888                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2889   "TARGET_SHMEDIA"
2890   "muls.l       %1, %2, %0"
2891   [(set_attr "type" "dmpy_media")
2892    (set_attr "highpart" "ignore")])
2894 (define_insn "mulsidi3_compact"
2895   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2896         (mult:DI
2897          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2898          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2899    (clobber (reg:SI MACH_REG))
2900    (clobber (reg:SI MACL_REG))]
2901   "TARGET_SH2"
2902   "#")
2904 (define_split
2905   [(set (match_operand:DI 0 "arith_reg_dest" "")
2906         (mult:DI
2907          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2908          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2909    (clobber (reg:SI MACH_REG))
2910    (clobber (reg:SI MACL_REG))]
2911   "TARGET_SH2"
2912   [(const_int 0)]
2914   rtx low_dst = gen_lowpart (SImode, operands[0]);
2915   rtx high_dst = gen_highpart (SImode, operands[0]);
2917   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2919   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2920   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2921   /* We need something to tag the possible REG_EQUAL notes on to.  */
2922   emit_move_insn (operands[0], operands[0]);
2923   DONE;
2926 (define_insn "umulsidi3_i"
2927   [(set (reg:SI MACH_REG)
2928         (truncate:SI
2929          (lshiftrt:DI
2930           (mult:DI
2931            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2932            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2933           (const_int 32))))
2934    (set (reg:SI MACL_REG)
2935         (mult:SI (match_dup 0)
2936                  (match_dup 1)))]
2937   "TARGET_SH2"
2938   "dmulu.l      %1,%0"
2939   [(set_attr "type" "dmpy")])
2941 (define_expand "umulsidi3"
2942   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2943         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2944                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2945   "TARGET_SH2 || TARGET_SHMEDIA"
2947   if (TARGET_SH2)
2948     {
2949       emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
2950       DONE;
2951     }
2954 (define_insn "umulsidi3_media"
2955   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2956         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2957                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2958   "TARGET_SHMEDIA"
2959   "mulu.l       %1, %2, %0"
2960   [(set_attr "type" "dmpy_media")
2961    (set_attr "highpart" "ignore")])
2963 (define_insn "umulsidi3_compact"
2964   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2965         (mult:DI
2966          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2967          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2968    (clobber (reg:SI MACH_REG))
2969    (clobber (reg:SI MACL_REG))]
2970   "TARGET_SH2"
2971   "#")
2973 (define_split
2974   [(set (match_operand:DI 0 "arith_reg_dest" "")
2975         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2976                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2977    (clobber (reg:SI MACH_REG))
2978    (clobber (reg:SI MACL_REG))]
2979   "TARGET_SH2"
2980   [(const_int 0)]
2982   rtx low_dst = gen_lowpart (SImode, operands[0]);
2983   rtx high_dst = gen_highpart (SImode, operands[0]);
2985   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2987   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2988   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2989   /* We need something to tag the possible REG_EQUAL notes on to.  */
2990   emit_move_insn (operands[0], operands[0]);
2991   DONE;
2994 (define_insn "smulsi3_highpart_i"
2995   [(set (reg:SI MACH_REG)
2996         (truncate:SI
2997          (lshiftrt:DI
2998           (mult:DI
2999            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3000            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3001           (const_int 32))))
3002    (clobber (reg:SI MACL_REG))]
3003   "TARGET_SH2"
3004   "dmuls.l      %1,%0"
3005   [(set_attr "type" "dmpy")])
3007 (define_expand "smulsi3_highpart"
3008   [(parallel
3009     [(set (reg:SI MACH_REG)
3010           (truncate:SI
3011            (lshiftrt:DI
3012             (mult:DI
3013              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3014              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3015             (const_int 32))))
3016     (clobber (reg:SI MACL_REG))])
3017    (set (match_operand:SI 0 "arith_reg_operand" "")
3018         (reg:SI MACH_REG))]
3019   "TARGET_SH2"
3021   rtx insn, mach;
3023   mach = gen_rtx_REG (SImode, MACH_REG);
3024   start_sequence ();
3025   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3026   insn = get_insns ();  
3027   end_sequence ();
3028   /* expand_binop can't find a suitable code in mul_highpart_optab to
3029      make a REG_EQUAL note from, so make one here.
3030      See also {,u}mulhisi.
3031      ??? Alternatively, we could put this at the calling site of expand_binop,
3032      i.e. expand_mult_highpart.  */
3033   /* Use emit_libcall_block for loop invariant code motion and to make
3034      a REG_EQUAL note.  */
3035   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3037   DONE;
3040 (define_insn "umulsi3_highpart_i"
3041   [(set (reg:SI MACH_REG)
3042         (truncate:SI
3043          (lshiftrt:DI
3044           (mult:DI
3045            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3046            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3047           (const_int 32))))
3048    (clobber (reg:SI MACL_REG))]
3049   "TARGET_SH2"
3050   "dmulu.l      %1,%0"
3051   [(set_attr "type" "dmpy")])
3053 (define_expand "umulsi3_highpart"
3054   [(parallel
3055     [(set (reg:SI MACH_REG)
3056           (truncate:SI
3057            (lshiftrt:DI
3058             (mult:DI
3059              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3060              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3061             (const_int 32))))
3062     (clobber (reg:SI MACL_REG))])
3063    (set (match_operand:SI 0 "arith_reg_operand" "")
3064         (reg:SI MACH_REG))]
3065   "TARGET_SH2"
3067   rtx insn, mach;
3069   mach = gen_rtx_REG (SImode, MACH_REG);
3070   start_sequence ();
3071   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3072   insn = get_insns ();  
3073   end_sequence ();
3074   /* Use emit_libcall_block for loop invariant code motion and to make
3075      a REG_EQUAL note.  */
3076   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3078   DONE;
3081 (define_insn_and_split "muldi3"
3082   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3083         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3084                  (match_operand:DI 2 "arith_reg_operand" "r")))
3085    (clobber (match_scratch:DI 3 "=&r"))
3086    (clobber (match_scratch:DI 4 "=r"))]
3087   "TARGET_SHMEDIA"
3088   "#"
3089   "reload_completed"
3090   [(const_int 0)]
3092   rtx op3_v2si, op2_v2si;
3094   op3_v2si = operands[3];
3095   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3096     {
3097       op3_v2si = XEXP (op3_v2si, 0);
3098       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3099     }
3100   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3101   op2_v2si = operands[2];
3102   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3103     {
3104       op2_v2si = XEXP (op2_v2si, 0);
3105       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3106     }
3107   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3108   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3109   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3110   emit_insn (gen_umulsidi3_media (operands[4],
3111                                  sh_gen_truncate (SImode, operands[1], 0),
3112                                  sh_gen_truncate (SImode, operands[2], 0)));
3113   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3114   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3115   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3116   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3117   DONE;
3121 ;; -------------------------------------------------------------------------
3122 ;; Logical operations
3123 ;; -------------------------------------------------------------------------
3125 (define_insn "*andsi3_compact"
3126   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3127         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3128                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3129   "TARGET_SH1"
3130   "and  %2,%0"
3131   [(set_attr "type" "arith")])
3133 (define_insn "*andsi3_media"
3134   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3135         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3136                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3137   "TARGET_SHMEDIA"
3138   "@
3139         and     %1, %2, %0
3140         andi    %1, %2, %0"
3141   [(set_attr "type" "arith_media")])
3143 (define_insn "*andsi3_bclr"
3144   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3145         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3146                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3147   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3148   "bclr\\t%W2,%0"
3149   [(set_attr "type" "arith")])
3151 ;; If the constant is 255, then emit an extu.b instruction instead of an
3152 ;; and, since that will give better code.
3154 (define_expand "andsi3"
3155   [(set (match_operand:SI 0 "arith_reg_operand" "")
3156         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3157                 (match_operand:SI 2 "logical_operand" "")))]
3158   ""
3159   "
3161   if (TARGET_SH1
3162       && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3163     {
3164       emit_insn (gen_zero_extendqisi2 (operands[0],
3165                                        gen_lowpart (QImode, operands[1])));
3166       DONE;
3167     }
3170 (define_insn_and_split "anddi3"
3171   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3172         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3173                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3174   "TARGET_SHMEDIA"
3175   "@
3176         and     %1, %2, %0
3177         andi    %1, %2, %0
3178         #"
3179   "reload_completed
3180    && ! logical_operand (operands[2], DImode)"
3181   [(const_int 0)]
3182   "
3184   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3185     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3186   else
3187     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3188   DONE;
3190   [(set_attr "type" "arith_media")])
3192 (define_insn "andcsi3"
3193   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3194         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3195                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3196   "TARGET_SHMEDIA"
3197   "andc %1,%2,%0"
3198   [(set_attr "type" "arith_media")])
3200 (define_insn "andcdi3"
3201   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3202         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3203                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3204   "TARGET_SHMEDIA"
3205   "andc %1,%2,%0"
3206   [(set_attr "type" "arith_media")])
3208 (define_expand "iorsi3"
3209   [(set (match_operand:SI 0 "arith_reg_operand" "")
3210         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3211                 (match_operand:SI 2 "logical_operand" "")))]
3212   ""
3213   "")
3215 (define_insn "*iorsi3_compact"
3216   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3217         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3218                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3219   "TARGET_SH1
3220    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3221   "or   %2,%0"
3222   [(set_attr "type" "arith")])
3224 (define_insn "*iorsi3_media"
3225   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3226         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3227                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3228   "TARGET_SHMEDIA"
3229   "@
3230         or      %1, %2, %0
3231         ori     %1, %2, %0"
3232   [(set_attr "type" "arith_media")])
3234 (define_insn "*iorsi3_bset"
3235   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3236         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3237         (match_operand:SI 2 "const_int_operand" "Pso")))]
3238   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3239   "bset\\t%V2,%0"
3240   [(set_attr "type" "arith")])
3242 (define_insn "iordi3"
3243   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3244         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3245                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3246   "TARGET_SHMEDIA"
3247   "@
3248         or      %1, %2, %0
3249         ori     %1, %2, %0"
3250   [(set_attr "type" "arith_media")])
3252 (define_insn_and_split "*logical_sidi3"
3253   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3254         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3255                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3256                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3257   "TARGET_SHMEDIA"
3258   "#"
3259   "&& reload_completed"
3260   [(set (match_dup 0) (match_dup 3))]
3262   operands[3]
3263     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3264                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3265                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3268 (define_insn_and_split "*logical_sidisi3"
3269   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3270         (truncate:SI (sign_extend:DI
3271                         (match_operator:SI 3 "logical_operator"
3272                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3273                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3274   "TARGET_SHMEDIA"
3275   "#"
3276   "&& 1"
3277   [(set (match_dup 0) (match_dup 3))])
3279 (define_insn_and_split "*logical_sidi3_2"
3280   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3281         (sign_extend:DI (truncate:SI (sign_extend:DI
3282                         (match_operator:SI 3 "logical_operator"
3283                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3284                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3285   "TARGET_SHMEDIA"
3286   "#"
3287   "&& 1"
3288   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3290 (define_expand "xorsi3"
3291   [(set (match_operand:SI 0 "arith_reg_operand" "")
3292         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3293                 (match_operand:SI 2 "xor_operand" "")))]
3294   ""
3295   "")
3297 (define_insn "*xorsi3_compact"
3298   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3299         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3300                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3301   "TARGET_SH1"
3302   "xor  %2,%0"
3303   [(set_attr "type" "arith")])
3305 (define_insn "*xorsi3_media"
3306   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3307         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3308                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3309   "TARGET_SHMEDIA"
3310   "@
3311         xor     %1, %2, %0
3312         xori    %1, %2, %0"
3313   [(set_attr "type" "arith_media")])
3315 (define_insn "xordi3"
3316   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3317         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3318                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3319   "TARGET_SHMEDIA"
3320   "@
3321         xor     %1, %2, %0
3322         xori    %1, %2, %0"
3323   [(set_attr "type" "arith_media")])
3325 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3326 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3327 (define_split
3328   [(set (match_operand:DI 0 "arith_reg_dest" "")
3329         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3330                           [(match_operand 1 "any_register_operand" "")
3331                            (match_operand 2 "any_register_operand" "")])))]
3332   "TARGET_SHMEDIA"
3333   [(set (match_dup 5) (match_dup 4))
3334    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3336   enum machine_mode inmode = GET_MODE (operands[1]);
3337   int offset = 0;
3339   if (GET_CODE (operands[0]) == SUBREG)
3340     {
3341       offset = SUBREG_BYTE (operands[0]);
3342       operands[0] = SUBREG_REG (operands[0]);
3343     }
3344   gcc_assert (REG_P (operands[0]));
3345   if (! TARGET_LITTLE_ENDIAN)
3346     offset += 8 - GET_MODE_SIZE (inmode);
3347   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3350 ;; -------------------------------------------------------------------------
3351 ;; Shifts and rotates
3352 ;; -------------------------------------------------------------------------
3354 (define_expand "rotldi3"
3355   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3356         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3357                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3358   "TARGET_SHMEDIA"
3359   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3361 (define_insn "rotldi3_mextr"
3362   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3363         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3364                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3365   "TARGET_SHMEDIA"
3367   static char templ[16];
3369   sprintf (templ, "mextr%d\\t%%1,%%1,%%0",
3370            8 - (int) (INTVAL (operands[2]) >> 3));
3371   return templ;
3373   [(set_attr "type" "arith_media")])
3375 (define_expand "rotrdi3"
3376   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3377         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3378                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3379   "TARGET_SHMEDIA"
3381   if (! mextr_bit_offset (operands[2], HImode))
3382     FAIL;
3385 (define_insn "rotrdi3_mextr"
3386   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3387         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3388                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3389   "TARGET_SHMEDIA"
3391   static char templ[16];
3393   sprintf (templ, "mextr%d\\t%%1,%%1,%%0", (int) INTVAL (operands[2]) >> 3);
3394   return templ;
3396   [(set_attr "type" "arith_media")])
3398 (define_split
3399   [(set (match_operand:DI 0 "arith_reg_dest" "")
3400         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3401                                          "ua_address_operand" "")))
3402                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3403                            (const_int 8))))
3404    (clobber (match_operand:DI 3 "register_operand" ""))]
3405   "TARGET_SHMEDIA"
3406   [(match_dup 4) (match_dup 5)]
3408   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3409                  (operands[3], operands[1]));
3410   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3411                               GEN_INT (56), GEN_INT (8));
3414 (define_insn "rotlsi3_1"
3415   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3416         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3417                    (const_int 1)))
3418    (set (reg:SI T_REG)
3419         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3420   "TARGET_SH1"
3421   "rotl %0"
3422   [(set_attr "type" "arith")])
3424 (define_insn "rotlsi3_31"
3425   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3426         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3427                    (const_int 31)))
3428    (clobber (reg:SI T_REG))]
3429   "TARGET_SH1"
3430   "rotr %0"
3431   [(set_attr "type" "arith")])
3433 (define_insn "rotlsi3_16"
3434   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3435         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3436                    (const_int 16)))]
3437   "TARGET_SH1"
3438   "swap.w       %1,%0"
3439   [(set_attr "type" "arith")])
3441 (define_expand "rotlsi3"
3442   [(set (match_operand:SI 0 "arith_reg_dest" "")
3443         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3444                    (match_operand:SI 2 "immediate_operand" "")))]
3445   "TARGET_SH1"
3447   static const char rot_tab[] = {
3448     000, 000, 000, 000, 000, 000, 010, 001,
3449     001, 001, 011, 013, 003, 003, 003, 003,
3450     003, 003, 003, 003, 003, 013, 012, 002,
3451     002, 002, 010, 000, 000, 000, 000, 000,
3452   };
3454   int count, choice;
3456   if (!CONST_INT_P (operands[2]))
3457     FAIL;
3458   count = INTVAL (operands[2]);
3459   choice = rot_tab[count];
3460   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3461     FAIL;
3462   choice &= 7;
3463   switch (choice)
3464     {
3465     case 0:
3466       emit_move_insn (operands[0], operands[1]);
3467       count -= (count & 16) * 2;
3468       break;
3469     case 3:
3470      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3471      count -= 16;
3472      break;
3473     case 1:
3474     case 2:
3475       {
3476         rtx parts[2];
3477         parts[0] = gen_reg_rtx (SImode);
3478         parts[1] = gen_reg_rtx (SImode);
3479         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3480         emit_move_insn (parts[choice-1], operands[1]);
3481         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3482         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3483         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3484         count = (count & ~16) - 8;
3485       }
3486     }
3488   for (; count > 0; count--)
3489     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3490   for (; count < 0; count++)
3491     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3493   DONE;
3496 (define_insn "*rotlhi3_8"
3497   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3498         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3499                    (const_int 8)))]
3500   "TARGET_SH1"
3501   "swap.b       %1,%0"
3502   [(set_attr "type" "arith")])
3504 (define_expand "rotlhi3"
3505   [(set (match_operand:HI 0 "arith_reg_operand" "")
3506         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3507                    (match_operand:HI 2 "immediate_operand" "")))]
3508   "TARGET_SH1"
3510   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3511     FAIL;
3515 ;; shift left
3517 ;; This pattern is used by init_expmed for computing the costs of shift
3518 ;; insns.
3520 (define_insn_and_split "ashlsi3_std"
3521   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3522         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3523                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3524    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3525   "(TARGET_SH3 || TARGET_SH2A)
3526    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3527   "@
3528    shld %2,%0
3529    add  %0,%0
3530    shll%O2      %0
3531    #"
3532   "(TARGET_SH3 || TARGET_SH2A)
3533    && reload_completed
3534    && CONST_INT_P (operands[2])
3535    && ! satisfies_constraint_P27 (operands[2])"
3536   [(set (match_dup 3) (match_dup 2))
3537    (parallel
3538     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3539      (clobber (match_dup 4))])]
3541   operands[4] = gen_rtx_SCRATCH (SImode);
3543   [(set_attr "length" "*,*,*,4")
3544    (set_attr "type" "dyn_shift,arith,arith,arith")])
3546 (define_insn "ashlhi3_k"
3547   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3548         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3549                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3550   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3551   "@
3552         add     %0,%0
3553         shll%O2 %0"
3554   [(set_attr "type" "arith")])
3556 (define_insn "ashlsi3_n"
3557   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3558         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3559                    (match_operand:SI 2 "const_int_operand" "n")))
3560    (clobber (reg:SI T_REG))]
3561   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3562   "#"
3563   [(set (attr "length")
3564         (cond [(match_test "shift_insns_rtx (insn)")
3565                (const_string "2")
3566                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3567                (const_string "4")
3568                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3569                (const_string "6")]
3570               (const_string "8")))
3571    (set_attr "type" "arith")])
3573 (define_split
3574   [(set (match_operand:SI 0 "arith_reg_dest" "")
3575         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3576                    (match_operand:SI 2 "const_int_operand" "")))
3577    (clobber (reg:SI T_REG))]
3578   "TARGET_SH1 && reload_completed"
3579   [(use (reg:SI R0_REG))]
3581   gen_shifty_op (ASHIFT, operands);
3582   DONE;
3585 (define_insn "ashlsi3_media"
3586   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3587         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3588                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3589   "TARGET_SHMEDIA"
3590   "@
3591         shlld.l %1, %2, %0
3592         shlli.l %1, %2, %0"
3593   [(set_attr "type" "arith_media")
3594    (set_attr "highpart" "ignore")])
3596 (define_expand "ashlsi3"
3597   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3598                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3599                               (match_operand:SI 2 "nonmemory_operand" "")))
3600               (clobber (reg:SI T_REG))])]
3601   ""
3603   if (TARGET_SHMEDIA)
3604     {
3605       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3606       DONE;
3607     }
3608   if (CONST_INT_P (operands[2])
3609       && sh_dynamicalize_shift_p (operands[2]))
3610     operands[2] = force_reg (SImode, operands[2]);
3611   if (TARGET_SH3 || TARGET_SH2A)
3612     {
3613       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3614       DONE;
3615     }
3616   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3617     FAIL;
3620 (define_insn "*ashlhi3_n"
3621   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3622         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3623                    (match_operand:HI 2 "const_int_operand" "n")))
3624    (clobber (reg:SI T_REG))]
3625   "TARGET_SH1"
3626   "#"
3627   [(set (attr "length")
3628         (cond [(match_test "shift_insns_rtx (insn)")
3629                (const_string "2")
3630                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3631                (const_string "4")]
3632               (const_string "6")))
3633    (set_attr "type" "arith")])
3635 (define_expand "ashlhi3"
3636   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3637                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3638                               (match_operand:SI 2 "nonmemory_operand" "")))
3639               (clobber (reg:SI T_REG))])]
3640   "TARGET_SH1"
3642   if (!CONST_INT_P (operands[2]))
3643     FAIL;
3644   /* It may be possible to call gen_ashlhi3 directly with more generic
3645      operands.  Make sure operands[1] is a HImode register here.  */
3646   if (!arith_reg_operand (operands[1], HImode))
3647     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3650 (define_split
3651   [(set (match_operand:HI 0 "arith_reg_dest" "")
3652         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3653                    (match_operand:HI 2 "const_int_operand" "")))
3654    (clobber (reg:SI T_REG))]
3655   "TARGET_SH1 && reload_completed"
3656   [(use (reg:SI R0_REG))]
3658   gen_shifty_hi_op (ASHIFT, operands);
3659   DONE;
3663 ;; arithmetic shift right
3666 (define_insn "ashrsi3_k"
3667   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3668         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3669                      (match_operand:SI 2 "const_int_operand" "M")))
3670    (clobber (reg:SI T_REG))]
3671   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3672   "shar %0"
3673   [(set_attr "type" "arith")])
3675 ;; We can't do HImode right shifts correctly unless we start out with an
3676 ;; explicit zero / sign extension; doing that would result in worse overall
3677 ;; code, so just let the machine independent code widen the mode.
3678 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3681 ;; ??? This should be a define expand.
3683 (define_insn "ashrsi2_16"
3684   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3685         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3686                      (const_int 16)))]
3687   "TARGET_SH1"
3688   "#"
3689   [(set_attr "length" "4")])
3691 (define_split
3692   [(set (match_operand:SI 0 "arith_reg_dest" "")
3693         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3694                      (const_int 16)))]
3695   "TARGET_SH1"
3696   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3697    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3699   operands[2] = gen_lowpart (HImode, operands[0]);
3702 ;; ??? This should be a define expand.
3704 (define_insn "ashrsi2_31"
3705   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3706         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3707                      (const_int 31)))
3708    (clobber (reg:SI T_REG))]
3709   "TARGET_SH1"
3710   "#"
3711   [(set_attr "length" "4")])
3713 (define_split
3714   [(set (match_operand:SI 0 "arith_reg_dest" "")
3715         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3716                      (const_int 31)))
3717    (clobber (reg:SI T_REG))]
3718   "TARGET_SH1"
3719   [(const_int 0)]
3721   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3722   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3723   DONE;
3726 (define_peephole2
3727   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3728    (set (reg:SI T_REG)
3729         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3730   "TARGET_SH1
3731    && peep2_reg_dead_p (2, operands[0])
3732    && peep2_reg_dead_p (2, operands[1])"
3733   [(const_int 0)]
3735   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3736   DONE;
3739 (define_insn "ashlsi_c"
3740   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3741         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3742    (set (reg:SI T_REG)
3743         (lt:SI (match_dup 1) (const_int 0)))]
3744   "TARGET_SH1"
3745   "shll %0"
3746   [(set_attr "type" "arith")])
3748 (define_insn "*ashlsi_c_void"
3749   [(set (reg:SI T_REG)
3750         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3751    (clobber (match_scratch:SI 1 "=0"))]
3752   "TARGET_SH1 && cse_not_expected"
3753   "shll %0"
3754   [(set_attr "type" "arith")])
3756 (define_insn "ashrsi3_d"
3757   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3758         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3759                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3760   "TARGET_SH3 || TARGET_SH2A"
3761   "shad %2,%0"
3762   [(set_attr "type" "dyn_shift")])
3764 (define_insn "ashrsi3_n"
3765   [(set (reg:SI R4_REG)
3766         (ashiftrt:SI (reg:SI R4_REG)
3767                      (match_operand:SI 0 "const_int_operand" "i")))
3768    (clobber (reg:SI T_REG))
3769    (clobber (reg:SI PR_REG))
3770    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3771   "TARGET_SH1"
3772   "jsr  @%1%#"
3773   [(set_attr "type" "sfunc")
3774    (set_attr "needs_delay_slot" "yes")])
3776 (define_insn "ashrsi3_media"
3777   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3778         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3779                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3780   "TARGET_SHMEDIA"
3781   "@
3782         shard.l %1, %2, %0
3783         shari.l %1, %2, %0"
3784   [(set_attr "type" "arith_media")
3785    (set_attr "highpart" "ignore")])
3787 (define_expand "ashrsi3"
3788   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3789                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3790                                 (match_operand:SI 2 "nonmemory_operand" "")))
3791               (clobber (reg:SI T_REG))])]
3792   ""
3794   if (TARGET_SHMEDIA)
3795     {
3796       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3797       DONE;
3798     }
3799   if (expand_ashiftrt (operands))
3800     DONE;
3801   else
3802     FAIL;
3805 ;; logical shift right
3807 (define_insn "lshrsi3_d"
3808   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3809         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3810                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3811   "TARGET_SH3 || TARGET_SH2A"
3812   "shld %2,%0"
3813   [(set_attr "type" "dyn_shift")])
3815 ;;  Only the single bit shift clobbers the T bit.
3817 (define_insn "lshrsi3_m"
3818   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3819         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3820                      (match_operand:SI 2 "const_int_operand" "M")))
3821    (clobber (reg:SI T_REG))]
3822   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3823   "shlr %0"
3824   [(set_attr "type" "arith")])
3826 (define_insn "lshrsi3_k"
3827   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3828         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3829                      (match_operand:SI 2 "const_int_operand" "P27")))]
3830   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3831    && ! satisfies_constraint_M (operands[2])"
3832   "shlr%O2      %0"
3833   [(set_attr "type" "arith")])
3835 (define_insn "lshrsi3_n"
3836   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3837         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3838                      (match_operand:SI 2 "const_int_operand" "n")))
3839    (clobber (reg:SI T_REG))]
3840   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3841   "#"
3842   [(set (attr "length")
3843         (cond [(match_test "shift_insns_rtx (insn)")
3844                (const_string "2")
3845                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3846                (const_string "4")
3847                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3848                (const_string "6")]
3849               (const_string "8")))
3850    (set_attr "type" "arith")])
3852 (define_split
3853   [(set (match_operand:SI 0 "arith_reg_dest" "")
3854         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3855                      (match_operand:SI 2 "const_int_operand" "")))
3856    (clobber (reg:SI T_REG))]
3857   "TARGET_SH1 && reload_completed"
3858   [(use (reg:SI R0_REG))]
3860   gen_shifty_op (LSHIFTRT, operands);
3861   DONE;
3864 (define_insn "lshrsi3_media"
3865   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3866         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3867                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3868   "TARGET_SHMEDIA"
3869   "@
3870         shlrd.l %1, %2, %0
3871         shlri.l %1, %2, %0"
3872   [(set_attr "type" "arith_media")
3873    (set_attr "highpart" "ignore")])
3875 (define_expand "lshrsi3"
3876   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3877                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3878                                 (match_operand:SI 2 "nonmemory_operand" "")))
3879               (clobber (reg:SI T_REG))])]
3880   ""
3882   if (TARGET_SHMEDIA)
3883     {
3884       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3885       DONE;
3886     }
3887   if (CONST_INT_P (operands[2])
3888       && sh_dynamicalize_shift_p (operands[2]))
3889     operands[2] = force_reg (SImode, operands[2]);
3890   if ((TARGET_SH3 || TARGET_SH2A)
3891       && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3892     {
3893       rtx count = copy_to_mode_reg (SImode, operands[2]);
3894       emit_insn (gen_negsi2 (count, count));
3895       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3896       DONE;
3897     }
3898   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3899     FAIL;
3902 ;; ??? This should be a define expand.
3904 (define_insn "ashldi3_k"
3905   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3906         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3907                    (const_int 1)))
3908    (clobber (reg:SI T_REG))]
3909   "TARGET_SH1"
3910   "shll %R0\;rotcl      %S0"
3911   [(set_attr "length" "4")
3912    (set_attr "type" "arith")])
3914 ;; Expander for DImode shift left with SImode operations.
3916 (define_expand "ashldi3_std"
3917   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3918         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3919                    (match_operand:DI 2 "const_int_operand" "n")))]
3920   "TARGET_SH1 && INTVAL (operands[2]) < 32"
3922   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3923   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3924   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3925   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3926   rtx dst = gen_reg_rtx (DImode);
3927   rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3928   rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3929   rtx tmp0, tmp1;
3931   tmp0 = gen_reg_rtx (SImode);
3932   tmp1 = gen_reg_rtx (SImode);
3933   emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3934   emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));  
3935   emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));  
3936   emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3937   emit_move_insn (operands[0], dst);
3938   DONE;
3941 (define_insn "ashldi3_media"
3942   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3943         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3944                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3945   "TARGET_SHMEDIA"
3946   "@
3947         shlld   %1, %2, %0
3948         shlli   %1, %2, %0"
3949   [(set_attr "type" "arith_media")])
3951 (define_insn "*ashldisi3_media"
3952   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3953         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3954                    (match_operand:DI 2 "const_int_operand" "n")))]
3955   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3956   "shlli.l      %1, %2, %0"
3957   [(set_attr "type" "arith_media")
3958    (set_attr "highpart" "ignore")])
3960 (define_expand "ashldi3"
3961   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3962                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3963                               (match_operand:DI 2 "immediate_operand" "")))
3964               (clobber (reg:SI T_REG))])]
3965   ""
3967   if (TARGET_SHMEDIA)
3968     {
3969       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3970       DONE;
3971     }
3972   if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
3973     {
3974       emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3975       DONE;
3976     }
3977   else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 32)
3978     {
3979       emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3980       DONE;
3981     }
3982   else
3983     FAIL;
3986 ;; ??? This should be a define expand.
3988 (define_insn "lshrdi3_k"
3989   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3990         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3991                      (const_int 1)))
3992    (clobber (reg:SI T_REG))]
3993   "TARGET_SH1"
3994   "shlr %S0\;rotcr      %R0"
3995   [(set_attr "length" "4")
3996    (set_attr "type" "arith")])
3998 (define_insn "lshrdi3_media"
3999   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4000         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4001                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4002   "TARGET_SHMEDIA
4003    && (arith_reg_dest (operands[0], DImode)
4004        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
4005   "@
4006         shlrd   %1, %2, %0
4007         shlri   %1, %2, %0"
4008   [(set_attr "type" "arith_media")])
4010 (define_insn "*lshrdisi3_media"
4011   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4012         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4013                      (match_operand:DI 2 "const_int_operand" "n")))]
4014   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4015   "shlri.l      %1, %2, %0"
4016   [(set_attr "type" "arith_media")
4017    (set_attr "highpart" "ignore")])
4019 (define_expand "lshrdi3"
4020   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4021                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4022                                (match_operand:DI 2 "immediate_operand" "")))
4023              (clobber (reg:SI T_REG))])]
4024   ""
4026   if (TARGET_SHMEDIA)
4027     {
4028       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4029       DONE;
4030     }
4031   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4032     FAIL;
4035 ;; ??? This should be a define expand.
4037 (define_insn "ashrdi3_k"
4038   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4039         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4040                      (const_int 1)))
4041    (clobber (reg:SI T_REG))]
4042   "TARGET_SH1"
4043   "shar %S0\;rotcr      %R0"
4044   [(set_attr "length" "4")
4045    (set_attr "type" "arith")])
4047 (define_insn "ashrdi3_media"
4048   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4049         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4050                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4051   "TARGET_SHMEDIA
4052    && (arith_reg_dest (operands[0], DImode)
4053        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4054   "@
4055         shard   %1, %2, %0
4056         shari   %1, %2, %0"
4057   [(set_attr "type" "arith_media")])
4059 (define_insn "*ashrdisi3_media"
4060   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4061         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4062                      (match_operand:DI 2 "const_int_operand" "n")))]
4063   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4064   "shari.l      %1, %2, %0"
4065   [(set_attr "type" "arith_media")
4066    (set_attr "highpart" "ignore")])
4068 (define_insn "ashrdisi3_media_high"
4069   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4070         (truncate:SI
4071            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4072                         (match_operand:DI 2 "const_int_operand" "n"))))]
4073   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4074   "shari        %1, %2, %0"
4075   [(set_attr "type" "arith_media")])
4077 (define_insn "ashrdisi3_media_opaque"
4078   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4079         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4080                     (match_operand:DI 2 "const_int_operand" "n")]
4081          UNSPEC_ASHIFTRT))]
4082   "TARGET_SHMEDIA"
4083   "shari        %1, %2, %0"
4084   [(set_attr "type" "arith_media")])
4086 (define_expand "ashrdi3"
4087   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4088                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4089                                 (match_operand:DI 2 "immediate_operand" "")))
4090               (clobber (reg:SI T_REG))])]
4091   ""
4093   if (TARGET_SHMEDIA)
4094     {
4095       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4096       DONE;
4097     }
4098   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 1)
4099     FAIL;
4102 ;; combined left/right shift
4104 (define_split
4105   [(set (match_operand:SI 0 "register_operand" "")
4106         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4107                            (match_operand:SI 2 "const_int_operand" ""))
4108                 (match_operand:SI 3 "const_int_operand" "")))]
4109   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4110   [(use (reg:SI R0_REG))]
4112   if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
4113     FAIL;
4114   DONE;
4117 (define_split
4118   [(set (match_operand:SI 0 "register_operand" "")
4119         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4120                            (match_operand:SI 2 "const_int_operand" ""))
4121                 (match_operand:SI 3 "const_int_operand" "")))
4122    (clobber (reg:SI T_REG))]
4123   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4124   [(use (reg:SI R0_REG))]
4126   if (gen_shl_and (operands[0], operands[2], operands[3], operands[1]))
4127     FAIL;
4128   DONE;
4131 (define_insn ""
4132   [(set (match_operand:SI 0 "register_operand" "=r")
4133         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4134                            (match_operand:SI 2 "const_int_operand" "n"))
4135                 (match_operand:SI 3 "const_int_operand" "n")))
4136    (clobber (reg:SI T_REG))]
4137   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4138   "#"
4139   [(set (attr "length")
4140         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4141                (const_string "4")
4142                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4143                (const_string "6")
4144                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4145                (const_string "8")
4146                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4147                (const_string "10")
4148                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4149                (const_string "12")
4150                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4151                (const_string "14")
4152                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4153                (const_string "16")]
4154               (const_string "18")))
4155    (set_attr "type" "arith")])
4157 (define_insn ""
4158   [(set (match_operand:SI 0 "register_operand" "=z")
4159         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4160                            (match_operand:SI 2 "const_int_operand" "n"))
4161                 (match_operand:SI 3 "const_int_operand" "n")))
4162    (clobber (reg:SI T_REG))]
4163   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4164   "#"
4165   [(set (attr "length")
4166         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4167                (const_string "4")
4168                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4169                (const_string "6")
4170                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4171                (const_string "8")]
4172               (const_string "10")))
4173    (set_attr "type" "arith")])
4175 ;; shift left / and combination with a scratch register: The combine pass
4176 ;; does not accept the individual instructions, even though they are
4177 ;; cheap.  But it needs a precise description so that it is usable after
4178 ;; reload.
4179 (define_insn "and_shl_scratch"
4180   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4181         (lshiftrt:SI
4182          (ashift:SI
4183           (and:SI
4184            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4185                         (match_operand:SI 2 "const_int_operand" "N,n"))
4186            (match_operand:SI 3 "" "0,r"))
4187           (match_operand:SI 4 "const_int_operand" "n,n"))
4188          (match_operand:SI 5 "const_int_operand" "n,n")))
4189    (clobber (reg:SI T_REG))]
4190   "TARGET_SH1"
4191   "#"
4192   [(set (attr "length")
4193         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4194                (const_string "4")
4195                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4196                (const_string "6")
4197                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4198                (const_string "8")
4199                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4200                (const_string "10")]
4201               (const_string "12")))
4202    (set_attr "type" "arith")])
4204 (define_split
4205   [(set (match_operand:SI 0 "register_operand" "")
4206         (lshiftrt:SI
4207          (ashift:SI
4208           (and:SI
4209            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4210                         (match_operand:SI 2 "const_int_operand" ""))
4211            (match_operand:SI 3 "register_operand" ""))
4212           (match_operand:SI 4 "const_int_operand" ""))
4213          (match_operand:SI 5 "const_int_operand" "")))
4214    (clobber (reg:SI T_REG))]
4215   "TARGET_SH1"
4216   [(use (reg:SI R0_REG))]
4218   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4220   if (INTVAL (operands[2]))
4221     {
4222       gen_shifty_op (LSHIFTRT, operands);
4223     }
4224   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4225   operands[2] = operands[4];
4226   gen_shifty_op (ASHIFT, operands);
4227   if (INTVAL (operands[5]))
4228     {
4229       operands[2] = operands[5];
4230       gen_shifty_op (LSHIFTRT, operands);
4231     }
4232   DONE;
4235 ;; signed left/right shift combination.
4236 (define_split
4237   [(set (match_operand:SI 0 "register_operand" "")
4238         (sign_extract:SI
4239          (ashift:SI (match_operand:SI 1 "register_operand" "")
4240                     (match_operand:SI 2 "const_int_operand" ""))
4241          (match_operand:SI 3 "const_int_operand" "")
4242          (const_int 0)))
4243    (clobber (reg:SI T_REG))]
4244   "TARGET_SH1"
4245   [(use (reg:SI R0_REG))]
4247   if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1]))
4248     FAIL;
4249   DONE;
4252 (define_insn "shl_sext_ext"
4253   [(set (match_operand:SI 0 "register_operand" "=r")
4254         (sign_extract:SI
4255          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4256                     (match_operand:SI 2 "const_int_operand" "n"))
4257          (match_operand:SI 3 "const_int_operand" "n")
4258          (const_int 0)))
4259    (clobber (reg:SI T_REG))]
4260   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4261   "#"
4262   [(set (attr "length")
4263         (cond [(match_test "shl_sext_length (insn)")
4264                (const_string "2")
4265                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4266                (const_string "4")
4267                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4268                (const_string "6")
4269                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4270                (const_string "8")
4271                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4272                (const_string "10")
4273                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4274                (const_string "12")
4275                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4276                (const_string "14")
4277                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4278                (const_string "16")]
4279               (const_string "18")))
4280     (set_attr "type" "arith")])
4282 (define_insn "shl_sext_sub"
4283   [(set (match_operand:SI 0 "register_operand" "=z")
4284         (sign_extract:SI
4285          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4286                     (match_operand:SI 2 "const_int_operand" "n"))
4287          (match_operand:SI 3 "const_int_operand" "n")
4288          (const_int 0)))
4289    (clobber (reg:SI T_REG))]
4290   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4291   "#"
4292   [(set (attr "length")
4293         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4294                (const_string "6")
4295                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4296                (const_string "8")
4297                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4298                (const_string "10")
4299                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4300                (const_string "12")]
4301               (const_string "14")))
4302     (set_attr "type" "arith")])
4304 ;; These patterns are found in expansions of DImode shifts by 16, and
4305 ;; allow the xtrct instruction to be generated from C source.
4307 (define_insn "xtrct_left"
4308   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4309         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4310                            (const_int 16))
4311                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4312                              (const_int 16))))]
4313   "TARGET_SH1"
4314   "xtrct        %1,%0"
4315   [(set_attr "type" "arith")])
4317 (define_insn "xtrct_right"
4318   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4319         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4320                              (const_int 16))
4321                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4322                            (const_int 16))))]
4323   "TARGET_SH1"
4324   "xtrct        %2,%0"
4325   [(set_attr "type" "arith")])
4327 ;; -------------------------------------------------------------------------
4328 ;; Unary arithmetic
4329 ;; -------------------------------------------------------------------------
4331 (define_expand "negc"
4332   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
4333         (neg:SI (plus:SI (reg:SI T_REG)
4334                          (match_operand:SI 1 "arith_reg_operand" ""))))
4335    (set (reg:SI T_REG)
4336         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4337                (const_int 0)))])]
4338   ""
4339   "")
4341 (define_insn "*negc"
4342   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4343         (neg:SI (plus:SI (reg:SI T_REG)
4344                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4345    (set (reg:SI T_REG)
4346         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4347                (const_int 0)))]
4348   "TARGET_SH1"
4349   "negc %1,%0"
4350   [(set_attr "type" "arith")])
4352 (define_insn "*negdi_media"
4353   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4354         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4355   "TARGET_SHMEDIA"
4356   "sub  r63, %1, %0"
4357   [(set_attr "type" "arith_media")])
4359 ;; Don't expand immediately because otherwise neg:DI (abs:DI) will not be
4360 ;; combined.
4361 (define_expand "negdi2"
4362   [(set (match_operand:DI 0 "arith_reg_dest" "")
4363         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))
4364    (clobber (reg:SI T_REG))]
4365   "TARGET_SH1"
4366   "")
4368 (define_insn_and_split "*negdi2"
4369   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4370         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4371   "TARGET_SH1"
4372   "#"
4373   "TARGET_SH1"
4374   [(const_int 0)]
4376   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4377   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4379   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4380   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4382   rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4383   rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4385   emit_insn (gen_clrt ());
4386   emit_insn (gen_negc (low_dst, low_src));
4387   emit_insn (gen_negc (high_dst, high_src));
4388   DONE;
4391 (define_insn "negsi2"
4392   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4393         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4394   "TARGET_SH1"
4395   "neg  %1,%0"
4396   [(set_attr "type" "arith")])
4398 (define_insn "one_cmplsi2"
4399   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4400         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4401   "TARGET_SH1"
4402   "not  %1,%0"
4403   [(set_attr "type" "arith")])
4405 (define_expand "one_cmpldi2"
4406   [(set (match_operand:DI 0 "arith_reg_dest" "")
4407         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4408                 (const_int -1)))]
4409   "TARGET_SHMEDIA" "")
4411 (define_expand "abssi2"
4412   [(set (match_operand:SI 0 "arith_reg_dest" "")
4413         (abs:SI (match_operand:SI 1 "arith_reg_operand" "")))
4414    (clobber (reg:SI T_REG))]
4415   "TARGET_SH1"
4416   "")
4418 (define_insn_and_split "*abssi2"
4419   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4420         (abs:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4421   "TARGET_SH1"
4422   "#"
4423   "TARGET_SH1"
4424   [(const_int 0)]
4426   emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4427   emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4428                  const1_rtx));
4429   DONE;
4432 (define_insn_and_split "*negabssi2"
4433   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4434         (neg:SI (abs:SI (match_operand:SI 1 "arith_reg_operand" "r"))))]
4435   "TARGET_SH1"
4436   "#"
4437   "TARGET_SH1"
4438   [(const_int 0)]
4440   emit_insn (gen_cmpgesi_t (operands[1], const0_rtx));
4441   emit_insn (gen_negsi_cond (operands[0], operands[1], operands[1],
4442                  const0_rtx));
4443   DONE;
4446 ;; The SH4 202 can do zero-offset branches without pipeline stalls.
4447 ;; This can be used as some kind of conditional execution, which is useful
4448 ;; for abs.
4449 ;; Actually the instruction scheduling should decide whether to use a
4450 ;; zero-offset branch or not for any generic case involving a single
4451 ;; instruction on SH4 202.
4453 (define_insn_and_split "negsi_cond"
4454   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4455         (if_then_else:SI (eq:SI (reg:SI T_REG)
4456                           (match_operand:SI 3 "const_int_operand" "M,N"))
4457          (match_operand:SI 1 "arith_reg_operand" "0,0")
4458          (neg:SI (match_operand:SI 2 "arith_reg_operand" "r,r"))))]
4459   "TARGET_HARD_SH4"
4460   "@
4461         bt\\t0f\;neg\\t%2,%0\\n0:
4462         bf\\t0f\;neg\\t%2,%0\\n0:"
4463   "!TARGET_HARD_SH4"
4464   [(const_int 0)]
4466   rtx skip_neg_label = gen_label_rtx ();
4468   emit_insn (gen_movsi (operands[0], operands[1]));
4470   emit_jump_insn (INTVAL (operands[3])
4471                   ? gen_branch_true (skip_neg_label)
4472                   : gen_branch_false (skip_neg_label));
4474   emit_label_after (skip_neg_label,
4475                     emit_insn (gen_negsi2 (operands[0], operands[1])));
4476   DONE;
4478   [(set_attr "type" "arith") ;; poor approximation
4479    (set_attr "length" "4")])
4481 (define_expand "absdi2"
4482   [(set (match_operand:DI 0 "arith_reg_dest" "")
4483         (abs:DI (match_operand:DI 1 "arith_reg_operand" "")))
4484    (clobber (reg:SI T_REG))]
4485   "TARGET_SH1"
4486   "")
4488 (define_insn_and_split "*absdi2"
4489   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4490         (abs:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4491   "TARGET_SH1"
4492   "#"
4493   "&& reload_completed"
4494   [(const_int 0)]
4496   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4497   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4498   emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
4499   emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
4500                              const1_rtx));
4501   DONE;
4504 (define_insn_and_split "*negabsdi2"
4505   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4506         (neg:DI (abs:DI (match_operand:DI 1 "arith_reg_operand" "r"))))]
4507   "TARGET_SH1"
4508   "#"
4509   "&& reload_completed"
4510   [(const_int 0)]
4512   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4513   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4515   emit_insn (gen_cmpgesi_t (high_src, const0_rtx));
4516   emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1],
4517                              const0_rtx));
4518   DONE;
4521 (define_insn_and_split "negdi_cond"
4522   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
4523         (if_then_else:DI (eq:SI (reg:SI T_REG)
4524                                 (match_operand:SI 3 "const_int_operand" "M,N"))
4525          (match_operand:DI 1 "arith_reg_operand" "r,r")
4526          (neg:DI (match_operand:DI 2 "arith_reg_operand" "1,1"))))]
4527   "TARGET_SH1"
4528   "#"
4529   "TARGET_SH1"
4530   [(const_int 0)]
4532   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4533   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4535   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4536   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4538   rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4539   rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4541   rtx skip_neg_label = gen_label_rtx ();
4543   emit_insn (gen_movsi (low_dst, low_src));
4544   emit_insn (gen_movsi (high_dst, high_src));
4546   emit_jump_insn (INTVAL (operands[3]) 
4547                   ? gen_branch_true (skip_neg_label)
4548                   : gen_branch_false (skip_neg_label));
4550   if (!INTVAL (operands[3]))
4551     emit_insn (gen_clrt ());
4553   emit_insn (gen_negc (low_dst, low_src));
4554   emit_label_after (skip_neg_label, emit_insn (gen_negc (high_dst, high_src)));
4555   DONE;
4558 ;; -------------------------------------------------------------------------
4559 ;; Zero extension instructions
4560 ;; -------------------------------------------------------------------------
4562 (define_insn "zero_extendsidi2"
4563   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4564         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4565   "TARGET_SHMEDIA"
4566   "addz.l       %1, r63, %0"
4567   [(set_attr "type" "arith_media")
4568    (set_attr "highpart" "extend")])
4570 (define_insn "zero_extendhidi2"
4571   [(set (match_operand:DI 0 "register_operand" "=r,r")
4572         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4573   "TARGET_SHMEDIA"
4574   "@
4575         #
4576         ld%M1.uw        %m1, %0"
4577   [(set_attr "type" "*,load_media")
4578    (set (attr "highpart")
4579         (cond [(match_test "sh_contains_memref_p (insn)")
4580                (const_string "user")]
4581               (const_string "ignore")))])
4583 (define_split
4584   [(set (match_operand:DI 0 "register_operand" "")
4585         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4586   "TARGET_SHMEDIA && reload_completed"
4587   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4588    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4590   if (GET_CODE (operands[1]) == TRUNCATE)
4591     operands[1] = XEXP (operands[1], 0);
4594 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4595 ;; reload the entire truncate expression.
4596 (define_insn_and_split "*loaddi_trunc"
4597   [(set (match_operand 0 "any_register_operand" "=r")
4598         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4599   "TARGET_SHMEDIA && reload_completed"
4600   "#"
4601   "TARGET_SHMEDIA && reload_completed"
4602   [(set (match_dup 0) (match_dup 1))]
4604   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4607 (define_insn "zero_extendqidi2"
4608   [(set (match_operand:DI 0 "register_operand" "=r,r")
4609         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4610   "TARGET_SHMEDIA"
4611   "@
4612         andi    %1, 255, %0
4613         ld%M1.ub        %m1, %0"
4614   [(set_attr "type" "arith_media,load_media")
4615    (set (attr "highpart")
4616         (cond [(match_test "sh_contains_memref_p (insn)")
4617                (const_string "user")]
4618               (const_string "ignore")))])
4620 (define_expand "zero_extendhisi2"
4621   [(set (match_operand:SI 0 "arith_reg_operand" "")
4622         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4623   ""
4625   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4626     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4629 (define_insn "*zero_extendhisi2_compact"
4630   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4631         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4632   "TARGET_SH1"
4633   "extu.w       %1,%0"
4634   [(set_attr "type" "arith")])
4636 (define_insn "*zero_extendhisi2_media"
4637   [(set (match_operand:SI 0 "register_operand" "=r,r")
4638         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4639   "TARGET_SHMEDIA"
4640   "@
4641         #
4642         ld%M1.uw        %m1, %0"
4643   [(set_attr "type" "arith_media,load_media")
4644    (set (attr "highpart")
4645         (cond [(match_test "sh_contains_memref_p (insn)")
4646                (const_string "user")]
4647               (const_string "ignore")))])
4649 (define_split
4650   [(set (match_operand:SI 0 "register_operand" "")
4651         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4652   "TARGET_SHMEDIA && reload_completed"
4653   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4654    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4656   rtx op1 = operands[1];
4658   if (GET_CODE (op1) == TRUNCATE)
4659     op1 = XEXP (op1, 0);
4660   operands[2]
4661     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4662                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4665 (define_expand "zero_extendqisi2"
4666   [(set (match_operand:SI 0 "arith_reg_operand" "")
4667         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4668   ""
4670   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4671     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4674 (define_insn "*zero_extendqisi2_compact"
4675   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4676         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4677   "TARGET_SH1"
4678   "extu.b       %1,%0"
4679   [(set_attr "type" "arith")])
4681 (define_insn "*zero_extendqisi2_media"
4682   [(set (match_operand:SI 0 "register_operand" "=r,r")
4683         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4684   "TARGET_SHMEDIA"
4685   "@
4686         andi    %1, 255, %0
4687         ld%M1.ub        %m1, %0"
4688   [(set_attr "type" "arith_media,load_media")
4689    (set (attr "highpart")
4690         (cond [(match_test "sh_contains_memref_p (insn)")
4691                (const_string "user")]
4692               (const_string "ignore")))])
4694 (define_insn "zero_extendqihi2"
4695   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4696         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4697   "TARGET_SH1"
4698   "extu.b       %1,%0"
4699   [(set_attr "type" "arith")])
4701 ;; -------------------------------------------------------------------------
4702 ;; Sign extension instructions
4703 ;; -------------------------------------------------------------------------
4705 ;; ??? This should be a define expand.
4706 ;; ??? Or perhaps it should be dropped?
4708 ;; convert_move generates good code for SH[1-4].
4709 (define_insn "extendsidi2"
4710   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4711         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4712   "TARGET_SHMEDIA"
4713   "@
4714         add.l   %1, r63, %0
4715         ld%M1.l %m1, %0
4716         fmov.sl %1, %0"
4717   [(set_attr "type" "arith_media,load_media,fpconv_media")
4718    (set (attr "highpart")
4719         (cond [(match_test "sh_contains_memref_p (insn)")
4720                (const_string "user")]
4721               (const_string "extend")))])
4723 (define_insn "extendhidi2"
4724   [(set (match_operand:DI 0 "register_operand" "=r,r")
4725         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4726   "TARGET_SHMEDIA"
4727   "@
4728         #
4729         ld%M1.w %m1, %0"
4730   [(set_attr "type" "*,load_media")
4731    (set (attr "highpart")
4732         (cond [(match_test "sh_contains_memref_p (insn)")
4733                (const_string "user")]
4734               (const_string "ignore")))])
4736 (define_split
4737   [(set (match_operand:DI 0 "register_operand" "")
4738         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4739   "TARGET_SHMEDIA && reload_completed"
4740   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4741    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4743   if (GET_CODE (operands[1]) == TRUNCATE)
4744     operands[1] = XEXP (operands[1], 0);
4747 (define_insn "extendqidi2"
4748   [(set (match_operand:DI 0 "register_operand" "=r,r")
4749         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4750   "TARGET_SHMEDIA"
4751   "@
4752         #
4753         ld%M1.b %m1, %0"
4754   [(set_attr "type" "*,load_media")
4755    (set (attr "highpart")
4756         (cond [(match_test "sh_contains_memref_p (insn)")
4757                (const_string "user")]
4758               (const_string "ignore")))])
4760 (define_split
4761   [(set (match_operand:DI 0 "register_operand" "")
4762         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4763   "TARGET_SHMEDIA && reload_completed"
4764   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4765    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4767   if (GET_CODE (operands[1]) == TRUNCATE)
4768     operands[1] = XEXP (operands[1], 0);
4771 (define_expand "extendhisi2"
4772   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4773         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4774   ""
4775   "")
4777 (define_insn "*extendhisi2_compact"
4778   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4779         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4780   "TARGET_SH1"
4781   "@
4782         exts.w  %1,%0
4783         mov.w   %1,%0"
4784   [(set_attr "type" "arith,load")])
4786 (define_insn "*extendhisi2_media"
4787   [(set (match_operand:SI 0 "register_operand" "=r,r")
4788         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4789   "TARGET_SHMEDIA"
4790   "@
4791         #
4792         ld%M1.w %m1, %0"
4793   [(set_attr "type" "arith_media,load_media")
4794    (set (attr "highpart")
4795         (cond [(match_test "sh_contains_memref_p (insn)")
4796                (const_string "user")]
4797               (const_string "ignore")))])
4799 (define_split
4800   [(set (match_operand:SI 0 "register_operand" "")
4801         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4802   "TARGET_SHMEDIA && reload_completed"
4803   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4804    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4806   rtx op1 = operands[1];
4807   if (GET_CODE (op1) == TRUNCATE)
4808     op1 = XEXP (op1, 0);
4809   operands[2]
4810     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4811                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4814 (define_expand "extendqisi2"
4815   [(set (match_operand:SI 0 "arith_reg_dest" "")
4816         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4817   ""
4818   "")
4820 (define_insn "*extendqisi2_compact_reg"
4821   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4822         (sign_extend:SI (match_operand:QI 1 "register_operand" "r,t")))]
4823   "TARGET_SH1"
4824   "@
4825         exts.b  %1,%0
4826         movt    %0"
4827   [(set_attr "type" "arith,arith")])
4829 ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute.
4830 ;; See movqi insns.
4831 (define_insn "*extendqisi2_compact_mem_disp"
4832   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
4833         (sign_extend:SI
4834          (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
4835                           (match_operand:SI 2 "const_int_operand" "K04,N")))))]
4836   "TARGET_SH1 && ! TARGET_SH2A && CONST_OK_FOR_K04 (INTVAL (operands[2]))"
4837   "@
4838         mov.b   @(%O2,%1),%0
4839         mov.b   @%1,%0"
4840   [(set_attr "type" "load")])
4842 (define_insn "*extendqisi2_compact_mem_disp"
4843   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r")
4844         (sign_extend:SI
4845          (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
4846                           (match_operand:SI 2 "const_int_operand" "K04,N,K12")))))]
4847   "TARGET_SH2A
4848    && (CONST_OK_FOR_K04 (INTVAL (operands[2]))
4849        || (CONST_OK_FOR_K12 (INTVAL (operands[2]))))"
4850   "@
4851         mov.b   @(%O2,%1),%0
4852         mov.b   @%1,%0
4853         mov.b   @(%O2,%1),%0"
4854   [(set_attr "type" "load")
4855    (set_attr "length" "2,2,4")])
4857 ;; This will take care of other QImode addressing modes than displacement
4858 ;; addressing.
4859 (define_insn "*extendqisi2_compact_snd"
4860   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4861         (sign_extend:SI (match_operand:QI 1 "movsrc_no_disp_mem_operand" "Snd")))]
4862   "TARGET_SH1"
4863   "mov.b        %1,%0"
4864   [(set_attr "type" "load")])
4866 (define_insn "*extendqisi2_media"
4867   [(set (match_operand:SI 0 "register_operand" "=r,r")
4868         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4869   "TARGET_SHMEDIA"
4870   "@
4871         #
4872         ld%M1.b %m1, %0"
4873   [(set_attr "type" "arith_media,load_media")
4874    (set (attr "highpart")
4875         (cond [(match_test "sh_contains_memref_p (insn)")
4876                (const_string "user")]
4877               (const_string "ignore")))])
4879 (define_split
4880   [(set (match_operand:SI 0 "register_operand" "")
4881         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4882   "TARGET_SHMEDIA && reload_completed"
4883   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4884    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4886   rtx op1 = operands[1];
4887   if (GET_CODE (op1) == TRUNCATE)
4888     op1 = XEXP (op1, 0);
4889   operands[2]
4890     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4891                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4894 (define_expand "extendqihi2"
4895   [(set (match_operand:HI 0 "arith_reg_dest" "")
4896         (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "")))]
4897   ""
4898   "")
4900 (define_insn "*extendqihi2_compact_reg"
4901   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4902         (sign_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4903   "TARGET_SH1"
4904   "exts.b       %1,%0"
4905   [(set_attr "type" "arith")])
4907 ;; It would seem useful to combine the truncXi patterns into the movXi
4908 ;; patterns, but unary operators are ignored when matching constraints,
4909 ;; so we need separate patterns.
4910 (define_insn "truncdisi2"
4911   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4912         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4913   "TARGET_SHMEDIA"
4914   "@
4915         add.l   %1, r63, %0
4916         st%M0.l %m0, %1
4917         fst%M0.s        %m0, %T1
4918         fmov.ls %1, %0
4919         fmov.sl %T1, %0
4920         fmov.s  %T1, %0"
4921   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4922    (set (attr "highpart")
4923         (cond [(match_test "sh_contains_memref_p (insn)")
4924                (const_string "user")]
4925               (const_string "extend")))])
4927 (define_insn "truncdihi2"
4928   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4929         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4930   "TARGET_SHMEDIA"
4931   "@
4932         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4933         st%M0.w %m0, %1"
4934   [(set_attr "type"   "arith_media,store_media")
4935    (set_attr "length" "8,4")
4936    (set (attr "highpart")
4937         (cond [(match_test "sh_contains_memref_p (insn)")
4938                (const_string "user")]
4939               (const_string "extend")))])
4941 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4942 ; Because we use zero extension, we can't provide signed QImode compares
4943 ; using a simple compare or conditional branch insn.
4944 (define_insn "truncdiqi2"
4945   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4946         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4947   "TARGET_SHMEDIA"
4948   "@
4949         andi    %1, 255, %0
4950         st%M0.b %m0, %1"
4951   [(set_attr "type"   "arith_media,store")
4952    (set (attr "highpart")
4953         (cond [(match_test "sh_contains_memref_p (insn)")
4954                (const_string "user")]
4955               (const_string "extend")))])
4956 ;; -------------------------------------------------------------------------
4957 ;; Move instructions
4958 ;; -------------------------------------------------------------------------
4960 ;; define push and pop so it is easy for sh.c
4961 ;; We can't use push and pop on SHcompact because the stack must always
4962 ;; be 8-byte aligned.
4964 (define_expand "push"
4965   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4966         (match_operand:SI 0 "register_operand" "r,l,x"))]
4967   "TARGET_SH1 && ! TARGET_SH5"
4968   "")
4970 (define_expand "pop"
4971   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4972         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4973   "TARGET_SH1 && ! TARGET_SH5"
4974   "")
4976 (define_expand "push_e"
4977   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4978                    (match_operand:SF 0 "" ""))
4979               (use (reg:PSI FPSCR_REG))
4980               (clobber (scratch:SI))])]
4981   "TARGET_SH1 && ! TARGET_SH5"
4982   "")
4984 (define_insn "push_fpul"
4985   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4986   "TARGET_SH2E && ! TARGET_SH5"
4987   "sts.l        fpul,@-r15"
4988   [(set_attr "type" "fstore")
4989    (set_attr "late_fp_use" "yes")
4990    (set_attr "hit_stack" "yes")])
4992 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4993 ;; so use that.
4994 (define_expand "push_4"
4995   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4996                    (match_operand:DF 0 "" ""))
4997               (use (reg:PSI FPSCR_REG))
4998               (clobber (scratch:SI))])]
4999   "TARGET_SH1 && ! TARGET_SH5"
5000   "")
5002 (define_expand "pop_e"
5003   [(parallel [(set (match_operand:SF 0 "" "")
5004               (mem:SF (post_inc:SI (reg:SI SP_REG))))
5005               (use (reg:PSI FPSCR_REG))
5006               (clobber (scratch:SI))])]
5007   "TARGET_SH1 && ! TARGET_SH5"
5008   "")
5010 (define_insn "pop_fpul"
5011   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
5012   "TARGET_SH2E && ! TARGET_SH5"
5013   "lds.l        @r15+,fpul"
5014   [(set_attr "type" "load")
5015    (set_attr "hit_stack" "yes")])
5017 (define_expand "pop_4"
5018   [(parallel [(set (match_operand:DF 0 "" "")
5019                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
5020               (use (reg:PSI FPSCR_REG))
5021               (clobber (scratch:SI))])]
5022   "TARGET_SH1 && ! TARGET_SH5"
5023   "")
5025 (define_expand "push_fpscr"
5026   [(const_int 0)]
5027   "TARGET_SH2E"
5029   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
5030                                                  gen_rtx_PRE_DEC (Pmode,
5031                                                           stack_pointer_rtx)),
5032                                         get_fpscr_rtx ()));
5033   add_reg_note (insn, REG_INC, stack_pointer_rtx);
5034   DONE;
5037 (define_expand "pop_fpscr"
5038   [(const_int 0)]
5039   "TARGET_SH2E"
5041   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
5042                                         gen_frame_mem (PSImode,
5043                                                  gen_rtx_POST_INC (Pmode,
5044                                                           stack_pointer_rtx))));
5045   add_reg_note (insn, REG_INC, stack_pointer_rtx);
5046   DONE;
5049 ;; These two patterns can happen as the result of optimization, when
5050 ;; comparisons get simplified to a move of zero or 1 into the T reg.
5051 ;; They don't disappear completely, because the T reg is a fixed hard reg.
5053 (define_insn "clrt"
5054   [(set (reg:SI T_REG) (const_int 0))]
5055   "TARGET_SH1"
5056   "clrt")
5058 (define_insn "sett"
5059   [(set (reg:SI T_REG) (const_int 1))]
5060   "TARGET_SH1"
5061   "sett")
5063 ;; Define additional pop for SH1 and SH2 so it does not get 
5064 ;; placed in the delay slot.
5065 (define_insn "*movsi_pop"
5066   [(set (match_operand:SI 0 "register_operand" "=r,x,l")
5067         (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
5068   "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
5069    && ! TARGET_SH3"
5070   "@
5071    mov.l   %1,%0
5072    lds.l   %1,%0
5073    lds.l   %1,%0"
5074   [(set_attr "type" "load_si,mem_mac,pload")
5075    (set_attr "length" "2,2,2")
5076    (set_attr "in_delay_slot" "no,no,no")])
5078 ;; t/r must come after r/r, lest reload will try to reload stuff like
5079 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
5080 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
5081 (define_insn "movsi_i"
5082   [(set (match_operand:SI 0 "general_movdst_operand"
5083             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
5084         (match_operand:SI 1 "general_movsrc_operand"
5085          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
5086   "TARGET_SH1
5087    && ! TARGET_SH2E
5088    && ! TARGET_SH2A
5089    && (register_operand (operands[0], SImode)
5090        || register_operand (operands[1], SImode))"
5091   "@
5092         mov.l   %1,%0
5093         mov     %1,%0
5094         mov     %1,%0
5095         cmp/pl  %1
5096         mov.l   %1,%0
5097         sts     %1,%0
5098         sts     %1,%0
5099         movt    %0
5100         mov.l   %1,%0
5101         sts.l   %1,%0
5102         sts.l   %1,%0
5103         lds     %1,%0
5104         lds     %1,%0
5105         lds.l   %1,%0
5106         lds.l   %1,%0
5107         fake    %1,%0"
5108   [(set_attr "type" "pcload_si,move,movi8,mt_group,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
5109    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
5111 ;; t/r must come after r/r, lest reload will try to reload stuff like
5112 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
5113 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
5114 ;; will require a reload.
5115 ;; ??? We can't include f/f because we need the proper FPSCR setting when
5116 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
5117 (define_insn "movsi_ie"
5118   [(set (match_operand:SI 0 "general_movdst_operand"
5119             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
5120         (match_operand:SI 1 "general_movsrc_operand"
5121          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
5122   "(TARGET_SH2E || TARGET_SH2A)
5123    && (register_operand (operands[0], SImode)
5124        || register_operand (operands[1], SImode))"
5125   "@
5126         mov.l   %1,%0
5127         mov     %1,%0
5128         mov     %1,%0
5129         movi20  %1,%0
5130         movi20s %1,%0
5131         cmp/pl  %1
5132         mov.l   %1,%0
5133         sts     %1,%0
5134         sts     %1,%0
5135         movt    %0
5136         mov.l   %1,%0
5137         sts.l   %1,%0
5138         sts.l   %1,%0
5139         lds     %1,%0
5140         lds     %1,%0
5141         lds.l   %1,%0
5142         lds.l   %1,%0
5143         lds.l   %1,%0
5144         sts.l   %1,%0
5145         fake    %1,%0
5146         lds     %1,%0
5147         sts     %1,%0
5148         fsts    fpul,%0
5149         flds    %1,fpul
5150         fmov    %1,%0
5151         ! move optimized away"
5152   [(set_attr "type" "pcload_si,move,movi8,move,move,*,load_si,mac_gp,prget,arith,store,mac_mem,pstore,gp_mac,prset,mem_mac,pload,load,fstore,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
5153    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5154    (set_attr_alternative "length"
5155      [(const_int 2)
5156       (const_int 2)
5157       (const_int 2)
5158       (const_int 4)
5159       (const_int 4)
5160       (const_int 2)
5161       (if_then_else
5162         (match_test "TARGET_SH2A")
5163         (const_int 4) (const_int 2))
5164       (const_int 2)
5165       (const_int 2)
5166       (const_int 2)
5167       (if_then_else
5168         (match_test "TARGET_SH2A")
5169         (const_int 4) (const_int 2))
5170       (const_int 2)
5171       (const_int 2)
5172       (const_int 2)
5173       (const_int 2)
5174       (const_int 2)
5175       (const_int 2)
5176       (const_int 2)
5177       (const_int 2)
5178       (const_int 2)
5179       (const_int 2)
5180       (const_int 2)
5181       (const_int 2)
5182       (const_int 2)
5183       (const_int 2)
5184       (const_int 0)])])
5186 (define_insn "movsi_i_lowpart"
5187   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5188         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5189    "TARGET_SH1
5190     && (register_operand (operands[0], SImode)
5191         || register_operand (operands[1], SImode))"
5192   "@
5193         mov.l   %1,%0
5194         mov     %1,%0
5195         mov     %1,%0
5196         mov.l   %1,%0
5197         sts     %1,%0
5198         sts     %1,%0
5199         movt    %0
5200         mov.l   %1,%0
5201         fake    %1,%0"
5202   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5204 (define_insn_and_split "load_ra"
5205   [(set (match_operand:SI 0 "general_movdst_operand" "")
5206         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5207   "TARGET_SH1"
5208   "#"
5209   "&& ! currently_expanding_to_rtl"
5210   [(set (match_dup 0) (match_dup 1))]
5212   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5213     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5216 ;; The '?'s in the following constraints may not reflect the time taken
5217 ;; to perform the move. They are there to discourage the use of floating-
5218 ;; point registers for storing integer values.
5219 (define_insn "*movsi_media"
5220   [(set (match_operand:SI 0 "general_movdst_operand"
5221                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5222         (match_operand:SI 1 "general_movsrc_operand"
5223          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5224   "TARGET_SHMEDIA_FPU
5225    && (register_operand (operands[0], SImode)
5226        || sh_register_operand (operands[1], SImode)
5227        || GET_CODE (operands[1]) == TRUNCATE)"
5228   "@
5229         add.l   %1, r63, %0
5230         movi    %1, %0
5231         #
5232         ld%M1.l %m1, %0
5233         st%M0.l %m0, %N1
5234         fld%M1.s        %m1, %0
5235         fst%M0.s        %m0, %1
5236         fmov.ls %N1, %0
5237         fmov.sl %1, %0
5238         fmov.s  %1, %0
5239         ptabs   %1, %0
5240         gettr   %1, %0
5241         pt      %1, %0"
5242   [(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")
5243    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5244    (set (attr "highpart")
5245         (cond [(match_test "sh_contains_memref_p (insn)")
5246                (const_string "user")]
5247               (const_string "ignore")))])
5249 (define_insn "*movsi_media_nofpu"
5250   [(set (match_operand:SI 0 "general_movdst_operand"
5251                 "=r,r,r,r,m,*b,r,*b")
5252         (match_operand:SI 1 "general_movsrc_operand"
5253          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5254   "TARGET_SHMEDIA
5255    && (register_operand (operands[0], SImode)
5256        || sh_register_operand (operands[1], SImode)
5257        || GET_CODE (operands[1]) == TRUNCATE)"
5258   "@
5259         add.l   %1, r63, %0
5260         movi    %1, %0
5261         #
5262         ld%M1.l %m1, %0
5263         st%M0.l %m0, %N1
5264         ptabs   %1, %0
5265         gettr   %1, %0
5266         pt      %1, %0"
5267   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5268    (set_attr "length" "4,4,8,4,4,4,4,12")
5269    (set (attr "highpart")
5270         (cond [(match_test "sh_contains_memref_p (insn)")
5271                (const_string "user")]
5272               (const_string "ignore")))])
5274 (define_expand "movsi_const"
5275   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5276         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5277                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5278    (set (match_dup 0)
5279         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5280                 (const:SI (unspec:SI [(match_dup 1)
5281                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5282   "TARGET_SHMEDIA && reload_completed
5283    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5285   if (GET_CODE (operands[1]) == LABEL_REF
5286       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5287     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5288   else if (GOTOFF_P (operands[1]))
5289     {
5290       rtx unspec = XEXP (operands[1], 0);
5292       if (! UNSPEC_GOTOFF_P (unspec))
5293         {
5294           unspec = XEXP (unspec, 0);
5295           if (! UNSPEC_GOTOFF_P (unspec))
5296             abort ();
5297         }
5298       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5299           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5300         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5301     }
5304 (define_expand "movsi_const_16bit"
5305   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5306         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5307                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5308   "TARGET_SHMEDIA && flag_pic && reload_completed
5309    && GET_CODE (operands[1]) == SYMBOL_REF"
5310   "")
5312 (define_split
5313   [(set (match_operand:SI 0 "arith_reg_dest" "")
5314         (match_operand:SI 1 "immediate_operand" ""))]
5315   "TARGET_SHMEDIA && reload_completed
5316    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5317   [(const_int 0)]
5319   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5321   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5323   DONE;
5326 (define_split
5327   [(set (match_operand:SI 0 "register_operand" "")
5328         (match_operand:SI 1 "immediate_operand" ""))]
5329   "TARGET_SHMEDIA && reload_completed
5330    && ((CONST_INT_P (operands[1])
5331         && ! satisfies_constraint_I16 (operands[1]))
5332        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5333   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5335 (define_expand "movsi"
5336   [(set (match_operand:SI 0 "general_movdst_operand" "")
5337         (match_operand:SI 1 "general_movsrc_operand" ""))]
5338   ""
5340   if (prepare_move_operands (operands, SImode))
5341     DONE;
5344 (define_expand "ic_invalidate_line"
5345   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5346                                 (match_dup 1)] UNSPEC_ICACHE)
5347               (clobber (scratch:SI))])]
5348   "TARGET_HARD_SH4 || TARGET_SH5"
5350   if (TARGET_SHMEDIA)
5351     {
5352       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5353       DONE;
5354     }
5355   else if (TARGET_SHCOMPACT)
5356     {
5357       operands[1] = function_symbol (NULL, "__ic_invalidate", SFUNC_STATIC);
5358       operands[1] = force_reg (Pmode, operands[1]);
5359       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5360       DONE;
5361     }
5362   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5363     {
5364       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5365       DONE;
5366     }
5367   operands[0] = force_reg (Pmode, operands[0]);
5368   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5369                                                                Pmode)));
5372 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5373 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5374 ;; the requirement *1*00 for associative address writes.  The alignment of
5375 ;; %0 implies that its least significant bit is cleared,
5376 ;; thus we clear the V bit of a matching entry if there is one.
5377 (define_insn "ic_invalidate_line_i"
5378   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5379                      (match_operand:SI 1 "register_operand" "r")]
5380                      UNSPEC_ICACHE)
5381    (clobber (match_scratch:SI 2 "=&r"))]
5382   "TARGET_HARD_SH4"
5383   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5384   [(set_attr "length" "8")
5385    (set_attr "type" "cwb")])
5387 (define_insn "ic_invalidate_line_sh4a"
5388   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5389                     UNSPEC_ICACHE)]
5390   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5391   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5392   [(set_attr "length" "16")
5393    (set_attr "type" "cwb")])
5395 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5396 ;; an add in the code that calculates the address.
5397 (define_insn "ic_invalidate_line_media"
5398   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5399                     UNSPEC_ICACHE)]
5400   "TARGET_SHMEDIA"
5401   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5402   [(set_attr "length" "16")
5403    (set_attr "type" "invalidate_line_media")])
5405 (define_insn "ic_invalidate_line_compact"
5406   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5407                      (match_operand:SI 1 "register_operand" "r")]
5408                     UNSPEC_ICACHE)
5409    (clobber (reg:SI PR_REG))]
5410   "TARGET_SHCOMPACT"
5411   "jsr @%1%#"
5412   [(set_attr "type" "sfunc")
5413    (set_attr "needs_delay_slot" "yes")])
5415 (define_expand "initialize_trampoline"
5416   [(match_operand:SI 0 "" "")
5417    (match_operand:SI 1 "" "")
5418    (match_operand:SI 2 "" "")]
5419   "TARGET_SHCOMPACT"
5421   rtx sfun, tramp;
5423   tramp = force_reg (Pmode, operands[0]);
5424   sfun = force_reg (Pmode, function_symbol (NULL, "__init_trampoline",
5425                                             SFUNC_STATIC));
5426   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5427   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5429   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5430   DONE;
5433 (define_insn "initialize_trampoline_compact"
5434   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5435                      (match_operand:SI 1 "register_operand" "r")
5436                      (reg:SI R2_REG) (reg:SI R3_REG)]
5437                     UNSPEC_INIT_TRAMP)
5439    (clobber (reg:SI PR_REG))]
5440   "TARGET_SHCOMPACT"
5441   "jsr @%1%#"
5442   [(set_attr "type" "sfunc")
5443    (set_attr "needs_delay_slot" "yes")])
5445 (define_expand "movqi"
5446   [(set (match_operand:QI 0 "general_operand" "")
5447         (match_operand:QI 1 "general_operand" ""))]
5448   ""
5450   if (prepare_move_operands (operands, QImode))
5451     DONE;
5454 ;; If movqi_reg_reg is specified as an alternative of movqi, movqi will be
5455 ;; selected to copy QImode regs.  If one of them happens to be allocated
5456 ;; on the stack, reload will stick to movqi insn and generate wrong
5457 ;; displacement addressing because of the generic m alternatives.  
5458 ;; With the movqi_reg_reg being specified before movqi it will be intially 
5459 ;; picked to load/store regs.  If the regs regs are on the stack reload will
5460 ;; try other insns and not stick to movqi_reg_reg.
5461 (define_insn "*movqi_reg_reg"
5462   [(set (match_operand:QI 0 "arith_reg_dest"   "=r,r")
5463         (match_operand:QI 1 "register_operand" "r,t"))]
5464   "TARGET_SH1"
5465   "@
5466         mov     %1,%0
5467         movt    %0"
5468   [(set_attr "type" "move,arith")])
5470 ;; FIXME: The non-SH2A and SH2A variants should be combined by adding
5471 ;; "enabled" attribute as it is done in other targets.
5472 (define_insn "*movqi_store_mem_disp04"
5473   [(set (mem:QI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r")
5474                          (match_operand:SI 1 "const_int_operand" "K04,N")))
5475         (match_operand:QI 2 "arith_reg_operand" "z,r"))]
5476   "TARGET_SH1 && CONST_OK_FOR_K04 (INTVAL (operands[1]))"
5477   "@
5478         mov.b   %2,@(%O1,%0)
5479         mov.b   %2,@%0"
5480   [(set_attr "type" "store")])
5482 (define_insn "*movqi_store_mem_disp12"
5483   [(set (mem:QI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r")
5484                          (match_operand:SI 1 "const_int_operand" "K12")))
5485         (match_operand:QI 2 "arith_reg_operand" "r"))]
5486   "TARGET_SH2A && CONST_OK_FOR_K12 (INTVAL (operands[1]))"
5487   "mov.b        %2,@(%O1,%0)"
5488   [(set_attr "type" "store")
5489    (set_attr "length" "4")])
5491 (define_insn "*movqi_load_mem_disp"
5492   [(set (match_operand:QI 0 "arith_reg_dest" "=z,r")
5493         (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r")
5494                          (match_operand:SI 2 "const_int_operand" "K04,N"))))]
5495   "TARGET_SH1 && ! TARGET_SH2A && CONST_OK_FOR_K04 (INTVAL (operands[2]))"
5496   "@
5497         mov.b   @(%O2,%1),%0
5498         mov.b   @%1,%0"
5499   [(set_attr "type" "load")])
5501 (define_insn "*movqi_load_mem_disp"
5502   [(set (match_operand:QI 0 "arith_reg_dest" "=z,r,r")
5503         (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r")
5504                          (match_operand:SI 2 "const_int_operand" "K04,N,K12"))))]
5505   "TARGET_SH2A
5506    && (CONST_OK_FOR_K04 (INTVAL (operands[2]))
5507        || CONST_OK_FOR_K12 (INTVAL (operands[2])))"
5508   "@
5509         mov.b   @(%O2,%1),%0
5510         mov.b   @%1,%0
5511         mov.b   @(%O2,%1),%0"
5512   [(set_attr "type" "load")
5513    (set_attr "length" "2,2,4")])
5515 ;; The m constraints basically allow any kind of addresses to be used with any
5516 ;; source/target register as the other operand.  This is not true for 
5517 ;; displacement addressing modes on anything but SH2A.  That's why the
5518 ;; specialized load/store insns are specified above.
5519 (define_insn "*movqi"
5520   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,l")
5521         (match_operand:QI 1 "general_movsrc_operand"  "i,m,r,l,r"))]
5522   "TARGET_SH1
5523    && (arith_reg_operand (operands[0], QImode)
5524        || arith_reg_operand (operands[1], QImode))"
5525   "@
5526         mov     %1,%0
5527         mov.b   %1,%0
5528         mov.b   %1,%0
5529         sts     %1,%0
5530         lds     %1,%0"
5531  [(set_attr "type" "movi8,load,store,prget,prset")])
5533 (define_insn "*movqi_media"
5534   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5535         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5536   "TARGET_SHMEDIA
5537    && (arith_reg_operand (operands[0], QImode)
5538        || extend_reg_or_0_operand (operands[1], QImode))"
5539   "@
5540         add.l   %1, r63, %0
5541         movi    %1, %0
5542         ld%M1.ub        %m1, %0
5543         st%M0.b %m0, %N1"
5544   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5545    (set (attr "highpart")
5546         (cond [(match_test "sh_contains_memref_p (insn)")
5547                (const_string "user")]
5548               (const_string "ignore")))])
5550 (define_expand "reload_inqi"
5551   [(set (match_operand:SI 2 "" "=&r")
5552         (match_operand:QI 1 "inqhi_operand" ""))
5553    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5554         (truncate:QI (match_dup 3)))]
5555   "TARGET_SHMEDIA"
5557   rtx inner = XEXP (operands[1], 0);
5558   int regno = REGNO (inner);
5560   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5561   operands[1] = gen_rtx_REG (SImode, regno);
5562   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5565 ;; When storing r0, we have to avoid reg+reg addressing.
5566 (define_insn "movhi_i"
5567   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5568         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5569   "TARGET_SH1
5570    && (arith_reg_operand (operands[0], HImode)
5571        || arith_reg_operand (operands[1], HImode))
5572    && (!MEM_P (operands[0])
5573        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5574        || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5575        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5576   "@
5577         mov.w   %1,%0
5578         mov     %1,%0
5579         mov.w   %1,%0
5580         movt    %0
5581         mov.w   %1,%0
5582         sts     %1,%0
5583         lds     %1,%0
5584         fake    %1,%0"
5585   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5587 (define_insn "*movhi_media"
5588   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5589         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5590   "TARGET_SHMEDIA
5591    && (arith_reg_operand (operands[0], HImode)
5592        || arith_reg_or_0_operand (operands[1], HImode))"
5593   "@
5594         add.l   %1, r63, %0
5595         movi    %1, %0
5596         #
5597         ld%M1.w %m1, %0
5598         st%M0.w %m0, %N1"
5599   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5600    (set (attr "highpart")
5601         (cond [(match_test "sh_contains_memref_p (insn)")
5602                (const_string "user")]
5603               (const_string "ignore")))])
5605 (define_split
5606   [(set (match_operand:HI 0 "register_operand" "")
5607         (match_operand:HI 1 "immediate_operand" ""))]
5608   "TARGET_SHMEDIA && reload_completed
5609    && ! satisfies_constraint_I16 (operands[1])"
5610   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5612 (define_expand "movhi"
5613   [(set (match_operand:HI 0 "general_movdst_operand" "")
5614         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5615   ""
5617   if (prepare_move_operands (operands, HImode))
5618     DONE;
5621 (define_expand "reload_inhi"
5622   [(set (match_operand:SI 2 "" "=&r")
5623         (match_operand:HI 1 "inqhi_operand" ""))
5624    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5625         (truncate:HI (match_dup 3)))]
5626   "TARGET_SHMEDIA"
5628   rtx inner = XEXP (operands[1], 0);
5629   int regno = REGNO (inner);
5631   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5632   operands[1] = gen_rtx_REG (SImode, regno);
5633   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5636 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5637 ;; compiled with -m2 -ml -O3 -funroll-loops
5638 (define_insn "*movdi_i"
5639   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5640         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5641   "TARGET_SH1
5642    && (arith_reg_operand (operands[0], DImode)
5643        || arith_reg_operand (operands[1], DImode))"
5644   "* return output_movedouble (insn, operands, DImode);"
5645   [(set_attr "length" "4")
5646    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5648 ;; If the output is a register and the input is memory or a register, we have
5649 ;; to be careful and see which word needs to be loaded first.
5651 (define_split
5652   [(set (match_operand:DI 0 "general_movdst_operand" "")
5653         (match_operand:DI 1 "general_movsrc_operand" ""))]
5654   "TARGET_SH1 && reload_completed"
5655   [(set (match_dup 2) (match_dup 3))
5656    (set (match_dup 4) (match_dup 5))]
5658   int regno;
5660   if ((MEM_P (operands[0])
5661        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5662       || (MEM_P (operands[1])
5663           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5664     FAIL;
5666   switch (GET_CODE (operands[0]))
5667     {
5668     case REG:
5669       regno = REGNO (operands[0]);
5670       break;
5671     case SUBREG:
5672       regno = subreg_regno (operands[0]);
5673       break;
5674     case MEM:
5675       regno = -1;
5676       break;
5677     default:
5678       gcc_unreachable ();
5679     }
5681   if (regno == -1
5682       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5683     {
5684       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5685       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5686       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5687       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5688     }
5689   else
5690     {
5691       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5692       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5693       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5694       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5695     }
5697   if (operands[2] == 0 || operands[3] == 0
5698       || operands[4] == 0 || operands[5] == 0)
5699     FAIL;
5702 ;; The '?'s in the following constraints may not reflect the time taken
5703 ;; to perform the move. They are there to discourage the use of floating-
5704 ;; point registers for storing integer values.
5705 (define_insn "*movdi_media"
5706   [(set (match_operand:DI 0 "general_movdst_operand"
5707                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5708         (match_operand:DI 1 "general_movsrc_operand"
5709          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5710   "TARGET_SHMEDIA_FPU
5711    && (register_operand (operands[0], DImode)
5712        || sh_register_operand (operands[1], DImode))"
5713   "@
5714         add     %1, r63, %0
5715         movi    %1, %0
5716         #
5717         ld%M1.q %m1, %0
5718         st%M0.q %m0, %N1
5719         fld%M1.d        %m1, %0
5720         fst%M0.d        %m0, %1
5721         fmov.qd %N1, %0
5722         fmov.dq %1, %0
5723         fmov.d  %1, %0
5724         ptabs   %1, %0
5725         gettr   %1, %0
5726         pt      %1, %0"
5727   [(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")
5728    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5730 (define_insn "*movdi_media_nofpu"
5731   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5732         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5733   "TARGET_SHMEDIA
5734    && (register_operand (operands[0], DImode)
5735        || sh_register_operand (operands[1], DImode))"
5736   "@
5737         add     %1, r63, %0
5738         movi    %1, %0
5739         #
5740         ld%M1.q %m1, %0
5741         st%M0.q %m0, %N1
5742         ptabs   %1, %0
5743         gettr   %1, %0
5744         pt      %1, %0"
5745   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5746    (set_attr "length" "4,4,16,4,4,4,4,*")])
5748 (define_insn "*movdi_media_I16"
5749   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5750         (match_operand:DI 1 "const_int_operand" "I16"))]
5751   "TARGET_SHMEDIA && reload_completed"
5752   "movi %1, %0"
5753   [(set_attr "type" "arith_media")
5754    (set_attr "length" "4")])
5756 (define_split
5757   [(set (match_operand:DI 0 "arith_reg_dest" "")
5758         (match_operand:DI 1 "immediate_operand" ""))]
5759   "TARGET_SHMEDIA && reload_completed
5760    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5761   [(set (match_dup 0) (match_dup 1))]
5763   rtx insn;
5765   if (TARGET_SHMEDIA64)
5766     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5767   else
5768     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5770   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5772   DONE;
5775 (define_expand "movdi_const"
5776   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5777         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5778                               (const_int 48)] UNSPEC_EXTRACT_S16)))
5779    (set (match_dup 0)
5780         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5781                 (const:DI (unspec:DI [(match_dup 1)
5782                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
5783    (set (match_dup 0)
5784         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5785                 (const:DI (unspec:DI [(match_dup 1)
5786                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
5787    (set (match_dup 0)
5788         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5789                 (const:DI (unspec:DI [(match_dup 1)
5790                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5791   "TARGET_SHMEDIA64 && reload_completed
5792    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5794   sh_mark_label (operands[1], 4);
5797 (define_expand "movdi_const_32bit"
5798   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5799         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5800                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5801    (set (match_dup 0)
5802         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5803                 (const:DI (unspec:DI [(match_dup 1)
5804                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5805   "TARGET_SHMEDIA32 && reload_completed
5806    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5808   sh_mark_label (operands[1], 2);
5811 (define_expand "movdi_const_16bit"
5812   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5813         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5814                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5815   "TARGET_SHMEDIA && flag_pic && reload_completed
5816    && GET_CODE (operands[1]) == SYMBOL_REF"
5817   "")
5819 (define_split
5820   [(set (match_operand:DI 0 "ext_dest_operand" "")
5821         (match_operand:DI 1 "immediate_operand" ""))]
5822   "TARGET_SHMEDIA && reload_completed
5823    && CONST_INT_P (operands[1])
5824    && ! satisfies_constraint_I16 (operands[1])"
5825   [(set (match_dup 0) (match_dup 2))
5826    (match_dup 1)]
5828   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5829   unsigned HOST_WIDE_INT low = val;
5830   unsigned HOST_WIDE_INT high = val;
5831   unsigned HOST_WIDE_INT sign;
5832   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5834   /* Zero-extend the 16 least-significant bits.  */
5835   low &= 0xffff;
5837   /* Arithmetic shift right the word by 16 bits.  */
5838   high >>= 16;
5839   if (GET_CODE (operands[0]) == SUBREG
5840       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5841     {
5842       high &= 0xffff;
5843       high ^= 0x8000;
5844       high -= 0x8000;
5845     }
5846   else
5847     {
5848       sign = 1;
5849       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5850       high ^= sign;
5851       high -= sign;
5852     }
5853   do
5854     {
5855       /* If we can't generate the constant with a two-insn movi / shori
5856          sequence, try some other strategies.  */
5857       if (! CONST_OK_FOR_I16 (high))
5858         {
5859           /* Try constant load / left shift.  We know VAL != 0.  */
5860           val2 = val ^ (val-1);
5861           if (val2 > 0x1ffff)
5862             {
5863               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5865               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5866                   || (! CONST_OK_FOR_I16 (high >> 16)
5867                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5868                 {
5869                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5870                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5871                                                    GEN_INT (trailing_zeroes));
5872                   break;
5873                 }
5874             }
5875           /* Try constant load / right shift.  */
5876           val2 = (val >> 15) + 1;
5877           if (val2 == (val2 & -val2))
5878             {
5879               int shift = 49 - exact_log2 (val2);
5881               val2 = trunc_int_for_mode (val << shift, DImode);
5882               if (CONST_OK_FOR_I16 (val2))
5883                 {
5884                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5885                                                    GEN_INT (shift));
5886                   break;
5887                 }
5888             }
5889           /* Try mperm.w .  */
5890           val2 = val & 0xffff;
5891           if ((val >> 16 & 0xffff) == val2
5892               && (val >> 32 & 0xffff) == val2
5893               && (val >> 48 & 0xffff) == val2)
5894             {
5895               val2 = (HOST_WIDE_INT) val >> 48;
5896               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5897               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5898               break;
5899             }
5900           /* Try movi / mshflo.l  */
5901           val2 = (HOST_WIDE_INT) val >> 32;
5902           if (val2 == ((unsigned HOST_WIDE_INT)
5903                         trunc_int_for_mode (val, SImode)))
5904             {
5905               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5906                                              operands[0]);
5907               break;
5908             }
5909           /* Try movi / mshflo.l w/ r63.  */
5910           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5911           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5912             {
5913               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5914                                              const0_rtx);
5915               break;
5916             }
5917         }
5918       val2 = high;
5919       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5920     }
5921   while (0);
5922   operands[2] = GEN_INT (val2);
5925 (define_split
5926   [(set (match_operand:DI 0 "ext_dest_operand" "")
5927         (match_operand:DI 1 "immediate_operand" ""))]
5928   "TARGET_SHMEDIA && reload_completed
5929    && GET_CODE (operands[1]) == CONST_DOUBLE"
5930   [(set (match_dup 0) (match_dup 2))
5931   (set (match_dup 0)
5932        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5934   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5935   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5936   unsigned HOST_WIDE_INT val = low;
5937   unsigned HOST_WIDE_INT sign;
5939   /* Zero-extend the 16 least-significant bits.  */
5940   val &= 0xffff;
5941   operands[1] = GEN_INT (val);
5943   /* Arithmetic shift right the double-word by 16 bits.  */
5944   low >>= 16;
5945   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5946   high >>= 16;
5947   sign = 1;
5948   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5949   high ^= sign;
5950   high -= sign;
5952   /* This will only be true if high is a sign-extension of low, i.e.,
5953      it must be either 0 or (unsigned)-1, and be zero iff the
5954      most-significant bit of low is set.  */
5955   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5956     operands[2] = GEN_INT (low);
5957   else
5958     operands[2] = immed_double_const (low, high, DImode);
5961 (define_insn "shori_media"
5962   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5963         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5964                            (const_int 16))
5965                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5966   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5967   "@
5968         shori   %u2, %0
5969         #"
5970   [(set_attr "type" "arith_media,*")])
5972 (define_insn "*shori_media_si"
5973   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5974         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5975                            (const_int 16))
5976                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5977   "TARGET_SHMEDIA"
5978   "shori        %u2, %0")
5980 (define_expand "movdi"
5981   [(set (match_operand:DI 0 "general_movdst_operand" "")
5982         (match_operand:DI 1 "general_movsrc_operand" ""))]
5983   ""
5985   if (prepare_move_operands (operands, DImode))
5986     DONE;
5989 (define_insn "movdf_media"
5990   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5991         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5992   "TARGET_SHMEDIA_FPU
5993    && (register_operand (operands[0], DFmode)
5994        || sh_register_operand (operands[1], DFmode))"
5995   "@
5996         fmov.d  %1, %0
5997         fmov.qd %N1, %0
5998         fmov.dq %1, %0
5999         add     %1, r63, %0
6000         #
6001         fld%M1.d        %m1, %0
6002         fst%M0.d        %m0, %1
6003         ld%M1.q %m1, %0
6004         st%M0.q %m0, %N1"
6005   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
6007 (define_insn "movdf_media_nofpu"
6008   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
6009         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6010   "TARGET_SHMEDIA
6011    && (register_operand (operands[0], DFmode)
6012        || sh_register_operand (operands[1], DFmode))"
6013   "@
6014         add     %1, r63, %0
6015         #
6016         ld%M1.q %m1, %0
6017         st%M0.q %m0, %N1"
6018   [(set_attr "type" "arith_media,*,load_media,store_media")])
6020 (define_split
6021   [(set (match_operand:DF 0 "arith_reg_dest" "")
6022         (match_operand:DF 1 "immediate_operand" ""))]
6023   "TARGET_SHMEDIA && reload_completed"
6024   [(set (match_dup 3) (match_dup 2))]
6026   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
6027   long values[2];
6028   REAL_VALUE_TYPE value;
6030   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6031   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
6033   if (HOST_BITS_PER_WIDE_INT >= 64)
6034     operands[2] = immed_double_const ((unsigned long) values[endian]
6035                                       | ((HOST_WIDE_INT) values[1 - endian]
6036                                          << 32), 0, DImode);
6037   else
6038     {
6039       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
6040       operands[2] = immed_double_const (values[endian], values[1 - endian],
6041                                         DImode);
6042     }
6044   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6047 ;; ??? This should be a define expand.
6049 (define_insn "movdf_k"
6050   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
6051         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
6052   "TARGET_SH1
6053    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
6054        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
6055        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6056        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6057    && (arith_reg_operand (operands[0], DFmode)
6058        || arith_reg_operand (operands[1], DFmode))"
6060   return output_movedouble (insn, operands, DFmode);
6062   [(set_attr "length" "4")
6063    (set_attr "type" "move,pcload,load,store")])
6065 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
6066 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
6067 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
6068 ;; the d/m/c/X alternative, which is split later into single-precision
6069 ;; instructions.  And when not optimizing, no splits are done before fixing
6070 ;; up pcloads, so we need usable length information for that.
6071 (define_insn "movdf_i4"
6072   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
6073         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
6074    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
6075    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
6076   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6077    && (arith_reg_operand (operands[0], DFmode)
6078        || arith_reg_operand (operands[1], DFmode))"
6079   {
6080     switch (which_alternative)
6081     {
6082     case 0:
6083       if (TARGET_FMOVD)
6084         return "fmov    %1,%0";
6085       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
6086         return "fmov    %R1,%R0\n\tfmov %S1,%S0";
6087       else
6088         return "fmov    %S1,%S0\n\tfmov %R1,%R0";
6089     case 3:
6090     case 4:
6091       return "fmov.d    %1,%0";
6092     default:
6093       return "#";
6094     }
6095   }
6096   [(set_attr_alternative "length"
6097      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
6098       (const_int 4)
6099       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6100       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6101       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
6102       (const_int 4)
6103       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
6104       ;; We can't use 4-byte push/pop on SHcompact, so we have to
6105       ;; increment or decrement r15 explicitly.
6106       (if_then_else
6107        (match_test "TARGET_SHCOMPACT")
6108        (const_int 10) (const_int 8))
6109       (if_then_else
6110        (match_test "TARGET_SHCOMPACT")
6111        (const_int 10) (const_int 8))])
6112    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
6113    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
6114    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6115                                            (const_string "double")
6116                                            (const_string "none")))])
6118 ;; Moving DFmode between fp/general registers through memory
6119 ;; (the top of the stack) is faster than moving through fpul even for
6120 ;; little endian.  Because the type of an instruction is important for its
6121 ;; scheduling,  it is beneficial to split these operations, rather than
6122 ;; emitting them in one single chunk, even if this will expose a stack
6123 ;; use that will prevent scheduling of other stack accesses beyond this
6124 ;; instruction.
6125 (define_split
6126   [(set (match_operand:DF 0 "register_operand" "")
6127         (match_operand:DF 1 "register_operand" ""))
6128    (use (match_operand:PSI 2 "fpscr_operand" ""))
6129    (clobber (match_scratch:SI 3 "=X"))]
6130   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
6131    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
6132   [(const_int 0)]
6134   rtx insn, tos;
6136   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
6137     {
6138       emit_move_insn (stack_pointer_rtx,
6139                       plus_constant (stack_pointer_rtx, -8));
6140       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6141     }
6142   else
6143     tos = gen_tmp_stack_mem (DFmode,
6144                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
6145   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
6146   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
6147     add_reg_note (insn, REG_INC, stack_pointer_rtx);
6148   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6149     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
6150   else
6151     tos = gen_tmp_stack_mem (DFmode,
6152                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
6153   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
6154   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
6155     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
6156   else
6157     add_reg_note (insn, REG_INC, stack_pointer_rtx);
6158   DONE;
6161 ;; local-alloc sometimes allocates scratch registers even when not required,
6162 ;; so we must be prepared to handle these.
6164 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
6165 (define_split
6166   [(set (match_operand:DF 0 "general_movdst_operand" "")
6167         (match_operand:DF 1 "general_movsrc_operand"  ""))
6168    (use (match_operand:PSI 2 "fpscr_operand" ""))
6169    (clobber (match_scratch:SI 3 ""))]
6170   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
6171    && reload_completed
6172    && true_regnum (operands[0]) < 16
6173    && true_regnum (operands[1]) < 16"
6174   [(set (match_dup 0) (match_dup 1))]
6176   /* If this was a reg <-> mem operation with base + index reg addressing,
6177      we have to handle this in a special way.  */
6178   rtx mem = operands[0];
6179   int store_p = 1;
6180   if (! memory_operand (mem, DFmode))
6181     {
6182       mem = operands[1];
6183       store_p = 0;
6184     }
6185   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6186     mem = SUBREG_REG (mem);
6187   if (MEM_P (mem))
6188     {
6189       rtx addr = XEXP (mem, 0);
6190       if (GET_CODE (addr) == PLUS
6191           && REG_P (XEXP (addr, 0))
6192           && REG_P (XEXP (addr, 1)))
6193         {
6194           int offset;
6195           rtx reg0 = gen_rtx_REG (Pmode, 0);
6196           rtx regop = operands[store_p], word0 ,word1;
6198           if (GET_CODE (regop) == SUBREG)
6199             alter_subreg (&regop);
6200           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6201             offset = 2;
6202           else
6203             offset = 4;
6204           mem = copy_rtx (mem);
6205           PUT_MODE (mem, SImode);
6206           word0 = gen_rtx_SUBREG (SImode, regop, 0);
6207           alter_subreg (&word0);
6208           word1 = gen_rtx_SUBREG (SImode, regop, 4);
6209           alter_subreg (&word1);
6210           if (store_p || ! refers_to_regno_p (REGNO (word0),
6211                                               REGNO (word0) + 1, addr, 0))
6212             {
6213               emit_insn (store_p
6214                          ? gen_movsi_ie (mem, word0)
6215                          : gen_movsi_ie (word0, mem));
6216               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6217               mem = copy_rtx (mem);
6218               emit_insn (store_p
6219                          ? gen_movsi_ie (mem, word1)
6220                          : gen_movsi_ie (word1, mem));
6221               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6222             }
6223           else
6224             {
6225               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6226               emit_insn (gen_movsi_ie (word1, mem));
6227               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6228               mem = copy_rtx (mem);
6229               emit_insn (gen_movsi_ie (word0, mem));
6230             }
6231           DONE;
6232         }
6233     }
6236 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6237 (define_split
6238   [(set (match_operand:DF 0 "register_operand" "")
6239         (match_operand:DF 1 "memory_operand"  ""))
6240    (use (match_operand:PSI 2 "fpscr_operand" ""))
6241    (clobber (reg:SI R0_REG))]
6242   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6243   [(parallel [(set (match_dup 0) (match_dup 1))
6244               (use (match_dup 2))
6245               (clobber (scratch:SI))])]
6246   "")
6248 (define_expand "reload_indf__frn"
6249   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6250                    (match_operand:DF 1 "immediate_operand" "FQ"))
6251               (use (reg:PSI FPSCR_REG))
6252               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6253   "TARGET_SH1"
6254   "")
6256 (define_expand "reload_outdf__RnFRm"
6257   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6258                    (match_operand:DF 1 "register_operand" "af,r"))
6259               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6260   "TARGET_SH1"
6261   "")
6263 ;; Simplify no-op moves.
6264 (define_split
6265   [(set (match_operand:SF 0 "register_operand" "")
6266         (match_operand:SF 1 "register_operand" ""))
6267    (use (match_operand:PSI 2 "fpscr_operand" ""))
6268    (clobber (match_scratch:SI 3 ""))]
6269   "TARGET_SH2E && reload_completed
6270    && true_regnum (operands[0]) == true_regnum (operands[1])"
6271   [(set (match_dup 0) (match_dup 0))]
6272   "")
6274 ;; fmovd substitute post-reload splits
6275 (define_split
6276   [(set (match_operand:DF 0 "register_operand" "")
6277         (match_operand:DF 1 "register_operand" ""))
6278    (use (match_operand:PSI 2 "fpscr_operand" ""))
6279    (clobber (match_scratch:SI 3 ""))]
6280   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6281    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6282    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6283   [(const_int 0)]
6285   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6286   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6287                            gen_rtx_REG (SFmode, src), operands[2]));
6288   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6289                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6290   DONE;
6293 (define_split
6294   [(set (match_operand:DF 0 "register_operand" "")
6295         (mem:DF (match_operand:SI 1 "register_operand" "")))
6296    (use (match_operand:PSI 2 "fpscr_operand" ""))
6297    (clobber (match_scratch:SI 3 ""))]
6298   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6299    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6300    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6301   [(const_int 0)]
6303   int regno = true_regnum (operands[0]);
6304   rtx insn;
6305   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6306   rtx mem2
6307     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6308   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6309                                            regno + !! TARGET_LITTLE_ENDIAN),
6310                                   mem2, operands[2]));
6311   add_reg_note (insn, REG_INC, operands[1]);
6312   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6313                                                regno + ! TARGET_LITTLE_ENDIAN),
6314                                   change_address (mem, SFmode, NULL_RTX),
6315                                   operands[2]));
6316   DONE;
6319 (define_split
6320   [(set (match_operand:DF 0 "register_operand" "")
6321         (match_operand:DF 1 "memory_operand" ""))
6322    (use (match_operand:PSI 2 "fpscr_operand" ""))
6323    (clobber (match_scratch:SI 3 ""))]
6324   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6325    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6326   [(const_int 0)]
6328   int regno = true_regnum (operands[0]);
6329   rtx addr, insn;
6330   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6331   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6332   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6334   operands[1] = copy_rtx (mem2);
6335   addr = XEXP (mem2, 0);
6337   switch (GET_CODE (addr))
6338     {
6339     case REG:
6340       /* This is complicated.  If the register is an arithmetic register
6341          we can just fall through to the REG+DISP case below.  Otherwise
6342          we have to use a combination of POST_INC and REG addressing...  */
6343       if (! arith_reg_operand (operands[1], SFmode))
6344         {
6345           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6346           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6347           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6348           
6349           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6351           /* If we have modified the stack pointer, the value that we have
6352              read with post-increment might be modified by an interrupt,
6353              so write it back.  */
6354           if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6355             emit_insn (gen_push_e (reg0));
6356           else
6357             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6358           break;
6359         }
6360       /* Fall through.  */
6361          
6362     case PLUS:
6363       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6364       operands[1] = copy_rtx (operands[1]);
6365       XEXP (operands[1], 0) = plus_constant (addr, 4);
6366       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6367       break;
6368       
6369     case POST_INC:
6370       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6371       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6372     
6373       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6374       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6375       break;
6377     default:
6378       debug_rtx (addr);
6379       gcc_unreachable ();
6380     }
6382   DONE;
6385 (define_split
6386   [(set (match_operand:DF 0 "memory_operand" "")
6387         (match_operand:DF 1 "register_operand" ""))
6388    (use (match_operand:PSI 2 "fpscr_operand" ""))
6389    (clobber (match_scratch:SI 3 ""))]
6390   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6391    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6392   [(const_int 0)]
6394   int regno = true_regnum (operands[1]);
6395   rtx insn, addr;
6396   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6397   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6399   operands[0] = copy_rtx (operands[0]);
6400   PUT_MODE (operands[0], SFmode);
6401   addr = XEXP (operands[0], 0);
6403   switch (GET_CODE (addr))
6404     {
6405     case REG:
6406       /* This is complicated.  If the register is an arithmetic register
6407          we can just fall through to the REG+DISP case below.  Otherwise
6408          we have to use a combination of REG and PRE_DEC addressing...  */
6409       if (! arith_reg_operand (operands[0], SFmode))
6410         {
6411           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6412           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6414           operands[0] = copy_rtx (operands[0]);
6415           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6416           
6417           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6418           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6419           break;
6420         }
6421       /* Fall through.  */
6422       
6423     case PLUS:
6424       /* Since REG+DISP addressing has already been decided upon by gcc
6425          we can rely upon it having chosen an arithmetic register as the
6426          register component of the address.  Just emit the lower numbered
6427          register first, to the lower address, then the higher numbered
6428          register to the higher address.  */
6429       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6431       operands[0] = copy_rtx (operands[0]);
6432       XEXP (operands[0], 0) = plus_constant (addr, 4);
6434       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));         
6435       break;
6436       
6437     case PRE_DEC:
6438       /* This is easy.  Output the word to go to the higher address
6439          first (ie the word in the higher numbered register) then the
6440          word to go to the lower address.  */
6442       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6443       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6445       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6446       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6447       break;
6448       
6449     default:
6450       /* FAIL; */
6451       debug_rtx (addr);
6452       gcc_unreachable ();
6453     }
6455   DONE;
6458 ;; If the output is a register and the input is memory or a register, we have
6459 ;; to be careful and see which word needs to be loaded first.
6461 (define_split
6462   [(set (match_operand:DF 0 "general_movdst_operand" "")
6463         (match_operand:DF 1 "general_movsrc_operand" ""))]
6464   "TARGET_SH1 && reload_completed"
6465   [(set (match_dup 2) (match_dup 3))
6466    (set (match_dup 4) (match_dup 5))]
6468   int regno;
6470   if ((MEM_P (operands[0])
6471        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6472       || (MEM_P (operands[1])
6473           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6474     FAIL;
6476   switch (GET_CODE (operands[0]))
6477     {
6478     case REG:
6479       regno = REGNO (operands[0]);
6480       break;
6481     case SUBREG:
6482       regno = subreg_regno (operands[0]);
6483       break;
6484     case MEM:
6485       regno = -1;
6486       break;
6487     default:
6488       gcc_unreachable ();
6489     }
6491   if (regno == -1
6492       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6493     {
6494       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6495       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6496       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6497       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6498     }
6499   else
6500     {
6501       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6502       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6503       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6504       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6505     }
6507   if (operands[2] == 0 || operands[3] == 0
6508       || operands[4] == 0 || operands[5] == 0)
6509     FAIL;
6512 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6513 ;; used only once, let combine add in the index again.
6515 (define_split
6516   [(set (match_operand:SI 0 "register_operand" "")
6517         (match_operand:SI 1 "" ""))
6518    (clobber (match_operand 2 "register_operand" ""))]
6519   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6520    && ALLOW_INDEXED_ADDRESS"
6521   [(use (reg:SI R0_REG))]
6523   rtx addr, reg, const_int;
6525   if (!MEM_P (operands[1]))
6526     FAIL;
6527   addr = XEXP (operands[1], 0);
6528   if (GET_CODE (addr) != PLUS)
6529     FAIL;
6530   reg = XEXP (addr, 0);
6531   const_int = XEXP (addr, 1);
6532   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6533          && CONST_INT_P (const_int)))
6534     FAIL;
6535   emit_move_insn (operands[2], const_int);
6536   emit_move_insn (operands[0],
6537                   change_address (operands[1], VOIDmode,
6538                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6539   DONE;
6542 (define_split
6543   [(set (match_operand:SI 1 "" "")
6544         (match_operand:SI 0 "register_operand" ""))
6545    (clobber (match_operand 2 "register_operand" ""))]
6546   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6547    && ALLOW_INDEXED_ADDRESS"
6548   [(use (reg:SI R0_REG))]
6550   rtx addr, reg, const_int;
6552   if (!MEM_P (operands[1]))
6553     FAIL;
6554   addr = XEXP (operands[1], 0);
6555   if (GET_CODE (addr) != PLUS)
6556     FAIL;
6557   reg = XEXP (addr, 0);
6558   const_int = XEXP (addr, 1);
6559   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6560          && CONST_INT_P (const_int)))
6561     FAIL;
6562   emit_move_insn (operands[2], const_int);
6563   emit_move_insn (change_address (operands[1], VOIDmode,
6564                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6565                   operands[0]);
6566   DONE;
6569 (define_expand "movdf"
6570   [(set (match_operand:DF 0 "general_movdst_operand" "")
6571         (match_operand:DF 1 "general_movsrc_operand" ""))]
6572   ""
6574   if (prepare_move_operands (operands, DFmode))
6575     DONE;
6576   if (TARGET_SHMEDIA)
6577     {
6578       if (TARGET_SHMEDIA_FPU)
6579         emit_insn (gen_movdf_media (operands[0], operands[1]));
6580       else
6581         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6582       DONE;
6583     }
6584   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6585     {
6586       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6587       DONE;
6588     }
6591 ;;This is incompatible with the way gcc uses subregs.
6592 ;;(define_insn "movv2sf_i"
6593 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6594 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6595 ;;  "TARGET_SHMEDIA_FPU
6596 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6597 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6598 ;;  "@
6599 ;;      #
6600 ;;      fld%M1.p        %m1, %0
6601 ;;      fst%M0.p        %m0, %1"
6602 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6604 (define_insn_and_split "movv2sf_i"
6605   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6606         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6607   "TARGET_SHMEDIA_FPU"
6608   "#"
6609   "TARGET_SHMEDIA_FPU && reload_completed"
6610   [(set (match_dup 0) (match_dup 1))]
6612   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6613   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6616 (define_expand "movv2sf"
6617   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6618         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6619   "TARGET_SHMEDIA_FPU"
6621   if (prepare_move_operands (operands, V2SFmode))
6622     DONE;
6625 (define_expand "addv2sf3"
6626   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6627    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6628    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6629   "TARGET_SHMEDIA_FPU"
6631   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6632   DONE;
6635 (define_expand "subv2sf3"
6636   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6637    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6638    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6639   "TARGET_SHMEDIA_FPU"
6641   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6642   DONE;
6645 (define_expand "mulv2sf3"
6646   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6647    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6648    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6649   "TARGET_SHMEDIA_FPU"
6651   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6652   DONE;
6655 (define_expand "divv2sf3"
6656   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6657    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6658    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6659   "TARGET_SHMEDIA_FPU"
6661   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6662   DONE;
6665 (define_insn_and_split "*movv4sf_i"
6666   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6667         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6668   "TARGET_SHMEDIA_FPU"
6669   "#"
6670   "&& reload_completed"
6671   [(const_int 0)]
6673   int i;
6675   for (i = 0; i < 4/2; i++)
6676     {
6677       rtx x, y;
6679       if (MEM_P (operands[0]))
6680         x = adjust_address (operands[0], V2SFmode,
6681                             i * GET_MODE_SIZE (V2SFmode));
6682       else
6683         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6685       if (MEM_P (operands[1]))
6686         y = adjust_address (operands[1], V2SFmode,
6687                             i * GET_MODE_SIZE (V2SFmode));
6688       else
6689         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6691       emit_insn (gen_movv2sf_i (x, y));
6692     }
6694   DONE;
6696   [(set_attr "length" "8")])
6698 (define_expand "movv4sf"
6699   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6700         (match_operand:V4SF 1 "general_operand" ""))]
6701   "TARGET_SHMEDIA_FPU"
6703   if (prepare_move_operands (operands, V4SFmode))
6704     DONE;
6707 (define_insn_and_split "*movv16sf_i"
6708   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6709         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6710   "TARGET_SHMEDIA_FPU"
6711   "#"
6712   "&& reload_completed"
6713   [(const_int 0)]
6715   int i;
6717   for (i = 0; i < 16/2; i++)
6718     {
6719       rtx x,y;
6721       if (MEM_P (operands[0]))
6722         x = adjust_address (operands[0], V2SFmode,
6723                             i * GET_MODE_SIZE (V2SFmode));
6724       else
6725         {
6726           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6727           alter_subreg (&x);
6728         }
6730       if (MEM_P (operands[1]))
6731         y = adjust_address (operands[1], V2SFmode,
6732                             i * GET_MODE_SIZE (V2SFmode));
6733       else
6734         {
6735           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6736           alter_subreg (&y);
6737         }
6739       emit_insn (gen_movv2sf_i (x, y));
6740     }
6742   DONE;
6744   [(set_attr "length" "32")])
6746 (define_expand "movv16sf"
6747   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6748         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6749   "TARGET_SHMEDIA_FPU"
6751   if (prepare_move_operands (operands, V16SFmode))
6752     DONE;
6755 (define_insn "movsf_media"
6756   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6757         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6758   "TARGET_SHMEDIA_FPU
6759    && (register_operand (operands[0], SFmode)
6760        || sh_register_operand (operands[1], SFmode))"
6761   "@
6762         fmov.s  %1, %0
6763         fmov.ls %N1, %0
6764         fmov.sl %1, %0
6765         add.l   %1, r63, %0
6766         #
6767         fld%M1.s        %m1, %0
6768         fst%M0.s        %m0, %1
6769         ld%M1.l %m1, %0
6770         st%M0.l %m0, %N1"
6771   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6772    (set (attr "highpart")
6773         (cond [(match_test "sh_contains_memref_p (insn)")
6774                (const_string "user")]
6775               (const_string "ignore")))])
6777 (define_insn "movsf_media_nofpu"
6778   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6779         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6780   "TARGET_SHMEDIA
6781    && (register_operand (operands[0], SFmode)
6782        || sh_register_operand (operands[1], SFmode))"
6783   "@
6784         add.l   %1, r63, %0
6785         #
6786         ld%M1.l %m1, %0
6787         st%M0.l %m0, %N1"
6788   [(set_attr "type" "arith_media,*,load_media,store_media")
6789    (set (attr "highpart")
6790         (cond [(match_test "sh_contains_memref_p (insn)")
6791                (const_string "user")]
6792               (const_string "ignore")))])
6794 (define_split
6795   [(set (match_operand:SF 0 "arith_reg_dest" "")
6796         (match_operand:SF 1 "immediate_operand" ""))]
6797   "TARGET_SHMEDIA && reload_completed
6798    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6799   [(set (match_dup 3) (match_dup 2))]
6801   long values;
6802   REAL_VALUE_TYPE value;
6804   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6805   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6806   operands[2] = GEN_INT (values);
6808   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6811 (define_insn "movsf_i"
6812   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6813         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6814   "TARGET_SH1
6815    && (! TARGET_SH2E
6816        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6817        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6818        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6819    && (arith_reg_operand (operands[0], SFmode)
6820        || arith_reg_operand (operands[1], SFmode))"
6821   "@
6822         mov     %1,%0
6823         mov     #0,%0
6824         mov.l   %1,%0
6825         mov.l   %1,%0
6826         mov.l   %1,%0
6827         lds     %1,%0
6828         sts     %1,%0"
6829   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6831 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6832 ;; update_flow_info would not know where to put REG_EQUAL notes
6833 ;; when the destination changes mode.
6834 (define_insn "movsf_ie"
6835   [(set (match_operand:SF 0 "general_movdst_operand"
6836          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6837         (match_operand:SF 1 "general_movsrc_operand"
6838           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6839    (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"))
6840    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6841   "TARGET_SH2E
6842    && (arith_reg_operand (operands[0], SFmode)
6843        || arith_reg_operand (operands[1], SFmode)
6844        || arith_reg_operand (operands[3], SImode)
6845        || (fpul_operand (operands[0], SFmode)
6846            && memory_operand (operands[1], SFmode)
6847            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6848        || (fpul_operand (operands[1], SFmode)
6849            && memory_operand (operands[0], SFmode)
6850            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6851   "@
6852         fmov    %1,%0
6853         mov     %1,%0
6854         fldi0   %0
6855         fldi1   %0
6856         #
6857         fmov.s  %1,%0
6858         fmov.s  %1,%0
6859         mov.l   %1,%0
6860         mov.l   %1,%0
6861         mov.l   %1,%0
6862         fsts    fpul,%0
6863         flds    %1,fpul
6864         lds.l   %1,%0
6865         #
6866         sts     %1,%0
6867         lds     %1,%0
6868         sts.l   %1,%0
6869         lds.l   %1,%0
6870         ! move optimized away"
6871   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6872    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6873    (set_attr_alternative "length"
6874      [(const_int 2)
6875       (const_int 2)
6876       (const_int 2)
6877       (const_int 2)
6878       (const_int 4)
6879       (if_then_else
6880         (match_test "TARGET_SH2A")
6881         (const_int 4) (const_int 2))
6882       (if_then_else
6883         (match_test "TARGET_SH2A")
6884         (const_int 4) (const_int 2))
6885       (const_int 2)
6886       (if_then_else
6887         (match_test "TARGET_SH2A")
6888         (const_int 4) (const_int 2))
6889       (if_then_else
6890         (match_test "TARGET_SH2A")
6891         (const_int 4) (const_int 2))
6892       (const_int 2)
6893       (const_int 2)
6894       (const_int 2)
6895       (const_int 4)
6896       (const_int 2)
6897       (const_int 2)
6898       (const_int 2)
6899       (const_int 2)
6900       (const_int 0)])
6901    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6902                                            (const_string "single")
6903                                            (const_string "single")))])
6905 (define_split
6906   [(set (match_operand:SF 0 "register_operand" "")
6907         (match_operand:SF 1 "register_operand" ""))
6908    (use (match_operand:PSI 2 "fpscr_operand" ""))
6909    (clobber (reg:SI FPUL_REG))]
6910   "TARGET_SH1"
6911   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6912               (use (match_dup 2))
6913               (clobber (scratch:SI))])
6914    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6915               (use (match_dup 2))
6916               (clobber (scratch:SI))])]
6917   "")
6919 (define_expand "movsf"
6920   [(set (match_operand:SF 0 "general_movdst_operand" "")
6921         (match_operand:SF 1 "general_movsrc_operand" ""))]
6922   ""
6924   if (prepare_move_operands (operands, SFmode))
6925     DONE;
6926   if (TARGET_SHMEDIA)
6927     {
6928       if (TARGET_SHMEDIA_FPU)
6929         emit_insn (gen_movsf_media (operands[0], operands[1]));
6930       else
6931         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6932       DONE;
6933     }
6934   if (TARGET_SH2E)
6935     {
6936       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6937       DONE;
6938     }
6941 (define_insn "mov_nop"
6942   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6943   "TARGET_SH2E"
6944   ""
6945   [(set_attr "length" "0")
6946    (set_attr "type" "nil")])
6948 (define_expand "reload_insf__frn"
6949   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6950                    (match_operand:SF 1 "immediate_operand" "FQ"))
6951               (use (reg:PSI FPSCR_REG))
6952               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6953   "TARGET_SH1"
6954   "")
6956 (define_expand "reload_insi__i_fpul"
6957   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6958                    (match_operand:SI 1 "immediate_operand" "i"))
6959               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6960   "TARGET_SH1"
6961   "")
6963 (define_expand "ptabs"
6964   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6965   "TARGET_SHMEDIA"
6967   if (!TARGET_PT_FIXED)
6968     {
6969       rtx eq = operands[1];
6971       /* ??? For canonical RTL we really should remove any CONST from EQ
6972          before wrapping it in the AND, and finally wrap the EQ into a
6973          const if is constant.  However, for reload we must expose the
6974          input register or symbolic constant, and we can't have
6975          different insn structures outside of the operands for different
6976          alternatives of the same pattern.  */
6977       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6978                        GEN_INT (3));
6979       operands[1]
6980         = (gen_rtx_IF_THEN_ELSE
6981             (PDImode,
6982              eq,
6983              gen_rtx_MEM (PDImode, operands[1]),
6984              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6985                             PDImode, operands[1])));
6986     }
6989 ;; expanded by ptabs expander.
6990 (define_insn "*extendsipdi_media"
6991   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6992         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6993                                                           "r,Csy")
6994                                       (const_int 3))
6995                               (const_int 3))
6996                           (mem:PDI (match_dup 1))
6997                           (sign_extend:PDI (match_dup 1))))]
6998   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6999   "@
7000         ptabs   %1, %0
7001         pt      %1, %0"
7002   [(set_attr "type"   "ptabs_media,pt_media")
7003    (set_attr "length" "4,*")])
7005 (define_insn "*truncdipdi_media"
7006   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
7007         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
7008                                                           "r,Csy")
7009                                       (const_int 3))
7010                               (const_int 3))
7011                           (mem:PDI (match_dup 1))
7012                           (truncate:PDI (match_dup 1))))]
7013   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
7014   "@
7015         ptabs   %1, %0
7016         pt      %1, %0"
7017   [(set_attr "type"   "ptabs_media,pt_media")
7018    (set_attr "length" "4,*")])
7020 (define_insn "*movsi_y"
7021   [(set (match_operand:SI 0 "register_operand" "=y,y")
7022         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
7023    (clobber (match_scratch:SI 2 "=&z,r"))]
7024   "TARGET_SH2E
7025    && (reload_in_progress || reload_completed)"
7026   "#"
7027   [(set_attr "length" "4")
7028    (set_attr "type" "pcload,move")])
7030 (define_split
7031   [(set (match_operand:SI 0 "register_operand" "")
7032         (match_operand:SI 1 "immediate_operand" ""))
7033    (clobber (match_operand:SI 2 "register_operand" ""))]
7034   "TARGET_SH1"
7035   [(set (match_dup 2) (match_dup 1))
7036    (set (match_dup 0) (match_dup 2))]
7037   "")
7039 ;; ------------------------------------------------------------------------
7040 ;; Define the real conditional branch instructions.
7041 ;; ------------------------------------------------------------------------
7043 (define_insn "branch_true"
7044   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
7045                            (label_ref (match_operand 0 "" ""))
7046                            (pc)))]
7047   "TARGET_SH1"
7049   return output_branch (1, insn, operands);
7051   [(set_attr "type" "cbranch")])
7053 (define_insn "branch_false"
7054   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7055                            (label_ref (match_operand 0 "" ""))
7056                            (pc)))]
7057   "TARGET_SH1"
7059   return output_branch (0, insn, operands);
7061   [(set_attr "type" "cbranch")])
7063 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
7064 ;; which destination is too far away.
7065 ;; The const_int_operand is distinct for each branch target; it avoids
7066 ;; unwanted matches with redundant_insn.
7067 (define_insn "block_branch_redirect"
7068   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
7069   "TARGET_SH1"
7070   ""
7071   [(set_attr "length" "0")])
7073 ;; This one has the additional purpose to record a possible scratch register
7074 ;; for the following branch.
7075 ;; ??? Unfortunately, just setting the scratch register is not good enough,
7076 ;; because the insn then might be deemed dead and deleted.  And we can't
7077 ;; make the use in the jump insn explicit because that would disable
7078 ;; delay slot scheduling from the target.
7079 (define_insn "indirect_jump_scratch"
7080   [(set (match_operand:SI 0 "register_operand" "=r")
7081         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
7082    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
7083   "TARGET_SH1"
7084   ""
7085   [(set_attr "length" "0")])
7087 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
7088 ;; being pulled into the delay slot of a condbranch that has been made to
7089 ;; jump around the unconditional jump because it was out of range.
7090 (define_insn "stuff_delay_slot"
7091   [(set (pc)
7092         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
7093                  (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
7094   "TARGET_SH1"
7095   ""
7096   [(set_attr "length" "0")
7097    (set_attr "cond_delay_slot" "yes")])
7099 ;; Conditional branch insns
7101 (define_expand "cbranchint4_media"
7102   [(set (pc)
7103         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
7104                        [(match_operand 1 "" "")
7105                         (match_operand 2 "" "")])
7106                       (match_operand 3 "" "")
7107                       (pc)))]
7108   "TARGET_SHMEDIA"
7110   enum machine_mode mode = GET_MODE (operands[1]);
7111   if (mode == VOIDmode)
7112     mode = GET_MODE (operands[2]);
7113   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
7114     {
7115       operands[1] = force_reg (mode, operands[1]);
7116       if (CONSTANT_P (operands[2])
7117           && (! satisfies_constraint_I06 (operands[2])))
7118         operands[2] = force_reg (mode, operands[2]);
7119     }
7120   else
7121     {
7122       if (operands[1] != const0_rtx)
7123         operands[1] = force_reg (mode, operands[1]);
7124       if (operands[2] != const0_rtx)
7125         operands[2] = force_reg (mode, operands[2]);
7126     }
7127   switch (GET_CODE (operands[0]))
7128     {
7129     case LEU:
7130     case LE:
7131     case LTU:
7132     case LT:
7133       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
7134                                     VOIDmode, operands[2], operands[1]);
7135       operands[1] = XEXP (operands[0], 0);
7136       operands[2] = XEXP (operands[0], 1);
7137       break;
7138     default:
7139       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
7140                                     VOIDmode, operands[1], operands[2]);
7141       break;
7142     }
7143   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7146 (define_expand "cbranchfp4_media"
7147   [(set (pc)
7148         (if_then_else (match_operator 0 "sh_float_comparison_operator"
7149                        [(match_operand 1 "" "")
7150                         (match_operand 2 "" "")])
7151                       (match_operand 3 "" "")
7152                       (pc)))]
7153   "TARGET_SHMEDIA"
7155   rtx tmp = gen_reg_rtx (SImode);
7156   rtx cmp;
7157   if (GET_CODE (operands[0]) == NE)
7158     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
7159   else
7160     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
7161                           operands[1], operands[2]);
7163   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
7165   if (GET_CODE (cmp) == GET_CODE (operands[0]))
7166     operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
7167   else
7168     operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
7169   operands[1] = tmp;
7170   operands[2] = const0_rtx;
7171   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
7174 (define_insn "*beq_media_i"
7175   [(set (pc)
7176         (if_then_else (match_operator 3 "equality_comparison_operator"
7177                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
7178                          (match_operand:DI 2 "arith_operand" "r,I06")])
7179                       (match_operand 0 "target_operand" "b,b")
7180                       (pc)))]
7181   "TARGET_SHMEDIA"
7182   "@
7183         b%o3%'  %1, %2, %0%>
7184         b%o3i%' %1, %2, %0%>"
7185   [(set_attr "type" "cbranch_media")])
7187 (define_insn "*beq_media_i32"
7188   [(set (pc)
7189         (if_then_else (match_operator 3 "equality_comparison_operator"
7190                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
7191                          (match_operand:SI 2 "arith_operand" "r,I06")])
7192                       (match_operand 0 "target_operand" "b,b")
7193                       (pc)))]
7194   "TARGET_SHMEDIA"
7195   "@
7196         b%o3%'  %1, %2, %0%>
7197         b%o3i%' %1, %2, %0%>"
7198   [(set_attr "type" "cbranch_media")])
7200 (define_insn "*bgt_media_i"
7201   [(set (pc)
7202         (if_then_else (match_operator 3 "greater_comparison_operator"
7203                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7204                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7205                       (match_operand 0 "target_operand" "b")
7206                       (pc)))]
7207   "TARGET_SHMEDIA"
7208   "b%o3%'       %N1, %N2, %0%>"
7209   [(set_attr "type" "cbranch_media")])
7211 (define_insn "*bgt_media_i32"
7212   [(set (pc)
7213         (if_then_else (match_operator 3 "greater_comparison_operator"
7214                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7215                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7216                       (match_operand 0 "target_operand" "b")
7217                       (pc)))]
7218   "TARGET_SHMEDIA"
7219   "b%o3%'       %N1, %N2, %0%>"
7220   [(set_attr "type" "cbranch_media")])
7222 ;; These are only needed to make invert_jump() happy - otherwise, jump
7223 ;; optimization will be silently disabled.
7224 (define_insn "*blt_media_i"
7225   [(set (pc)
7226         (if_then_else (match_operator 3 "less_comparison_operator"
7227                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
7228                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
7229                       (match_operand 0 "target_operand" "b")
7230                       (pc)))]
7231   "TARGET_SHMEDIA"
7232   "b%o3%'       %N2, %N1, %0%>"
7233   [(set_attr "type" "cbranch_media")])
7235 (define_insn "*blt_media_i32"
7236   [(set (pc)
7237         (if_then_else (match_operator 3 "less_comparison_operator"
7238                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7239                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7240                       (match_operand 0 "target_operand" "b")
7241                       (pc)))]
7242   "TARGET_SHMEDIA"
7243   "b%o3%'       %N2, %N1, %0%>"
7244   [(set_attr "type" "cbranch_media")])
7246 ;; combiner splitter for test-and-branch on single bit in register.  This
7247 ;; is endian dependent because the non-paradoxical subreg looks different
7248 ;; on big endian.
7249 (define_split
7250   [(set (pc)
7251         (if_then_else
7252           (match_operator 3 "equality_comparison_operator"
7253             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7254                                                       "extend_reg_operand" "")
7255                                                     0)
7256                                          (const_int 1)
7257                                          (match_operand 2
7258                                           "const_int_operand" "")) 0)
7259              (const_int 0)])
7260           (match_operand 0 "target_operand" "")
7261           (pc)))
7262    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7263   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7264   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7265    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7267   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7268   operands[6] = (GET_CODE (operands[3]) == EQ
7269                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7270                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7273 ; operand 0 is the loop count pseudo register
7274 ; operand 1 is the number of loop iterations or 0 if it is unknown
7275 ; operand 2 is the maximum number of loop iterations
7276 ; operand 3 is the number of levels of enclosed loops
7277 ; operand 4 is the label to jump to at the top of the loop
7279 (define_expand "doloop_end"
7280   [(parallel [(set (pc) (if_then_else
7281                           (ne:SI (match_operand:SI 0 "" "")
7282                               (const_int 1))
7283                           (label_ref (match_operand 4 "" ""))
7284                           (pc)))
7285               (set (match_dup 0)
7286                    (plus:SI (match_dup 0) (const_int -1)))
7287               (clobber (reg:SI T_REG))])]
7288   "TARGET_SH2"
7290   if (GET_MODE (operands[0]) != SImode)
7291     FAIL;
7294 (define_insn_and_split "doloop_end_split"
7295   [(set (pc)
7296         (if_then_else (ne:SI  (match_operand:SI 2 "arith_reg_dest" "0")
7297                           (const_int 1))
7298                       (label_ref (match_operand 1 "" ""))
7299                       (pc)))
7300    (set (match_operand:SI 0 "arith_reg_dest" "=r")
7301         (plus (match_dup 2) (const_int -1)))
7302    (clobber (reg:SI T_REG))]
7303   "TARGET_SH2"
7304   "#"
7305   ""
7306   [(parallel [(set (reg:SI T_REG)
7307                    (eq:SI (match_dup 2) (const_int 1)))
7308               (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7309    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7310                            (label_ref (match_dup 1))
7311                            (pc)))]
7312   ""
7313    [(set_attr "type" "cbranch")])
7316 ;; ------------------------------------------------------------------------
7317 ;; Jump and linkage insns
7318 ;; ------------------------------------------------------------------------
7320 (define_insn "jump_compact"
7321   [(set (pc)
7322         (label_ref (match_operand 0 "" "")))]
7323   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7325   /* The length is 16 if the delay slot is unfilled.  */
7326   if (get_attr_length(insn) > 4)
7327     return output_far_jump(insn, operands[0]);
7328   else
7329     return "bra %l0%#";
7331   [(set_attr "type" "jump")
7332    (set_attr "needs_delay_slot" "yes")])
7334 ;; ??? It would be much saner to explicitly use the scratch register
7335 ;; in the jump insn, and have indirect_jump_scratch only set it,
7336 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7337 ;; from the target then, as it uses simplejump_p.
7338 ;;(define_insn "jump_compact_far"
7339 ;;  [(set (pc)
7340 ;;      (label_ref (match_operand 0 "" "")))
7341 ;;   (use (match_operand 1 "register_operand" "r")]
7342 ;;  "TARGET_SH1"
7343 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7344 ;;  [(set_attr "type" "jump")
7345 ;;   (set_attr "needs_delay_slot" "yes")])
7347 (define_insn "jump_media"
7348   [(set (pc)
7349         (match_operand 0 "target_operand" "b"))]
7350   "TARGET_SHMEDIA"
7351   "blink        %0, r63%>"
7352   [(set_attr "type" "jump_media")])
7354 (define_expand "jump"
7355   [(set (pc)
7356         (label_ref (match_operand 0 "" "")))]
7357   ""
7359   if (TARGET_SH1)
7360     emit_jump_insn (gen_jump_compact (operands[0]));
7361   else if (TARGET_SHMEDIA)
7362     {
7363       if (reload_in_progress || reload_completed)
7364         FAIL;
7365       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7366                                                          operands[0])));
7367     }
7368   DONE;
7371 (define_insn "force_mode_for_call"
7372   [(use (reg:PSI FPSCR_REG))]
7373   "TARGET_SHCOMPACT"
7374   ""
7375   [(set_attr "length" "0")
7376    (set (attr "fp_mode")
7377         (if_then_else (eq_attr "fpu_single" "yes")
7378                       (const_string "single") (const_string "double")))])
7380 (define_insn "calli"
7381   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7382          (match_operand 1 "" ""))
7383    (use (reg:PSI FPSCR_REG))
7384    (clobber (reg:SI PR_REG))]
7385   "TARGET_SH1"
7387   if (TARGET_SH2A && (dbr_sequence_length () == 0))
7388     return "jsr/n\\t@%0";
7389   else
7390     return "jsr\\t@%0%#";
7392   [(set_attr "type" "call")
7393    (set (attr "fp_mode")
7394         (if_then_else (eq_attr "fpu_single" "yes")
7395                       (const_string "single") (const_string "double")))
7396    (set_attr "needs_delay_slot" "yes")
7397    (set_attr "fp_set" "unknown")])
7399 ;; This is TBR relative jump instruction for SH2A architecture.
7400 ;; Its use is enabled assigning an attribute "function_vector"
7401 ;; and the vector number to a function during its declaration.
7403 (define_insn "calli_tbr_rel"
7404   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7405          (match_operand 1 "" ""))
7406    (use (reg:PSI FPSCR_REG))
7407    (clobber (reg:SI PR_REG))]
7408   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7410   unsigned HOST_WIDE_INT vect_num;
7411   vect_num = sh2a_get_function_vector_number (operands[0]);
7412   operands[2] = GEN_INT (vect_num * 4);
7414   return "jsr/n\\t@@(%O2,tbr)";
7416   [(set_attr "type" "call")
7417    (set (attr "fp_mode")
7418         (if_then_else (eq_attr "fpu_single" "yes")
7419                       (const_string "single") (const_string "double")))
7420    (set_attr "needs_delay_slot" "no")
7421    (set_attr "fp_set" "unknown")])
7423 ;; This is a pc-rel call, using bsrf, for use with PIC.
7425 (define_insn "calli_pcrel"
7426   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7427          (match_operand 1 "" ""))
7428    (use (reg:PSI FPSCR_REG))
7429    (use (reg:SI PIC_REG))
7430    (use (match_operand 2 "" ""))
7431    (clobber (reg:SI PR_REG))]
7432   "TARGET_SH2"
7433   "bsrf %0\\n%O2:%#"
7434   [(set_attr "type" "call")
7435    (set (attr "fp_mode")
7436         (if_then_else (eq_attr "fpu_single" "yes")
7437                       (const_string "single") (const_string "double")))
7438    (set_attr "needs_delay_slot" "yes")
7439    (set_attr "fp_set" "unknown")])
7441 (define_insn_and_split "call_pcrel"
7442   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7443          (match_operand 1 "" ""))
7444    (use (reg:PSI FPSCR_REG))
7445    (use (reg:SI PIC_REG))
7446    (clobber (reg:SI PR_REG))
7447    (clobber (match_scratch:SI 2 "=r"))]
7448   "TARGET_SH2"
7449   "#"
7450   "reload_completed"
7451   [(const_int 0)]
7453   rtx lab = PATTERN (gen_call_site ());
7455   if (SYMBOL_REF_LOCAL_P (operands[0]))
7456     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7457   else
7458     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7459   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7460   DONE;
7462   [(set_attr "type" "call")
7463    (set (attr "fp_mode")
7464         (if_then_else (eq_attr "fpu_single" "yes")
7465                       (const_string "single") (const_string "double")))
7466    (set_attr "needs_delay_slot" "yes")
7467    (set_attr "fp_set" "unknown")])
7469 (define_insn "call_compact"
7470   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7471          (match_operand 1 "" ""))
7472    (match_operand 2 "immediate_operand" "n")
7473    (use (reg:SI R0_REG))
7474    (use (reg:SI R1_REG))
7475    (use (reg:PSI FPSCR_REG))
7476    (clobber (reg:SI PR_REG))]
7477   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7478   "jsr  @%0%#"
7479   [(set_attr "type" "call")
7480    (set (attr "fp_mode")
7481         (if_then_else (eq_attr "fpu_single" "yes")
7482                       (const_string "single") (const_string "double")))
7483    (set_attr "needs_delay_slot" "yes")])
7485 (define_insn "call_compact_rettramp"
7486   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7487          (match_operand 1 "" ""))
7488    (match_operand 2 "immediate_operand" "n")
7489    (use (reg:SI R0_REG))
7490    (use (reg:SI R1_REG))
7491    (use (reg:PSI FPSCR_REG))
7492    (clobber (reg:SI R10_REG))
7493    (clobber (reg:SI PR_REG))]
7494   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7495   "jsr  @%0%#"
7496   [(set_attr "type" "call")
7497    (set (attr "fp_mode")
7498         (if_then_else (eq_attr "fpu_single" "yes")
7499                       (const_string "single") (const_string "double")))
7500    (set_attr "needs_delay_slot" "yes")])
7502 (define_insn "call_media"
7503   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7504          (match_operand 1 "" ""))
7505    (clobber (reg:DI PR_MEDIA_REG))]
7506   "TARGET_SHMEDIA"
7507   "blink        %0, r18"
7508   [(set_attr "type" "jump_media")])
7510 (define_insn "call_valuei"
7511   [(set (match_operand 0 "" "=rf")
7512         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7513               (match_operand 2 "" "")))
7514    (use (reg:PSI FPSCR_REG))
7515    (clobber (reg:SI PR_REG))]
7516   "TARGET_SH1"
7518   if (TARGET_SH2A && (dbr_sequence_length () == 0))
7519     return "jsr/n\\t@%1";
7520   else
7521     return "jsr\\t@%1%#";
7523   [(set_attr "type" "call")
7524    (set (attr "fp_mode")
7525         (if_then_else (eq_attr "fpu_single" "yes")
7526                       (const_string "single") (const_string "double")))
7527    (set_attr "needs_delay_slot" "yes")
7528    (set_attr "fp_set" "unknown")])
7530 ;; This is TBR relative jump instruction for SH2A architecture.
7531 ;; Its use is enabled by assigning an attribute "function_vector"
7532 ;; and the vector number to a function during its declaration.
7534 (define_insn "call_valuei_tbr_rel"
7535   [(set (match_operand 0 "" "=rf")
7536         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7537               (match_operand 2 "" "")))
7538    (use (reg:PSI FPSCR_REG))
7539    (clobber (reg:SI PR_REG))]
7540   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7542   unsigned HOST_WIDE_INT vect_num;
7543   vect_num = sh2a_get_function_vector_number (operands[1]);
7544   operands[3] = GEN_INT (vect_num * 4);
7546   return "jsr/n\\t@@(%O3,tbr)";
7548   [(set_attr "type" "call")
7549    (set (attr "fp_mode")
7550         (if_then_else (eq_attr "fpu_single" "yes")
7551                       (const_string "single") (const_string "double")))
7552    (set_attr "needs_delay_slot" "no")
7553    (set_attr "fp_set" "unknown")])
7555 (define_insn "call_valuei_pcrel"
7556   [(set (match_operand 0 "" "=rf")
7557         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7558               (match_operand 2 "" "")))
7559    (use (reg:PSI FPSCR_REG))
7560    (use (reg:SI PIC_REG))
7561    (use (match_operand 3 "" ""))
7562    (clobber (reg:SI PR_REG))]
7563   "TARGET_SH2"
7564   "bsrf %1\\n%O3:%#"
7565   [(set_attr "type" "call")
7566    (set (attr "fp_mode")
7567         (if_then_else (eq_attr "fpu_single" "yes")
7568                       (const_string "single") (const_string "double")))
7569    (set_attr "needs_delay_slot" "yes")
7570    (set_attr "fp_set" "unknown")])
7572 (define_insn_and_split "call_value_pcrel"
7573   [(set (match_operand 0 "" "=rf")
7574         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7575               (match_operand 2 "" "")))
7576    (use (reg:PSI FPSCR_REG))
7577    (use (reg:SI PIC_REG))
7578    (clobber (reg:SI PR_REG))
7579    (clobber (match_scratch:SI 3 "=r"))]
7580   "TARGET_SH2"
7581   "#"
7582   "reload_completed"
7583   [(const_int 0)]
7585   rtx lab = PATTERN (gen_call_site ());
7587   if (SYMBOL_REF_LOCAL_P (operands[1]))
7588     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7589   else
7590     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7591   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7592                                          operands[2], copy_rtx (lab)));
7593   DONE;
7595   [(set_attr "type" "call")
7596    (set (attr "fp_mode")
7597         (if_then_else (eq_attr "fpu_single" "yes")
7598                       (const_string "single") (const_string "double")))
7599    (set_attr "needs_delay_slot" "yes")
7600    (set_attr "fp_set" "unknown")])
7602 (define_insn "call_value_compact"
7603   [(set (match_operand 0 "" "=rf")
7604         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7605               (match_operand 2 "" "")))
7606    (match_operand 3 "immediate_operand" "n")
7607    (use (reg:SI R0_REG))
7608    (use (reg:SI R1_REG))
7609    (use (reg:PSI FPSCR_REG))
7610    (clobber (reg:SI PR_REG))]
7611   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7612   "jsr  @%1%#"
7613   [(set_attr "type" "call")
7614    (set (attr "fp_mode")
7615         (if_then_else (eq_attr "fpu_single" "yes")
7616                       (const_string "single") (const_string "double")))
7617    (set_attr "needs_delay_slot" "yes")])
7619 (define_insn "call_value_compact_rettramp"
7620   [(set (match_operand 0 "" "=rf")
7621         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7622               (match_operand 2 "" "")))
7623    (match_operand 3 "immediate_operand" "n")
7624    (use (reg:SI R0_REG))
7625    (use (reg:SI R1_REG))
7626    (use (reg:PSI FPSCR_REG))
7627    (clobber (reg:SI R10_REG))
7628    (clobber (reg:SI PR_REG))]
7629   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7630   "jsr  @%1%#"
7631   [(set_attr "type" "call")
7632    (set (attr "fp_mode")
7633         (if_then_else (eq_attr "fpu_single" "yes")
7634                       (const_string "single") (const_string "double")))
7635    (set_attr "needs_delay_slot" "yes")])
7637 (define_insn "call_value_media"
7638   [(set (match_operand 0 "" "=rf")
7639         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7640               (match_operand 2 "" "")))
7641    (clobber (reg:DI PR_MEDIA_REG))]
7642   "TARGET_SHMEDIA"
7643   "blink        %1, r18"
7644   [(set_attr "type" "jump_media")])
7646 (define_expand "call"
7647   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7648                             (match_operand 1 "" ""))
7649               (match_operand 2 "" "")
7650               (use (reg:PSI FPSCR_REG))
7651               (clobber (reg:SI PR_REG))])]
7652   ""
7654   if (TARGET_SHMEDIA)
7655     {
7656       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7657       emit_call_insn (gen_call_media (operands[0], operands[1]));
7658       DONE;
7659     }
7660   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7661     {
7662       rtx cookie_rtx = operands[2];
7663       long cookie = INTVAL (cookie_rtx);
7664       rtx func = XEXP (operands[0], 0);
7665       rtx r0, r1;
7667       if (flag_pic)
7668         {
7669           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7670             {
7671               rtx reg = gen_reg_rtx (Pmode);
7673               emit_insn (gen_symGOTPLT2reg (reg, func));
7674               func = reg;
7675             }
7676           else
7677             func = legitimize_pic_address (func, Pmode, 0);
7678         }
7680       r0 = gen_rtx_REG (SImode, R0_REG);
7681       r1 = gen_rtx_REG (SImode, R1_REG);
7683       /* Since such a call function may use all call-clobbered
7684          registers, we force a mode switch earlier, so that we don't
7685          run out of registers when adjusting fpscr for the call.  */
7686       emit_insn (gen_force_mode_for_call ());
7688       operands[0]
7689         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
7690       operands[0] = force_reg (SImode, operands[0]);
7692       emit_move_insn (r0, func);
7693       emit_move_insn (r1, cookie_rtx);
7695       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7696         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7697                                                    operands[2]));
7698       else
7699         emit_call_insn (gen_call_compact (operands[0], operands[1],
7700                                           operands[2]));
7702       DONE;
7703     }
7704   else if (TARGET_SHCOMPACT && flag_pic
7705            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7706            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7707     {
7708       rtx reg = gen_reg_rtx (Pmode);
7710       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7711       XEXP (operands[0], 0) = reg;
7712     }
7713   if (!flag_pic && TARGET_SH2A
7714       && MEM_P (operands[0])
7715       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7716     {
7717       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7718         {
7719           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7720                                              operands[1]));
7721           DONE;
7722         }
7723     }
7724   if (flag_pic && TARGET_SH2
7725       && MEM_P (operands[0])
7726       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7727     {
7728       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7729       DONE;
7730     }
7731   else
7732   {
7733     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7734     operands[1] = operands[2];
7735   }
7737   emit_call_insn (gen_calli (operands[0], operands[1]));
7738   DONE;
7741 (define_insn "call_pop_compact"
7742   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7743          (match_operand 1 "" ""))
7744    (match_operand 2 "immediate_operand" "n")
7745    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7746                                  (match_operand 3 "immediate_operand" "n")))
7747    (use (reg:SI R0_REG))
7748    (use (reg:SI R1_REG))
7749    (use (reg:PSI FPSCR_REG))
7750    (clobber (reg:SI PR_REG))]
7751   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7752   "jsr  @%0%#"
7753   [(set_attr "type" "call")
7754    (set (attr "fp_mode")
7755         (if_then_else (eq_attr "fpu_single" "yes")
7756                       (const_string "single") (const_string "double")))
7757    (set_attr "needs_delay_slot" "yes")])
7759 (define_insn "call_pop_compact_rettramp"
7760   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7761          (match_operand 1 "" ""))
7762    (match_operand 2 "immediate_operand" "n")
7763    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7764                                  (match_operand 3 "immediate_operand" "n")))
7765    (use (reg:SI R0_REG))
7766    (use (reg:SI R1_REG))
7767    (use (reg:PSI FPSCR_REG))
7768    (clobber (reg:SI R10_REG))
7769    (clobber (reg:SI PR_REG))]
7770   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7771   "jsr  @%0%#"
7772   [(set_attr "type" "call")
7773    (set (attr "fp_mode")
7774         (if_then_else (eq_attr "fpu_single" "yes")
7775                       (const_string "single") (const_string "double")))
7776    (set_attr "needs_delay_slot" "yes")])
7778 (define_expand "call_pop"
7779   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7780                     (match_operand 1 "" ""))
7781              (match_operand 2 "" "")
7782              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7783                                            (match_operand 3 "" "")))])]
7784   "TARGET_SHCOMPACT"
7786   rtx cookie_rtx;
7787   long cookie;
7788   rtx func;
7789   rtx r0, r1;
7791   gcc_assert (operands[2] && INTVAL (operands[2]));
7792   cookie_rtx = operands[2];
7793   cookie = INTVAL (cookie_rtx);
7794   func = XEXP (operands[0], 0);
7796   if (flag_pic)
7797     {
7798       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7799         {
7800           rtx reg = gen_reg_rtx (Pmode);
7801           emit_insn (gen_symGOTPLT2reg (reg, func));
7802           func = reg;
7803         }
7804       else
7805         func = legitimize_pic_address (func, Pmode, 0);
7806     }
7808   r0 = gen_rtx_REG (SImode, R0_REG);
7809   r1 = gen_rtx_REG (SImode, R1_REG);
7811   /* Since such a call function may use all call-clobbered
7812      registers, we force a mode switch earlier, so that we don't
7813      run out of registers when adjusting fpscr for the call.  */
7814   emit_insn (gen_force_mode_for_call ());
7816   operands[0] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
7817                                  SFUNC_GOT);
7818   operands[0] = force_reg (SImode, operands[0]);
7820   emit_move_insn (r0, func);
7821   emit_move_insn (r1, cookie_rtx);
7823   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7824     emit_call_insn (gen_call_pop_compact_rettramp
7825                      (operands[0], operands[1], operands[2], operands[3]));
7826   else
7827     emit_call_insn (gen_call_pop_compact
7828                      (operands[0], operands[1], operands[2], operands[3]));
7830   DONE;
7833 (define_expand "call_value"
7834   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7835                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7836                                  (match_operand 2 "" "")))
7837               (match_operand 3 "" "")
7838               (use (reg:PSI FPSCR_REG))
7839               (clobber (reg:SI PR_REG))])]
7840   ""
7842   if (TARGET_SHMEDIA)
7843     {
7844       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7845       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7846                                             operands[2]));
7847       DONE;
7848     }
7849   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7850     {
7851       rtx cookie_rtx = operands[3];
7852       long cookie = INTVAL (cookie_rtx);
7853       rtx func = XEXP (operands[1], 0);
7854       rtx r0, r1;
7856       if (flag_pic)
7857         {
7858           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7859             {
7860               rtx reg = gen_reg_rtx (Pmode);
7862               emit_insn (gen_symGOTPLT2reg (reg, func));
7863               func = reg;
7864             }
7865           else
7866             func = legitimize_pic_address (func, Pmode, 0);
7867         }
7869       r0 = gen_rtx_REG (SImode, R0_REG);
7870       r1 = gen_rtx_REG (SImode, R1_REG);
7872       /* Since such a call function may use all call-clobbered
7873          registers, we force a mode switch earlier, so that we don't
7874          run out of registers when adjusting fpscr for the call.  */
7875       emit_insn (gen_force_mode_for_call ());
7877       operands[1]
7878         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
7879       operands[1] = force_reg (SImode, operands[1]);
7881       emit_move_insn (r0, func);
7882       emit_move_insn (r1, cookie_rtx);
7884       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7885         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7886                                                          operands[1],
7887                                                          operands[2],
7888                                                          operands[3]));
7889       else
7890         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7891                                                 operands[2], operands[3]));
7893       DONE;
7894     }
7895   else if (TARGET_SHCOMPACT && flag_pic
7896            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7897            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7898     {
7899       rtx reg = gen_reg_rtx (Pmode);
7901       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7902       XEXP (operands[1], 0) = reg;
7903     }
7904   if (!flag_pic && TARGET_SH2A
7905       && MEM_P (operands[1])
7906       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7907     {
7908       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7909         {
7910           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7911                                  XEXP (operands[1], 0), operands[2]));
7912           DONE;
7913         }
7914     }
7915   if (flag_pic && TARGET_SH2
7916       && MEM_P (operands[1])
7917       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7918     {
7919       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7920                                             operands[2]));
7921       DONE;
7922     }
7923   else
7924     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7926   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7927   DONE;
7930 (define_insn "sibcalli"
7931   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7932          (match_operand 1 "" ""))
7933    (use (reg:PSI FPSCR_REG))
7934    (return)]
7935   "TARGET_SH1"
7936   "jmp  @%0%#"
7937   [(set_attr "needs_delay_slot" "yes")
7938    (set (attr "fp_mode")
7939         (if_then_else (eq_attr "fpu_single" "yes")
7940                       (const_string "single") (const_string "double")))
7941    (set_attr "type" "jump_ind")])
7943 (define_insn "sibcalli_pcrel"
7944   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7945          (match_operand 1 "" ""))
7946    (use (match_operand 2 "" ""))
7947    (use (reg:PSI FPSCR_REG))
7948    (return)]
7949   "TARGET_SH2"
7950   "braf %0\\n%O2:%#"
7951   [(set_attr "needs_delay_slot" "yes")
7952    (set (attr "fp_mode")
7953         (if_then_else (eq_attr "fpu_single" "yes")
7954                       (const_string "single") (const_string "double")))
7955    (set_attr "type" "jump_ind")])
7957 ;; This uses an unspec to describe that the symbol_ref is very close.
7958 (define_insn "sibcalli_thunk"
7959   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7960                              UNSPEC_THUNK))
7961          (match_operand 1 "" ""))
7962    (use (reg:PSI FPSCR_REG))
7963    (return)]
7964   "TARGET_SH1"
7965   "bra  %O0"
7966   [(set_attr "needs_delay_slot" "yes")
7967    (set (attr "fp_mode")
7968         (if_then_else (eq_attr "fpu_single" "yes")
7969                       (const_string "single") (const_string "double")))
7970    (set_attr "type" "jump")
7971    (set_attr "length" "2")])
7973 (define_insn_and_split "sibcall_pcrel"
7974   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7975          (match_operand 1 "" ""))
7976    (use (reg:PSI FPSCR_REG))
7977    (clobber (match_scratch:SI 2 "=k"))
7978    (return)]
7979   "TARGET_SH2"
7980   "#"
7981   "reload_completed"
7982   [(const_int 0)]
7984   rtx lab = PATTERN (gen_call_site ());
7985   rtx call_insn;
7987   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7988   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7989                                                   copy_rtx (lab)));
7990   SIBLING_CALL_P (call_insn) = 1;
7991   DONE;
7993   [(set_attr "needs_delay_slot" "yes")
7994    (set (attr "fp_mode")
7995         (if_then_else (eq_attr "fpu_single" "yes")
7996                       (const_string "single") (const_string "double")))
7997    (set_attr "type" "jump_ind")])
7999 (define_insn "sibcall_compact"
8000   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
8001          (match_operand 1 "" ""))
8002    (return)
8003    (use (match_operand:SI 2 "register_operand" "z,x"))
8004    (use (reg:SI R1_REG))
8005    (use (reg:PSI FPSCR_REG))
8006    ;; We want to make sure the `x' above will only match MACH_REG
8007    ;; because sibcall_epilogue may clobber MACL_REG.
8008    (clobber (reg:SI MACL_REG))]
8009   "TARGET_SHCOMPACT"
8010   "@
8011         jmp     @%0%#
8012         jmp     @%0\\n  sts     %2, r0"
8013   [(set_attr "needs_delay_slot" "yes,no")
8014    (set_attr "length" "2,4")
8015    (set (attr "fp_mode") (const_string "single"))
8016    (set_attr "type" "jump_ind")])
8018 (define_insn "sibcall_media"
8019   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8020          (match_operand 1 "" ""))
8021    (use (reg:SI PR_MEDIA_REG))
8022    (return)]
8023   "TARGET_SHMEDIA"
8024   "blink        %0, r63"
8025   [(set_attr "type" "jump_media")])
8027 (define_expand "sibcall"
8028   [(parallel
8029     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8030            (match_operand 1 "" ""))
8031      (match_operand 2 "" "")
8032      (use (reg:PSI FPSCR_REG))
8033      (return)])]
8034   ""
8036   if (TARGET_SHMEDIA)
8037     {
8038       operands[0] = shmedia_prepare_call_address (operands[0], 1);
8039       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8040       DONE;
8041     }
8042   else if (TARGET_SHCOMPACT && operands[2]
8043            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8044     {
8045       rtx cookie_rtx = operands[2];
8046       long cookie = INTVAL (cookie_rtx);
8047       rtx func = XEXP (operands[0], 0);
8048       rtx mach, r1;
8050       if (flag_pic)
8051         {
8052           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8053             {
8054               rtx reg = gen_reg_rtx (Pmode);
8056               emit_insn (gen_symGOT2reg (reg, func));
8057               func = reg;
8058             }
8059           else
8060             func = legitimize_pic_address (func, Pmode, 0);
8061         }
8063       /* FIXME: if we could tell whether all argument registers are
8064          already taken, we could decide whether to force the use of
8065          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8066          simple way to tell.  We could use the CALL_COOKIE, but we
8067          can't currently tell a register used for regular argument
8068          passing from one that is unused.  If we leave it up to reload
8069          to decide which register to use, it seems to always choose
8070          R0_REG, which leaves no available registers in SIBCALL_REGS
8071          to hold the address of the trampoline.  */
8072       mach = gen_rtx_REG (SImode, MACH_REG);
8073       r1 = gen_rtx_REG (SImode, R1_REG);
8075       /* Since such a call function may use all call-clobbered
8076          registers, we force a mode switch earlier, so that we don't
8077          run out of registers when adjusting fpscr for the call.  */
8078       emit_insn (gen_force_mode_for_call ());
8080       operands[0]
8081         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
8082       operands[0] = force_reg (SImode, operands[0]);
8084       /* We don't need a return trampoline, since the callee will
8085          return directly to the upper caller.  */
8086       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8087         {
8088           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8089           cookie_rtx = GEN_INT (cookie);
8090         }
8092       emit_move_insn (mach, func);
8093       emit_move_insn (r1, cookie_rtx);
8095       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8096       DONE;
8097     }
8098   else if (TARGET_SHCOMPACT && flag_pic
8099            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8100            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8101     {
8102       rtx reg = gen_reg_rtx (Pmode);
8104       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8105       XEXP (operands[0], 0) = reg;
8106     }
8107   if (flag_pic && TARGET_SH2
8108       && MEM_P (operands[0])
8109       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8110       /* The PLT needs the PIC register, but the epilogue would have
8111          to restore it, so we can only use PC-relative PIC calls for
8112          static functions.  */
8113       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8114     {
8115       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8116       DONE;
8117     }
8118   else
8119     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8121   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8122   DONE;
8125 (define_insn "sibcall_valuei"
8126   [(set (match_operand 0 "" "=rf")
8127         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8128               (match_operand 2 "" "")))
8129    (use (reg:PSI FPSCR_REG))
8130    (return)]
8131   "TARGET_SH1"
8132   "jmp  @%1%#"
8133   [(set_attr "needs_delay_slot" "yes")
8134    (set (attr "fp_mode")
8135         (if_then_else (eq_attr "fpu_single" "yes")
8136                       (const_string "single") (const_string "double")))
8137    (set_attr "type" "jump_ind")])
8139 (define_insn "sibcall_valuei_pcrel"
8140   [(set (match_operand 0 "" "=rf")
8141         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8142               (match_operand 2 "" "")))
8143    (use (match_operand 3 "" ""))
8144    (use (reg:PSI FPSCR_REG))
8145    (return)]
8146   "TARGET_SH2"
8147   "braf %1\\n%O3:%#"
8148   [(set_attr "needs_delay_slot" "yes")
8149    (set (attr "fp_mode")
8150         (if_then_else (eq_attr "fpu_single" "yes")
8151                       (const_string "single") (const_string "double")))
8152    (set_attr "type" "jump_ind")])
8154 (define_insn_and_split "sibcall_value_pcrel"
8155   [(set (match_operand 0 "" "=rf")
8156         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8157               (match_operand 2 "" "")))
8158    (use (reg:PSI FPSCR_REG))
8159    (clobber (match_scratch:SI 3 "=k"))
8160    (return)]
8161   "TARGET_SH2"
8162   "#"
8163   "reload_completed"
8164   [(const_int 0)]
8166   rtx lab = PATTERN (gen_call_site ());
8167   rtx call_insn;
8169   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8170   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8171                                                         operands[3],
8172                                                         operands[2],
8173                                                         copy_rtx (lab)));
8174   SIBLING_CALL_P (call_insn) = 1;
8175   DONE;
8177   [(set_attr "needs_delay_slot" "yes")
8178    (set (attr "fp_mode")
8179         (if_then_else (eq_attr "fpu_single" "yes")
8180                       (const_string "single") (const_string "double")))
8181    (set_attr "type" "jump_ind")])
8183 (define_insn "sibcall_value_compact"
8184   [(set (match_operand 0 "" "=rf,rf")
8185         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8186               (match_operand 2 "" "")))
8187    (return)
8188    (use (match_operand:SI 3 "register_operand" "z,x"))
8189    (use (reg:SI R1_REG))
8190    (use (reg:PSI FPSCR_REG))
8191    ;; We want to make sure the `x' above will only match MACH_REG
8192    ;; because sibcall_epilogue may clobber MACL_REG.
8193    (clobber (reg:SI MACL_REG))]
8194   "TARGET_SHCOMPACT"
8195   "@
8196         jmp     @%1%#
8197         jmp     @%1\\n  sts     %3, r0"
8198   [(set_attr "needs_delay_slot" "yes,no")
8199    (set_attr "length" "2,4")
8200    (set (attr "fp_mode") (const_string "single"))
8201    (set_attr "type" "jump_ind")])
8203 (define_insn "sibcall_value_media"
8204   [(set (match_operand 0 "" "=rf")
8205         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8206               (match_operand 2 "" "")))
8207    (use (reg:SI PR_MEDIA_REG))
8208    (return)]
8209   "TARGET_SHMEDIA"
8210   "blink        %1, r63"
8211   [(set_attr "type" "jump_media")])
8213 (define_expand "sibcall_value"
8214   [(parallel
8215     [(set (match_operand 0 "arith_reg_operand" "")
8216           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8217                 (match_operand 2 "" "")))
8218      (match_operand 3 "" "")
8219      (use (reg:PSI FPSCR_REG))
8220      (return)])]
8221   ""
8223   if (TARGET_SHMEDIA)
8224     {
8225       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8226       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8227                                                operands[2]));
8228       DONE;
8229     }
8230   else if (TARGET_SHCOMPACT && operands[3]
8231            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8232     {
8233       rtx cookie_rtx = operands[3];
8234       long cookie = INTVAL (cookie_rtx);
8235       rtx func = XEXP (operands[1], 0);
8236       rtx mach, r1;
8238       if (flag_pic)
8239         {
8240           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8241             {
8242               rtx reg = gen_reg_rtx (Pmode);
8244               emit_insn (gen_symGOT2reg (reg, func));
8245               func = reg;
8246             }
8247           else
8248             func = legitimize_pic_address (func, Pmode, 0);
8249         }
8251       /* FIXME: if we could tell whether all argument registers are
8252          already taken, we could decide whether to force the use of
8253          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8254          simple way to tell.  We could use the CALL_COOKIE, but we
8255          can't currently tell a register used for regular argument
8256          passing from one that is unused.  If we leave it up to reload
8257          to decide which register to use, it seems to always choose
8258          R0_REG, which leaves no available registers in SIBCALL_REGS
8259          to hold the address of the trampoline.  */
8260       mach = gen_rtx_REG (SImode, MACH_REG);
8261       r1 = gen_rtx_REG (SImode, R1_REG);
8263       /* Since such a call function may use all call-clobbered
8264          registers, we force a mode switch earlier, so that we don't
8265          run out of registers when adjusting fpscr for the call.  */
8266       emit_insn (gen_force_mode_for_call ());
8268       operands[1]
8269         = function_symbol (NULL, "__GCC_shcompact_call_trampoline", SFUNC_GOT);
8270       operands[1] = force_reg (SImode, operands[1]);
8272       /* We don't need a return trampoline, since the callee will
8273          return directly to the upper caller.  */
8274       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8275         {
8276           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8277           cookie_rtx = GEN_INT (cookie);
8278         }
8280       emit_move_insn (mach, func);
8281       emit_move_insn (r1, cookie_rtx);
8283       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8284                                                  operands[2], mach));
8285       DONE;
8286     }
8287   else if (TARGET_SHCOMPACT && flag_pic
8288            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8289            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8290     {
8291       rtx reg = gen_reg_rtx (Pmode);
8293       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8294       XEXP (operands[1], 0) = reg;
8295     }
8296   if (flag_pic && TARGET_SH2
8297       && MEM_P (operands[1])
8298       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8299       /* The PLT needs the PIC register, but the epilogue would have
8300          to restore it, so we can only use PC-relative PIC calls for
8301          static functions.  */
8302       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8303     {
8304       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8305                                                XEXP (operands[1], 0),
8306                                                operands[2]));
8307       DONE;
8308     }
8309   else
8310     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8312   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8313   DONE;
8316 (define_insn "call_value_pop_compact"
8317   [(set (match_operand 0 "" "=rf")
8318         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8319               (match_operand 2 "" "")))
8320    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8321                                  (match_operand 4 "immediate_operand" "n")))
8322    (match_operand 3 "immediate_operand" "n")
8323    (use (reg:SI R0_REG))
8324    (use (reg:SI R1_REG))
8325    (use (reg:PSI FPSCR_REG))
8326    (clobber (reg:SI PR_REG))]
8327   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8328   "jsr  @%1%#"
8329   [(set_attr "type" "call")
8330    (set (attr "fp_mode")
8331         (if_then_else (eq_attr "fpu_single" "yes")
8332                       (const_string "single") (const_string "double")))
8333    (set_attr "needs_delay_slot" "yes")])
8335 (define_insn "call_value_pop_compact_rettramp"
8336   [(set (match_operand 0 "" "=rf")
8337         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8338               (match_operand 2 "" "")))
8339    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8340                                  (match_operand 4 "immediate_operand" "n")))
8341    (match_operand 3 "immediate_operand" "n")
8342    (use (reg:SI R0_REG))
8343    (use (reg:SI R1_REG))
8344    (use (reg:PSI FPSCR_REG))
8345    (clobber (reg:SI R10_REG))
8346    (clobber (reg:SI PR_REG))]
8347   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8348   "jsr  @%1%#"
8349   [(set_attr "type" "call")
8350    (set (attr "fp_mode")
8351         (if_then_else (eq_attr "fpu_single" "yes")
8352                       (const_string "single") (const_string "double")))
8353    (set_attr "needs_delay_slot" "yes")])
8355 (define_expand "call_value_pop"
8356   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8357                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8358                                  (match_operand 2 "" "")))
8359               (match_operand 3 "" "")
8360               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8361                                             (match_operand 4 "" "")))])]
8362   "TARGET_SHCOMPACT"
8364   rtx cookie_rtx;
8365   long cookie;
8366   rtx func;
8367   rtx r0, r1;
8369   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8370   cookie_rtx = operands[3];
8371   cookie = INTVAL (cookie_rtx);
8372   func = XEXP (operands[1], 0);
8374   if (flag_pic)
8375     {
8376       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8377         {
8378           rtx reg = gen_reg_rtx (Pmode);
8380           emit_insn (gen_symGOTPLT2reg (reg, func));
8381           func = reg;
8382         }
8383       else
8384         func = legitimize_pic_address (func, Pmode, 0);
8385     }
8387   r0 = gen_rtx_REG (SImode, R0_REG);
8388   r1 = gen_rtx_REG (SImode, R1_REG);
8390   /* Since such a call function may use all call-clobbered
8391      registers, we force a mode switch earlier, so that we don't
8392      run out of registers when adjusting fpscr for the call.  */
8393   emit_insn (gen_force_mode_for_call ());
8395   operands[1] = function_symbol (NULL, "__GCC_shcompact_call_trampoline",
8396                                  SFUNC_GOT);
8397   operands[1] = force_reg (SImode, operands[1]);
8399   emit_move_insn (r0, func);
8400   emit_move_insn (r1, cookie_rtx);
8402   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8403     emit_call_insn (gen_call_value_pop_compact_rettramp
8404                         (operands[0], operands[1], operands[2],
8405                          operands[3], operands[4]));
8406   else
8407     emit_call_insn (gen_call_value_pop_compact
8408                         (operands[0], operands[1], operands[2],
8409                          operands[3], operands[4]));
8411   DONE;
8414 (define_expand "sibcall_epilogue"
8415   [(return)]
8416   ""
8418   sh_expand_epilogue (1);
8419   if (TARGET_SHCOMPACT)
8420     {
8421       rtx insn, set;
8423       /* If epilogue clobbers r0, preserve it in macl.  */
8424       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8425         if ((set = single_set (insn))
8426             && REG_P (SET_DEST (set))
8427             && REGNO (SET_DEST (set)) == R0_REG)
8428           {
8429             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8430             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8432             /* We can't tell at this point whether the sibcall is a
8433                sibcall_compact and, if it is, whether it uses r0 or
8434                mach as operand 2, so let the instructions that
8435                preserve r0 be optimized away if r0 turns out to be
8436                dead.  */
8437             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8438             emit_move_insn (r0, tmp);
8439             break;
8440           }
8441     }
8442   DONE;
8445 (define_insn "indirect_jump_compact"
8446   [(set (pc)
8447         (match_operand:SI 0 "arith_reg_operand" "r"))]
8448   "TARGET_SH1"
8449   "jmp  @%0%#"
8450   [(set_attr "needs_delay_slot" "yes")
8451    (set_attr "type" "jump_ind")])
8453 (define_expand "indirect_jump"
8454   [(set (pc)
8455         (match_operand 0 "register_operand" ""))]
8456   ""
8458   if (GET_MODE (operands[0]) != Pmode)
8459     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8462 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8463 ;; which can be present in structured code from indirect jumps which can not
8464 ;; be present in structured code.  This allows -fprofile-arcs to work.
8466 ;; For SH1 processors.
8467 (define_insn "casesi_jump_1"
8468   [(set (pc)
8469         (match_operand:SI 0 "register_operand" "r"))
8470    (use (label_ref (match_operand 1 "" "")))]
8471   "TARGET_SH1"
8472   "jmp  @%0%#"
8473   [(set_attr "needs_delay_slot" "yes")
8474    (set_attr "type" "jump_ind")])
8476 ;; For all later processors.
8477 (define_insn "casesi_jump_2"
8478   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8479                       (label_ref (match_operand 1 "" ""))))
8480    (use (label_ref (match_operand 2 "" "")))]
8481   "TARGET_SH2
8482    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8483   "braf %0%#"
8484   [(set_attr "needs_delay_slot" "yes")
8485    (set_attr "type" "jump_ind")])
8487 (define_insn "casesi_jump_media"
8488   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8489    (use (label_ref (match_operand 1 "" "")))]
8490   "TARGET_SHMEDIA"
8491   "blink        %0, r63"
8492   [(set_attr "type" "jump_media")])
8494 ;; Call subroutine returning any type.
8495 ;; ??? This probably doesn't work.
8497 (define_expand "untyped_call"
8498   [(parallel [(call (match_operand 0 "" "")
8499                     (const_int 0))
8500               (match_operand 1 "" "")
8501               (match_operand 2 "" "")])]
8502   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8504   int i;
8506   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8508   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8509     {
8510       rtx set = XVECEXP (operands[2], 0, i);
8511       emit_move_insn (SET_DEST (set), SET_SRC (set));
8512     }
8514   /* The optimizer does not know that the call sets the function value
8515      registers we stored in the result block.  We avoid problems by
8516      claiming that all hard registers are used and clobbered at this
8517      point.  */
8518   emit_insn (gen_blockage ());
8520   DONE;
8523 ;; ------------------------------------------------------------------------
8524 ;; Misc insns
8525 ;; ------------------------------------------------------------------------
8527 (define_insn "dect"
8528   [(set (reg:SI T_REG)
8529         (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8530    (set (match_operand:SI 0 "arith_reg_dest" "=r")
8531         (plus:SI (match_dup 1) (const_int -1)))]
8532   "TARGET_SH2"
8533   "dt   %0"
8534   [(set_attr "type" "arith")])
8536 (define_insn "nop"
8537   [(const_int 0)]
8538   ""
8539   "nop")
8541 ;; Load address of a label. This is only generated by the casesi expand,
8542 ;; and by machine_dependent_reorg (fixing up fp moves).
8543 ;; This must use unspec, because this only works for labels that are
8544 ;; within range,
8546 (define_insn "mova"
8547   [(set (reg:SI R0_REG)
8548         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8549   "TARGET_SH1"
8550   "mova %O0,r0"
8551   [(set_attr "in_delay_slot" "no")
8552    (set_attr "type" "arith")])
8554 ;; machine_dependent_reorg will make this a `mova'.
8555 (define_insn "mova_const"
8556   [(set (reg:SI R0_REG)
8557         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8558   "TARGET_SH1"
8559   "#"
8560   [(set_attr "in_delay_slot" "no")
8561    (set_attr "type" "arith")])
8563 (define_expand "GOTaddr2picreg"
8564   [(set (reg:SI R0_REG)
8565         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8566                    UNSPEC_MOVA))
8567    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8568    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8569   ""
8571   if (TARGET_VXWORKS_RTP)
8572     {
8573       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8574       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8575       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8576       DONE;
8577     }
8579   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8580   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8582   if (TARGET_SHMEDIA)
8583     {
8584       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8585       rtx pic = operands[0];
8586       rtx lab = PATTERN (gen_call_site ());
8587       rtx insn, equiv;
8589       equiv = operands[1];
8590       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8591                                     UNSPEC_PCREL_SYMOFF);
8592       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8594       if (Pmode == SImode)
8595         {
8596           emit_insn (gen_movsi_const (pic, operands[1]));
8597           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8598         }
8599       else
8600         {
8601           emit_insn (gen_movdi_const (pic, operands[1]));
8602           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8603         }
8605       insn = emit_move_insn (operands[0], tr);
8607       set_unique_reg_note (insn, REG_EQUAL, equiv);
8609       DONE;
8610     }
8613 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8614 ;; PIC register.
8616 (define_expand "vxworks_picreg"
8617   [(set (reg:SI PIC_REG)
8618         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8619    (set (reg:SI R0_REG)
8620         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8621    (set (reg:SI PIC_REG)
8622         (mem:SI (reg:SI PIC_REG)))
8623    (set (reg:SI PIC_REG)
8624         (mem:SI (plus:SI (reg:SI PIC_REG)
8625                          (reg:SI R0_REG))))]
8626   "TARGET_VXWORKS_RTP")
8628 (define_insn "*ptb"
8629   [(set (match_operand 0 "target_reg_operand" "=b")
8630         (const (unspec [(match_operand 1 "" "Csy")]
8631                              UNSPEC_DATALABEL)))]
8632   "TARGET_SHMEDIA && flag_pic
8633    && satisfies_constraint_Csy (operands[1])"
8634   "ptb/u        datalabel %1, %0"
8635   [(set_attr "type" "ptabs_media")
8636    (set_attr "length" "*")])
8638 (define_insn "ptrel_si"
8639   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8640         (plus:SI (match_operand:SI 1 "register_operand" "r")
8641               (pc)))
8642    (match_operand:SI 2 "" "")]
8643   "TARGET_SHMEDIA"
8644   "%O2: ptrel/u %1, %0"
8645   [(set_attr "type" "ptabs_media")])
8647 (define_insn "ptrel_di"
8648   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8649         (plus:DI (match_operand:DI 1 "register_operand" "r")
8650               (pc)))
8651    (match_operand:DI 2 "" "")]
8652   "TARGET_SHMEDIA"
8653   "%O2: ptrel/u %1, %0"
8654   [(set_attr "type" "ptabs_media")])
8656 (define_expand "builtin_setjmp_receiver"
8657   [(match_operand 0 "" "")]
8658   "flag_pic"
8660   emit_insn (gen_GOTaddr2picreg ());
8661   DONE;
8664 (define_expand "call_site"
8665   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8666   "TARGET_SH1"
8668   static HOST_WIDE_INT i = 0;
8669   operands[0] = GEN_INT (i);
8670   i++;
8673 ;; op0 = op1 + r12 but hide it before reload completed.  See the comment
8674 ;; in symGOT_load expand.
8676 (define_insn_and_split "chk_guard_add"
8677   [(set (match_operand:SI 0 "register_operand" "=&r")
8678         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8679                     (reg:SI PIC_REG)]
8680                    UNSPEC_CHKADD))]
8681   "TARGET_SH1"
8682   "#"
8683   "TARGET_SH1 && reload_completed"
8684   [(set (match_dup 0) (reg:SI PIC_REG))
8685    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
8686   ""
8687   [(set_attr "type" "arith")])
8689 (define_expand "sym_label2reg"
8690   [(set (match_operand:SI 0 "" "")
8691         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8692                               (const (plus:SI (match_operand:SI 2 "" "")
8693                                               (const_int 2)))]
8694                              UNSPEC_SYMOFF)))]
8695   "TARGET_SH1" "")
8697 (define_expand "symGOT_load"
8698   [(set (match_dup 2) (match_operand 1 "" ""))
8699    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8700    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8701   ""
8703   rtx mem;
8705   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8706   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8708   if (TARGET_SHMEDIA)
8709     {
8710       rtx reg = operands[2];
8712       if (Pmode == DImode)
8713         {      
8714           if (flag_pic > 1)
8715             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8716           else
8717             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8718         }
8719       else
8720         {
8721           if (flag_pic > 1)
8722             emit_insn (gen_movsi_const (reg, operands[1]));
8723           else
8724             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8725         }
8726     }
8727   else
8728     emit_move_insn (operands[2], operands[1]);
8730   /* When stack protector inserts codes after the result is set to
8731      R0, @(rX, r12) will cause a spill failure for R0.  Use a unspec
8732      insn to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8733      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8734      matter because this is a rare situation.  */
8735   if (!TARGET_SHMEDIA
8736       && flag_stack_protect
8737       && GET_CODE (operands[1]) == CONST
8738       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8739       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8740       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8741                  "__stack_chk_guard") == 0)
8742     emit_insn (gen_chk_guard_add (operands[3], operands[2]));
8743   else
8744     emit_move_insn (operands[3], gen_rtx_PLUS (Pmode, operands[2],
8745                                                gen_rtx_REG (Pmode, PIC_REG)));
8747   /* N.B. This is not constant for a GOTPLT relocation.  */
8748   mem = gen_rtx_MEM (Pmode, operands[3]);
8749   MEM_NOTRAP_P (mem) = 1;
8750   /* ??? Should we have a special alias set for the GOT?  */
8751   emit_move_insn (operands[0], mem);
8753   DONE;
8756 (define_expand "sym2GOT"
8757   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8758   ""
8759   "")
8761 (define_expand "symGOT2reg"
8762   [(match_operand 0 "" "") (match_operand 1 "" "")]
8763   ""
8765   rtx gotsym, insn;
8767   gotsym = gen_sym2GOT (operands[1]);
8768   PUT_MODE (gotsym, Pmode);
8769   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8771   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8773   DONE;
8776 (define_expand "symGOTPLT2reg"
8777   [(match_operand 0 "" "") (match_operand 1 "" "")]
8778   ""
8780   rtx pltsym = gen_rtx_CONST (Pmode,
8781                               gen_rtx_UNSPEC (Pmode,
8782                                               gen_rtvec (1, operands[1]),
8783                                               UNSPEC_GOTPLT));
8784   emit_insn (gen_symGOT_load (operands[0], pltsym));
8785   DONE;
8788 (define_expand "sym2GOTOFF"
8789   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8790   ""
8791   "")
8793 (define_expand "symGOTOFF2reg"
8794   [(match_operand 0 "" "") (match_operand 1 "" "")]
8795   ""
8797   rtx gotoffsym, insn;
8798   rtx t = (!can_create_pseudo_p ()
8799            ? operands[0]
8800            : gen_reg_rtx (GET_MODE (operands[0])));
8802   gotoffsym = gen_sym2GOTOFF (operands[1]);
8803   PUT_MODE (gotoffsym, Pmode);
8804   emit_move_insn (t, gotoffsym);
8805   insn = emit_move_insn (operands[0],
8806                          gen_rtx_PLUS (Pmode, t,
8807                                        gen_rtx_REG (Pmode, PIC_REG)));
8809   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8811   DONE;
8814 (define_expand "symPLT_label2reg"
8815   [(set (match_operand:SI 0 "" "")
8816         (const:SI
8817          (unspec:SI
8818           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8819            (const:SI (plus:SI (match_operand:SI 2 "" "")
8820                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8821    ;; Even though the PIC register is not really used by the call
8822    ;; sequence in which this is expanded, the PLT code assumes the PIC
8823    ;; register is set, so we must not skip its initialization.  Since
8824    ;; we only use this expand as part of calling sequences, and never
8825    ;; to take the address of a function, this is the best point to
8826    ;; insert the (use).  Using the PLT to take the address of a
8827    ;; function would be wrong, not only because the PLT entry could
8828    ;; then be called from a function that doesn't initialize the PIC
8829    ;; register to the proper GOT, but also because pointers to the
8830    ;; same function might not compare equal, should they be set by
8831    ;; different shared libraries.
8832    (use (reg:SI PIC_REG))]
8833   "TARGET_SH1"
8834   "")
8836 (define_expand "sym2PIC"
8837   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8838   ""
8839   "")
8841 ;; TLS code generation.
8842 ;; ??? this should be a define_insn_and_split
8843 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8844 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8845 ;; for details.
8847 (define_insn "tls_global_dynamic"
8848   [(set (match_operand:SI 0 "register_operand" "=&z")
8849         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8850                                   UNSPEC_TLSGD))
8851               (const_int 0)))
8852    (use (reg:PSI FPSCR_REG))
8853    (use (reg:SI PIC_REG))
8854    (clobber (reg:SI PR_REG))
8855    (clobber (scratch:SI))]
8856   "TARGET_SH1"
8858   return       "mov.l   1f,r4"                  "\n"
8859          "      mova    2f,r0"                  "\n"
8860          "      mov.l   2f,r1"                  "\n"
8861          "      add     r0,r1"                  "\n"
8862          "      jsr     @r1"                    "\n"
8863          "      add     r12,r4"                 "\n"
8864          "      bra     3f"                     "\n"
8865          "      nop"                            "\n"
8866          "      .align  2"                      "\n"
8867          "1:    .long   %a1@TLSGD"              "\n"
8868          "2:    .long   __tls_get_addr@PLT"     "\n"
8869          "3:";
8871   [(set_attr "type" "tls_load")
8872    (set_attr "length" "26")])
8874 (define_insn "tls_local_dynamic"
8875   [(set (match_operand:SI 0 "register_operand" "=&z")
8876         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8877                                   UNSPEC_TLSLDM))
8878               (const_int 0)))
8879    (use (reg:PSI FPSCR_REG))
8880    (use (reg:SI PIC_REG))
8881    (clobber (reg:SI PR_REG))
8882    (clobber (scratch:SI))]
8883   "TARGET_SH1"
8885   return       "mov.l   1f,r4"                  "\n"
8886          "      mova    2f,r0"                  "\n"
8887          "      mov.l   2f,r1"                  "\n"
8888          "      add     r0,r1"                  "\n"
8889          "      jsr     @r1"                    "\n"
8890          "      add     r12,r4"                 "\n"
8891          "      bra     3f"                     "\n"
8892          "      nop"                            "\n"
8893          "      .align  2"                      "\n"
8894          "1:    .long   %a1@TLSLDM"             "\n"
8895          "2:    .long   __tls_get_addr@PLT"     "\n"
8896          "3:";
8898   [(set_attr "type" "tls_load")
8899    (set_attr "length" "26")])
8901 (define_expand "sym2DTPOFF"
8902   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8903   ""
8904   "")
8906 (define_expand "symDTPOFF2reg"
8907   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8908   ""
8910   rtx dtpoffsym;
8911   rtx t = (!can_create_pseudo_p ()
8912            ? operands[0]
8913            : gen_reg_rtx (GET_MODE (operands[0])));
8915   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8916   PUT_MODE (dtpoffsym, Pmode);
8917   emit_move_insn (t, dtpoffsym);
8918   emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8919   DONE;
8922 (define_expand "sym2GOTTPOFF"
8923   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8924   ""
8925   "")
8927 (define_insn "tls_initial_exec"
8928   [(set (match_operand:SI 0 "register_operand" "=&r")
8929         (unspec:SI [(match_operand:SI 1 "" "")]
8930                     UNSPEC_TLSIE))
8931    (use (reg:SI GBR_REG))
8932    (use (reg:SI PIC_REG))
8933    (clobber (reg:SI R0_REG))]
8934   ""
8936   return       "mov.l   1f,r0"          "\n"
8937          "      stc     gbr,%0"         "\n"
8938          "      mov.l   @(r0,r12),r0"   "\n"
8939          "      bra     2f"             "\n"
8940          "      add     r0,%0"          "\n"
8941          "      .align  2"              "\n"
8942          "1:    .long   %a1"            "\n"
8943          "2:";
8945   [(set_attr "type" "tls_load")
8946    (set_attr "length" "16")])
8948 (define_expand "sym2TPOFF"
8949   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8950   ""
8951   "")
8953 (define_expand "symTPOFF2reg"
8954   [(match_operand 0 "" "") (match_operand 1 "" "")]
8955   ""
8957   rtx tpoffsym;
8959   tpoffsym = gen_sym2TPOFF (operands[1]);
8960   PUT_MODE (tpoffsym, Pmode);
8961   emit_move_insn (operands[0], tpoffsym);
8962   DONE;
8965 (define_insn "load_gbr"
8966   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8967    (use (reg:SI GBR_REG))]
8968   ""
8969   "stc  gbr,%0"
8970   [(set_attr "type" "tls_load")])
8972 ;; case instruction for switch statements.
8974 ;; Operand 0 is index
8975 ;; operand 1 is the minimum bound
8976 ;; operand 2 is the maximum bound - minimum bound + 1
8977 ;; operand 3 is CODE_LABEL for the table;
8978 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8980 (define_expand "casesi"
8981   [(match_operand:SI 0 "arith_reg_operand" "")
8982    (match_operand:SI 1 "arith_reg_operand" "")
8983    (match_operand:SI 2 "arith_reg_operand" "")
8984    (match_operand 3 "" "") (match_operand 4 "" "")]
8985   ""
8987   rtx reg = gen_reg_rtx (SImode);
8988   rtx reg2 = gen_reg_rtx (SImode);
8989   if (TARGET_SHMEDIA)
8990     {
8991       rtx reg = gen_reg_rtx (DImode);
8992       rtx reg2 = gen_reg_rtx (DImode);
8993       rtx reg3 = gen_reg_rtx (Pmode);
8994       rtx reg4 = gen_reg_rtx (Pmode);
8995       rtx reg5 = gen_reg_rtx (Pmode);
8996       rtx load, test;
8998       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8999       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9000       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9002       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
9003       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
9004       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9005       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
9006       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
9007       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9008       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9009                                                (Pmode, operands[3])));
9010       /* Messy: can we subreg to clean this up? */
9011       if (Pmode == DImode)
9012         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9013       else
9014         load = gen_casesi_load_media (reg4,
9015                                       gen_rtx_SUBREG (DImode, reg3, 0),
9016                                       reg2, operands[3]);
9017       PUT_MODE (SET_SRC (load), Pmode);
9018       emit_insn (load);
9019       /* ??? The following add could be eliminated if we used ptrel.  */
9020       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9021       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9022       emit_barrier ();
9023       DONE;
9024     }
9025   operands[1] = copy_to_mode_reg (SImode, operands[1]);
9026   operands[2] = copy_to_mode_reg (SImode, operands[2]);
9027   /* If optimizing, casesi_worker depends on the mode of the instruction
9028      before label it 'uses' - operands[3].  */
9029   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9030                            reg));
9031   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9032   if (TARGET_SH2)
9033     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9034   else
9035     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9036   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9037      operands[3], but to lab.  We will fix this up in
9038      machine_dependent_reorg.  */
9039   emit_barrier ();
9040   DONE;
9043 (define_expand "casesi_0"
9044   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9045    (set (match_dup 4) (minus:SI (match_dup 4)
9046                                 (match_operand:SI 1 "arith_operand" "")))
9047    (set (reg:SI T_REG)
9048         (gtu:SI (match_dup 4)
9049                 (match_operand:SI 2 "arith_reg_operand" "")))
9050    (set (pc)
9051         (if_then_else (ne (reg:SI T_REG)
9052                           (const_int 0))
9053                       (label_ref (match_operand 3 "" ""))
9054                       (pc)))]
9055   "TARGET_SH1"
9056   "")
9058 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9059 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9060 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9062 (define_insn "casesi_worker_0"
9063   [(set (match_operand:SI 0 "register_operand" "=r,r")
9064         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9065                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9066    (clobber (match_scratch:SI 3 "=X,1"))
9067    (clobber (match_scratch:SI 4 "=&z,z"))]
9068   "TARGET_SH1"
9069   "#")
9071 (define_split
9072   [(set (match_operand:SI 0 "register_operand" "")
9073         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9074                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9075    (clobber (match_scratch:SI 3 ""))
9076    (clobber (match_scratch:SI 4 ""))]
9077   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9078   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9079    (parallel [(set (match_dup 0)
9080               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9081                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9082               (clobber (match_dup 3))])
9083    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9085   if (GET_CODE (operands[2]) == CODE_LABEL)
9086     LABEL_NUSES (operands[2])++;
9089 (define_split
9090   [(set (match_operand:SI 0 "register_operand" "")
9091         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9092                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9093    (clobber (match_scratch:SI 3 ""))
9094    (clobber (match_scratch:SI 4 ""))]
9095   "TARGET_SH2 && reload_completed"
9096   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9097    (parallel [(set (match_dup 0)
9098               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9099                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9100               (clobber (match_dup 3))])]
9102   if (GET_CODE (operands[2]) == CODE_LABEL)
9103     LABEL_NUSES (operands[2])++;
9106 (define_insn "casesi_worker_1"
9107   [(set (match_operand:SI 0 "register_operand" "=r,r")
9108         (unspec:SI [(reg:SI R0_REG)
9109                     (match_operand:SI 1 "register_operand" "0,r")
9110                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9111    (clobber (match_scratch:SI 3 "=X,1"))]
9112   "TARGET_SH1"
9114   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9116   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9118   switch (GET_MODE (diff_vec))
9119     {
9120     case SImode:
9121       return "shll2     %1\;mov.l       @(r0,%1),%0";
9122     case HImode:
9123       return "add       %1,%1\;mov.w    @(r0,%1),%0";
9124     case QImode:
9125       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9126         return "mov.b   @(r0,%1),%0\;extu.b     %0,%0";
9127       return "mov.b     @(r0,%1),%0";
9128     default:
9129       gcc_unreachable ();
9130     }
9132   [(set_attr "length" "4")])
9134 (define_insn "casesi_worker_2"
9135   [(set (match_operand:SI 0 "register_operand" "=r,r")
9136         (unspec:SI [(reg:SI R0_REG)
9137                     (match_operand:SI 1 "register_operand" "0,r")
9138                     (label_ref (match_operand 2 "" ""))
9139                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9140    (clobber (match_operand:SI 4 "" "=X,1"))]
9141   "TARGET_SH2 && reload_completed && flag_pic"
9143   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9144   const char *load;
9146   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9148   switch (GET_MODE (diff_vec))
9149     {
9150     case SImode:
9151       output_asm_insn ("shll2    %1", operands);
9152       load = "mov.l     @(r0,%1),%0"; break;
9153     case HImode:
9154       output_asm_insn ("add     %1,%1", operands);
9155       load = "mov.w     @(r0,%1),%0"; break;
9156     case QImode:
9157       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9158         load = "mov.b   @(r0,%1),%0\;extu.b     %0,%0";
9159       else
9160         load = "mov.b   @(r0,%1),%0";
9161       break;
9162     default:
9163       gcc_unreachable ();
9164     }
9165   output_asm_insn ("add\tr0,%1\;mova\t%O3,r0\\n", operands);
9166   return load;
9168   [(set_attr "length" "8")])
9170 (define_insn "casesi_shift_media"
9171   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9172         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9173                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9174                     UNSPEC_CASESI)))]
9175   "TARGET_SHMEDIA"
9177   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9179   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9181   switch (GET_MODE (diff_vec))
9182     {
9183     case SImode:
9184       return "shlli     %1, 2, %0";
9185     case HImode:
9186       return "shlli     %1, 1, %0";
9187     case QImode:
9188       if (rtx_equal_p (operands[0], operands[1]))
9189         return "";
9190       return "add       %1, r63, %0";
9191     default:
9192       gcc_unreachable ();
9193     }
9195   [(set_attr "type" "arith_media")])
9197 (define_insn "casesi_load_media"
9198   [(set (match_operand 0 "any_arith_reg_dest" "=r")
9199         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9200                          (match_operand:DI 2 "arith_reg_operand" "r")
9201                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9202   "TARGET_SHMEDIA"
9204   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9206   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9208   switch (GET_MODE (diff_vec))
9209     {
9210     case SImode:
9211       return "ldx.l     %1, %2, %0";
9212     case HImode:
9213 #if 0
9214       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9215         return "ldx.uw  %1, %2, %0";
9216 #endif
9217       return "ldx.w     %1, %2, %0";
9218     case QImode:
9219       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9220         return "ldx.ub  %1, %2, %0";
9221       return "ldx.b     %1, %2, %0";
9222     default:
9223       gcc_unreachable ();
9224     }
9226   [(set_attr "type" "load_media")])
9228 (define_expand "return"
9229   [(return)]
9230   "reload_completed && ! sh_need_epilogue ()"
9232   if (TARGET_SHMEDIA)
9233     {
9234       emit_jump_insn (gen_return_media ());
9235       DONE;
9236     }
9238   if (TARGET_SHCOMPACT
9239       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9240     {
9241       emit_jump_insn (gen_shcompact_return_tramp ());
9242       DONE;
9243     }
9246 (define_insn "*return_i"
9247   [(return)]
9248   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9249                     && (crtl->args.info.call_cookie
9250                         & CALL_COOKIE_RET_TRAMP (1)))
9251    && reload_completed
9252    && lookup_attribute (\"trap_exit\",
9253                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9255   if (TARGET_SH2A && (dbr_sequence_length () == 0)
9256       && !current_function_interrupt)
9257     return "rts/n";
9258   else
9259     return "%@  %#";
9261   [(set_attr "type" "return")
9262    (set_attr "needs_delay_slot" "yes")])
9264 ;; trapa has no delay slot.
9265 (define_insn "*return_trapa"
9266   [(return)]
9267   "TARGET_SH1 && !TARGET_SHCOMPACT
9268    && reload_completed"
9269   "%@"
9270   [(set_attr "type" "return")])
9272 (define_expand "shcompact_return_tramp"
9273   [(return)]
9274   "TARGET_SHCOMPACT
9275    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9277   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9279   function_symbol (reg, "__GCC_shcompact_return_trampoline", SFUNC_STATIC);
9280   emit_jump_insn (gen_shcompact_return_tramp_i ());
9281   DONE;
9284 (define_insn "shcompact_return_tramp_i"
9285   [(parallel [(return) (use (reg:SI R0_REG))])]
9286   "TARGET_SHCOMPACT
9287    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9288   "jmp  @r0%#"
9289   [(set_attr "type" "jump_ind")
9290    (set_attr "needs_delay_slot" "yes")])
9292 (define_insn "return_media_i"
9293   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9294   "TARGET_SHMEDIA && reload_completed"
9295   "blink        %0, r63"
9296   [(set_attr "type" "jump_media")])
9298 (define_insn "return_media_rte"
9299   [(return)]
9300   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9301   "rte"
9302   [(set_attr "type" "jump_media")])
9304 (define_expand "return_media"
9305   [(return)]
9306   "TARGET_SHMEDIA && reload_completed"
9308   int tr_regno = sh_media_register_for_return ();
9309   rtx tr;
9311   if (current_function_interrupt)
9312     {
9313       emit_jump_insn (gen_return_media_rte ());
9314       DONE;
9315     }
9316   if (tr_regno < 0)
9317     {
9318       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9320       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9321       tr_regno = TR0_REG;
9322       tr = gen_rtx_REG (Pmode, tr_regno);
9323       emit_move_insn (tr, r18);
9324     }
9325   else
9326     tr = gen_rtx_REG (Pmode, tr_regno);
9328   emit_jump_insn (gen_return_media_i (tr));
9329   DONE;
9332 (define_insn "shcompact_preserve_incoming_args"
9333   [(set (match_operand:SI 0 "register_operand" "+r")
9334         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9335   "TARGET_SHCOMPACT"
9336   ""
9337   [(set_attr "length" "0")])
9339 (define_insn "shcompact_incoming_args"
9340   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9341    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9342    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9343    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9344    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9345    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9346    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9347    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9348    (set (mem:BLK (reg:SI MACL_REG))
9349         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9350    (use (reg:SI R0_REG))
9351    (clobber (reg:SI R0_REG))
9352    (clobber (reg:SI MACL_REG))
9353    (clobber (reg:SI MACH_REG))
9354    (clobber (reg:SI PR_REG))]
9355   "TARGET_SHCOMPACT"
9356   "jsr  @r0%#"
9357   [(set_attr "needs_delay_slot" "yes")])
9359 (define_insn "shmedia_save_restore_regs_compact"
9360   [(set (reg:SI SP_REG)
9361         (plus:SI (reg:SI SP_REG)
9362                  (match_operand:SI 0 "immediate_operand" "i")))
9363    (use (reg:SI R0_REG))
9364    (clobber (reg:SI PR_REG))]
9365   "TARGET_SHCOMPACT
9366    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9367        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9368   "jsr @r0%#"
9369   [(set_attr "needs_delay_slot" "yes")])
9371 (define_expand "prologue"
9372   [(const_int 0)]
9373   ""
9375   sh_expand_prologue ();
9376   DONE;
9379 (define_expand "epilogue"
9380   [(return)]
9381   ""
9383   sh_expand_epilogue (0);
9384   emit_jump_insn (gen_return ());
9385   DONE;
9388 (define_expand "eh_return"
9389   [(use (match_operand 0 "register_operand" ""))]
9390   ""
9392   rtx ra = operands[0];
9394   if (TARGET_SHMEDIA64)
9395     emit_insn (gen_eh_set_ra_di (ra));
9396   else
9397     emit_insn (gen_eh_set_ra_si (ra));
9399   DONE;
9402 ;; Clobber the return address on the stack.  We can't expand this
9403 ;; until we know where it will be put in the stack frame.
9405 (define_insn "eh_set_ra_si"
9406   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9407       UNSPECV_EH_RETURN)
9408    (clobber (match_scratch:SI 1 "=&r"))]
9409   "! TARGET_SHMEDIA64"
9410   "#")
9412 (define_insn "eh_set_ra_di"
9413   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9414       UNSPECV_EH_RETURN)
9415    (clobber (match_scratch:DI 1 "=&r"))]
9416   "TARGET_SHMEDIA64"
9417   "#")
9419 (define_split
9420   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9421       UNSPECV_EH_RETURN)
9422    (clobber (match_scratch 1 ""))]
9423   "reload_completed"
9424   [(const_int 0)]
9426   sh_set_return_address (operands[0], operands[1]);
9427   DONE;
9430 (define_insn "blockage"
9431   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9432   ""
9433   ""
9434   [(set_attr "length" "0")])
9436 ;; Define movml instructions for SH2A target.  Currently they are
9437 ;; used to push and pop all banked registers only.
9439 (define_insn "movml_push_banked"
9440   [(set (match_operand:SI 0 "register_operand" "=r")
9441           (plus (match_dup 0) (const_int -32)))
9442    (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9443    (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9444    (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9445    (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9446    (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9447    (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9448    (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9449    (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9450   "TARGET_SH2A && REGNO (operands[0]) == 15"
9451   "movml.l\tr7,@-r15"
9452   [(set_attr "in_delay_slot" "no")])
9454 (define_insn "movml_pop_banked"
9455   [(set (match_operand:SI 0 "register_operand" "=r")
9456           (plus (match_dup 0) (const_int 32)))
9457    (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9458    (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9459    (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9460    (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9461    (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9462    (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9463    (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9464    (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9465   "TARGET_SH2A && REGNO (operands[0]) == 15"
9466   "movml.l\t@r15+,r7"
9467   [(set_attr "in_delay_slot" "no")])
9469 ;; ------------------------------------------------------------------------
9470 ;; Scc instructions
9471 ;; ------------------------------------------------------------------------
9473 (define_insn "movt"
9474   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9475         (eq:SI (reg:SI T_REG) (const_int 1)))]
9476   "TARGET_SH1"
9477   "movt %0"
9478   [(set_attr "type" "arith")])
9480 (define_insn "movrt"
9481   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9482         (xor:SI (reg:SI T_REG) (const_int 1)))]
9483   "TARGET_SH2A"
9484   "movrt        %0"
9485   [(set_attr "type" "arith")])
9487 (define_expand "cstore4_media"
9488   [(set (match_operand:SI 0 "register_operand" "=r")
9489         (match_operator:SI 1 "sh_float_comparison_operator"
9490          [(match_operand 2 "logical_operand" "")
9491           (match_operand 3 "cmp_operand" "")]))]
9492   "TARGET_SHMEDIA"
9494   enum machine_mode mode = GET_MODE (operands[2]);
9495   enum rtx_code code = GET_CODE (operands[1]);
9496   bool invert, swap;
9497   if (mode == VOIDmode)
9498     mode = GET_MODE (operands[3]);
9499   if (operands[2] == const0_rtx)
9500     {
9501       if (code == EQ || code == NE)
9502         operands[2] = operands[3], operands[3] = const0_rtx;
9503     }
9504   else
9505     operands[2] = force_reg (mode, operands[2]);
9506   if (operands[3] != const0_rtx)
9507     operands[3] = force_reg (mode, operands[3]);
9509   switch (code)
9510     {
9511     case GEU:
9512     case GE:
9513       swap = invert = !FLOAT_MODE_P (mode);
9514       break;
9516     case LEU:
9517     case LE:
9518       swap = FLOAT_MODE_P (mode), invert = !swap;
9519       break;
9521     case LTU:
9522     case LT:
9523       swap = true, invert = false;
9524       break;
9526     case GTU:
9527     case GT:
9528     case EQ:
9529     case UNORDERED:
9530       swap = invert = false;
9531       break;
9533     case NE:
9534       swap = invert = true;
9535       break;
9537     default:
9538       gcc_unreachable ();
9539   }
9541   if (swap)
9542     {
9543       rtx tem = operands[2];
9544       operands[2] = operands[3];
9545       operands[3] = tem;
9546       code = swap_condition (code);
9547     }
9549   if (invert)
9550     {
9551       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9552       code = reverse_condition (code);
9553       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9554       emit_insn (gen_cstore4_media (tem, operands[1],
9555                                     operands[2], operands[3]));
9556       code = EQ;
9557       operands[2] = tem;
9558       operands[3] = const0_rtx;
9559     }
9561   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9564 (define_expand "cstoresi4"
9565   [(set (match_operand:SI 0 "register_operand" "=r")
9566         (match_operator:SI 1 "comparison_operator"
9567          [(match_operand:SI 2 "cmpsi_operand" "")
9568           (match_operand:SI 3 "arith_operand" "")]))]
9569   "TARGET_SH1 || TARGET_SHMEDIA"
9571   if (TARGET_SHMEDIA)
9572     {
9573       emit_insn (gen_cstore4_media (operands[0], operands[1],
9574                                     operands[2], operands[3]));
9575       DONE;
9576     }
9578    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9579        && sh_expand_t_scc (operands))
9580      DONE;
9582    if (! currently_expanding_to_rtl)
9583      FAIL;
9584    
9585    sh_emit_compare_and_set (operands, SImode);
9586    DONE;
9589 (define_expand "cstoredi4"
9590   [(set (match_operand:SI 0 "register_operand" "=r")
9591         (match_operator:SI 1 "comparison_operator"
9592          [(match_operand:DI 2 "arith_operand" "")
9593           (match_operand:DI 3 "arith_operand" "")]))]
9594   "TARGET_SH2 || TARGET_SHMEDIA"
9596   if (TARGET_SHMEDIA)
9597     {
9598       emit_insn (gen_cstore4_media (operands[0], operands[1],
9599                                     operands[2], operands[3]));
9600       DONE;
9601     }
9603    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9604        && sh_expand_t_scc (operands))
9605      DONE;
9607    if (! currently_expanding_to_rtl)
9608      FAIL;
9609    
9610    sh_emit_compare_and_set (operands, DImode);
9611    DONE;
9614 ;; Move the complement of the T reg to a reg.
9615 ;; On SH2A the movrt insn can be used.
9616 ;; On anything else than SH2A this has to be done with multiple instructions.
9617 ;; One obvious way would be:
9618 ;;      cmp/eq  ...
9619 ;;      movt    r0
9620 ;;      xor     #1,r0
9622 ;; However, this puts pressure on r0 in most cases and thus the following is
9623 ;; more appealing:
9624 ;;      cmp/eq  ...
9625 ;;      mov     #-1,temp
9626 ;;      negc    temp,dest
9628 ;; If the constant -1 can be CSE-ed or lifted out of a loop it effectively
9629 ;; becomes a one instruction operation.  Moreover, care must be taken that
9630 ;; the insn can still be combined with inverted compare and branch code
9631 ;; around it.  On the other hand, if a function returns the complement of
9632 ;; a previous comparison result in the T bit, the xor #1,r0 approach might
9633 ;; lead to better code.
9635 (define_expand "movnegt"
9636   [(set (match_operand:SI 0 "arith_reg_dest" "")
9637         (xor:SI (reg:SI T_REG) (const_int 1)))]
9638   ""
9640   if (TARGET_SH2A)
9641     emit_insn (gen_movrt (operands[0]));
9642   else
9643     {
9644       rtx val = force_reg (SImode, gen_int_mode (-1, SImode));
9645       emit_insn (gen_movrt_negc (operands[0], val));
9646     }
9647   DONE;
9650 (define_insn "movrt_negc"
9651   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9652         (xor:SI (reg:SI T_REG) (const_int 1)))
9653    (set (reg:SI T_REG) (const_int 1))
9654    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
9655   "TARGET_SH1"
9656   "negc %1,%0"
9657   [(set_attr "type" "arith")])
9659 ;; The *negnegt patterns help the combine pass to figure out how to fold 
9660 ;; an explicit double T bit negation.
9661 (define_insn_and_split "*negnegt"
9662   [(set (reg:SI T_REG)
9663         (eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 3)
9664         (const_int 0)))]
9665   "! TARGET_LITTLE_ENDIAN"
9666   "#"
9667   ""
9668   [(const_int 0)])
9670 (define_insn_and_split "*negnegt"
9671   [(set (reg:SI T_REG)
9672         (eq:SI (subreg:QI (xor:SI (reg:SI T_REG) (const_int 1)) 0)
9673         (const_int 0)))]
9674   "TARGET_LITTLE_ENDIAN"
9675   "#"
9676   ""
9677   [(const_int 0)])
9679 ;; The *movtt patterns improve code at -O1.
9680 (define_insn_and_split "*movtt"
9681   [(set (reg:SI T_REG)
9682         (eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 3))
9683         (const_int 1)))]
9684   "! TARGET_LITTLE_ENDIAN"
9685   "#"
9686   ""
9687   [(const_int 0)])
9689 (define_insn_and_split "*movtt"
9690   [(set (reg:SI T_REG)
9691         (eq:SI (zero_extend:SI (subreg:QI (reg:SI T_REG) 0))
9692         (const_int 1)))]
9693   "TARGET_LITTLE_ENDIAN"
9694   "#"
9695   ""
9696   [(const_int 0)])
9698 ;; The *movt_qi patterns help the combine pass convert a movrt_negc pattern
9699 ;; into a movt Rn, xor #1 Rn pattern.  This can happen when e.g. a function
9700 ;; returns the inverted T bit value.
9701 (define_insn "*movt_qi"
9702   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9703         (zero_extend:SI (subreg:QI (reg:SI T_REG) 3)))]
9704   "! TARGET_LITTLE_ENDIAN"
9705   "movt %0"
9706   [(set_attr "type" "arith")])
9708 (define_insn "*movt_qi"
9709   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9710         (zero_extend:SI (subreg:QI (reg:SI T_REG) 0)))]
9711   "TARGET_LITTLE_ENDIAN"
9712   "movt %0"
9713   [(set_attr "type" "arith")])
9715 (define_expand "cstoresf4"
9716   [(set (match_operand:SI 0 "register_operand" "=r")
9717         (match_operator:SI 1 "sh_float_comparison_operator"
9718          [(match_operand:SF 2 "arith_operand" "")
9719           (match_operand:SF 3 "arith_operand" "")]))]
9720   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9722   if (TARGET_SHMEDIA)
9723     {
9724       emit_insn (gen_cstore4_media (operands[0], operands[1],
9725                                     operands[2], operands[3]));
9726       DONE;
9727     }
9729   if (! currently_expanding_to_rtl)
9730     FAIL;
9731    
9732   sh_emit_compare_and_set (operands, SFmode);
9733   DONE;
9736 (define_expand "cstoredf4"
9737   [(set (match_operand:SI 0 "register_operand" "=r")
9738         (match_operator:SI 1 "sh_float_comparison_operator"
9739          [(match_operand:DF 2 "arith_operand" "")
9740           (match_operand:DF 3 "arith_operand" "")]))]
9741   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9743   if (TARGET_SHMEDIA)
9744     {
9745       emit_insn (gen_cstore4_media (operands[0], operands[1],
9746                                     operands[2], operands[3]));
9747       DONE;
9748     }
9750   if (! currently_expanding_to_rtl)
9751     FAIL;
9752    
9753   sh_emit_compare_and_set (operands, DFmode);
9754   DONE;
9757 ;; -------------------------------------------------------------------------
9758 ;; Instructions to cope with inline literal tables
9759 ;; -------------------------------------------------------------------------
9761 ; 2 byte integer in line
9763 (define_insn "consttable_2"
9764  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9765                     (match_operand 1 "" "")]
9766                    UNSPECV_CONST2)]
9767  ""
9769   if (operands[1] != const0_rtx)
9770     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9771   return "";
9773  [(set_attr "length" "2")
9774  (set_attr "in_delay_slot" "no")])
9776 ; 4 byte integer in line
9778 (define_insn "consttable_4"
9779  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9780                     (match_operand 1 "" "")]
9781                    UNSPECV_CONST4)]
9782  ""
9784   if (operands[1] != const0_rtx)
9785     {
9786       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9787       mark_symbol_refs_as_used (operands[0]);
9788     }
9789   return "";
9791  [(set_attr "length" "4")
9792   (set_attr "in_delay_slot" "no")])
9794 ; 8 byte integer in line
9796 (define_insn "consttable_8"
9797  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9798                     (match_operand 1 "" "")]
9799                    UNSPECV_CONST8)]
9800  ""
9802   if (operands[1] != const0_rtx)
9803     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9804   return "";
9806  [(set_attr "length" "8")
9807   (set_attr "in_delay_slot" "no")])
9809 ; 4 byte floating point
9811 (define_insn "consttable_sf"
9812  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9813                     (match_operand 1 "" "")]
9814                    UNSPECV_CONST4)]
9815  ""
9817   if (operands[1] != const0_rtx)
9818     {
9819       REAL_VALUE_TYPE d;
9820       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9821       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9822     }
9823   return "";
9825  [(set_attr "length" "4")
9826   (set_attr "in_delay_slot" "no")])
9828 ; 8 byte floating point
9830 (define_insn "consttable_df"
9831  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9832                     (match_operand 1 "" "")]
9833                    UNSPECV_CONST8)]
9834  ""
9836   if (operands[1] != const0_rtx)
9837     {
9838       REAL_VALUE_TYPE d;
9839       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9840       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9841     }
9842   return "";
9844  [(set_attr "length" "8")
9845   (set_attr "in_delay_slot" "no")])
9847 ;; Alignment is needed for some constant tables; it may also be added for
9848 ;; Instructions at the start of loops, or after unconditional branches.
9849 ;; ??? We would get more accurate lengths if we did instruction
9850 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9851 ;; here is too conservative.
9853 ; align to a two byte boundary
9855 (define_expand "align_2"
9856  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9857  ""
9858  "")
9860 ; align to a four byte boundary
9861 ;; align_4 and align_log are instructions for the starts of loops, or
9862 ;; after unconditional branches, which may take up extra room.
9864 (define_expand "align_4"
9865  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9866  ""
9867  "")
9869 ; align to a cache line boundary
9871 (define_insn "align_log"
9872  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9873  ""
9874  ""
9875  [(set_attr "length" "0")
9876   (set_attr "in_delay_slot" "no")])
9878 ; emitted at the end of the literal table, used to emit the
9879 ; 32bit branch labels if needed.
9881 (define_insn "consttable_end"
9882   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9883   ""
9885   return output_jump_label_table ();
9887   [(set_attr "in_delay_slot" "no")])
9889 ; emitted at the end of the window in the literal table.
9891 (define_insn "consttable_window_end"
9892   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9893   ""
9894   ""
9895   [(set_attr "length" "0")
9896    (set_attr "in_delay_slot" "no")])
9898 ;; -------------------------------------------------------------------------
9899 ;; Misc
9900 ;; -------------------------------------------------------------------------
9902 ;; String/block move insn.
9904 (define_expand "movmemsi"
9905   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9906                    (mem:BLK (match_operand:BLK 1 "" "")))
9907               (use (match_operand:SI 2 "nonmemory_operand" ""))
9908               (use (match_operand:SI 3 "immediate_operand" ""))
9909               (clobber (reg:SI PR_REG))
9910               (clobber (reg:SI R4_REG))
9911               (clobber (reg:SI R5_REG))
9912               (clobber (reg:SI R0_REG))])]
9913   "TARGET_SH1 && ! TARGET_SH5"
9915   if(expand_block_move (operands))
9916      DONE;
9917   else FAIL;
9920 (define_insn "block_move_real"
9921   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9922                    (mem:BLK (reg:SI R5_REG)))
9923               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9924               (clobber (reg:SI PR_REG))
9925               (clobber (reg:SI R0_REG))])]
9926   "TARGET_SH1 && ! TARGET_HARD_SH4"
9927   "jsr  @%0%#"
9928   [(set_attr "type" "sfunc")
9929    (set_attr "needs_delay_slot" "yes")])
9931 (define_insn "block_lump_real"
9932   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9933                    (mem:BLK (reg:SI R5_REG)))
9934               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9935               (use (reg:SI R6_REG))
9936               (clobber (reg:SI PR_REG))
9937               (clobber (reg:SI T_REG))
9938               (clobber (reg:SI R4_REG))
9939               (clobber (reg:SI R5_REG))
9940               (clobber (reg:SI R6_REG))
9941               (clobber (reg:SI R0_REG))])]
9942   "TARGET_SH1 && ! TARGET_HARD_SH4"
9943   "jsr  @%0%#"
9944   [(set_attr "type" "sfunc")
9945    (set_attr "needs_delay_slot" "yes")])
9947 (define_insn "block_move_real_i4"
9948   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9949                    (mem:BLK (reg:SI R5_REG)))
9950               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9951               (clobber (reg:SI PR_REG))
9952               (clobber (reg:SI R0_REG))
9953               (clobber (reg:SI R1_REG))
9954               (clobber (reg:SI R2_REG))])]
9955   "TARGET_HARD_SH4"
9956   "jsr  @%0%#"
9957   [(set_attr "type" "sfunc")
9958    (set_attr "needs_delay_slot" "yes")])
9960 (define_insn "block_lump_real_i4"
9961   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9962                    (mem:BLK (reg:SI R5_REG)))
9963               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9964               (use (reg:SI R6_REG))
9965               (clobber (reg:SI PR_REG))
9966               (clobber (reg:SI T_REG))
9967               (clobber (reg:SI R4_REG))
9968               (clobber (reg:SI R5_REG))
9969               (clobber (reg:SI R6_REG))
9970               (clobber (reg:SI R0_REG))
9971               (clobber (reg:SI R1_REG))
9972               (clobber (reg:SI R2_REG))
9973               (clobber (reg:SI R3_REG))])]
9974   "TARGET_HARD_SH4"
9975   "jsr  @%0%#"
9976   [(set_attr "type" "sfunc")
9977    (set_attr "needs_delay_slot" "yes")])
9979 ;; -------------------------------------------------------------------------
9980 ;; Floating point instructions.
9981 ;; -------------------------------------------------------------------------
9983 ;; ??? All patterns should have a type attribute.
9985 (define_expand "movpsi"
9986   [(set (match_operand:PSI 0 "register_operand" "")
9987         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9988   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9989   "")
9991 ;; The c / m alternative is a fake to guide reload to load directly into
9992 ;; fpscr, since reload doesn't know how to use post-increment.
9993 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9994 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9995 ;; predicate after reload.
9996 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9997 ;; like a mac -> gpr move.
9998 (define_insn "fpu_switch"
9999   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10000         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10001   "TARGET_SH2E
10002    && (! reload_completed
10003        || true_regnum (operands[0]) != FPSCR_REG
10004        || !MEM_P (operands[1])
10005        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10006   "@
10007         ! precision stays the same
10008         lds.l   %1,fpscr
10009         mov.l   %1,%0
10010         #
10011         lds     %1,fpscr
10012         mov     %1,%0
10013         mov.l   %1,%0
10014         sts     fpscr,%0
10015         sts.l   fpscr,%0"
10016   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10017    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10019 (define_peephole2
10020   [(set (reg:PSI FPSCR_REG)
10021         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10022   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10023   [(const_int 0)]
10025   rtx fpscr, mem, new_insn;
10027   fpscr = SET_DEST (PATTERN (curr_insn));
10028   mem = SET_SRC (PATTERN (curr_insn));
10029   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10031   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10032   add_reg_note (new_insn, REG_INC, operands[0]);
10033   DONE;
10036 (define_split
10037   [(set (reg:PSI FPSCR_REG)
10038         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10039   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10040    && (flag_peephole2 ? epilogue_completed : reload_completed)"
10041   [(const_int 0)]
10043   rtx fpscr, mem, new_insn;
10045   fpscr = SET_DEST (PATTERN (curr_insn));
10046   mem = SET_SRC (PATTERN (curr_insn));
10047   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10049   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10050   add_reg_note (new_insn, REG_INC, operands[0]);
10052   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10053     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10054   DONE;
10057 ;; ??? This uses the fp unit, but has no type indicating that.
10058 ;; If we did that, this would either give a bogus latency or introduce
10059 ;; a bogus FIFO constraint.
10060 ;; Since this insn is currently only used for prologues/epilogues,
10061 ;; it is probably best to claim no function unit, which matches the
10062 ;; current setting.
10063 (define_insn "toggle_sz"
10064   [(set (reg:PSI FPSCR_REG)
10065         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10066   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10067   "fschg"
10068   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10070 ;; There's no way we can use it today, since optimize mode switching
10071 ;; doesn't enable us to know from which mode we're switching to the
10072 ;; mode it requests, to tell whether we can use a relative mode switch
10073 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10074 ;; memory).
10075 (define_insn "toggle_pr"
10076   [(set (reg:PSI FPSCR_REG)
10077         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10078   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10079   "fpchg"
10080   [(set_attr "type" "fpscr_toggle")])
10082 (define_expand "addsf3"
10083   [(set (match_operand:SF 0 "arith_reg_operand" "")
10084         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10085                  (match_operand:SF 2 "arith_reg_operand" "")))]
10086   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10088   if (TARGET_SH2E)
10089     {
10090       expand_sf_binop (&gen_addsf3_i, operands);
10091       DONE;
10092     }
10095 (define_insn "*addsf3_media"
10096   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10097         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10098                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10099   "TARGET_SHMEDIA_FPU"
10100   "fadd.s       %1, %2, %0"
10101   [(set_attr "type" "fparith_media")])
10103 (define_insn_and_split "unary_sf_op"
10104   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10105         (vec_select:V2SF
10106          (vec_concat:V2SF
10107           (vec_select:SF
10108            (match_dup 0)
10109            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10110           (match_operator:SF 2 "unary_float_operator"
10111             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10112                             (parallel [(match_operand 4
10113                                         "const_int_operand" "n")]))]))
10114          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10115   "TARGET_SHMEDIA_FPU"
10116   "#"
10117   "TARGET_SHMEDIA_FPU && reload_completed"
10118   [(set (match_dup 5) (match_dup 6))]
10120   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10121   rtx op1 = gen_rtx_REG (SFmode,
10122                          (true_regnum (operands[1])
10123                           + (INTVAL (operands[4]) ^ endian)));
10125   operands[7] = gen_rtx_REG (SFmode,
10126                              (true_regnum (operands[0])
10127                               + (INTVAL (operands[3]) ^ endian)));
10128   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10130   [(set_attr "type" "fparith_media")])
10132 (define_insn_and_split "binary_sf_op0"
10133   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10134         (vec_concat:V2SF
10135           (match_operator:SF 3 "binary_float_operator"
10136             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10137                             (parallel [(const_int 0)]))
10138              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10139                             (parallel [(const_int 0)]))])
10140           (vec_select:SF
10141            (match_dup 0)
10142            (parallel [(const_int 1)]))))]
10143   "TARGET_SHMEDIA_FPU"
10144   "#"
10145   "&& reload_completed"
10146   [(set (match_dup 4) (match_dup 5))]
10148   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10149   rtx op1 = gen_rtx_REG (SFmode,
10150                          true_regnum (operands[1]) + endian);
10151   rtx op2 = gen_rtx_REG (SFmode,
10152                          true_regnum (operands[2]) + endian);
10154   operands[4] = gen_rtx_REG (SFmode,
10155                              true_regnum (operands[0]) + endian);
10156   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10158   [(set_attr "type" "fparith_media")])
10160 (define_insn_and_split "binary_sf_op1"
10161   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10162         (vec_concat:V2SF
10163           (vec_select:SF
10164            (match_dup 0)
10165            (parallel [(const_int 0)]))
10166           (match_operator:SF 3 "binary_float_operator"
10167             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10168                             (parallel [(const_int 1)]))
10169              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10170                             (parallel [(const_int 1)]))])))]
10171   "TARGET_SHMEDIA_FPU"
10172   "#"
10173   "&& reload_completed"
10174   [(set (match_dup 4) (match_dup 5))]
10176   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10177   rtx op1 = gen_rtx_REG (SFmode, true_regnum (operands[1]) + (1 ^ endian));
10178   rtx op2 = gen_rtx_REG (SFmode, true_regnum (operands[2]) + (1 ^ endian));
10180   operands[4] = gen_rtx_REG (SFmode, true_regnum (operands[0]) + (1 ^ endian));
10181   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10183   [(set_attr "type" "fparith_media")])
10185 (define_insn "addsf3_i"
10186   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10187         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10188                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10189    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10190   "TARGET_SH2E"
10191   "fadd %2,%0"
10192   [(set_attr "type" "fp")
10193    (set_attr "fp_mode" "single")])
10195 (define_expand "subsf3"
10196   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10197         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10198                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10199   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10201   if (TARGET_SH2E)
10202     {
10203       expand_sf_binop (&gen_subsf3_i, operands);
10204       DONE;
10205     }
10208 (define_insn "*subsf3_media"
10209   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10210         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10211                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10212   "TARGET_SHMEDIA_FPU"
10213   "fsub.s       %1, %2, %0"
10214   [(set_attr "type" "fparith_media")])
10216 (define_insn "subsf3_i"
10217   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10218         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10219                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10220    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10221   "TARGET_SH2E"
10222   "fsub %2,%0"
10223   [(set_attr "type" "fp")
10224    (set_attr "fp_mode" "single")])
10226 (define_expand "mulsf3"
10227   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10228         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10229                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10230   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10231   "")
10233 (define_insn "*mulsf3_media"
10234   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10235         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10236                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10237   "TARGET_SHMEDIA_FPU"
10238   "fmul.s       %1, %2, %0"
10239   [(set_attr "type" "fparith_media")])
10241 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10242 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
10243 ;; we start out with a mulsf pattern that does not depend on fpscr.
10244 ;; This is split after combine to introduce the dependency, in order to
10245 ;; get mode switching and scheduling right.
10246 (define_insn_and_split "mulsf3_ie"
10247   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10248         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10249                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10250   "TARGET_SH2E"
10251   "fmul %2,%0"
10252   "TARGET_SH4 || TARGET_SH2A_SINGLE"
10253   [(const_int 0)]
10255   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10256              get_fpscr_rtx ()));
10257   DONE;
10259   [(set_attr "type" "fp")])
10261 (define_insn "mulsf3_i4"
10262   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10263         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10264                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10265    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10266   "TARGET_SH2E"
10267   "fmul %2,%0"
10268   [(set_attr "type" "fp")
10269    (set_attr "fp_mode" "single")])
10271 (define_insn "mac_media"
10272   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10273         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10274                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10275                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10276   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10277   "fmac.s %1, %2, %0"
10278   [(set_attr "type" "fparith_media")])
10280 (define_insn "*macsf3"
10281   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10282         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10283                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10284                  (match_operand:SF 3 "arith_reg_operand" "0")))
10285    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10286   "TARGET_SH2E && TARGET_FMAC"
10287   "fmac fr0,%2,%0"
10288   [(set_attr "type" "fp")
10289    (set_attr "fp_mode" "single")])
10291 (define_expand "divsf3"
10292   [(set (match_operand:SF 0 "arith_reg_operand" "")
10293         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10294                 (match_operand:SF 2 "arith_reg_operand" "")))]
10295   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10297   if (TARGET_SH2E)
10298     {
10299       expand_sf_binop (&gen_divsf3_i, operands);
10300       DONE;
10301     }
10304 (define_insn "*divsf3_media"
10305   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10306         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10307                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10308   "TARGET_SHMEDIA_FPU"
10309   "fdiv.s       %1, %2, %0"
10310   [(set_attr "type" "fdiv_media")])
10312 (define_insn "divsf3_i"
10313   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10314         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10315                  (match_operand:SF 2 "arith_reg_operand" "f")))
10316    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10317   "TARGET_SH2E"
10318   "fdiv %2,%0"
10319   [(set_attr "type" "fdiv")
10320    (set_attr "fp_mode" "single")])
10322 (define_insn "floatdisf2"
10323   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10324         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10325   "TARGET_SHMEDIA_FPU"
10326   "float.qs %1, %0"
10327   [(set_attr "type" "fpconv_media")])
10329 (define_expand "floatsisf2"
10330   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10331         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10332   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10334   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10335     {
10336       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10337       DONE;
10338     }
10341 (define_insn "*floatsisf2_media"
10342   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10343         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10344   "TARGET_SHMEDIA_FPU"
10345   "float.ls     %1, %0"
10346   [(set_attr "type" "fpconv_media")])
10348 (define_insn "floatsisf2_i4"
10349   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10350         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10351    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10352   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10353   "float        %1,%0"
10354   [(set_attr "type" "fp")
10355    (set_attr "fp_mode" "single")])
10357 (define_insn "*floatsisf2_ie"
10358   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10359         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10360   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10361   "float        %1,%0"
10362   [(set_attr "type" "fp")])
10364 (define_insn "fix_truncsfdi2"
10365   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10366         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10367   "TARGET_SHMEDIA_FPU"
10368   "ftrc.sq %1, %0"
10369   [(set_attr "type" "fpconv_media")])
10371 (define_expand "fix_truncsfsi2"
10372   [(set (match_operand:SI 0 "fpul_operand" "=y")
10373         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10374   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10376   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10377     {
10378       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10379       DONE;
10380     }
10383 (define_insn "*fix_truncsfsi2_media"
10384   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10385         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10386   "TARGET_SHMEDIA_FPU"
10387   "ftrc.sl      %1, %0"
10388   [(set_attr "type" "fpconv_media")])
10390 (define_insn "fix_truncsfsi2_i4"
10391   [(set (match_operand:SI 0 "fpul_operand" "=y")
10392         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10393    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10394   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10395   "ftrc %1,%0"
10396   [(set_attr "type" "ftrc_s")
10397    (set_attr "fp_mode" "single")])
10399 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10400 ;; fix_truncsfsi2_i4.
10401 ;; (define_insn "fix_truncsfsi2_i4_2"
10402 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10403 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10404 ;;   (use (reg:PSI FPSCR_REG))
10405 ;;   (clobber (reg:SI FPUL_REG))]
10406 ;;  "TARGET_SH4"
10407 ;;  "#"
10408 ;;  [(set_attr "length" "4")
10409 ;;   (set_attr "fp_mode" "single")])
10411 ;;(define_split
10412 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10413 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10414 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10415 ;;   (clobber (reg:SI FPUL_REG))]
10416 ;;  "TARGET_SH4"
10417 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10418 ;;            (use (match_dup 2))])
10419 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10421 (define_insn "*fixsfsi"
10422   [(set (match_operand:SI 0 "fpul_operand" "=y")
10423         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10424   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10425   "ftrc %1,%0"
10426   [(set_attr "type" "fp")])
10428 (define_insn "cmpgtsf_t"
10429   [(set (reg:SI T_REG)
10430         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10431                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10432   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10433   "fcmp/gt      %1,%0"
10434   [(set_attr "type" "fp_cmp")
10435    (set_attr "fp_mode" "single")])
10437 (define_insn "cmpeqsf_t"
10438   [(set (reg:SI T_REG)
10439         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10440                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10441   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10442   "fcmp/eq      %1,%0"
10443   [(set_attr "type" "fp_cmp")
10444    (set_attr "fp_mode" "single")])
10446 (define_insn "ieee_ccmpeqsf_t"
10447   [(set (reg:SI T_REG)
10448         (ior:SI (reg:SI T_REG)
10449                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10450                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10451   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10453   return output_ieee_ccmpeq (insn, operands);
10455   [(set_attr "length" "4")])
10458 (define_insn "cmpgtsf_t_i4"
10459   [(set (reg:SI T_REG)
10460         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10461                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10462    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10463   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10464   "fcmp/gt      %1,%0"
10465   [(set_attr "type" "fp_cmp")
10466    (set_attr "fp_mode" "single")])
10468 (define_insn "cmpeqsf_t_i4"
10469   [(set (reg:SI T_REG)
10470         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10471                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10472    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10473   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10474   "fcmp/eq      %1,%0"
10475   [(set_attr "type" "fp_cmp")
10476    (set_attr "fp_mode" "single")])
10478 (define_insn "*ieee_ccmpeqsf_t_4"
10479   [(set (reg:SI T_REG)
10480         (ior:SI (reg:SI T_REG)
10481                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10482                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10483    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10484   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10486   return output_ieee_ccmpeq (insn, operands);
10488   [(set_attr "length" "4")
10489    (set_attr "fp_mode" "single")])
10491 (define_insn "cmpeqsf_media"
10492   [(set (match_operand:SI 0 "register_operand" "=r")
10493         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10494                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10495   "TARGET_SHMEDIA_FPU"
10496   "fcmpeq.s     %1, %2, %0"
10497   [(set_attr "type" "fcmp_media")])
10499 (define_insn "cmpgtsf_media"
10500   [(set (match_operand:SI 0 "register_operand" "=r")
10501         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10502                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10503   "TARGET_SHMEDIA_FPU"
10504   "fcmpgt.s     %1, %2, %0"
10505   [(set_attr "type" "fcmp_media")])
10507 (define_insn "cmpgesf_media"
10508   [(set (match_operand:SI 0 "register_operand" "=r")
10509         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10510                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10511   "TARGET_SHMEDIA_FPU"
10512   "fcmpge.s     %1, %2, %0"
10513   [(set_attr "type" "fcmp_media")])
10515 (define_insn "cmpunsf_media"
10516   [(set (match_operand:SI 0 "register_operand" "=r")
10517         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10518                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10519   "TARGET_SHMEDIA_FPU"
10520   "fcmpun.s     %1, %2, %0"
10521   [(set_attr "type" "fcmp_media")])
10523 (define_expand "cbranchsf4"
10524   [(set (pc)
10525         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10526                        [(match_operand:SF 1 "arith_operand" "")
10527                         (match_operand:SF 2 "arith_operand" "")])
10528                       (match_operand 3 "" "")
10529                       (pc)))]
10530   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10532   if (TARGET_SHMEDIA)
10533     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10534                                           operands[3]));
10535   else
10536     sh_emit_compare_and_branch (operands, SFmode);
10537   DONE;
10540 (define_expand "negsf2"
10541   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10542         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10543   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10545   if (TARGET_SH2E)
10546     {
10547       expand_sf_unop (&gen_negsf2_i, operands);
10548       DONE;
10549     }
10552 (define_insn "*negsf2_media"
10553   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10554         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10555   "TARGET_SHMEDIA_FPU"
10556   "fneg.s       %1, %0"
10557   [(set_attr "type" "fmove_media")])
10559 (define_insn "negsf2_i"
10560   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10561         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10562    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10563   "TARGET_SH2E"
10564   "fneg %0"
10565   [(set_attr "type" "fmove")
10566    (set_attr "fp_mode" "single")])
10568 (define_expand "sqrtsf2"
10569   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10570         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10571   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10573   if (TARGET_SH3E)
10574     {
10575       expand_sf_unop (&gen_sqrtsf2_i, operands);
10576       DONE;
10577     }
10580 (define_insn "*sqrtsf2_media"
10581   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10582         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10583   "TARGET_SHMEDIA_FPU"
10584   "fsqrt.s      %1, %0"
10585   [(set_attr "type" "fdiv_media")])
10587 (define_insn "sqrtsf2_i"
10588   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10589         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10590    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10591   "TARGET_SH3E"
10592   "fsqrt        %0"
10593   [(set_attr "type" "fdiv")
10594    (set_attr "fp_mode" "single")])
10596 (define_insn "rsqrtsf2"
10597   [(set (match_operand:SF 0 "register_operand" "=f")
10598         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10599                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10600    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10601   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10602    && operands[1] == CONST1_RTX (SFmode)"
10603   "fsrra        %0"
10604   [(set_attr "type" "fsrra")
10605    (set_attr "fp_mode" "single")])
10607 (define_insn "fsca"
10608   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10609         (vec_concat:V2SF
10610          (unspec:SF [(mult:SF
10611                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10612                       (match_operand:SF 2 "immediate_operand" "i"))
10613                     ] UNSPEC_FSINA)
10614          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10615                     ] UNSPEC_FCOSA)))
10616    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10617   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10618    && operands[2] == sh_fsca_int2sf ()"
10619   "fsca fpul,%d0"
10620   [(set_attr "type" "fsca")
10621    (set_attr "fp_mode" "single")])
10623 (define_expand "sinsf2"
10624   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10625         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10626                    UNSPEC_FSINA))]
10627   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10629   rtx scaled = gen_reg_rtx (SFmode);
10630   rtx truncated = gen_reg_rtx (SImode);
10631   rtx fsca = gen_reg_rtx (V2SFmode);
10632   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10634   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10635   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10636   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10637                           get_fpscr_rtx ()));
10638   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10639   DONE;
10642 (define_expand "cossf2"
10643   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10644         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10645                    UNSPEC_FCOSA))]
10646   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10648   rtx scaled = gen_reg_rtx (SFmode);
10649   rtx truncated = gen_reg_rtx (SImode);
10650   rtx fsca = gen_reg_rtx (V2SFmode);
10651   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10653   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10654   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10655   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10656                           get_fpscr_rtx ()));
10657   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10658   DONE;
10661 (define_expand "abssf2"
10662   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10663         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10664   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10666   if (TARGET_SH2E)
10667     {
10668       expand_sf_unop (&gen_abssf2_i, operands);
10669       DONE;
10670     }
10673 (define_insn "*abssf2_media"
10674   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10675         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10676   "TARGET_SHMEDIA_FPU"
10677   "fabs.s       %1, %0"
10678   [(set_attr "type" "fmove_media")])
10680 (define_insn "abssf2_i"
10681   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10682         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10683    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10684   "TARGET_SH2E"
10685   "fabs %0"
10686   [(set_attr "type" "fmove")
10687    (set_attr "fp_mode" "single")])
10689 (define_expand "adddf3"
10690   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10691         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10692                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10693   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10695   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10696     {
10697       expand_df_binop (&gen_adddf3_i, operands);
10698       DONE;
10699     }
10702 (define_insn "*adddf3_media"
10703   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10704         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10705                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10706   "TARGET_SHMEDIA_FPU"
10707   "fadd.d       %1, %2, %0"
10708   [(set_attr "type" "dfparith_media")])
10710 (define_insn "adddf3_i"
10711   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10712         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10713                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10714    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10715   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10716   "fadd %2,%0"
10717   [(set_attr "type" "dfp_arith")
10718    (set_attr "fp_mode" "double")])
10720 (define_expand "subdf3"
10721   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10722         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10723                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10724   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10726   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10727     {
10728       expand_df_binop (&gen_subdf3_i, operands);
10729       DONE;
10730     }
10733 (define_insn "*subdf3_media"
10734   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10735         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10736                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10737   "TARGET_SHMEDIA_FPU"
10738   "fsub.d       %1, %2, %0"
10739   [(set_attr "type" "dfparith_media")])
10741 (define_insn "subdf3_i"
10742   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10743         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10744                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10745    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10746   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10747   "fsub %2,%0"
10748   [(set_attr "type" "dfp_arith")
10749    (set_attr "fp_mode" "double")])
10751 (define_expand "muldf3"
10752   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10753         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10754                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10755   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10757   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10758     {
10759       expand_df_binop (&gen_muldf3_i, operands);
10760       DONE;
10761     }
10764 (define_insn "*muldf3_media"
10765   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10766         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10767                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10768   "TARGET_SHMEDIA_FPU"
10769   "fmul.d       %1, %2, %0"
10770   [(set_attr "type" "dfmul_media")])
10772 (define_insn "muldf3_i"
10773   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10774         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10775                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10776    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10777   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10778   "fmul %2,%0"
10779   [(set_attr "type" "dfp_mul")
10780    (set_attr "fp_mode" "double")])
10782 (define_expand "divdf3"
10783   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10784         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10785                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10786   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10788   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10789     {
10790       expand_df_binop (&gen_divdf3_i, operands);
10791       DONE;
10792     }
10795 (define_insn "*divdf3_media"
10796   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10797         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10798                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10799   "TARGET_SHMEDIA_FPU"
10800   "fdiv.d       %1, %2, %0"
10801   [(set_attr "type" "dfdiv_media")])
10803 (define_insn "divdf3_i"
10804   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10805         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10806                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10807    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10808   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10809   "fdiv %2,%0"
10810   [(set_attr "type" "dfdiv")
10811    (set_attr "fp_mode" "double")])
10813 (define_insn "floatdidf2"
10814   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10815         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10816   "TARGET_SHMEDIA_FPU"
10817   "float.qd     %1, %0"
10818   [(set_attr "type" "dfpconv_media")])
10820 (define_expand "floatsidf2"
10821   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10822         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10823   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10825   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10826     {
10827       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10828                                       get_fpscr_rtx ()));
10829       DONE;
10830     }
10833 (define_insn "*floatsidf2_media"
10834   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10835         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10836   "TARGET_SHMEDIA_FPU"
10837   "float.ld     %1, %0"
10838   [(set_attr "type" "dfpconv_media")])
10840 (define_insn "floatsidf2_i"
10841   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10842         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10843    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10844   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10845   "float        %1,%0"
10846   [(set_attr "type" "dfp_conv")
10847    (set_attr "fp_mode" "double")])
10849 (define_insn "fix_truncdfdi2"
10850   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10851         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10852   "TARGET_SHMEDIA_FPU"
10853   "ftrc.dq      %1, %0"
10854   [(set_attr "type" "dfpconv_media")])
10856 (define_expand "fix_truncdfsi2"
10857   [(set (match_operand:SI 0 "fpul_operand" "")
10858         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10859   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10861   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10862     {
10863       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10864                                           get_fpscr_rtx ()));
10865       DONE;
10866     }
10869 (define_insn "*fix_truncdfsi2_media"
10870   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10871         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10872   "TARGET_SHMEDIA_FPU"
10873   "ftrc.dl      %1, %0"
10874   [(set_attr "type" "dfpconv_media")])
10876 (define_insn "fix_truncdfsi2_i"
10877   [(set (match_operand:SI 0 "fpul_operand" "=y")
10878         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10879    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10880   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10881   "ftrc %1,%0"
10882   [(set_attr "type" "dfp_conv")
10883    (set_attr "dfp_comp" "no")
10884    (set_attr "fp_mode" "double")])
10886 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10887 ;; fix_truncdfsi2_i.
10888 ;; (define_insn "fix_truncdfsi2_i4"
10889 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10890 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10891 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10892 ;;    (clobber (reg:SI FPUL_REG))]
10893 ;;   "TARGET_SH4"
10894 ;;   "#"
10895 ;;   [(set_attr "length" "4")
10896 ;;    (set_attr "fp_mode" "double")])
10898 ;; (define_split
10899 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10900 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10901 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10902 ;;    (clobber (reg:SI FPUL_REG))]
10903 ;;   "TARGET_SH4"
10904 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10905 ;;            (use (match_dup 2))])
10906 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10908 (define_insn "cmpgtdf_t"
10909   [(set (reg:SI T_REG)
10910         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10911                (match_operand:DF 1 "arith_reg_operand" "f")))
10912    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10913   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10914   "fcmp/gt      %1,%0"
10915   [(set_attr "type" "dfp_cmp")
10916    (set_attr "fp_mode" "double")])
10918 (define_insn "cmpeqdf_t"
10919   [(set (reg:SI T_REG)
10920         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10921                (match_operand:DF 1 "arith_reg_operand" "f")))
10922    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10923   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10924   "fcmp/eq      %1,%0"
10925   [(set_attr "type" "dfp_cmp")
10926    (set_attr "fp_mode" "double")])
10928 (define_insn "*ieee_ccmpeqdf_t"
10929   [(set (reg:SI T_REG)
10930         (ior:SI (reg:SI T_REG)
10931                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10932                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10933    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10934   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10936   return output_ieee_ccmpeq (insn, operands);
10938   [(set_attr "length" "4")
10939    (set_attr "fp_mode" "double")])
10941 (define_insn "cmpeqdf_media"
10942   [(set (match_operand:SI 0 "register_operand" "=r")
10943         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10944                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10945   "TARGET_SHMEDIA_FPU"
10946   "fcmpeq.d     %1,%2,%0"
10947   [(set_attr "type" "fcmp_media")])
10949 (define_insn "cmpgtdf_media"
10950   [(set (match_operand:SI 0 "register_operand" "=r")
10951         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10952                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10953   "TARGET_SHMEDIA_FPU"
10954   "fcmpgt.d     %1,%2,%0"
10955   [(set_attr "type" "fcmp_media")])
10957 (define_insn "cmpgedf_media"
10958   [(set (match_operand:SI 0 "register_operand" "=r")
10959         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10960                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10961   "TARGET_SHMEDIA_FPU"
10962   "fcmpge.d     %1,%2,%0"
10963   [(set_attr "type" "fcmp_media")])
10965 (define_insn "cmpundf_media"
10966   [(set (match_operand:SI 0 "register_operand" "=r")
10967         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10968                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10969   "TARGET_SHMEDIA_FPU"
10970   "fcmpun.d     %1,%2,%0"
10971   [(set_attr "type" "fcmp_media")])
10973 (define_expand "cbranchdf4"
10974   [(set (pc)
10975         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10976                        [(match_operand:DF 1 "arith_operand" "")
10977                         (match_operand:DF 2 "arith_operand" "")])
10978                       (match_operand 3 "" "")
10979                       (pc)))]
10980   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10982   if (TARGET_SHMEDIA)
10983     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10984                                           operands[3]));
10985   else
10986     sh_emit_compare_and_branch (operands, DFmode);
10987   DONE;
10991 (define_expand "negdf2"
10992   [(set (match_operand:DF 0 "arith_reg_operand" "")
10993         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10994   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10996   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10997     {
10998       expand_df_unop (&gen_negdf2_i, operands);
10999       DONE;
11000     }
11003 (define_insn "*negdf2_media"
11004   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11005         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11006   "TARGET_SHMEDIA_FPU"
11007   "fneg.d       %1, %0"
11008   [(set_attr "type" "fmove_media")])
11010 (define_insn "negdf2_i"
11011   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11012         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11013    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11014   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11015   "fneg %0"
11016   [(set_attr "type" "fmove")
11017    (set_attr "fp_mode" "double")])
11019 (define_expand "sqrtdf2"
11020   [(set (match_operand:DF 0 "arith_reg_operand" "")
11021         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11022   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11024   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11025     {
11026       expand_df_unop (&gen_sqrtdf2_i, operands);
11027       DONE;
11028     }
11031 (define_insn "*sqrtdf2_media"
11032   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11033         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11034   "TARGET_SHMEDIA_FPU"
11035   "fsqrt.d      %1, %0"
11036   [(set_attr "type" "dfdiv_media")])
11038 (define_insn "sqrtdf2_i"
11039   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11040         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11041    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11042   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11043   "fsqrt        %0"
11044   [(set_attr "type" "dfdiv")
11045    (set_attr "fp_mode" "double")])
11047 (define_expand "absdf2"
11048   [(set (match_operand:DF 0 "arith_reg_operand" "")
11049         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11050   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11052   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11053     {
11054       expand_df_unop (&gen_absdf2_i, operands);
11055       DONE;
11056     }
11059 (define_insn "*absdf2_media"
11060   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11061         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11062   "TARGET_SHMEDIA_FPU"
11063   "fabs.d       %1, %0"
11064   [(set_attr "type" "fmove_media")])
11066 (define_insn "absdf2_i"
11067   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11068         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11069    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11070   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11071   "fabs %0"
11072   [(set_attr "type" "fmove")
11073    (set_attr "fp_mode" "double")])
11075 (define_expand "extendsfdf2"
11076   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11077         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11078   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11080   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11081     {
11082       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11083                                         get_fpscr_rtx ()));
11084       DONE;
11085     }
11088 (define_insn "*extendsfdf2_media"
11089   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11090         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11091   "TARGET_SHMEDIA_FPU"
11092   "fcnv.sd      %1, %0"
11093   [(set_attr "type" "dfpconv_media")])
11095 (define_insn "extendsfdf2_i4"
11096   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11097         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11098    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11099   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11100   "fcnvsd  %1,%0"
11101   [(set_attr "type" "fp")
11102    (set_attr "fp_mode" "double")])
11104 (define_expand "truncdfsf2"
11105   [(set (match_operand:SF 0 "fpul_operand" "")
11106         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11107   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11109   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11110     {
11111       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11112                                        get_fpscr_rtx ()));
11113       DONE;
11114     }
11117 (define_insn "*truncdfsf2_media"
11118   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11119         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11120   "TARGET_SHMEDIA_FPU"
11121   "fcnv.ds      %1, %0"
11122   [(set_attr "type" "dfpconv_media")])
11124 (define_insn "truncdfsf2_i4"
11125   [(set (match_operand:SF 0 "fpul_operand" "=y")
11126         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11127    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11128   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11129   "fcnvds  %1,%0"
11130   [(set_attr "type" "fp")
11131    (set_attr "fp_mode" "double")])
11133 ;; Bit field extract patterns.  These give better code for packed bitfields,
11134 ;; because they allow auto-increment addresses to be generated.
11136 (define_expand "insv"
11137   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11138                          (match_operand:SI 1 "immediate_operand" "")
11139                          (match_operand:SI 2 "immediate_operand" ""))
11140         (match_operand:SI 3 "general_operand" ""))]
11141   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11143   rtx addr_target, orig_address, shift_reg, qi_val;
11144   HOST_WIDE_INT bitsize, size, v = 0;
11145   rtx x = operands[3];
11147   if (TARGET_SH2A && TARGET_BITOPS
11148       && (satisfies_constraint_Sbw (operands[0])
11149           || satisfies_constraint_Sbv (operands[0]))
11150       && satisfies_constraint_M (operands[1])
11151       && satisfies_constraint_K03 (operands[2]))
11152     {
11153       if (satisfies_constraint_N (operands[3]))
11154         {
11155           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11156           DONE;
11157         }
11158       else if (satisfies_constraint_M (operands[3]))
11159         {
11160           emit_insn (gen_bset_m2a (operands[0], operands[2]));
11161           DONE;
11162         }
11163       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11164                 && satisfies_constraint_M (operands[1]))
11165         {
11166           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11167           DONE;
11168         }
11169       else if (REG_P (operands[3])
11170                && satisfies_constraint_M (operands[1]))
11171         {
11172           emit_insn (gen_bld_reg (operands[3], const0_rtx));
11173           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11174           DONE;
11175         }
11176     }
11177   /* ??? expmed doesn't care for non-register predicates.  */
11178   if (! memory_operand (operands[0], VOIDmode)
11179       || ! immediate_operand (operands[1], VOIDmode)
11180       || ! immediate_operand (operands[2], VOIDmode)
11181       || ! general_operand (x, VOIDmode))
11182     FAIL;
11183   /* If this isn't a 16 / 24 / 32 bit field, or if
11184      it doesn't start on a byte boundary, then fail.  */
11185   bitsize = INTVAL (operands[1]);
11186   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11187       || (INTVAL (operands[2]) % 8) != 0)
11188     FAIL;
11190   size = bitsize / 8;
11191   orig_address = XEXP (operands[0], 0);
11192   shift_reg = gen_reg_rtx (SImode);
11193   if (CONST_INT_P (x))
11194     {
11195       v = INTVAL (x);
11196       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11197     }
11198   else
11199     {
11200       emit_insn (gen_movsi (shift_reg, operands[3]));
11201       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11202     }
11203   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11205   operands[0] = replace_equiv_address (operands[0], addr_target);
11206   emit_insn (gen_movqi (operands[0], qi_val));
11208   while (size -= 1)
11209     {
11210       if (CONST_INT_P (x))
11211         qi_val
11212           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11213       else
11214         {
11215           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11216           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11217         }
11218       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11219       emit_insn (gen_movqi (operands[0], qi_val));
11220     }
11222   DONE;
11225 (define_insn "movua"
11226   [(set (match_operand:SI 0 "register_operand" "=z")
11227         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11228                    UNSPEC_MOVUA))]
11229   "TARGET_SH4A_ARCH"
11230   "movua.l      %1,%0"
11231   [(set_attr "type" "movua")])
11233 ;; We shouldn't need this, but cse replaces increments with references
11234 ;; to other regs before flow has a chance to create post_inc
11235 ;; addressing modes, and only postreload's cse_move2add brings the
11236 ;; increments back to a usable form.
11237 (define_peephole2
11238   [(set (match_operand:SI 0 "register_operand" "")
11239         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11240                          (const_int 32) (const_int 0)))
11241    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11242   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11243   [(set (match_operand:SI 0 "register_operand" "")
11244         (sign_extract:SI (mem:SI (post_inc:SI
11245                                   (match_operand:SI 1 "register_operand" "")))
11246                          (const_int 32) (const_int 0)))]
11247   "")
11249 (define_expand "extv"
11250   [(set (match_operand:SI 0 "register_operand" "")
11251         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11252                          (match_operand 2 "const_int_operand" "")
11253                          (match_operand 3 "const_int_operand" "")))]
11254   "TARGET_SH4A_ARCH || TARGET_SH2A"
11256   if (TARGET_SH2A && TARGET_BITOPS
11257       && (satisfies_constraint_Sbw (operands[1])
11258           || satisfies_constraint_Sbv (operands[1]))
11259       && satisfies_constraint_M (operands[2])
11260       && satisfies_constraint_K03 (operands[3]))
11261    {
11262       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11263       if (REGNO (operands[0]) != T_REG)
11264         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11265       DONE;
11266    }
11267   if (TARGET_SH4A_ARCH
11268       && INTVAL (operands[2]) == 32
11269       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11270       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11271     {
11272       rtx src = adjust_address (operands[1], BLKmode, 0);
11273       set_mem_size (src, 4);
11274       emit_insn (gen_movua (operands[0], src));
11275       DONE;
11276     }
11278   FAIL;
11281 (define_expand "extzv"
11282   [(set (match_operand:SI 0 "register_operand" "")
11283         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11284                          (match_operand 2 "const_int_operand" "")
11285                          (match_operand 3 "const_int_operand" "")))]
11286   "TARGET_SH4A_ARCH || TARGET_SH2A"
11288   if (TARGET_SH2A && TARGET_BITOPS
11289       && (satisfies_constraint_Sbw (operands[1])
11290           || satisfies_constraint_Sbv (operands[1]))
11291       && satisfies_constraint_M (operands[2])
11292       && satisfies_constraint_K03 (operands[3]))
11293     {
11294       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11295       if (REGNO (operands[0]) != T_REG)
11296         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11297       DONE;
11298     }
11299   if (TARGET_SH4A_ARCH
11300       && INTVAL (operands[2]) == 32
11301       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11302       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11303     {
11304       rtx src = adjust_address (operands[1], BLKmode, 0);
11305       set_mem_size (src, 4);
11306       emit_insn (gen_movua (operands[0], src));
11307       DONE;
11308     }
11310   FAIL;
11313 ;; SH2A instructions for bitwise operations.
11315 ;; Clear a bit in a memory location.
11316 (define_insn "bclr_m2a"
11317   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11318         (and:QI
11319             (not:QI (ashift:QI (const_int 1)
11320                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11321             (match_dup 0)))]
11322   "TARGET_SH2A && TARGET_BITOPS"
11323   "@
11324         bclr.b\\t%1,%0
11325         bclr.b\\t%1,@(0,%t0)"
11326 [(set_attr "length" "4,4")])
11328 (define_insn "bclrmem_m2a"
11329   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11330         (and:QI (match_dup 0)
11331                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11332   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11333   "@
11334         bclr.b\\t%W1,%0
11335         bclr.b\\t%W1,@(0,%t0)"
11336   [(set_attr "length" "4,4")])
11338 ;; Set a bit in a memory location.
11339 (define_insn "bset_m2a"
11340   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11341         (ior:QI
11342             (ashift:QI (const_int 1)
11343                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11344             (match_dup 0)))]
11345   "TARGET_SH2A && TARGET_BITOPS"
11346   "@
11347         bset.b\\t%1,%0
11348         bset.b\\t%1,@(0,%t0)"
11349   [(set_attr "length" "4,4")])
11351 (define_insn "bsetmem_m2a"
11352   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11353         (ior:QI (match_dup 0)
11354                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11355   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11356   "@
11357         bset.b\\t%V1,%0
11358         bset.b\\t%V1,@(0,%t0)"
11359   [(set_attr "length" "4,4")])
11361 ;;; Transfer the contents of the T bit to a specified bit of memory.
11362 (define_insn "bst_m2a"
11363   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11364         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11365             (and:QI
11366                 (not:QI (ashift:QI (const_int 1)
11367                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11368                 (match_dup 0))
11369             (ior:QI
11370                 (ashift:QI (const_int 1) (match_dup 1))
11371                 (match_dup 0))))]
11372   "TARGET_SH2A && TARGET_BITOPS"
11373   "@
11374         bst.b\\t%1,%0
11375         bst.b\\t%1,@(0,%t0)"
11376   [(set_attr "length" "4")])
11378 ;; Store a specified bit of memory in the T bit.
11379 (define_insn "bld_m2a"
11380   [(set (reg:SI T_REG)
11381         (zero_extract:SI
11382             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11383             (const_int 1)
11384             (match_operand 1 "const_int_operand" "K03,K03")))]
11385   "TARGET_SH2A && TARGET_BITOPS"
11386   "@
11387         bld.b\\t%1,%0
11388         bld.b\\t%1,@(0,%t0)"
11389   [(set_attr "length" "4,4")])
11391 ;; Store a specified bit of memory in the T bit.
11392 (define_insn "bldsign_m2a"
11393   [(set (reg:SI T_REG)
11394         (sign_extract:SI
11395             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11396             (const_int 1)
11397             (match_operand 1 "const_int_operand" "K03,K03")))]
11398   "TARGET_SH2A && TARGET_BITOPS"
11399   "@
11400         bld.b\\t%1,%0
11401         bld.b\\t%1,@(0,%t0)"
11402   [(set_attr "length" "4,4")])
11404 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11405 (define_insn "bld_reg"
11406   [(set (reg:SI T_REG)
11407         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11408                          (const_int 1)
11409                          (match_operand 1 "const_int_operand" "K03")))]
11410   "TARGET_SH2A"
11411   "bld\\t%1,%0")
11413 (define_insn "*bld_regqi"
11414   [(set (reg:SI T_REG)
11415         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11416                          (const_int 1)
11417                          (match_operand 1 "const_int_operand" "K03")))]
11418   "TARGET_SH2A"
11419   "bld\\t%1,%0")
11421 ;; Take logical and of a specified bit of memory with the T bit and
11422 ;; store its result in the T bit.
11423 (define_insn "band_m2a"
11424   [(set (reg:SI T_REG)
11425         (and:SI (reg:SI T_REG)
11426                 (zero_extract:SI
11427                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11428                     (const_int 1)
11429                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11430   "TARGET_SH2A && TARGET_BITOPS"
11431   "@
11432         band.b\\t%1,%0
11433         band.b\\t%1,@(0,%t0)"
11434   [(set_attr "length" "4,4")])
11436 (define_insn "bandreg_m2a"
11437   [(set (match_operand:SI 0 "register_operand" "=r,r")
11438         (and:SI (zero_extract:SI
11439                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11440                     (const_int 1)
11441                     (match_operand 2 "const_int_operand" "K03,K03"))
11442                 (match_operand:SI 3 "register_operand" "r,r")))]
11443   "TARGET_SH2A && TARGET_BITOPS"
11444   "@
11445         band.b\\t%2,%1\;movt\\t%0
11446         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11447   [(set_attr "length" "6,6")])
11449 ;; Take logical or of a specified bit of memory with the T bit and
11450 ;; store its result in the T bit.
11451 (define_insn "bor_m2a"
11452   [(set (reg:SI T_REG)
11453         (ior:SI (reg:SI T_REG)
11454                 (zero_extract:SI
11455                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11456                     (const_int 1)
11457                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11458   "TARGET_SH2A && TARGET_BITOPS"
11459   "@
11460         bor.b\\t%1,%0
11461         bor.b\\t%1,@(0,%t0)"
11462   [(set_attr "length" "4,4")])
11464 (define_insn "borreg_m2a"
11465   [(set (match_operand:SI 0 "register_operand" "=r,r")
11466         (ior:SI (zero_extract:SI
11467                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11468                     (const_int 1)
11469                     (match_operand 2 "const_int_operand" "K03,K03"))
11470                 (match_operand:SI 3 "register_operand" "=r,r")))]
11471   "TARGET_SH2A && TARGET_BITOPS"
11472   "@
11473         bor.b\\t%2,%1\;movt\\t%0
11474         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11475   [(set_attr "length" "6,6")])
11477 ;; Take exclusive or of a specified bit of memory with the T bit and
11478 ;; store its result in the T bit.
11479 (define_insn "bxor_m2a"
11480   [(set (reg:SI T_REG)
11481         (xor:SI (reg:SI T_REG)
11482                 (zero_extract:SI
11483                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11484                     (const_int 1)
11485                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11486   "TARGET_SH2A && TARGET_BITOPS"
11487   "@
11488         bxor.b\\t%1,%0
11489         bxor.b\\t%1,@(0,%t0)"
11490   [(set_attr "length" "4,4")])
11492 (define_insn "bxorreg_m2a"
11493   [(set (match_operand:SI 0 "register_operand" "=r,r")
11494         (xor:SI (zero_extract:SI
11495                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11496                     (const_int 1)
11497                     (match_operand 2 "const_int_operand" "K03,K03"))
11498                 (match_operand:SI 3 "register_operand" "=r,r")))]
11499   "TARGET_SH2A && TARGET_BITOPS"
11500   "@
11501         bxor.b\\t%2,%1\;movt\\t%0
11502         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11503   [(set_attr "length" "6,6")])
11506 ;; -------------------------------------------------------------------------
11507 ;; Peepholes
11508 ;; -------------------------------------------------------------------------
11509 ;; This matches cases where the bit in a memory location is set.
11510 (define_peephole2
11511   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11512         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11513    (set (match_dup 0)
11514         (ior:SI (match_dup 0)
11515         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11516    (set (match_dup 1)
11517         (match_operand 3 "arith_reg_operand" "r,r"))]
11518   "TARGET_SH2A && TARGET_BITOPS
11519    && satisfies_constraint_Pso (operands[2])
11520    && REGNO (operands[0]) == REGNO (operands[3])"
11521   [(set (match_dup 1)
11522         (ior:QI (match_dup 1)
11523                 (match_dup 2)))]
11524   "")
11526 ;; This matches cases where the bit in a memory location is cleared.
11527 (define_peephole2
11528   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11529         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11530    (set (match_dup 0)
11531         (and:SI (match_dup 0)
11532         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11533    (set (match_dup 1)
11534         (match_operand 3 "arith_reg_operand" "r,r"))]
11535   "TARGET_SH2A && TARGET_BITOPS
11536    && satisfies_constraint_Psz (operands[2])
11537    && REGNO (operands[0]) == REGNO (operands[3])"
11538   [(set (match_dup 1)
11539         (and:QI (match_dup 1)
11540                 (match_dup 2)))]
11541   "")
11543 ;; This matches cases where a stack pointer increment at the start of the
11544 ;; epilogue combines with a stack slot read loading the return value.
11546 (define_peephole
11547   [(set (match_operand:SI 0 "arith_reg_operand" "")
11548         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11549    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11550   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11551   "mov.l        @%1+,%0")
11553 ;; See the comment on the dt combiner pattern above.
11555 (define_peephole
11556   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11557         (plus:SI (match_dup 0)
11558                  (const_int -1)))
11559    (set (reg:SI T_REG)
11560         (eq:SI (match_dup 0)
11561                (const_int 0)))]
11562   "TARGET_SH2"
11563   "dt   %0")
11565 ;; The following peepholes fold load sequences for which reload was not
11566 ;; able to generate a displacement addressing move insn.
11567 ;; This can happen when reload has to transform a move insn 
11568 ;; without displacement into one with displacement.  Or when reload can't
11569 ;; fit a displacement into the insn's constraints.  In the latter case, the
11570 ;; load destination reg remains at r0, which reload compensates by inserting
11571 ;; another mov insn.
11573 ;; Fold sequence:
11574 ;;      mov #54,r0
11575 ;;      mov.b @(r0,r15),r0
11576 ;;      mov r0,r3
11577 ;; into:
11578 ;;      mov.b @(54,r15),r3
11580 (define_peephole2
11581   [(set (match_operand:SI 0 "arith_reg_dest" "")
11582         (match_operand:SI 1 "const_int_operand" ""))
11583    (set (match_operand:SI 2 "arith_reg_dest" "")
11584         (sign_extend:SI
11585          (mem:QI (plus:SI (match_dup 0)
11586                           (match_operand:SI 3 "arith_reg_operand" "")))))
11587    (set (match_operand:QI 4 "arith_reg_dest" "")
11588         (match_operand:QI 5 "arith_reg_operand" ""))]
11589   "TARGET_SH2A
11590    && CONST_OK_FOR_K12 (INTVAL (operands[1]))
11591    && REGNO (operands[2]) == REGNO (operands[5])
11592    && peep2_reg_dead_p (3, operands[5])"
11593   [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))]
11594   "")
11596 ;; Fold sequence:
11597 ;;      mov #54,r0
11598 ;;      mov.b @(r0,r15),r1
11599 ;; into:
11600 ;;      mov.b @(54,r15),r1
11602 (define_peephole2
11603   [(set (match_operand:SI 0 "arith_reg_dest" "")
11604         (match_operand:SI 1 "const_int_operand" ""))
11605    (set (match_operand:SI 2 "arith_reg_dest" "")
11606          (sign_extend:SI
11607          (mem:QI (plus:SI (match_dup 0)
11608                           (match_operand:SI 3 "arith_reg_operand" "")))))]
11609   "TARGET_SH2A
11610    && CONST_OK_FOR_K12 (INTVAL (operands[1]))
11611    && (peep2_reg_dead_p (2, operands[0])
11612        || REGNO (operands[0]) == REGNO (operands[2]))"
11613   [(set (match_dup 2)
11614         (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))]
11615   "")
11617 ;; Fold sequence:
11618 ;;      mov.b @(r0,r15),r0
11619 ;;      mov r0,r3
11620 ;; into:
11621 ;;      mov.b @(r0,r15),r3
11623 (define_peephole2
11624   [(set (match_operand:SI 0 "arith_reg_dest" "")
11625         (sign_extend:SI
11626          (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "")
11627                           (match_operand:SI 2 "arith_reg_operand" "")))))
11628    (set (match_operand:QI 3 "arith_reg_dest" "")
11629         (match_operand:QI 4 "arith_reg_operand" ""))]
11630   "TARGET_SH1
11631    && REGNO (operands[0]) == REGNO (operands[4])
11632    && peep2_reg_dead_p (2, operands[0])"
11633   [(set (match_dup 3)
11634         (mem:QI (plus:SI (match_dup 1) (match_dup 2))))]
11635   "")
11637 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11638 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11639 ;; reload when the constant is too large for a reg+offset address.
11641 ;; ??? We would get much better code if this was done in reload.  This would
11642 ;; require modifying find_reloads_address to recognize that if the constant
11643 ;; is out-of-range for an immediate add, then we get better code by reloading
11644 ;; the constant into a register than by reloading the sum into a register,
11645 ;; since the former is one instruction shorter if the address does not need
11646 ;; to be offsettable.  Unfortunately this does not work, because there is
11647 ;; only one register, r0, that can be used as an index register.  This register
11648 ;; is also the function return value register.  So, if we try to force reload
11649 ;; to use double-reg addresses, then we end up with some instructions that
11650 ;; need to use r0 twice.  The only way to fix this is to change the calling
11651 ;; convention so that r0 is not used to return values.
11653 (define_peephole
11654   [(set (match_operand:SI 0 "register_operand" "=r")
11655         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11656    (set (mem:SI (match_dup 0))
11657         (match_operand:SI 2 "general_movsrc_operand" ""))]
11658   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11659   "mov.l        %2,@(%0,%1)")
11661 (define_peephole
11662   [(set (match_operand:SI 0 "register_operand" "=r")
11663         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11664    (set (match_operand:SI 2 "general_movdst_operand" "")
11665         (mem:SI (match_dup 0)))]
11666   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11667   "mov.l        @(%0,%1),%2")
11669 (define_peephole
11670   [(set (match_operand:SI 0 "register_operand" "=r")
11671         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11672    (set (mem:HI (match_dup 0))
11673         (match_operand:HI 2 "general_movsrc_operand" ""))]
11674   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11675   "mov.w        %2,@(%0,%1)")
11677 (define_peephole
11678   [(set (match_operand:SI 0 "register_operand" "=r")
11679         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11680    (set (match_operand:HI 2 "general_movdst_operand" "")
11681         (mem:HI (match_dup 0)))]
11682   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11683   "mov.w        @(%0,%1),%2")
11685 (define_peephole
11686   [(set (match_operand:SI 0 "register_operand" "=r")
11687         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11688    (set (mem:QI (match_dup 0))
11689         (match_operand:QI 2 "general_movsrc_operand" ""))]
11690   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11691   "mov.b        %2,@(%0,%1)")
11693 (define_peephole
11694   [(set (match_operand:SI 0 "register_operand" "=r")
11695         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11696    (set (match_operand:QI 2 "general_movdst_operand" "")
11697         (mem:QI (match_dup 0)))]
11698   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11699   "mov.b        @(%0,%1),%2")
11701 (define_peephole
11702   [(set (match_operand:SI 0 "register_operand" "=r")
11703         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11704    (set (mem:SF (match_dup 0))
11705         (match_operand:SF 2 "general_movsrc_operand" ""))]
11706   "TARGET_SH1 && REGNO (operands[0]) == 0
11707    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11708        || (GET_CODE (operands[2]) == SUBREG
11709            && REGNO (SUBREG_REG (operands[2])) < 16))
11710    && reg_unused_after (operands[0], insn)"
11711   "mov.l        %2,@(%0,%1)")
11713 (define_peephole
11714   [(set (match_operand:SI 0 "register_operand" "=r")
11715         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11716    (set (match_operand:SF 2 "general_movdst_operand" "")
11718         (mem:SF (match_dup 0)))]
11719   "TARGET_SH1 && REGNO (operands[0]) == 0
11720    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11721        || (GET_CODE (operands[2]) == SUBREG
11722            && REGNO (SUBREG_REG (operands[2])) < 16))
11723    && reg_unused_after (operands[0], insn)"
11724   "mov.l        @(%0,%1),%2")
11726 (define_peephole
11727   [(set (match_operand:SI 0 "register_operand" "=r")
11728         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11729    (set (mem:SF (match_dup 0))
11730         (match_operand:SF 2 "general_movsrc_operand" ""))]
11731   "TARGET_SH2E && REGNO (operands[0]) == 0
11732    && ((REG_P (operands[2])
11733         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11734        || (GET_CODE (operands[2]) == SUBREG
11735            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11736    && reg_unused_after (operands[0], insn)"
11737   "fmov{.s|}    %2,@(%0,%1)")
11739 (define_peephole
11740   [(set (match_operand:SI 0 "register_operand" "=r")
11741         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11742    (set (match_operand:SF 2 "general_movdst_operand" "")
11744         (mem:SF (match_dup 0)))]
11745   "TARGET_SH2E && REGNO (operands[0]) == 0
11746    && ((REG_P (operands[2])
11747         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11748        || (GET_CODE (operands[2]) == SUBREG
11749            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11750    && reg_unused_after (operands[0], insn)"
11751   "fmov{.s|}    @(%0,%1),%2")
11753 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11754 (define_insn "sp_switch_1"
11755   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11756   "TARGET_SH1"
11758   output_asm_insn ("mov.l r0,@-r15\;mov.l %0,r0", operands);
11759   output_asm_insn ("mov.l @r0,r0\;mov.l r15,@-r0", operands);
11760   return "mov r0,r15";
11762   [(set_attr "length" "10")])
11764 ;; Switch back to the original stack for interrupt functions with the
11765 ;; sp_switch attribute.  */
11766 (define_insn "sp_switch_2"
11767   [(const_int 2)]
11768   "TARGET_SH1"
11769   "mov.l @r15+,r15\;mov.l @r15+,r0"
11770   [(set_attr "length" "4")])
11772 ;; Integer vector moves
11774 (define_expand "movv8qi"
11775   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11776         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11777   "TARGET_SHMEDIA"
11779   if (prepare_move_operands (operands, V8QImode))
11780     DONE;
11783 (define_insn "movv8qi_i"
11784   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11785         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11786   "TARGET_SHMEDIA
11787    && (register_operand (operands[0], V8QImode)
11788        || sh_register_operand (operands[1], V8QImode))"
11789   "@
11790         add     %1, r63, %0
11791         movi    %1, %0
11792         #
11793         ld%M1.q %m1, %0
11794         st%M0.q %m0, %N1"
11795   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11796    (set_attr "length" "4,4,16,4,4")])
11798 (define_split
11799   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11800         (subreg:V8QI (const_int 0) 0))]
11801   "TARGET_SHMEDIA"
11802   [(set (match_dup 0)
11803         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11804                             (const_int 0) (const_int 0) (const_int 0)
11805                             (const_int 0) (const_int 0)]))])
11807 (define_split
11808   [(set (match_operand 0 "arith_reg_dest" "")
11809         (match_operand 1 "sh_rep_vec" ""))]
11810   "TARGET_SHMEDIA && reload_completed
11811    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11812    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11813    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11814    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11815        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11816    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11817        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11818   [(set (match_dup 0) (match_dup 1))
11819    (match_dup 2)]
11821   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11822   rtx elt1 = XVECEXP (operands[1], 0, 1);
11824   if (unit_size > 2)
11825     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11826   else
11827     {
11828       if (unit_size < 2)
11829         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11830       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11831     }
11832   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11833   operands[1] = XVECEXP (operands[1], 0, 0);
11834   if (unit_size < 2)
11835     {
11836       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11837         operands[1]
11838           = GEN_INT (TARGET_LITTLE_ENDIAN
11839                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11840                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11841       else
11842         {
11843           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11844           operands[1]
11845             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11846         }
11847     }
11850 (define_split
11851   [(set (match_operand 0 "arith_reg_dest" "")
11852         (match_operand 1 "sh_const_vec" ""))]
11853   "TARGET_SHMEDIA && reload_completed
11854    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11855    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11856   [(set (match_dup 0) (match_dup 1))]
11858   rtx v = operands[1];
11859   enum machine_mode new_mode
11860     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11862   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11863   operands[1]
11864     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11867 (define_expand "movv2hi"
11868   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11869         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11870   "TARGET_SHMEDIA"
11872   if (prepare_move_operands (operands, V2HImode))
11873     DONE;
11876 (define_insn "movv2hi_i"
11877   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11878         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11879   "TARGET_SHMEDIA
11880    && (register_operand (operands[0], V2HImode)
11881        || sh_register_operand (operands[1], V2HImode))"
11882   "@
11883         add.l   %1, r63, %0
11884         movi    %1, %0
11885         #
11886         ld%M1.l %m1, %0
11887         st%M0.l %m0, %N1"
11888   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11889    (set_attr "length" "4,4,16,4,4")
11890    (set (attr "highpart")
11891         (cond [(match_test "sh_contains_memref_p (insn)")
11892                (const_string "user")]
11893               (const_string "ignore")))])
11895 (define_expand "movv4hi"
11896   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11897         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11898   "TARGET_SHMEDIA"
11900   if (prepare_move_operands (operands, V4HImode))
11901     DONE;
11904 (define_insn "movv4hi_i"
11905   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11906         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11907   "TARGET_SHMEDIA
11908    && (register_operand (operands[0], V4HImode)
11909        || sh_register_operand (operands[1], V4HImode))"
11910   "@
11911         add     %1, r63, %0
11912         movi    %1, %0
11913         #
11914         ld%M1.q %m1, %0
11915         st%M0.q %m0, %N1"
11916   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11917    (set_attr "length" "4,4,16,4,4")
11918    (set_attr "highpart" "depend")])
11920 (define_expand "movv2si"
11921   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11922         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11923   "TARGET_SHMEDIA"
11925   if (prepare_move_operands (operands, V2SImode))
11926   DONE;
11929 (define_insn "movv2si_i"
11930   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11931         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11932   "TARGET_SHMEDIA
11933    && (register_operand (operands[0], V2SImode)
11934        || sh_register_operand (operands[1], V2SImode))"
11935   "@
11936         add     %1, r63, %0
11937         #
11938         #
11939         ld%M1.q %m1, %0
11940         st%M0.q %m0, %N1"
11941   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11942    (set_attr "length" "4,4,16,4,4")
11943    (set_attr "highpart" "depend")])
11945 ;; Multimedia Intrinsics
11947 (define_insn "absv2si2"
11948   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11949         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11950   "TARGET_SHMEDIA"
11951   "mabs.l       %1, %0"
11952   [(set_attr "type" "mcmp_media")
11953    (set_attr "highpart" "depend")])
11955 (define_insn "absv4hi2"
11956   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11957         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11958   "TARGET_SHMEDIA"
11959   "mabs.w       %1, %0"
11960   [(set_attr "type" "mcmp_media")
11961    (set_attr "highpart" "depend")])
11963 (define_insn "addv2si3"
11964   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11965         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11966                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11967   "TARGET_SHMEDIA"
11968   "madd.l       %1, %2, %0"
11969   [(set_attr "type" "arith_media")
11970    (set_attr "highpart" "depend")])
11972 (define_insn "addv4hi3"
11973   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11974         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11975                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11976   "TARGET_SHMEDIA"
11977   "madd.w       %1, %2, %0"
11978   [(set_attr "type" "arith_media")
11979    (set_attr "highpart" "depend")])
11981 (define_insn_and_split "addv2hi3"
11982   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11983         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11984                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11985   "TARGET_SHMEDIA"
11986   "#"
11987   "TARGET_SHMEDIA"
11988   [(const_int 0)]
11990   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11991   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11992   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11993   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11994   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11996   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11997   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11998   DONE;
12000   [(set_attr "highpart" "must_split")])
12002 (define_insn "ssaddv2si3"
12003   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12004         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12005                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12006   "TARGET_SHMEDIA"
12007   "madds.l      %1, %2, %0"
12008   [(set_attr "type" "mcmp_media")
12009    (set_attr "highpart" "depend")])
12011 (define_insn "usaddv8qi3"
12012   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12013         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12014                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12015   "TARGET_SHMEDIA"
12016   "madds.ub     %1, %2, %0"
12017   [(set_attr "type" "mcmp_media")
12018    (set_attr "highpart" "depend")])
12020 (define_insn "ssaddv4hi3"
12021   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12022         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12023                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12024   "TARGET_SHMEDIA"
12025   "madds.w      %1, %2, %0"
12026   [(set_attr "type" "mcmp_media")
12027    (set_attr "highpart" "depend")])
12029 (define_insn "negcmpeqv8qi"
12030   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12031         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12032                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12033   "TARGET_SHMEDIA"
12034   "mcmpeq.b     %N1, %N2, %0"
12035   [(set_attr "type" "mcmp_media")
12036    (set_attr "highpart" "depend")])
12038 (define_insn "negcmpeqv2si"
12039   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12040         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12041                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12042   "TARGET_SHMEDIA"
12043   "mcmpeq.l     %N1, %N2, %0"
12044   [(set_attr "type" "mcmp_media")
12045    (set_attr "highpart" "depend")])
12047 (define_insn "negcmpeqv4hi"
12048   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12049         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12050                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12051   "TARGET_SHMEDIA"
12052   "mcmpeq.w     %N1, %N2, %0"
12053   [(set_attr "type" "mcmp_media")
12054    (set_attr "highpart" "depend")])
12056 (define_insn "negcmpgtuv8qi"
12057   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12058         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12059                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12060   "TARGET_SHMEDIA"
12061   "mcmpgt.ub    %N1, %N2, %0"
12062   [(set_attr "type" "mcmp_media")
12063    (set_attr "highpart" "depend")])
12065 (define_insn "negcmpgtv2si"
12066   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12067         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12068                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12069   "TARGET_SHMEDIA"
12070   "mcmpgt.l     %N1, %N2, %0"
12071   [(set_attr "type" "mcmp_media")
12072    (set_attr "highpart" "depend")])
12074 (define_insn "negcmpgtv4hi"
12075   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12076         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12077                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12078   "TARGET_SHMEDIA"
12079   "mcmpgt.w     %N1, %N2, %0"
12080   [(set_attr "type" "mcmp_media")
12081    (set_attr "highpart" "depend")])
12083 (define_insn "mcmv"
12084   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12085         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12086                         (match_operand:DI 2 "arith_reg_operand" "r"))
12087                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12088                         (not:DI (match_dup 2)))))]
12089   "TARGET_SHMEDIA"
12090   "mcmv %N1, %2, %0"
12091   [(set_attr "type" "arith_media")
12092    (set_attr "highpart" "depend")])
12094 (define_insn "mcnvs_lw"
12095   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12096         (vec_concat:V4HI
12097          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12098          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12099   "TARGET_SHMEDIA"
12100   "mcnvs.lw     %N1, %N2, %0"
12101   [(set_attr "type" "mcmp_media")])
12103 (define_insn "mcnvs_wb"
12104   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12105         (vec_concat:V8QI
12106          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12107          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12108   "TARGET_SHMEDIA"
12109   "mcnvs.wb     %N1, %N2, %0"
12110   [(set_attr "type" "mcmp_media")])
12112 (define_insn "mcnvs_wub"
12113   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12114         (vec_concat:V8QI
12115          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12116          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12117   "TARGET_SHMEDIA"
12118   "mcnvs.wub    %N1, %N2, %0"
12119   [(set_attr "type" "mcmp_media")])
12121 (define_insn "mextr_rl"
12122   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12123         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12124                              (match_operand:HI 3 "mextr_bit_offset" "i"))
12125                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12126                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12127   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12129   static char templ[21];
12130   sprintf (templ, "mextr%d\\t%%N1, %%N2, %%0", (int) INTVAL (operands[3]) >> 3);
12131   return templ;
12133   [(set_attr "type" "arith_media")])
12135 (define_insn "*mextr_lr"
12136   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12137         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12138                            (match_operand:HI 3 "mextr_bit_offset" "i"))
12139                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12140                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12141   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12143   static char templ[21];
12144   sprintf (templ, "mextr%d\\t%%N2, %%N1, %%0", (int) INTVAL (operands[4]) >> 3);
12145   return templ;
12147   [(set_attr "type" "arith_media")])
12149 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12150 ; vector then varies depending on endianness.
12151 (define_expand "mextr1"
12152   [(match_operand:DI 0 "arith_reg_dest" "")
12153    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12154    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12155   "TARGET_SHMEDIA"
12157   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12158                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
12159   DONE;
12162 (define_expand "mextr2"
12163   [(match_operand:DI 0 "arith_reg_dest" "")
12164    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12165    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12166   "TARGET_SHMEDIA"
12168   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12169                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
12170   DONE;
12173 (define_expand "mextr3"
12174   [(match_operand:DI 0 "arith_reg_dest" "")
12175    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12176    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12177   "TARGET_SHMEDIA"
12179   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12180                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
12181   DONE;
12184 (define_expand "mextr4"
12185   [(match_operand:DI 0 "arith_reg_dest" "")
12186    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12187    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12188   "TARGET_SHMEDIA"
12190   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12191                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
12192   DONE;
12195 (define_expand "mextr5"
12196   [(match_operand:DI 0 "arith_reg_dest" "")
12197    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12198    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12199   "TARGET_SHMEDIA"
12201   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12202                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
12203   DONE;
12206 (define_expand "mextr6"
12207   [(match_operand:DI 0 "arith_reg_dest" "")
12208    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12209    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12210   "TARGET_SHMEDIA"
12212   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12213                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
12214   DONE;
12217 (define_expand "mextr7"
12218   [(match_operand:DI 0 "arith_reg_dest" "")
12219    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12220    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12221   "TARGET_SHMEDIA"
12223   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12224                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
12225   DONE;
12228 (define_expand "mmacfx_wl"
12229   [(match_operand:V2SI 0 "arith_reg_dest" "")
12230    (match_operand:V2HI 1 "extend_reg_operand" "")
12231    (match_operand:V2HI 2 "extend_reg_operand" "")
12232    (match_operand:V2SI 3 "arith_reg_operand" "")]
12233   "TARGET_SHMEDIA"
12235   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12236                               operands[1], operands[2]));
12237   DONE;
12240 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12241 ;; is depend
12242 (define_insn "mmacfx_wl_i"
12243   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12244         (ss_plus:V2SI
12245          (match_operand:V2SI 1 "arith_reg_operand" "0")
12246          (ss_truncate:V2SI
12247           (ashift:V2DI
12248            (sign_extend:V2DI
12249             (mult:V2SI
12250              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12251              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12252            (const_int 1)))))]
12253   "TARGET_SHMEDIA"
12254   "mmacfx.wl    %2, %3, %0"
12255   [(set_attr "type" "mac_media")
12256    (set_attr "highpart" "depend")])
12258 (define_expand "mmacnfx_wl"
12259   [(match_operand:V2SI 0 "arith_reg_dest" "")
12260    (match_operand:V2HI 1 "extend_reg_operand" "")
12261    (match_operand:V2HI 2 "extend_reg_operand" "")
12262    (match_operand:V2SI 3 "arith_reg_operand" "")]
12263   "TARGET_SHMEDIA"
12265   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12266                                operands[1], operands[2]));
12267   DONE;
12270 (define_insn "mmacnfx_wl_i"
12271   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12272         (ss_minus:V2SI
12273          (match_operand:V2SI 1 "arith_reg_operand" "0")
12274          (ss_truncate:V2SI
12275           (ashift:V2DI
12276            (sign_extend:V2DI
12277             (mult:V2SI
12278              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12279              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12280            (const_int 1)))))]
12281   "TARGET_SHMEDIA"
12282   "mmacnfx.wl   %2, %3, %0"
12283   [(set_attr "type" "mac_media")
12284    (set_attr "highpart" "depend")])
12286 (define_insn "mulv2si3"
12287   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12288         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12289                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12290   "TARGET_SHMEDIA"
12291   "mmul.l       %1, %2, %0"
12292   [(set_attr "type" "d2mpy_media")
12293    (set_attr "highpart" "depend")])
12295 (define_insn "mulv4hi3"
12296   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12297         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12298                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12299   "TARGET_SHMEDIA"
12300   "mmul.w       %1, %2, %0"
12301   [(set_attr "type" "dmpy_media")
12302    (set_attr "highpart" "depend")])
12304 (define_insn "mmulfx_l"
12305   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12306         (ss_truncate:V2SI
12307          (ashiftrt:V2DI
12308           (mult:V2DI
12309            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12310            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12311           (const_int 31))))]
12312   "TARGET_SHMEDIA"
12313   "mmulfx.l     %1, %2, %0"
12314   [(set_attr "type" "d2mpy_media")
12315    (set_attr "highpart" "depend")])
12317 (define_insn "mmulfx_w"
12318   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12319         (ss_truncate:V4HI
12320          (ashiftrt:V4SI
12321           (mult:V4SI
12322            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12323            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12324           (const_int 15))))]
12325   "TARGET_SHMEDIA"
12326   "mmulfx.w     %1, %2, %0"
12327   [(set_attr "type" "dmpy_media")
12328    (set_attr "highpart" "depend")])
12330 (define_insn "mmulfxrp_w"
12331   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12332         (ss_truncate:V4HI
12333          (ashiftrt:V4SI
12334           (plus:V4SI
12335            (mult:V4SI
12336             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12337             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12338            (const_int 16384))
12339           (const_int 15))))]
12340   "TARGET_SHMEDIA"
12341   "mmulfxrp.w   %1, %2, %0"
12342   [(set_attr "type" "dmpy_media")
12343    (set_attr "highpart" "depend")])
12346 (define_expand "mmulhi_wl"
12347   [(match_operand:V2SI 0 "arith_reg_dest" "")
12348    (match_operand:V4HI 1 "arith_reg_operand" "")
12349    (match_operand:V4HI 2 "arith_reg_operand" "")]
12350   "TARGET_SHMEDIA"
12352   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12353              (operands[0], operands[1], operands[2]));
12354   DONE;
12357 (define_expand "mmullo_wl"
12358   [(match_operand:V2SI 0 "arith_reg_dest" "")
12359    (match_operand:V4HI 1 "arith_reg_operand" "")
12360    (match_operand:V4HI 2 "arith_reg_operand" "")]
12361   "TARGET_SHMEDIA"
12363   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12364              (operands[0], operands[1], operands[2]));
12365   DONE;
12368 (define_insn "mmul23_wl"
12369   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12370         (vec_select:V2SI
12371          (mult:V4SI
12372           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12373           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12374          (parallel [(const_int 2) (const_int 3)])))]
12375   "TARGET_SHMEDIA"
12377   return (TARGET_LITTLE_ENDIAN
12378           ? "mmulhi.wl  %1, %2, %0"
12379           : "mmullo.wl  %1, %2, %0");
12381   [(set_attr "type" "dmpy_media")
12382    (set (attr "highpart")
12383         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12384          (const_string "user")))])
12386 (define_insn "mmul01_wl"
12387   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12388         (vec_select:V2SI
12389          (mult:V4SI
12390           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12391           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12392          (parallel [(const_int 0) (const_int 1)])))]
12393   "TARGET_SHMEDIA"
12395   return (TARGET_LITTLE_ENDIAN
12396           ? "mmullo.wl  %1, %2, %0"
12397           : "mmulhi.wl  %1, %2, %0");
12399   [(set_attr "type" "dmpy_media")
12400    (set (attr "highpart")
12401         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12402          (const_string "user")))])
12405 (define_expand "mmulsum_wq"
12406   [(match_operand:DI 0 "arith_reg_dest" "")
12407    (match_operand:V4HI 1 "arith_reg_operand" "")
12408    (match_operand:V4HI 2 "arith_reg_operand" "")
12409    (match_operand:DI 3 "arith_reg_operand" "")]
12410   "TARGET_SHMEDIA"
12412   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12413                                operands[1], operands[2]));
12414   DONE;
12417 (define_insn "mmulsum_wq_i"
12418   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12419         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12420          (plus:DI
12421           (plus:DI
12422            (vec_select:DI
12423             (mult:V4DI
12424              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12425              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12426             (parallel [(const_int 0)]))
12427            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12428                                      (sign_extend:V4DI (match_dup 3)))
12429                           (parallel [(const_int 1)])))
12430           (plus:DI
12431            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12432                                      (sign_extend:V4DI (match_dup 3)))
12433                           (parallel [(const_int 2)]))
12434            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12435                                      (sign_extend:V4DI (match_dup 3)))
12436                           (parallel [(const_int 3)]))))))]
12437   "TARGET_SHMEDIA"
12438   "mmulsum.wq   %2, %3, %0"
12439   [(set_attr "type" "mac_media")])
12441 (define_expand "mperm_w"
12442   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12443    (match_operand:V4HI 1 "arith_reg_operand" "r")
12444    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12445   "TARGET_SHMEDIA"
12447   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12448              (operands[0], operands[1], operands[2]));
12449   DONE;
12452 ; This use of vec_select isn't exactly correct according to rtl.texi
12453 ; (because not constant), but it seems a straightforward extension.
12454 (define_insn "mperm_w_little"
12455   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12456         (vec_select:V4HI
12457          (match_operand:V4HI 1 "arith_reg_operand" "r")
12458          (parallel
12459           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12460                             (const_int 2) (const_int 0))
12461            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12462            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12463            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12464   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12465   "mperm.w      %1, %N2, %0"
12466   [(set_attr "type" "arith_media")])
12468 (define_insn "mperm_w_big"
12469   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12470         (vec_select:V4HI
12471          (match_operand:V4HI 1 "arith_reg_operand" "r")
12472          (parallel
12473           [(zero_extract:QI (not:QI (match_operand:QI 2
12474                                      "extend_reg_or_0_operand" "rZ"))
12475                             (const_int 2) (const_int 0))
12476            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12477            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12478            (zero_extract:QI (not:QI (match_dup 2))
12479                             (const_int 2) (const_int 6))])))]
12480   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12481   "mperm.w      %1, %N2, %0"
12482   [(set_attr "type" "arith_media")])
12484 (define_insn "mperm_w0"
12485   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12486         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12487                                           "trunc_hi_operand" "r"))))]
12488   "TARGET_SHMEDIA"
12489   "mperm.w      %1, r63, %0"
12490   [(set_attr "type" "arith_media")
12491    (set_attr "highpart" "ignore")])
12493 (define_expand "msad_ubq"
12494   [(match_operand:DI 0 "arith_reg_dest" "")
12495    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12496    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12497    (match_operand:DI 3 "arith_reg_operand" "")]
12498   "TARGET_SHMEDIA"
12500   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12501                              operands[1], operands[2]));
12502   DONE;
12505 (define_insn "msad_ubq_i"
12506   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12507         (plus:DI
12508          (plus:DI
12509           (plus:DI
12510            (plus:DI
12511             (match_operand:DI 1 "arith_reg_operand" "0")
12512             (abs:DI (vec_select:DI
12513                      (minus:V8DI
12514                       (zero_extend:V8DI
12515                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12516                       (zero_extend:V8DI
12517                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12518                      (parallel [(const_int 0)]))))
12519            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12520                                               (zero_extend:V8DI (match_dup 3)))
12521                                   (parallel [(const_int 1)]))))
12522           (plus:DI
12523            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12524                                               (zero_extend:V8DI (match_dup 3)))
12525                                   (parallel [(const_int 2)])))
12526            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12527                                               (zero_extend:V8DI (match_dup 3)))
12528                                   (parallel [(const_int 3)])))))
12529          (plus:DI
12530           (plus:DI
12531            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12532                                               (zero_extend:V8DI (match_dup 3)))
12533                                   (parallel [(const_int 4)])))
12534            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12535                                               (zero_extend:V8DI (match_dup 3)))
12536                                   (parallel [(const_int 5)]))))
12537           (plus:DI
12538            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12539                                               (zero_extend:V8DI (match_dup 3)))
12540                                   (parallel [(const_int 6)])))
12541            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12542                                               (zero_extend:V8DI (match_dup 3)))
12543                                   (parallel [(const_int 7)])))))))]
12544   "TARGET_SHMEDIA"
12545   "msad.ubq     %N2, %N3, %0"
12546   [(set_attr "type" "mac_media")])
12548 (define_insn "mshalds_l"
12549   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12550         (ss_truncate:V2SI
12551          (ashift:V2DI
12552           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12553           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12554                   (const_int 31)))))]
12555   "TARGET_SHMEDIA"
12556   "mshalds.l    %1, %2, %0"
12557   [(set_attr "type" "mcmp_media")
12558    (set_attr "highpart" "depend")])
12560 (define_insn "mshalds_w"
12561   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12562         (ss_truncate:V4HI
12563          (ashift:V4SI
12564           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12565           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12566                   (const_int 15)))))]
12567   "TARGET_SHMEDIA"
12568   "mshalds.w    %1, %2, %0"
12569   [(set_attr "type" "mcmp_media")
12570    (set_attr "highpart" "depend")])
12572 (define_insn "ashrv2si3"
12573   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12574         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12575                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12576   "TARGET_SHMEDIA"
12577   "mshard.l     %1, %2, %0"
12578   [(set_attr "type" "arith_media")
12579    (set_attr "highpart" "depend")])
12581 (define_insn "ashrv4hi3"
12582   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12583         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12584                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12585   "TARGET_SHMEDIA"
12586   "mshard.w     %1, %2, %0"
12587   [(set_attr "type" "arith_media")
12588    (set_attr "highpart" "depend")])
12590 (define_insn "mshards_q"
12591   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12592         (ss_truncate:HI
12593          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12594                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12595   "TARGET_SHMEDIA"
12596   "mshards.q    %1, %N2, %0"
12597   [(set_attr "type" "mcmp_media")])
12599 (define_expand "mshfhi_b"
12600   [(match_operand:V8QI 0 "arith_reg_dest" "")
12601    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12602    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12603   "TARGET_SHMEDIA"
12605   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12606              (operands[0], operands[1], operands[2]));
12607   DONE;
12610 (define_expand "mshflo_b"
12611   [(match_operand:V8QI 0 "arith_reg_dest" "")
12612    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12613    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12614   "TARGET_SHMEDIA"
12616   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12617              (operands[0], operands[1], operands[2]));
12618   DONE;
12621 (define_insn "mshf4_b"
12622   [(set
12623     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12624     (vec_select:V8QI
12625      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12626                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12627      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12628                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12629   "TARGET_SHMEDIA"
12631   return (TARGET_LITTLE_ENDIAN
12632           ? "mshfhi.b   %N1, %N2, %0"
12633           : "mshflo.b   %N1, %N2, %0");
12635   [(set_attr "type" "arith_media")
12636    (set (attr "highpart")
12637         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12638          (const_string "user")))])
12640 (define_insn "mshf0_b"
12641   [(set
12642     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12643     (vec_select:V8QI
12644      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12645                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12646      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12647                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12648   "TARGET_SHMEDIA"
12650   return (TARGET_LITTLE_ENDIAN
12651           ? "mshflo.b   %N1, %N2, %0"
12652           : "mshfhi.b   %N1, %N2, %0");
12654   [(set_attr "type" "arith_media")
12655    (set (attr "highpart")
12656         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12657          (const_string "user")))])
12659 (define_expand "mshfhi_l"
12660   [(match_operand:V2SI 0 "arith_reg_dest" "")
12661    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12662    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12663   "TARGET_SHMEDIA"
12665   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12666              (operands[0], operands[1], operands[2]));
12667   DONE;
12670 (define_expand "mshflo_l"
12671   [(match_operand:V2SI 0 "arith_reg_dest" "")
12672    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12673    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12674   "TARGET_SHMEDIA"
12676   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12677              (operands[0], operands[1], operands[2]));
12678   DONE;
12681 (define_insn "mshf4_l"
12682   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12683         (vec_select:V2SI
12684          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12685                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12686          (parallel [(const_int 1) (const_int 3)])))]
12687   "TARGET_SHMEDIA"
12689   return (TARGET_LITTLE_ENDIAN
12690           ? "mshfhi.l   %N1, %N2, %0"
12691           : "mshflo.l   %N1, %N2, %0");
12693   [(set_attr "type" "arith_media")
12694    (set (attr "highpart")
12695         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12696          (const_string "user")))])
12698 (define_insn "mshf0_l"
12699   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12700         (vec_select:V2SI
12701          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12702                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12703          (parallel [(const_int 0) (const_int 2)])))]
12704   "TARGET_SHMEDIA"
12706   return (TARGET_LITTLE_ENDIAN
12707           ? "mshflo.l   %N1, %N2, %0"
12708           : "mshfhi.l   %N1, %N2, %0");
12710   [(set_attr "type" "arith_media")
12711    (set (attr "highpart")
12712         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12713          (const_string "user")))])
12715 (define_expand "mshfhi_w"
12716   [(match_operand:V4HI 0 "arith_reg_dest" "")
12717    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12718    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12719   "TARGET_SHMEDIA"
12721   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12722              (operands[0], operands[1], operands[2]));
12723   DONE;
12726 (define_expand "mshflo_w"
12727   [(match_operand:V4HI 0 "arith_reg_dest" "")
12728    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12729    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12730   "TARGET_SHMEDIA"
12732   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12733              (operands[0], operands[1], operands[2]));
12734   DONE;
12737 (define_insn "mshf4_w"
12738   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12739         (vec_select:V4HI
12740          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12741                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12742          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12743   "TARGET_SHMEDIA"
12745   return (TARGET_LITTLE_ENDIAN
12746           ? "mshfhi.w   %N1, %N2, %0"
12747           : "mshflo.w   %N1, %N2, %0");
12749   [(set_attr "type" "arith_media")
12750    (set (attr "highpart")
12751         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12752          (const_string "user")))])
12754 (define_insn "mshf0_w"
12755   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12756         (vec_select:V4HI
12757          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12758                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12759          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12760   "TARGET_SHMEDIA"
12762   return (TARGET_LITTLE_ENDIAN
12763           ? "mshflo.w   %N1, %N2, %0"
12764           : "mshfhi.w   %N1, %N2, %0");
12766   [(set_attr "type" "arith_media")
12767    (set (attr "highpart")
12768         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12769          (const_string "user")))])
12771 (define_insn "mshflo_w_x"
12772   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12773         (vec_select:V4HI
12774          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12775                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12776          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12777   "TARGET_SHMEDIA"
12778   "mshflo.w     %N1, %N2, %0"
12779   [(set_attr "type" "arith_media")
12780    (set_attr "highpart" "ignore")])
12782 ;; These are useful to expand ANDs and as combiner patterns.
12783 (define_insn_and_split "mshfhi_l_di"
12784   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12785         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12786                              (const_int 32))
12787                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12788                         (const_int -4294967296))))]
12789   "TARGET_SHMEDIA"
12790   "@
12791         mshfhi.l        %N1, %N2, %0
12792         #"
12793   "TARGET_SHMEDIA && reload_completed
12794    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12795   [(set (match_dup 3) (match_dup 4))
12796    (set (match_dup 5) (match_dup 6))]
12798   operands[3] = gen_lowpart (SImode, operands[0]);
12799   operands[4] = gen_highpart (SImode, operands[1]);
12800   operands[5] = gen_highpart (SImode, operands[0]);
12801   operands[6] = gen_highpart (SImode, operands[2]);
12803   [(set_attr "type" "arith_media")])
12805 (define_insn "*mshfhi_l_di_rev"
12806   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12807         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12808                         (const_int -4294967296))
12809                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12810                              (const_int 32))))]
12811   "TARGET_SHMEDIA"
12812   "mshfhi.l     %N2, %N1, %0"
12813   [(set_attr "type" "arith_media")])
12815 (define_split
12816   [(set (match_operand:DI 0 "arith_reg_dest" "")
12817         (ior:DI (zero_extend:DI (match_operand:SI 1
12818                                               "extend_reg_or_0_operand" ""))
12819                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12820                         (const_int -4294967296))))
12821    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12822   "TARGET_SHMEDIA"
12823   [(const_int 0)]
12825   emit_insn (gen_ashldi3_media (operands[3],
12826                                 simplify_gen_subreg (DImode, operands[1],
12827                                                      SImode, 0),
12828                                 GEN_INT (32)));
12829   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12830   DONE;
12833 (define_insn "mshflo_l_di"
12834   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12835         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12836                         (const_int 4294967295))
12837                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12838                            (const_int 32))))]
12840   "TARGET_SHMEDIA"
12841   "mshflo.l     %N1, %N2, %0"
12842   [(set_attr "type" "arith_media")
12843    (set_attr "highpart" "ignore")])
12845 (define_insn "*mshflo_l_di_rev"
12846   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12847         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12848                            (const_int 32))
12849                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12850                         (const_int 4294967295))))]
12852   "TARGET_SHMEDIA"
12853   "mshflo.l     %N2, %N1, %0"
12854   [(set_attr "type" "arith_media")
12855    (set_attr "highpart" "ignore")])
12857 ;; Combiner pattern for trampoline initialization.
12858 (define_insn_and_split "*double_shori"
12859   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12860         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12861                            (const_int 32))
12862                 (match_operand:DI 2 "const_int_operand" "n")))]
12863   "TARGET_SHMEDIA
12864    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12865   "#"
12866   "rtx_equal_p (operands[0], operands[1])"
12867   [(const_int 0)]
12869   HOST_WIDE_INT v = INTVAL (operands[2]);
12871   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12872   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12873   DONE;
12875   [(set_attr "highpart" "ignore")])
12878 (define_insn "*mshflo_l_di_x"
12879   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12880         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12881                                  "rZ"))
12882                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12883                            (const_int 32))))]
12885   "TARGET_SHMEDIA"
12886   "mshflo.l     %N1, %N2, %0"
12887   [(set_attr "type" "arith_media")
12888    (set_attr "highpart" "ignore")])
12890 (define_insn_and_split "concat_v2sf"
12891   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12892 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12893         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12894                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12896   "TARGET_SHMEDIA"
12897   "@
12898         mshflo.l        %N1, %N2, %0
12899         #
12900         #"
12901   "TARGET_SHMEDIA && reload_completed
12902    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12903   [(set (match_dup 3) (match_dup 1))
12904    (set (match_dup 4) (match_dup 2))]
12906   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12907   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12909   [(set_attr "type" "arith_media")
12910    (set_attr "highpart" "ignore")])
12912 (define_insn "*mshflo_l_di_x_rev"
12913   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12914         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12915                            (const_int 32))
12916                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12918   "TARGET_SHMEDIA"
12919   "mshflo.l     %N2, %N1, %0"
12920   [(set_attr "type" "arith_media")
12921    (set_attr "highpart" "ignore")])
12923 (define_insn "ashlv2si3"
12924   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12925         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12926                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12927   "TARGET_SHMEDIA"
12928   "mshlld.l     %1, %2, %0"
12929   [(set_attr "type" "arith_media")
12930    (set_attr "highpart" "depend")])
12932 (define_split
12933   [(set (match_operand 0 "any_register_operand" "")
12934         (match_operator 3 "shift_operator"
12935           [(match_operand 1 "any_register_operand" "")
12936            (match_operand 2 "shift_count_reg_operand" "")]))]
12937   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12938   [(set (match_dup 0) (match_dup 3))]
12940   rtx count = operands[2];
12941   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12943   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12944          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12945          || GET_CODE (count) == TRUNCATE)
12946     count = XEXP (count, 0);
12947   inner_mode = GET_MODE (count);
12948   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12949                                subreg_lowpart_offset (outer_mode, inner_mode));
12950   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12951                                 operands[1], count);
12954 (define_insn "ashlv4hi3"
12955   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12956         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12957                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12958   "TARGET_SHMEDIA"
12959   "mshlld.w     %1, %2, %0"
12960   [(set_attr "type" "arith_media")
12961    (set_attr "highpart" "depend")])
12963 (define_insn "lshrv2si3"
12964   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12965         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12966                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12967   "TARGET_SHMEDIA"
12968   "mshlrd.l     %1, %2, %0"
12969   [(set_attr "type" "arith_media")
12970    (set_attr "highpart" "depend")])
12972 (define_insn "lshrv4hi3"
12973   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12974         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12975                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12976   "TARGET_SHMEDIA"
12977   "mshlrd.w     %1, %2, %0"
12978   [(set_attr "type" "arith_media")
12979    (set_attr "highpart" "depend")])
12981 (define_insn "subv2si3"
12982   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12983         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12984                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12985   "TARGET_SHMEDIA"
12986   "msub.l       %N1, %2, %0"
12987   [(set_attr "type" "arith_media")
12988    (set_attr "highpart" "depend")])
12990 (define_insn "subv4hi3"
12991   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12992         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12993                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12994   "TARGET_SHMEDIA"
12995   "msub.w       %N1, %2, %0"
12996   [(set_attr "type" "arith_media")
12997    (set_attr "highpart" "depend")])
12999 (define_insn_and_split "subv2hi3"
13000   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13001         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13002                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13003   "TARGET_SHMEDIA"
13004   "#"
13005   "TARGET_SHMEDIA"
13006   [(const_int 0)]
13008   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13009   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13010   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13011   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13012   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13014   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13015   emit_insn (gen_truncdisi2 (si_dst, di_dst));
13016   DONE;
13018   [(set_attr "highpart" "must_split")])
13020 (define_insn "sssubv2si3"
13021   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13022         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13023                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13024   "TARGET_SHMEDIA"
13025   "msubs.l      %N1, %2, %0"
13026   [(set_attr "type" "mcmp_media")
13027    (set_attr "highpart" "depend")])
13029 (define_insn "ussubv8qi3"
13030   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13031         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13032                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13033   "TARGET_SHMEDIA"
13034   "msubs.ub     %N1, %2, %0"
13035   [(set_attr "type" "mcmp_media")
13036    (set_attr "highpart" "depend")])
13038 (define_insn "sssubv4hi3"
13039   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13040         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13041                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13042   "TARGET_SHMEDIA"
13043   "msubs.w      %N1, %2, %0"
13044   [(set_attr "type" "mcmp_media")
13045    (set_attr "highpart" "depend")])
13047 ;; Floating Point Intrinsics
13049 (define_insn "fcosa_s"
13050   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13051         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13052                    UNSPEC_FCOSA))]
13053   "TARGET_SHMEDIA"
13054   "fcosa.s      %1, %0"
13055   [(set_attr "type" "atrans_media")])
13057 (define_insn "fsina_s"
13058   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13059         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13060                    UNSPEC_FSINA))]
13061   "TARGET_SHMEDIA"
13062   "fsina.s      %1, %0"
13063   [(set_attr "type" "atrans_media")])
13065 (define_insn "fipr"
13066   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13067         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13068                                                     "fp_arith_reg_operand" "f")
13069                                                    (match_operand:V4SF 2
13070                                                     "fp_arith_reg_operand" "f"))
13071                                          (parallel [(const_int 0)]))
13072                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13073                                          (parallel [(const_int 1)])))
13074                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13075                                          (parallel [(const_int 2)]))
13076                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13077                                          (parallel [(const_int 3)])))))]
13078   "TARGET_SHMEDIA"
13079   "fipr.s       %1, %2, %0"
13080   [(set_attr "type" "fparith_media")])
13082 (define_insn "fsrra_s"
13083   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13084         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13085                    UNSPEC_FSRRA))]
13086   "TARGET_SHMEDIA"
13087   "fsrra.s      %1, %0"
13088   [(set_attr "type" "atrans_media")])
13090 (define_insn "ftrv"
13091   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13092         (plus:V4SF
13093          (plus:V4SF
13094           (mult:V4SF
13095            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13096                             (parallel [(const_int 0) (const_int 5)
13097                                        (const_int 10) (const_int 15)]))
13098            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13099           (mult:V4SF
13100            (vec_select:V4SF (match_dup 1)
13101                             (parallel [(const_int 4) (const_int 9)
13102                                        (const_int 14) (const_int 3)]))
13103            (vec_select:V4SF (match_dup 2)
13104                             (parallel [(const_int 1) (const_int 2)
13105                                        (const_int 3) (const_int 0)]))))
13106          (plus:V4SF
13107           (mult:V4SF
13108            (vec_select:V4SF (match_dup 1)
13109                             (parallel [(const_int 8) (const_int 13)
13110                                        (const_int 2) (const_int 7)]))
13111            (vec_select:V4SF (match_dup 2)
13112                             (parallel [(const_int 2) (const_int 3)
13113                                        (const_int 0) (const_int 1)])))
13114           (mult:V4SF
13115            (vec_select:V4SF (match_dup 1)
13116                             (parallel [(const_int 12) (const_int 1)
13117                                        (const_int 6) (const_int 11)]))
13118            (vec_select:V4SF (match_dup 2)
13119                             (parallel [(const_int 3) (const_int 0)
13120                                        (const_int 1) (const_int 2)]))))))]
13121   "TARGET_SHMEDIA"
13122   "ftrv.s %1, %2, %0"
13123   [(set_attr "type" "fparith_media")])
13125 (define_insn "ldhi_l"
13126   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13127         (zero_extract:SI
13128          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13129                                   (const_int 3))
13130                           (const_int -3)))
13131          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13132          (const_int 0)))]
13133   "TARGET_SHMEDIA32"
13134   "ldhi.l       %U1, %0"
13135   [(set_attr "type" "load_media")])
13137 (define_insn "ldhi_q"
13138   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13139         (zero_extract:DI
13140          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13141                                   (const_int 7))
13142                           (const_int -7)))
13143          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13144          (const_int 0)))]
13145   "TARGET_SHMEDIA32"
13146   "ldhi.q       %U1, %0"
13147   [(set_attr "type" "load_media")])
13149 (define_insn_and_split "*ldhi_q_comb0"
13150   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13151         (zero_extract:DI
13152          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13153                                             "register_operand" "r")
13154                                            (match_operand:SI 2
13155                                             "ua_offset" "I06"))
13156                                   (const_int 7))
13157                           (const_int -7)))
13158          (plus:SI (and:SI (match_dup 1) (const_int 7))
13159                   (const_int 1))
13160          (const_int 0)))]
13161   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13162   "#"
13163   ""
13164   [(pc)]
13166   emit_insn (gen_ldhi_q (operands[0],
13167                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
13168   DONE;
13171 (define_insn_and_split "*ldhi_q_comb1"
13172   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13173         (zero_extract:DI
13174          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13175                                             "register_operand" "r")
13176                                            (match_operand:SI 2
13177                                             "ua_offset" "I06"))
13178                                   (const_int 7))
13179                           (const_int -7)))
13180          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
13181                                                    "ua_offset" "I06"))
13182                           (const_int 7))
13183                   (const_int 1))
13184          (const_int 0)))]
13185   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13186    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13187   "#"
13188   ""
13189   [(pc)]
13191   emit_insn (gen_ldhi_q (operands[0],
13192                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
13193   DONE;
13196 (define_insn "ldlo_l"
13197   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13198         (zero_extract:SI
13199          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13200                          (const_int -4)))
13201          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13202          (and:SI (match_dup 1) (const_int 3))))]
13203   "TARGET_SHMEDIA32"
13204   "ldlo.l       %U1, %0"
13205   [(set_attr "type" "load_media")])
13207 (define_insn "ldlo_q"
13208   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13209         (zero_extract:DI
13210          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13211                          (const_int -8)))
13212          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13213          (and:SI (match_dup 1) (const_int 7))))]
13214   "TARGET_SHMEDIA32"
13215   "ldlo.q       %U1, %0"
13216   [(set_attr "type" "load_media")])
13218 (define_insn_and_split "*ldlo_q_comb0"
13219   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13220         (zero_extract:DI
13221          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13222                                   (match_operand:SI 2 "ua_offset" "I06"))
13223                          (const_int -8)))
13224          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13225          (and:SI (match_dup 1) (const_int 7))))]
13226   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13227   "#"
13228   ""
13229   [(pc)]
13231   emit_insn (gen_ldlo_q (operands[0],
13232                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
13233   DONE;
13236 (define_insn_and_split "*ldlo_q_comb1"
13237   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13238         (zero_extract:DI
13239          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13240                                   (match_operand:SI 2 "ua_offset" "I06"))
13241                          (const_int -8)))
13242          (minus:SI (const_int 8)
13243                    (and:SI (plus:SI (match_dup 1)
13244                                     (match_operand:SI 3 "ua_offset" "I06"))
13245                            (const_int 7)))
13246          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13247   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13248    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13249   "#"
13250   ""
13251   [(pc)]
13253   emit_insn (gen_ldlo_q (operands[0],
13254                          gen_rtx_PLUS (SImode, operands[1], operands[2])));
13255   DONE;
13258 (define_insn "sthi_l"
13259   [(set (zero_extract:SI
13260          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13261                                   (const_int 3))
13262                           (const_int -3)))
13263          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13264          (const_int 0))
13265         (match_operand:SI 1 "arith_reg_operand" "r"))]
13266   "TARGET_SHMEDIA32"
13267   "sthi.l       %U0, %1"
13268   [(set_attr "type" "ustore_media")])
13270 ;; All unaligned stores are considered to be 'narrow' because they typically
13271 ;; operate on less that a quadword, and when they operate on a full quadword,
13272 ;; the vanilla store high / store low sequence will cause a stall if not
13273 ;; scheduled apart.
13274 (define_insn "sthi_q"
13275   [(set (zero_extract:DI
13276          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13277                                   (const_int 7))
13278                           (const_int -7)))
13279          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13280          (const_int 0))
13281         (match_operand:DI 1 "arith_reg_operand" "r"))]
13282   "TARGET_SHMEDIA32"
13283   "sthi.q       %U0, %1"
13284   [(set_attr "type" "ustore_media")])
13286 (define_insn_and_split "*sthi_q_comb0"
13287   [(set (zero_extract:DI
13288          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13289                                             "register_operand" "r")
13290                                            (match_operand:SI 1 "ua_offset"
13291                                             "I06"))
13292                                   (const_int 7))
13293                           (const_int -7)))
13294          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13295          (const_int 0))
13296         (match_operand:DI 2 "arith_reg_operand" "r"))]
13297   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13298   "#"
13299   ""
13300   [(pc)]
13302   emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13303                          operands[2]));
13304   DONE;
13307 (define_insn_and_split "*sthi_q_comb1"
13308   [(set (zero_extract:DI
13309          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13310                                             "register_operand" "r")
13311                                            (match_operand:SI 1 "ua_offset"
13312                                             "I06"))
13313                                   (const_int 7))
13314                           (const_int -7)))
13315          (plus:SI (and:SI (plus:SI (match_dup 0)
13316                                    (match_operand:SI 2 "ua_offset" "I06"))
13317                           (const_int 7))
13318                   (const_int 1))
13319          (const_int 0))
13320         (match_operand:DI 3 "arith_reg_operand" "r"))]
13321   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13322    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13323   "#"
13324   ""
13325   [(pc)]
13327   emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13328                          operands[3]));
13329   DONE;
13332 ;; This is highpart user because the address is used as full 64 bit.
13333 (define_insn "stlo_l"
13334   [(set (zero_extract:SI
13335          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13336                          (const_int -4)))
13337          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13338          (and:SI (match_dup 0) (const_int 3)))
13339         (match_operand:SI 1 "arith_reg_operand" "r"))]
13340   "TARGET_SHMEDIA32"
13341   "stlo.l       %U0, %1"
13342   [(set_attr "type" "ustore_media")])
13344 (define_insn "stlo_q"
13345   [(set (zero_extract:DI
13346          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13347                          (const_int -8)))
13348          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13349          (and:SI (match_dup 0) (const_int 7)))
13350         (match_operand:DI 1 "arith_reg_operand" "r"))]
13351   "TARGET_SHMEDIA32"
13352   "stlo.q       %U0, %1"
13353   [(set_attr "type" "ustore_media")])
13355 (define_insn_and_split "*stlo_q_comb0"
13356   [(set (zero_extract:DI
13357          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13358                                   (match_operand:SI 1 "ua_offset" "I06"))
13359                          (const_int -8)))
13360          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13361          (and:SI (match_dup 0) (const_int 7)))
13362         (match_operand:DI 2 "arith_reg_operand" "r"))]
13363   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13364   "#"
13365   ""
13366   [(pc)]
13368   emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13369                          operands[2]));
13370   DONE;
13373 (define_insn_and_split "*stlo_q_comb1"
13374   [(set (zero_extract:DI
13375          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13376                                   (match_operand:SI 1 "ua_offset" "I06"))
13377                          (const_int -8)))
13378          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13379                                                   (match_operand:SI 2
13380                                                    "ua_offset" "I06"))
13381                                          (const_int 7)))
13382          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13383         (match_operand:DI 3 "arith_reg_operand" "r"))]
13384   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13385   "#"
13386   ""
13387   [(pc)]
13389   emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13390                          operands[3]));
13391    DONE;
13394 (define_insn "ldhi_l64"
13395   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13396         (zero_extract:SI
13397          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13398                                   (const_int 3))
13399                           (const_int -3)))
13400          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13401          (const_int 0)))]
13402   "TARGET_SHMEDIA64"
13403   "ldhi.l       %U1, %0"
13404   [(set_attr "type" "load_media")])
13406 (define_insn "ldhi_q64"
13407   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13408         (zero_extract:DI
13409          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13410                                   (const_int 7))
13411                           (const_int -7)))
13412          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13413          (const_int 0)))]
13414   "TARGET_SHMEDIA64"
13415   "ldhi.q       %U1, %0"
13416   [(set_attr "type" "load_media")])
13418 (define_insn "ldlo_l64"
13419   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13420         (zero_extract:SI
13421          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13422                          (const_int -4)))
13423          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13424          (and:DI (match_dup 1) (const_int 3))))]
13425   "TARGET_SHMEDIA64"
13426   "ldlo.l       %U1, %0"
13427   [(set_attr "type" "load_media")])
13429 (define_insn "ldlo_q64"
13430   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13431         (zero_extract:DI
13432          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13433                          (const_int -8)))
13434          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13435          (and:DI (match_dup 1) (const_int 7))))]
13436   "TARGET_SHMEDIA64"
13437   "ldlo.q       %U1, %0"
13438   [(set_attr "type" "load_media")])
13440 (define_insn "sthi_l64"
13441   [(set (zero_extract:SI
13442          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13443                                   (const_int 3))
13444                           (const_int -3)))
13445          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13446          (const_int 0))
13447         (match_operand:SI 1 "arith_reg_operand" "r"))]
13448   "TARGET_SHMEDIA64"
13449   "sthi.l       %U0, %1"
13450   [(set_attr "type" "ustore_media")])
13452 (define_insn "sthi_q64"
13453   [(set (zero_extract:DI
13454          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13455                                   (const_int 7))
13456                           (const_int -7)))
13457          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13458          (const_int 0))
13459         (match_operand:DI 1 "arith_reg_operand" "r"))]
13460   "TARGET_SHMEDIA64"
13461   "sthi.q       %U0, %1"
13462   [(set_attr "type" "ustore_media")])
13464 (define_insn "stlo_l64"
13465   [(set (zero_extract:SI
13466          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13467                          (const_int -4)))
13468          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13469          (and:DI (match_dup 0) (const_int 3)))
13470         (match_operand:SI 1 "arith_reg_operand" "r"))]
13471   "TARGET_SHMEDIA64"
13472   "stlo.l       %U0, %1"
13473   [(set_attr "type" "ustore_media")])
13475 (define_insn "stlo_q64"
13476   [(set (zero_extract:DI
13477          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13478                          (const_int -8)))
13479          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13480          (and:DI (match_dup 0) (const_int 7)))
13481         (match_operand:DI 1 "arith_reg_operand" "r"))]
13482   "TARGET_SHMEDIA64"
13483   "stlo.q       %U0, %1"
13484   [(set_attr "type" "ustore_media")])
13486 (define_insn "nsb"
13487   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13488         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13489                    UNSPEC_NSB))]
13490   "TARGET_SHMEDIA"
13491   "nsb  %1, %0"
13492   [(set_attr "type" "arith_media")])
13494 (define_insn "nsbsi"
13495   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13496         (zero_extend:SI
13497          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13498                     UNSPEC_NSB)))]
13499   "TARGET_SHMEDIA"
13500   "nsb  %1, %0"
13501   [(set_attr "type" "arith_media")])
13503 (define_insn "nsbdi"
13504   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13505         (zero_extend:DI
13506          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13507                     UNSPEC_NSB)))]
13508   "TARGET_SHMEDIA"
13509   "nsb  %1, %0"
13510   [(set_attr "type" "arith_media")])
13512 (define_expand "ffsdi2"
13513   [(set (match_operand:DI 0 "arith_reg_dest" "")
13514         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13515   "TARGET_SHMEDIA"
13517   rtx scratch = gen_reg_rtx (DImode);
13518   rtx last;
13520   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13521   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13522   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13523   emit_insn (gen_nsbdi (scratch, scratch));
13524   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13525   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13526   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13527   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13529   DONE;
13532 (define_expand "ffssi2"
13533   [(set (match_operand:SI 0 "arith_reg_dest" "")
13534         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13535   "TARGET_SHMEDIA"
13537   rtx scratch = gen_reg_rtx (SImode);
13538   rtx discratch = gen_reg_rtx (DImode);
13539   rtx last;
13541   emit_insn (gen_adddi3 (discratch,
13542                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13543                          constm1_rtx));
13544   emit_insn (gen_andcdi3 (discratch,
13545                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13546                           discratch));
13547   emit_insn (gen_nsbsi (scratch, discratch));
13548   last = emit_insn (gen_subsi3 (operands[0],
13549                                 force_reg (SImode, GEN_INT (63)), scratch));
13550   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13552   DONE;
13555 (define_insn "byterev"
13556   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13557         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13558                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13559                                     (const_int 4) (const_int 3) (const_int 2)
13560                                     (const_int 1) (const_int 0)])))]
13561   "TARGET_SHMEDIA"
13562   "byterev      %1, %0"
13563   [(set_attr "type" "arith_media")])
13565 (define_insn "*prefetch_media"
13566   [(prefetch (match_operand:QI 0 "address_operand" "p")
13567              (match_operand:SI 1 "const_int_operand" "n")
13568              (match_operand:SI 2 "const_int_operand" "n"))]
13569   "TARGET_SHMEDIA"
13571   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13572   output_asm_insn ("ld%M0.b    %m0,r63", operands);
13573   return "";
13575   [(set_attr "type" "other")])
13577 (define_insn "*prefetch_i4"
13578   [(prefetch (match_operand:SI 0 "register_operand" "r")
13579              (match_operand:SI 1 "const_int_operand" "n")
13580              (match_operand:SI 2 "const_int_operand" "n"))]
13581   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13582   "pref @%0";
13583   [(set_attr "type" "other")])
13585 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13586 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13587 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13588 (define_expand "prefetch"
13589   [(prefetch (match_operand 0 "address_operand" "p")
13590              (match_operand:SI 1 "const_int_operand" "n")
13591              (match_operand:SI 2 "const_int_operand" "n"))]
13592   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13593    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13595   if (GET_MODE (operands[0]) != Pmode
13596       || !CONST_INT_P (operands[1])
13597       || !CONST_INT_P (operands[2]))
13598     FAIL;
13599   if (! TARGET_SHMEDIA)
13600     operands[0] = force_reg (Pmode, operands[0]);
13603 (define_insn "prefetch_m2a"
13604   [(prefetch (match_operand:SI 0 "register_operand" "r")
13605              (match_operand:SI 1 "const_int_operand" "n")
13606              (match_operand:SI 2 "const_int_operand" "n"))]
13607   "TARGET_SH2A"
13608   "pref\\t@%0"
13609   [(set_attr "type" "other")])
13611 (define_insn "alloco_i"
13612   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13613         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13614   "TARGET_SHMEDIA32"
13616   rtx xops[2];
13618   if (GET_CODE (operands[0]) == PLUS)
13619     {
13620       xops[0] = XEXP (operands[0], 0);
13621       xops[1] = XEXP (operands[0], 1);
13622     }
13623   else
13624     {
13625       xops[0] = operands[0];
13626       xops[1] = const0_rtx;
13627     }
13628   output_asm_insn ("alloco   %0, %1", xops);
13629   return "";
13631   [(set_attr "type" "other")])
13633 (define_split
13634   [(set (match_operand 0 "any_register_operand" "")
13635         (match_operand 1 "" ""))]
13636   "TARGET_SHMEDIA && reload_completed"
13637   [(set (match_dup 0) (match_dup 1))]
13639   int n_changes = 0;
13641   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13642   if (!n_changes)
13643     FAIL;
13646 ; Stack Protector Patterns
13648 (define_expand "stack_protect_set"
13649   [(set (match_operand 0 "memory_operand" "")
13650         (match_operand 1 "memory_operand" ""))]
13651   ""
13653   if (TARGET_SHMEDIA)
13654     {
13655       if (TARGET_SHMEDIA64)
13656         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13657       else
13658         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13659     }
13660   else
13661     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13663   DONE;
13666 (define_insn "stack_protect_set_si"
13667   [(set (match_operand:SI 0 "memory_operand" "=m")
13668         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13669    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13670   "!TARGET_SHMEDIA"
13671   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13672   [(set_attr "type" "other")
13673    (set_attr "length" "6")])
13675 (define_insn "stack_protect_set_si_media"
13676   [(set (match_operand:SI 0 "memory_operand" "=m")
13677         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13678    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13679   "TARGET_SHMEDIA"
13680   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13681   [(set_attr "type" "other")
13682    (set_attr "length" "12")])
13684 (define_insn "stack_protect_set_di_media"
13685   [(set (match_operand:DI 0 "memory_operand" "=m")
13686         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13687    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13688   "TARGET_SHMEDIA64"
13689   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13690   [(set_attr "type" "other")
13691    (set_attr "length" "12")])
13693 (define_expand "stack_protect_test"
13694   [(match_operand 0 "memory_operand" "")
13695    (match_operand 1 "memory_operand" "")
13696    (match_operand 2 "" "")]
13697   ""
13699   if (TARGET_SHMEDIA)
13700     {
13701       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13702       rtx test;
13704       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13705       if (TARGET_SHMEDIA64)
13706         {
13707           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13708                                                       operands[1]));
13709           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13710         }
13711       else
13712         {
13713           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13714                                                       operands[1]));
13715           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13716         }
13717     }
13718   else
13719     {
13720       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13721       emit_jump_insn (gen_branch_true (operands[2]));
13722     }
13724   DONE;
13727 (define_insn "stack_protect_test_si"
13728   [(set (reg:SI T_REG)
13729         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13730                     (match_operand:SI 1 "memory_operand" "m")]
13731                    UNSPEC_SP_TEST))
13732   (set (match_scratch:SI 2 "=&r") (const_int 0))
13733   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13734   "!TARGET_SHMEDIA"
13735   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13736   [(set_attr "type" "other")
13737    (set_attr "length" "10")])
13739 (define_insn "stack_protect_test_si_media"
13740   [(set (match_operand:SI 0 "register_operand" "=&r")
13741         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13742                     (match_operand:SI 2 "memory_operand" "m")]
13743                    UNSPEC_SP_TEST))
13744   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13745   "TARGET_SHMEDIA"
13746   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13747   [(set_attr "type" "other")
13748    (set_attr "length" "16")])
13750 (define_insn "stack_protect_test_di_media"
13751   [(set (match_operand:DI 0 "register_operand" "=&r")
13752         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13753                     (match_operand:DI 2 "memory_operand" "m")]
13754                    UNSPEC_SP_TEST))
13755   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13756   "TARGET_SHMEDIA64"
13757   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13758   [(set_attr "type" "other")
13759    (set_attr "length" "16")])
13761 (include "sync.md")