2008-05-30 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / sh / sh.md
blob95f436f642a08509ffbb816b5f17402438049635
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 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
24 ;; ??? Should prepend a * to all pattern names which are not used.
25 ;; This will make the compiler smaller, and rebuilds after changes faster.
27 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
28 ;; sequences.  Especially the sequences for arithmetic right shifts.
30 ;; ??? Should check all DImode patterns for consistency and usefulness.
32 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
33 ;; way to generate them.
35 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
36 ;; for a str* inline function.
38 ;; BSR is not generated by the compiler proper, but when relaxing, it
39 ;; generates .uses pseudo-ops that allow linker relaxation to create
40 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
42 ;; Special constraints for SH machine description:
44 ;;    t -- T
45 ;;    x -- mac
46 ;;    l -- pr
47 ;;    z -- r0
49 ;; Special formats used for outputting SH instructions:
51 ;;   %.  --  print a .s if insn needs delay slot
52 ;;   %@  --  print rte/rts if is/isn't an interrupt function
53 ;;   %#  --  output a nop if there is nothing to put in the delay slot
54 ;;   %O  --  print a constant without the #
55 ;;   %R  --  print the lsw reg of a double
56 ;;   %S  --  print the msw reg of a double
57 ;;   %T  --  print next word of a double REG or MEM
59 ;; Special predicates:
61 ;;  arith_operand          -- operand is valid source for arithmetic op
62 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
63 ;;  general_movdst_operand -- operand is valid move destination
64 ;;  general_movsrc_operand -- operand is valid move source
65 ;;  logical_operand        -- operand is valid source for logical op
67 ;; -------------------------------------------------------------------------
68 ;; Constants
69 ;; -------------------------------------------------------------------------
71 (define_constants [
72   (AP_REG       145)
73   (PR_REG       146)
74   (T_REG        147)
75   (GBR_REG      144)
76   (MACH_REG     148)
77   (MACL_REG     149)
78   (FPUL_REG     150)
79   (RAP_REG      152)
81   (FPSCR_REG    151)
83   (PIC_REG      12)
84   (FP_REG       14)
85   (SP_REG       15)
87   (PR_MEDIA_REG 18)
88   (T_MEDIA_REG  19)
90   (R0_REG       0)
91   (R1_REG       1)
92   (R2_REG       2)
93   (R3_REG       3)
94   (R4_REG       4)
95   (R5_REG       5)
96   (R6_REG       6)
97   (R7_REG       7)
98   (R8_REG       8)
99   (R9_REG       9)
100   (R10_REG      10)
101   (R20_REG      20)
102   (R21_REG      21)
103   (R22_REG      22)
104   (R23_REG      23)
106   (DR0_REG      64)
107   (DR2_REG      66)
108   (DR4_REG      68)
109   (FR23_REG     87)
111   (TR0_REG      128)
112   (TR1_REG      129)
113   (TR2_REG      130)
115   (XD0_REG      136)
117   ;; These are used with unspec.
118   (UNSPEC_COMPACT_ARGS  0)
119   (UNSPEC_MOVA          1)
120   (UNSPEC_CASESI        2)
121   (UNSPEC_DATALABEL     3)
122   (UNSPEC_BBR           4)
123   (UNSPEC_SFUNC         5)
124   (UNSPEC_PIC           6)
125   (UNSPEC_GOT           7)
126   (UNSPEC_GOTOFF        8)
127   (UNSPEC_PLT           9)
128   (UNSPEC_CALLER        10)
129   (UNSPEC_GOTPLT        11)
130   (UNSPEC_ICACHE        12)
131   (UNSPEC_INIT_TRAMP    13)
132   (UNSPEC_FCOSA         14)
133   (UNSPEC_FSRRA         15)
134   (UNSPEC_FSINA         16)
135   (UNSPEC_NSB           17)
136   (UNSPEC_ALLOCO        18)
137   (UNSPEC_TLSGD         20)
138   (UNSPEC_TLSLDM        21)
139   (UNSPEC_TLSIE         22)
140   (UNSPEC_DTPOFF        23)
141   (UNSPEC_GOTTPOFF      24)
142   (UNSPEC_TPOFF         25)
143   (UNSPEC_RA            26)
144   (UNSPEC_DIV_INV_M0    30)
145   (UNSPEC_DIV_INV_M1    31)
146   (UNSPEC_DIV_INV_M2    32)
147   (UNSPEC_DIV_INV_M3    33)
148   (UNSPEC_DIV_INV20     34)
149   (UNSPEC_DIV_INV_TABLE 37)
150   (UNSPEC_ASHIFTRT      35)
151   (UNSPEC_THUNK         36)
152   (UNSPEC_SP_SET        40)
153   (UNSPEC_SP_TEST       41)
154   (UNSPEC_MOVUA         42)
156   ;; These are used with unspec_volatile.
157   (UNSPECV_BLOCKAGE     0)
158   (UNSPECV_ALIGN        1)
159   (UNSPECV_CONST2       2)
160   (UNSPECV_CONST4       4)
161   (UNSPECV_CONST8       6)
162   (UNSPECV_WINDOW_END   10)
163   (UNSPECV_CONST_END    11)
164   (UNSPECV_EH_RETURN    12)
167 ;; -------------------------------------------------------------------------
168 ;; Attributes
169 ;; -------------------------------------------------------------------------
171 ;; Target CPU.
173 (define_attr "cpu"
174  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
175   (const (symbol_ref "sh_cpu_attr")))
177 (define_attr "endian" "big,little"
178  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
179                       (const_string "little") (const_string "big"))))
181 ;; Indicate if the default fpu mode is single precision.
182 (define_attr "fpu_single" "yes,no"
183   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
184                          (const_string "yes") (const_string "no"))))
186 (define_attr "fmovd" "yes,no"
187   (const (if_then_else (symbol_ref "TARGET_FMOVD")
188                        (const_string "yes") (const_string "no"))))
189 ;; pipeline model
190 (define_attr "pipe_model" "sh1,sh4,sh5media"
191   (const
192    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
193           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
194          (const_string "sh1"))))
196 ;; cbranch      conditional branch instructions
197 ;; jump         unconditional jumps
198 ;; arith        ordinary arithmetic
199 ;; arith3       a compound insn that behaves similarly to a sequence of
200 ;;              three insns of type arith
201 ;; arith3b      like above, but might end with a redirected branch
202 ;; load         from memory
203 ;; load_si      Likewise, SImode variant for general register.
204 ;; fload        Likewise, but load to fp register.
205 ;; store        to memory
206 ;; fstore       floating point register to memory
207 ;; move         general purpose register to register
208 ;; movi8        8-bit immediate to general purpose register
209 ;; mt_group     other sh4 mt instructions
210 ;; fmove        register to register, floating point
211 ;; smpy         word precision integer multiply
212 ;; dmpy         longword or doublelongword precision integer multiply
213 ;; return       rts
214 ;; pload        load of pr reg, which can't be put into delay slot of rts
215 ;; prset        copy register to pr reg, ditto
216 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
217 ;; prget        copy pr to register, ditto
218 ;; pcload       pc relative load of constant value
219 ;; pcfload      Likewise, but load to fp register.
220 ;; pcload_si    Likewise, SImode variant for general register.
221 ;; rte          return from exception
222 ;; sfunc        special function call with known used registers
223 ;; call         function call
224 ;; fp           floating point
225 ;; fpscr_toggle toggle a bit in the fpscr
226 ;; fdiv         floating point divide (or square root)
227 ;; gp_fpul      move from general purpose register to fpul
228 ;; fpul_gp      move from fpul to general purpose register
229 ;; mac_gp       move from mac[lh] to general purpose register
230 ;; gp_mac       move from general purpose register to mac[lh]
231 ;; mac_mem      move from mac[lh] to memory
232 ;; mem_mac      move from memory to mac[lh]
233 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
234 ;; ftrc_s       fix_truncsfsi2_i4
235 ;; dfdiv        double precision floating point divide (or square root)
236 ;; cwb          ic_invalidate_line_i
237 ;; movua        SH4a unaligned load
238 ;; fsrra        square root reciprocal approximate
239 ;; fsca         sine and cosine approximate
240 ;; tls_load     load TLS related address
241 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
242 ;; cbranch_media SHmedia conditional branch instructions
243 ;; cmp_media    SHmedia compare instructions
244 ;; dfdiv_media  SHmedia double precision divide and square root
245 ;; dfmul_media  SHmedia double precision multiply instruction
246 ;; dfparith_media SHmedia double precision floating point arithmetic
247 ;; dfpconv_media SHmedia double precision floating point conversions
248 ;; dmpy_media   SHmedia longword multiply
249 ;; fcmp_media   SHmedia floating point compare instructions
250 ;; fdiv_media   SHmedia single precision divide and square root
251 ;; fload_media  SHmedia floating point register load instructions
252 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
253 ;; fparith_media SHmedia single precision floating point arithmetic
254 ;; fpconv_media SHmedia single precision floating point conversions
255 ;; fstore_media SHmedia floating point register store instructions
256 ;; gettr_media  SHmedia gettr instruction
257 ;; invalidate_line_media SHmedia invalidate_line sequence
258 ;; jump_media   SHmedia unconditional branch instructions
259 ;; load_media   SHmedia general register load instructions
260 ;; pt_media     SHmedia pt instruction (expanded by assembler)
261 ;; ptabs_media  SHmedia ptabs instruction
262 ;; store_media  SHmedia general register store instructions
263 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
264 ;; mac_media    SHmedia mac-style fixed point operations
265 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
266 ;; atrans_media SHmedia approximate transcendental functions
267 ;; ustore_media SHmedia unaligned stores
268 ;; nil          no-op move, will be deleted.
270 (define_attr "type"
271  "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"
272   (const_string "other"))
274 ;; We define a new attribute namely "insn_class".We use
275 ;; this for the DFA based pipeline description.
277 ;; mt_group      SH4 "mt" group instructions.
279 ;; ex_group      SH4 "ex" group instructions.
281 ;; ls_group      SH4 "ls" group instructions.
284 (define_attr "insn_class"
285   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
286   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
287          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
288          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
289          (eq_attr "type" "cbranch,jump") (const_string "br_group")
290          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
291            (const_string "fe_group")
292          (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")]
293         (const_string "none")))
294 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
295 ;; so these do not belong in an insn group, although they are modeled
296 ;; with their own define_insn_reservations.
298 ;; Indicate what precision must be selected in fpscr for this insn, if any.
300 (define_attr "fp_mode" "single,double,none" (const_string "none"))
302 ;; Indicate if the fpu mode is set by this instruction
303 ;; "unknown" must have the value as "none" in fp_mode, and means
304 ;; that the instruction/abi has left the processor in an unknown
305 ;; state.
306 ;; "none" means that nothing has changed and no mode is set.
307 ;; This attribute is only used for the Renesas ABI.
308 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
310 ; If a conditional branch destination is within -252..258 bytes away
311 ; from the instruction it can be 2 bytes long.  Something in the
312 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
313 ; branches are initially assumed to be 16 bytes long.
314 ; In machine_dependent_reorg, we split all branches that are longer than
315 ; 2 bytes.
317 ;; The maximum range used for SImode constant pool entries is 1018.  A final
318 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
319 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
320 ;; instruction around the pool table, 2 bytes of alignment before the table,
321 ;; and 30 bytes of alignment after the table.  That gives a maximum total
322 ;; pool size of 1058 bytes.
323 ;; Worst case code/pool content size ratio is 1:2 (using asms).
324 ;; Thus, in the worst case, there is one instruction in front of a maximum
325 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
326 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
327 ;; If we have a forward branch, the initial table will be put after the
328 ;; unconditional branch.
330 ;; ??? We could do much better by keeping track of the actual pcloads within
331 ;; the branch range and in the pcload range in front of the branch range.
333 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
334 ;; inside an le.
335 (define_attr "short_cbranch_p" "no,yes"
336   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
337          (const_string "no")
338          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
339          (const_string "yes")
340          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
341          (const_string "no")
342          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
343          (const_string "yes")
344          ] (const_string "no")))
346 (define_attr "med_branch_p" "no,yes"
347   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
348               (const_int 1988))
349          (const_string "yes")
350          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
351          (const_string "no")
352          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
353               (const_int 8186))
354          (const_string "yes")
355          ] (const_string "no")))
357 (define_attr "med_cbranch_p" "no,yes"
358   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
359               (const_int 1986))
360          (const_string "yes")
361          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
362          (const_string "no")
363          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
364                (const_int 8184))
365          (const_string "yes")
366          ] (const_string "no")))
368 (define_attr "braf_branch_p" "no,yes"
369   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
370          (const_string "no")
371          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
372               (const_int 20660))
373          (const_string "yes")
374          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
375          (const_string "no")
376          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
377               (const_int 65530))
378          (const_string "yes")
379          ] (const_string "no")))
381 (define_attr "braf_cbranch_p" "no,yes"
382   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
383          (const_string "no")
384          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
385               (const_int 20658))
386          (const_string "yes")
387          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
388          (const_string "no")
389          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
390               (const_int 65528))
391          (const_string "yes")
392          ] (const_string "no")))
394 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
395 ; For wider ranges, we need a combination of a code and a data part.
396 ; If we can get a scratch register for a long range jump, the code
397 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
398 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
399 ; long; otherwise, it must be 6 bytes long.
401 ; All other instructions are two bytes long by default.
403 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
404 ;; but getattrtab doesn't understand this.
405 (define_attr "length" ""
406   (cond [(eq_attr "type" "cbranch")
407          (cond [(eq_attr "short_cbranch_p" "yes")
408                 (const_int 2)
409                 (eq_attr "med_cbranch_p" "yes")
410                 (const_int 6)
411                 (eq_attr "braf_cbranch_p" "yes")
412                 (const_int 12)
413 ;; ??? using pc is not computed transitively.
414                 (ne (match_dup 0) (match_dup 0))
415                 (const_int 14)
416                 (ne (symbol_ref ("flag_pic")) (const_int 0))
417                 (const_int 24)
418                 ] (const_int 16))
419          (eq_attr "type" "jump")
420          (cond [(eq_attr "med_branch_p" "yes")
421                 (const_int 2)
422                 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
423                          (const_int 0))
424                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
425                               (symbol_ref "INSN"))
426                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
427                               (symbol_ref "code_for_indirect_jump_scratch"))))
428                 (cond [(eq_attr "braf_branch_p" "yes")
429                        (const_int 6)
430                        (eq (symbol_ref "flag_pic") (const_int 0))
431                        (const_int 10)
432                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
433                        (const_int 10)] (const_int 18))
434                 (eq_attr "braf_branch_p" "yes")
435                 (const_int 10)
436 ;; ??? using pc is not computed transitively.
437                 (ne (match_dup 0) (match_dup 0))
438                 (const_int 12)
439                 (ne (symbol_ref ("flag_pic")) (const_int 0))
440                 (const_int 22)
441                 ] (const_int 14))
442          (eq_attr "type" "pt_media")
443          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
444                        (const_int 20) (const_int 12))
445          (and (eq_attr "type" "jump_media")
446               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
447          (const_int 8)
448          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
449                          (const_int 4)
450                          (const_int 2))))
452 ;; DFA descriptions for the pipelines
454 (include "sh1.md")
455 (include "shmedia.md")
456 (include "sh4.md")
458 (include "predicates.md")
459 (include "constraints.md")
461 ;; Definitions for filling delay slots
463 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
465 (define_attr "banked" "yes,no" 
466         (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
467                    (const_int 1))
468                (const_string "yes")]
469               (const_string "no")))
471 ;; ??? This should be (nil) instead of (const_int 0)
472 (define_attr "hit_stack" "yes,no"
473         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
474                    (const_int 0))
475                (const_string "no")]
476               (const_string "yes")))
478 (define_attr "interrupt_function" "no,yes"
479   (const (symbol_ref "current_function_interrupt")))
481 (define_attr "in_delay_slot" "yes,no"
482   (cond [(eq_attr "type" "cbranch") (const_string "no")
483          (eq_attr "type" "pcload,pcload_si") (const_string "no")
484          (eq_attr "needs_delay_slot" "yes") (const_string "no")
485          (eq_attr "length" "2") (const_string "yes")
486          ] (const_string "no")))
488 (define_attr "cond_delay_slot" "yes,no"
489   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
490          ] (const_string "no")))
492 (define_attr "is_sfunc" ""
493   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
495 (define_attr "is_mac_media" ""
496   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
498 (define_attr "branch_zero" "yes,no"
499   (cond [(eq_attr "type" "!cbranch") (const_string "no")
500          (ne (symbol_ref "(next_active_insn (insn)\
501                            == (prev_active_insn\
502                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
503                           && get_attr_length (next_active_insn (insn)) == 2")
504              (const_int 0))
505          (const_string "yes")]
506         (const_string "no")))
508 ;; SH4 Double-precision computation with double-precision result -
509 ;; the two halves are ready at different times.
510 (define_attr "dfp_comp" "yes,no"
511   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
512         (const_string "no")))
514 ;; Insns for which the latency of a preceding fp insn is decreased by one.
515 (define_attr "late_fp_use" "yes,no" (const_string "no"))
516 ;; And feeding insns for which this relevant.
517 (define_attr "any_fp_comp" "yes,no"
518   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
519          (const_string "yes")]
520         (const_string "no")))
522 (define_attr "any_int_load" "yes,no"
523   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
524          (const_string "yes")]
525         (const_string "no")))
527 (define_attr "highpart" "user, ignore, extend, depend, must_split"
528   (const_string "user"))
530 (define_delay
531   (eq_attr "needs_delay_slot" "yes")
532   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
534 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
535 ;; and thus we can't put a pop instruction in its delay slot.
536 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
537 ;; instruction can go in the delay slot.
539 ;; Since a normal return (rts) implicitly uses the PR register,
540 ;; we can't allow PR register loads in an rts delay slot.
542 (define_delay
543   (eq_attr "type" "return")
544   [(and (eq_attr "in_delay_slot" "yes")
545         (ior (and (eq_attr "interrupt_function" "no")
546                   (eq_attr "type" "!pload,prset"))
547              (and (eq_attr "interrupt_function" "yes")
548                   (ior
549                    (eq (symbol_ref "TARGET_SH3") (const_int 0))
550                    (eq_attr "hit_stack" "no")
551                    (eq_attr "banked" "no"))))) (nil) (nil)])
553 ;; Since a call implicitly uses the PR register, we can't allow
554 ;; a PR register store in a jsr delay slot.
556 (define_delay
557   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
558   [(and (eq_attr "in_delay_slot" "yes")
559         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
561 ;; Say that we have annulled true branches, since this gives smaller and
562 ;; faster code when branches are predicted as not taken.
564 ;; ??? The non-annulled condition should really be "in_delay_slot",
565 ;; but insns that can be filled in non-annulled get priority over insns
566 ;; that can only be filled in anulled.
568 (define_delay
569   (and (eq_attr "type" "cbranch")
570        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
571   ;; SH2e has a hardware bug that pretty much prohibits the use of
572   ;; annuled delay slots.
573   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
574                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
576 ;; -------------------------------------------------------------------------
577 ;; SImode signed integer comparisons
578 ;; -------------------------------------------------------------------------
580 (define_insn ""
581   [(set (reg:SI T_REG)
582         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
583                        (match_operand:SI 1 "arith_operand" "K08,r"))
584                (const_int 0)))]
585   "TARGET_SH1"
586   "tst  %1,%0"
587   [(set_attr "type" "mt_group")])
589 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
590 ;; That would still allow reload to create cmpi instructions, but would
591 ;; perhaps allow forcing the constant into a register when that is better.
592 ;; Probably should use r0 for mem/imm compares, but force constant into a
593 ;; register for pseudo/imm compares.
595 (define_insn "cmpeqsi_t"
596   [(set (reg:SI T_REG)
597         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
598                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
599   "TARGET_SH1"
600   "@
601         tst     %0,%0
602         cmp/eq  %1,%0
603         cmp/eq  %1,%0"
604    [(set_attr "type" "mt_group")])
606 (define_insn "cmpgtsi_t"
607   [(set (reg:SI T_REG)
608         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
609                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
610   "TARGET_SH1"
611   "@
612         cmp/gt  %1,%0
613         cmp/pl  %0"
614    [(set_attr "type" "mt_group")])
616 (define_insn "cmpgesi_t"
617   [(set (reg:SI T_REG)
618         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
619                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
620   "TARGET_SH1"
621   "@
622         cmp/ge  %1,%0
623         cmp/pz  %0"
624    [(set_attr "type" "mt_group")])
626 ;; -------------------------------------------------------------------------
627 ;; SImode compare and branch
628 ;; -------------------------------------------------------------------------
630 (define_expand "cbranchsi4"
631   [(set (pc)
632         (if_then_else (match_operator 0 "comparison_operator"
633                         [(match_operand:SI 1 "arith_operand" "")
634                          (match_operand:SI 2 "arith_operand" "")])
635                       (label_ref (match_operand 3 "" ""))
636                       (pc)))
637    (clobber (reg:SI T_REG))]
638   "TARGET_CBRANCHDI4"
639   "expand_cbranchsi4 (operands, CODE_FOR_nothing, -1); DONE;")
641 ;; -------------------------------------------------------------------------
642 ;; SImode unsigned integer comparisons
643 ;; -------------------------------------------------------------------------
645 (define_insn_and_split "cmpgeusi_t"
646   [(set (reg:SI T_REG)
647         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
648                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
649   "TARGET_SH1"
650   "cmp/hs       %1,%0"
651   "&& operands[1] == CONST0_RTX (SImode)"
652   [(pc)]
653   "
655   emit_insn (gen_sett ());
656   DONE;
658    [(set_attr "type" "mt_group")])
660 (define_insn "cmpgtusi_t"
661   [(set (reg:SI T_REG)
662         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
663                 (match_operand:SI 1 "arith_reg_operand" "r")))]
664   "TARGET_SH1"
665   "cmp/hi       %1,%0"
666    [(set_attr "type" "mt_group")])
668 ;; We save the compare operands in the cmpxx patterns and use them when
669 ;; we generate the branch.
671 (define_expand "cmpsi"
672   [(set (reg:SI T_REG)
673         (compare (match_operand:SI 0 "cmpsi_operand" "")
674                  (match_operand:SI 1 "arith_operand" "")))]
675   "TARGET_SH1 || TARGET_SHMEDIA"
676   "
678   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
679       && GET_CODE (operands[1]) != CONST_INT)
680     operands[0] = copy_to_mode_reg (SImode, operands[0]);
681   sh_compare_op0 = operands[0];
682   sh_compare_op1 = operands[1];
683   DONE;
686 ;; -------------------------------------------------------------------------
687 ;; DImode compare and branch
688 ;; -------------------------------------------------------------------------
691 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
692 ;; Therefore, we aim to have a set of three branches that go straight to the
693 ;; destination, i.e. only one of them is taken at any one time.
694 ;; This mechanism should also be slightly better for the sh4-200.
696 (define_expand "cbranchdi4"
697   [(set (pc)
698         (if_then_else (match_operator 0 "comparison_operator"
699                         [(match_operand:DI 1 "arith_operand" "")
700                          (match_operand:DI 2 "arith_operand" "")])
701                       (label_ref (match_operand 3 "" ""))
702                       (pc)))
703    (clobber (match_dup 4))
704    (clobber (reg:SI T_REG))]
705   "TARGET_CBRANCHDI4"
706   "
708   enum rtx_code comparison;
710   if (TARGET_EXPAND_CBRANCHDI4)
711     {
712       if (expand_cbranchdi4 (operands, CODE_FOR_nothing))
713         DONE;
714     }
715   comparison = prepare_cbranch_operands (operands, DImode, CODE_FOR_nothing);
716   if (comparison != GET_CODE (operands[0]))
717     operands[0]
718       = gen_rtx_fmt_ee (VOIDmode, comparison, operands[1], operands[2]);
719    operands[4] = gen_rtx_SCRATCH (SImode);
722 (define_insn_and_split "cbranchdi4_i"
723   [(set (pc)
724         (if_then_else (match_operator 0 "comparison_operator"
725                         [(match_operand:DI 1 "arith_operand" "r,r")
726                          (match_operand:DI 2 "arith_operand" "rN,i")])
727                       (label_ref (match_operand 3 "" ""))
728                       (pc)))
729    (clobber (match_scratch:SI 4 "=X,&r"))
730    (clobber (reg:SI T_REG))]
731   "TARGET_CBRANCHDI4"
732   "#"
733   "&& reload_completed"
734   [(pc)]
735   "
737   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
738     FAIL;
739   DONE;
742 ;; -------------------------------------------------------------------------
743 ;; DImode signed integer comparisons
744 ;; -------------------------------------------------------------------------
746 (define_insn ""
747   [(set (reg:SI T_REG)
748         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
749                        (match_operand:DI 1 "arith_operand" "r"))
750                (const_int 0)))]
751   "TARGET_SH1"
752   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
753                                  insn, operands);"
754   [(set_attr "length" "6")
755    (set_attr "type" "arith3b")])
757 (define_insn "cmpeqdi_t"
758   [(set (reg:SI T_REG)
759         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
760                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
761   "TARGET_SH1"
762   "@
763         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
764         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
765   [(set_attr "length" "6")
766    (set_attr "type" "arith3b")])
768 (define_split
769   [(set (reg:SI T_REG)
770         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
771                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
772 ;; If we applied this split when not optimizing, it would only be
773 ;; applied during the machine-dependent reorg, when no new basic blocks
774 ;; may be created.
775   "TARGET_SH1 && reload_completed && optimize"
776   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
777    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
778                            (label_ref (match_dup 6))
779                            (pc)))
780    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
781    (match_dup 6)]
782   "
784   operands[2]
785     = gen_rtx_REG (SImode,
786                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
787   operands[3]
788     = (operands[1] == const0_rtx
789        ? const0_rtx
790        : gen_rtx_REG (SImode,
791                       true_regnum (operands[1])
792                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
793   operands[4] = gen_lowpart (SImode, operands[0]);
794   operands[5] = gen_lowpart (SImode, operands[1]);
795   operands[6] = gen_label_rtx ();
798 (define_insn "cmpgtdi_t"
799   [(set (reg:SI T_REG)
800         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
801                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
802   "TARGET_SH2"
803   "@
804         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
805         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
806   [(set_attr "length" "8")
807    (set_attr "type" "arith3")])
809 (define_insn "cmpgedi_t"
810   [(set (reg:SI T_REG)
811         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
812                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
813   "TARGET_SH2"
814   "@
815         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
816         cmp/pz\\t%S0"
817   [(set_attr "length" "8,2")
818    (set_attr "type" "arith3,mt_group")])
820 ;; -------------------------------------------------------------------------
821 ;; DImode unsigned integer comparisons
822 ;; -------------------------------------------------------------------------
824 (define_insn "cmpgeudi_t"
825   [(set (reg:SI T_REG)
826         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
827                 (match_operand:DI 1 "arith_reg_operand" "r")))]
828   "TARGET_SH2"
829   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
830   [(set_attr "length" "8")
831    (set_attr "type" "arith3")])
833 (define_insn "cmpgtudi_t"
834   [(set (reg:SI T_REG)
835         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
836                 (match_operand:DI 1 "arith_reg_operand" "r")))]
837   "TARGET_SH2"
838   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
839   [(set_attr "length" "8")
840    (set_attr "type" "arith3")])
842 (define_insn "cmpeqsi_media"
843   [(set (match_operand:SI 0 "register_operand" "=r")
844         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
845                (match_operand:SI 2 "cmp_operand" "Nr")))]
846   "TARGET_SHMEDIA"
847   "cmpeq        %1, %N2, %0"
848   [(set_attr "type" "cmp_media")])
850 (define_insn "cmpeqdi_media"
851   [(set (match_operand:SI 0 "register_operand" "=r")
852         (eq:SI (match_operand:DI 1 "register_operand" "%r")
853                (match_operand:DI 2 "cmp_operand" "Nr")))]
854   "TARGET_SHMEDIA"
855   "cmpeq        %1, %N2, %0"
856   [(set_attr "type" "cmp_media")])
858 (define_insn "cmpgtsi_media"
859   [(set (match_operand:SI 0 "register_operand" "=r")
860         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
861                (match_operand:SI 2 "cmp_operand" "rN")))]
862   "TARGET_SHMEDIA"
863   "cmpgt        %N1, %N2, %0"
864   [(set_attr "type" "cmp_media")])
866 (define_insn "cmpgtdi_media"
867   [(set (match_operand:SI 0 "register_operand" "=r")
868         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
869                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
870   "TARGET_SHMEDIA"
871   "cmpgt        %N1, %N2, %0"
872   [(set_attr "type" "cmp_media")])
874 (define_insn "cmpgtusi_media"
875   [(set (match_operand:SI 0 "register_operand" "=r")
876         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
877                 (match_operand:SI 2 "cmp_operand" "rN")))]
878   "TARGET_SHMEDIA"
879   "cmpgtu       %N1, %N2, %0"
880   [(set_attr "type" "cmp_media")])
882 (define_insn "cmpgtudi_media"
883   [(set (match_operand:SI 0 "register_operand" "=r")
884         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
885                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
886   "TARGET_SHMEDIA"
887   "cmpgtu       %N1, %N2, %0"
888   [(set_attr "type" "cmp_media")])
890 ; These two patterns are for combine.
891 (define_insn "*cmpne0sisi_media"
892   [(set (match_operand:SI 0 "register_operand" "=r")
893         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
894   "TARGET_SHMEDIA"
895   "cmpgtu       %1,r63,%0"
896   [(set_attr "type" "cmp_media")])
898 ;; We save the compare operands in the cmpxx patterns and use them when
899 ;; we generate the branch.
901 (define_expand "cmpdi"
902   [(set (reg:SI T_REG)
903         (compare (match_operand:DI 0 "arith_operand" "")
904                  (match_operand:DI 1 "arith_operand" "")))]
905   "TARGET_SH2 || TARGET_SHMEDIA"
906   "
908   sh_compare_op0 = operands[0];
909   sh_compare_op1 = operands[1];
910   DONE;
912 ;; -------------------------------------------------------------------------
913 ;; Conditional move instructions
914 ;; -------------------------------------------------------------------------
916 ;; The insn names may seem reversed, but note that cmveq performs the move
917 ;; if op1 == 0, and cmvne does it if op1 != 0.
919 (define_insn "movdicc_false"
920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
921         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
922                              (const_int 0))
923          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
924          (match_operand:DI 3 "arith_reg_operand" "0")))]
925   "TARGET_SHMEDIA"
926   "cmveq        %1, %N2, %0"
927   [(set_attr "type" "arith_media")])
929 (define_insn "movdicc_true"
930   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
931         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
932                              (const_int 0))
933          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
934          (match_operand:DI 3 "arith_reg_operand" "0")))]
935   "TARGET_SHMEDIA"
936   "cmvne        %1, %N2, %0"
937   [(set_attr "type" "arith_media")])
939 (define_peephole2
940   [(set (match_operand:DI 0 "arith_reg_dest" "")
941         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
942                            [(match_operand:DI 1 "arith_reg_operand" "")
943                             (const_int 0)])
944          (match_operand:DI 2 "arith_reg_dest" "")
945          (match_dup 0)))
946    (set (match_dup 2) (match_dup 0))]
947   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
948   [(set (match_dup 2)
949         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
950   "
952   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
953                                 VOIDmode, operands[1], CONST0_RTX (DImode));
956 (define_peephole2
957   [(set (match_operand:DI 0 "general_movdst_operand" "")
958         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
959    (set (match_operand:DI 2 "arith_reg_dest" "")
960         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
961                            [(match_operand:DI 3 "arith_reg_operand" "")
962                             (const_int 0)])
963          (match_dup 0)
964          (match_dup 2)))]
965   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
966   [(set (match_dup 2)
967         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
968   "")
970 (define_expand "movdicc"
971   [(set (match_operand:DI 0 "register_operand" "")
972         (if_then_else:DI (match_operand 1 "comparison_operator" "")
973                          (match_operand:DI 2 "register_operand" "")
974                          (match_operand:DI 3 "register_operand" "")))]
975   "TARGET_SHMEDIA"
976   "
978   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
979       && GET_MODE (sh_compare_op0) == DImode
980       && sh_compare_op1 == const0_rtx)
981     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
982                                   sh_compare_op0, sh_compare_op1);
983   else
984     {
985       rtx tmp;
987       if (!can_create_pseudo_p ())
988         FAIL;
990       tmp = gen_reg_rtx (DImode);
992       switch (GET_CODE (operands[1]))
993         {
994         case EQ:
995           emit_insn (gen_seq (tmp));
996           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
997           break;
999         case NE:
1000           emit_insn (gen_seq (tmp));
1001           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1002           break;
1004         case GT:
1005           emit_insn (gen_sgt (tmp));
1006           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1007           break;
1009         case LT:
1010           emit_insn (gen_slt (tmp));
1011           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1012           break;
1014         case GE:
1015           emit_insn (gen_slt (tmp));
1016           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1017           break;
1019         case LE:
1020           emit_insn (gen_sgt (tmp));
1021           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1022           break;
1024         case GTU:
1025           emit_insn (gen_sgtu (tmp));
1026           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1027           break;
1029         case LTU:
1030           emit_insn (gen_sltu (tmp));
1031           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1032           break;
1034         case GEU:
1035           emit_insn (gen_sltu (tmp));
1036           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1037           break;
1039         case LEU:
1040           emit_insn (gen_sgtu (tmp));
1041           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1042           break;
1044         case UNORDERED:
1045           emit_insn (gen_sunordered (tmp));
1046           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1047           break;
1049         case ORDERED:
1050           emit_insn (gen_sunordered (tmp));
1051           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1052           break;
1054         case UNEQ:
1055         case UNGE:
1056         case UNGT:
1057         case UNLE:
1058         case UNLT:
1059         case LTGT:
1060           FAIL;
1062         default:
1063           gcc_unreachable ();
1064         }
1065     }
1068 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1069 ;; SImode to DImode.
1070 (define_insn "movsicc_false"
1071   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1072         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1073                           (const_int 0))
1074          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1075          (match_operand:SI 3 "arith_reg_operand" "0")))]
1076   "TARGET_SHMEDIA"
1077   "cmveq        %1, %N2, %0"
1078   [(set_attr "type" "arith_media")])
1080 (define_insn "movsicc_true"
1081   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1082         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1083                           (const_int 0))
1084          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1085          (match_operand:SI 3 "arith_reg_operand" "0")))]
1086   "TARGET_SHMEDIA"
1087   "cmvne        %1, %N2, %0"
1088   [(set_attr "type" "arith_media")])
1090 (define_peephole2
1091   [(set (match_operand:SI 0 "arith_reg_dest" "")
1092         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1093                            [(match_operand:SI 1 "arith_reg_operand" "")
1094                             (const_int 0)])
1095          (match_operand:SI 2 "arith_reg_dest" "")
1096          (match_dup 0)))
1097    (set (match_dup 2) (match_dup 0))]
1098   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1099   [(set (match_dup 2)
1100         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1101   "
1103   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1104                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1107 (define_peephole2
1108   [(set (match_operand:SI 0 "general_movdst_operand" "")
1109         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1110    (set (match_operand:SI 2 "arith_reg_dest" "")
1111         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1112                            [(match_operand:SI 3 "arith_reg_operand" "")
1113                             (const_int 0)])
1114          (match_dup 0)
1115          (match_dup 2)))]
1116   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1117    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1118   [(set (match_dup 2)
1119         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1120   "
1122   replace_rtx (operands[4], operands[0], operands[1]);
1125 (define_peephole2
1126   [(set (match_operand 0 "any_register_operand" "")
1127         (match_operand 1 "any_register_operand" ""))
1128    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1129    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1130   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1131     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1132    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1133    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1134    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1135    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1136    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1137    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1138    && (REGNO_REG_CLASS (REGNO (operands[0]))
1139        == REGNO_REG_CLASS (REGNO (operands[2])))
1140    && (REGNO_REG_CLASS (REGNO (operands[1]))
1141        == REGNO_REG_CLASS (REGNO (operands[0])))"
1142   [(set (match_dup 0) (match_dup 3))
1143    (set (match_dup 4) (match_dup 5))]
1144   "
1146   rtx set1, set2, insn2;
1147   rtx replacements[4];
1149   /* We want to replace occurrences of operands[0] with operands[1] and
1150      operands[2] with operands[0] in operands[4]/operands[5].
1151      Doing just two replace_rtx calls naively would result in the second
1152      replacement undoing all that the first did if operands[1] and operands[2]
1153      are identical, so we must do this simultaneously.  */
1154   replacements[0] = operands[0];
1155   replacements[1] = operands[1];
1156   replacements[2] = operands[2];
1157   replacements[3] = operands[0];
1158   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1159       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1160       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1161     FAIL;
1163   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1164   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1165   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1166   /* The operands array is aliased to recog_data.operand, which gets
1167      clobbered by extract_insn, so finish with it now.  */
1168   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1169   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1170   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1171      always uses emit_insn.  */
1172   /* Check that we don't violate matching constraints or earlyclobbers.  */
1173   extract_insn (emit_insn (set1));
1174   if (! constrain_operands (1))
1175     goto failure;
1176   insn2 = emit (set2);
1177   if (GET_CODE (insn2) == BARRIER)
1178     goto failure;
1179   extract_insn (insn2);
1180   if (! constrain_operands (1))
1181     {
1182       rtx tmp;
1183     failure:
1184       tmp = replacements[0];
1185       replacements[0] = replacements[1];
1186       replacements[1] = tmp;
1187       tmp = replacements[2];
1188       replacements[2] = replacements[3];
1189       replacements[3] = tmp;
1190       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1191       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1192       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1193       FAIL;
1194     }
1195   DONE;
1198 ;; The register allocator is rather clumsy in handling multi-way conditional
1199 ;; moves, so allow the combiner to make them, and we split them up after
1200 ;; reload.  */
1201 (define_insn_and_split "*movsicc_umin"
1202   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1203         (umin:SI (if_then_else:SI
1204                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1205                        (const_int 0))
1206                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1207                    (match_operand:SI 3 "register_operand" "0"))
1208                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1209    (clobber (match_scratch:SI 5 "=&r"))]
1210   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1211   "#"
1212   "TARGET_SHMEDIA && reload_completed"
1213   [(pc)]
1214   "
1216   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1217                                 operands[3]));
1218   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1219   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1220                                 operands[0]));
1221   DONE;
1224 (define_insn "*movsicc_t_false"
1225   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1226         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1227                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1228                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1229   "TARGET_PRETEND_CMOVE
1230    && (arith_reg_operand (operands[1], SImode)
1231        || (immediate_operand (operands[1], SImode)
1232            && satisfies_constraint_I08 (operands[1])))"
1233   "bt 0f\;mov %1,%0\\n0:"
1234   [(set_attr "type" "mt_group,arith") ;; poor approximation
1235    (set_attr "length" "4")])
1237 (define_insn "*movsicc_t_true"
1238   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1239         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1240                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1241                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1242   "TARGET_PRETEND_CMOVE
1243    && (arith_reg_operand (operands[1], SImode)
1244        || (immediate_operand (operands[1], SImode)
1245            && satisfies_constraint_I08 (operands[1])))"
1246   "bf 0f\;mov %1,%0\\n0:"
1247   [(set_attr "type" "mt_group,arith") ;; poor approximation
1248    (set_attr "length" "4")])
1250 (define_expand "movsicc"
1251   [(set (match_operand:SI 0 "arith_reg_dest" "")
1252         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1253                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1254                          (match_operand:SI 3 "arith_reg_operand" "")))]
1255   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1256   "
1258   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1259       && GET_MODE (sh_compare_op0) == SImode
1260       && (TARGET_SHMEDIA
1261           || (REG_P (sh_compare_op0) && REGNO (sh_compare_op0) == T_REG))
1262       && sh_compare_op1 == const0_rtx)
1263     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1264                                   sh_compare_op0, sh_compare_op1);
1265   else if (TARGET_PRETEND_CMOVE)
1266     {
1267       enum rtx_code code = GET_CODE (operands[1]);
1268       enum rtx_code new_code = code;
1269       rtx tmp;
1271       if (! currently_expanding_to_rtl)
1272         FAIL;
1273       switch (code)
1274         {
1275         case LT: case LE: case LEU: case LTU:
1276           if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) != MODE_INT)
1277             break;
1278         case NE:
1279           new_code = reverse_condition (code);
1280           break;
1281         case EQ: case GT: case GE: case GEU: case GTU:
1282           break;
1283         default:
1284           FAIL;
1285         }
1286       tmp = prepare_scc_operands (new_code);
1287       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1288                                     tmp, const0_rtx);
1289     }
1290   else
1291     {
1292       rtx tmp;
1294       if (!can_create_pseudo_p ())
1295         FAIL;
1297       tmp = gen_reg_rtx (SImode);
1299       switch (GET_CODE (operands[1]))
1300         {
1301         case EQ:
1302           emit_insn (gen_seq (tmp));
1303           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1304           break;
1306         case NE:
1307           emit_insn (gen_seq (tmp));
1308           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1309           break;
1311         case GT:
1312           emit_insn (gen_sgt (tmp));
1313           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1314           break;
1316         case LT:
1317           emit_insn (gen_slt (tmp));
1318           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1319           break;
1321         case GE:
1322           emit_insn (gen_slt (tmp));
1323           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1324           break;
1326         case LE:
1327           emit_insn (gen_sgt (tmp));
1328           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1329           break;
1331         case GTU:
1332           emit_insn (gen_sgtu (tmp));
1333           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1334           break;
1336         case LTU:
1337           emit_insn (gen_sltu (tmp));
1338           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1339           break;
1341         case GEU:
1342           emit_insn (gen_sltu (tmp));
1343           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1344           break;
1346         case LEU:
1347           emit_insn (gen_sgtu (tmp));
1348           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1349           break;
1351         case UNORDERED:
1352           emit_insn (gen_sunordered (tmp));
1353           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1354           break;
1356         case ORDERED:
1357           emit_insn (gen_sunordered (tmp));
1358           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1359           break;
1361         case UNEQ:
1362         case UNGE:
1363         case UNGT:
1364         case UNLE:
1365         case UNLT:
1366         case LTGT:
1367           FAIL;
1369         default:
1370           abort ();
1371         }
1372     }
1375 (define_expand "movqicc"
1376   [(set (match_operand:QI 0 "register_operand" "")
1377         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1378                          (match_operand:QI 2 "register_operand" "")
1379                          (match_operand:QI 3 "register_operand" "")))]
1380   "TARGET_SHMEDIA"
1381   "
1383   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1384   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1385   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1386   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1387   DONE;
1390 ;; -------------------------------------------------------------------------
1391 ;; Addition instructions
1392 ;; -------------------------------------------------------------------------
1394 (define_expand "adddi3"
1395   [(set (match_operand:DI 0 "arith_reg_operand" "")
1396         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1397                  (match_operand:DI 2 "arith_operand" "")))]
1398   ""
1399   "
1401   if (TARGET_SH1)
1402     {
1403       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1404         FAIL;
1405       operands[2] = force_reg (DImode, operands[2]);
1406       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1407       DONE;
1408     }
1411 (define_insn "*adddi3_media"
1412   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1413         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1414                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1415   "TARGET_SHMEDIA"
1416   "@
1417         add     %1, %2, %0
1418         addi    %1, %2, %0"
1419   [(set_attr "type" "arith_media")])
1421 (define_insn "*adddisi3_media"
1422   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1423         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1424                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1425   "TARGET_SHMEDIA"
1426   "@
1427         add.l   %1, %2, %0
1428         addi.l  %1, %2, %0"
1429   [(set_attr "type" "arith_media")
1430    (set_attr "highpart" "ignore")])
1432 (define_insn "adddi3z_media"
1433   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1434         (zero_extend:DI
1435          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1436                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1437   "TARGET_SHMEDIA"
1438   "addz.l       %1, %N2, %0"
1439   [(set_attr "type" "arith_media")
1440    (set_attr "highpart" "ignore")])
1442 (define_insn "adddi3_compact"
1443   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1444         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1445                  (match_operand:DI 2 "arith_reg_operand" "r")))
1446    (clobber (reg:SI T_REG))]
1447   "TARGET_SH1"
1448   "#"
1449   [(set_attr "length" "6")])
1451 (define_split
1452   [(set (match_operand:DI 0 "arith_reg_dest" "")
1453         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1454                  (match_operand:DI 2 "arith_reg_operand" "")))
1455    (clobber (reg:SI T_REG))]
1456   "TARGET_SH1 && reload_completed"
1457   [(const_int 0)]
1458   "
1460   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1461   high0 = gen_rtx_REG (SImode,
1462                        true_regnum (operands[0])
1463                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1464   high2 = gen_rtx_REG (SImode,
1465                        true_regnum (operands[2])
1466                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1467   emit_insn (gen_clrt ());
1468   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1469   emit_insn (gen_addc1 (high0, high0, high2));
1470   DONE;
1473 (define_insn "addc"
1474   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1475         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1476                           (match_operand:SI 2 "arith_reg_operand" "r"))
1477                  (reg:SI T_REG)))
1478    (set (reg:SI T_REG)
1479         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1480   "TARGET_SH1"
1481   "addc %2,%0"
1482   [(set_attr "type" "arith")])
1484 (define_insn "addc1"
1485   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1486         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1487                           (match_operand:SI 2 "arith_reg_operand" "r"))
1488                  (reg:SI T_REG)))
1489    (clobber (reg:SI T_REG))]
1490   "TARGET_SH1"
1491   "addc %2,%0"
1492   [(set_attr "type" "arith")])
1494 (define_expand "addsi3"
1495   [(set (match_operand:SI 0 "arith_reg_operand" "")
1496         (plus:SI (match_operand:SI 1 "arith_operand" "")
1497                  (match_operand:SI 2 "arith_operand" "")))]
1498   ""
1499   "
1501   if (TARGET_SHMEDIA)
1502     operands[1] = force_reg (SImode, operands[1]);
1505 (define_insn "addsi3_media"
1506   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1507         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1508                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1509   "TARGET_SHMEDIA"
1510   "@
1511         add.l   %1, %2, %0
1512         addi.l  %1, %2, %0"
1513   [(set_attr "type" "arith_media")
1514    (set_attr "highpart" "ignore")])
1516 (define_insn "addsidi3_media"
1517   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1518         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1519                                   "%r,r")
1520                                  (match_operand:SI 2 "arith_operand"
1521                                   "r,I10"))))]
1522   "TARGET_SHMEDIA"
1523   "@
1524         add.l   %1, %2, %0
1525         addi.l  %1, %2, %0"
1526   [(set_attr "type" "arith_media")
1527    (set_attr "highpart" "ignore")])
1529 (define_insn "*addsi3_compact"
1530   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1531         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1532                  (match_operand:SI 2 "arith_operand" "rI08")))]
1533   "TARGET_SH1"
1534   "add  %2,%0"
1535   [(set_attr "type" "arith")])
1537 ;; -------------------------------------------------------------------------
1538 ;; Subtraction instructions
1539 ;; -------------------------------------------------------------------------
1541 (define_expand "subdi3"
1542   [(set (match_operand:DI 0 "arith_reg_operand" "")
1543         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1544                   (match_operand:DI 2 "arith_reg_operand" "")))]
1545   ""
1546   "
1548   if (TARGET_SH1)
1549     {
1550       operands[1] = force_reg (DImode, operands[1]);
1551       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1552       DONE;
1553     }
1556 (define_insn "*subdi3_media"
1557   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
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  %N1, %2, %0"
1562   [(set_attr "type" "arith_media")])
1563   
1564 (define_insn "subdisi3_media"
1565   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1566         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1567                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1568   "TARGET_SHMEDIA"
1569   "sub.l        %N1, %2, %0"
1570   [(set_attr "type" "arith_media")
1571    (set_attr "highpart" "ignore")])
1573 (define_insn "subdi3_compact"
1574   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1575         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1576                  (match_operand:DI 2 "arith_reg_operand" "r")))
1577    (clobber (reg:SI T_REG))]
1578   "TARGET_SH1"
1579   "#"
1580   [(set_attr "length" "6")])
1582 (define_split
1583   [(set (match_operand:DI 0 "arith_reg_dest" "")
1584         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1585                   (match_operand:DI 2 "arith_reg_operand" "")))
1586    (clobber (reg:SI T_REG))]
1587   "TARGET_SH1 && reload_completed"
1588   [(const_int 0)]
1589   "
1591   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1592   high0 = gen_rtx_REG (SImode,
1593                        true_regnum (operands[0])
1594                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1595   high2 = gen_rtx_REG (SImode,
1596                        true_regnum (operands[2])
1597                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1598   emit_insn (gen_clrt ());
1599   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1600   emit_insn (gen_subc1 (high0, high0, high2));
1601   DONE;
1604 (define_insn "subc"
1605   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1606         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1607                             (match_operand:SI 2 "arith_reg_operand" "r"))
1608                   (reg:SI T_REG)))
1609    (set (reg:SI T_REG)
1610         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1611                           (reg:SI T_REG))
1612                 (match_dup 1)))]
1613   "TARGET_SH1"
1614   "subc %2,%0"
1615   [(set_attr "type" "arith")])
1617 (define_insn "subc1"
1618   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1619         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1620                             (match_operand:SI 2 "arith_reg_operand" "r"))
1621                   (reg:SI T_REG)))
1622    (clobber (reg:SI T_REG))]
1623   "TARGET_SH1"
1624   "subc %2,%0"
1625   [(set_attr "type" "arith")])
1627 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1628 ;; pattern for this case.  This helps multimedia applications that compute
1629 ;; the sum of absolute differences.
1630 (define_insn "mov_neg_si_t"
1631   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1632   "TARGET_SH1"
1633   "subc %0,%0"
1634   [(set_attr "type" "arith")])
1636 (define_insn "*subsi3_internal"
1637   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1638         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1639                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1640   "TARGET_SH1"
1641   "sub  %2,%0"
1642   [(set_attr "type" "arith")])
1644 (define_insn_and_split "*subsi3_media"
1645   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1646         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1647                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1648   "TARGET_SHMEDIA
1649    && (operands[1] != constm1_rtx
1650        || (GET_CODE (operands[2]) != TRUNCATE
1651            && GET_CODE (operands[2]) != SUBREG))"
1652   "sub.l        %N1, %2, %0"
1653   "operands[1] == constm1_rtx"
1654   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1655   ""
1656   [(set_attr "type" "arith_media")
1657    (set_attr "highpart" "ignore")])
1659 (define_split
1660   [(set (match_operand:SI 0 "arith_reg_dest" "")
1661         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1662                                                        "general_extend_operand"
1663                                                        "") 0)) 0)))]
1664   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1665   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1666    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1667   "")
1669 (define_split
1670   [(set (match_operand:SI 0 "arith_reg_dest" "")
1671         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1672                                                        "general_extend_operand"
1673                                                        "") 0)) 3)))]
1674   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1675   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1676    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1677   "")
1678 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1679 ;; will sometimes save one instruction.  Otherwise we might get
1680 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1681 ;; are the same.
1683 (define_expand "subsi3"
1684   [(set (match_operand:SI 0 "arith_reg_operand" "")
1685         (minus:SI (match_operand:SI 1 "arith_operand" "")
1686                   (match_operand:SI 2 "arith_reg_operand" "")))]
1687   ""
1688   "
1690   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1691     {
1692       emit_insn (gen_negsi2 (operands[0], operands[2]));
1693       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1694       DONE;
1695     }
1696   if (TARGET_SHMEDIA)
1697     {
1698       if (!can_create_pseudo_p ()
1699           && ! arith_reg_or_0_operand (operands[1], SImode))
1700         FAIL;
1701       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1702         operands[1] = force_reg (SImode, operands[1]);
1703     }
1706 ;; -------------------------------------------------------------------------
1707 ;; Division instructions
1708 ;; -------------------------------------------------------------------------
1710 ;; We take advantage of the library routines which don't clobber as many
1711 ;; registers as a normal function call would.
1713 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1714 ;; also has an effect on the register that holds the address of the sfunc.
1715 ;; To make this work, we have an extra dummy insn that shows the use
1716 ;; of this register for reorg.
1718 (define_insn "use_sfunc_addr"
1719   [(set (reg:SI PR_REG)
1720         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1721   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1722   ""
1723   [(set_attr "length" "0")])
1725 (define_insn "udivsi3_sh2a"
1726   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1727         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1728                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1729   "TARGET_SH2A"
1730   "divu %2,%1"
1731   [(set_attr "type" "arith")
1732    (set_attr "in_delay_slot" "no")])
1734 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1735 ;; hard register 0.  If we used hard register 0, then the next instruction
1736 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1737 ;; gets allocated to a stack slot that needs its address reloaded, then
1738 ;; there is nothing to prevent reload from using r0 to reload the address.
1739 ;; This reload would clobber the value in r0 we are trying to store.
1740 ;; If we let reload allocate r0, then this problem can never happen.
1742 (define_insn "udivsi3_i1"
1743   [(set (match_operand:SI 0 "register_operand" "=z")
1744         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1745    (clobber (reg:SI T_REG))
1746    (clobber (reg:SI PR_REG))
1747    (clobber (reg:SI R4_REG))
1748    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1749   "TARGET_SH1 && ! TARGET_SH4"
1750   "jsr  @%1%#"
1751   [(set_attr "type" "sfunc")
1752    (set_attr "needs_delay_slot" "yes")])
1754 ; Since shmedia-nofpu code could be linked against shcompact code, and
1755 ; the udivsi3 libcall has the same name, we must consider all registers
1756 ; clobbered that are in the union of the registers clobbered by the
1757 ; shmedia and the shcompact implementation.  Note, if the shcompact
1758 ; implementation actually used shcompact code, we'd need to clobber
1759 ; also r23 and fr23.
1760 (define_insn "udivsi3_i1_media"
1761   [(set (match_operand:SI 0 "register_operand" "=z")
1762         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1763    (clobber (reg:SI T_MEDIA_REG))
1764    (clobber (reg:SI PR_MEDIA_REG))
1765    (clobber (reg:SI R20_REG))
1766    (clobber (reg:SI R21_REG))
1767    (clobber (reg:SI R22_REG))
1768    (clobber (reg:DI TR0_REG))
1769    (clobber (reg:DI TR1_REG))
1770    (clobber (reg:DI TR2_REG))
1771    (use (match_operand 1 "target_reg_operand" "b"))]
1772   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1773   "blink        %1, r18"
1774   [(set_attr "type" "sfunc")
1775    (set_attr "needs_delay_slot" "yes")])
1777 (define_expand "udivsi3_i4_media"
1778   [(set (match_dup 3)
1779         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1780    (set (match_dup 4)
1781         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1782    (set (match_dup 5) (float:DF (match_dup 3)))
1783    (set (match_dup 6) (float:DF (match_dup 4)))
1784    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1785    (set (match_dup 8) (fix:DI (match_dup 7)))
1786    (set (match_operand:SI 0 "register_operand" "")
1787         (truncate:SI (match_dup 8)))]
1788   "TARGET_SHMEDIA_FPU"
1789   "
1791   operands[3] = gen_reg_rtx (DImode);
1792   operands[4] = gen_reg_rtx (DImode);
1793   operands[5] = gen_reg_rtx (DFmode);
1794   operands[6] = gen_reg_rtx (DFmode);
1795   operands[7] = gen_reg_rtx (DFmode);
1796   operands[8] = gen_reg_rtx (DImode);
1799 (define_insn "udivsi3_i4"
1800   [(set (match_operand:SI 0 "register_operand" "=y")
1801         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1802    (clobber (reg:SI T_REG))
1803    (clobber (reg:SI PR_REG))
1804    (clobber (reg:DF DR0_REG))
1805    (clobber (reg:DF DR2_REG))
1806    (clobber (reg:DF DR4_REG))
1807    (clobber (reg:SI R0_REG))
1808    (clobber (reg:SI R1_REG))
1809    (clobber (reg:SI R4_REG))
1810    (clobber (reg:SI R5_REG))
1811    (use (reg:PSI FPSCR_REG))
1812    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1813   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1814   "jsr  @%1%#"
1815   [(set_attr "type" "sfunc")
1816    (set_attr "fp_mode" "double")
1817    (set_attr "needs_delay_slot" "yes")])
1819 (define_insn "udivsi3_i4_single"
1820   [(set (match_operand:SI 0 "register_operand" "=y")
1821         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1822    (clobber (reg:SI T_REG))
1823    (clobber (reg:SI PR_REG))
1824    (clobber (reg:DF DR0_REG))
1825    (clobber (reg:DF DR2_REG))
1826    (clobber (reg:DF DR4_REG))
1827    (clobber (reg:SI R0_REG))
1828    (clobber (reg:SI R1_REG))
1829    (clobber (reg:SI R4_REG))
1830    (clobber (reg:SI R5_REG))
1831    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1832   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1833   "jsr  @%1%#"
1834   [(set_attr "type" "sfunc")
1835    (set_attr "needs_delay_slot" "yes")])
1837 (define_insn "udivsi3_i4_int"
1838   [(set (match_operand:SI 0 "register_operand" "=z")
1839         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1840    (clobber (reg:SI T_REG))
1841    (clobber (reg:SI R1_REG))
1842    (clobber (reg:SI PR_REG))
1843    (clobber (reg:SI MACH_REG))
1844    (clobber (reg:SI MACL_REG))
1845    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1846   "TARGET_SH1"
1847   "jsr  @%1%#"
1848   [(set_attr "type" "sfunc")
1849    (set_attr "needs_delay_slot" "yes")])
1852 (define_expand "udivsi3"
1853   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1854    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1855    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1856    (parallel [(set (match_operand:SI 0 "register_operand" "")
1857                    (udiv:SI (reg:SI R4_REG)
1858                             (reg:SI R5_REG)))
1859               (clobber (reg:SI T_REG))
1860               (clobber (reg:SI PR_REG))
1861               (clobber (reg:SI R4_REG))
1862               (use (match_dup 3))])]
1863   ""
1864   "
1866   rtx last;
1868   operands[3] = gen_reg_rtx (Pmode);
1869   /* Emit the move of the address to a pseudo outside of the libcall.  */
1870   if (TARGET_DIVIDE_CALL_TABLE)
1871     {
1872       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1873          that causes problems when the divide code is supposed to come from a
1874          separate library.  Division by zero is undefined, so dividing 1 can be
1875          implemented by comparing with the divisor.  */
1876       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1877         {
1878           emit_insn (gen_cmpsi (operands[1], operands[2]));
1879           emit_insn (gen_sgeu (operands[0]));
1880           DONE;
1881         }
1882       else if (operands[2] == const0_rtx)
1883         {
1884           emit_move_insn (operands[0], operands[2]);
1885           DONE;
1886         }
1887       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1888       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1889     }
1890   else if (TARGET_DIVIDE_CALL_FP)
1891     {
1892       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1893       if (TARGET_FPU_SINGLE)
1894         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1895       else
1896         last = gen_udivsi3_i4 (operands[0], operands[3]);
1897     }
1898   else if (TARGET_SHMEDIA_FPU)
1899     {
1900       operands[1] = force_reg (SImode, operands[1]);
1901       operands[2] = force_reg (SImode, operands[2]);
1902       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1903       DONE;
1904     }
1905   else if (TARGET_SH2A)
1906     {
1907       operands[1] = force_reg (SImode, operands[1]);
1908       operands[2] = force_reg (SImode, operands[2]);
1909       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1910       DONE;
1911     }
1912   else if (TARGET_SH5)
1913     {
1914       function_symbol (operands[3],
1915                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1916                        SFUNC_STATIC);
1918       if (TARGET_SHMEDIA)
1919         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1920       else if (TARGET_FPU_ANY)
1921         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1922       else
1923         last = gen_udivsi3_i1 (operands[0], operands[3]);
1924     }
1925   else
1926     {
1927       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1928       last = gen_udivsi3_i1 (operands[0], operands[3]);
1929     }
1930   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1931   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1932   emit_insn (last);
1933   DONE;
1936 (define_insn "divsi3_sh2a"
1937   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1938         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1939                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1940   "TARGET_SH2A"
1941   "divs %2,%1"
1942   [(set_attr "type" "arith")
1943    (set_attr "in_delay_slot" "no")])
1945 (define_insn "divsi3_i1"
1946   [(set (match_operand:SI 0 "register_operand" "=z")
1947         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1948    (clobber (reg:SI T_REG))
1949    (clobber (reg:SI PR_REG))
1950    (clobber (reg:SI R1_REG))
1951    (clobber (reg:SI R2_REG))
1952    (clobber (reg:SI R3_REG))
1953    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1954   "TARGET_SH1 && ! TARGET_SH4"
1955   "jsr  @%1%#"
1956   [(set_attr "type" "sfunc")
1957    (set_attr "needs_delay_slot" "yes")])
1959 (define_insn "divsi3_i1_media"
1960   [(set (match_operand:SI 0 "register_operand" "=z")
1961         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1962    (clobber (reg:SI T_MEDIA_REG))
1963    (clobber (reg:SI PR_MEDIA_REG))
1964    (clobber (reg:SI R1_REG))
1965    (clobber (reg:SI R20_REG))
1966    (clobber (reg:SI R21_REG))
1967    (clobber (reg:SI TR0_REG))
1968    (use (match_operand 1 "target_reg_operand" "b"))]
1969   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1970   "blink        %1, r18"
1971   [(set_attr "type" "sfunc")])
1973 (define_insn "divsi3_media_2"
1974   [(set (match_operand:SI 0 "register_operand" "=z")
1975         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1976    (clobber (reg:SI T_MEDIA_REG))
1977    (clobber (reg:SI PR_MEDIA_REG))
1978    (clobber (reg:SI R1_REG))
1979    (clobber (reg:SI R21_REG))
1980    (clobber (reg:SI TR0_REG))
1981    (use (reg:SI R20_REG))
1982    (use (match_operand 1 "target_reg_operand" "b"))]
1983   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1984   "blink        %1, r18"
1985   [(set_attr "type" "sfunc")])
1987 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1988 ;; hard reg clobbers and data dependencies that we need when we want
1989 ;; to rematerialize the division into a call.
1990 (define_insn_and_split "divsi_inv_call"
1991   [(set (match_operand:SI 0 "register_operand" "=r")
1992         (div:SI (match_operand:SI 1 "register_operand" "r")
1993                 (match_operand:SI 2 "register_operand" "r")))
1994    (clobber (reg:SI R4_REG))
1995    (clobber (reg:SI R5_REG))
1996    (clobber (reg:SI T_MEDIA_REG))
1997    (clobber (reg:SI PR_MEDIA_REG))
1998    (clobber (reg:SI R1_REG))
1999    (clobber (reg:SI R21_REG))
2000    (clobber (reg:SI TR0_REG))
2001    (clobber (reg:SI R20_REG))
2002    (use (match_operand:SI 3 "register_operand" "r"))]
2003   "TARGET_SHMEDIA"
2004   "#"
2005   "&& (high_life_started || reload_completed)"
2006   [(set (match_dup 0) (match_dup 3))]
2007   ""
2008   [(set_attr "highpart" "must_split")])
2010 ;; This is the combiner pattern for -mdiv=inv:call .
2011 (define_insn_and_split "*divsi_inv_call_combine"
2012   [(set (match_operand:SI 0 "register_operand" "=z")
2013         (div:SI (match_operand:SI 1 "register_operand" "r")
2014                 (match_operand:SI 2 "register_operand" "r")))
2015    (clobber (reg:SI R4_REG))
2016    (clobber (reg:SI R5_REG))
2017    (clobber (reg:SI T_MEDIA_REG))
2018    (clobber (reg:SI PR_MEDIA_REG))
2019    (clobber (reg:SI R1_REG))
2020    (clobber (reg:SI R21_REG))
2021    (clobber (reg:SI TR0_REG))
2022    (clobber (reg:SI R20_REG))
2023    (use (unspec:SI [(match_dup 1)
2024                     (match_operand:SI 3 "" "")
2025                     (unspec:SI [(match_operand:SI 4 "" "")
2026                                 (match_dup 3)
2027                                 (match_operand:DI 5 "" "")]
2028                      UNSPEC_DIV_INV_M2)
2029                     (match_operand:DI 6 "" "")
2030                     (const_int 0)
2031                     (const_int 0)]
2032          UNSPEC_DIV_INV_M3))]
2033   "TARGET_SHMEDIA"
2034   "#"
2035   "&& (high_life_started || reload_completed)"
2036   [(pc)]
2037   "
2039   const char *name = sh_divsi3_libfunc;
2040   enum sh_function_kind kind = SFUNC_GOT;
2041   rtx sym;
2043   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
2044   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
2045   while (TARGET_DIVIDE_INV_CALL2)
2046     {
2047       rtx x = operands[3];
2049       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
2050         break;
2051       x = XVECEXP (x, 0, 0);
2052       name = \"__sdivsi3_2\";
2053       kind = SFUNC_STATIC;
2054       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
2055       break;
2056     }
2057   sym = function_symbol (NULL, name, kind);
2058   emit_insn (gen_divsi3_media_2 (operands[0], sym));
2059   DONE;
2061   [(set_attr "highpart" "must_split")])
2063 (define_expand "divsi3_i4_media"
2064   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
2065    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
2066    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
2067    (set (match_operand:SI 0 "register_operand" "=r")
2068         (fix:SI (match_dup 5)))]
2069   "TARGET_SHMEDIA_FPU"
2070   "
2072   operands[3] = gen_reg_rtx (DFmode);
2073   operands[4] = gen_reg_rtx (DFmode);
2074   operands[5] = gen_reg_rtx (DFmode);
2077 (define_insn "divsi3_i4"
2078   [(set (match_operand:SI 0 "register_operand" "=y")
2079         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2080    (clobber (reg:SI PR_REG))
2081    (clobber (reg:DF DR0_REG))
2082    (clobber (reg:DF DR2_REG))
2083    (use (reg:PSI FPSCR_REG))
2084    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2085   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
2086   "jsr  @%1%#"
2087   [(set_attr "type" "sfunc")
2088    (set_attr "fp_mode" "double")
2089    (set_attr "needs_delay_slot" "yes")])
2091 (define_insn "divsi3_i4_single"
2092   [(set (match_operand:SI 0 "register_operand" "=y")
2093         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2094    (clobber (reg:SI PR_REG))
2095    (clobber (reg:DF DR0_REG))
2096    (clobber (reg:DF DR2_REG))
2097    (clobber (reg:SI R2_REG))
2098    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2099   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
2100   "jsr  @%1%#"
2101   [(set_attr "type" "sfunc")
2102    (set_attr "needs_delay_slot" "yes")])
2104 (define_insn "divsi3_i4_int"
2105   [(set (match_operand:SI 0 "register_operand" "=z")
2106         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2107    (clobber (reg:SI T_REG))
2108    (clobber (reg:SI PR_REG))
2109    (clobber (reg:SI R1_REG))
2110    (clobber (reg:SI MACH_REG))
2111    (clobber (reg:SI MACL_REG))
2112    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2113   "TARGET_SH1"
2114   "jsr  @%1%#"
2115   [(set_attr "type" "sfunc")
2116    (set_attr "needs_delay_slot" "yes")])
2118 (define_expand "divsi3"
2119   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
2120    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2121    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2122    (parallel [(set (match_operand:SI 0 "register_operand" "")
2123                    (div:SI (reg:SI R4_REG)
2124                            (reg:SI R5_REG)))
2125               (clobber (reg:SI T_REG))
2126               (clobber (reg:SI PR_REG))
2127               (clobber (reg:SI R1_REG))
2128               (clobber (reg:SI R2_REG))
2129               (clobber (reg:SI R3_REG))
2130               (use (match_dup 3))])]
2131   ""
2132   "
2134   rtx last;
2136   operands[3] = gen_reg_rtx (Pmode);
2137   /* Emit the move of the address to a pseudo outside of the libcall.  */
2138   if (TARGET_DIVIDE_CALL_TABLE)
2139     {
2140       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2141       last = gen_divsi3_i4_int (operands[0], operands[3]);
2142     }
2143   else if (TARGET_DIVIDE_CALL_FP)
2144     {
2145       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2146       if (TARGET_FPU_SINGLE)
2147         last = gen_divsi3_i4_single (operands[0], operands[3]);
2148       else
2149         last = gen_divsi3_i4 (operands[0], operands[3]);
2150     }
2151   else if (TARGET_SH2A)
2152     {
2153       operands[1] = force_reg (SImode, operands[1]);
2154       operands[2] = force_reg (SImode, operands[2]);
2155       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2156       DONE;
2157     }
2158   else if (TARGET_DIVIDE_INV)
2159     {
2160       rtx dividend = operands[1];
2161       rtx divisor = operands[2];
2162       rtx tab_base;
2163       rtx nsb_res = gen_reg_rtx (DImode);
2164       rtx norm64 = gen_reg_rtx (DImode);
2165       rtx tab_ix = gen_reg_rtx (DImode);
2166       rtx norm32 = gen_reg_rtx (SImode);
2167       rtx i92 = force_reg (DImode, GEN_INT (92));
2168       rtx scratch0a = gen_reg_rtx (DImode);
2169       rtx scratch0b = gen_reg_rtx (DImode);
2170       rtx inv0 = gen_reg_rtx (SImode);
2171       rtx scratch1a = gen_reg_rtx (DImode);
2172       rtx scratch1b = gen_reg_rtx (DImode);
2173       rtx shift = gen_reg_rtx (DImode);
2174       rtx i2p27, i43;
2175       rtx inv1 = gen_reg_rtx (SImode);
2176       rtx scratch2a = gen_reg_rtx (DImode);
2177       rtx scratch2b = gen_reg_rtx (SImode);
2178       rtx inv2 = gen_reg_rtx (SImode);
2179       rtx scratch3a = gen_reg_rtx (DImode);
2180       rtx scratch3b = gen_reg_rtx (DImode);
2181       rtx scratch3c = gen_reg_rtx (DImode);
2182       rtx scratch3d = gen_reg_rtx (SImode);
2183       rtx scratch3e = gen_reg_rtx (DImode);
2184       rtx result = gen_reg_rtx (SImode);
2186       if (! arith_reg_or_0_operand (dividend, SImode))
2187         dividend = force_reg (SImode, dividend);
2188       if (! arith_reg_operand (divisor, SImode))
2189         divisor = force_reg (SImode, divisor);
2190       if (flag_pic && Pmode != DImode)
2191         {
2192           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2193           tab_base = gen_datalabel_ref (tab_base);
2194           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2195         }
2196       else
2197         {
2198           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2199           tab_base = gen_datalabel_ref (tab_base);
2200           tab_base = force_reg (DImode, tab_base);
2201         }
2202       if (TARGET_DIVIDE_INV20U)
2203         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2204       else
2205         i2p27 = GEN_INT (0);
2206       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2207         i43 = force_reg (DImode, GEN_INT (43));
2208       else
2209         i43 = GEN_INT (0);
2210       emit_insn (gen_nsbdi (nsb_res,
2211                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2212       emit_insn (gen_ashldi3_media (norm64,
2213                                     gen_rtx_SUBREG (DImode, divisor, 0),
2214                                     nsb_res));
2215       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2216       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2217       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2218                                    inv0, scratch0a, scratch0b,
2219                                    scratch1a, scratch1b));
2220       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2221       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2222                                    scratch2a));
2223       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2224                                    i2p27, i43,
2225                                    scratch3a, scratch3b, scratch3c,
2226                                    scratch2a, scratch2b, scratch3d, scratch3e));
2227       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2228         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2229       else if (TARGET_DIVIDE_INV_FP)
2230         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2231                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2232                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2233                                      gen_reg_rtx (DFmode)));
2234       else
2235         emit_move_insn (operands[0], result);
2236       DONE;
2237     }
2238   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2239     {
2240       operands[1] = force_reg (SImode, operands[1]);
2241       operands[2] = force_reg (SImode, operands[2]);
2242       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2243       DONE;
2244     }
2245   else if (TARGET_SH5)
2246     {
2247       if (TARGET_DIVIDE_CALL2)
2248         {
2249           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2250           tab_base = gen_datalabel_ref (tab_base);
2251           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2252         }
2253       if (TARGET_FPU_ANY && TARGET_SH1)
2254         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2255       else if (TARGET_DIVIDE_CALL2)
2256         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2257       else
2258         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2260       if (TARGET_SHMEDIA)
2261         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2262                 (operands[0], operands[3]));
2263       else if (TARGET_FPU_ANY)
2264         last = gen_divsi3_i4_single (operands[0], operands[3]);
2265       else
2266         last = gen_divsi3_i1 (operands[0], operands[3]);
2267     }
2268   else
2269     {
2270       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2271       last = gen_divsi3_i1 (operands[0], operands[3]);
2272     }
2273   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2274   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2275   emit_insn (last);
2276   DONE;
2279 ;; operands: scratch, tab_base, tab_ix
2280 ;; These are unspecs because we could generate an indexed addressing mode
2281 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2282 ;; confuse reload.  See PR27117.
2284 (define_insn "divsi_inv_qitable"
2285   [(set (match_operand:DI 0 "register_operand" "=r")
2286         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2287                                     (match_operand:DI 2 "register_operand" "r")]
2288                          UNSPEC_DIV_INV_TABLE)))]
2289   "TARGET_SHMEDIA"
2290   "@
2291         ldx.ub  %1, %2, %0"
2292   [(set_attr "type" "load_media")
2293    (set_attr "highpart" "user")])
2295 ;; operands: scratch, tab_base, tab_ix
2296 (define_insn "divsi_inv_hitable"
2297   [(set (match_operand:DI 0 "register_operand" "=r")
2298         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2299                                     (match_operand:DI 2 "register_operand" "r")]
2300                          UNSPEC_DIV_INV_TABLE)))]
2301   "TARGET_SHMEDIA"
2302   "@
2303         ldx.w   %1, %2, %0"
2304   [(set_attr "type" "load_media")
2305    (set_attr "highpart" "user")])
2307 ;; operands: inv0, tab_base, tab_ix, norm32
2308 ;; scratch equiv in sdivsi3_2: r19, r21
2309 (define_expand "divsi_inv_m0"
2310   [(set (match_operand:SI 0 "register_operand" "=r")
2311         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2312                     (match_operand:DI 2 "register_operand" "r")
2313                     (match_operand:SI 3 "register_operand" "r")]
2314          UNSPEC_DIV_INV_M0))
2315    (clobber (match_operand:DI 4 "register_operand" "=r"))
2316    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2317   "TARGET_SHMEDIA"
2318   "
2321 tab_base: r20
2322 tab_ix: r21
2323 norm32: r25
2324  ldx.ub r20, r21, r19 // u0.8
2325  shlli r21, 1, r21
2326  muls.l r25, r19, r19 // s2.38
2327  ldx.w r20, r21, r21  // s2.14
2328  shari r19, 24, r19   // truncate to s2.14
2329  sub r21, r19, r19    // some 11 bit inverse in s1.14
2332   rtx inv0 = operands[0];
2333   rtx tab_base = operands[1];
2334   rtx tab_ix = operands[2];
2335   rtx norm32 = operands[3];
2336   rtx scratch0 = operands[4];
2337   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2338   rtx scratch1 = operands[5];
2340   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2341   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2342   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2343   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2344   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2345   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2346   DONE;
2349 ;; operands: inv1, tab_base, tab_ix, norm32
2350 (define_insn_and_split "divsi_inv_m1"
2351   [(set (match_operand:SI 0 "register_operand" "=r")
2352         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2353                     (match_operand:DI 2 "register_operand" "r")
2354                     (match_operand:SI 3 "register_operand" "r")]
2355          UNSPEC_DIV_INV_M1))
2356    (clobber (match_operand:SI 4 "register_operand" "=r"))
2357    (clobber (match_operand:DI 5 "register_operand" "=r"))
2358    (clobber (match_operand:DI 6 "register_operand" "=r"))
2359    (clobber (match_operand:DI 7 "register_operand" "=r"))
2360    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2361   "TARGET_SHMEDIA"
2362   "#"
2363   "&& !can_create_pseudo_p ()"
2364   [(pc)]
2365   "
2367 /* inv0: r19
2368  muls.l r19, r19, r18 // u0.28
2369  muls.l r25, r18, r18 // s2.58
2370  shlli r19, 45, r0    // multiply by two and convert to s2.58
2371  sub r0, r18, r18
2372  shari r18, 28, r18   // some 18 bit inverse in s1.30
2375   rtx inv1 = operands[0];
2376   rtx tab_base = operands[1];
2377   rtx tab_ix = operands[2];
2378   rtx norm32 = operands[3];
2379   rtx inv0 = operands[4];
2380   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2381   rtx scratch0a = operands[5];
2382   rtx scratch0b = operands[6];
2383   rtx scratch0 = operands[7];
2384   rtx scratch1 = operands[8];
2385   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2387   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2388                                scratch0a, scratch0b));
2389   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2390   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2391   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2392   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2393   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2394   DONE;
2397 ;; operands: inv2, norm32, inv1, i92
2398 (define_insn_and_split "divsi_inv_m2"
2399   [(set (match_operand:SI 0 "register_operand" "=r")
2400         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2401                     (match_operand:SI 2 "register_operand" "r")
2402                     (match_operand:DI 3 "register_operand" "r")]
2403          UNSPEC_DIV_INV_M2))
2404    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2405   "TARGET_SHMEDIA"
2406   "#"
2407   "&& !can_create_pseudo_p ()"
2408   [(pc)]
2409   "
2412  muls.l r18, r25, r0  // s2.60
2413  shari r0, 16, r0     // s-16.44
2414   sub
2415  muls.l r0, r18, r19  // s-16.74
2416  shari r19, 30, r19   // s-16.44
2418   rtx inv2 = operands[0];
2419   rtx norm32 = operands[1];
2420   rtx inv1 = operands[2];
2421   rtx i92 = operands[3];
2422   rtx scratch0 = operands[4];
2423   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2425   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2426   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2427   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2428   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2429   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2430   DONE;
2433 (define_insn_and_split "divsi_inv_m3"
2434   [(set (match_operand:SI 0 "register_operand" "=r")
2435         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2436                     (match_operand:SI 2 "register_operand" "r")
2437                     (match_operand:SI 3 "register_operand" "r")
2438                     (match_operand:DI 4 "register_operand" "r")
2439                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2440                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2441          UNSPEC_DIV_INV_M3))
2442    (clobber (match_operand:DI 7 "register_operand" "=r"))
2443    (clobber (match_operand:DI 8 "register_operand" "=r"))
2444    (clobber (match_operand:DI 9 "register_operand" "=r"))
2445    (clobber (match_operand:DI 10 "register_operand" "=r"))
2446    (clobber (match_operand:SI 11 "register_operand" "=r"))
2447    (clobber (match_operand:SI 12 "register_operand" "=r"))
2448    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2449   "TARGET_SHMEDIA"
2450   "#"
2451   "&& !can_create_pseudo_p ()"
2452   [(pc)]
2453   "
2456   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2457   r0: scratch0  r19: scratch1 r21: scratch2
2459   muls.l r18, r4, r25 // s32.30
2460  muls.l r19, r4, r19  // s15.30
2461  shari r25, 63, r21
2462   shari r19, 14, r19  // s18.-14
2463  sub r25, r19, r0
2464  shard r0, r1, r0
2465  sub r0, r21, r0
2468   rtx result = operands[0];
2469   rtx dividend = operands[1];
2470   rtx inv1 = operands[2];
2471   rtx inv2 = operands[3];
2472   rtx shift = operands[4];
2473   rtx scratch0 = operands[7];
2474   rtx scratch1 = operands[8];
2475   rtx scratch2 = operands[9];
2477   if (satisfies_constraint_N (dividend))
2478     {
2479       emit_move_insn (result, dividend);
2480       DONE;
2481     }
2483   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2484   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2485   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2486   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2487   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2488   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2489   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2490   DONE;
2493 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2494 ;; inv1: tab_base, tab_ix, norm32
2495 ;; inv2: norm32, inv1, i92
2496 (define_insn_and_split "divsi_inv_m1_3"
2497   [(set (match_operand:SI 0 "register_operand" "=r")
2498         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2499                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2500                                 (match_operand:DI 3 "register_operand" "r")
2501                                 (match_operand:SI 4 "register_operand" "r")]
2502                      UNSPEC_DIV_INV_M1)
2503                     (unspec:SI [(match_dup 4)
2504                                 (unspec:SI [(match_dup 2)
2505                                             (match_dup 3)
2506                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2507                                 (match_operand:SI 5 "" "")]
2508                      UNSPEC_DIV_INV_M2)
2509                     (match_operand:DI 6 "register_operand" "r")
2510                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2511                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2512          UNSPEC_DIV_INV_M3))
2513    (clobber (match_operand:DI 9 "register_operand" "=r"))
2514    (clobber (match_operand:DI 10 "register_operand" "=r"))
2515    (clobber (match_operand:DI 11 "register_operand" "=r"))
2516    (clobber (match_operand:DI 12 "register_operand" "=r"))
2517    (clobber (match_operand:SI 13 "register_operand" "=r"))
2518    (clobber (match_operand:SI 14 "register_operand" "=r"))
2519    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2520   "TARGET_SHMEDIA
2521    && (TARGET_DIVIDE_INV_MINLAT
2522        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2523   "#"
2524   "&& !can_create_pseudo_p ()"
2525   [(pc)]
2526   "
2528   rtx result = operands[0];
2529   rtx dividend = operands[1];
2530   rtx tab_base = operands[2];
2531   rtx tab_ix = operands[3];
2532   rtx norm32 = operands[4];
2533   /* rtx i92 = operands[5]; */
2534   rtx shift = operands[6];
2535   rtx i2p27 = operands[7];
2536   rtx i43 = operands[8];
2537   rtx scratch0 = operands[9];
2538   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2539   rtx scratch1 = operands[10];
2540   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2541   rtx scratch2 = operands[11];
2542   rtx scratch3 = operands[12];
2543   rtx scratch4 = operands[13];
2544   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2545   rtx scratch5 = operands[14];
2546   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2547   rtx scratch6 = operands[15];
2549   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2550                                scratch0, scratch1));
2551   /* inv0 == scratch4 */
2552   if (! TARGET_DIVIDE_INV20U)
2553     {
2554       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2555       i2p27 = scratch0;
2556       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2557     }
2558   else
2559     {
2560       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2561       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2562     }
2563   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2564   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2565   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2566   /* inv1 == scratch4 */
2568   if (TARGET_DIVIDE_INV_MINLAT)
2569     {
2570       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2571       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2572       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2573       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2574       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2575       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2576       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2577       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2578       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2579       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2580       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2581     }
2582   else
2583     {
2584       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2585       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2586       emit_insn (gen_nsbdi (scratch6,
2587                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2588       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2589       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2590       emit_insn (gen_divsi_inv20 (scratch2,
2591                                   norm32, scratch4, dividend,
2592                                   scratch6, scratch3, i43,
2593                                   /* scratch0 may be shared with i2p27.  */
2594                                   scratch0, scratch1, scratch5,
2595                                   label, label, i2p27));
2596     }
2597   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2598   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2599   DONE;
2602 (define_insn "divsi_inv20"
2603   [(set (match_operand:DI 0 "register_operand" "=&r")
2604         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2605                     (match_operand:SI 2 "register_operand" "r")
2606                     (match_operand:SI 3 "register_operand" "r")
2607                     (match_operand:DI 4 "register_operand" "r")
2608                     (match_operand:DI 5 "register_operand" "r")
2609                     (match_operand:DI 6 "register_operand" "r")
2610                     (match_operand:DI 12 "register_operand" "r")
2611                     (match_operand 10 "target_operand" "b")
2612                     (match_operand 11 "immediate_operand" "i")]
2613          UNSPEC_DIV_INV20))
2614    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2615    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2616    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2617   "TARGET_SHMEDIA
2618    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2619   "*
2621 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2622              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2623              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2624              %10 label (tr), %11 label (imm)
2626  muls.l inv1, norm32, scratch0  // s2.60
2627   muls.l inv1, dividend, result // s32.30
2628   xor i2p27, result_sign, round_scratch
2629  bge/u dividend_nsb, i43, tr.. (label)
2630  shari scratch0, 16, scratch0   // s-16.44
2631  muls.l sratch0_si, inv1, scratch0 // s-16.74
2632   sub result, round_scratch, result
2633   shari dividend, 14, scratch1   // s19.-14
2634  shari scratch0, 30, scratch0   // s-16.44
2635  muls.l scratch0, scratch1, round_scratch // s15.30
2636 label:
2637  sub result, round_scratch, result */
2639   int likely = TARGET_DIVIDE_INV20L;
2641   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2642   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2643   output_asm_insn (likely
2644                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2645                    : \"bge/u\t%4, %6, %10\", operands);
2646   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2647   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2648   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2649   return (likely
2650           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2651           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2654 (define_insn_and_split "divsi_inv_fp"
2655   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2656         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2657                 (match_operand:SI 2 "register_operand" "rf")))
2658    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2659    (clobber (match_operand:SI 4 "register_operand" "=r"))
2660    (clobber (match_operand:SI 5 "register_operand" "=r"))
2661    (clobber (match_operand:DF 6 "register_operand" "=r"))
2662    (clobber (match_operand:DF 7 "register_operand" "=r"))
2663    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2664   "TARGET_SHMEDIA_FPU"
2665   "#"
2666   "&& (high_life_started || reload_completed)"
2667   [(set (match_dup 0) (match_dup 3))]
2668   ""
2669   [(set_attr "highpart" "must_split")])
2671 ;; If a matching group of divide-by-inverse instructions is in the same
2672 ;; basic block after gcse & loop optimizations, we want to transform them
2673 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2674 (define_insn_and_split "*divsi_inv_fp_combine"
2675   [(set (match_operand:SI 0 "register_operand" "=f")
2676         (div:SI (match_operand:SI 1 "register_operand" "f")
2677                 (match_operand:SI 2 "register_operand" "f")))
2678    (use (unspec:SI [(match_dup 1)
2679                     (match_operand:SI 3 "" "")
2680                     (unspec:SI [(match_operand:SI 4 "" "")
2681                                 (match_dup 3)
2682                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2683                     (match_operand:DI 6 "" "")
2684                     (const_int 0)
2685                     (const_int 0)] UNSPEC_DIV_INV_M3))
2686    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2687    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2688    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2689    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2690    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2691   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2692   "#"
2693   "&& 1"
2694   [(set (match_dup 9) (float:DF (match_dup 1)))
2695    (set (match_dup 10) (float:DF (match_dup 2)))
2696    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2697    (set (match_dup 8)
2698         (fix:SI (match_dup 11)))
2699    (set (match_dup 0) (match_dup 8))]
2700   "
2702   if (! fp_arith_reg_operand (operands[1], SImode))
2703     {
2704       emit_move_insn (operands[7], operands[1]);
2705       operands[1] = operands[7];
2706     }
2707   if (! fp_arith_reg_operand (operands[2], SImode))
2708     {
2709       emit_move_insn (operands[8], operands[2]);
2710       operands[2] = operands[8];
2711     }
2713   [(set_attr "highpart" "must_split")])
2715 ;; -------------------------------------------------------------------------
2716 ;; Multiplication instructions
2717 ;; -------------------------------------------------------------------------
2719 (define_insn "umulhisi3_i"
2720   [(set (reg:SI MACL_REG)
2721         (mult:SI (zero_extend:SI
2722                   (match_operand:HI 0 "arith_reg_operand" "r"))
2723                  (zero_extend:SI
2724                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2725   "TARGET_SH1"
2726   "mulu.w       %1,%0"
2727   [(set_attr "type" "smpy")])
2729 (define_insn "mulhisi3_i"
2730   [(set (reg:SI MACL_REG)
2731         (mult:SI (sign_extend:SI
2732                   (match_operand:HI 0 "arith_reg_operand" "r"))
2733                  (sign_extend:SI
2734                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2735   "TARGET_SH1"
2736   "muls.w       %1,%0"
2737   [(set_attr "type" "smpy")])
2739 (define_expand "mulhisi3"
2740   [(set (reg:SI MACL_REG)
2741         (mult:SI (sign_extend:SI
2742                   (match_operand:HI 1 "arith_reg_operand" ""))
2743                  (sign_extend:SI
2744                   (match_operand:HI 2 "arith_reg_operand" ""))))
2745    (set (match_operand:SI 0 "arith_reg_operand" "")
2746         (reg:SI MACL_REG))]
2747   "TARGET_SH1"
2748   "
2750   rtx insn, macl;
2752   macl = gen_rtx_REG (SImode, MACL_REG);
2753   start_sequence ();
2754   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2755   insn = get_insns ();  
2756   end_sequence ();
2757   /* expand_binop can't find a suitable code in umul_widen_optab to
2758      make a REG_EQUAL note from, so make one here.
2759      See also smulsi3_highpart.
2760      ??? Alternatively, we could put this at the calling site of expand_binop,
2761      i.e. expand_expr.  */
2762   /* Use emit_libcall_block for loop invariant code motion and to make
2763      a REG_EQUAL note.  */
2764   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2766   DONE;
2769 (define_expand "umulhisi3"
2770   [(set (reg:SI MACL_REG)
2771         (mult:SI (zero_extend:SI
2772                   (match_operand:HI 1 "arith_reg_operand" ""))
2773                  (zero_extend:SI
2774                   (match_operand:HI 2 "arith_reg_operand" ""))))
2775    (set (match_operand:SI 0 "arith_reg_operand" "")
2776         (reg:SI MACL_REG))]
2777   "TARGET_SH1"
2778   "
2780   rtx insn, macl;
2782   macl = gen_rtx_REG (SImode, MACL_REG);
2783   start_sequence ();
2784   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2785   insn = get_insns ();  
2786   end_sequence ();
2787   /* expand_binop can't find a suitable code in umul_widen_optab to
2788      make a REG_EQUAL note from, so make one here.
2789      See also smulsi3_highpart.
2790      ??? Alternatively, we could put this at the calling site of expand_binop,
2791      i.e. expand_expr.  */
2792   /* Use emit_libcall_block for loop invariant code motion and to make
2793      a REG_EQUAL note.  */
2794   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2796   DONE;
2799 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2800 ;; a call to a routine which clobbers known registers.
2802 (define_insn ""
2803   [(set (match_operand:SI 1 "register_operand" "=z")
2804         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2805    (clobber (reg:SI MACL_REG))
2806    (clobber (reg:SI T_REG))
2807    (clobber (reg:SI PR_REG))
2808    (clobber (reg:SI R3_REG))
2809    (clobber (reg:SI R2_REG))
2810    (clobber (reg:SI R1_REG))
2811    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2812   "TARGET_SH1"
2813   "jsr  @%0%#"
2814   [(set_attr "type" "sfunc")
2815    (set_attr "needs_delay_slot" "yes")])
2817 (define_expand "mulsi3_call"
2818   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2819    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2820    (parallel[(set (match_operand:SI 0 "register_operand" "")
2821                   (mult:SI (reg:SI R4_REG)
2822                            (reg:SI R5_REG)))
2823              (clobber (reg:SI MACL_REG))
2824              (clobber (reg:SI T_REG))
2825              (clobber (reg:SI PR_REG))
2826              (clobber (reg:SI R3_REG))
2827              (clobber (reg:SI R2_REG))
2828              (clobber (reg:SI R1_REG))
2829              (use (match_operand:SI 3 "register_operand" ""))])]
2830   "TARGET_SH1"
2831   "")
2833 (define_insn "mul_r"
2834   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2835         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2836                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2837   "TARGET_SH2A"
2838   "mulr %2,%0"
2839   [(set_attr "type" "dmpy")])
2841 (define_insn "mul_l"
2842   [(set (reg:SI MACL_REG)
2843         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2844                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2845   "TARGET_SH2"
2846   "mul.l        %1,%0"
2847   [(set_attr "type" "dmpy")])
2849 (define_expand "mulsi3"
2850   [(set (reg:SI MACL_REG)
2851         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2852                   (match_operand:SI 2 "arith_reg_operand" "")))
2853    (set (match_operand:SI 0 "arith_reg_operand" "")
2854         (reg:SI MACL_REG))]
2855   "TARGET_SH1"
2856   "
2858   if (!TARGET_SH2)
2859     {
2860       /* The address must be set outside the libcall,
2861          since it goes into a pseudo.  */
2862       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2863       rtx addr = force_reg (SImode, sym);
2864       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2865                                    operands[2], addr);
2866       emit_insn (insns);
2867     }
2868   else
2869     {
2870       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2872       emit_insn (gen_mul_l (operands[1], operands[2]));
2873       /* consec_sets_giv can only recognize the first insn that sets a
2874          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2875          note.  */
2876       emit_insn (gen_movsi_i ((operands[0]), macl));
2877     }
2878   DONE;
2881 (define_insn "mulsidi3_i"
2882   [(set (reg:SI MACH_REG)
2883         (truncate:SI
2884          (lshiftrt:DI
2885           (mult:DI
2886            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2887            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2888           (const_int 32))))
2889    (set (reg:SI MACL_REG)
2890         (mult:SI (match_dup 0)
2891                  (match_dup 1)))]
2892   "TARGET_SH2"
2893   "dmuls.l      %1,%0"
2894   [(set_attr "type" "dmpy")])
2896 (define_expand "mulsidi3"
2897   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2898         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2899                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2900   "TARGET_SH2 || TARGET_SHMEDIA"
2901   "
2903   if (TARGET_SH2)
2904     {
2905        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2906                                         operands[2]));
2907        DONE;
2908     }
2911 (define_insn "mulsidi3_media"
2912   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2913         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2914                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2915   "TARGET_SHMEDIA"
2916   "muls.l       %1, %2, %0"
2917   [(set_attr "type" "dmpy_media")
2918    (set_attr "highpart" "ignore")])
2920 (define_insn "mulsidi3_compact"
2921   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2922         (mult:DI
2923          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2924          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2925    (clobber (reg:SI MACH_REG))
2926    (clobber (reg:SI MACL_REG))]
2927   "TARGET_SH2"
2928   "#")
2930 (define_split
2931   [(set (match_operand:DI 0 "arith_reg_dest" "")
2932         (mult:DI
2933          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2934          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2935    (clobber (reg:SI MACH_REG))
2936    (clobber (reg:SI MACL_REG))]
2937   "TARGET_SH2"
2938   [(const_int 0)]
2939   "
2941   rtx low_dst = gen_lowpart (SImode, operands[0]);
2942   rtx high_dst = gen_highpart (SImode, operands[0]);
2944   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2946   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2947   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2948   /* We need something to tag the possible REG_EQUAL notes on to.  */
2949   emit_move_insn (operands[0], operands[0]);
2950   DONE;
2953 (define_insn "umulsidi3_i"
2954   [(set (reg:SI MACH_REG)
2955         (truncate:SI
2956          (lshiftrt:DI
2957           (mult:DI
2958            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2959            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2960           (const_int 32))))
2961    (set (reg:SI MACL_REG)
2962         (mult:SI (match_dup 0)
2963                  (match_dup 1)))]
2964   "TARGET_SH2"
2965   "dmulu.l      %1,%0"
2966   [(set_attr "type" "dmpy")])
2968 (define_expand "umulsidi3"
2969   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2970         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2971                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2972   "TARGET_SH2 || TARGET_SHMEDIA"
2973   "
2975   if (TARGET_SH2)
2976     {
2977        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2978                                          operands[2]));
2979        DONE;
2980     }
2983 (define_insn "umulsidi3_media"
2984   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2985         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2986                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2987   "TARGET_SHMEDIA"
2988   "mulu.l       %1, %2, %0"
2989   [(set_attr "type" "dmpy_media")
2990    (set_attr "highpart" "ignore")])
2992 (define_insn "umulsidi3_compact"
2993   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2994         (mult:DI
2995          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2996          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2997    (clobber (reg:SI MACH_REG))
2998    (clobber (reg:SI MACL_REG))]
2999   "TARGET_SH2"
3000   "#")
3002 (define_split
3003   [(set (match_operand:DI 0 "arith_reg_dest" "")
3004         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3005                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
3006    (clobber (reg:SI MACH_REG))
3007    (clobber (reg:SI MACL_REG))]
3008   "TARGET_SH2"
3009   [(const_int 0)]
3010   "
3012   rtx low_dst = gen_lowpart (SImode, operands[0]);
3013   rtx high_dst = gen_highpart (SImode, operands[0]);
3015   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
3017   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
3018   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
3019   /* We need something to tag the possible REG_EQUAL notes on to.  */
3020   emit_move_insn (operands[0], operands[0]);
3021   DONE;
3024 (define_insn "smulsi3_highpart_i"
3025   [(set (reg:SI MACH_REG)
3026         (truncate:SI
3027          (lshiftrt:DI
3028           (mult:DI
3029            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3030            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3031           (const_int 32))))
3032    (clobber (reg:SI MACL_REG))]
3033   "TARGET_SH2"
3034   "dmuls.l      %1,%0"
3035   [(set_attr "type" "dmpy")])
3037 (define_expand "smulsi3_highpart"
3038   [(parallel
3039     [(set (reg:SI MACH_REG)
3040           (truncate:SI
3041            (lshiftrt:DI
3042             (mult:DI
3043              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3044              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3045             (const_int 32))))
3046     (clobber (reg:SI MACL_REG))])
3047    (set (match_operand:SI 0 "arith_reg_operand" "")
3048         (reg:SI MACH_REG))]
3049   "TARGET_SH2"
3050   "
3052   rtx insn, mach;
3054   mach = gen_rtx_REG (SImode, MACH_REG);
3055   start_sequence ();
3056   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
3057   insn = get_insns ();  
3058   end_sequence ();
3059   /* expand_binop can't find a suitable code in mul_highpart_optab to
3060      make a REG_EQUAL note from, so make one here.
3061      See also {,u}mulhisi.
3062      ??? Alternatively, we could put this at the calling site of expand_binop,
3063      i.e. expand_mult_highpart.  */
3064   /* Use emit_libcall_block for loop invariant code motion and to make
3065      a REG_EQUAL note.  */
3066   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3068   DONE;
3071 (define_insn "umulsi3_highpart_i"
3072   [(set (reg:SI MACH_REG)
3073         (truncate:SI
3074          (lshiftrt:DI
3075           (mult:DI
3076            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
3077            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
3078           (const_int 32))))
3079    (clobber (reg:SI MACL_REG))]
3080   "TARGET_SH2"
3081   "dmulu.l      %1,%0"
3082   [(set_attr "type" "dmpy")])
3084 (define_expand "umulsi3_highpart"
3085   [(parallel
3086     [(set (reg:SI MACH_REG)
3087           (truncate:SI
3088            (lshiftrt:DI
3089             (mult:DI
3090              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
3091              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
3092             (const_int 32))))
3093     (clobber (reg:SI MACL_REG))])
3094    (set (match_operand:SI 0 "arith_reg_operand" "")
3095         (reg:SI MACH_REG))]
3096   "TARGET_SH2"
3097   "
3099   rtx insn, mach;
3101   mach = gen_rtx_REG (SImode, MACH_REG);
3102   start_sequence ();
3103   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
3104   insn = get_insns ();  
3105   end_sequence ();
3106   /* Use emit_libcall_block for loop invariant code motion and to make
3107      a REG_EQUAL note.  */
3108   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
3110   DONE;
3113 (define_insn_and_split "muldi3"
3114   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3115         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
3116                  (match_operand:DI 2 "arith_reg_operand" "r")))
3117    (clobber (match_scratch:DI 3 "=&r"))
3118    (clobber (match_scratch:DI 4 "=r"))]
3119   "TARGET_SHMEDIA"
3120   "#"
3121   "reload_completed"
3122   [(const_int 0)]
3123   "
3125   rtx op3_v2si, op2_v2si;
3127   op3_v2si = operands[3];
3128   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
3129     {
3130       op3_v2si = XEXP (op3_v2si, 0);
3131       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
3132     }
3133   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
3134   op2_v2si = operands[2];
3135   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
3136     {
3137       op2_v2si = XEXP (op2_v2si, 0);
3138       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3139     }
3140   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3141   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3142   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3143   emit_insn (gen_umulsidi3_media (operands[4],
3144                                  sh_gen_truncate (SImode, operands[1], 0),
3145                                  sh_gen_truncate (SImode, operands[2], 0)));
3146   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3147   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3148   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3149   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3150   DONE;
3154 ;; -------------------------------------------------------------------------
3155 ;; Logical operations
3156 ;; -------------------------------------------------------------------------
3158 (define_insn "*andsi3_compact"
3159   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3160         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3161                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3162   "TARGET_SH1"
3163   "and  %2,%0"
3164   [(set_attr "type" "arith")])
3166 (define_insn "*andsi3_media"
3167   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3168         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3169                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3170   "TARGET_SHMEDIA"
3171   "@
3172         and     %1, %2, %0
3173         andi    %1, %2, %0"
3174   [(set_attr "type" "arith_media")])
3176 (define_insn "*andsi3_bclr"
3177   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3178         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3179                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3180   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3181   "bclr\\t%W2,%0"
3182   [(set_attr "type" "arith")])
3184 ;; If the constant is 255, then emit an extu.b instruction instead of an
3185 ;; and, since that will give better code.
3187 (define_expand "andsi3"
3188   [(set (match_operand:SI 0 "arith_reg_operand" "")
3189         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3190                 (match_operand:SI 2 "logical_operand" "")))]
3191   ""
3192   "
3194   if (TARGET_SH1
3195       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3196     {
3197       emit_insn (gen_zero_extendqisi2 (operands[0],
3198                                        gen_lowpart (QImode, operands[1])));
3199       DONE;
3200     }
3203 (define_insn_and_split "anddi3"
3204   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3205         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3206                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3207   "TARGET_SHMEDIA"
3208   "@
3209         and     %1, %2, %0
3210         andi    %1, %2, %0
3211         #"
3212   "reload_completed
3213    && ! logical_operand (operands[2], DImode)"
3214   [(const_int 0)]
3215   "
3217   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3218     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3219   else
3220     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3221   DONE;
3223   [(set_attr "type" "arith_media")])
3225 (define_insn "andcsi3"
3226   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3227         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3228                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3229   "TARGET_SHMEDIA"
3230   "andc %1,%2,%0"
3231   [(set_attr "type" "arith_media")])
3233 (define_insn "andcdi3"
3234   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3235         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3236                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3237   "TARGET_SHMEDIA"
3238   "andc %1,%2,%0"
3239   [(set_attr "type" "arith_media")])
3241 (define_expand "iorsi3"
3242   [(set (match_operand:SI 0 "arith_reg_operand" "")
3243         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3244                 (match_operand:SI 2 "logical_operand" "")))]
3245   ""
3246   "")
3248 (define_insn "*iorsi3_compact"
3249   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3250         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3251                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3252   "TARGET_SH1
3253    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3254   "or   %2,%0"
3255   [(set_attr "type" "arith")])
3257 (define_insn "*iorsi3_media"
3258   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3259         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3260                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3261   "TARGET_SHMEDIA"
3262   "@
3263         or      %1, %2, %0
3264         ori     %1, %2, %0"
3265   [(set_attr "type" "arith_media")])
3267 (define_insn "*iorsi3_bset"
3268   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3269         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3270         (match_operand:SI 2 "const_int_operand" "Pso")))]
3271   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3272   "bset\\t%V2,%0"
3273   [(set_attr "type" "arith")])
3275 (define_insn "iordi3"
3276   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3277         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3278                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3279   "TARGET_SHMEDIA"
3280   "@
3281         or      %1, %2, %0
3282         ori     %1, %2, %0"
3283   [(set_attr "type" "arith_media")])
3285 (define_insn_and_split "*logical_sidi3"
3286   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3287         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3288                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3289                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3290   "TARGET_SHMEDIA"
3291   "#"
3292   "&& reload_completed"
3293   [(set (match_dup 0) (match_dup 3))]
3294   "
3296   operands[3]
3297     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3298                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3299                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3302 (define_insn_and_split "*logical_sidisi3"
3303   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3304         (truncate:SI (sign_extend:DI
3305                         (match_operator:SI 3 "logical_operator"
3306                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3307                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3308   "TARGET_SHMEDIA"
3309   "#"
3310   "&& 1"
3311   [(set (match_dup 0) (match_dup 3))])
3313 (define_insn_and_split "*logical_sidi3_2"
3314   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3315         (sign_extend:DI (truncate:SI (sign_extend:DI
3316                         (match_operator:SI 3 "logical_operator"
3317                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3318                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3319   "TARGET_SHMEDIA"
3320   "#"
3321   "&& 1"
3322   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3324 (define_expand "xorsi3"
3325   [(set (match_operand:SI 0 "arith_reg_operand" "")
3326         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3327                 (match_operand:SI 2 "xor_operand" "")))]
3328   ""
3329   "")
3331 (define_insn "*xorsi3_compact"
3332   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3333         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3334                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3335   "TARGET_SH1"
3336   "xor  %2,%0"
3337   [(set_attr "type" "arith")])
3339 (define_insn "*xorsi3_media"
3340   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3341         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3342                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3343   "TARGET_SHMEDIA"
3344   "@
3345         xor     %1, %2, %0
3346         xori    %1, %2, %0"
3347   [(set_attr "type" "arith_media")])
3349 ;; Store the complements of the T bit in a register.
3350 (define_insn "xorsi3_movrt"
3351   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3352         (xor:SI (reg:SI T_REG)
3353                 (const_int 1)))]
3354   "TARGET_SH2A"
3355   "movrt\\t%0"
3356   [(set_attr "type" "arith")])
3358 (define_insn "xordi3"
3359   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3360         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3361                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3362   "TARGET_SHMEDIA"
3363   "@
3364         xor     %1, %2, %0
3365         xori    %1, %2, %0"
3366   [(set_attr "type" "arith_media")])
3368 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3369 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3370 (define_split
3371   [(set (match_operand:DI 0 "arith_reg_dest" "")
3372         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3373                           [(match_operand 1 "any_register_operand" "")
3374                            (match_operand 2 "any_register_operand" "")])))]
3375   "TARGET_SHMEDIA"
3376   [(set (match_dup 5) (match_dup 4))
3377    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3380   enum machine_mode inmode = GET_MODE (operands[1]);
3381   int offset = 0;
3383   if (GET_CODE (operands[0]) == SUBREG)
3384     {
3385       offset = SUBREG_BYTE (operands[0]);
3386       operands[0] = SUBREG_REG (operands[0]);
3387     }
3388   gcc_assert (GET_CODE (operands[0]) == REG);
3389   if (! TARGET_LITTLE_ENDIAN)
3390     offset += 8 - GET_MODE_SIZE (inmode);
3391   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3394 ;; -------------------------------------------------------------------------
3395 ;; Shifts and rotates
3396 ;; -------------------------------------------------------------------------
3398 (define_expand "rotldi3"
3399   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3400         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3401                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3402   "TARGET_SHMEDIA"
3403   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3405 (define_insn "rotldi3_mextr"
3406   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3407         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3408                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3409   "TARGET_SHMEDIA"
3410   "*
3412   static char templ[16];
3414   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3415            8 - (int) (INTVAL (operands[2]) >> 3));
3416   return templ;
3418   [(set_attr "type" "arith_media")])
3420 (define_expand "rotrdi3"
3421   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3422         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3423                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3424   "TARGET_SHMEDIA"
3425   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3427 (define_insn "rotrdi3_mextr"
3428   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3429         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3430                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3431   "TARGET_SHMEDIA"
3432   "*
3434   static char templ[16];
3436   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3437   return templ;
3439   [(set_attr "type" "arith_media")])
3441 (define_split
3442   [(set (match_operand:DI 0 "arith_reg_dest" "")
3443         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3444                                          "ua_address_operand" "")))
3445                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3446                            (const_int 8))))
3447    (clobber (match_operand:DI 3 "register_operand" ""))]
3448   "TARGET_SHMEDIA"
3449   [(match_dup 4) (match_dup 5)]
3450   "
3452   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3453                  (operands[3], operands[1]));
3454   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3455                               GEN_INT (56), GEN_INT (8));
3458 (define_insn "rotlsi3_1"
3459   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3460         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3461                    (const_int 1)))
3462    (set (reg:SI T_REG)
3463         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3464   "TARGET_SH1"
3465   "rotl %0"
3466   [(set_attr "type" "arith")])
3468 (define_insn "rotlsi3_31"
3469   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3470         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3471                    (const_int 31)))
3472    (clobber (reg:SI T_REG))]
3473   "TARGET_SH1"
3474   "rotr %0"
3475   [(set_attr "type" "arith")])
3477 (define_insn "rotlsi3_16"
3478   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3479         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3480                    (const_int 16)))]
3481   "TARGET_SH1"
3482   "swap.w       %1,%0"
3483   [(set_attr "type" "arith")])
3485 (define_expand "rotlsi3"
3486   [(set (match_operand:SI 0 "arith_reg_dest" "")
3487         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3488                    (match_operand:SI 2 "immediate_operand" "")))]
3489   "TARGET_SH1"
3490   "
3492   static const char rot_tab[] = {
3493     000, 000, 000, 000, 000, 000, 010, 001,
3494     001, 001, 011, 013, 003, 003, 003, 003,
3495     003, 003, 003, 003, 003, 013, 012, 002,
3496     002, 002, 010, 000, 000, 000, 000, 000,
3497   };
3499   int count, choice;
3501   if (GET_CODE (operands[2]) != CONST_INT)
3502     FAIL;
3503   count = INTVAL (operands[2]);
3504   choice = rot_tab[count];
3505   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3506     FAIL;
3507   choice &= 7;
3508   switch (choice)
3509     {
3510     case 0:
3511       emit_move_insn (operands[0], operands[1]);
3512       count -= (count & 16) * 2;
3513       break;
3514     case 3:
3515      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3516      count -= 16;
3517      break;
3518     case 1:
3519     case 2:
3520       {
3521         rtx parts[2];
3522         parts[0] = gen_reg_rtx (SImode);
3523         parts[1] = gen_reg_rtx (SImode);
3524         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3525         emit_move_insn (parts[choice-1], operands[1]);
3526         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3527         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3528         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3529         count = (count & ~16) - 8;
3530       }
3531     }
3533   for (; count > 0; count--)
3534     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3535   for (; count < 0; count++)
3536     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3538   DONE;
3541 (define_insn "*rotlhi3_8"
3542   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3543         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3544                    (const_int 8)))]
3545   "TARGET_SH1"
3546   "swap.b       %1,%0"
3547   [(set_attr "type" "arith")])
3549 (define_expand "rotlhi3"
3550   [(set (match_operand:HI 0 "arith_reg_operand" "")
3551         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3552                    (match_operand:HI 2 "immediate_operand" "")))]
3553   "TARGET_SH1"
3554   "
3556   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3557     FAIL;
3561 ;; shift left
3563 (define_insn "ashlsi3_sh2a"
3564   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3565         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3566                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3567   "TARGET_SH2A"
3568   "shad %2,%0"
3569   [(set_attr "type" "arith")
3570    (set_attr "length" "4")])
3572 ;; This pattern is used by init_expmed for computing the costs of shift
3573 ;; insns.
3575 (define_insn_and_split "ashlsi3_std"
3576   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3577         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3578                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3579    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3580   "TARGET_SH3
3581    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3582   "@
3583    shld %2,%0
3584    add  %0,%0
3585    shll%O2      %0
3586    #"
3587   "TARGET_SH3
3588    && reload_completed
3589    && GET_CODE (operands[2]) == CONST_INT
3590    && ! satisfies_constraint_P27 (operands[2])"
3591   [(set (match_dup 3) (match_dup 2))
3592    (parallel
3593     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3594      (clobber (match_dup 4))])]
3595   "operands[4] = gen_rtx_SCRATCH (SImode);"
3596   [(set_attr "length" "*,*,*,4")
3597    (set_attr "type" "dyn_shift,arith,arith,arith")])
3599 (define_insn "ashlhi3_k"
3600   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3601         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3602                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3603   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3604   "@
3605         add     %0,%0
3606         shll%O2 %0"
3607   [(set_attr "type" "arith")])
3609 (define_insn "ashlsi3_n"
3610   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3611         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3612                    (match_operand:SI 2 "const_int_operand" "n")))
3613    (clobber (reg:SI T_REG))]
3614   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3615   "#"
3616   [(set (attr "length")
3617         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3618                (const_string "2")
3619                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3620                (const_string "4")
3621                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3622                (const_string "6")]
3623               (const_string "8")))
3624    (set_attr "type" "arith")])
3626 (define_split
3627   [(set (match_operand:SI 0 "arith_reg_dest" "")
3628         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3629                    (match_operand:SI 2 "const_int_operand" "")))
3630    (clobber (reg:SI T_REG))]
3631   "TARGET_SH1 && reload_completed"
3632   [(use (reg:SI R0_REG))]
3633   "
3635   gen_shifty_op (ASHIFT, operands);
3636   DONE;
3639 (define_insn "ashlsi3_media"
3640   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3641         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3642                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3643   "TARGET_SHMEDIA"
3644   "@
3645         shlld.l %1, %2, %0
3646         shlli.l %1, %2, %0"
3647   [(set_attr "type" "arith_media")
3648    (set_attr "highpart" "ignore")])
3650 (define_expand "ashlsi3"
3651   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3652                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3653                               (match_operand:SI 2 "nonmemory_operand" "")))
3654               (clobber (reg:SI T_REG))])]
3655   ""
3656   "
3658   if (TARGET_SHMEDIA)
3659     {
3660       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3661       DONE;
3662     }
3663   if (GET_CODE (operands[2]) == CONST_INT
3664       && sh_dynamicalize_shift_p (operands[2]))
3665     operands[2] = force_reg (SImode, operands[2]);
3666   if (TARGET_SH3)
3667     {
3668       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3669       DONE;
3670     }
3671   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3672     FAIL;
3675 (define_insn "*ashlhi3_n"
3676   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3677         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3678                    (match_operand:HI 2 "const_int_operand" "n")))
3679    (clobber (reg:SI T_REG))]
3680   "TARGET_SH1"
3681   "#"
3682   [(set (attr "length")
3683         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3684                (const_string "2")
3685                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3686                (const_string "4")]
3687               (const_string "6")))
3688    (set_attr "type" "arith")])
3690 (define_expand "ashlhi3"
3691   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3692                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3693                               (match_operand:SI 2 "nonmemory_operand" "")))
3694               (clobber (reg:SI T_REG))])]
3695   "TARGET_SH1"
3696   "
3698   if (GET_CODE (operands[2]) != CONST_INT)
3699     FAIL;
3700   /* It may be possible to call gen_ashlhi3 directly with more generic
3701      operands.  Make sure operands[1] is a HImode register here.  */
3702   if (!arith_reg_operand (operands[1], HImode))
3703     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3706 (define_split
3707   [(set (match_operand:HI 0 "arith_reg_dest" "")
3708         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3709                    (match_operand:HI 2 "const_int_operand" "")))
3710    (clobber (reg:SI T_REG))]
3711   "TARGET_SH1 && reload_completed"
3712   [(use (reg:SI R0_REG))]
3713   "
3715   gen_shifty_hi_op (ASHIFT, operands);
3716   DONE;
3720 ; arithmetic shift right
3723 (define_insn "ashrsi3_sh2a"
3724   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3725         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3726                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3727   "TARGET_SH2A"
3728   "shad %2,%0"
3729   [(set_attr "type" "dyn_shift")
3730    (set_attr "length" "4")])
3732 (define_insn "ashrsi3_k"
3733   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3734         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3735                      (match_operand:SI 2 "const_int_operand" "M")))
3736    (clobber (reg:SI T_REG))]
3737   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3738   "shar %0"
3739   [(set_attr "type" "arith")])
3741 ;; We can't do HImode right shifts correctly unless we start out with an
3742 ;; explicit zero / sign extension; doing that would result in worse overall
3743 ;; code, so just let the machine independent code widen the mode.
3744 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3747 ;; ??? This should be a define expand.
3749 (define_insn "ashrsi2_16"
3750   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3751         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3752                      (const_int 16)))]
3753   "TARGET_SH1"
3754   "#"
3755   [(set_attr "length" "4")])
3757 (define_split
3758   [(set (match_operand:SI 0 "arith_reg_dest" "")
3759         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3760                      (const_int 16)))]
3761   "TARGET_SH1"
3762   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3763    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3764   "operands[2] = gen_lowpart (HImode, operands[0]);")
3766 ;; ??? This should be a define expand.
3768 (define_insn "ashrsi2_31"
3769   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3770         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3771                      (const_int 31)))
3772    (clobber (reg:SI T_REG))]
3773   "TARGET_SH1"
3774   "#"
3775   [(set_attr "length" "4")])
3777 (define_split
3778   [(set (match_operand:SI 0 "arith_reg_dest" "")
3779         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3780                      (const_int 31)))
3781    (clobber (reg:SI T_REG))]
3782   "TARGET_SH1"
3783   [(const_int 0)]
3784   "
3786   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3787   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3788   DONE;
3791 (define_peephole2
3792   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3793    (set (reg:SI T_REG)
3794         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3795   "TARGET_SH1
3796    && peep2_reg_dead_p (2, operands[0])
3797    && peep2_reg_dead_p (2, operands[1])"
3798   [(const_int 0)]
3799   "
3801   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3802   DONE;
3805 (define_insn "ashlsi_c"
3806   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3807         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3808    (set (reg:SI T_REG)
3809         (lt:SI (match_dup 1) (const_int 0)))]
3810   "TARGET_SH1"
3811   "shll %0"
3812   [(set_attr "type" "arith")])
3814 (define_insn "*ashlsi_c_void"
3815   [(set (reg:SI T_REG)
3816         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3817    (clobber (match_scratch:SI 1 "=0"))]
3818   "TARGET_SH1 && cse_not_expected"
3819   "shll %0"
3820   [(set_attr "type" "arith")])
3822 (define_insn "ashrsi3_d"
3823   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3824         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3825                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3826   "TARGET_SH3"
3827   "shad %2,%0"
3828   [(set_attr "type" "dyn_shift")])
3830 (define_insn "ashrsi3_n"
3831   [(set (reg:SI R4_REG)
3832         (ashiftrt:SI (reg:SI R4_REG)
3833                      (match_operand:SI 0 "const_int_operand" "i")))
3834    (clobber (reg:SI T_REG))
3835    (clobber (reg:SI PR_REG))
3836    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3837   "TARGET_SH1"
3838   "jsr  @%1%#"
3839   [(set_attr "type" "sfunc")
3840    (set_attr "needs_delay_slot" "yes")])
3842 (define_insn "ashrsi3_media"
3843   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3844         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3845                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3846   "TARGET_SHMEDIA"
3847   "@
3848         shard.l %1, %2, %0
3849         shari.l %1, %2, %0"
3850   [(set_attr "type" "arith_media")
3851    (set_attr "highpart" "ignore")])
3853 (define_expand "ashrsi3"
3854   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3855                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3856                                 (match_operand:SI 2 "nonmemory_operand" "")))
3857               (clobber (reg:SI T_REG))])]
3858   ""
3859   "
3861   if (TARGET_SHMEDIA)
3862     {
3863       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3864       DONE;
3865     }
3866   if (expand_ashiftrt (operands))
3867     DONE;
3868   else
3869     FAIL;
3872 ;; logical shift right
3874 (define_insn "lshrsi3_sh2a"
3875   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3876         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3877                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3878   "TARGET_SH2A"
3879   "shld %2,%0"
3880   [(set_attr "type" "dyn_shift")
3881    (set_attr "length" "4")])
3883 (define_insn "lshrsi3_d"
3884   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3885         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3886                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3887   "TARGET_SH3"
3888   "shld %2,%0"
3889   [(set_attr "type" "dyn_shift")])
3891 ;;  Only the single bit shift clobbers the T bit.
3893 (define_insn "lshrsi3_m"
3894   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3895         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3896                      (match_operand:SI 2 "const_int_operand" "M")))
3897    (clobber (reg:SI T_REG))]
3898   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3899   "shlr %0"
3900   [(set_attr "type" "arith")])
3902 (define_insn "lshrsi3_k"
3903   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3904         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3905                      (match_operand:SI 2 "const_int_operand" "P27")))]
3906   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3907    && ! satisfies_constraint_M (operands[2])"
3908   "shlr%O2      %0"
3909   [(set_attr "type" "arith")])
3911 (define_insn "lshrsi3_n"
3912   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3913         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3914                      (match_operand:SI 2 "const_int_operand" "n")))
3915    (clobber (reg:SI T_REG))]
3916   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3917   "#"
3918   [(set (attr "length")
3919         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3920                (const_string "2")
3921                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3922                (const_string "4")
3923                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3924                (const_string "6")]
3925               (const_string "8")))
3926    (set_attr "type" "arith")])
3928 (define_split
3929   [(set (match_operand:SI 0 "arith_reg_dest" "")
3930         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3931                      (match_operand:SI 2 "const_int_operand" "")))
3932    (clobber (reg:SI T_REG))]
3933   "TARGET_SH1 && reload_completed"
3934   [(use (reg:SI R0_REG))]
3935   "
3937   gen_shifty_op (LSHIFTRT, operands);
3938   DONE;
3941 (define_insn "lshrsi3_media"
3942   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3943         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3944                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3945   "TARGET_SHMEDIA"
3946   "@
3947         shlrd.l %1, %2, %0
3948         shlri.l %1, %2, %0"
3949   [(set_attr "type" "arith_media")
3950    (set_attr "highpart" "ignore")])
3952 (define_expand "lshrsi3"
3953   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3954                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3955                                 (match_operand:SI 2 "nonmemory_operand" "")))
3956               (clobber (reg:SI T_REG))])]
3957   ""
3958   "
3960   if (TARGET_SHMEDIA)
3961     {
3962       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3963       DONE;
3964     }
3965   if (GET_CODE (operands[2]) == CONST_INT
3966       && sh_dynamicalize_shift_p (operands[2]))
3967     operands[2] = force_reg (SImode, operands[2]);
3968   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3969     {
3970       rtx count = copy_to_mode_reg (SImode, operands[2]);
3971       emit_insn (gen_negsi2 (count, count));
3972       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3973       DONE;
3974     }
3975   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3976     FAIL;
3979 ;; ??? This should be a define expand.
3981 (define_insn "ashldi3_k"
3982   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3983         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3984                    (const_int 1)))
3985    (clobber (reg:SI T_REG))]
3986   "TARGET_SH1"
3987   "shll %R0\;rotcl      %S0"
3988   [(set_attr "length" "4")
3989    (set_attr "type" "arith")])
3991 (define_insn "ashldi3_media"
3992   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3993         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3994                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3995   "TARGET_SHMEDIA"
3996   "@
3997         shlld   %1, %2, %0
3998         shlli   %1, %2, %0"
3999   [(set_attr "type" "arith_media")])
4001 (define_insn "*ashldisi3_media"
4002   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4003         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
4004                    (match_operand:DI 2 "const_int_operand" "n")))]
4005   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4006   "shlli.l      %1, %2, %0"
4007   [(set_attr "type" "arith_media")
4008    (set_attr "highpart" "ignore")])
4010 (define_expand "ashldi3"
4011   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4012                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
4013                               (match_operand:DI 2 "immediate_operand" "")))
4014               (clobber (reg:SI T_REG))])]
4015   ""
4016   "
4018   if (TARGET_SHMEDIA)
4019     {
4020       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
4021       DONE;
4022     }
4023   if (GET_CODE (operands[2]) != CONST_INT
4024       || INTVAL (operands[2]) != 1)
4025     FAIL;
4028 ;; ??? This should be a define expand.
4030 (define_insn "lshrdi3_k"
4031   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4032         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4033                      (const_int 1)))
4034    (clobber (reg:SI T_REG))]
4035   "TARGET_SH1"
4036   "shlr %S0\;rotcr      %R0"
4037   [(set_attr "length" "4")
4038    (set_attr "type" "arith")])
4040 (define_insn "lshrdi3_media"
4041   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4042         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4043                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4044   "TARGET_SHMEDIA
4045    && (arith_reg_dest (operands[0], DImode)
4046        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
4047   "@
4048         shlrd   %1, %2, %0
4049         shlri   %1, %2, %0"
4050   [(set_attr "type" "arith_media")])
4052 (define_insn "*lshrdisi3_media"
4053   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4054         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4055                      (match_operand:DI 2 "const_int_operand" "n")))]
4056   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4057   "shlri.l      %1, %2, %0"
4058   [(set_attr "type" "arith_media")
4059    (set_attr "highpart" "ignore")])
4061 (define_expand "lshrdi3"
4062   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4063                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4064                                (match_operand:DI 2 "immediate_operand" "")))
4065              (clobber (reg:SI T_REG))])]
4066   ""
4067   "
4069   if (TARGET_SHMEDIA)
4070     {
4071       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
4072       DONE;
4073     }
4074   if (GET_CODE (operands[2]) != CONST_INT
4075       || INTVAL (operands[2]) != 1)
4076     FAIL;
4079 ;; ??? This should be a define expand.
4081 (define_insn "ashrdi3_k"
4082   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4083         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
4084                      (const_int 1)))
4085    (clobber (reg:SI T_REG))]
4086   "TARGET_SH1"
4087   "shar %S0\;rotcr      %R0"
4088   [(set_attr "length" "4")
4089    (set_attr "type" "arith")])
4091 (define_insn "ashrdi3_media"
4092   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
4093         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
4094                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
4095   "TARGET_SHMEDIA
4096    && (arith_reg_dest (operands[0], DImode)
4097        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
4098   "@
4099         shard   %1, %2, %0
4100         shari   %1, %2, %0"
4101   [(set_attr "type" "arith_media")])
4103 (define_insn "*ashrdisi3_media"
4104   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4105         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4106                      (match_operand:DI 2 "const_int_operand" "n")))]
4107   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4108   "shari.l      %1, %2, %0"
4109   [(set_attr "type" "arith_media")
4110    (set_attr "highpart" "ignore")])
4112 (define_insn "ashrdisi3_media_high"
4113   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4114         (truncate:SI
4115            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4116                         (match_operand:DI 2 "const_int_operand" "n"))))]
4117   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4118   "shari        %1, %2, %0"
4119   [(set_attr "type" "arith_media")])
4121 (define_insn "ashrdisi3_media_opaque"
4122   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4123         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4124                     (match_operand:DI 2 "const_int_operand" "n")]
4125          UNSPEC_ASHIFTRT))]
4126   "TARGET_SHMEDIA"
4127   "shari        %1, %2, %0"
4128   [(set_attr "type" "arith_media")])
4130 (define_expand "ashrdi3"
4131   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4132                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4133                                 (match_operand:DI 2 "immediate_operand" "")))
4134               (clobber (reg:SI T_REG))])]
4135   ""
4136   "
4138   if (TARGET_SHMEDIA)
4139     {
4140       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4141       DONE;
4142     }
4143   if (GET_CODE (operands[2]) != CONST_INT
4144       || INTVAL (operands[2]) != 1)
4145     FAIL;
4148 ;; combined left/right shift
4150 (define_split
4151   [(set (match_operand:SI 0 "register_operand" "")
4152         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4153                            (match_operand:SI 2 "const_int_operand" ""))
4154                 (match_operand:SI 3 "const_int_operand" "")))]
4155   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4156   [(use (reg:SI R0_REG))]
4157   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4158    DONE;")
4160 (define_split
4161   [(set (match_operand:SI 0 "register_operand" "")
4162         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4163                            (match_operand:SI 2 "const_int_operand" ""))
4164                 (match_operand:SI 3 "const_int_operand" "")))
4165    (clobber (reg:SI T_REG))]
4166   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4167   [(use (reg:SI R0_REG))]
4168   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4169    DONE;")
4171 (define_insn ""
4172   [(set (match_operand:SI 0 "register_operand" "=r")
4173         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4174                            (match_operand:SI 2 "const_int_operand" "n"))
4175                 (match_operand:SI 3 "const_int_operand" "n")))
4176    (clobber (reg:SI T_REG))]
4177   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4178  "#"
4179   [(set (attr "length")
4180         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4181                (const_string "4")
4182                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4183                (const_string "6")
4184                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4185                (const_string "8")
4186                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4187                (const_string "10")
4188                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4189                (const_string "12")
4190                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4191                (const_string "14")
4192                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4193                (const_string "16")]
4194               (const_string "18")))
4195    (set_attr "type" "arith")])
4197 (define_insn ""
4198   [(set (match_operand:SI 0 "register_operand" "=z")
4199         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4200                            (match_operand:SI 2 "const_int_operand" "n"))
4201                 (match_operand:SI 3 "const_int_operand" "n")))
4202    (clobber (reg:SI T_REG))]
4203   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4204  "#"
4205   [(set (attr "length")
4206         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4207                (const_string "4")
4208                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4209                (const_string "6")
4210                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4211                (const_string "8")]
4212               (const_string "10")))
4213    (set_attr "type" "arith")])
4215 ;; shift left / and combination with a scratch register: The combine pass
4216 ;; does not accept the individual instructions, even though they are
4217 ;; cheap.  But it needs a precise description so that it is usable after
4218 ;; reload.
4219 (define_insn "and_shl_scratch"
4220   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4221         (lshiftrt:SI
4222          (ashift:SI
4223           (and:SI
4224            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4225                         (match_operand:SI 2 "const_int_operand" "N,n"))
4226            (match_operand:SI 3 "" "0,r"))
4227           (match_operand:SI 4 "const_int_operand" "n,n"))
4228          (match_operand:SI 5 "const_int_operand" "n,n")))
4229    (clobber (reg:SI T_REG))]
4230   "TARGET_SH1"
4231   "#"
4232   [(set (attr "length")
4233         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4234                (const_string "4")
4235                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4236                (const_string "6")
4237                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4238                (const_string "8")
4239                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4240                (const_string "10")]
4241               (const_string "12")))
4242    (set_attr "type" "arith")])
4244 (define_split
4245   [(set (match_operand:SI 0 "register_operand" "")
4246         (lshiftrt:SI
4247          (ashift:SI
4248           (and:SI
4249            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4250                         (match_operand:SI 2 "const_int_operand" ""))
4251            (match_operand:SI 3 "register_operand" ""))
4252           (match_operand:SI 4 "const_int_operand" ""))
4253          (match_operand:SI 5 "const_int_operand" "")))
4254    (clobber (reg:SI T_REG))]
4255   "TARGET_SH1"
4256   [(use (reg:SI R0_REG))]
4257   "
4259   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4261   if (INTVAL (operands[2]))
4262     {
4263       gen_shifty_op (LSHIFTRT, operands);
4264     }
4265   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4266   operands[2] = operands[4];
4267   gen_shifty_op (ASHIFT, operands);
4268   if (INTVAL (operands[5]))
4269     {
4270       operands[2] = operands[5];
4271       gen_shifty_op (LSHIFTRT, operands);
4272     }
4273   DONE;
4276 ;; signed left/right shift combination.
4277 (define_split
4278   [(set (match_operand:SI 0 "register_operand" "")
4279         (sign_extract:SI
4280          (ashift:SI (match_operand:SI 1 "register_operand" "")
4281                     (match_operand:SI 2 "const_int_operand" ""))
4282          (match_operand:SI 3 "const_int_operand" "")
4283          (const_int 0)))
4284    (clobber (reg:SI T_REG))]
4285   "TARGET_SH1"
4286   [(use (reg:SI R0_REG))]
4287   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4288    DONE;")
4290 (define_insn "shl_sext_ext"
4291   [(set (match_operand:SI 0 "register_operand" "=r")
4292         (sign_extract:SI
4293          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4294                     (match_operand:SI 2 "const_int_operand" "n"))
4295          (match_operand:SI 3 "const_int_operand" "n")
4296          (const_int 0)))
4297    (clobber (reg:SI T_REG))]
4298   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4299   "#"
4300   [(set (attr "length")
4301         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4302                (const_string "2")
4303                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4304                (const_string "4")
4305                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4306                (const_string "6")
4307                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4308                (const_string "8")
4309                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4310                (const_string "10")
4311                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4312                (const_string "12")
4313                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4314                (const_string "14")
4315                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4316                (const_string "16")]
4317               (const_string "18")))
4318     (set_attr "type" "arith")])
4320 (define_insn "shl_sext_sub"
4321   [(set (match_operand:SI 0 "register_operand" "=z")
4322         (sign_extract:SI
4323          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4324                     (match_operand:SI 2 "const_int_operand" "n"))
4325          (match_operand:SI 3 "const_int_operand" "n")
4326          (const_int 0)))
4327    (clobber (reg:SI T_REG))]
4328   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4329   "#"
4330   [(set (attr "length")
4331         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4332                (const_string "6")
4333                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4334                (const_string "8")
4335                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4336                (const_string "10")
4337                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4338                (const_string "12")]
4339               (const_string "14")))
4340     (set_attr "type" "arith")])
4342 ;; These patterns are found in expansions of DImode shifts by 16, and
4343 ;; allow the xtrct instruction to be generated from C source.
4345 (define_insn "xtrct_left"
4346   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4347         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4348                            (const_int 16))
4349                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4350                              (const_int 16))))]
4351   "TARGET_SH1"
4352   "xtrct        %1,%0"
4353   [(set_attr "type" "arith")])
4355 (define_insn "xtrct_right"
4356   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4357         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4358                              (const_int 16))
4359                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4360                            (const_int 16))))]
4361   "TARGET_SH1"
4362   "xtrct        %2,%0"
4363   [(set_attr "type" "arith")])
4365 ;; -------------------------------------------------------------------------
4366 ;; Unary arithmetic
4367 ;; -------------------------------------------------------------------------
4369 (define_insn "negc"
4370   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4371         (neg:SI (plus:SI (reg:SI T_REG)
4372                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4373    (set (reg:SI T_REG)
4374         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4375                (const_int 0)))]
4376   "TARGET_SH1"
4377   "negc %1,%0"
4378   [(set_attr "type" "arith")])
4380 (define_insn "*negdi_media"
4381   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4382         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4383   "TARGET_SHMEDIA"
4384   "sub  r63, %1, %0"
4385   [(set_attr "type" "arith_media")])
4387 (define_expand "negdi2"
4388   [(set (match_operand:DI 0 "arith_reg_operand" "")
4389         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4390   ""
4391   "
4393   if (TARGET_SH1)
4394     {
4395       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4396       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4398       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4399       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4401       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4402       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4404       emit_insn (gen_clrt ());
4405       emit_insn (gen_negc (low_dst, low_src));
4406       emit_insn (gen_negc (high_dst, high_src));
4407       DONE;
4408     }
4411 (define_insn "negsi2"
4412   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4413         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4414   "TARGET_SH1"
4415   "neg  %1,%0"
4416   [(set_attr "type" "arith")])
4418 (define_insn "one_cmplsi2"
4419   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4420         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4421   "TARGET_SH1"
4422   "not  %1,%0"
4423   [(set_attr "type" "arith")])
4425 (define_expand "one_cmpldi2"
4426   [(set (match_operand:DI 0 "arith_reg_dest" "")
4427         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4428                 (const_int -1)))]
4429   "TARGET_SHMEDIA" "")
4431 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4432    This can be used as some kind of conditional execution, which is useful
4433    for abs.  */
4434 (define_split
4435   [(set (match_operand:SI 0 "arith_reg_dest" "")
4436         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4437                          (match_operand:SI 1 "arith_reg_operand" ""))
4438                  (reg:SI T_REG)))]
4439   "TARGET_HARD_SH4"
4440   [(const_int 0)]
4441   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4442    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4443    DONE;")
4445 (define_insn "cneg"
4446   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4447         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4448                       (match_operand:SI 1 "arith_reg_operand" "0")
4449                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4450   "TARGET_HARD_SH4"
4451   "bf 0f\;neg %2,%0\\n0:"
4452   [(set_attr "type" "arith") ;; poor approximation
4453    (set_attr "length" "4")])
4456 ;; -------------------------------------------------------------------------
4457 ;; Zero extension instructions
4458 ;; -------------------------------------------------------------------------
4460 (define_insn "zero_extendsidi2"
4461   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4462         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4463   "TARGET_SHMEDIA"
4464   "addz.l       %1, r63, %0"
4465   [(set_attr "type" "arith_media")
4466    (set_attr "highpart" "extend")])
4468 (define_insn "zero_extendhidi2"
4469   [(set (match_operand:DI 0 "register_operand" "=r,r")
4470         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4471   "TARGET_SHMEDIA"
4472   "@
4473         #
4474         ld%M1.uw        %m1, %0"
4475   [(set_attr "type" "*,load_media")
4476    (set (attr "highpart")
4477         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4478                (const_string "user")]
4479               (const_string "ignore")))])
4481 (define_split
4482   [(set (match_operand:DI 0 "register_operand" "")
4483         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4484   "TARGET_SHMEDIA && reload_completed"
4485   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4486    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4487   "
4489   if (GET_CODE (operands[1]) == TRUNCATE)
4490     operands[1] = XEXP (operands[1], 0);
4493 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4494 ;; reload the entire truncate expression.
4495 (define_insn_and_split "*loaddi_trunc"
4496   [(set (match_operand 0 "any_register_operand" "=r")
4497         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4498   "TARGET_SHMEDIA && reload_completed"
4499   "#"
4500   "TARGET_SHMEDIA && reload_completed"
4501   [(set (match_dup 0) (match_dup 1))]
4502   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4504 (define_insn "zero_extendqidi2"
4505   [(set (match_operand:DI 0 "register_operand" "=r,r")
4506         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4507   "TARGET_SHMEDIA"
4508   "@
4509         andi    %1, 255, %0
4510         ld%M1.ub        %m1, %0"
4511   [(set_attr "type" "arith_media,load_media")
4512    (set (attr "highpart")
4513         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4514                (const_string "user")]
4515               (const_string "ignore")))])
4517 (define_expand "zero_extendhisi2"
4518   [(set (match_operand:SI 0 "arith_reg_operand" "")
4519         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4520   ""
4521   "
4523   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4524     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4527 (define_insn "*zero_extendhisi2_compact"
4528   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4529         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4530   "TARGET_SH1"
4531   "extu.w       %1,%0"
4532   [(set_attr "type" "arith")])
4534 (define_insn "*zero_extendhisi2_media"
4535   [(set (match_operand:SI 0 "register_operand" "=r,r")
4536         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4537   "TARGET_SHMEDIA"
4538   "@
4539         #
4540         ld%M1.uw        %m1, %0"
4541   [(set_attr "type" "arith_media,load_media")
4542    (set (attr "highpart")
4543         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4544                (const_string "user")]
4545               (const_string "ignore")))])
4547 (define_split
4548   [(set (match_operand:SI 0 "register_operand" "")
4549         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4550   "TARGET_SHMEDIA && reload_completed"
4551   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4552    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4553   "
4555   rtx op1 = operands[1];
4557   if (GET_CODE (op1) == TRUNCATE)
4558     op1 = XEXP (op1, 0);
4559   operands[2]
4560     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4561                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4564 (define_expand "zero_extendqisi2"
4565   [(set (match_operand:SI 0 "arith_reg_operand" "")
4566         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4567   ""
4568   "
4570   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4571     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4574 (define_insn "*zero_extendqisi2_compact"
4575   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4576         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4577   "TARGET_SH1"
4578   "extu.b       %1,%0"
4579   [(set_attr "type" "arith")])
4581 (define_insn "*zero_extendqisi2_media"
4582   [(set (match_operand:SI 0 "register_operand" "=r,r")
4583         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4584   "TARGET_SHMEDIA"
4585   "@
4586         andi    %1, 255, %0
4587         ld%M1.ub        %m1, %0"
4588   [(set_attr "type" "arith_media,load_media")
4589    (set (attr "highpart")
4590         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4591                (const_string "user")]
4592               (const_string "ignore")))])
4594 (define_insn "zero_extendqihi2"
4595   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4596         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4597   "TARGET_SH1"
4598   "extu.b       %1,%0"
4599   [(set_attr "type" "arith")])
4601 ;; -------------------------------------------------------------------------
4602 ;; Sign extension instructions
4603 ;; -------------------------------------------------------------------------
4605 ;; ??? This should be a define expand.
4606 ;; ??? Or perhaps it should be dropped?
4608 ;; convert_move generates good code for SH[1-4].
4609 (define_insn "extendsidi2"
4610   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4611         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4612   "TARGET_SHMEDIA"
4613   "@
4614         add.l   %1, r63, %0
4615         ld%M1.l %m1, %0
4616         fmov.sl %1, %0"
4617   [(set_attr "type" "arith_media,load_media,fpconv_media")
4618    (set (attr "highpart")
4619         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4620                (const_string "user")]
4621               (const_string "extend")))])
4623 (define_insn "extendhidi2"
4624   [(set (match_operand:DI 0 "register_operand" "=r,r")
4625         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4626   "TARGET_SHMEDIA"
4627   "@
4628         #
4629         ld%M1.w %m1, %0"
4630   [(set_attr "type" "*,load_media")
4631    (set (attr "highpart")
4632         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4633                (const_string "user")]
4634               (const_string "ignore")))])
4636 (define_split
4637   [(set (match_operand:DI 0 "register_operand" "")
4638         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4639   "TARGET_SHMEDIA && reload_completed"
4640   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4641    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4642   "
4644   if (GET_CODE (operands[1]) == TRUNCATE)
4645     operands[1] = XEXP (operands[1], 0);
4648 (define_insn "extendqidi2"
4649   [(set (match_operand:DI 0 "register_operand" "=r,r")
4650         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4651   "TARGET_SHMEDIA"
4652   "@
4653         #
4654         ld%M1.b %m1, %0"
4655   [(set_attr "type" "*,load_media")
4656    (set (attr "highpart")
4657         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4658                (const_string "user")]
4659               (const_string "ignore")))])
4661 (define_split
4662   [(set (match_operand:DI 0 "register_operand" "")
4663         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4664   "TARGET_SHMEDIA && reload_completed"
4665   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4666    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4667   "
4669   if (GET_CODE (operands[1]) == TRUNCATE)
4670     operands[1] = XEXP (operands[1], 0);
4673 (define_expand "extendhisi2"
4674   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4675         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4676   ""
4677   "")
4679 (define_insn "*extendhisi2_compact"
4680   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4681         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4682   "TARGET_SH1"
4683   "@
4684         exts.w  %1,%0
4685         mov.w   %1,%0"
4686   [(set_attr "type" "arith,load")])
4688 (define_insn "*extendhisi2_media"
4689   [(set (match_operand:SI 0 "register_operand" "=r,r")
4690         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4691   "TARGET_SHMEDIA"
4692   "@
4693         #
4694         ld%M1.w %m1, %0"
4695   [(set_attr "type" "arith_media,load_media")
4696    (set (attr "highpart")
4697         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4698                (const_string "user")]
4699               (const_string "ignore")))])
4701 (define_split
4702   [(set (match_operand:SI 0 "register_operand" "")
4703         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4704   "TARGET_SHMEDIA && reload_completed"
4705   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4706    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4707   "
4709   rtx op1 = operands[1];
4710   if (GET_CODE (op1) == TRUNCATE)
4711     op1 = XEXP (op1, 0);
4712   operands[2]
4713     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4714                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4717 (define_expand "extendqisi2"
4718   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4719         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4720   ""
4721   "")
4723 (define_insn "*extendqisi2_compact"
4724   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4725         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4726   "TARGET_SH1"
4727   "@
4728         exts.b  %1,%0
4729         mov.b   %1,%0"
4730   [(set_attr "type" "arith,load")
4731    (set_attr_alternative "length"
4732      [(const_int 2)
4733        (if_then_else
4734         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4735         (const_int 4) (const_int 2))])])
4737 (define_insn "*extendqisi2_media"
4738   [(set (match_operand:SI 0 "register_operand" "=r,r")
4739         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4740   "TARGET_SHMEDIA"
4741   "@
4742         #
4743         ld%M1.b %m1, %0"
4744   [(set_attr "type" "arith_media,load_media")
4745    (set (attr "highpart")
4746         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4747                (const_string "user")]
4748               (const_string "ignore")))])
4750 (define_split
4751   [(set (match_operand:SI 0 "register_operand" "")
4752         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4753   "TARGET_SHMEDIA && reload_completed"
4754   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4755    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4756    "
4758   rtx op1 = operands[1];
4759   if (GET_CODE (op1) == TRUNCATE)
4760     op1 = XEXP (op1, 0);
4761   operands[2]
4762     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4763                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4766 (define_insn "extendqihi2"
4767   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4768         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4769   "TARGET_SH1"
4770   "@
4771         exts.b  %1,%0
4772         mov.b   %1,%0"
4773   [(set_attr "type" "arith,load")
4774    (set_attr_alternative "length"
4775      [(const_int 2)
4776        (if_then_else
4777         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4778         (const_int 4) (const_int 2))])])
4780 /* It would seem useful to combine the truncXi patterns into the movXi
4781    patterns, but unary operators are ignored when matching constraints,
4782    so we need separate patterns.  */
4783 (define_insn "truncdisi2"
4784   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4785         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4786   "TARGET_SHMEDIA"
4787   "@
4788         add.l   %1, r63, %0
4789         st%M0.l %m0, %1
4790         fst%M0.s        %m0, %T1
4791         fmov.ls %1, %0
4792         fmov.sl %T1, %0
4793         fmov.s  %T1, %0"
4794   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4795    (set (attr "highpart")
4796         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4797                (const_string "user")]
4798               (const_string "extend")))])
4800 (define_insn "truncdihi2"
4801   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4802         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4803   "TARGET_SHMEDIA"
4804   "@
4805         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4806         st%M0.w %m0, %1"
4807   [(set_attr "type"   "arith_media,store_media")
4808    (set_attr "length" "8,4")
4809    (set (attr "highpart")
4810         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4811                (const_string "user")]
4812               (const_string "extend")))])
4814 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4815 ; Because we use zero extension, we can't provide signed QImode compares
4816 ; using a simple compare or conditional branch insn.
4817 (define_insn "truncdiqi2"
4818   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4819         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4820   "TARGET_SHMEDIA"
4821   "@
4822         andi    %1, 255, %0
4823         st%M0.b %m0, %1"
4824   [(set_attr "type"   "arith_media,store")
4825    (set (attr "highpart")
4826         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4827                (const_string "user")]
4828               (const_string "extend")))])
4829 ;; -------------------------------------------------------------------------
4830 ;; Move instructions
4831 ;; -------------------------------------------------------------------------
4833 ;; define push and pop so it is easy for sh.c
4834 ;; We can't use push and pop on SHcompact because the stack must always
4835 ;; be 8-byte aligned.
4837 (define_expand "push"
4838   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4839         (match_operand:SI 0 "register_operand" "r,l,x"))]
4840   "TARGET_SH1 && ! TARGET_SH5"
4841   "")
4843 (define_expand "pop"
4844   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4845         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4846   "TARGET_SH1 && ! TARGET_SH5"
4847   "")
4849 (define_expand "push_e"
4850   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4851                    (match_operand:SF 0 "" ""))
4852               (use (reg:PSI FPSCR_REG))
4853               (clobber (scratch:SI))])]
4854   "TARGET_SH1 && ! TARGET_SH5"
4855   "")
4857 (define_insn "push_fpul"
4858   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4859   "TARGET_SH2E && ! TARGET_SH5"
4860   "sts.l        fpul,@-r15"
4861   [(set_attr "type" "fstore")
4862    (set_attr "late_fp_use" "yes")
4863    (set_attr "hit_stack" "yes")])
4865 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4866 ;; so use that.
4867 (define_expand "push_4"
4868   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4869                    (match_operand:DF 0 "" ""))
4870               (use (reg:PSI FPSCR_REG))
4871               (clobber (scratch:SI))])]
4872   "TARGET_SH1 && ! TARGET_SH5"
4873   "")
4875 (define_expand "pop_e"
4876   [(parallel [(set (match_operand:SF 0 "" "")
4877               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4878               (use (reg:PSI FPSCR_REG))
4879               (clobber (scratch:SI))])]
4880   "TARGET_SH1 && ! TARGET_SH5"
4881   "")
4883 (define_insn "pop_fpul"
4884   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4885   "TARGET_SH2E && ! TARGET_SH5"
4886   "lds.l        @r15+,fpul"
4887   [(set_attr "type" "load")
4888    (set_attr "hit_stack" "yes")])
4890 (define_expand "pop_4"
4891   [(parallel [(set (match_operand:DF 0 "" "")
4892                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4893               (use (reg:PSI FPSCR_REG))
4894               (clobber (scratch:SI))])]
4895   "TARGET_SH1 && ! TARGET_SH5"
4896   "")
4898 (define_expand "push_fpscr"
4899   [(const_int 0)]
4900   "TARGET_SH2E"
4901   "
4903   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4904                                                  gen_rtx_PRE_DEC (Pmode,
4905                                                           stack_pointer_rtx)),
4906                                         get_fpscr_rtx ()));
4907   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4908   DONE;
4911 (define_expand "pop_fpscr"
4912   [(const_int 0)]
4913   "TARGET_SH2E"
4914   "
4916   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4917                                         gen_frame_mem (PSImode,
4918                                                  gen_rtx_POST_INC (Pmode,
4919                                                           stack_pointer_rtx))));
4920   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4921   DONE;
4924 ;; These two patterns can happen as the result of optimization, when
4925 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4926 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4928 (define_insn "clrt"
4929   [(set (reg:SI T_REG) (const_int 0))]
4930   "TARGET_SH1"
4931   "clrt")
4933 (define_insn "sett"
4934   [(set (reg:SI T_REG) (const_int 1))]
4935   "TARGET_SH1"
4936   "sett")
4938 ;; t/r must come after r/r, lest reload will try to reload stuff like
4939 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4940 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4941 (define_insn "movsi_i"
4942   [(set (match_operand:SI 0 "general_movdst_operand"
4943             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4944         (match_operand:SI 1 "general_movsrc_operand"
4945          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4946   "TARGET_SH1
4947    && ! TARGET_SH2E
4948    && ! TARGET_SH2A
4949    && (register_operand (operands[0], SImode)
4950        || register_operand (operands[1], SImode))"
4951   "@
4952         mov.l   %1,%0
4953         mov     %1,%0
4954         mov     %1,%0
4955         cmp/pl  %1
4956         mov.l   %1,%0
4957         sts     %1,%0
4958         sts     %1,%0
4959         movt    %0
4960         mov.l   %1,%0
4961         sts.l   %1,%0
4962         sts.l   %1,%0
4963         lds     %1,%0
4964         lds     %1,%0
4965         lds.l   %1,%0
4966         lds.l   %1,%0
4967         fake    %1,%0"
4968   [(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")
4969    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4971 ;; t/r must come after r/r, lest reload will try to reload stuff like
4972 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4973 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4974 ;; will require a reload.
4975 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4976 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4977 (define_insn "movsi_ie"
4978   [(set (match_operand:SI 0 "general_movdst_operand"
4979             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4980         (match_operand:SI 1 "general_movsrc_operand"
4981          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4982   "(TARGET_SH2E || TARGET_SH2A)
4983    && (register_operand (operands[0], SImode)
4984        || register_operand (operands[1], SImode))"
4985   "@
4986         mov.l   %1,%0
4987         mov     %1,%0
4988         mov     %1,%0
4989         movi20  %1,%0
4990         movi20s %1,%0
4991         cmp/pl  %1
4992         mov.l   %1,%0
4993         sts     %1,%0
4994         sts     %1,%0
4995         movt    %0
4996         mov.l   %1,%0
4997         sts.l   %1,%0
4998         sts.l   %1,%0
4999         lds     %1,%0
5000         lds     %1,%0
5001         lds.l   %1,%0
5002         lds.l   %1,%0
5003         lds.l   %1,%0
5004         sts.l   %1,%0
5005         fake    %1,%0
5006         lds     %1,%0
5007         sts     %1,%0
5008         fsts    fpul,%0
5009         flds    %1,fpul
5010         fmov    %1,%0
5011         ! move optimized away"
5012   [(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")
5013    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
5014    (set_attr_alternative "length"
5015      [(const_int 2)
5016       (const_int 2)
5017       (const_int 2)
5018       (const_int 4)
5019       (const_int 4)
5020       (const_int 2)
5021       (if_then_else
5022         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5023         (const_int 4) (const_int 2))
5024       (const_int 2)
5025       (const_int 2)
5026       (const_int 2)
5027       (if_then_else
5028         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5029         (const_int 4) (const_int 2))
5030       (const_int 2)
5031       (const_int 2)
5032       (const_int 2)
5033       (const_int 2)
5034       (const_int 2)
5035       (const_int 2)
5036       (const_int 2)
5037       (const_int 2)
5038       (const_int 2)
5039       (const_int 2)
5040       (const_int 2)
5041       (const_int 2)
5042       (const_int 2)
5043       (const_int 2)
5044       (const_int 0)])])
5046 (define_insn "movsi_i_lowpart"
5047   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
5048         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
5049    "TARGET_SH1
5050     && (register_operand (operands[0], SImode)
5051         || register_operand (operands[1], SImode))"
5052   "@
5053         mov.l   %1,%0
5054         mov     %1,%0
5055         mov     %1,%0
5056         mov.l   %1,%0
5057         sts     %1,%0
5058         sts     %1,%0
5059         movt    %0
5060         mov.l   %1,%0
5061         fake    %1,%0"
5062   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
5064 (define_insn_and_split "load_ra"
5065   [(set (match_operand:SI 0 "general_movdst_operand" "")
5066         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
5067   "TARGET_SH1"
5068   "#"
5069   "&& ! currently_expanding_to_rtl"
5070   [(set (match_dup 0) (match_dup 1))]
5071   "
5073   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
5074     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
5077 ;; The '?'s in the following constraints may not reflect the time taken
5078 ;; to perform the move. They are there to discourage the use of floating-
5079 ;; point registers for storing integer values.
5080 (define_insn "*movsi_media"
5081   [(set (match_operand:SI 0 "general_movdst_operand"
5082                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5083         (match_operand:SI 1 "general_movsrc_operand"
5084          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5085   "TARGET_SHMEDIA_FPU
5086    && (register_operand (operands[0], SImode)
5087        || sh_register_operand (operands[1], SImode)
5088        || GET_CODE (operands[1]) == TRUNCATE)"
5089   "@
5090         add.l   %1, r63, %0
5091         movi    %1, %0
5092         #
5093         ld%M1.l %m1, %0
5094         st%M0.l %m0, %N1
5095         fld%M1.s        %m1, %0
5096         fst%M0.s        %m0, %1
5097         fmov.ls %N1, %0
5098         fmov.sl %1, %0
5099         fmov.s  %1, %0
5100         ptabs   %1, %0
5101         gettr   %1, %0
5102         pt      %1, %0"
5103   [(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")
5104    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5105    (set (attr "highpart")
5106         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5107                (const_string "user")]
5108               (const_string "ignore")))])
5110 (define_insn "*movsi_media_nofpu"
5111   [(set (match_operand:SI 0 "general_movdst_operand"
5112                 "=r,r,r,r,m,*b,r,*b")
5113         (match_operand:SI 1 "general_movsrc_operand"
5114          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5115   "TARGET_SHMEDIA
5116    && (register_operand (operands[0], SImode)
5117        || sh_register_operand (operands[1], SImode)
5118        || GET_CODE (operands[1]) == TRUNCATE)"
5119   "@
5120         add.l   %1, r63, %0
5121         movi    %1, %0
5122         #
5123         ld%M1.l %m1, %0
5124         st%M0.l %m0, %N1
5125         ptabs   %1, %0
5126         gettr   %1, %0
5127         pt      %1, %0"
5128   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5129    (set_attr "length" "4,4,8,4,4,4,4,12")
5130    (set (attr "highpart")
5131         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5132                (const_string "user")]
5133               (const_string "ignore")))])
5135 (define_expand "movsi_const"
5136   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5137         (const:SI (sign_extend:SI
5138                    (truncate:HI
5139                     (ashiftrt:SI
5140                      (match_operand:DI 1 "immediate_operand" "s")
5141                      (const_int 16))))))
5142    (set (match_dup 0)
5143         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5144                 (const:SI
5145                   (zero_extend:SI
5146                    (truncate:HI (match_dup 1))))))]
5147   "TARGET_SHMEDIA && reload_completed
5148    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5149   "
5151   if (GET_CODE (operands[1]) == LABEL_REF
5152       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5153     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5154   else if (GOTOFF_P (operands[1]))
5155     {
5156       rtx unspec = XEXP (operands[1], 0);
5158       if (! UNSPEC_GOTOFF_P (unspec))
5159         {
5160           unspec = XEXP (unspec, 0);
5161           if (! UNSPEC_GOTOFF_P (unspec))
5162             abort ();
5163         }
5164       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5165           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5166         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5167     }
5170 (define_expand "movsi_const_16bit"
5171   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5172         (const:SI (sign_extend:SI
5173                    (truncate:HI
5174                     (match_operand:DI 1 "immediate_operand" "s")))))]
5175   "TARGET_SHMEDIA && flag_pic && reload_completed
5176    && GET_CODE (operands[1]) == SYMBOL_REF"
5177   "")
5179 (define_split
5180   [(set (match_operand:SI 0 "arith_reg_dest" "")
5181         (match_operand:SI 1 "immediate_operand" ""))]
5182   "TARGET_SHMEDIA && reload_completed
5183    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5184   [(const_int 0)]
5185   "
5187   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5189   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5191   DONE;
5194 (define_split
5195   [(set (match_operand:SI 0 "register_operand" "")
5196         (match_operand:SI 1 "immediate_operand" ""))]
5197   "TARGET_SHMEDIA && reload_completed
5198    && ((GET_CODE (operands[1]) == CONST_INT
5199         && ! satisfies_constraint_I16 (operands[1]))
5200        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5201   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5203 (define_expand "movsi"
5204   [(set (match_operand:SI 0 "general_movdst_operand" "")
5205         (match_operand:SI 1 "general_movsrc_operand" ""))]
5206   ""
5207   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5209 (define_expand "ic_invalidate_line"
5210   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5211                                 (match_dup 1)] UNSPEC_ICACHE)
5212               (clobber (scratch:SI))])]
5213   "TARGET_HARD_SH4 || TARGET_SH5"
5214   "
5216   if (TARGET_SHMEDIA)
5217     {
5218       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5219       DONE;
5220     }
5221   else if (TARGET_SHCOMPACT)
5222     {
5223       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5224       operands[1] = force_reg (Pmode, operands[1]);
5225       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5226       DONE;
5227     }
5228   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5229     {
5230       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5231       DONE;
5232     }
5233   operands[0] = force_reg (Pmode, operands[0]);
5234   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5235                                                                Pmode)));
5238 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5239 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5240 ;; the requirement *1*00 for associative address writes.  The alignment of
5241 ;; %0 implies that its least significant bit is cleared,
5242 ;; thus we clear the V bit of a matching entry if there is one.
5243 (define_insn "ic_invalidate_line_i"
5244   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5245                      (match_operand:SI 1 "register_operand" "r")]
5246                      UNSPEC_ICACHE)
5247    (clobber (match_scratch:SI 2 "=&r"))]
5248   "TARGET_HARD_SH4"
5249   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5250   [(set_attr "length" "8")
5251    (set_attr "type" "cwb")])
5253 (define_insn "ic_invalidate_line_sh4a"
5254   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5255                     UNSPEC_ICACHE)]
5256   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5257   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5258   [(set_attr "length" "16")
5259    (set_attr "type" "cwb")])
5261 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5262 ;; an add in the code that calculates the address.
5263 (define_insn "ic_invalidate_line_media"
5264   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5265                     UNSPEC_ICACHE)]
5266   "TARGET_SHMEDIA"
5267   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5268   [(set_attr "length" "16")
5269    (set_attr "type" "invalidate_line_media")])
5271 (define_insn "ic_invalidate_line_compact"
5272   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5273                      (match_operand:SI 1 "register_operand" "r")]
5274                     UNSPEC_ICACHE)
5275    (clobber (reg:SI PR_REG))]
5276   "TARGET_SHCOMPACT"
5277   "jsr @%1%#"
5278   [(set_attr "type" "sfunc")
5279    (set_attr "needs_delay_slot" "yes")])
5281 (define_expand "initialize_trampoline"
5282   [(match_operand:SI 0 "" "")
5283    (match_operand:SI 1 "" "")
5284    (match_operand:SI 2 "" "")]
5285   "TARGET_SHCOMPACT"
5286   "
5288   rtx sfun, tramp;
5290   tramp = force_reg (Pmode, operands[0]);
5291   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5292                                             SFUNC_STATIC));
5293   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5294   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5296   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5297   DONE;
5300 (define_insn "initialize_trampoline_compact"
5301   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5302                      (match_operand:SI 1 "register_operand" "r")
5303                      (reg:SI R2_REG) (reg:SI R3_REG)]
5304                     UNSPEC_INIT_TRAMP)
5306    (clobber (reg:SI PR_REG))]
5307   "TARGET_SHCOMPACT"
5308   "jsr @%1%#"
5309   [(set_attr "type" "sfunc")
5310    (set_attr "needs_delay_slot" "yes")])
5312 (define_insn "movqi_i"
5313   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5314         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5315   "TARGET_SH1
5316    && (arith_reg_operand (operands[0], QImode)
5317        || arith_reg_operand (operands[1], QImode))"
5318   "@
5319         mov     %1,%0
5320         mov     %1,%0
5321         mov.b   %1,%0
5322         mov.b   %1,%0
5323         movt    %0
5324         sts     %1,%0
5325         lds     %1,%0"
5326  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5327   (set_attr_alternative "length"
5328      [(const_int 2)
5329       (const_int 2)
5330       (if_then_else
5331         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5332         (const_int 4) (const_int 2))
5333       (if_then_else
5334         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5335         (const_int 4) (const_int 2))
5336       (const_int 2)
5337       (const_int 2)
5338       (const_int 2)])])
5340 (define_insn "*movqi_media"
5341   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5342         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5343   "TARGET_SHMEDIA
5344    && (arith_reg_operand (operands[0], QImode)
5345        || extend_reg_or_0_operand (operands[1], QImode))"
5346   "@
5347         add.l   %1, r63, %0
5348         movi    %1, %0
5349         ld%M1.ub        %m1, %0
5350         st%M0.b %m0, %N1"
5351   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5352    (set (attr "highpart")
5353         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5354                (const_string "user")]
5355               (const_string "ignore")))])
5357 (define_expand "movqi"
5358   [(set (match_operand:QI 0 "general_operand" "")
5359         (match_operand:QI 1 "general_operand"  ""))]
5360   ""
5361   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5363 (define_expand "reload_inqi"
5364   [(set (match_operand:SI 2 "" "=&r")
5365         (match_operand:QI 1 "inqhi_operand" ""))
5366    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5367         (truncate:QI (match_dup 3)))]
5368   "TARGET_SHMEDIA"
5369   "
5371   rtx inner = XEXP (operands[1], 0);
5372   int regno = REGNO (inner);
5374   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5375   operands[1] = gen_rtx_REG (SImode, regno);
5376   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5379 /* When storing r0, we have to avoid reg+reg addressing.  */
5380 (define_insn "movhi_i"
5381   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5382         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5383   "TARGET_SH1
5384    && (arith_reg_operand (operands[0], HImode)
5385        || arith_reg_operand (operands[1], HImode))
5386    && (GET_CODE (operands[0]) != MEM
5387        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5388        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5389        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5390   "@
5391         mov.w   %1,%0
5392         mov     %1,%0
5393         mov.w   %1,%0
5394         movt    %0
5395         mov.w   %1,%0
5396         sts     %1,%0
5397         lds     %1,%0
5398         fake    %1,%0"
5399   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5401 (define_insn "*movhi_media"
5402   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5403         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5404   "TARGET_SHMEDIA
5405    && (arith_reg_operand (operands[0], HImode)
5406        || arith_reg_or_0_operand (operands[1], HImode))"
5407   "@
5408         add.l   %1, r63, %0
5409         movi    %1, %0
5410         #
5411         ld%M1.w %m1, %0
5412         st%M0.w %m0, %N1"
5413   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5414    (set (attr "highpart")
5415         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5416                (const_string "user")]
5417               (const_string "ignore")))])
5419 (define_split
5420   [(set (match_operand:HI 0 "register_operand" "")
5421         (match_operand:HI 1 "immediate_operand" ""))]
5422   "TARGET_SHMEDIA && reload_completed
5423    && ! satisfies_constraint_I16 (operands[1])"
5424   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5426 (define_expand "movhi"
5427   [(set (match_operand:HI 0 "general_movdst_operand" "")
5428         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5429   ""
5430   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5432 (define_expand "reload_inhi"
5433   [(set (match_operand:SI 2 "" "=&r")
5434         (match_operand:HI 1 "inqhi_operand" ""))
5435    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5436         (truncate:HI (match_dup 3)))]
5437   "TARGET_SHMEDIA"
5438   "
5440   rtx inner = XEXP (operands[1], 0);
5441   int regno = REGNO (inner);
5443   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5444   operands[1] = gen_rtx_REG (SImode, regno);
5445   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5448 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5449 ;; compiled with -m2 -ml -O3 -funroll-loops
5450 (define_insn "*movdi_i"
5451   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5452         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5453   "TARGET_SH1
5454    && (arith_reg_operand (operands[0], DImode)
5455        || arith_reg_operand (operands[1], DImode))"
5456   "* return output_movedouble (insn, operands, DImode);"
5457   [(set_attr "length" "4")
5458    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5460 ;; If the output is a register and the input is memory or a register, we have
5461 ;; to be careful and see which word needs to be loaded first.
5463 (define_split
5464   [(set (match_operand:DI 0 "general_movdst_operand" "")
5465         (match_operand:DI 1 "general_movsrc_operand" ""))]
5466   "TARGET_SH1 && reload_completed"
5467   [(set (match_dup 2) (match_dup 3))
5468    (set (match_dup 4) (match_dup 5))]
5469   "
5471   int regno;
5473   if ((GET_CODE (operands[0]) == MEM
5474        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5475       || (GET_CODE (operands[1]) == MEM
5476           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5477     FAIL;
5479   switch (GET_CODE (operands[0]))
5480     {
5481     case REG:
5482       regno = REGNO (operands[0]);
5483       break;
5484     case SUBREG:
5485       regno = subreg_regno (operands[0]);
5486       break;
5487     case MEM:
5488       regno = -1;
5489       break;
5490     default:
5491       gcc_unreachable ();
5492     }
5494   if (regno == -1
5495       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5496     {
5497       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5498       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5499       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5500       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5501     }
5502   else
5503     {
5504       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5505       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5506       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5507       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5508     }
5510   if (operands[2] == 0 || operands[3] == 0
5511       || operands[4] == 0 || operands[5] == 0)
5512     FAIL;
5515 ;; The '?'s in the following constraints may not reflect the time taken
5516 ;; to perform the move. They are there to discourage the use of floating-
5517 ;; point registers for storing integer values.
5518 (define_insn "*movdi_media"
5519   [(set (match_operand:DI 0 "general_movdst_operand"
5520                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5521         (match_operand:DI 1 "general_movsrc_operand"
5522          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5523   "TARGET_SHMEDIA_FPU
5524    && (register_operand (operands[0], DImode)
5525        || sh_register_operand (operands[1], DImode))"
5526   "@
5527         add     %1, r63, %0
5528         movi    %1, %0
5529         #
5530         ld%M1.q %m1, %0
5531         st%M0.q %m0, %N1
5532         fld%M1.d        %m1, %0
5533         fst%M0.d        %m0, %1
5534         fmov.qd %N1, %0
5535         fmov.dq %1, %0
5536         fmov.d  %1, %0
5537         ptabs   %1, %0
5538         gettr   %1, %0
5539         pt      %1, %0"
5540   [(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")
5541    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5543 (define_insn "*movdi_media_nofpu"
5544   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5545         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5546   "TARGET_SHMEDIA
5547    && (register_operand (operands[0], DImode)
5548        || sh_register_operand (operands[1], DImode))"
5549   "@
5550         add     %1, r63, %0
5551         movi    %1, %0
5552         #
5553         ld%M1.q %m1, %0
5554         st%M0.q %m0, %N1
5555         ptabs   %1, %0
5556         gettr   %1, %0
5557         pt      %1, %0"
5558   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5559    (set_attr "length" "4,4,16,4,4,4,4,*")])
5561 (define_insn "*movdi_media_I16"
5562   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5563         (match_operand:DI 1 "const_int_operand" "I16"))]
5564   "TARGET_SHMEDIA && reload_completed"
5565   "movi %1, %0"
5566   [(set_attr "type" "arith_media")
5567    (set_attr "length" "4")])
5569 (define_split
5570   [(set (match_operand:DI 0 "arith_reg_dest" "")
5571         (match_operand:DI 1 "immediate_operand" ""))]
5572   "TARGET_SHMEDIA && reload_completed
5573    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5574   [(set (match_dup 0) (match_dup 1))]
5575   "
5577   rtx insn;
5579   if (TARGET_SHMEDIA64)
5580     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5581   else
5582     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5584   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5586   DONE;
5589 (define_expand "movdi_const"
5590   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5591         (const:DI (sign_extend:DI
5592                    (truncate:HI
5593                     (ashiftrt:DI
5594                      (match_operand:DI 1 "immediate_operand" "s")
5595                      (const_int 48))))))
5596    (set (match_dup 0)
5597         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5598                 (const:DI
5599                  (zero_extend:DI
5600                   (truncate:HI
5601                    (ashiftrt:SI
5602                     (match_dup 1)
5603                     (const_int 32)))))))
5604    (set (match_dup 0)
5605         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5606                 (const:DI
5607                  (zero_extend:DI
5608                   (truncate:HI
5609                    (ashiftrt:SI
5610                     (match_dup 1)
5611                     (const_int 16)))))))
5612    (set (match_dup 0)
5613         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5614                 (const:DI
5615                  (zero_extend:DI
5616                   (truncate:HI
5617                    (match_dup 1))))))]
5618   "TARGET_SHMEDIA64 && reload_completed
5619    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5620   "
5622   sh_mark_label (operands[1], 4);
5625 (define_expand "movdi_const_32bit"
5626   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5627         (const:DI (sign_extend:DI
5628                    (truncate:HI
5629                     (ashiftrt:DI
5630                      (match_operand:DI 1 "immediate_operand" "s")
5631                      (const_int 16))))))
5632    (set (match_dup 0)
5633         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5634                 (const:DI
5635                  (zero_extend:DI
5636                   (truncate:HI
5637                    (match_dup 1))))))]
5638   "TARGET_SHMEDIA32 && reload_completed
5639    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5640   "
5642   sh_mark_label (operands[1], 2);
5645 (define_expand "movdi_const_16bit"
5646   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5647         (const:DI (sign_extend:DI
5648                    (truncate:HI
5649                     (match_operand:DI 1 "immediate_operand" "s")))))]
5650   "TARGET_SHMEDIA && flag_pic && reload_completed
5651    && GET_CODE (operands[1]) == SYMBOL_REF"
5652   "")
5654 (define_split
5655   [(set (match_operand:DI 0 "ext_dest_operand" "")
5656         (match_operand:DI 1 "immediate_operand" ""))]
5657   "TARGET_SHMEDIA && reload_completed
5658    && GET_CODE (operands[1]) == CONST_INT
5659    && ! satisfies_constraint_I16 (operands[1])"
5660   [(set (match_dup 0) (match_dup 2))
5661    (match_dup 1)]
5662   "
5664   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5665   unsigned HOST_WIDE_INT low = val;
5666   unsigned HOST_WIDE_INT high = val;
5667   unsigned HOST_WIDE_INT sign;
5668   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5670   /* Zero-extend the 16 least-significant bits.  */
5671   low &= 0xffff;
5673   /* Arithmetic shift right the word by 16 bits.  */
5674   high >>= 16;
5675   if (GET_CODE (operands[0]) == SUBREG
5676       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5677     {
5678       high &= 0xffff;
5679       high ^= 0x8000;
5680       high -= 0x8000;
5681     }
5682   else
5683     {
5684       sign = 1;
5685       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5686       high ^= sign;
5687       high -= sign;
5688     }
5689   do
5690     {
5691       /* If we can't generate the constant with a two-insn movi / shori
5692          sequence, try some other strategies.  */
5693       if (! CONST_OK_FOR_I16 (high))
5694         {
5695           /* Try constant load / left shift.  We know VAL != 0.  */
5696           val2 = val ^ (val-1);
5697           if (val2 > 0x1ffff)
5698             {
5699               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5701               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5702                   || (! CONST_OK_FOR_I16 (high >> 16)
5703                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5704                 {
5705                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5706                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5707                                                    GEN_INT (trailing_zeroes));
5708                   break;
5709                 }
5710             }
5711           /* Try constant load / right shift.  */
5712           val2 = (val >> 15) + 1;
5713           if (val2 == (val2 & -val2))
5714             {
5715               int shift = 49 - exact_log2 (val2);
5717               val2 = trunc_int_for_mode (val << shift, DImode);
5718               if (CONST_OK_FOR_I16 (val2))
5719                 {
5720                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5721                                                    GEN_INT (shift));
5722                   break;
5723                 }
5724             }
5725           /* Try mperm.w .  */
5726           val2 = val & 0xffff;
5727           if ((val >> 16 & 0xffff) == val2
5728               && (val >> 32 & 0xffff) == val2
5729               && (val >> 48 & 0xffff) == val2)
5730             {
5731               val2 = (HOST_WIDE_INT) val >> 48;
5732               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5733               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5734               break;
5735             }
5736           /* Try movi / mshflo.l  */
5737           val2 = (HOST_WIDE_INT) val >> 32;
5738           if (val2 == ((unsigned HOST_WIDE_INT)
5739                         trunc_int_for_mode (val, SImode)))
5740             {
5741               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5742                                              operands[0]);
5743               break;
5744             }
5745           /* Try movi / mshflo.l w/ r63.  */
5746           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5747           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5748             {
5749               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5750                                              const0_rtx);
5751               break;
5752             }
5753         }
5754       val2 = high;
5755       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5756     }
5757   while (0);
5758   operands[2] = GEN_INT (val2);
5761 (define_split
5762   [(set (match_operand:DI 0 "ext_dest_operand" "")
5763         (match_operand:DI 1 "immediate_operand" ""))]
5764   "TARGET_SHMEDIA && reload_completed
5765    && GET_CODE (operands[1]) == CONST_DOUBLE"
5766   [(set (match_dup 0) (match_dup 2))
5767   (set (match_dup 0)
5768        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5769   "
5771   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5772   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5773   unsigned HOST_WIDE_INT val = low;
5774   unsigned HOST_WIDE_INT sign;
5776   /* Zero-extend the 16 least-significant bits.  */
5777   val &= 0xffff;
5778   operands[1] = GEN_INT (val);
5780   /* Arithmetic shift right the double-word by 16 bits.  */
5781   low >>= 16;
5782   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5783   high >>= 16;
5784   sign = 1;
5785   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5786   high ^= sign;
5787   high -= sign;
5789   /* This will only be true if high is a sign-extension of low, i.e.,
5790      it must be either 0 or (unsigned)-1, and be zero iff the
5791      most-significant bit of low is set.  */
5792   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5793     operands[2] = GEN_INT (low);
5794   else
5795     operands[2] = immed_double_const (low, high, DImode);
5798 (define_insn "shori_media"
5799   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5800         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5801                            (const_int 16))
5802                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5803   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5804   "@
5805         shori   %u2, %0
5806         #"
5807   [(set_attr "type" "arith_media,*")])
5809 (define_insn "*shori_media_si"
5810   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5811         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5812                            (const_int 16))
5813                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5814   "TARGET_SHMEDIA"
5815   "shori        %u2, %0")
5817 (define_expand "movdi"
5818   [(set (match_operand:DI 0 "general_movdst_operand" "")
5819         (match_operand:DI 1 "general_movsrc_operand" ""))]
5820   ""
5821   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5823 (define_insn "movdf_media"
5824   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5825         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5826   "TARGET_SHMEDIA_FPU
5827    && (register_operand (operands[0], DFmode)
5828        || sh_register_operand (operands[1], DFmode))"
5829   "@
5830         fmov.d  %1, %0
5831         fmov.qd %N1, %0
5832         fmov.dq %1, %0
5833         add     %1, r63, %0
5834         #
5835         fld%M1.d        %m1, %0
5836         fst%M0.d        %m0, %1
5837         ld%M1.q %m1, %0
5838         st%M0.q %m0, %N1"
5839   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5841 (define_insn "movdf_media_nofpu"
5842   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5843         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5844   "TARGET_SHMEDIA
5845    && (register_operand (operands[0], DFmode)
5846        || sh_register_operand (operands[1], DFmode))"
5847   "@
5848         add     %1, r63, %0
5849         #
5850         ld%M1.q %m1, %0
5851         st%M0.q %m0, %N1"
5852   [(set_attr "type" "arith_media,*,load_media,store_media")])
5854 (define_split
5855   [(set (match_operand:DF 0 "arith_reg_dest" "")
5856         (match_operand:DF 1 "immediate_operand" ""))]
5857   "TARGET_SHMEDIA && reload_completed"
5858   [(set (match_dup 3) (match_dup 2))]
5859   "
5861   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5862   long values[2];
5863   REAL_VALUE_TYPE value;
5865   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5866   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5868   if (HOST_BITS_PER_WIDE_INT >= 64)
5869     operands[2] = immed_double_const ((unsigned long) values[endian]
5870                                       | ((HOST_WIDE_INT) values[1 - endian]
5871                                          << 32), 0, DImode);
5872   else
5873     {
5874       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5875       operands[2] = immed_double_const (values[endian], values[1 - endian],
5876                                         DImode);
5877     }
5879   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5882 ;; ??? This should be a define expand.
5884 (define_insn "movdf_k"
5885   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5886         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5887   "TARGET_SH1
5888    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5889        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5890        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5891        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5892    && (arith_reg_operand (operands[0], DFmode)
5893        || arith_reg_operand (operands[1], DFmode))"
5894   "* return output_movedouble (insn, operands, DFmode);"
5895   [(set_attr "length" "4")
5896    (set_attr "type" "move,pcload,load,store")])
5898 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5899 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5900 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5901 ;; the d/m/c/X alternative, which is split later into single-precision
5902 ;; instructions.  And when not optimizing, no splits are done before fixing
5903 ;; up pcloads, so we need usable length information for that.
5904 (define_insn "movdf_i4"
5905   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5906         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5907    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5908    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5909   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5910    && (arith_reg_operand (operands[0], DFmode)
5911        || arith_reg_operand (operands[1], DFmode))"
5912   "@
5913         fmov    %1,%0
5914         #
5915         #
5916         fmov.d  %1,%0
5917         fmov.d  %1,%0
5918         #
5919         #
5920         #
5921         #
5922         #"
5923   [(set_attr_alternative "length"
5924      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5925       (const_int 4)
5926       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5927       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5928       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5929       (const_int 4)
5930       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5931       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5932       ;; increment or decrement r15 explicitly.
5933       (if_then_else
5934        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5935        (const_int 10) (const_int 8))
5936       (if_then_else
5937        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5938        (const_int 10) (const_int 8))])
5939    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5940    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5941    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5942                                            (const_string "double")
5943                                            (const_string "none")))])
5945 ;; Moving DFmode between fp/general registers through memory
5946 ;; (the top of the stack) is faster than moving through fpul even for
5947 ;; little endian.  Because the type of an instruction is important for its
5948 ;; scheduling,  it is beneficial to split these operations, rather than
5949 ;; emitting them in one single chunk, even if this will expose a stack
5950 ;; use that will prevent scheduling of other stack accesses beyond this
5951 ;; instruction.
5952 (define_split
5953   [(set (match_operand:DF 0 "register_operand" "")
5954         (match_operand:DF 1 "register_operand" ""))
5955    (use (match_operand:PSI 2 "fpscr_operand" ""))
5956    (clobber (match_scratch:SI 3 "=X"))]
5957   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5958    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5959   [(const_int 0)]
5960   "
5962   rtx insn, tos;
5964   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5965     {
5966       emit_move_insn (stack_pointer_rtx,
5967                       plus_constant (stack_pointer_rtx, -8));
5968       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5969     }
5970   else
5971     tos = gen_tmp_stack_mem (DFmode,
5972                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5973   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5974   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5975     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5976   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5977     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5978   else
5979     tos = gen_tmp_stack_mem (DFmode,
5980                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5981   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5982   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5983     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5984   else
5985     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5986   DONE;
5989 ;; local-alloc sometimes allocates scratch registers even when not required,
5990 ;; so we must be prepared to handle these.
5992 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5993 (define_split
5994   [(set (match_operand:DF 0 "general_movdst_operand" "")
5995         (match_operand:DF 1 "general_movsrc_operand"  ""))
5996    (use (match_operand:PSI 2 "fpscr_operand" ""))
5997    (clobber (match_scratch:SI 3 ""))]
5998   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5999    && reload_completed
6000    && true_regnum (operands[0]) < 16
6001    && true_regnum (operands[1]) < 16"
6002   [(set (match_dup 0) (match_dup 1))]
6003   "
6005   /* If this was a reg <-> mem operation with base + index reg addressing,
6006      we have to handle this in a special way.  */
6007   rtx mem = operands[0];
6008   int store_p = 1;
6009   if (! memory_operand (mem, DFmode))
6010     {
6011       mem = operands[1];
6012       store_p = 0;
6013     }
6014   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
6015     mem = SUBREG_REG (mem);
6016   if (GET_CODE (mem) == MEM)
6017     {
6018       rtx addr = XEXP (mem, 0);
6019       if (GET_CODE (addr) == PLUS
6020           && GET_CODE (XEXP (addr, 0)) == REG
6021           && GET_CODE (XEXP (addr, 1)) == REG)
6022         {
6023           int offset;
6024           rtx reg0 = gen_rtx_REG (Pmode, 0);
6025           rtx regop = operands[store_p], word0 ,word1;
6027           if (GET_CODE (regop) == SUBREG)
6028             alter_subreg (&regop);
6029           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
6030             offset = 2;
6031           else
6032             offset = 4;
6033           mem = copy_rtx (mem);
6034           PUT_MODE (mem, SImode);
6035           word0 = gen_rtx_SUBREG (SImode, regop, 0);
6036           alter_subreg (&word0);
6037           word1 = gen_rtx_SUBREG (SImode, regop, 4);
6038           alter_subreg (&word1);
6039           if (store_p || ! refers_to_regno_p (REGNO (word0),
6040                                               REGNO (word0) + 1, addr, 0))
6041             {
6042               emit_insn (store_p
6043                          ? gen_movsi_ie (mem, word0)
6044                          : gen_movsi_ie (word0, mem));
6045               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6046               mem = copy_rtx (mem);
6047               emit_insn (store_p
6048                          ? gen_movsi_ie (mem, word1)
6049                          : gen_movsi_ie (word1, mem));
6050               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6051             }
6052           else
6053             {
6054               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
6055               emit_insn (gen_movsi_ie (word1, mem));
6056               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
6057               mem = copy_rtx (mem);
6058               emit_insn (gen_movsi_ie (word0, mem));
6059             }
6060           DONE;
6061         }
6062     }
6065 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
6066 (define_split
6067   [(set (match_operand:DF 0 "register_operand" "")
6068         (match_operand:DF 1 "memory_operand"  ""))
6069    (use (match_operand:PSI 2 "fpscr_operand" ""))
6070    (clobber (reg:SI R0_REG))]
6071   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
6072   [(parallel [(set (match_dup 0) (match_dup 1))
6073               (use (match_dup 2))
6074               (clobber (scratch:SI))])]
6075   "")
6077 (define_expand "reload_indf__frn"
6078   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
6079                    (match_operand:DF 1 "immediate_operand" "FQ"))
6080               (use (reg:PSI FPSCR_REG))
6081               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6082   "TARGET_SH1"
6083   "")
6085 (define_expand "reload_outdf__RnFRm"
6086   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
6087                    (match_operand:DF 1 "register_operand" "af,r"))
6088               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
6089   "TARGET_SH1"
6090   "")
6092 ;; Simplify no-op moves.
6093 (define_split
6094   [(set (match_operand:SF 0 "register_operand" "")
6095         (match_operand:SF 1 "register_operand" ""))
6096    (use (match_operand:PSI 2 "fpscr_operand" ""))
6097    (clobber (match_scratch:SI 3 ""))]
6098   "TARGET_SH2E && reload_completed
6099    && true_regnum (operands[0]) == true_regnum (operands[1])"
6100   [(set (match_dup 0) (match_dup 0))]
6101   "")
6103 ;; fmovd substitute post-reload splits
6104 (define_split
6105   [(set (match_operand:DF 0 "register_operand" "")
6106         (match_operand:DF 1 "register_operand" ""))
6107    (use (match_operand:PSI 2 "fpscr_operand" ""))
6108    (clobber (match_scratch:SI 3 ""))]
6109   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6110    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6111    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6112   [(const_int 0)]
6113   "
6115   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6116   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6117                            gen_rtx_REG (SFmode, src), operands[2]));
6118   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6119                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6120   DONE;
6123 (define_split
6124   [(set (match_operand:DF 0 "register_operand" "")
6125         (mem:DF (match_operand:SI 1 "register_operand" "")))
6126    (use (match_operand:PSI 2 "fpscr_operand" ""))
6127    (clobber (match_scratch:SI 3 ""))]
6128   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6129    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6130    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6131   [(const_int 0)]
6132   "
6134   int regno = true_regnum (operands[0]);
6135   rtx insn;
6136   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6137   rtx mem2
6138     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6139   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6140                                            regno + !! TARGET_LITTLE_ENDIAN),
6141                                   mem2, operands[2]));
6142   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
6143   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6144                                                regno + ! TARGET_LITTLE_ENDIAN),
6145                                   change_address (mem, SFmode, NULL_RTX),
6146                                   operands[2]));
6147   DONE;
6150 (define_split
6151   [(set (match_operand:DF 0 "register_operand" "")
6152         (match_operand:DF 1 "memory_operand" ""))
6153    (use (match_operand:PSI 2 "fpscr_operand" ""))
6154    (clobber (match_scratch:SI 3 ""))]
6155   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6156    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6157   [(const_int 0)]
6158   "
6160   int regno = true_regnum (operands[0]);
6161   rtx addr, insn, adjust = NULL_RTX;
6162   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6163   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
6164   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
6166   operands[1] = copy_rtx (mem2);
6167   addr = XEXP (mem2, 0);
6168   if (GET_CODE (addr) != POST_INC)
6169     {
6170       /* If we have to modify the stack pointer, the value that we have
6171          read with post-increment might be modified by an interrupt,
6172          so write it back.  */
6173       if (REGNO (addr) == STACK_POINTER_REGNUM)
6174         adjust = gen_push_e (reg0);
6175       else
6176         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
6177       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6178     }
6179   addr = XEXP (addr, 0);
6180   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6181   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6182   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6183   if (adjust)
6184     emit_insn (adjust);
6185   else
6186     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6187   DONE;
6190 (define_split
6191   [(set (match_operand:DF 0 "memory_operand" "")
6192         (match_operand:DF 1 "register_operand" ""))
6193    (use (match_operand:PSI 2 "fpscr_operand" ""))
6194    (clobber (match_scratch:SI 3 ""))]
6195   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6196    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6197   [(const_int 0)]
6198   "
6200   int regno = true_regnum (operands[1]);
6201   rtx insn, addr, adjust = NULL_RTX;
6203   operands[0] = copy_rtx (operands[0]);
6204   PUT_MODE (operands[0], SFmode);
6205   insn = emit_insn (gen_movsf_ie (operands[0],
6206                                   gen_rtx_REG (SFmode,
6207                                            regno + ! TARGET_LITTLE_ENDIAN),
6208                                   operands[2]));
6209   operands[0] = copy_rtx (operands[0]);
6210   addr = XEXP (operands[0], 0);
6211   if (GET_CODE (addr) != PRE_DEC)
6212     {
6213       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
6214       emit_insn_before (adjust, insn);
6215       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6216     }
6217   addr = XEXP (addr, 0);
6218   if (! adjust)
6219     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6220   insn = emit_insn (gen_movsf_ie (operands[0],
6221                                   gen_rtx_REG (SFmode,
6222                                            regno + !! TARGET_LITTLE_ENDIAN),
6223                                   operands[2]));
6224   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
6225   DONE;
6228 ;; If the output is a register and the input is memory or a register, we have
6229 ;; to be careful and see which word needs to be loaded first.
6231 (define_split
6232   [(set (match_operand:DF 0 "general_movdst_operand" "")
6233         (match_operand:DF 1 "general_movsrc_operand" ""))]
6234   "TARGET_SH1 && reload_completed"
6235   [(set (match_dup 2) (match_dup 3))
6236    (set (match_dup 4) (match_dup 5))]
6237   "
6239   int regno;
6241   if ((GET_CODE (operands[0]) == MEM
6242        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6243       || (GET_CODE (operands[1]) == MEM
6244           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6245     FAIL;
6247   switch (GET_CODE (operands[0]))
6248     {
6249     case REG:
6250       regno = REGNO (operands[0]);
6251       break;
6252     case SUBREG:
6253       regno = subreg_regno (operands[0]);
6254       break;
6255     case MEM:
6256       regno = -1;
6257       break;
6258     default:
6259       gcc_unreachable ();
6260     }
6262   if (regno == -1
6263       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6264     {
6265       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6266       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6267       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6268       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6269     }
6270   else
6271     {
6272       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6273       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6274       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6275       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6276     }
6278   if (operands[2] == 0 || operands[3] == 0
6279       || operands[4] == 0 || operands[5] == 0)
6280     FAIL;
6283 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6284 ;; used only once, let combine add in the index again.
6286 (define_split
6287   [(set (match_operand:SI 0 "register_operand" "")
6288         (match_operand:SI 1 "" ""))
6289    (clobber (match_operand 2 "register_operand" ""))]
6290   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6291    && ALLOW_INDEXED_ADDRESS"
6292   [(use (reg:SI R0_REG))]
6293   "
6295   rtx addr, reg, const_int;
6297   if (GET_CODE (operands[1]) != MEM)
6298     FAIL;
6299   addr = XEXP (operands[1], 0);
6300   if (GET_CODE (addr) != PLUS)
6301     FAIL;
6302   reg = XEXP (addr, 0);
6303   const_int = XEXP (addr, 1);
6304   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6305          && GET_CODE (const_int) == CONST_INT))
6306     FAIL;
6307   emit_move_insn (operands[2], const_int);
6308   emit_move_insn (operands[0],
6309                   change_address (operands[1], VOIDmode,
6310                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6311   DONE;
6314 (define_split
6315   [(set (match_operand:SI 1 "" "")
6316         (match_operand:SI 0 "register_operand" ""))
6317    (clobber (match_operand 2 "register_operand" ""))]
6318   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6319    && ALLOW_INDEXED_ADDRESS"
6320   [(use (reg:SI R0_REG))]
6321   "
6323   rtx addr, reg, const_int;
6325   if (GET_CODE (operands[1]) != MEM)
6326     FAIL;
6327   addr = XEXP (operands[1], 0);
6328   if (GET_CODE (addr) != PLUS)
6329     FAIL;
6330   reg = XEXP (addr, 0);
6331   const_int = XEXP (addr, 1);
6332   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6333          && GET_CODE (const_int) == CONST_INT))
6334     FAIL;
6335   emit_move_insn (operands[2], const_int);
6336   emit_move_insn (change_address (operands[1], VOIDmode,
6337                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6338                   operands[0]);
6339   DONE;
6342 (define_expand "movdf"
6343   [(set (match_operand:DF 0 "general_movdst_operand" "")
6344         (match_operand:DF 1 "general_movsrc_operand" ""))]
6345   ""
6346   "
6348   if (prepare_move_operands (operands, DFmode)) DONE;
6349   if (TARGET_SHMEDIA)
6350     {
6351       if (TARGET_SHMEDIA_FPU)
6352         emit_insn (gen_movdf_media (operands[0], operands[1]));
6353       else
6354         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6355       DONE;
6356     }
6357   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6358     {
6359       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6360       DONE;
6361     }
6364 ;;This is incompatible with the way gcc uses subregs.
6365 ;;(define_insn "movv2sf_i"
6366 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6367 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6368 ;;  "TARGET_SHMEDIA_FPU
6369 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6370 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6371 ;;  "@
6372 ;;      #
6373 ;;      fld%M1.p        %m1, %0
6374 ;;      fst%M0.p        %m0, %1"
6375 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6377 (define_insn_and_split "movv2sf_i"
6378   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6379         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6380   "TARGET_SHMEDIA_FPU"
6381   "#"
6382   "TARGET_SHMEDIA_FPU && reload_completed"
6383   [(set (match_dup 0) (match_dup 1))]
6384   "
6386   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6387   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6390 (define_expand "movv2sf"
6391   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6392         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6393   "TARGET_SHMEDIA_FPU"
6394   "
6396   if (prepare_move_operands (operands, V2SFmode))
6397     DONE;
6400 (define_expand "addv2sf3"
6401   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6402    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6403    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6404   "TARGET_SHMEDIA_FPU"
6405   "
6407   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6408   DONE;
6411 (define_expand "subv2sf3"
6412   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6413    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6414    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6415   "TARGET_SHMEDIA_FPU"
6416   "
6418   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6419   DONE;
6422 (define_expand "mulv2sf3"
6423   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6424    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6425    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6426   "TARGET_SHMEDIA_FPU"
6427   "
6429   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6430   DONE;
6433 (define_expand "divv2sf3"
6434   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6435    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6436    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6437   "TARGET_SHMEDIA_FPU"
6438   "
6440   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6441   DONE;
6444 (define_insn_and_split "*movv4sf_i"
6445   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6446         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6447   "TARGET_SHMEDIA_FPU"
6448   "#"
6449   "&& reload_completed"
6450   [(const_int 0)]
6451   "
6453   int i;
6455   for (i = 0; i < 4/2; i++)
6456     {
6457       rtx x, y;
6459       if (GET_CODE (operands[0]) == MEM)
6460         x = adjust_address (operands[0], V2SFmode,
6461                             i * GET_MODE_SIZE (V2SFmode));
6462       else
6463         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6465       if (GET_CODE (operands[1]) == MEM)
6466         y = adjust_address (operands[1], V2SFmode,
6467                             i * GET_MODE_SIZE (V2SFmode));
6468       else
6469         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6471       emit_insn (gen_movv2sf_i (x, y));
6472     }
6474   DONE;
6476   [(set_attr "length" "8")])
6478 (define_expand "movv4sf"
6479   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6480         (match_operand:V4SF 1 "general_operand" ""))]
6481   "TARGET_SHMEDIA_FPU"
6482   "
6484   if (prepare_move_operands (operands, V4SFmode))
6485     DONE;
6488 (define_insn_and_split "*movv16sf_i"
6489   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6490         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6491   "TARGET_SHMEDIA_FPU"
6492   "#"
6493   "&& reload_completed"
6494   [(const_int 0)]
6495   "
6497   int i;
6499   for (i = 0; i < 16/2; i++)
6500     {
6501       rtx x,y;
6503       if (GET_CODE (operands[0]) == MEM)
6504         x = adjust_address (operands[0], V2SFmode,
6505                             i * GET_MODE_SIZE (V2SFmode));
6506       else
6507         {
6508           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6509           alter_subreg (&x);
6510         }
6512       if (GET_CODE (operands[1]) == MEM)
6513         y = adjust_address (operands[1], V2SFmode,
6514                             i * GET_MODE_SIZE (V2SFmode));
6515       else
6516         {
6517           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6518           alter_subreg (&y);
6519         }
6521       emit_insn (gen_movv2sf_i (x, y));
6522     }
6524   DONE;
6526   [(set_attr "length" "32")])
6528 (define_expand "movv16sf"
6529   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6530         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6531   "TARGET_SHMEDIA_FPU"
6532   "
6534   if (prepare_move_operands (operands, V16SFmode))
6535     DONE;
6538 (define_insn "movsf_media"
6539   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6540         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6541   "TARGET_SHMEDIA_FPU
6542    && (register_operand (operands[0], SFmode)
6543        || sh_register_operand (operands[1], SFmode))"
6544   "@
6545         fmov.s  %1, %0
6546         fmov.ls %N1, %0
6547         fmov.sl %1, %0
6548         add.l   %1, r63, %0
6549         #
6550         fld%M1.s        %m1, %0
6551         fst%M0.s        %m0, %1
6552         ld%M1.l %m1, %0
6553         st%M0.l %m0, %N1"
6554   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6555    (set (attr "highpart")
6556         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6557                (const_string "user")]
6558               (const_string "ignore")))])
6560 (define_insn "movsf_media_nofpu"
6561   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6562         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6563   "TARGET_SHMEDIA
6564    && (register_operand (operands[0], SFmode)
6565        || sh_register_operand (operands[1], SFmode))"
6566   "@
6567         add.l   %1, r63, %0
6568         #
6569         ld%M1.l %m1, %0
6570         st%M0.l %m0, %N1"
6571   [(set_attr "type" "arith_media,*,load_media,store_media")
6572    (set (attr "highpart")
6573         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6574                (const_string "user")]
6575               (const_string "ignore")))])
6577 (define_split
6578   [(set (match_operand:SF 0 "arith_reg_dest" "")
6579         (match_operand:SF 1 "immediate_operand" ""))]
6580   "TARGET_SHMEDIA && reload_completed
6581    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6582   [(set (match_dup 3) (match_dup 2))]
6583   "
6585   long values;
6586   REAL_VALUE_TYPE value;
6588   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6589   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6590   operands[2] = GEN_INT (values);
6592   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6595 (define_insn "movsf_i"
6596   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6597         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6598   "TARGET_SH1
6599    && (! TARGET_SH2E
6600        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6601        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6602        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6603    && (arith_reg_operand (operands[0], SFmode)
6604        || arith_reg_operand (operands[1], SFmode))"
6605   "@
6606         mov     %1,%0
6607         mov     #0,%0
6608         mov.l   %1,%0
6609         mov.l   %1,%0
6610         mov.l   %1,%0
6611         lds     %1,%0
6612         sts     %1,%0"
6613   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6615 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6616 ;; update_flow_info would not know where to put REG_EQUAL notes
6617 ;; when the destination changes mode.
6618 (define_insn "movsf_ie"
6619   [(set (match_operand:SF 0 "general_movdst_operand"
6620          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6621         (match_operand:SF 1 "general_movsrc_operand"
6622           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6623    (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"))
6624    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6626   "TARGET_SH2E
6627    && (arith_reg_operand (operands[0], SFmode)
6628        || arith_reg_operand (operands[1], SFmode)
6629        || arith_reg_operand (operands[3], SImode)
6630        || (fpul_operand (operands[0], SFmode)
6631            && memory_operand (operands[1], SFmode)
6632            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6633        || (fpul_operand (operands[1], SFmode)
6634            && memory_operand (operands[0], SFmode)
6635            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6636   "@
6637         fmov    %1,%0
6638         mov     %1,%0
6639         fldi0   %0
6640         fldi1   %0
6641         #
6642         fmov.s  %1,%0
6643         fmov.s  %1,%0
6644         mov.l   %1,%0
6645         mov.l   %1,%0
6646         mov.l   %1,%0
6647         fsts    fpul,%0
6648         flds    %1,fpul
6649         lds.l   %1,%0
6650         #
6651         sts     %1,%0
6652         lds     %1,%0
6653         sts.l   %1,%0
6654         lds.l   %1,%0
6655         ! move optimized away"
6656   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6657    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6658    (set_attr "length" "*,*,*,*,4,2,2,*,*,*,2,2,2,4,2,2,2,2,0")
6659    (set_attr_alternative "length"
6660      [(const_int 2)
6661       (const_int 2)
6662       (const_int 2)
6663       (const_int 2)
6664       (const_int 4)
6665       (if_then_else
6666         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6667         (const_int 4) (const_int 2))
6668       (if_then_else
6669         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6670         (const_int 4) (const_int 2))
6671       (const_int 2)
6672       (const_int 2)
6673       (const_int 2)
6674       (const_int 2)
6675       (const_int 2)
6676       (const_int 2)
6677       (const_int 4)
6678       (const_int 2)
6679       (const_int 2)
6680       (const_int 2)
6681       (const_int 2)
6682       (const_int 0)])
6683    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6684                                            (const_string "single")
6685                                            (const_string "none")))])
6687 (define_split
6688   [(set (match_operand:SF 0 "register_operand" "")
6689         (match_operand:SF 1 "register_operand" ""))
6690    (use (match_operand:PSI 2 "fpscr_operand" ""))
6691    (clobber (reg:SI FPUL_REG))]
6692   "TARGET_SH1"
6693   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6694               (use (match_dup 2))
6695               (clobber (scratch:SI))])
6696    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6697               (use (match_dup 2))
6698               (clobber (scratch:SI))])]
6699   "")
6701 (define_expand "movsf"
6702   [(set (match_operand:SF 0 "general_movdst_operand" "")
6703         (match_operand:SF 1 "general_movsrc_operand" ""))]
6704   ""
6705   "
6707   if (prepare_move_operands (operands, SFmode))
6708     DONE;
6709   if (TARGET_SHMEDIA)
6710     {
6711       if (TARGET_SHMEDIA_FPU)
6712         emit_insn (gen_movsf_media (operands[0], operands[1]));
6713       else
6714         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6715       DONE;
6716     }
6717   if (TARGET_SH2E)
6718     {
6719       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6720       DONE;
6721     }
6724 (define_insn "mov_nop"
6725   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6726   "TARGET_SH2E"
6727   ""
6728   [(set_attr "length" "0")
6729    (set_attr "type" "nil")])
6731 (define_expand "reload_insf__frn"
6732   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6733                    (match_operand:SF 1 "immediate_operand" "FQ"))
6734               (use (reg:PSI FPSCR_REG))
6735               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6736   "TARGET_SH1"
6737   "")
6739 (define_expand "reload_insi__i_fpul"
6740   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6741                    (match_operand:SI 1 "immediate_operand" "i"))
6742               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6743   "TARGET_SH1"
6744   "")
6746 (define_expand "ptabs"
6747   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6748   "TARGET_SHMEDIA"
6749   "
6751   if (!TARGET_PT_FIXED)
6752     {
6753       rtx eq = operands[1];
6755       /* ??? For canonical RTL we really should remove any CONST from EQ
6756          before wrapping it in the AND, and finally wrap the EQ into a
6757          const if is constant.  However, for reload we must expose the
6758          input register or symbolic constant, and we can't have
6759          different insn structures outside of the operands for different
6760          alternatives of the same pattern.  */
6761       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6762                        GEN_INT (3));
6763       operands[1]
6764         = (gen_rtx_IF_THEN_ELSE
6765             (PDImode,
6766              eq,
6767              gen_rtx_MEM (PDImode, operands[1]),
6768              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6769                             PDImode, operands[1])));
6770     }
6773 ;; expanded by ptabs expander.
6774 (define_insn "*extendsipdi_media"
6775   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6776         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6777                                                           "r,Csy")
6778                                       (const_int 3))
6779                               (const_int 3))
6780                           (mem:PDI (match_dup 1))
6781                           (sign_extend:PDI (match_dup 1))))]
6782   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6783   "@
6784         ptabs   %1, %0
6785         pt      %1, %0"
6786   [(set_attr "type"   "ptabs_media,pt_media")
6787    (set_attr "length" "4,*")])
6789 (define_insn "*truncdipdi_media"
6790   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6791         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6792                                                           "r,Csy")
6793                                       (const_int 3))
6794                               (const_int 3))
6795                           (mem:PDI (match_dup 1))
6796                           (truncate:PDI (match_dup 1))))]
6797   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6798   "@
6799         ptabs   %1, %0
6800         pt      %1, %0"
6801   [(set_attr "type"   "ptabs_media,pt_media")
6802    (set_attr "length" "4,*")])
6804 (define_insn "*movsi_y"
6805   [(set (match_operand:SI 0 "register_operand" "=y,y")
6806         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6807    (clobber (match_scratch:SI 2 "=&z,r"))]
6808   "TARGET_SH2E
6809    && (reload_in_progress || reload_completed)"
6810   "#"
6811   [(set_attr "length" "4")
6812    (set_attr "type" "pcload,move")])
6814 (define_split
6815   [(set (match_operand:SI 0 "register_operand" "")
6816         (match_operand:SI 1 "immediate_operand" ""))
6817    (clobber (match_operand:SI 2 "register_operand" ""))]
6818   "TARGET_SH1"
6819   [(set (match_dup 2) (match_dup 1))
6820    (set (match_dup 0) (match_dup 2))]
6821   "")
6823 (define_split
6824   [(set (match_operand:SI 0 "register_operand" "")
6825         (match_operand:SI 1 "memory_operand" ""))
6826    (clobber (reg:SI R0_REG))]
6827   "TARGET_SH1"
6828   [(set (match_dup 0) (match_dup 1))]
6829   "")
6831 ;; ------------------------------------------------------------------------
6832 ;; Define the real conditional branch instructions.
6833 ;; ------------------------------------------------------------------------
6835 (define_insn "branch_true"
6836   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6837                            (label_ref (match_operand 0 "" ""))
6838                            (pc)))]
6839   "TARGET_SH1"
6840   "* return output_branch (1, insn, operands);"
6841   [(set_attr "type" "cbranch")])
6843 (define_insn "branch_false"
6844   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6845                            (label_ref (match_operand 0 "" ""))
6846                            (pc)))]
6847   "TARGET_SH1"
6848   "* return output_branch (0, insn, operands);"
6849   [(set_attr "type" "cbranch")])
6851 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6852 ;; which destination is too far away.
6853 ;; The const_int_operand is distinct for each branch target; it avoids
6854 ;; unwanted matches with redundant_insn.
6855 (define_insn "block_branch_redirect"
6856   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6857   "TARGET_SH1"
6858   ""
6859   [(set_attr "length" "0")])
6861 ;; This one has the additional purpose to record a possible scratch register
6862 ;; for the following branch.
6863 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6864 ;; because the insn then might be deemed dead and deleted.  And we can't
6865 ;; make the use in the jump insn explicit because that would disable
6866 ;; delay slot scheduling from the target.
6867 (define_insn "indirect_jump_scratch"
6868   [(set (match_operand:SI 0 "register_operand" "=r")
6869         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6870    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6871   "TARGET_SH1"
6872   ""
6873   [(set_attr "length" "0")])
6875 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6876 ;; being pulled into the delay slot of a condbranch that has been made to
6877 ;; jump around the unconditional jump because it was out of range.
6878 (define_insn "stuff_delay_slot"
6879   [(set (pc)
6880         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6881    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6882   "TARGET_SH1"
6883   ""
6884   [(set_attr "length" "0")
6885    (set_attr "cond_delay_slot" "yes")])
6887 ;; Conditional branch insns
6889 (define_expand "beq_media"
6890   [(set (pc)
6891         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6892                           (match_operand:DI 2 "arith_operand" "r,I06"))
6893                       (match_operand 0 "" "")
6894                       (pc)))]
6895   "TARGET_SHMEDIA"
6896   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6898 (define_insn "*beq_media_i"
6899   [(set (pc)
6900         (if_then_else (match_operator 3 "equality_comparison_operator"
6901                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6902                          (match_operand:DI 2 "arith_operand" "r,I06")])
6903                       (match_operand 0 "target_operand" "b,b")
6904                       (pc)))]
6905   "TARGET_SHMEDIA"
6906   "@
6907         b%o3%'  %1, %2, %0%>
6908         b%o3i%' %1, %2, %0%>"
6909   [(set_attr "type" "cbranch_media")])
6911 (define_insn "*beq_media_i32"
6912   [(set (pc)
6913         (if_then_else (match_operator 3 "equality_comparison_operator"
6914                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6915                          (match_operand:SI 2 "arith_operand" "r,I06")])
6916                       (match_operand 0 "target_operand" "b,b")
6917                       (pc)))]
6918   "TARGET_SHMEDIA"
6919   "@
6920         b%o3%'  %1, %2, %0%>
6921         b%o3i%' %1, %2, %0%>"
6922   [(set_attr "type" "cbranch_media")])
6924 (define_expand "bne_media"
6925   [(set (pc)
6926         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6927                           (match_operand:DI 2 "arith_operand" "r,I06"))
6928                       (match_operand 0 "" "")
6929                       (pc)))]
6930   "TARGET_SHMEDIA"
6931   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6933 (define_expand "bgt_media"
6934   [(set (pc)
6935         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6936                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6937                       (match_operand 0 "" "")
6938                       (pc)))]
6939   "TARGET_SHMEDIA"
6940   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6942 (define_expand "bge_media"
6943   [(set (pc)
6944         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6945                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6946                       (match_operand 0 "" "")
6947                       (pc)))]
6948   "TARGET_SHMEDIA"
6949   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6951 (define_expand "bgtu_media"
6952   [(set (pc)
6953         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6954                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6955                       (match_operand 0 "" "")
6956                       (pc)))]
6957   "TARGET_SHMEDIA"
6958   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6960 (define_expand "bgeu_media"
6961   [(set (pc)
6962         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6963                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6964                       (match_operand 0 "" "")
6965                       (pc)))]
6966   "TARGET_SHMEDIA"
6967   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6969 (define_insn "*bgt_media_i"
6970   [(set (pc)
6971         (if_then_else (match_operator 3 "greater_comparison_operator"
6972                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6973                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6974                       (match_operand 0 "target_operand" "b")
6975                       (pc)))]
6976   "TARGET_SHMEDIA"
6977   "b%o3%'       %N1, %N2, %0%>"
6978   [(set_attr "type" "cbranch_media")])
6980 (define_insn "*bgt_media_i32"
6981   [(set (pc)
6982         (if_then_else (match_operator 3 "greater_comparison_operator"
6983                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6984                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6985                       (match_operand 0 "target_operand" "b")
6986                       (pc)))]
6987   "TARGET_SHMEDIA"
6988   "b%o3%'       %N1, %N2, %0%>"
6989   [(set_attr "type" "cbranch_media")])
6991 ;; These are only needed to make invert_jump() happy - otherwise, jump
6992 ;; optimization will be silently disabled.
6993 (define_insn "*blt_media_i"
6994   [(set (pc)
6995         (if_then_else (match_operator 3 "less_comparison_operator"
6996                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6997                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6998                       (match_operand 0 "target_operand" "b")
6999                       (pc)))]
7000   "TARGET_SHMEDIA"
7001   "b%o3%'       %N2, %N1, %0%>"
7002   [(set_attr "type" "cbranch_media")])
7004 (define_insn "*blt_media_i32"
7005   [(set (pc)
7006         (if_then_else (match_operator 3 "less_comparison_operator"
7007                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
7008                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
7009                       (match_operand 0 "target_operand" "b")
7010                       (pc)))]
7011   "TARGET_SHMEDIA"
7012   "b%o3%'       %N2, %N1, %0%>"
7013   [(set_attr "type" "cbranch_media")])
7015 (define_expand "beq"
7016   [(set (pc)
7017         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7018                       (label_ref (match_operand 0 "" ""))
7019                       (pc)))]
7020   ""
7021   "
7023   if (TARGET_SHMEDIA)
7024     {
7025       enum machine_mode mode = GET_MODE (sh_compare_op0);
7027       if (mode != DImode && mode != SImode)
7028         {
7029           rtx tmp = gen_reg_rtx (DImode);
7031           emit_insn (gen_seq (tmp));
7032           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7033           DONE;
7034         }
7036       sh_compare_op0 = force_reg (mode, sh_compare_op0);
7037       if (CONSTANT_P (sh_compare_op1)
7038           && (! satisfies_constraint_I06 (sh_compare_op1)))
7039         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7040       emit_jump_insn (gen_beq_media (operands[0],
7041                                      sh_compare_op0, sh_compare_op1));
7042       DONE;
7043     }
7045   from_compare (operands, EQ);
7048 (define_expand "bne"
7049   [(set (pc)
7050         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7051                       (label_ref (match_operand 0 "" ""))
7052                       (pc)))]
7053   ""
7054   "
7056   if (TARGET_SHMEDIA)
7057     {
7058       enum machine_mode mode = GET_MODE (sh_compare_op0);
7060       if (mode != DImode && mode != SImode)
7061         {
7062           rtx tmp = gen_reg_rtx (DImode);
7064           emit_insn (gen_seq (tmp));
7065           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
7066           DONE;
7067         }
7069       sh_compare_op0 = force_reg (mode, sh_compare_op0);
7070       if (CONSTANT_P (sh_compare_op1)
7071           && (! satisfies_constraint_I06 (sh_compare_op1)))
7072         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7073       emit_jump_insn (gen_bne_media (operands[0],
7074                                      sh_compare_op0, sh_compare_op1));
7075       DONE;
7076     }
7078   from_compare (operands, EQ);
7081 (define_expand "bgt"
7082   [(set (pc)
7083         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7084                       (label_ref (match_operand 0 "" ""))
7085                       (pc)))]
7086   ""
7087   "
7089   if (TARGET_SHMEDIA)
7090     {
7091       enum machine_mode mode = GET_MODE (sh_compare_op0);
7093       if (mode != DImode && mode != SImode)
7094         {
7095           rtx tmp = gen_reg_rtx (DImode);
7097           emit_insn (gen_sgt (tmp));
7098           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7099           DONE;
7100         }
7102       if (sh_compare_op0 != const0_rtx)
7103         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7104       if (sh_compare_op1 != const0_rtx)
7105         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7106       emit_jump_insn (gen_bgt_media (operands[0],
7107                                      sh_compare_op0, sh_compare_op1));
7108       DONE;
7109     }
7111   from_compare (operands, GT);
7114 (define_expand "blt"
7115   [(set (pc)
7116         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7117                       (label_ref (match_operand 0 "" ""))
7118                       (pc)))]
7119   ""
7120   "
7122   if (TARGET_SHMEDIA)
7123     {
7124       enum machine_mode mode = GET_MODE (sh_compare_op0);
7126       if (mode != DImode && mode != SImode)
7127         {
7128           rtx tmp = gen_reg_rtx (DImode);
7130           emit_insn (gen_slt (tmp));
7131           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7132           DONE;
7133         }
7135       if (sh_compare_op0 != const0_rtx)
7136         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7137       if (sh_compare_op1 != const0_rtx)
7138         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7139       emit_jump_insn (gen_bgt_media (operands[0],
7140                                      sh_compare_op1, sh_compare_op0));
7141       DONE;
7142     }
7144   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7145     {
7146       rtx tmp = sh_compare_op0;
7147       sh_compare_op0 = sh_compare_op1;
7148       sh_compare_op1 = tmp;
7149       emit_insn (gen_bgt (operands[0]));
7150       DONE;
7151     }
7152   from_compare (operands, GE);
7155 (define_expand "ble"
7156   [(set (pc)
7157         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7158                       (label_ref (match_operand 0 "" ""))
7159                       (pc)))]
7160   ""
7161   "
7163   if (TARGET_SHMEDIA)
7164     {
7165       enum machine_mode mode = GET_MODE (sh_compare_op0);
7167       if (mode != DImode && mode != SImode)
7168         {
7169           rtx tmp = gen_reg_rtx (DImode);
7171           emit_insn (gen_sle (tmp));
7172           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7173           DONE;
7174         }
7176       if (sh_compare_op0 != const0_rtx)
7177         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7178       if (sh_compare_op1 != const0_rtx)
7179         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7180       emit_jump_insn (gen_bge_media (operands[0],
7181                                      sh_compare_op1, sh_compare_op0));
7182       DONE;
7183     }
7185   if (TARGET_SH2E
7186       && TARGET_IEEE
7187       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7188     {
7189       rtx tmp = sh_compare_op0;
7190       sh_compare_op0 = sh_compare_op1;
7191       sh_compare_op1 = tmp;
7192       emit_insn (gen_bge (operands[0]));
7193       DONE;
7194     }
7195   from_compare (operands, GT);
7198 (define_expand "bge"
7199   [(set (pc)
7200         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7201                       (label_ref (match_operand 0 "" ""))
7202                       (pc)))]
7203   ""
7204   "
7206   if (TARGET_SHMEDIA)
7207     {
7208       enum machine_mode mode = GET_MODE (sh_compare_op0);
7210       if (mode != DImode && mode != SImode)
7211         {
7212           rtx tmp = gen_reg_rtx (DImode);
7214           emit_insn (gen_sge (tmp));
7215           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
7216           DONE;
7217         }
7219       if (sh_compare_op0 != const0_rtx)
7220         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7221       if (sh_compare_op1 != const0_rtx)
7222         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7223       emit_jump_insn (gen_bge_media (operands[0],
7224                                      sh_compare_op0, sh_compare_op1));
7225       DONE;
7226     }
7228   if (TARGET_SH2E
7229       && ! TARGET_IEEE
7230       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7231     {
7232       rtx tmp = sh_compare_op0;
7233       sh_compare_op0 = sh_compare_op1;
7234       sh_compare_op1 = tmp;
7235       emit_insn (gen_ble (operands[0]));
7236       DONE;
7237     }
7238   from_compare (operands, GE);
7241 (define_expand "bgtu"
7242   [(set (pc)
7243         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7244                       (label_ref (match_operand 0 "" ""))
7245                       (pc)))]
7246   ""
7247   "
7249   if (TARGET_SHMEDIA)
7250     {
7251       enum machine_mode mode = GET_MODE (sh_compare_op0);
7253       if (sh_compare_op0 != const0_rtx)
7254         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7255       if (sh_compare_op1 != const0_rtx)
7256         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7257       emit_jump_insn (gen_bgtu_media (operands[0],
7258                                       sh_compare_op0, sh_compare_op1));
7259       DONE;
7260     }
7262   from_compare (operands, GTU);
7265 (define_expand "bltu"
7266   [(set (pc)
7267         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7268                       (label_ref (match_operand 0 "" ""))
7269                       (pc)))]
7270   ""
7271   "
7273   if (TARGET_SHMEDIA)
7274     {
7275       enum machine_mode mode = GET_MODE (sh_compare_op0);
7277       if (sh_compare_op0 != const0_rtx)
7278         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7279       if (sh_compare_op1 != const0_rtx)
7280         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7281       emit_jump_insn (gen_bgtu_media (operands[0],
7282                                       sh_compare_op1, sh_compare_op0));
7283       DONE;
7284     }
7286   from_compare (operands, GEU);
7289 (define_expand "bgeu"
7290   [(set (pc)
7291         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7292                       (label_ref (match_operand 0 "" ""))
7293                       (pc)))]
7294   ""
7295   "
7297   if (TARGET_SHMEDIA)
7298     {
7299       enum machine_mode mode = GET_MODE (sh_compare_op0);
7301       if (sh_compare_op0 != const0_rtx)
7302         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7303       if (sh_compare_op1 != const0_rtx)
7304         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7305       emit_jump_insn (gen_bgeu_media (operands[0],
7306                                       sh_compare_op0, sh_compare_op1));
7307       DONE;
7308     }
7310   from_compare (operands, GEU);
7313 (define_expand "bleu"
7314   [(set (pc)
7315         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7316                       (label_ref (match_operand 0 "" ""))
7317                       (pc)))]
7318   ""
7319   "
7321   if (TARGET_SHMEDIA)
7322     {
7323       enum machine_mode mode = GET_MODE (sh_compare_op0);
7325       if (sh_compare_op0 != const0_rtx)
7326         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7327       if (sh_compare_op1 != const0_rtx)
7328         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7329       emit_jump_insn (gen_bgeu_media (operands[0],
7330                                       sh_compare_op1, sh_compare_op0));
7331       DONE;
7332     }
7334   from_compare (operands, GTU);
7337 (define_expand "bunordered"
7338   [(set (match_dup 1) (unordered:SI (match_dup 2) (match_dup 3)))
7339    (set (pc)
7340         (if_then_else (ne (match_dup 1) (const_int 0))
7341                       (match_operand 0 "" "")
7342                       (pc)))]
7343   "TARGET_SHMEDIA"
7344   "
7346   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7347   operands[1] = gen_reg_rtx (SImode);
7348   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7349   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7352 ;; combiner splitter for test-and-branch on single bit in register.  This
7353 ;; is endian dependent because the non-paradoxical subreg looks different
7354 ;; on big endian.
7355 (define_split
7356   [(set (pc)
7357         (if_then_else
7358           (match_operator 3 "equality_comparison_operator"
7359             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7360                                                       "extend_reg_operand" "")
7361                                                     0)
7362                                          (const_int 1)
7363                                          (match_operand 2
7364                                           "const_int_operand" "")) 0)
7365              (const_int 0)])
7366           (match_operand 0 "target_operand" "")
7367           (pc)))
7368    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7369   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7370   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7371    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7373   "
7375   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7376   operands[6] = (GET_CODE (operands[3]) == EQ
7377                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7378                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7381 ; operand 0 is the loop count pseudo register
7382 ; operand 1 is the number of loop iterations or 0 if it is unknown
7383 ; operand 2 is the maximum number of loop iterations
7384 ; operand 3 is the number of levels of enclosed loops
7385 ; operand 4 is the label to jump to at the top of the loop
7387 (define_expand "doloop_end"
7388   [(parallel [(set (pc) (if_then_else
7389                           (ne:SI (match_operand:SI 0 "" "")
7390                               (const_int 1))
7391                           (label_ref (match_operand 4 "" ""))
7392                           (pc)))
7393               (set (match_dup 0)
7394                    (plus:SI (match_dup 0) (const_int -1)))
7395               (clobber (reg:SI T_REG))])]
7396   "TARGET_SH2"
7397   "
7399   if (GET_MODE (operands[0]) != SImode)
7400     FAIL;
7404 (define_insn_and_split "doloop_end_split"
7405   [(set (pc)
7406         (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7407                           (const_int 1))
7408                       (label_ref (match_operand 1 "" ""))
7409                       (pc)))
7410    (set (match_dup 0)
7411         (plus (match_dup 0) (const_int -1)))
7412    (clobber (reg:SI T_REG))]
7413   "TARGET_SH2"
7414   "#"
7415   ""
7416   [(parallel [(set (reg:SI T_REG)
7417                    (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7418                           (const_int 1)))
7419               (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7420    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7421                            (label_ref (match_operand 1 "" ""))
7422                            (pc)))]
7424    [(set_attr "type" "cbranch")])
7427 ;; ------------------------------------------------------------------------
7428 ;; Jump and linkage insns
7429 ;; ------------------------------------------------------------------------
7431 (define_insn "jump_compact"
7432   [(set (pc)
7433         (label_ref (match_operand 0 "" "")))]
7434   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7435   "*
7437   /* The length is 16 if the delay slot is unfilled.  */
7438   if (get_attr_length(insn) > 4)
7439     return output_far_jump(insn, operands[0]);
7440   else
7441     return   \"bra      %l0%#\";
7443   [(set_attr "type" "jump")
7444    (set_attr "needs_delay_slot" "yes")])
7446 ;; ??? It would be much saner to explicitly use the scratch register
7447 ;; in the jump insn, and have indirect_jump_scratch only set it,
7448 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7449 ;; from the target then, as it uses simplejump_p.
7450 ;;(define_insn "jump_compact_far"
7451 ;;  [(set (pc)
7452 ;;      (label_ref (match_operand 0 "" "")))
7453 ;;   (use (match_operand 1 "register_operand" "r")]
7454 ;;  "TARGET_SH1"
7455 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7456 ;;  [(set_attr "type" "jump")
7457 ;;   (set_attr "needs_delay_slot" "yes")])
7459 (define_insn "jump_media"
7460   [(set (pc)
7461         (match_operand 0 "target_operand" "b"))]
7462   "TARGET_SHMEDIA"
7463   "blink        %0, r63%>"
7464   [(set_attr "type" "jump_media")])
7466 (define_expand "jump"
7467   [(set (pc)
7468         (label_ref (match_operand 0 "" "")))]
7469   ""
7470   "
7472   if (TARGET_SH1)
7473     emit_jump_insn (gen_jump_compact (operands[0]));
7474   else if (TARGET_SHMEDIA)
7475     {
7476       if (reload_in_progress || reload_completed)
7477         FAIL;
7478       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7479                                                          operands[0])));
7480     }
7481   DONE;
7484 (define_insn "force_mode_for_call"
7485   [(use (reg:PSI FPSCR_REG))]
7486   "TARGET_SHCOMPACT"
7487   ""
7488   [(set_attr "length" "0")
7489    (set (attr "fp_mode")
7490         (if_then_else (eq_attr "fpu_single" "yes")
7491                       (const_string "single") (const_string "double")))])
7493 (define_insn "calli"
7494   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7495          (match_operand 1 "" ""))
7496    (use (reg:PSI FPSCR_REG))
7497    (clobber (reg:SI PR_REG))]
7498   "TARGET_SH1"
7499   "*
7500    {
7501      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7502         return \"jsr/n\\t@%0\";
7503      else
7504         return \"jsr\\t@%0%#\";
7505    }"
7507   [(set_attr "type" "call")
7508    (set (attr "fp_mode")
7509         (if_then_else (eq_attr "fpu_single" "yes")
7510                       (const_string "single") (const_string "double")))
7511    (set_attr "needs_delay_slot" "yes")
7512    (set_attr "fp_set" "unknown")])
7514 ;; This is TBR relative jump instruction for SH2A architecture.
7515 ;; Its use is enabled assigning an attribute "function_vector"
7516 ;; and the vector number to a function during its declaration.
7518 (define_insn "calli_tbr_rel"
7519   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7520          (match_operand 1 "" ""))
7521    (use (reg:PSI FPSCR_REG))
7522    (clobber (reg:SI PR_REG))]
7523   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7524   "*
7526   unsigned HOST_WIDE_INT vect_num;
7527   vect_num = sh2a_get_function_vector_number (operands[0]);
7528   operands[2] = GEN_INT (vect_num * 4);
7530   return \"jsr/n\\t@@(%O2,tbr)\";
7532   [(set_attr "type" "call")
7533    (set (attr "fp_mode")
7534         (if_then_else (eq_attr "fpu_single" "yes")
7535                       (const_string "single") (const_string "double")))
7536    (set_attr "needs_delay_slot" "no")
7537    (set_attr "fp_set" "unknown")])
7539 ;; This is a pc-rel call, using bsrf, for use with PIC.
7541 (define_insn "calli_pcrel"
7542   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7543          (match_operand 1 "" ""))
7544    (use (reg:PSI FPSCR_REG))
7545    (use (reg:SI PIC_REG))
7546    (use (match_operand 2 "" ""))
7547    (clobber (reg:SI PR_REG))]
7548   "TARGET_SH2"
7549   "bsrf %0\\n%O2:%#"
7550   [(set_attr "type" "call")
7551    (set (attr "fp_mode")
7552         (if_then_else (eq_attr "fpu_single" "yes")
7553                       (const_string "single") (const_string "double")))
7554    (set_attr "needs_delay_slot" "yes")
7555    (set_attr "fp_set" "unknown")])
7557 (define_insn_and_split "call_pcrel"
7558   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7559          (match_operand 1 "" ""))
7560    (use (reg:PSI FPSCR_REG))
7561    (use (reg:SI PIC_REG))
7562    (clobber (reg:SI PR_REG))
7563    (clobber (match_scratch:SI 2 "=r"))]
7564   "TARGET_SH2"
7565   "#"
7566   "reload_completed"
7567   [(const_int 0)]
7568   "
7570   rtx lab = PATTERN (gen_call_site ());
7572   if (SYMBOL_REF_LOCAL_P (operands[0]))
7573     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7574   else
7575     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7576   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7577   DONE;
7579   [(set_attr "type" "call")
7580    (set (attr "fp_mode")
7581         (if_then_else (eq_attr "fpu_single" "yes")
7582                       (const_string "single") (const_string "double")))
7583    (set_attr "needs_delay_slot" "yes")
7584    (set_attr "fp_set" "unknown")])
7586 (define_insn "call_compact"
7587   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7588          (match_operand 1 "" ""))
7589    (match_operand 2 "immediate_operand" "n")
7590    (use (reg:SI R0_REG))
7591    (use (reg:SI R1_REG))
7592    (use (reg:PSI FPSCR_REG))
7593    (clobber (reg:SI PR_REG))]
7594   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7595   "jsr  @%0%#"
7596   [(set_attr "type" "call")
7597    (set (attr "fp_mode")
7598         (if_then_else (eq_attr "fpu_single" "yes")
7599                       (const_string "single") (const_string "double")))
7600    (set_attr "needs_delay_slot" "yes")])
7602 (define_insn "call_compact_rettramp"
7603   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7604          (match_operand 1 "" ""))
7605    (match_operand 2 "immediate_operand" "n")
7606    (use (reg:SI R0_REG))
7607    (use (reg:SI R1_REG))
7608    (use (reg:PSI FPSCR_REG))
7609    (clobber (reg:SI R10_REG))
7610    (clobber (reg:SI PR_REG))]
7611   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7612   "jsr  @%0%#"
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_media"
7620   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7621          (match_operand 1 "" ""))
7622    (clobber (reg:DI PR_MEDIA_REG))]
7623   "TARGET_SHMEDIA"
7624   "blink        %0, r18"
7625   [(set_attr "type" "jump_media")])
7627 (define_insn "call_valuei"
7628   [(set (match_operand 0 "" "=rf")
7629         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7630               (match_operand 2 "" "")))
7631    (use (reg:PSI FPSCR_REG))
7632    (clobber (reg:SI PR_REG))]
7633   "TARGET_SH1"
7634   "*
7635    {
7636      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7637         return \"jsr/n\\t@%1\";
7638      else
7639         return \"jsr\\t@%1%#\";
7640    }"
7641   [(set_attr "type" "call")
7642    (set (attr "fp_mode")
7643         (if_then_else (eq_attr "fpu_single" "yes")
7644                       (const_string "single") (const_string "double")))
7645    (set_attr "needs_delay_slot" "yes")
7646    (set_attr "fp_set" "unknown")])
7648 ;; This is TBR relative jump instruction for SH2A architecture.
7649 ;; Its use is enabled assigning an attribute "function_vector"
7650 ;; and the vector number to a function during its declaration.
7652 (define_insn "call_valuei_tbr_rel"
7653   [(set (match_operand 0 "" "=rf")
7654         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7655               (match_operand 2 "" "")))
7656    (use (reg:PSI FPSCR_REG))
7657    (clobber (reg:SI PR_REG))]
7658   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7659   "*
7661   unsigned HOST_WIDE_INT vect_num;
7662   vect_num = sh2a_get_function_vector_number (operands[1]);
7663   operands[3] = GEN_INT (vect_num * 4);
7665   return \"jsr/n\\t@@(%O3,tbr)\";
7667   [(set_attr "type" "call")
7668    (set (attr "fp_mode")
7669         (if_then_else (eq_attr "fpu_single" "yes")
7670                       (const_string "single") (const_string "double")))
7671    (set_attr "needs_delay_slot" "no")
7672    (set_attr "fp_set" "unknown")])
7674 (define_insn "call_valuei_pcrel"
7675   [(set (match_operand 0 "" "=rf")
7676         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7677               (match_operand 2 "" "")))
7678    (use (reg:PSI FPSCR_REG))
7679    (use (reg:SI PIC_REG))
7680    (use (match_operand 3 "" ""))
7681    (clobber (reg:SI PR_REG))]
7682   "TARGET_SH2"
7683   "bsrf %1\\n%O3:%#"
7684   [(set_attr "type" "call")
7685    (set (attr "fp_mode")
7686         (if_then_else (eq_attr "fpu_single" "yes")
7687                       (const_string "single") (const_string "double")))
7688    (set_attr "needs_delay_slot" "yes")
7689    (set_attr "fp_set" "unknown")])
7691 (define_insn_and_split "call_value_pcrel"
7692   [(set (match_operand 0 "" "=rf")
7693         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7694               (match_operand 2 "" "")))
7695    (use (reg:PSI FPSCR_REG))
7696    (use (reg:SI PIC_REG))
7697    (clobber (reg:SI PR_REG))
7698    (clobber (match_scratch:SI 3 "=r"))]
7699   "TARGET_SH2"
7700   "#"
7701   "reload_completed"
7702   [(const_int 0)]
7703   "
7705   rtx lab = PATTERN (gen_call_site ());
7707   if (SYMBOL_REF_LOCAL_P (operands[1]))
7708     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7709   else
7710     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7711   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7712                                          operands[2], copy_rtx (lab)));
7713   DONE;
7715   [(set_attr "type" "call")
7716    (set (attr "fp_mode")
7717         (if_then_else (eq_attr "fpu_single" "yes")
7718                       (const_string "single") (const_string "double")))
7719    (set_attr "needs_delay_slot" "yes")
7720    (set_attr "fp_set" "unknown")])
7722 (define_insn "call_value_compact"
7723   [(set (match_operand 0 "" "=rf")
7724         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7725               (match_operand 2 "" "")))
7726    (match_operand 3 "immediate_operand" "n")
7727    (use (reg:SI R0_REG))
7728    (use (reg:SI R1_REG))
7729    (use (reg:PSI FPSCR_REG))
7730    (clobber (reg:SI PR_REG))]
7731   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7732   "jsr  @%1%#"
7733   [(set_attr "type" "call")
7734    (set (attr "fp_mode")
7735         (if_then_else (eq_attr "fpu_single" "yes")
7736                       (const_string "single") (const_string "double")))
7737    (set_attr "needs_delay_slot" "yes")])
7739 (define_insn "call_value_compact_rettramp"
7740   [(set (match_operand 0 "" "=rf")
7741         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7742               (match_operand 2 "" "")))
7743    (match_operand 3 "immediate_operand" "n")
7744    (use (reg:SI R0_REG))
7745    (use (reg:SI R1_REG))
7746    (use (reg:PSI FPSCR_REG))
7747    (clobber (reg:SI R10_REG))
7748    (clobber (reg:SI PR_REG))]
7749   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7750   "jsr  @%1%#"
7751   [(set_attr "type" "call")
7752    (set (attr "fp_mode")
7753         (if_then_else (eq_attr "fpu_single" "yes")
7754                       (const_string "single") (const_string "double")))
7755    (set_attr "needs_delay_slot" "yes")])
7757 (define_insn "call_value_media"
7758   [(set (match_operand 0 "" "=rf")
7759         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7760               (match_operand 2 "" "")))
7761    (clobber (reg:DI PR_MEDIA_REG))]
7762   "TARGET_SHMEDIA"
7763   "blink        %1, r18"
7764   [(set_attr "type" "jump_media")])
7766 (define_expand "call"
7767   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7768                             (match_operand 1 "" ""))
7769               (match_operand 2 "" "")
7770               (use (reg:PSI FPSCR_REG))
7771               (clobber (reg:SI PR_REG))])]
7772   ""
7773   "
7775   if (TARGET_SHMEDIA)
7776     {
7777       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7778       emit_call_insn (gen_call_media (operands[0], operands[1]));
7779       DONE;
7780     }
7781   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7782     {
7783       rtx cookie_rtx = operands[2];
7784       long cookie = INTVAL (cookie_rtx);
7785       rtx func = XEXP (operands[0], 0);
7786       rtx r0, r1;
7788       if (flag_pic)
7789         {
7790           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7791             {
7792               rtx reg = gen_reg_rtx (Pmode);
7794               emit_insn (gen_symGOTPLT2reg (reg, func));
7795               func = reg;
7796             }
7797           else
7798             func = legitimize_pic_address (func, Pmode, 0);
7799         }
7801       r0 = gen_rtx_REG (SImode, R0_REG);
7802       r1 = gen_rtx_REG (SImode, R1_REG);
7804       /* Since such a call function may use all call-clobbered
7805          registers, we force a mode switch earlier, so that we don't
7806          run out of registers when adjusting fpscr for the call.  */
7807       emit_insn (gen_force_mode_for_call ());
7809       operands[0]
7810         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7811                            SFUNC_GOT);
7812       operands[0] = force_reg (SImode, operands[0]);
7814       emit_move_insn (r0, func);
7815       emit_move_insn (r1, cookie_rtx);
7817       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7818         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7819                                                    operands[2]));
7820       else
7821         emit_call_insn (gen_call_compact (operands[0], operands[1],
7822                                           operands[2]));
7824       DONE;
7825     }
7826   else if (TARGET_SHCOMPACT && flag_pic
7827            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7828            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7829     {
7830       rtx reg = gen_reg_rtx (Pmode);
7832       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7833       XEXP (operands[0], 0) = reg;
7834     }
7835   if (!flag_pic && TARGET_SH2A
7836       && GET_CODE (operands[0]) == MEM
7837       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7838     {
7839       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7840         {
7841           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7842                                              operands[1]));
7843           DONE;
7844         }
7845     }
7846   if (flag_pic && TARGET_SH2
7847       && GET_CODE (operands[0]) == MEM
7848       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7849     {
7850       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7851       DONE;
7852     }
7853   else
7854   {
7855     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7856     operands[1] = operands[2];
7857   }
7859   emit_call_insn (gen_calli (operands[0], operands[1]));
7860   DONE;
7863 (define_insn "call_pop_compact"
7864   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7865          (match_operand 1 "" ""))
7866    (match_operand 2 "immediate_operand" "n")
7867    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7868                                  (match_operand 3 "immediate_operand" "n")))
7869    (use (reg:SI R0_REG))
7870    (use (reg:SI R1_REG))
7871    (use (reg:PSI FPSCR_REG))
7872    (clobber (reg:SI PR_REG))]
7873   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7874   "jsr  @%0%#"
7875   [(set_attr "type" "call")
7876    (set (attr "fp_mode")
7877         (if_then_else (eq_attr "fpu_single" "yes")
7878                       (const_string "single") (const_string "double")))
7879    (set_attr "needs_delay_slot" "yes")])
7881 (define_insn "call_pop_compact_rettramp"
7882   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7883          (match_operand 1 "" ""))
7884    (match_operand 2 "immediate_operand" "n")
7885    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7886                                  (match_operand 3 "immediate_operand" "n")))
7887    (use (reg:SI R0_REG))
7888    (use (reg:SI R1_REG))
7889    (use (reg:PSI FPSCR_REG))
7890    (clobber (reg:SI R10_REG))
7891    (clobber (reg:SI PR_REG))]
7892   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7893   "jsr  @%0%#"
7894   [(set_attr "type" "call")
7895    (set (attr "fp_mode")
7896         (if_then_else (eq_attr "fpu_single" "yes")
7897                       (const_string "single") (const_string "double")))
7898    (set_attr "needs_delay_slot" "yes")])
7900 (define_expand "call_pop"
7901   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7902                     (match_operand 1 "" ""))
7903              (match_operand 2 "" "")
7904              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7905                                            (match_operand 3 "" "")))])]
7906   "TARGET_SHCOMPACT"
7907   "
7909   rtx cookie_rtx;
7910   long cookie;
7911   rtx func;
7912   rtx r0, r1;
7914   gcc_assert (operands[2] && INTVAL (operands[2]));
7915   cookie_rtx = operands[2];
7916   cookie = INTVAL (cookie_rtx);
7917   func = XEXP (operands[0], 0);
7919   if (flag_pic)
7920     {
7921       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7922         {
7923           rtx reg = gen_reg_rtx (Pmode);
7924           emit_insn (gen_symGOTPLT2reg (reg, func));
7925           func = reg;
7926         }
7927       else
7928         func = legitimize_pic_address (func, Pmode, 0);
7929     }
7931   r0 = gen_rtx_REG (SImode, R0_REG);
7932   r1 = gen_rtx_REG (SImode, R1_REG);
7934   /* Since such a call function may use all call-clobbered
7935      registers, we force a mode switch earlier, so that we don't
7936      run out of registers when adjusting fpscr for the call.  */
7937   emit_insn (gen_force_mode_for_call ());
7939   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7940                                  SFUNC_GOT);
7941   operands[0] = force_reg (SImode, operands[0]);
7943   emit_move_insn (r0, func);
7944   emit_move_insn (r1, cookie_rtx);
7946   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7947     emit_call_insn (gen_call_pop_compact_rettramp
7948                      (operands[0], operands[1], operands[2], operands[3]));
7949   else
7950     emit_call_insn (gen_call_pop_compact
7951                      (operands[0], operands[1], operands[2], operands[3]));
7953   DONE;
7956 (define_expand "call_value"
7957   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7958                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7959                                  (match_operand 2 "" "")))
7960               (match_operand 3 "" "")
7961               (use (reg:PSI FPSCR_REG))
7962               (clobber (reg:SI PR_REG))])]
7963   ""
7964   "
7966   if (TARGET_SHMEDIA)
7967     {
7968       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7969       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7970                                             operands[2]));
7971       DONE;
7972     }
7973   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7974     {
7975       rtx cookie_rtx = operands[3];
7976       long cookie = INTVAL (cookie_rtx);
7977       rtx func = XEXP (operands[1], 0);
7978       rtx r0, r1;
7980       if (flag_pic)
7981         {
7982           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7983             {
7984               rtx reg = gen_reg_rtx (Pmode);
7986               emit_insn (gen_symGOTPLT2reg (reg, func));
7987               func = reg;
7988             }
7989           else
7990             func = legitimize_pic_address (func, Pmode, 0);
7991         }
7993       r0 = gen_rtx_REG (SImode, R0_REG);
7994       r1 = gen_rtx_REG (SImode, R1_REG);
7996       /* Since such a call function may use all call-clobbered
7997          registers, we force a mode switch earlier, so that we don't
7998          run out of registers when adjusting fpscr for the call.  */
7999       emit_insn (gen_force_mode_for_call ());
8001       operands[1]
8002         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8003                            SFUNC_GOT);
8004       operands[1] = force_reg (SImode, operands[1]);
8006       emit_move_insn (r0, func);
8007       emit_move_insn (r1, cookie_rtx);
8009       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8010         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
8011                                                          operands[1],
8012                                                          operands[2],
8013                                                          operands[3]));
8014       else
8015         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
8016                                                 operands[2], operands[3]));
8018       DONE;
8019     }
8020   else if (TARGET_SHCOMPACT && flag_pic
8021            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8022            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8023     {
8024       rtx reg = gen_reg_rtx (Pmode);
8026       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
8027       XEXP (operands[1], 0) = reg;
8028     }
8029   if (!flag_pic && TARGET_SH2A
8030       && GET_CODE (operands[1]) == MEM
8031       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8032     {
8033       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
8034         {
8035           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
8036                                  XEXP (operands[1], 0), operands[2]));
8037           DONE;
8038         }
8039     }
8040   if (flag_pic && TARGET_SH2
8041       && GET_CODE (operands[1]) == MEM
8042       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
8043     {
8044       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
8045                                             operands[2]));
8046       DONE;
8047     }
8048   else
8049     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8051   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
8052   DONE;
8055 (define_insn "sibcalli"
8056   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
8057          (match_operand 1 "" ""))
8058    (use (reg:PSI FPSCR_REG))
8059    (return)]
8060   "TARGET_SH1"
8061   "jmp  @%0%#"
8062   [(set_attr "needs_delay_slot" "yes")
8063    (set (attr "fp_mode")
8064         (if_then_else (eq_attr "fpu_single" "yes")
8065                       (const_string "single") (const_string "double")))
8066    (set_attr "type" "jump_ind")])
8068 (define_insn "sibcalli_pcrel"
8069   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
8070          (match_operand 1 "" ""))
8071    (use (match_operand 2 "" ""))
8072    (use (reg:PSI FPSCR_REG))
8073    (return)]
8074   "TARGET_SH2"
8075   "braf %0\\n%O2:%#"
8076   [(set_attr "needs_delay_slot" "yes")
8077    (set (attr "fp_mode")
8078         (if_then_else (eq_attr "fpu_single" "yes")
8079                       (const_string "single") (const_string "double")))
8080    (set_attr "type" "jump_ind")])
8082 ;; This uses an unspec to describe that the symbol_ref is very close.
8083 (define_insn "sibcalli_thunk"
8084   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
8085                              UNSPEC_THUNK))
8086          (match_operand 1 "" ""))
8087    (use (reg:PSI FPSCR_REG))
8088    (return)]
8089   "TARGET_SH1"
8090   "bra  %O0"
8091   [(set_attr "needs_delay_slot" "yes")
8092    (set (attr "fp_mode")
8093         (if_then_else (eq_attr "fpu_single" "yes")
8094                       (const_string "single") (const_string "double")))
8095    (set_attr "type" "jump")
8096    (set_attr "length" "2")])
8098 (define_insn_and_split "sibcall_pcrel"
8099   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
8100          (match_operand 1 "" ""))
8101    (use (reg:PSI FPSCR_REG))
8102    (clobber (match_scratch:SI 2 "=k"))
8103    (return)]
8104   "TARGET_SH2"
8105   "#"
8106   "reload_completed"
8107   [(const_int 0)]
8108   "
8110   rtx lab = PATTERN (gen_call_site ());
8111   rtx call_insn;
8113   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
8114   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
8115                                                   copy_rtx (lab)));
8116   SIBLING_CALL_P (call_insn) = 1;
8117   DONE;
8119   [(set_attr "needs_delay_slot" "yes")
8120    (set (attr "fp_mode")
8121         (if_then_else (eq_attr "fpu_single" "yes")
8122                       (const_string "single") (const_string "double")))
8123    (set_attr "type" "jump_ind")])
8125 (define_insn "sibcall_compact"
8126   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
8127          (match_operand 1 "" ""))
8128    (return)
8129    (use (match_operand:SI 2 "register_operand" "z,x"))
8130    (use (reg:SI R1_REG))
8131    (use (reg:PSI FPSCR_REG))
8132    ;; We want to make sure the `x' above will only match MACH_REG
8133    ;; because sibcall_epilogue may clobber MACL_REG.
8134    (clobber (reg:SI MACL_REG))]
8135   "TARGET_SHCOMPACT"
8136   "@
8137         jmp     @%0%#
8138         jmp     @%0\\n  sts     %2, r0"
8139   [(set_attr "needs_delay_slot" "yes,no")
8140    (set_attr "length" "2,4")
8141    (set (attr "fp_mode") (const_string "single"))
8142    (set_attr "type" "jump_ind")])
8144 (define_insn "sibcall_media"
8145   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
8146          (match_operand 1 "" ""))
8147    (use (reg:SI PR_MEDIA_REG))
8148    (return)]
8149   "TARGET_SHMEDIA"
8150   "blink        %0, r63"
8151   [(set_attr "type" "jump_media")])
8153 (define_expand "sibcall"
8154   [(parallel
8155     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
8156            (match_operand 1 "" ""))
8157      (match_operand 2 "" "")
8158      (use (reg:PSI FPSCR_REG))
8159      (return)])]
8160   ""
8161   "
8163   if (TARGET_SHMEDIA)
8164     {
8165       operands[0] = shmedia_prepare_call_address (operands[0], 1);
8166       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
8167       DONE;
8168     }
8169   else if (TARGET_SHCOMPACT && operands[2]
8170            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8171     {
8172       rtx cookie_rtx = operands[2];
8173       long cookie = INTVAL (cookie_rtx);
8174       rtx func = XEXP (operands[0], 0);
8175       rtx mach, r1;
8177       if (flag_pic)
8178         {
8179           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8180             {
8181               rtx reg = gen_reg_rtx (Pmode);
8183               emit_insn (gen_symGOT2reg (reg, func));
8184               func = reg;
8185             }
8186           else
8187             func = legitimize_pic_address (func, Pmode, 0);
8188         }
8190       /* FIXME: if we could tell whether all argument registers are
8191          already taken, we could decide whether to force the use of
8192          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8193          simple way to tell.  We could use the CALL_COOKIE, but we
8194          can't currently tell a register used for regular argument
8195          passing from one that is unused.  If we leave it up to reload
8196          to decide which register to use, it seems to always choose
8197          R0_REG, which leaves no available registers in SIBCALL_REGS
8198          to hold the address of the trampoline.  */
8199       mach = gen_rtx_REG (SImode, MACH_REG);
8200       r1 = gen_rtx_REG (SImode, R1_REG);
8202       /* Since such a call function may use all call-clobbered
8203          registers, we force a mode switch earlier, so that we don't
8204          run out of registers when adjusting fpscr for the call.  */
8205       emit_insn (gen_force_mode_for_call ());
8207       operands[0]
8208         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8209                            SFUNC_GOT);
8210       operands[0] = force_reg (SImode, operands[0]);
8212       /* We don't need a return trampoline, since the callee will
8213          return directly to the upper caller.  */
8214       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8215         {
8216           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8217           cookie_rtx = GEN_INT (cookie);
8218         }
8220       emit_move_insn (mach, func);
8221       emit_move_insn (r1, cookie_rtx);
8223       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
8224       DONE;
8225     }
8226   else if (TARGET_SHCOMPACT && flag_pic
8227            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8228            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8229     {
8230       rtx reg = gen_reg_rtx (Pmode);
8232       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
8233       XEXP (operands[0], 0) = reg;
8234     }
8235   if (flag_pic && TARGET_SH2
8236       && GET_CODE (operands[0]) == MEM
8237       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
8238       /* The PLT needs the PIC register, but the epilogue would have
8239          to restore it, so we can only use PC-relative PIC calls for
8240          static functions.  */
8241       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
8242     {
8243       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
8244       DONE;
8245     }
8246   else
8247     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
8249   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
8250   DONE;
8253 (define_insn "sibcall_valuei"
8254   [(set (match_operand 0 "" "=rf")
8255         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
8256               (match_operand 2 "" "")))
8257    (use (reg:PSI FPSCR_REG))
8258    (return)]
8259   "TARGET_SH1"
8260   "jmp  @%1%#"
8261   [(set_attr "needs_delay_slot" "yes")
8262    (set (attr "fp_mode")
8263         (if_then_else (eq_attr "fpu_single" "yes")
8264                       (const_string "single") (const_string "double")))
8265    (set_attr "type" "jump_ind")])
8267 (define_insn "sibcall_valuei_pcrel"
8268   [(set (match_operand 0 "" "=rf")
8269         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
8270               (match_operand 2 "" "")))
8271    (use (match_operand 3 "" ""))
8272    (use (reg:PSI FPSCR_REG))
8273    (return)]
8274   "TARGET_SH2"
8275   "braf %1\\n%O3:%#"
8276   [(set_attr "needs_delay_slot" "yes")
8277    (set (attr "fp_mode")
8278         (if_then_else (eq_attr "fpu_single" "yes")
8279                       (const_string "single") (const_string "double")))
8280    (set_attr "type" "jump_ind")])
8282 (define_insn_and_split "sibcall_value_pcrel"
8283   [(set (match_operand 0 "" "=rf")
8284         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
8285               (match_operand 2 "" "")))
8286    (use (reg:PSI FPSCR_REG))
8287    (clobber (match_scratch:SI 3 "=k"))
8288    (return)]
8289   "TARGET_SH2"
8290   "#"
8291   "reload_completed"
8292   [(const_int 0)]
8293   "
8295   rtx lab = PATTERN (gen_call_site ());
8296   rtx call_insn;
8298   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
8299   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
8300                                                         operands[3],
8301                                                         operands[2],
8302                                                         copy_rtx (lab)));
8303   SIBLING_CALL_P (call_insn) = 1;
8304   DONE;
8306   [(set_attr "needs_delay_slot" "yes")
8307    (set (attr "fp_mode")
8308         (if_then_else (eq_attr "fpu_single" "yes")
8309                       (const_string "single") (const_string "double")))
8310    (set_attr "type" "jump_ind")])
8312 (define_insn "sibcall_value_compact"
8313   [(set (match_operand 0 "" "=rf,rf")
8314         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
8315               (match_operand 2 "" "")))
8316    (return)
8317    (use (match_operand:SI 3 "register_operand" "z,x"))
8318    (use (reg:SI R1_REG))
8319    (use (reg:PSI FPSCR_REG))
8320    ;; We want to make sure the `x' above will only match MACH_REG
8321    ;; because sibcall_epilogue may clobber MACL_REG.
8322    (clobber (reg:SI MACL_REG))]
8323   "TARGET_SHCOMPACT"
8324   "@
8325         jmp     @%1%#
8326         jmp     @%1\\n  sts     %3, r0"
8327   [(set_attr "needs_delay_slot" "yes,no")
8328    (set_attr "length" "2,4")
8329    (set (attr "fp_mode") (const_string "single"))
8330    (set_attr "type" "jump_ind")])
8332 (define_insn "sibcall_value_media"
8333   [(set (match_operand 0 "" "=rf")
8334         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
8335               (match_operand 2 "" "")))
8336    (use (reg:SI PR_MEDIA_REG))
8337    (return)]
8338   "TARGET_SHMEDIA"
8339   "blink        %1, r63"
8340   [(set_attr "type" "jump_media")])
8342 (define_expand "sibcall_value"
8343   [(parallel
8344     [(set (match_operand 0 "arith_reg_operand" "")
8345           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8346                 (match_operand 2 "" "")))
8347      (match_operand 3 "" "")
8348      (use (reg:PSI FPSCR_REG))
8349      (return)])]
8350   ""
8351   "
8353   if (TARGET_SHMEDIA)
8354     {
8355       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8356       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8357                                                operands[2]));
8358       DONE;
8359     }
8360   else if (TARGET_SHCOMPACT && operands[3]
8361            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8362     {
8363       rtx cookie_rtx = operands[3];
8364       long cookie = INTVAL (cookie_rtx);
8365       rtx func = XEXP (operands[1], 0);
8366       rtx mach, r1;
8368       if (flag_pic)
8369         {
8370           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8371             {
8372               rtx reg = gen_reg_rtx (Pmode);
8374               emit_insn (gen_symGOT2reg (reg, func));
8375               func = reg;
8376             }
8377           else
8378             func = legitimize_pic_address (func, Pmode, 0);
8379         }
8381       /* FIXME: if we could tell whether all argument registers are
8382          already taken, we could decide whether to force the use of
8383          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8384          simple way to tell.  We could use the CALL_COOKIE, but we
8385          can't currently tell a register used for regular argument
8386          passing from one that is unused.  If we leave it up to reload
8387          to decide which register to use, it seems to always choose
8388          R0_REG, which leaves no available registers in SIBCALL_REGS
8389          to hold the address of the trampoline.  */
8390       mach = gen_rtx_REG (SImode, MACH_REG);
8391       r1 = gen_rtx_REG (SImode, R1_REG);
8393       /* Since such a call function may use all call-clobbered
8394          registers, we force a mode switch earlier, so that we don't
8395          run out of registers when adjusting fpscr for the call.  */
8396       emit_insn (gen_force_mode_for_call ());
8398       operands[1]
8399         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8400                            SFUNC_GOT);
8401       operands[1] = force_reg (SImode, operands[1]);
8403       /* We don't need a return trampoline, since the callee will
8404          return directly to the upper caller.  */
8405       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8406         {
8407           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8408           cookie_rtx = GEN_INT (cookie);
8409         }
8411       emit_move_insn (mach, func);
8412       emit_move_insn (r1, cookie_rtx);
8414       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8415                                                  operands[2], mach));
8416       DONE;
8417     }
8418   else if (TARGET_SHCOMPACT && flag_pic
8419            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8420            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8421     {
8422       rtx reg = gen_reg_rtx (Pmode);
8424       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8425       XEXP (operands[1], 0) = reg;
8426     }
8427   if (flag_pic && TARGET_SH2
8428       && GET_CODE (operands[1]) == MEM
8429       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8430       /* The PLT needs the PIC register, but the epilogue would have
8431          to restore it, so we can only use PC-relative PIC calls for
8432          static functions.  */
8433       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8434     {
8435       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8436                                                XEXP (operands[1], 0),
8437                                                operands[2]));
8438       DONE;
8439     }
8440   else
8441     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8443   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8444   DONE;
8447 (define_insn "call_value_pop_compact"
8448   [(set (match_operand 0 "" "=rf")
8449         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8450               (match_operand 2 "" "")))
8451    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8452                                  (match_operand 4 "immediate_operand" "n")))
8453    (match_operand 3 "immediate_operand" "n")
8454    (use (reg:SI R0_REG))
8455    (use (reg:SI R1_REG))
8456    (use (reg:PSI FPSCR_REG))
8457    (clobber (reg:SI PR_REG))]
8458   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8459   "jsr  @%1%#"
8460   [(set_attr "type" "call")
8461    (set (attr "fp_mode")
8462         (if_then_else (eq_attr "fpu_single" "yes")
8463                       (const_string "single") (const_string "double")))
8464    (set_attr "needs_delay_slot" "yes")])
8466 (define_insn "call_value_pop_compact_rettramp"
8467   [(set (match_operand 0 "" "=rf")
8468         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8469               (match_operand 2 "" "")))
8470    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8471                                  (match_operand 4 "immediate_operand" "n")))
8472    (match_operand 3 "immediate_operand" "n")
8473    (use (reg:SI R0_REG))
8474    (use (reg:SI R1_REG))
8475    (use (reg:PSI FPSCR_REG))
8476    (clobber (reg:SI R10_REG))
8477    (clobber (reg:SI PR_REG))]
8478   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8479   "jsr  @%1%#"
8480   [(set_attr "type" "call")
8481    (set (attr "fp_mode")
8482         (if_then_else (eq_attr "fpu_single" "yes")
8483                       (const_string "single") (const_string "double")))
8484    (set_attr "needs_delay_slot" "yes")])
8486 (define_expand "call_value_pop"
8487   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8488                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8489                                  (match_operand 2 "" "")))
8490               (match_operand 3 "" "")
8491               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8492                                             (match_operand 4 "" "")))])]
8493   "TARGET_SHCOMPACT"
8494   "
8496   rtx cookie_rtx;
8497   long cookie;
8498   rtx func;
8499   rtx r0, r1;
8501   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8502   cookie_rtx = operands[3];
8503   cookie = INTVAL (cookie_rtx);
8504   func = XEXP (operands[1], 0);
8506   if (flag_pic)
8507     {
8508       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8509         {
8510           rtx reg = gen_reg_rtx (Pmode);
8512           emit_insn (gen_symGOTPLT2reg (reg, func));
8513           func = reg;
8514         }
8515       else
8516         func = legitimize_pic_address (func, Pmode, 0);
8517     }
8519   r0 = gen_rtx_REG (SImode, R0_REG);
8520   r1 = gen_rtx_REG (SImode, R1_REG);
8522   /* Since such a call function may use all call-clobbered
8523      registers, we force a mode switch earlier, so that we don't
8524      run out of registers when adjusting fpscr for the call.  */
8525   emit_insn (gen_force_mode_for_call ());
8527   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8528                                  SFUNC_GOT);
8529   operands[1] = force_reg (SImode, operands[1]);
8531   emit_move_insn (r0, func);
8532   emit_move_insn (r1, cookie_rtx);
8534   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8535     emit_call_insn (gen_call_value_pop_compact_rettramp
8536                         (operands[0], operands[1], operands[2],
8537                          operands[3], operands[4]));
8538   else
8539     emit_call_insn (gen_call_value_pop_compact
8540                         (operands[0], operands[1], operands[2],
8541                          operands[3], operands[4]));
8543   DONE;
8546 (define_expand "sibcall_epilogue"
8547   [(return)]
8548   ""
8549   "
8551   sh_expand_epilogue (1);
8552   if (TARGET_SHCOMPACT)
8553     {
8554       rtx insn, set;
8556       /* If epilogue clobbers r0, preserve it in macl.  */
8557       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8558         if ((set = single_set (insn))
8559             && GET_CODE (SET_DEST (set)) == REG
8560             && REGNO (SET_DEST (set)) == R0_REG)
8561           {
8562             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8563             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8565             /* We can't tell at this point whether the sibcall is a
8566                sibcall_compact and, if it is, whether it uses r0 or
8567                mach as operand 2, so let the instructions that
8568                preserve r0 be optimized away if r0 turns out to be
8569                dead.  */
8570             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8571             emit_move_insn (r0, tmp);
8572             break;
8573           }
8574     }
8575   DONE;
8578 (define_insn "indirect_jump_compact"
8579   [(set (pc)
8580         (match_operand:SI 0 "arith_reg_operand" "r"))]
8581   "TARGET_SH1"
8582   "jmp  @%0%#"
8583   [(set_attr "needs_delay_slot" "yes")
8584    (set_attr "type" "jump_ind")])
8586 (define_expand "indirect_jump"
8587   [(set (pc)
8588         (match_operand 0 "register_operand" ""))]
8589   ""
8590   "
8592   if (GET_MODE (operands[0]) != Pmode)
8593     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8596 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8597 ;; which can be present in structured code from indirect jumps which can not
8598 ;; be present in structured code.  This allows -fprofile-arcs to work.
8600 ;; For SH1 processors.
8601 (define_insn "casesi_jump_1"
8602   [(set (pc)
8603         (match_operand:SI 0 "register_operand" "r"))
8604    (use (label_ref (match_operand 1 "" "")))]
8605   "TARGET_SH1"
8606   "jmp  @%0%#"
8607   [(set_attr "needs_delay_slot" "yes")
8608    (set_attr "type" "jump_ind")])
8610 ;; For all later processors.
8611 (define_insn "casesi_jump_2"
8612   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8613                       (label_ref (match_operand 1 "" ""))))
8614    (use (label_ref (match_operand 2 "" "")))]
8615   "TARGET_SH2
8616    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8617   "braf %0%#"
8618   [(set_attr "needs_delay_slot" "yes")
8619    (set_attr "type" "jump_ind")])
8621 (define_insn "casesi_jump_media"
8622   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8623    (use (label_ref (match_operand 1 "" "")))]
8624   "TARGET_SHMEDIA"
8625   "blink        %0, r63"
8626   [(set_attr "type" "jump_media")])
8628 ;; Call subroutine returning any type.
8629 ;; ??? This probably doesn't work.
8631 (define_expand "untyped_call"
8632   [(parallel [(call (match_operand 0 "" "")
8633                     (const_int 0))
8634               (match_operand 1 "" "")
8635               (match_operand 2 "" "")])]
8636   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8637   "
8639   int i;
8641   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8643   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8644     {
8645       rtx set = XVECEXP (operands[2], 0, i);
8646       emit_move_insn (SET_DEST (set), SET_SRC (set));
8647     }
8649   /* The optimizer does not know that the call sets the function value
8650      registers we stored in the result block.  We avoid problems by
8651      claiming that all hard registers are used and clobbered at this
8652      point.  */
8653   emit_insn (gen_blockage ());
8655   DONE;
8658 ;; ------------------------------------------------------------------------
8659 ;; Misc insns
8660 ;; ------------------------------------------------------------------------
8662 (define_insn "dect"
8663   [(set (reg:SI T_REG)
8664         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8665    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8666   "TARGET_SH2"
8667   "dt   %0"
8668   [(set_attr "type" "arith")])
8670 (define_insn "nop"
8671   [(const_int 0)]
8672   ""
8673   "nop")
8675 ;; Load address of a label. This is only generated by the casesi expand,
8676 ;; and by machine_dependent_reorg (fixing up fp moves).
8677 ;; This must use unspec, because this only works for labels that are
8678 ;; within range,
8680 (define_insn "mova"
8681   [(set (reg:SI R0_REG)
8682         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8683   "TARGET_SH1"
8684   "mova %O0,r0"
8685   [(set_attr "in_delay_slot" "no")
8686    (set_attr "type" "arith")])
8688 ;; machine_dependent_reorg will make this a `mova'.
8689 (define_insn "mova_const"
8690   [(set (reg:SI R0_REG)
8691         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8692   "TARGET_SH1"
8693   "#"
8694   [(set_attr "in_delay_slot" "no")
8695    (set_attr "type" "arith")])
8697 (define_expand "GOTaddr2picreg"
8698   [(set (reg:SI R0_REG)
8699         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8700                    UNSPEC_MOVA))
8701    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8702    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8703   "" "
8705   if (TARGET_VXWORKS_RTP)
8706     {
8707       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8708       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8709       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8710       DONE;
8711     }
8713   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8714   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8716   if (TARGET_SHMEDIA)
8717     {
8718       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8719       rtx pic = operands[0];
8720       rtx lab = PATTERN (gen_call_site ());
8721       rtx insn, equiv;
8723       equiv = operands[1];
8724       operands[1] = gen_rtx_MINUS (Pmode,
8725                                    operands[1],
8726                                    gen_rtx_CONST
8727                                    (Pmode,
8728                                     gen_rtx_MINUS (Pmode,
8729                                                    gen_rtx_CONST (Pmode,
8730                                                                   lab),
8731                                                    pc_rtx)));
8732       operands[1] = gen_sym2PIC (operands[1]);
8733       PUT_MODE (operands[1], Pmode);
8735       if (Pmode == SImode)
8736         {
8737           emit_insn (gen_movsi_const (pic, operands[1]));
8738           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8739         }
8740       else
8741         {
8742           emit_insn (gen_movdi_const (pic, operands[1]));
8743           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8744         }
8746       insn = emit_move_insn (operands[0], tr);
8748       set_unique_reg_note (insn, REG_EQUAL, equiv);
8750       DONE;
8751     }
8755 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8756 ;; PIC register.
8758 (define_expand "vxworks_picreg"
8759   [(set (reg:SI PIC_REG)
8760         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8761    (set (reg:SI R0_REG)
8762         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8763    (set (reg:SI PIC_REG)
8764         (mem:SI (reg:SI PIC_REG)))
8765    (set (reg:SI PIC_REG)
8766         (mem:SI (plus:SI (reg:SI PIC_REG)
8767                          (reg:SI R0_REG))))]
8768   "TARGET_VXWORKS_RTP")
8770 (define_insn "*ptb"
8771   [(set (match_operand 0 "target_reg_operand" "=b")
8772         (const (unspec [(match_operand 1 "" "Csy")]
8773                              UNSPEC_DATALABEL)))]
8774   "TARGET_SHMEDIA && flag_pic
8775    && satisfies_constraint_Csy (operands[1])"
8776   "ptb/u        datalabel %1, %0"
8777   [(set_attr "type" "ptabs_media")
8778    (set_attr "length" "*")])
8780 (define_insn "ptrel_si"
8781   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8782         (plus:SI (match_operand:SI 1 "register_operand" "r")
8783               (pc)))
8784    (match_operand:SI 2 "" "")]
8785   "TARGET_SHMEDIA"
8786   "%O2: ptrel/u %1, %0"
8787   [(set_attr "type" "ptabs_media")])
8789 (define_insn "ptrel_di"
8790   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8791         (plus:DI (match_operand:DI 1 "register_operand" "r")
8792               (pc)))
8793    (match_operand:DI 2 "" "")]
8794   "TARGET_SHMEDIA"
8795   "%O2: ptrel/u %1, %0"
8796   [(set_attr "type" "ptabs_media")])
8798 (define_expand "builtin_setjmp_receiver"
8799   [(match_operand 0 "" "")]
8800   "flag_pic"
8801   "
8803   emit_insn (gen_GOTaddr2picreg ());
8804   DONE;
8807 (define_expand "call_site"
8808   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8809   "TARGET_SH1"
8810   "
8812   static HOST_WIDE_INT i = 0;
8813   operands[0] = GEN_INT (i);
8814   i++;
8817 (define_expand "sym_label2reg"
8818   [(set (match_operand:SI 0 "" "")
8819         (const:SI (minus:SI
8820                    (const:SI
8821                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8822                    (const:SI
8823                     (plus:SI
8824                      (match_operand:SI 2 "" "")
8825                      (const_int 2))))))]
8826   "TARGET_SH1" "")
8828 (define_expand "symGOT_load"
8829   [(set (match_dup 2) (match_operand 1 "" ""))
8830    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8831    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8832   ""
8833   "
8835   rtx insn, mem;
8837   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8838   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8840   if (TARGET_SHMEDIA)
8841     {
8842       rtx reg = operands[2];
8844       if (Pmode == DImode)
8845         {      
8846           if (flag_pic > 1)
8847             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8848           else
8849             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8850         }
8851       else
8852         {
8853           if (flag_pic > 1)
8854             emit_insn (gen_movsi_const (reg, operands[1]));
8855           else
8856             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8857         }
8858     }
8859   else
8860     emit_move_insn (operands[2], operands[1]);
8862   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8863                                              operands[2],
8864                                              gen_rtx_REG (Pmode, PIC_REG)));
8866   /* When stack protector inserts codes after the result is set to
8867      R0, @(rX, r12) will cause a spill failure for R0.  Don't schedule
8868      insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8869      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8870      matter because this is a rare situation.  */
8871   if (!TARGET_SHMEDIA
8872       && flag_stack_protect
8873       && GET_CODE (operands[1]) == CONST
8874       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8875       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8876       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8877                  \"__stack_chk_guard\") == 0)
8878     emit_insn (gen_blockage ());
8880   /* N.B. This is not constant for a GOTPLT relocation.  */
8881   mem = gen_rtx_MEM (Pmode, operands[3]);
8882   MEM_NOTRAP_P (mem) = 1;
8883   /* ??? Should we have a special alias set for the GOT?  */
8884   insn = emit_move_insn (operands[0], mem);
8886   set_unique_reg_note (insn, REG_EQUAL,
8887                        XVECEXP (XEXP (operands[1], 0), 0, 0));
8889   DONE;
8892 (define_expand "sym2GOT"
8893   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8894   ""
8895   "")
8897 (define_expand "symGOT2reg"
8898   [(match_operand 0 "" "") (match_operand 1 "" "")]
8899   ""
8900   "
8902   rtx gotsym, insn;
8904   gotsym = gen_sym2GOT (operands[1]);
8905   PUT_MODE (gotsym, Pmode);
8906   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8908   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8910   DONE;
8913 (define_expand "symGOTPLT2reg"
8914   [(match_operand 0 "" "") (match_operand 1 "" "")]
8915   ""
8916   "
8918   rtx pltsym = gen_rtx_CONST (Pmode,
8919                               gen_rtx_UNSPEC (Pmode,
8920                                               gen_rtvec (1, operands[1]),
8921                                               UNSPEC_GOTPLT));
8922   emit_insn (gen_symGOT_load (operands[0], pltsym));
8923   DONE;
8926 (define_expand "sym2GOTOFF"
8927   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8928   ""
8929   "")
8931 (define_expand "symGOTOFF2reg"
8932   [(match_operand 0 "" "") (match_operand 1 "" "")]
8933   ""
8934   "
8936   rtx gotoffsym, insn;
8937   rtx t = (!can_create_pseudo_p ()
8938            ? operands[0]
8939            : gen_reg_rtx (GET_MODE (operands[0])));
8941   gotoffsym = gen_sym2GOTOFF (operands[1]);
8942   PUT_MODE (gotoffsym, Pmode);
8943   emit_move_insn (t, gotoffsym);
8944   insn = emit_move_insn (operands[0],
8945                          gen_rtx_PLUS (Pmode, t,
8946                                        gen_rtx_REG (Pmode, PIC_REG)));
8948   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8950   DONE;
8953 (define_expand "symPLT_label2reg"
8954   [(set (match_operand:SI 0 "" "")
8955         (const:SI (minus:SI
8956                    (const:SI
8957                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8958                    (const:SI
8959                     (minus:SI
8960                      (const:SI (plus:SI
8961                                 (match_operand:SI 2 "" "")
8962                                 (const_int 2)))
8963                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8964    ;; Even though the PIC register is not really used by the call
8965    ;; sequence in which this is expanded, the PLT code assumes the PIC
8966    ;; register is set, so we must not skip its initialization.  Since
8967    ;; we only use this expand as part of calling sequences, and never
8968    ;; to take the address of a function, this is the best point to
8969    ;; insert the (use).  Using the PLT to take the address of a
8970    ;; function would be wrong, not only because the PLT entry could
8971    ;; then be called from a function that doesn't initialize the PIC
8972    ;; register to the proper GOT, but also because pointers to the
8973    ;; same function might not compare equal, should they be set by
8974    ;; different shared libraries.
8975    (use (reg:SI PIC_REG))]
8976   "TARGET_SH1"
8977   "")
8979 (define_expand "sym2PIC"
8980   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8981   ""
8982   "")
8984 ;; TLS code generation.
8985 ;; ??? this should be a define_insn_and_split
8986 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8987 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8988 ;; for details.
8990 (define_insn "tls_global_dynamic"
8991   [(set (match_operand:SI 0 "register_operand" "=&z")
8992         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8993                                   UNSPEC_TLSGD))
8994               (const_int 0)))
8995    (use (reg:PSI FPSCR_REG))
8996    (use (reg:SI PIC_REG))
8997    (clobber (reg:SI PR_REG))
8998    (clobber (scratch:SI))]
8999   "TARGET_SH1"
9000   "*
9002   return \"\\
9003 mov.l\\t1f,r4\\n\\
9004 \\tmova\\t2f,r0\\n\\
9005 \\tmov.l\\t2f,r1\\n\\
9006 \\tadd\\tr0,r1\\n\\
9007 \\tjsr\\t@r1\\n\\
9008 \\tadd\\tr12,r4\\n\\
9009 \\tbra\\t3f\\n\\
9010 \\tnop\\n\\
9011 \\t.align\\t2\\n\\
9012 1:\\t.long\\t%a1@TLSGD\\n\\
9013 2:\\t.long\\t__tls_get_addr@PLT\\n\\
9014 3:\";
9016   [(set_attr "type" "tls_load")
9017    (set_attr "length" "26")])
9019 (define_insn "tls_local_dynamic"
9020   [(set (match_operand:SI 0 "register_operand" "=&z")
9021         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
9022                                   UNSPEC_TLSLDM))
9023               (const_int 0)))
9024    (use (reg:PSI FPSCR_REG))
9025    (use (reg:SI PIC_REG))
9026    (clobber (reg:SI PR_REG))
9027    (clobber (scratch:SI))]
9028   "TARGET_SH1"
9029   "*
9031   return \"\\
9032 mov.l\\t1f,r4\\n\\
9033 \\tmova\\t2f,r0\\n\\
9034 \\tmov.l\\t2f,r1\\n\\
9035 \\tadd\\tr0,r1\\n\\
9036 \\tjsr\\t@r1\\n\\
9037 \\tadd\\tr12,r4\\n\\
9038 \\tbra\\t3f\\n\\
9039 \\tnop\\n\\
9040 \\t.align\\t2\\n\\
9041 1:\\t.long\\t%a1@TLSLDM\\n\\
9042 2:\\t.long\\t__tls_get_addr@PLT\\n\\
9043 3:\";
9045   [(set_attr "type" "tls_load")
9046    (set_attr "length" "26")])
9048 (define_expand "sym2DTPOFF"
9049   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
9050   ""
9051   "")
9053 (define_expand "symDTPOFF2reg"
9054   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
9055   ""
9056   "
9058   rtx dtpoffsym, insn;
9059   rtx t = (!can_create_pseudo_p ()
9060            ? operands[0]
9061            : gen_reg_rtx (GET_MODE (operands[0])));
9063   dtpoffsym = gen_sym2DTPOFF (operands[1]);
9064   PUT_MODE (dtpoffsym, Pmode);
9065   emit_move_insn (t, dtpoffsym);
9066   insn = emit_move_insn (operands[0],
9067                          gen_rtx_PLUS (Pmode, t, operands[2]));
9068   DONE;
9071 (define_expand "sym2GOTTPOFF"
9072   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
9073   ""
9074   "")
9076 (define_insn "tls_initial_exec"
9077   [(set (match_operand:SI 0 "register_operand" "=&r")
9078         (unspec:SI [(match_operand:SI 1 "" "")]
9079                     UNSPEC_TLSIE))
9080    (use (reg:SI GBR_REG))
9081    (use (reg:SI PIC_REG))
9082    (clobber (reg:SI R0_REG))]
9083   ""
9084   "*
9086   return \"\\
9087 mov.l\\t1f,r0\\n\\
9088 \\tstc\\tgbr,%0\\n\\
9089 \\tmov.l\\t@(r0,r12),r0\\n\\
9090 \\tbra\\t2f\\n\\
9091 \\tadd\\tr0,%0\\n\\
9092 \\t.align\\t2\\n\\
9093 1:\\t.long\\t%a1\\n\\
9094 2:\";
9096   [(set_attr "type" "tls_load")
9097    (set_attr "length" "16")])
9099 (define_expand "sym2TPOFF"
9100   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
9101   ""
9102   "")
9104 (define_expand "symTPOFF2reg"
9105   [(match_operand 0 "" "") (match_operand 1 "" "")]
9106   ""
9107   "
9109   rtx tpoffsym, insn;
9111   tpoffsym = gen_sym2TPOFF (operands[1]);
9112   PUT_MODE (tpoffsym, Pmode);
9113   insn = emit_move_insn (operands[0], tpoffsym);
9114   DONE;
9117 (define_insn "load_gbr"
9118   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
9119    (use (reg:SI GBR_REG))]
9120   ""
9121   "stc  gbr,%0"
9122   [(set_attr "type" "tls_load")])
9124 ;; case instruction for switch statements.
9126 ;; Operand 0 is index
9127 ;; operand 1 is the minimum bound
9128 ;; operand 2 is the maximum bound - minimum bound + 1
9129 ;; operand 3 is CODE_LABEL for the table;
9130 ;; operand 4 is the CODE_LABEL to go to if index out of range.
9132 (define_expand "casesi"
9133   [(match_operand:SI 0 "arith_reg_operand" "")
9134    (match_operand:SI 1 "arith_reg_operand" "")
9135    (match_operand:SI 2 "arith_reg_operand" "")
9136    (match_operand 3 "" "") (match_operand 4 "" "")]
9137   ""
9138   "
9140   rtx reg = gen_reg_rtx (SImode);
9141   rtx reg2 = gen_reg_rtx (SImode);
9142   if (TARGET_SHMEDIA)
9143     {
9144       rtx reg = gen_reg_rtx (DImode);
9145       rtx reg2 = gen_reg_rtx (DImode);
9146       rtx reg3 = gen_reg_rtx (Pmode);
9147       rtx reg4 = gen_reg_rtx (Pmode);
9148       rtx reg5 = gen_reg_rtx (Pmode);
9149       rtx load;
9151       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
9152       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
9153       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
9155       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
9156       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
9157       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
9158       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
9159       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
9160                                                (Pmode, operands[3])));
9161       /* Messy: can we subreg to clean this up? */
9162       if (Pmode == DImode)
9163         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
9164       else
9165         load = gen_casesi_load_media (reg4,
9166                                       gen_rtx_SUBREG (DImode, reg3, 0),
9167                                       reg2, operands[3]);
9168       PUT_MODE (SET_SRC (load), Pmode);
9169       emit_insn (load);
9170       /* ??? The following add could be eliminated if we used ptrel.  */
9171       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
9172       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
9173       emit_barrier ();
9174       DONE;
9175     }
9176   operands[1] = copy_to_mode_reg (SImode, operands[1]);
9177   operands[2] = copy_to_mode_reg (SImode, operands[2]);
9178   /* If optimizing, casesi_worker depends on the mode of the instruction
9179      before label it 'uses' - operands[3].  */
9180   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
9181                            reg));
9182   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
9183   if (TARGET_SH2)
9184     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
9185   else
9186     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
9187   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
9188      operands[3], but to lab.  We will fix this up in
9189      machine_dependent_reorg.  */
9190   emit_barrier ();
9191   DONE;
9194 (define_expand "casesi_0"
9195   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
9196    (set (match_dup 4) (minus:SI (match_dup 4)
9197                                 (match_operand:SI 1 "arith_operand" "")))
9198    (set (reg:SI T_REG)
9199         (gtu:SI (match_dup 4)
9200                 (match_operand:SI 2 "arith_reg_operand" "")))
9201    (set (pc)
9202         (if_then_else (ne (reg:SI T_REG)
9203                           (const_int 0))
9204                       (label_ref (match_operand 3 "" ""))
9205                       (pc)))]
9206   "TARGET_SH1"
9207   "")
9209 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
9210 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
9211 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
9213 (define_insn "casesi_worker_0"
9214   [(set (match_operand:SI 0 "register_operand" "=r,r")
9215         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
9216                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9217    (clobber (match_scratch:SI 3 "=X,1"))
9218    (clobber (match_scratch:SI 4 "=&z,z"))]
9219   "TARGET_SH1"
9220   "#")
9222 (define_split
9223   [(set (match_operand:SI 0 "register_operand" "")
9224         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9225                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9226    (clobber (match_scratch:SI 3 ""))
9227    (clobber (match_scratch:SI 4 ""))]
9228   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
9229   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9230    (parallel [(set (match_dup 0)
9231               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9232                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9233               (clobber (match_dup 3))])
9234    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
9235   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9237 (define_split
9238   [(set (match_operand:SI 0 "register_operand" "")
9239         (unspec:SI [(match_operand:SI 1 "register_operand" "")
9240                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9241    (clobber (match_scratch:SI 3 ""))
9242    (clobber (match_scratch:SI 4 ""))]
9243   "TARGET_SH2 && reload_completed"
9244   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
9245    (parallel [(set (match_dup 0)
9246               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
9247                           (label_ref (match_dup 2))] UNSPEC_CASESI))
9248               (clobber (match_dup 3))])]
9249   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
9251 (define_insn "casesi_worker_1"
9252   [(set (match_operand:SI 0 "register_operand" "=r,r")
9253         (unspec:SI [(reg:SI R0_REG)
9254                     (match_operand:SI 1 "register_operand" "0,r")
9255                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
9256    (clobber (match_scratch:SI 3 "=X,1"))]
9257   "TARGET_SH1"
9258   "*
9260   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9262   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9264   switch (GET_MODE (diff_vec))
9265     {
9266     case SImode:
9267       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
9268     case HImode:
9269       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
9270     case QImode:
9271       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9272         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9273       return \"mov.b    @(r0,%1),%0\";
9274     default:
9275       gcc_unreachable ();
9276     }
9278   [(set_attr "length" "4")])
9280 (define_insn "casesi_worker_2"
9281   [(set (match_operand:SI 0 "register_operand" "=r,r")
9282         (unspec:SI [(reg:SI R0_REG)
9283                     (match_operand:SI 1 "register_operand" "0,r")
9284                     (label_ref (match_operand 2 "" ""))
9285                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
9286    (clobber (match_operand:SI 4 "" "=X,1"))]
9287   "TARGET_SH2 && reload_completed && flag_pic"
9288   "*
9290   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9291   const char *load;
9293   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9295   switch (GET_MODE (diff_vec))
9296     {
9297     case SImode:
9298       output_asm_insn (\"shll2    %1\", operands);
9299       load = \"mov.l    @(r0,%1),%0\"; break;
9300     case HImode:
9301       output_asm_insn (\"add    %1,%1\", operands);
9302       load = \"mov.w    @(r0,%1),%0\"; break;
9303     case QImode:
9304       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9305         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
9306       else
9307         load = \"mov.b  @(r0,%1),%0\";
9308       break;
9309     default:
9310       gcc_unreachable ();
9311     }
9312   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
9313   return load;
9315   [(set_attr "length" "8")])
9317 (define_insn "casesi_shift_media"
9318   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9319         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
9320                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
9321                     UNSPEC_CASESI)))]
9322   "TARGET_SHMEDIA"
9323   "*
9325   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
9327   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9329   switch (GET_MODE (diff_vec))
9330     {
9331     case SImode:
9332       return \"shlli    %1, 2, %0\";
9333     case HImode:
9334       return \"shlli    %1, 1, %0\";
9335     case QImode:
9336       if (rtx_equal_p (operands[0], operands[1]))
9337         return \"\";
9338       return \"add      %1, r63, %0\";
9339     default:
9340       gcc_unreachable ();
9341     }
9343   [(set_attr "type" "arith_media")])
9345 (define_insn "casesi_load_media"
9346   [(set (match_operand 0 "any_arith_reg_dest" "=r")
9347         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
9348                          (match_operand:DI 2 "arith_reg_operand" "r")
9349                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
9350   "TARGET_SHMEDIA"
9351   "*
9353   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
9355   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
9357   switch (GET_MODE (diff_vec))
9358     {
9359     case SImode:
9360       return \"ldx.l    %1, %2, %0\";
9361     case HImode:
9362 #if 0
9363       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9364         return \"ldx.uw %1, %2, %0\";
9365 #endif
9366       return \"ldx.w    %1, %2, %0\";
9367     case QImode:
9368       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9369         return \"ldx.ub %1, %2, %0\";
9370       return \"ldx.b    %1, %2, %0\";
9371     default:
9372       gcc_unreachable ();
9373     }
9375   [(set_attr "type" "load_media")])
9377 (define_expand "return"
9378   [(return)]
9379   "reload_completed && ! sh_need_epilogue ()"
9380   "
9382   if (TARGET_SHMEDIA)
9383     {
9384       emit_jump_insn (gen_return_media ());
9385       DONE;
9386     }
9388   if (TARGET_SHCOMPACT
9389       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9390     {
9391       emit_jump_insn (gen_shcompact_return_tramp ());
9392       DONE;
9393     }
9396 (define_insn "*return_i"
9397   [(return)]
9398   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9399                     && (crtl->args.info.call_cookie
9400                         & CALL_COOKIE_RET_TRAMP (1)))
9401    && reload_completed
9402    && lookup_attribute (\"trap_exit\",
9403                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9404   "*
9405   {
9406     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9407                         && !current_function_interrupt)
9408        return \"rts/n\";
9409     else
9410        return \"%@      %#\";
9411   }"
9412   [(set_attr "type" "return")
9413    (set_attr "needs_delay_slot" "yes")])
9415 ;; trapa has no delay slot.
9416 (define_insn "*return_trapa"
9417   [(return)]
9418   "TARGET_SH1 && !TARGET_SHCOMPACT
9419    && reload_completed"
9420   "%@"
9421   [(set_attr "type" "return")])
9423 (define_expand "shcompact_return_tramp"
9424   [(return)]
9425   "TARGET_SHCOMPACT
9426    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9427   "
9429   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9431   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9432   emit_jump_insn (gen_shcompact_return_tramp_i ());
9433   DONE;
9436 (define_insn "shcompact_return_tramp_i"
9437   [(parallel [(return) (use (reg:SI R0_REG))])]
9438   "TARGET_SHCOMPACT
9439    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9440   "jmp  @r0%#"
9441   [(set_attr "type" "jump_ind")
9442    (set_attr "needs_delay_slot" "yes")])
9444 (define_insn "return_media_i"
9445   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9446   "TARGET_SHMEDIA && reload_completed"
9447   "blink        %0, r63"
9448   [(set_attr "type" "jump_media")])
9450 (define_insn "return_media_rte"
9451   [(return)]
9452   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9453   "rte"
9454   [(set_attr "type" "jump_media")])
9456 (define_expand "return_media"
9457   [(return)]
9458   "TARGET_SHMEDIA && reload_completed"
9459   "
9461   int tr_regno = sh_media_register_for_return ();
9462   rtx tr;
9464   if (current_function_interrupt)
9465     {
9466       emit_jump_insn (gen_return_media_rte ());
9467       DONE;
9468     }
9469   if (tr_regno < 0)
9470     {
9471       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9473       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9474       tr_regno = TR0_REG;
9475       tr = gen_rtx_REG (Pmode, tr_regno);
9476       emit_move_insn (tr, r18);
9477     }
9478   else
9479     tr = gen_rtx_REG (Pmode, tr_regno);
9481   emit_jump_insn (gen_return_media_i (tr));
9482   DONE;
9485 (define_insn "shcompact_preserve_incoming_args"
9486   [(set (match_operand:SI 0 "register_operand" "+r")
9487         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9488   "TARGET_SHCOMPACT"
9489   ""
9490   [(set_attr "length" "0")])
9492 (define_insn "shcompact_incoming_args"
9493   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9494    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9495    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9496    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9497    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9498    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9499    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9500    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9501    (set (mem:BLK (reg:SI MACL_REG))
9502         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9503    (use (reg:SI R0_REG))
9504    (clobber (reg:SI R0_REG))
9505    (clobber (reg:SI MACL_REG))
9506    (clobber (reg:SI MACH_REG))
9507    (clobber (reg:SI PR_REG))]
9508   "TARGET_SHCOMPACT"
9509   "jsr  @r0%#"
9510   [(set_attr "needs_delay_slot" "yes")])
9512 (define_insn "shmedia_save_restore_regs_compact"
9513   [(set (reg:SI SP_REG)
9514         (plus:SI (reg:SI SP_REG)
9515                  (match_operand:SI 0 "immediate_operand" "i")))
9516    (use (reg:SI R0_REG))
9517    (clobber (reg:SI PR_REG))]
9518   "TARGET_SHCOMPACT
9519    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9520        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9521   "jsr @r0%#"
9522   [(set_attr "needs_delay_slot" "yes")])
9524 (define_expand "prologue"
9525   [(const_int 0)]
9526   ""
9527   "sh_expand_prologue (); DONE;")
9529 (define_expand "epilogue"
9530   [(return)]
9531   ""
9532   "
9534   sh_expand_epilogue (0);
9535   emit_jump_insn (gen_return ());
9536   DONE;
9539 (define_expand "eh_return"
9540   [(use (match_operand 0 "register_operand" ""))]
9541   ""
9543   rtx ra = operands[0];
9545   if (TARGET_SHMEDIA64)
9546     emit_insn (gen_eh_set_ra_di (ra));
9547   else
9548     emit_insn (gen_eh_set_ra_si (ra));
9550   DONE;
9553 ;; Clobber the return address on the stack.  We can't expand this
9554 ;; until we know where it will be put in the stack frame.
9556 (define_insn "eh_set_ra_si"
9557   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9558       UNSPECV_EH_RETURN)
9559    (clobber (match_scratch:SI 1 "=&r"))]
9560   "! TARGET_SHMEDIA64"
9561   "#")
9563 (define_insn "eh_set_ra_di"
9564   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9565       UNSPECV_EH_RETURN)
9566    (clobber (match_scratch:DI 1 "=&r"))]
9567   "TARGET_SHMEDIA64"
9568   "#")
9570 (define_split
9571   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9572       UNSPECV_EH_RETURN)
9573    (clobber (match_scratch 1 ""))]
9574   "reload_completed"
9575   [(const_int 0)]
9576   "
9578   sh_set_return_address (operands[0], operands[1]);
9579   DONE;
9582 (define_insn "blockage"
9583   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9584   ""
9585   ""
9586   [(set_attr "length" "0")])
9588 ;; ------------------------------------------------------------------------
9589 ;; Scc instructions
9590 ;; ------------------------------------------------------------------------
9592 (define_insn "movt"
9593   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9594         (eq:SI (reg:SI T_REG) (const_int 1)))]
9595   "TARGET_SH1"
9596   "movt %0"
9597   [(set_attr "type" "arith")])
9599 ;; complements the T bit and stores the result in a register
9600 (define_insn "movrt"
9601   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9602         (if_then_else (eq:SI (reg:SI T_REG) (const_int 0))
9603         (const_int 1)
9604         (const_int 0)))]
9605   "TARGET_SH2A"
9606   "movrt\\t%0"
9607    [(set_attr "type" "arith")])
9609 (define_expand "seq"
9610   [(set (match_operand:SI 0 "arith_reg_dest" "")
9611         (match_dup 1))]
9612   ""
9613   "
9615   if (TARGET_SHMEDIA)
9616     {
9617       rtx reg;
9619       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9620       if (sh_compare_op1 != const0_rtx)
9621         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9622                                     ? GET_MODE (sh_compare_op0)
9623                                     : GET_MODE (sh_compare_op1),
9624                                     sh_compare_op1);
9625       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
9626         {
9627           if (GET_MODE (operands[0]) != SImode)
9628             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
9630           switch (GET_MODE (sh_compare_op0))
9631             {
9632             case SImode:
9633               emit_insn (gen_cmpeqsi_media (operands[0],
9634                                               sh_compare_op0, sh_compare_op1));
9635               break;
9637             case DImode:
9638               emit_insn (gen_cmpeqdi_media (operands[0],
9639                                               sh_compare_op0, sh_compare_op1));
9640               break;
9642             case SFmode:
9643               if (! TARGET_SHMEDIA_FPU)
9644                 FAIL;
9645               emit_insn (gen_cmpeqsf_media (operands[0],
9646                                               sh_compare_op0, sh_compare_op1));
9647               break;
9649             case DFmode:
9650               if (! TARGET_SHMEDIA_FPU)
9651                 FAIL;
9652               emit_insn (gen_cmpeqdf_media (operands[0],
9653                                               sh_compare_op0, sh_compare_op1));
9654               break;
9656             default:
9657               FAIL;
9658             }
9659           DONE;
9660         }
9662       reg = operands[0];
9663       if (GET_MODE (operands[0]) != SImode)
9664         reg = (!can_create_pseudo_p ()
9665                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9666                : gen_reg_rtx (SImode));
9668       switch (GET_MODE (sh_compare_op0))
9669         {
9670         case SImode:
9671           emit_insn (gen_cmpeqsi_media (reg,
9672                                         sh_compare_op0, sh_compare_op1));
9673           break;
9675         case DImode:
9676           emit_insn (gen_cmpeqdi_media (reg,
9677                                         sh_compare_op0, sh_compare_op1));
9678           break;
9680         case SFmode:
9681           if (! TARGET_SHMEDIA_FPU)
9682             FAIL;
9683           emit_insn (gen_cmpeqsf_media (reg,
9684                                         sh_compare_op0, sh_compare_op1));
9685           break;
9687         case DFmode:
9688           if (! TARGET_SHMEDIA_FPU)
9689             FAIL;
9690           emit_insn (gen_cmpeqdf_media (reg,
9691                                         sh_compare_op0, sh_compare_op1));
9692           break;
9694         default:
9695           FAIL;
9696         }
9698       if (GET_MODE (operands[0]) == DImode)
9699         emit_insn (gen_extendsidi2 (operands[0], reg));
9701       DONE;
9702     }
9703   if (sh_expand_t_scc (EQ, operands[0]))
9704     DONE;
9705   if (! currently_expanding_to_rtl)
9706     FAIL;
9707   operands[1] = prepare_scc_operands (EQ);
9710 (define_expand "slt"
9711   [(set (match_operand:SI 0 "arith_reg_operand" "")
9712         (match_dup 1))]
9713   ""
9714   "
9716   if (TARGET_SHMEDIA)
9717     {
9718       rtx reg;
9720       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9721       if (sh_compare_op1 != const0_rtx)
9722         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9723                                     ? GET_MODE (sh_compare_op0)
9724                                     : GET_MODE (sh_compare_op1),
9725                                     sh_compare_op1);
9727       reg = operands[0];
9728       if (GET_MODE (operands[0]) != SImode)
9729         reg = (!can_create_pseudo_p ()
9730                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9731                : gen_reg_rtx (SImode));
9733       switch (GET_MODE (sh_compare_op0))
9734         {
9735         case SImode:
9736           emit_insn (gen_cmpgtsi_media (reg,
9737                                         sh_compare_op1, sh_compare_op0));
9738           break;
9740         case DImode:
9741           emit_insn (gen_cmpgtdi_media (reg,
9742                                         sh_compare_op1, sh_compare_op0));
9743           break;
9745         case SFmode:
9746           if (! TARGET_SHMEDIA_FPU)
9747             FAIL;
9748           emit_insn (gen_cmpgtsf_media (reg,
9749                                         sh_compare_op1, sh_compare_op0));
9750           break;
9752         case DFmode:
9753           if (! TARGET_SHMEDIA_FPU)
9754             FAIL;
9755           emit_insn (gen_cmpgtdf_media (reg,
9756                                         sh_compare_op1, sh_compare_op0));
9757           break;
9759         default:
9760           FAIL;
9761         }
9763       if (GET_MODE (operands[0]) == DImode)
9764         emit_insn (gen_extendsidi2 (operands[0], reg));
9766       DONE;
9767     }
9768   if (! currently_expanding_to_rtl)
9769     FAIL;
9770   operands[1] = prepare_scc_operands (LT);
9773 (define_expand "sle"
9774   [(match_operand:SI 0 "arith_reg_operand" "")]
9775   ""
9776   "
9778   rtx tmp = sh_compare_op0;
9780   if (TARGET_SHMEDIA)
9781     {
9782       rtx reg;
9784       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9785       if (sh_compare_op1 != const0_rtx)
9786         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9787                                     ? GET_MODE (sh_compare_op0)
9788                                     : GET_MODE (sh_compare_op1),
9789                                     sh_compare_op1);
9791       reg = operands[0];
9792       if (GET_MODE (operands[0]) != SImode)
9793         reg = (!can_create_pseudo_p ()
9794                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9795                : gen_reg_rtx (SImode));
9797       switch (GET_MODE (sh_compare_op0))
9798         {
9799         case SImode:
9800           {
9801             tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9803             emit_insn (gen_cmpgtsi_media (tmp,
9804                                           sh_compare_op0, sh_compare_op1));
9805             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9806             break;
9807           }
9809         case DImode:
9810           {
9811             tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9813             emit_insn (gen_cmpgtdi_media (tmp,
9814                                           sh_compare_op0, sh_compare_op1));
9815             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9816             break;
9817           }
9819         case SFmode:
9820           if (! TARGET_SHMEDIA_FPU)
9821             FAIL;
9822           emit_insn (gen_cmpgesf_media (reg,
9823                                         sh_compare_op1, sh_compare_op0));
9824           break;
9826         case DFmode:
9827           if (! TARGET_SHMEDIA_FPU)
9828             FAIL;
9829           emit_insn (gen_cmpgedf_media (reg,
9830                                         sh_compare_op1, sh_compare_op0));
9831           break;
9833         default:
9834           FAIL;
9835         }
9837       if (GET_MODE (operands[0]) == DImode)
9838         emit_insn (gen_extendsidi2 (operands[0], reg));
9840       DONE;
9841     }
9843   sh_compare_op0 = sh_compare_op1;
9844   sh_compare_op1 = tmp;
9845   emit_insn (gen_sge (operands[0]));
9846   DONE;
9849 (define_expand "sgt"
9850   [(set (match_operand:SI 0 "arith_reg_operand" "")
9851         (match_dup 1))]
9852   ""
9853   "
9855   if (TARGET_SHMEDIA)
9856     {
9857       rtx reg;
9859       reg = operands[0];
9860       if (GET_MODE (operands[0]) != SImode)
9861         reg = (!can_create_pseudo_p () ?
9862                gen_rtx_SUBREG (SImode, operands[0], 0)
9863                : gen_reg_rtx (SImode));
9864       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9865       if (sh_compare_op1 != const0_rtx)
9866         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9867                                     ? GET_MODE (sh_compare_op0)
9868                                     : GET_MODE (sh_compare_op1),
9869                                     sh_compare_op1);
9871       switch (GET_MODE (sh_compare_op0))
9872         {
9873         case SImode:
9874           emit_insn (gen_cmpgtsi_media (reg,
9875                                         sh_compare_op0, sh_compare_op1));
9876           break;
9878         case DImode:
9879           emit_insn (gen_cmpgtdi_media (reg,
9880                                         sh_compare_op0, sh_compare_op1));
9881           break;
9883         case SFmode:
9884           if (! TARGET_SHMEDIA_FPU)
9885             FAIL;
9886           emit_insn (gen_cmpgtsf_media (reg,
9887                                         sh_compare_op0, sh_compare_op1));
9888           break;
9890         case DFmode:
9891           if (! TARGET_SHMEDIA_FPU)
9892             FAIL;
9893           emit_insn (gen_cmpgtdf_media (reg,
9894                                         sh_compare_op0, sh_compare_op1));
9895           break;
9897         default:
9898           FAIL;
9899         }
9901       if (GET_MODE (operands[0]) == DImode)
9902         emit_insn (gen_extendsidi2 (operands[0], reg));
9904       DONE;
9905     }
9906   if (! currently_expanding_to_rtl)
9907     FAIL;
9908   operands[1] = prepare_scc_operands (GT);
9911 (define_expand "sge"
9912   [(set (match_operand:SI 0 "arith_reg_operand" "")
9913         (match_dup 1))]
9914   ""
9915   "
9917   if (TARGET_SHMEDIA)
9918     {
9919       rtx reg;
9920       enum machine_mode mode = GET_MODE (sh_compare_op0);
9922       if ((mode) == VOIDmode)
9923         mode = GET_MODE (sh_compare_op1);
9924       reg = operands[0];
9925       if (GET_MODE (operands[0]) != SImode)
9926         reg = (!can_create_pseudo_p ()
9927                ? gen_rtx_SUBREG (SImode, operands[0], 0)
9928                : gen_reg_rtx (SImode));
9929       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9930       if (sh_compare_op1 != const0_rtx)
9931         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9933       switch (mode)
9934         {
9935         case SImode:
9936           {
9937             rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9939             emit_insn (gen_cmpgtsi_media (tmp,
9940                                           sh_compare_op1, sh_compare_op0));
9941             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9942             break;
9943           }
9945         case DImode:
9946           {
9947             rtx tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
9949             emit_insn (gen_cmpgtdi_media (tmp,
9950                                           sh_compare_op1, sh_compare_op0));
9951             emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
9952             break;
9953           }
9955         case SFmode:
9956           if (! TARGET_SHMEDIA_FPU)
9957             FAIL;
9958           emit_insn (gen_cmpgesf_media (reg,
9959                                         sh_compare_op0, sh_compare_op1));
9960           break;
9962         case DFmode:
9963           if (! TARGET_SHMEDIA_FPU)
9964             FAIL;
9965           emit_insn (gen_cmpgedf_media (reg,
9966                                         sh_compare_op0, sh_compare_op1));
9967           break;
9969         default:
9970           FAIL;
9971         }
9973       if (GET_MODE (operands[0]) == DImode)
9974         emit_insn (gen_extendsidi2 (operands[0], reg));
9976       DONE;
9977     }
9979   if (! currently_expanding_to_rtl)
9980     FAIL;
9981   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9982     {
9983       if (TARGET_IEEE)
9984         {
9985           rtx lab = gen_label_rtx ();
9986           prepare_scc_operands (EQ);
9987           emit_jump_insn (gen_branch_true (lab));
9988           prepare_scc_operands (GT);
9989           emit_label (lab);
9990           emit_insn (gen_movt (operands[0]));
9991         }
9992       else
9993         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9994       DONE;
9995     }
9996   operands[1] = prepare_scc_operands (GE);
9999 (define_expand "sgtu"
10000   [(set (match_operand:SI 0 "arith_reg_operand" "")
10001         (match_dup 1))]
10002   ""
10003   "
10005   if (TARGET_SHMEDIA)
10006     {
10007       rtx reg;
10009       reg = operands[0];
10010       if (GET_MODE (operands[0]) == DImode)
10011         reg = (!can_create_pseudo_p ()
10012                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10013                : gen_reg_rtx (SImode));
10014       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10015       if (sh_compare_op1 != const0_rtx)
10016         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10017                                     ? GET_MODE (sh_compare_op0)
10018                                     : GET_MODE (sh_compare_op1),
10019                                     sh_compare_op1);
10021       emit_insn (gen_cmpgtudi_media (reg,
10022                                      sh_compare_op0, sh_compare_op1));
10023       if (GET_MODE (operands[0]) == DImode)
10024         emit_insn (gen_extendsidi2 (operands[0], reg));
10026       DONE;
10027     }
10028   if (! currently_expanding_to_rtl)
10029     FAIL;
10030   operands[1] = prepare_scc_operands (GTU);
10033 (define_expand "sltu"
10034   [(set (match_operand:SI 0 "arith_reg_operand" "")
10035         (match_dup 1))]
10036   ""
10037   "
10039   if (TARGET_SHMEDIA)
10040     {
10041       rtx reg;
10043       reg = operands[0];
10044       if (GET_MODE (operands[0]) == DImode)
10045         reg = (!can_create_pseudo_p ()
10046                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10047                : gen_reg_rtx (SImode));
10048       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10049       if (sh_compare_op1 != const0_rtx)
10050         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10051                                     ? GET_MODE (sh_compare_op0)
10052                                     : GET_MODE (sh_compare_op1),
10053                                     sh_compare_op1);
10055       emit_insn (gen_cmpgtudi_media (reg,
10056                                      sh_compare_op1, sh_compare_op0));
10057       if (GET_MODE (operands[0]) == DImode)
10058         emit_insn (gen_extendsidi2 (operands[0], reg));
10060       DONE;
10061     }
10062   if (! currently_expanding_to_rtl)
10063     FAIL;
10064   operands[1] = prepare_scc_operands (LTU);
10067 (define_expand "sleu"
10068   [(set (match_operand:SI 0 "arith_reg_operand" "")
10069         (match_dup 1))]
10070   ""
10071   "
10073   if (TARGET_SHMEDIA)
10074     {
10075       rtx tmp, reg;
10077       reg = operands[0];
10078       if (GET_MODE (operands[0]) != SImode)
10079         reg = (!can_create_pseudo_p ()
10080                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10081                : gen_reg_rtx (SImode));
10082       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10083       if (sh_compare_op1 != const0_rtx)
10084         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10085                                     ? GET_MODE (sh_compare_op0)
10086                                     : GET_MODE (sh_compare_op1),
10087                                     sh_compare_op1);
10089       tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10091       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
10092       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10093       if (GET_MODE (operands[0]) == DImode)
10094         emit_insn (gen_extendsidi2 (operands[0], reg));
10096       DONE;
10097     }
10098   if (! currently_expanding_to_rtl)
10099     FAIL;
10100   operands[1] = prepare_scc_operands (LEU);
10103 (define_expand "sgeu"
10104   [(set (match_operand:SI 0 "arith_reg_operand" "")
10105         (match_dup 1))]
10106   ""
10107   "
10109   if (TARGET_SHMEDIA)
10110     {
10111       rtx tmp, reg;
10113       reg = operands[0];
10114       if (GET_MODE (operands[0]) != SImode)
10115         reg = (!can_create_pseudo_p ()
10116                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10117                : gen_reg_rtx (SImode));
10118       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10119       if (sh_compare_op1 != const0_rtx)
10120         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10121                                     ? GET_MODE (sh_compare_op0)
10122                                     : GET_MODE (sh_compare_op1),
10123                                     sh_compare_op1);
10125       tmp = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (SImode);
10127       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
10128       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10129       if (GET_MODE (operands[0]) == DImode)
10130         emit_insn (gen_extendsidi2 (operands[0], reg));
10132       DONE;
10133     }
10135   if (! currently_expanding_to_rtl)
10136     FAIL;
10137   operands[1] = prepare_scc_operands (GEU);
10140 ;; sne moves the complement of the T reg to DEST like this:
10141 ;;      cmp/eq ...
10142 ;;      mov    #-1,temp
10143 ;;      negc   temp,dest
10144 ;;   This is better than xoring compare result with 1 because it does
10145 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
10146 ;;   loop.
10148 (define_expand "sne"
10149   [(set (match_dup 2) (const_int -1))
10150    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
10151                    (neg:SI (plus:SI (match_dup 1)
10152                                     (match_dup 2))))
10153               (set (reg:SI T_REG)
10154                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
10155                           (const_int 0)))])]
10156   ""
10157   "
10159   if (TARGET_SHMEDIA)
10160     {
10161       rtx tmp, reg;
10163       reg = operands[0];
10164       if (GET_MODE (operands[0]) != SImode)
10165         reg = (!can_create_pseudo_p ()
10166                ? gen_rtx_SUBREG (SImode, operands[0], 0)
10167                : gen_reg_rtx (SImode));
10168       if (! TARGET_SHMEDIA_FPU
10169           && GET_MODE (sh_compare_op0) != DImode
10170           && GET_MODE (sh_compare_op0) != SImode)
10171         FAIL;
10173       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10174       if (sh_compare_op1 != const0_rtx)
10175         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
10176                                     ? GET_MODE (sh_compare_op0)
10177                                     : GET_MODE (sh_compare_op1),
10178                                     sh_compare_op1);
10180       tmp = !can_create_pseudo_p () ? reg : gen_reg_rtx (SImode);
10182       emit_insn (gen_seq (tmp));
10183       emit_insn (gen_cmpeqdi_media (reg, tmp, const0_rtx));
10184       if (GET_MODE (operands[0]) == DImode)
10185         emit_insn (gen_extendsidi2 (operands[0], reg));
10187       DONE;
10188     }
10190   if (sh_expand_t_scc (NE, operands[0]))
10191     DONE;
10192   if (! currently_expanding_to_rtl)
10193     FAIL;
10194   operands[1] = prepare_scc_operands (EQ);
10195   operands[2] = gen_reg_rtx (SImode);
10198 (define_expand "sunordered"
10199   [(set (match_operand:SI 0 "arith_reg_operand" "")
10200         (unordered:SI (match_dup 1) (match_dup 2)))]
10201   "TARGET_SHMEDIA_FPU"
10202   "
10204   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
10205   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
10208 ;; Use the same trick for FP sle / sge
10210 ;; Apart from the constant use and the T setting, this is like movt,
10211 ;; except that it uses the logically negated value of T, i.e.
10212 ;; operand[0] := T ? 0 : 1.
10213 (define_expand "movnegt"
10214   [(set (match_dup 2) (const_int -1))
10215    (parallel [(set (match_operand 0 "" "")
10216                    (neg:SI (plus:SI (match_dup 1)
10217                                     (match_dup 2))))
10218               (set (reg:SI T_REG)
10219                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
10220                           (const_int 0)))])]
10221   "TARGET_SH1"
10222   "operands[2] = gen_reg_rtx (SImode);")
10224 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
10225 ;; This prevents a regression that occurred when we switched from xor to
10226 ;; mov/neg for sne.
10228 (define_split
10229   [(set (match_operand:SI 0 "arith_reg_dest" "")
10230         (plus:SI (reg:SI T_REG)
10231                  (const_int -1)))]
10232   "TARGET_SH1"
10233   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
10234    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
10235   "")
10237 ;; -------------------------------------------------------------------------
10238 ;; Instructions to cope with inline literal tables
10239 ;; -------------------------------------------------------------------------
10241 ; 2 byte integer in line
10243 (define_insn "consttable_2"
10244  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10245                     (match_operand 1 "" "")]
10246                    UNSPECV_CONST2)]
10247  ""
10248  "*
10250   if (operands[1] != const0_rtx)
10251     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
10252   return \"\";
10254  [(set_attr "length" "2")
10255  (set_attr "in_delay_slot" "no")])
10257 ; 4 byte integer in line
10259 (define_insn "consttable_4"
10260  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10261                     (match_operand 1 "" "")]
10262                    UNSPECV_CONST4)]
10263  ""
10264  "*
10266   if (operands[1] != const0_rtx)
10267     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
10268   return \"\";
10270  [(set_attr "length" "4")
10271   (set_attr "in_delay_slot" "no")])
10273 ; 8 byte integer in line
10275 (define_insn "consttable_8"
10276  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
10277                     (match_operand 1 "" "")]
10278                    UNSPECV_CONST8)]
10279  ""
10280  "*
10282   if (operands[1] != const0_rtx)
10283     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
10284   return \"\";
10286  [(set_attr "length" "8")
10287   (set_attr "in_delay_slot" "no")])
10289 ; 4 byte floating point
10291 (define_insn "consttable_sf"
10292  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
10293                     (match_operand 1 "" "")]
10294                    UNSPECV_CONST4)]
10295  ""
10296  "*
10298   if (operands[1] != const0_rtx)
10299     {
10300       REAL_VALUE_TYPE d;
10301       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10302       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
10303     }
10304   return \"\";
10306  [(set_attr "length" "4")
10307   (set_attr "in_delay_slot" "no")])
10309 ; 8 byte floating point
10311 (define_insn "consttable_df"
10312  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
10313                     (match_operand 1 "" "")]
10314                    UNSPECV_CONST8)]
10315  ""
10316  "*
10318   if (operands[1] != const0_rtx)
10319     {
10320       REAL_VALUE_TYPE d;
10321       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
10322       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
10323     }
10324   return \"\";
10326  [(set_attr "length" "8")
10327   (set_attr "in_delay_slot" "no")])
10329 ;; Alignment is needed for some constant tables; it may also be added for
10330 ;; Instructions at the start of loops, or after unconditional branches.
10331 ;; ??? We would get more accurate lengths if we did instruction
10332 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
10333 ;; here is too conservative.
10335 ; align to a two byte boundary
10337 (define_expand "align_2"
10338  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
10339  ""
10340  "")
10342 ; align to a four byte boundary
10343 ;; align_4 and align_log are instructions for the starts of loops, or
10344 ;; after unconditional branches, which may take up extra room.
10346 (define_expand "align_4"
10347  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
10348  ""
10349  "")
10351 ; align to a cache line boundary
10353 (define_insn "align_log"
10354  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
10355  ""
10356  ""
10357  [(set_attr "length" "0")
10358   (set_attr "in_delay_slot" "no")])
10360 ; emitted at the end of the literal table, used to emit the
10361 ; 32bit branch labels if needed.
10363 (define_insn "consttable_end"
10364   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
10365   ""
10366   "* return output_jump_label_table ();"
10367   [(set_attr "in_delay_slot" "no")])
10369 ; emitted at the end of the window in the literal table.
10371 (define_insn "consttable_window_end"
10372   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
10373   ""
10374   ""
10375   [(set_attr "length" "0")
10376    (set_attr "in_delay_slot" "no")])
10378 ;; -------------------------------------------------------------------------
10379 ;; Misc
10380 ;; -------------------------------------------------------------------------
10382 ;; String/block move insn.
10384 (define_expand "movmemsi"
10385   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
10386                    (mem:BLK (match_operand:BLK 1 "" "")))
10387               (use (match_operand:SI 2 "nonmemory_operand" ""))
10388               (use (match_operand:SI 3 "immediate_operand" ""))
10389               (clobber (reg:SI PR_REG))
10390               (clobber (reg:SI R4_REG))
10391               (clobber (reg:SI R5_REG))
10392               (clobber (reg:SI R0_REG))])]
10393   "TARGET_SH1 && ! TARGET_SH5"
10394   "
10396   if(expand_block_move (operands))
10397      DONE;
10398   else FAIL;
10401 (define_insn "block_move_real"
10402   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10403                    (mem:BLK (reg:SI R5_REG)))
10404               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10405               (clobber (reg:SI PR_REG))
10406               (clobber (reg:SI R0_REG))])]
10407   "TARGET_SH1 && ! TARGET_HARD_SH4"
10408   "jsr  @%0%#"
10409   [(set_attr "type" "sfunc")
10410    (set_attr "needs_delay_slot" "yes")])
10412 (define_insn "block_lump_real"
10413   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10414                    (mem:BLK (reg:SI R5_REG)))
10415               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10416               (use (reg:SI R6_REG))
10417               (clobber (reg:SI PR_REG))
10418               (clobber (reg:SI T_REG))
10419               (clobber (reg:SI R4_REG))
10420               (clobber (reg:SI R5_REG))
10421               (clobber (reg:SI R6_REG))
10422               (clobber (reg:SI R0_REG))])]
10423   "TARGET_SH1 && ! TARGET_HARD_SH4"
10424   "jsr  @%0%#"
10425   [(set_attr "type" "sfunc")
10426    (set_attr "needs_delay_slot" "yes")])
10428 (define_insn "block_move_real_i4"
10429   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10430                    (mem:BLK (reg:SI R5_REG)))
10431               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10432               (clobber (reg:SI PR_REG))
10433               (clobber (reg:SI R0_REG))
10434               (clobber (reg:SI R1_REG))
10435               (clobber (reg:SI R2_REG))])]
10436   "TARGET_HARD_SH4"
10437   "jsr  @%0%#"
10438   [(set_attr "type" "sfunc")
10439    (set_attr "needs_delay_slot" "yes")])
10441 (define_insn "block_lump_real_i4"
10442   [(parallel [(set (mem:BLK (reg:SI R4_REG))
10443                    (mem:BLK (reg:SI R5_REG)))
10444               (use (match_operand:SI 0 "arith_reg_operand" "r"))
10445               (use (reg:SI R6_REG))
10446               (clobber (reg:SI PR_REG))
10447               (clobber (reg:SI T_REG))
10448               (clobber (reg:SI R4_REG))
10449               (clobber (reg:SI R5_REG))
10450               (clobber (reg:SI R6_REG))
10451               (clobber (reg:SI R0_REG))
10452               (clobber (reg:SI R1_REG))
10453               (clobber (reg:SI R2_REG))
10454               (clobber (reg:SI R3_REG))])]
10455   "TARGET_HARD_SH4"
10456   "jsr  @%0%#"
10457   [(set_attr "type" "sfunc")
10458    (set_attr "needs_delay_slot" "yes")])
10460 ;; -------------------------------------------------------------------------
10461 ;; Floating point instructions.
10462 ;; -------------------------------------------------------------------------
10464 ;; ??? All patterns should have a type attribute.
10466 (define_expand "movpsi"
10467   [(set (match_operand:PSI 0 "register_operand" "")
10468         (match_operand:PSI 1 "general_movsrc_operand" ""))]
10469   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10470   "")
10472 ;; The c / m alternative is a fake to guide reload to load directly into
10473 ;; fpscr, since reload doesn't know how to use post-increment.
10474 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
10475 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
10476 ;; predicate after reload.
10477 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
10478 ;; like a mac -> gpr move.
10479 (define_insn "fpu_switch"
10480   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
10481         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
10482   "TARGET_SH2E
10483    && (! reload_completed
10484        || true_regnum (operands[0]) != FPSCR_REG
10485        || GET_CODE (operands[1]) != MEM
10486        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
10487   "@
10488         ! precision stays the same
10489         lds.l   %1,fpscr
10490         mov.l   %1,%0
10491         #
10492         lds     %1,fpscr
10493         mov     %1,%0
10494         mov.l   %1,%0
10495         sts     fpscr,%0
10496         sts.l   fpscr,%0"
10497   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
10498    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
10500 (define_peephole2
10501   [(set (reg:PSI FPSCR_REG)
10502         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10503   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
10504   [(const_int 0)]
10506   rtx fpscr, mem, new_insn;
10508   fpscr = SET_DEST (PATTERN (curr_insn));
10509   mem = SET_SRC (PATTERN (curr_insn));
10510   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10512   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10513   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10514   DONE;
10517 (define_split
10518   [(set (reg:PSI FPSCR_REG)
10519         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
10520   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
10521    && (flag_peephole2 ? epilogue_completed : reload_completed)"
10522   [(const_int 0)]
10524   rtx fpscr, mem, new_insn;
10526   fpscr = SET_DEST (PATTERN (curr_insn));
10527   mem = SET_SRC (PATTERN (curr_insn));
10528   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
10530   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
10531   REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
10533   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
10534     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
10535   DONE;
10538 ;; ??? This uses the fp unit, but has no type indicating that.
10539 ;; If we did that, this would either give a bogus latency or introduce
10540 ;; a bogus FIFO constraint.
10541 ;; Since this insn is currently only used for prologues/epilogues,
10542 ;; it is probably best to claim no function unit, which matches the
10543 ;; current setting.
10544 (define_insn "toggle_sz"
10545   [(set (reg:PSI FPSCR_REG)
10546         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
10547   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10548   "fschg"
10549   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
10551 ;; There's no way we can use it today, since optimize mode switching
10552 ;; doesn't enable us to know from which mode we're switching to the
10553 ;; mode it requests, to tell whether we can use a relative mode switch
10554 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
10555 ;; memory).
10556 (define_insn "toggle_pr"
10557   [(set (reg:PSI FPSCR_REG)
10558         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
10559   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
10560   "fpchg"
10561   [(set_attr "type" "fpscr_toggle")])
10563 (define_expand "addsf3"
10564   [(set (match_operand:SF 0 "arith_reg_operand" "")
10565         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
10566                  (match_operand:SF 2 "arith_reg_operand" "")))]
10567   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10568   "
10570   if (TARGET_SH2E)
10571     {
10572       expand_sf_binop (&gen_addsf3_i, operands);
10573       DONE;
10574     }
10577 (define_insn "*addsf3_media"
10578   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10579         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10580                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10581   "TARGET_SHMEDIA_FPU"
10582   "fadd.s       %1, %2, %0"
10583   [(set_attr "type" "fparith_media")])
10585 (define_insn_and_split "unary_sf_op"
10586   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10587         (vec_select:V2SF
10588          (vec_concat:V2SF
10589           (vec_select:SF
10590            (match_dup 0)
10591            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
10592           (match_operator:SF 2 "unary_float_operator"
10593             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10594                             (parallel [(match_operand 4
10595                                         "const_int_operand" "n")]))]))
10596          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
10597   "TARGET_SHMEDIA_FPU"
10598   "#"
10599   "TARGET_SHMEDIA_FPU && reload_completed"
10600   [(set (match_dup 5) (match_dup 6))]
10601   "
10603   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10604   rtx op1 = gen_rtx_REG (SFmode,
10605                          (true_regnum (operands[1])
10606                           + (INTVAL (operands[4]) ^ endian)));
10608   operands[7] = gen_rtx_REG (SFmode,
10609                              (true_regnum (operands[0])
10610                               + (INTVAL (operands[3]) ^ endian)));
10611   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
10613   [(set_attr "type" "fparith_media")])
10615 (define_insn_and_split "binary_sf_op0"
10616   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10617         (vec_concat:V2SF
10618           (match_operator:SF 3 "binary_float_operator"
10619             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10620                             (parallel [(const_int 0)]))
10621              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10622                             (parallel [(const_int 0)]))])
10623           (vec_select:SF
10624            (match_dup 0)
10625            (parallel [(const_int 1)]))))]
10626   "TARGET_SHMEDIA_FPU"
10627   "#"
10628   "&& reload_completed"
10629   [(set (match_dup 4) (match_dup 5))]
10630   "
10632   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10633   rtx op1 = gen_rtx_REG (SFmode,
10634                          true_regnum (operands[1]) + endian);
10635   rtx op2 = gen_rtx_REG (SFmode,
10636                          true_regnum (operands[2]) + endian);
10638   operands[4] = gen_rtx_REG (SFmode,
10639                              true_regnum (operands[0]) + endian);
10640   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10642   [(set_attr "type" "fparith_media")])
10644 (define_insn_and_split "binary_sf_op1"
10645   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10646         (vec_concat:V2SF
10647           (vec_select:SF
10648            (match_dup 0)
10649            (parallel [(const_int 0)]))
10650           (match_operator:SF 3 "binary_float_operator"
10651             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
10652                             (parallel [(const_int 1)]))
10653              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
10654                             (parallel [(const_int 1)]))])))]
10655   "TARGET_SHMEDIA_FPU"
10656   "#"
10657   "&& reload_completed"
10658   [(set (match_dup 4) (match_dup 5))]
10659   "
10661   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
10662   rtx op1 = gen_rtx_REG (SFmode,
10663                          true_regnum (operands[1]) + (1 ^ endian));
10664   rtx op2 = gen_rtx_REG (SFmode,
10665                          true_regnum (operands[2]) + (1 ^ endian));
10667   operands[4] = gen_rtx_REG (SFmode,
10668                              true_regnum (operands[0]) + (1 ^ endian));
10669   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
10671   [(set_attr "type" "fparith_media")])
10673 (define_insn "addsf3_i"
10674   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10675         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10676                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10677    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10678   "TARGET_SH2E"
10679   "fadd %2,%0"
10680   [(set_attr "type" "fp")
10681    (set_attr "fp_mode" "single")])
10683 (define_expand "subsf3"
10684   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10685         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10686                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10687   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10688   "
10690   if (TARGET_SH2E)
10691     {
10692       expand_sf_binop (&gen_subsf3_i, operands);
10693       DONE;
10694     }
10697 (define_insn "*subsf3_media"
10698   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10699         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10700                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10701   "TARGET_SHMEDIA_FPU"
10702   "fsub.s       %1, %2, %0"
10703   [(set_attr "type" "fparith_media")])
10705 (define_insn "subsf3_i"
10706   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10707         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
10708                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10709    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10710   "TARGET_SH2E"
10711   "fsub %2,%0"
10712   [(set_attr "type" "fp")
10713    (set_attr "fp_mode" "single")])
10715 (define_expand "mulsf3"
10716   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10717         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10718                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10719   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10720   "")
10722 (define_insn "*mulsf3_media"
10723   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10724         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10725                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10726   "TARGET_SHMEDIA_FPU"
10727   "fmul.s       %1, %2, %0"
10728   [(set_attr "type" "fparith_media")])
10730 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10731 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
10732 ;; we start out with a mulsf pattern that does not depend on fpscr.
10733 ;; This is split after combine to introduce the dependency, in order to
10734 ;; get mode switching and scheduling right.
10735 (define_insn_and_split "mulsf3_ie"
10736   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10737         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10738                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10739   "TARGET_SH2E"
10740   "fmul %2,%0"
10741   "TARGET_SH4 || TARGET_SH2A_SINGLE"
10742   [(const_int 0)]
10743   "
10745   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
10746              get_fpscr_rtx ()));
10747   DONE;
10749   [(set_attr "type" "fp")])
10751 (define_insn "mulsf3_i4"
10752   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10753         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10754                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10755    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10756   "TARGET_SH2E"
10757   "fmul %2,%0"
10758   [(set_attr "type" "fp")
10759    (set_attr "fp_mode" "single")])
10761 (define_insn "mac_media"
10762   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10763         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10764                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10765                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10766   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10767   "fmac.s %1, %2, %0"
10768   [(set_attr "type" "fparith_media")])
10770 (define_insn "*macsf3"
10771   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10772         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10773                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10774                  (match_operand:SF 3 "arith_reg_operand" "0")))
10775    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10776   "TARGET_SH2E && TARGET_FMAC"
10777   "fmac fr0,%2,%0"
10778   [(set_attr "type" "fp")
10779    (set_attr "fp_mode" "single")])
10781 (define_expand "divsf3"
10782   [(set (match_operand:SF 0 "arith_reg_operand" "")
10783         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10784                 (match_operand:SF 2 "arith_reg_operand" "")))]
10785   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10786   "
10788   if (TARGET_SH2E)
10789     {
10790       expand_sf_binop (&gen_divsf3_i, operands);
10791       DONE;
10792     }
10795 (define_insn "*divsf3_media"
10796   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10797         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10798                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10799   "TARGET_SHMEDIA_FPU"
10800   "fdiv.s       %1, %2, %0"
10801   [(set_attr "type" "fdiv_media")])
10803 (define_insn "divsf3_i"
10804   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10805         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10806                  (match_operand:SF 2 "arith_reg_operand" "f")))
10807    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10808   "TARGET_SH2E"
10809   "fdiv %2,%0"
10810   [(set_attr "type" "fdiv")
10811    (set_attr "fp_mode" "single")])
10813 (define_insn "floatdisf2"
10814   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10815         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10816   "TARGET_SHMEDIA_FPU"
10817   "float.qs %1, %0"
10818   [(set_attr "type" "fpconv_media")])
10820 (define_expand "floatsisf2"
10821   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10822         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10823   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10824   "
10826   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10827     {
10828       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10829       DONE;
10830     }
10833 (define_insn "*floatsisf2_media"
10834   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10835         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10836   "TARGET_SHMEDIA_FPU"
10837   "float.ls     %1, %0"
10838   [(set_attr "type" "fpconv_media")])
10840 (define_insn "floatsisf2_i4"
10841   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10842         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10843    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10844   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10845   "float        %1,%0"
10846   [(set_attr "type" "fp")
10847    (set_attr "fp_mode" "single")])
10849 (define_insn "*floatsisf2_ie"
10850   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10851         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10852   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10853   "float        %1,%0"
10854   [(set_attr "type" "fp")])
10856 (define_insn "fix_truncsfdi2"
10857   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10858         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10859   "TARGET_SHMEDIA_FPU"
10860   "ftrc.sq %1, %0"
10861   [(set_attr "type" "fpconv_media")])
10863 (define_expand "fix_truncsfsi2"
10864   [(set (match_operand:SI 0 "fpul_operand" "=y")
10865         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10866   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10867   "
10869   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10870     {
10871       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10872       DONE;
10873     }
10876 (define_insn "*fix_truncsfsi2_media"
10877   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10878         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10879   "TARGET_SHMEDIA_FPU"
10880   "ftrc.sl      %1, %0"
10881   [(set_attr "type" "fpconv_media")])
10883 (define_insn "fix_truncsfsi2_i4"
10884   [(set (match_operand:SI 0 "fpul_operand" "=y")
10885         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10886    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10887   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10888   "ftrc %1,%0"
10889   [(set_attr "type" "ftrc_s")
10890    (set_attr "fp_mode" "single")])
10892 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10893 ;; fix_truncsfsi2_i4.
10894 ;; (define_insn "fix_truncsfsi2_i4_2"
10895 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10896 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10897 ;;   (use (reg:PSI FPSCR_REG))
10898 ;;   (clobber (reg:SI FPUL_REG))]
10899 ;;  "TARGET_SH4"
10900 ;;  "#"
10901 ;;  [(set_attr "length" "4")
10902 ;;   (set_attr "fp_mode" "single")])
10904 ;;(define_split
10905 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10906 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10907 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10908 ;;   (clobber (reg:SI FPUL_REG))]
10909 ;;  "TARGET_SH4"
10910 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10911 ;;            (use (match_dup 2))])
10912 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10914 (define_insn "*fixsfsi"
10915   [(set (match_operand:SI 0 "fpul_operand" "=y")
10916         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10917   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10918   "ftrc %1,%0"
10919   [(set_attr "type" "fp")])
10921 (define_insn "cmpgtsf_t"
10922   [(set (reg:SI T_REG)
10923         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10924                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10925   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10926   "fcmp/gt      %1,%0"
10927   [(set_attr "type" "fp_cmp")
10928    (set_attr "fp_mode" "single")])
10930 (define_insn "cmpeqsf_t"
10931   [(set (reg:SI T_REG)
10932         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10933                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10934   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10935   "fcmp/eq      %1,%0"
10936   [(set_attr "type" "fp_cmp")
10937    (set_attr "fp_mode" "single")])
10939 (define_insn "ieee_ccmpeqsf_t"
10940   [(set (reg:SI T_REG)
10941         (ior:SI (reg:SI T_REG)
10942                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10943                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10944   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10945   "* return output_ieee_ccmpeq (insn, operands);"
10946   [(set_attr "length" "4")])
10949 (define_insn "cmpgtsf_t_i4"
10950   [(set (reg:SI T_REG)
10951         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10952                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10953    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10954   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10955   "fcmp/gt      %1,%0"
10956   [(set_attr "type" "fp_cmp")
10957    (set_attr "fp_mode" "single")])
10959 (define_insn "cmpeqsf_t_i4"
10960   [(set (reg:SI T_REG)
10961         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10962                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10963    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10964   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10965   "fcmp/eq      %1,%0"
10966   [(set_attr "type" "fp_cmp")
10967    (set_attr "fp_mode" "single")])
10969 (define_insn "*ieee_ccmpeqsf_t_4"
10970   [(set (reg:SI T_REG)
10971         (ior:SI (reg:SI T_REG)
10972                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10973                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10974    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10975   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10976   "* return output_ieee_ccmpeq (insn, operands);"
10977   [(set_attr "length" "4")
10978    (set_attr "fp_mode" "single")])
10980 (define_insn "cmpeqsf_media"
10981   [(set (match_operand:SI 0 "register_operand" "=r")
10982         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10983                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10984   "TARGET_SHMEDIA_FPU"
10985   "fcmpeq.s     %1, %2, %0"
10986   [(set_attr "type" "fcmp_media")])
10988 (define_insn "cmpgtsf_media"
10989   [(set (match_operand:SI 0 "register_operand" "=r")
10990         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10991                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10992   "TARGET_SHMEDIA_FPU"
10993   "fcmpgt.s     %1, %2, %0"
10994   [(set_attr "type" "fcmp_media")])
10996 (define_insn "cmpgesf_media"
10997   [(set (match_operand:SI 0 "register_operand" "=r")
10998         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10999                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11000   "TARGET_SHMEDIA_FPU"
11001   "fcmpge.s     %1, %2, %0"
11002   [(set_attr "type" "fcmp_media")])
11004 (define_insn "cmpunsf_media"
11005   [(set (match_operand:SI 0 "register_operand" "=r")
11006         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
11007                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
11008   "TARGET_SHMEDIA_FPU"
11009   "fcmpun.s     %1, %2, %0"
11010   [(set_attr "type" "fcmp_media")])
11012 (define_expand "cmpsf"
11013   [(set (reg:SI T_REG)
11014         (compare (match_operand:SF 0 "arith_operand" "")
11015                  (match_operand:SF 1 "arith_operand" "")))]
11016   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11017   "
11019   sh_compare_op0 = operands[0];
11020   sh_compare_op1 = operands[1];
11021   DONE;
11024 (define_expand "negsf2"
11025   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11026         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11027   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11028   "
11030   if (TARGET_SH2E)
11031     {
11032       expand_sf_unop (&gen_negsf2_i, operands);
11033       DONE;
11034     }
11037 (define_insn "*negsf2_media"
11038   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11039         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11040   "TARGET_SHMEDIA_FPU"
11041   "fneg.s       %1, %0"
11042   [(set_attr "type" "fmove_media")])
11044 (define_insn "negsf2_i"
11045   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11046         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11047    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11048   "TARGET_SH2E"
11049   "fneg %0"
11050   [(set_attr "type" "fmove")
11051    (set_attr "fp_mode" "single")])
11053 (define_expand "sqrtsf2"
11054   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11055         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11056   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
11057   "
11059   if (TARGET_SH3E)
11060     {
11061       expand_sf_unop (&gen_sqrtsf2_i, operands);
11062       DONE;
11063     }
11066 (define_insn "*sqrtsf2_media"
11067   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11068         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11069   "TARGET_SHMEDIA_FPU"
11070   "fsqrt.s      %1, %0"
11071   [(set_attr "type" "fdiv_media")])
11073 (define_insn "sqrtsf2_i"
11074   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11075         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11076    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11077   "TARGET_SH3E"
11078   "fsqrt        %0"
11079   [(set_attr "type" "fdiv")
11080    (set_attr "fp_mode" "single")])
11082 (define_insn "rsqrtsf2"
11083   [(set (match_operand:SF 0 "register_operand" "=f")
11084         (div:SF (match_operand:SF 1 "immediate_operand" "i")
11085                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
11086    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11087   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
11088    && operands[1] == CONST1_RTX (SFmode)"
11089   "fsrra        %0"
11090   [(set_attr "type" "fsrra")
11091    (set_attr "fp_mode" "single")])
11093 (define_insn "fsca"
11094   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
11095         (vec_concat:V2SF
11096          (unspec:SF [(mult:SF
11097                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
11098                       (match_operand:SF 2 "immediate_operand" "i"))
11099                     ] UNSPEC_FSINA)
11100          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
11101                     ] UNSPEC_FCOSA)))
11102    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11103   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
11104    && operands[2] == sh_fsca_int2sf ()"
11105   "fsca fpul,%d0"
11106   [(set_attr "type" "fsca")
11107    (set_attr "fp_mode" "single")])
11109 (define_expand "sinsf2"
11110   [(set (match_operand:SF 0 "nonimmediate_operand" "")
11111         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
11112                    UNSPEC_FSINA))]
11113   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
11114   "
11116   rtx scaled = gen_reg_rtx (SFmode);
11117   rtx truncated = gen_reg_rtx (SImode);
11118   rtx fsca = gen_reg_rtx (V2SFmode);
11119   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
11121   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
11122   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
11123   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11124                           get_fpscr_rtx ()));
11125   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
11126   DONE;
11129 (define_expand "cossf2"
11130   [(set (match_operand:SF 0 "nonimmediate_operand" "")
11131         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
11132                    UNSPEC_FCOSA))]
11133   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
11134   "
11136   rtx scaled = gen_reg_rtx (SFmode);
11137   rtx truncated = gen_reg_rtx (SImode);
11138   rtx fsca = gen_reg_rtx (V2SFmode);
11139   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
11141   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
11142   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
11143   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11144                           get_fpscr_rtx ()));
11145   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
11146   DONE;
11149 (define_expand "sindf2"
11150   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11151         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11152                    UNSPEC_FSINA))]
11153   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11154   "
11156   rtx scaled = gen_reg_rtx (DFmode);
11157   rtx truncated = gen_reg_rtx (SImode);
11158   rtx fsca = gen_reg_rtx (V2SFmode);
11159   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11160   rtx sfresult = gen_reg_rtx (SFmode);
11162   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11163   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11164   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11165                           get_fpscr_rtx ()));
11166   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
11167   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11168   DONE;
11171 (define_expand "cosdf2"
11172   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11173         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
11174                    UNSPEC_FCOSA))]
11175   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
11176   "
11178   rtx scaled = gen_reg_rtx (DFmode);
11179   rtx truncated = gen_reg_rtx (SImode);
11180   rtx fsca = gen_reg_rtx (V2SFmode);
11181   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
11182   rtx sfresult = gen_reg_rtx (SFmode);
11184   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
11185   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
11186   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
11187                           get_fpscr_rtx ()));
11188   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
11189   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
11190   DONE;
11193 (define_expand "abssf2"
11194   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
11195         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
11196   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
11197   "
11199   if (TARGET_SH2E)
11200     {
11201       expand_sf_unop (&gen_abssf2_i, operands);
11202       DONE;
11203     }
11206 (define_insn "*abssf2_media"
11207   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11208         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11209   "TARGET_SHMEDIA_FPU"
11210   "fabs.s       %1, %0"
11211   [(set_attr "type" "fmove_media")])
11213 (define_insn "abssf2_i"
11214   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11215         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
11216    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11217   "TARGET_SH2E"
11218   "fabs %0"
11219   [(set_attr "type" "fmove")
11220    (set_attr "fp_mode" "single")])
11222 (define_expand "adddf3"
11223   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11224         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11225                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11226   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11227   "
11229   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11230     {
11231       expand_df_binop (&gen_adddf3_i, operands);
11232       DONE;
11233     }
11236 (define_insn "*adddf3_media"
11237   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11238         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11239                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11240   "TARGET_SHMEDIA_FPU"
11241   "fadd.d       %1, %2, %0"
11242   [(set_attr "type" "dfparith_media")])
11244 (define_insn "adddf3_i"
11245   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11246         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11247                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11248    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11249   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11250   "fadd %2,%0"
11251   [(set_attr "type" "dfp_arith")
11252    (set_attr "fp_mode" "double")])
11254 (define_expand "subdf3"
11255   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11256         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11257                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11258   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11259   "
11261   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11262     {
11263       expand_df_binop (&gen_subdf3_i, operands);
11264       DONE;
11265     }
11268 (define_insn "*subdf3_media"
11269   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11270         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11271                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11272   "TARGET_SHMEDIA_FPU"
11273   "fsub.d       %1, %2, %0"
11274   [(set_attr "type" "dfparith_media")])
11276 (define_insn "subdf3_i"
11277   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11278         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11279                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11280    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11281   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11282   "fsub %2,%0"
11283   [(set_attr "type" "dfp_arith")
11284    (set_attr "fp_mode" "double")])
11286 (define_expand "muldf3"
11287   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11288         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11289                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11290   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11291   "
11293   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11294     {
11295       expand_df_binop (&gen_muldf3_i, operands);
11296       DONE;
11297     }
11300 (define_insn "*muldf3_media"
11301   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11302         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
11303                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11304   "TARGET_SHMEDIA_FPU"
11305   "fmul.d       %1, %2, %0"
11306   [(set_attr "type" "dfmul_media")])
11308 (define_insn "muldf3_i"
11309   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11310         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
11311                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11312    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11313   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11314   "fmul %2,%0"
11315   [(set_attr "type" "dfp_mul")
11316    (set_attr "fp_mode" "double")])
11318 (define_expand "divdf3"
11319   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11320         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
11321                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
11322   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11323   "
11325   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11326     {
11327       expand_df_binop (&gen_divdf3_i, operands);
11328       DONE;
11329     }
11332 (define_insn "*divdf3_media"
11333   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11334         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
11335                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11336   "TARGET_SHMEDIA_FPU"
11337   "fdiv.d       %1, %2, %0"
11338   [(set_attr "type" "dfdiv_media")])
11340 (define_insn "divdf3_i"
11341   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11342         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
11343                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
11344    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
11345   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11346   "fdiv %2,%0"
11347   [(set_attr "type" "dfdiv")
11348    (set_attr "fp_mode" "double")])
11350 (define_insn "floatdidf2"
11351   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11352         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
11353   "TARGET_SHMEDIA_FPU"
11354   "float.qd     %1, %0"
11355   [(set_attr "type" "dfpconv_media")])
11357 (define_expand "floatsidf2"
11358   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11359         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
11360   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11361   "
11363   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11364     {
11365       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
11366                                       get_fpscr_rtx ()));
11367       DONE;
11368     }
11371 (define_insn "*floatsidf2_media"
11372   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11373         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
11374   "TARGET_SHMEDIA_FPU"
11375   "float.ld     %1, %0"
11376   [(set_attr "type" "dfpconv_media")])
11378 (define_insn "floatsidf2_i"
11379   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11380         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
11381    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11382   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11383   "float        %1,%0"
11384   [(set_attr "type" "dfp_conv")
11385    (set_attr "fp_mode" "double")])
11387 (define_insn "fix_truncdfdi2"
11388   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
11389         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11390   "TARGET_SHMEDIA_FPU"
11391   "ftrc.dq      %1, %0"
11392   [(set_attr "type" "dfpconv_media")])
11394 (define_expand "fix_truncdfsi2"
11395   [(set (match_operand:SI 0 "fpul_operand" "")
11396         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11397   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11398   "
11400   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11401     {
11402       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
11403                                           get_fpscr_rtx ()));
11404       DONE;
11405     }
11408 (define_insn "*fix_truncdfsi2_media"
11409   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
11410         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11411   "TARGET_SHMEDIA_FPU"
11412   "ftrc.dl      %1, %0"
11413   [(set_attr "type" "dfpconv_media")])
11415 (define_insn "fix_truncdfsi2_i"
11416   [(set (match_operand:SI 0 "fpul_operand" "=y")
11417         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11418    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11419   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11420   "ftrc %1,%0"
11421   [(set_attr "type" "dfp_conv")
11422    (set_attr "dfp_comp" "no")
11423    (set_attr "fp_mode" "double")])
11425 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
11426 ;; fix_truncdfsi2_i.
11427 ;; (define_insn "fix_truncdfsi2_i4"
11428 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11429 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11430 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
11431 ;;    (clobber (reg:SI FPUL_REG))]
11432 ;;   "TARGET_SH4"
11433 ;;   "#"
11434 ;;   [(set_attr "length" "4")
11435 ;;    (set_attr "fp_mode" "double")])
11437 ;; (define_split
11438 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11439 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
11440 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
11441 ;;    (clobber (reg:SI FPUL_REG))]
11442 ;;   "TARGET_SH4"
11443 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
11444 ;;            (use (match_dup 2))])
11445 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
11447 (define_insn "cmpgtdf_t"
11448   [(set (reg:SI T_REG)
11449         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
11450                (match_operand:DF 1 "arith_reg_operand" "f")))
11451    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11452   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11453   "fcmp/gt      %1,%0"
11454   [(set_attr "type" "dfp_cmp")
11455    (set_attr "fp_mode" "double")])
11457 (define_insn "cmpeqdf_t"
11458   [(set (reg:SI T_REG)
11459         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11460                (match_operand:DF 1 "arith_reg_operand" "f")))
11461    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11462   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11463   "fcmp/eq      %1,%0"
11464   [(set_attr "type" "dfp_cmp")
11465    (set_attr "fp_mode" "double")])
11467 (define_insn "*ieee_ccmpeqdf_t"
11468   [(set (reg:SI T_REG)
11469         (ior:SI (reg:SI T_REG)
11470                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
11471                        (match_operand:DF 1 "arith_reg_operand" "f"))))
11472    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11473   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11474   "* return output_ieee_ccmpeq (insn, operands);"
11475   [(set_attr "length" "4")
11476    (set_attr "fp_mode" "double")])
11478 (define_insn "cmpeqdf_media"
11479   [(set (match_operand:SI 0 "register_operand" "=r")
11480         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11481                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11482   "TARGET_SHMEDIA_FPU"
11483   "fcmpeq.d     %1,%2,%0"
11484   [(set_attr "type" "fcmp_media")])
11486 (define_insn "cmpgtdf_media"
11487   [(set (match_operand:SI 0 "register_operand" "=r")
11488         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11489                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11490   "TARGET_SHMEDIA_FPU"
11491   "fcmpgt.d     %1,%2,%0"
11492   [(set_attr "type" "fcmp_media")])
11494 (define_insn "cmpgedf_media"
11495   [(set (match_operand:SI 0 "register_operand" "=r")
11496         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11497                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11498   "TARGET_SHMEDIA_FPU"
11499   "fcmpge.d     %1,%2,%0"
11500   [(set_attr "type" "fcmp_media")])
11502 (define_insn "cmpundf_media"
11503   [(set (match_operand:SI 0 "register_operand" "=r")
11504         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
11505                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
11506   "TARGET_SHMEDIA_FPU"
11507   "fcmpun.d     %1,%2,%0"
11508   [(set_attr "type" "fcmp_media")])
11510 (define_expand "cmpdf"
11511   [(set (reg:SI T_REG)
11512         (compare (match_operand:DF 0 "arith_operand" "")
11513                  (match_operand:DF 1 "arith_operand" "")))]
11514   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11515   "
11517   sh_compare_op0 = operands[0];
11518   sh_compare_op1 = operands[1];
11519   DONE;
11522 (define_expand "negdf2"
11523   [(set (match_operand:DF 0 "arith_reg_operand" "")
11524         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11525   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11526   "
11528   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11529     {
11530       expand_df_unop (&gen_negdf2_i, operands);
11531       DONE;
11532     }
11535 (define_insn "*negdf2_media"
11536   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11537         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11538   "TARGET_SHMEDIA_FPU"
11539   "fneg.d       %1, %0"
11540   [(set_attr "type" "fmove_media")])
11542 (define_insn "negdf2_i"
11543   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11544         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11545    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11546   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11547   "fneg %0"
11548   [(set_attr "type" "fmove")
11549    (set_attr "fp_mode" "double")])
11551 (define_expand "sqrtdf2"
11552   [(set (match_operand:DF 0 "arith_reg_operand" "")
11553         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11554   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11555   "
11557   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11558     {
11559       expand_df_unop (&gen_sqrtdf2_i, operands);
11560       DONE;
11561     }
11564 (define_insn "*sqrtdf2_media"
11565   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11566         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11567   "TARGET_SHMEDIA_FPU"
11568   "fsqrt.d      %1, %0"
11569   [(set_attr "type" "dfdiv_media")])
11571 (define_insn "sqrtdf2_i"
11572   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11573         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11574    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11575   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11576   "fsqrt        %0"
11577   [(set_attr "type" "dfdiv")
11578    (set_attr "fp_mode" "double")])
11580 (define_expand "absdf2"
11581   [(set (match_operand:DF 0 "arith_reg_operand" "")
11582         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
11583   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11584   "
11586   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11587     {
11588       expand_df_unop (&gen_absdf2_i, operands);
11589       DONE;
11590     }
11593 (define_insn "*absdf2_media"
11594   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11595         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11596   "TARGET_SHMEDIA_FPU"
11597   "fabs.d       %1, %0"
11598   [(set_attr "type" "fmove_media")])
11600 (define_insn "absdf2_i"
11601   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11602         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
11603    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11604   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11605   "fabs %0"
11606   [(set_attr "type" "fmove")
11607    (set_attr "fp_mode" "double")])
11609 (define_expand "extendsfdf2"
11610   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
11611         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
11612   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11613   "
11615   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11616     {
11617       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
11618                                         get_fpscr_rtx ()));
11619       DONE;
11620     }
11623 (define_insn "*extendsfdf2_media"
11624   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11625         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
11626   "TARGET_SHMEDIA_FPU"
11627   "fcnv.sd      %1, %0"
11628   [(set_attr "type" "dfpconv_media")])
11630 (define_insn "extendsfdf2_i4"
11631   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
11632         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
11633    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11634   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11635   "fcnvsd  %1,%0"
11636   [(set_attr "type" "fp")
11637    (set_attr "fp_mode" "double")])
11639 (define_expand "truncdfsf2"
11640   [(set (match_operand:SF 0 "fpul_operand" "")
11641         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
11642   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
11643   "
11645   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
11646     {
11647       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
11648                                        get_fpscr_rtx ()));
11649       DONE;
11650     }
11653 (define_insn "*truncdfsf2_media"
11654   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
11655         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
11656   "TARGET_SHMEDIA_FPU"
11657   "fcnv.ds      %1, %0"
11658   [(set_attr "type" "dfpconv_media")])
11660 (define_insn "truncdfsf2_i4"
11661   [(set (match_operand:SF 0 "fpul_operand" "=y")
11662         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
11663    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
11664   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
11665   "fcnvds  %1,%0"
11666   [(set_attr "type" "fp")
11667    (set_attr "fp_mode" "double")])
11669 ;; Bit field extract patterns.  These give better code for packed bitfields,
11670 ;; because they allow auto-increment addresses to be generated.
11672 (define_expand "insv"
11673   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
11674                          (match_operand:SI 1 "immediate_operand" "")
11675                          (match_operand:SI 2 "immediate_operand" ""))
11676         (match_operand:SI 3 "general_operand" ""))]
11677   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
11678   "
11680   rtx addr_target, orig_address, shift_reg, qi_val;
11681   HOST_WIDE_INT bitsize, size, v = 0;
11682   rtx x = operands[3];
11684   if (TARGET_SH2A && TARGET_BITOPS
11685       && (satisfies_constraint_Sbw (operands[0])
11686           || satisfies_constraint_Sbv (operands[0]))
11687       && satisfies_constraint_M (operands[1])
11688       && satisfies_constraint_K03 (operands[2]))
11689     {
11690       if (satisfies_constraint_N (operands[3]))
11691         {
11692           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
11693           DONE;
11694         }
11695       else if (satisfies_constraint_M (operands[3]))
11696         {
11697           emit_insn (gen_bset_m2a (operands[0], operands[2]));
11698           DONE;
11699         }
11700       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
11701                 && satisfies_constraint_M (operands[1]))
11702         {
11703           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11704           DONE;
11705         }
11706       else if (REG_P (operands[3])
11707                && satisfies_constraint_M (operands[1]))
11708         {
11709           emit_insn (gen_bld_reg (operands[3], const0_rtx));
11710           emit_insn (gen_bst_m2a (operands[0], operands[2]));
11711           DONE;
11712         }
11713     }
11714   /* ??? expmed doesn't care for non-register predicates.  */
11715   if (! memory_operand (operands[0], VOIDmode)
11716       || ! immediate_operand (operands[1], VOIDmode)
11717       || ! immediate_operand (operands[2], VOIDmode)
11718       || ! general_operand (x, VOIDmode))
11719     FAIL;
11720   /* If this isn't a 16 / 24 / 32 bit field, or if
11721      it doesn't start on a byte boundary, then fail.  */
11722   bitsize = INTVAL (operands[1]);
11723   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11724       || (INTVAL (operands[2]) % 8) != 0)
11725     FAIL;
11727   size = bitsize / 8;
11728   orig_address = XEXP (operands[0], 0);
11729   shift_reg = gen_reg_rtx (SImode);
11730   if (GET_CODE (x) == CONST_INT)
11731     {
11732       v = INTVAL (x);
11733       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11734     }
11735   else
11736     {
11737       emit_insn (gen_movsi (shift_reg, operands[3]));
11738       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11739     }
11740   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11742   operands[0] = replace_equiv_address (operands[0], addr_target);
11743   emit_insn (gen_movqi (operands[0], qi_val));
11745   while (size -= 1)
11746     {
11747       if (GET_CODE (x) == CONST_INT)
11748         qi_val
11749           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11750       else
11751         {
11752           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11753           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11754         }
11755       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11756       emit_insn (gen_movqi (operands[0], qi_val));
11757     }
11759   DONE;
11762 (define_insn "movua"
11763   [(set (match_operand:SI 0 "register_operand" "=z")
11764         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11765                    UNSPEC_MOVUA))]
11766   "TARGET_SH4A_ARCH"
11767   "movua.l      %1,%0"
11768   [(set_attr "type" "movua")])
11770 ;; We shouldn't need this, but cse replaces increments with references
11771 ;; to other regs before flow has a chance to create post_inc
11772 ;; addressing modes, and only postreload's cse_move2add brings the
11773 ;; increments back to a usable form.
11774 (define_peephole2
11775   [(set (match_operand:SI 0 "register_operand" "")
11776         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11777                          (const_int 32) (const_int 0)))
11778    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11779   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11780   [(set (match_operand:SI 0 "register_operand" "")
11781         (sign_extract:SI (mem:SI (post_inc:SI
11782                                   (match_operand:SI 1 "register_operand" "")))
11783                          (const_int 32) (const_int 0)))]
11784   "")
11786 (define_expand "extv"
11787   [(set (match_operand:SI 0 "register_operand" "")
11788         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11789                          (match_operand 2 "const_int_operand" "")
11790                          (match_operand 3 "const_int_operand" "")))]
11791   "TARGET_SH4A_ARCH || TARGET_SH2A"
11793   if (TARGET_SH2A && TARGET_BITOPS
11794       && (satisfies_constraint_Sbw (operands[1])
11795           || satisfies_constraint_Sbv (operands[1]))
11796       && satisfies_constraint_M (operands[2])
11797       && satisfies_constraint_K03 (operands[3]))
11798    {
11799       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11800       if (REGNO (operands[0]) != T_REG)
11801         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11802       DONE;
11803    }
11804   if (TARGET_SH4A_ARCH
11805       && INTVAL (operands[2]) == 32
11806       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11807       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11808     {
11809       rtx src = adjust_address (operands[1], BLKmode, 0);
11810       set_mem_size (src, GEN_INT (4));
11811       emit_insn (gen_movua (operands[0], src));
11812       DONE;
11813     }
11815   FAIL;
11818 (define_expand "extzv"
11819   [(set (match_operand:SI 0 "register_operand" "")
11820         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11821                          (match_operand 2 "const_int_operand" "")
11822                          (match_operand 3 "const_int_operand" "")))]
11823   "TARGET_SH4A_ARCH || TARGET_SH2A"
11825   if (TARGET_SH2A && TARGET_BITOPS
11826       && (satisfies_constraint_Sbw (operands[1])
11827           || satisfies_constraint_Sbv (operands[1]))
11828       && satisfies_constraint_M (operands[2])
11829       && satisfies_constraint_K03 (operands[3]))
11830     {
11831       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11832       if (REGNO (operands[0]) != T_REG)
11833         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11834       DONE;
11835     }
11836   if (TARGET_SH4A_ARCH
11837       && INTVAL (operands[2]) == 32
11838       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11839       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11840     {
11841       rtx src = adjust_address (operands[1], BLKmode, 0);
11842       set_mem_size (src, GEN_INT (4));
11843       emit_insn (gen_movua (operands[0], src));
11844       DONE;
11845     }
11847   FAIL;
11850 ;; SH2A instructions for bitwise operations.
11852 ;; Clear a bit in a memory location.
11853 (define_insn "bclr_m2a"
11854   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11855         (and:QI
11856             (not:QI (ashift:QI (const_int 1)
11857                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11858             (match_dup 0)))]
11859   "TARGET_SH2A && TARGET_BITOPS"
11860   "@
11861         bclr.b\\t%1,%0
11862         bclr.b\\t%1,@(0,%t0)"
11863 [(set_attr "length" "4,4")])
11865 (define_insn "bclrmem_m2a"
11866   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11867         (and:QI (match_dup 0)
11868                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11869   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11870   "@
11871         bclr.b\\t%W1,%0
11872         bclr.b\\t%W1,@(0,%t0)"
11873   [(set_attr "length" "4,4")])
11875 ;; Set a bit in a memory location.
11876 (define_insn "bset_m2a"
11877   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11878         (ior:QI
11879             (ashift:QI (const_int 1)
11880                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11881             (match_dup 0)))]
11882   "TARGET_SH2A && TARGET_BITOPS"
11883   "@
11884         bset.b\\t%1,%0
11885         bset.b\\t%1,@(0,%t0)"
11886   [(set_attr "length" "4,4")])
11888 (define_insn "bsetmem_m2a"
11889   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11890         (ior:QI (match_dup 0)
11891                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11892   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11893   "@
11894         bset.b\\t%V1,%0
11895         bset.b\\t%V1,@(0,%t0)"
11896   [(set_attr "length" "4,4")])
11898 ;;; Transfer the contents of the T bit to a specified bit of memory.
11899 (define_insn "bst_m2a"
11900   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11901         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11902             (and:QI
11903                 (not:QI (ashift:QI (const_int 1)
11904                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11905                 (match_dup 0))
11906             (ior:QI
11907                 (ashift:QI (const_int 1) (match_dup 1))
11908                 (match_dup 0))))]
11909   "TARGET_SH2A && TARGET_BITOPS"
11910   "@
11911         bst.b\\t%1,%0
11912         bst.b\\t%1,@(0,%t0)"
11913   [(set_attr "length" "4")])
11915 ;; Store a specified bit of memory in the T bit.
11916 (define_insn "bld_m2a"
11917   [(set (reg:SI T_REG)
11918         (zero_extract:SI
11919             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11920             (const_int 1)
11921             (match_operand 1 "const_int_operand" "K03,K03")))]
11922   "TARGET_SH2A && TARGET_BITOPS"
11923   "@
11924         bld.b\\t%1,%0
11925         bld.b\\t%1,@(0,%t0)"
11926   [(set_attr "length" "4,4")])
11928 ;; Store a specified bit of memory in the T bit.
11929 (define_insn "bldsign_m2a"
11930   [(set (reg:SI T_REG)
11931         (sign_extract:SI
11932             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11933             (const_int 1)
11934             (match_operand 1 "const_int_operand" "K03,K03")))]
11935   "TARGET_SH2A && TARGET_BITOPS"
11936   "@
11937         bld.b\\t%1,%0
11938         bld.b\\t%1,@(0,%t0)"
11939   [(set_attr "length" "4,4")])
11941 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11942 (define_insn "bld_reg"
11943   [(set (reg:SI T_REG)
11944         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11945                          (const_int 1)
11946                          (match_operand 1 "const_int_operand" "K03")))]
11947   "TARGET_SH2A"
11948   "bld\\t%1,%0")
11950 (define_insn "*bld_regqi"
11951   [(set (reg:SI T_REG)
11952         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11953                          (const_int 1)
11954                          (match_operand 1 "const_int_operand" "K03")))]
11955   "TARGET_SH2A"
11956   "bld\\t%1,%0")
11958 ;; Take logical and of a specified bit of memory with the T bit and
11959 ;; store its result in the T bit.
11960 (define_insn "band_m2a"
11961   [(set (reg:SI T_REG)
11962         (and:SI (reg:SI T_REG)
11963                 (zero_extract:SI
11964                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11965                     (const_int 1)
11966                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11967   "TARGET_SH2A && TARGET_BITOPS"
11968   "@
11969         band.b\\t%1,%0
11970         band.b\\t%1,@(0,%t0)"
11971   [(set_attr "length" "4,4")])
11973 (define_insn "bandreg_m2a"
11974   [(set (match_operand:SI 0 "register_operand" "=r,r")
11975         (and:SI (zero_extract:SI
11976                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11977                     (const_int 1)
11978                     (match_operand 2 "const_int_operand" "K03,K03"))
11979                 (match_operand:SI 3 "register_operand" "r,r")))]
11980   "TARGET_SH2A && TARGET_BITOPS"
11981   "@
11982         band.b\\t%2,%1\;movt\\t%0
11983         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11984   [(set_attr "length" "6,6")])
11986 ;; Take logical or of a specified bit of memory with the T bit and
11987 ;; store its result in the T bit.
11988 (define_insn "bor_m2a"
11989   [(set (reg:SI T_REG)
11990         (ior:SI (reg:SI T_REG)
11991                 (zero_extract:SI
11992                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11993                     (const_int 1)
11994                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11995   "TARGET_SH2A && TARGET_BITOPS"
11996   "@
11997         bor.b\\t%1,%0
11998         bor.b\\t%1,@(0,%t0)"
11999   [(set_attr "length" "4,4")])
12001 (define_insn "borreg_m2a"
12002   [(set (match_operand:SI 0 "register_operand" "=r,r")
12003         (ior:SI (zero_extract:SI
12004                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
12005                     (const_int 1)
12006                     (match_operand 2 "const_int_operand" "K03,K03"))
12007                 (match_operand:SI 3 "register_operand" "=r,r")))]
12008   "TARGET_SH2A && TARGET_BITOPS"
12009   "@
12010         bor.b\\t%2,%1\;movt\\t%0
12011         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
12012   [(set_attr "length" "6,6")])
12014 ;; Take exclusive or of a specified bit of memory with the T bit and
12015 ;; store its result in the T bit.
12016 (define_insn "bxor_m2a"
12017   [(set (reg:SI T_REG)
12018         (xor:SI (reg:SI T_REG)
12019                 (zero_extract:SI
12020                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
12021                     (const_int 1)
12022                     (match_operand 1 "const_int_operand" "K03,K03"))))]
12023   "TARGET_SH2A && TARGET_BITOPS"
12024   "@
12025         bxor.b\\t%1,%0
12026         bxor.b\\t%1,@(0,%t0)"
12027   [(set_attr "length" "4,4")])
12029 (define_insn "bxorreg_m2a"
12030   [(set (match_operand:SI 0 "register_operand" "=r,r")
12031         (xor:SI (zero_extract:SI
12032                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
12033                     (const_int 1)
12034                     (match_operand 2 "const_int_operand" "K03,K03"))
12035                 (match_operand:SI 3 "register_operand" "=r,r")))]
12036   "TARGET_SH2A && TARGET_BITOPS"
12037   "@
12038         bxor.b\\t%2,%1\;movt\\t%0
12039         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
12040   [(set_attr "length" "6,6")])
12043 ;; -------------------------------------------------------------------------
12044 ;; Peepholes
12045 ;; -------------------------------------------------------------------------
12046 ;; This matches cases where the bit in a memory location is set.
12047 (define_peephole2
12048   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
12049         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
12050    (set (match_dup 0)
12051         (ior:SI (match_dup 0)
12052         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
12053    (set (match_dup 1)
12054         (match_operand 3 "arith_reg_operand" "r,r"))]
12055   "TARGET_SH2A && TARGET_BITOPS
12056    && satisfies_constraint_Pso (operands[2])
12057    && REGNO (operands[0]) == REGNO (operands[3])"
12058   [(set (match_dup 1)
12059         (ior:QI (match_dup 1)
12060                 (match_dup 2)))]
12061   "")
12063 ;; This matches cases where the bit in a memory location is cleared.
12064 (define_peephole2
12065   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
12066         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
12067    (set (match_dup 0)
12068         (and:SI (match_dup 0)
12069         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
12070    (set (match_dup 1)
12071         (match_operand 3 "arith_reg_operand" "r,r"))]
12072   "TARGET_SH2A && TARGET_BITOPS
12073    && satisfies_constraint_Psz (operands[2])
12074    && REGNO (operands[0]) == REGNO (operands[3])"
12075   [(set (match_dup 1)
12076         (and:QI (match_dup 1)
12077                 (match_dup 2)))]
12078   "")
12080 ;; This matches cases where a stack pointer increment at the start of the
12081 ;; epilogue combines with a stack slot read loading the return value.
12083 (define_peephole
12084   [(set (match_operand:SI 0 "arith_reg_operand" "")
12085         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
12086    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
12087   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
12088   "mov.l        @%1+,%0")
12090 ;; See the comment on the dt combiner pattern above.
12092 (define_peephole
12093   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
12094         (plus:SI (match_dup 0)
12095                  (const_int -1)))
12096    (set (reg:SI T_REG)
12097         (eq:SI (match_dup 0)
12098                (const_int 0)))]
12099   "TARGET_SH2"
12100   "dt   %0")
12102 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
12103 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
12104 ;; reload when the constant is too large for a reg+offset address.
12106 ;; ??? We would get much better code if this was done in reload.  This would
12107 ;; require modifying find_reloads_address to recognize that if the constant
12108 ;; is out-of-range for an immediate add, then we get better code by reloading
12109 ;; the constant into a register than by reloading the sum into a register,
12110 ;; since the former is one instruction shorter if the address does not need
12111 ;; to be offsettable.  Unfortunately this does not work, because there is
12112 ;; only one register, r0, that can be used as an index register.  This register
12113 ;; is also the function return value register.  So, if we try to force reload
12114 ;; to use double-reg addresses, then we end up with some instructions that
12115 ;; need to use r0 twice.  The only way to fix this is to change the calling
12116 ;; convention so that r0 is not used to return values.
12118 (define_peephole
12119   [(set (match_operand:SI 0 "register_operand" "=r")
12120         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12121    (set (mem:SI (match_dup 0))
12122         (match_operand:SI 2 "general_movsrc_operand" ""))]
12123   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12124   "mov.l        %2,@(%0,%1)")
12126 (define_peephole
12127   [(set (match_operand:SI 0 "register_operand" "=r")
12128         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12129    (set (match_operand:SI 2 "general_movdst_operand" "")
12130         (mem:SI (match_dup 0)))]
12131   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12132   "mov.l        @(%0,%1),%2")
12134 (define_peephole
12135   [(set (match_operand:SI 0 "register_operand" "=r")
12136         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12137    (set (mem:HI (match_dup 0))
12138         (match_operand:HI 2 "general_movsrc_operand" ""))]
12139   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12140   "mov.w        %2,@(%0,%1)")
12142 (define_peephole
12143   [(set (match_operand:SI 0 "register_operand" "=r")
12144         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12145    (set (match_operand:HI 2 "general_movdst_operand" "")
12146         (mem:HI (match_dup 0)))]
12147   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12148   "mov.w        @(%0,%1),%2")
12150 (define_peephole
12151   [(set (match_operand:SI 0 "register_operand" "=r")
12152         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12153    (set (mem:QI (match_dup 0))
12154         (match_operand:QI 2 "general_movsrc_operand" ""))]
12155   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12156   "mov.b        %2,@(%0,%1)")
12158 (define_peephole
12159   [(set (match_operand:SI 0 "register_operand" "=r")
12160         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12161    (set (match_operand:QI 2 "general_movdst_operand" "")
12162         (mem:QI (match_dup 0)))]
12163   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
12164   "mov.b        @(%0,%1),%2")
12166 (define_peephole
12167   [(set (match_operand:SI 0 "register_operand" "=r")
12168         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12169    (set (mem:SF (match_dup 0))
12170         (match_operand:SF 2 "general_movsrc_operand" ""))]
12171   "TARGET_SH1 && REGNO (operands[0]) == 0
12172    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
12173        || (GET_CODE (operands[2]) == SUBREG
12174            && REGNO (SUBREG_REG (operands[2])) < 16))
12175    && reg_unused_after (operands[0], insn)"
12176   "mov.l        %2,@(%0,%1)")
12178 (define_peephole
12179   [(set (match_operand:SI 0 "register_operand" "=r")
12180         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12181    (set (match_operand:SF 2 "general_movdst_operand" "")
12183         (mem:SF (match_dup 0)))]
12184   "TARGET_SH1 && REGNO (operands[0]) == 0
12185    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
12186        || (GET_CODE (operands[2]) == SUBREG
12187            && REGNO (SUBREG_REG (operands[2])) < 16))
12188    && reg_unused_after (operands[0], insn)"
12189   "mov.l        @(%0,%1),%2")
12191 (define_peephole
12192   [(set (match_operand:SI 0 "register_operand" "=r")
12193         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12194    (set (mem:SF (match_dup 0))
12195         (match_operand:SF 2 "general_movsrc_operand" ""))]
12196   "TARGET_SH2E && REGNO (operands[0]) == 0
12197    && ((GET_CODE (operands[2]) == REG
12198         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
12199        || (GET_CODE (operands[2]) == SUBREG
12200            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
12201    && reg_unused_after (operands[0], insn)"
12202   "fmov{.s|}    %2,@(%0,%1)")
12204 (define_peephole
12205   [(set (match_operand:SI 0 "register_operand" "=r")
12206         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
12207    (set (match_operand:SF 2 "general_movdst_operand" "")
12209         (mem:SF (match_dup 0)))]
12210   "TARGET_SH2E && REGNO (operands[0]) == 0
12211    && ((GET_CODE (operands[2]) == REG
12212         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
12213        || (GET_CODE (operands[2]) == SUBREG
12214            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
12215    && reg_unused_after (operands[0], insn)"
12216   "fmov{.s|}    @(%0,%1),%2")
12218 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
12219 (define_insn "sp_switch_1"
12220   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
12221   "TARGET_SH1"
12222   "*
12224   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
12225   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
12226   return \"mov r0,r15\";
12228   [(set_attr "length" "10")])
12230 ;; Switch back to the original stack for interrupt functions with the
12231 ;; sp_switch attribute.  */
12232 (define_insn "sp_switch_2"
12233   [(const_int 2)]
12234   "TARGET_SH1"
12235   "mov.l @r15+,r15\;mov.l @r15+,r0"
12236   [(set_attr "length" "4")])
12238 ;; Integer vector moves
12240 (define_expand "movv8qi"
12241   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
12242         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
12243   "TARGET_SHMEDIA"
12244   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
12246 (define_insn "movv8qi_i"
12247   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
12248         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12249   "TARGET_SHMEDIA
12250    && (register_operand (operands[0], V8QImode)
12251        || sh_register_operand (operands[1], V8QImode))"
12252   "@
12253         add     %1, r63, %0
12254         movi    %1, %0
12255         #
12256         ld%M1.q %m1, %0
12257         st%M0.q %m0, %N1"
12258   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
12259    (set_attr "length" "4,4,16,4,4")])
12261 (define_split
12262   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
12263         (subreg:V8QI (const_int 0) 0))]
12264   "TARGET_SHMEDIA"
12265   [(set (match_dup 0)
12266         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
12267                             (const_int 0) (const_int 0) (const_int 0)
12268                             (const_int 0) (const_int 0)]))])
12270 (define_split
12271   [(set (match_operand 0 "arith_reg_dest" "")
12272         (match_operand 1 "sh_rep_vec" ""))]
12273   "TARGET_SHMEDIA && reload_completed
12274    && GET_MODE (operands[0]) == GET_MODE (operands[1])
12275    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
12276    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
12277    && (XVECEXP (operands[1], 0, 0) != const0_rtx
12278        || XVECEXP (operands[1], 0, 1) != const0_rtx)
12279    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
12280        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
12281   [(set (match_dup 0) (match_dup 1))
12282    (match_dup 2)]
12283   "
12285   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
12286   rtx elt1 = XVECEXP (operands[1], 0, 1);
12288   if (unit_size > 2)
12289     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
12290   else
12291     {
12292       if (unit_size < 2)
12293         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
12294       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
12295     }
12296   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
12297   operands[1] = XVECEXP (operands[1], 0, 0);
12298   if (unit_size < 2)
12299     {
12300       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
12301         operands[1]
12302           = GEN_INT (TARGET_LITTLE_ENDIAN
12303                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
12304                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
12305       else
12306         {
12307           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
12308           operands[1]
12309             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
12310         }
12311     }
12314 (define_split
12315   [(set (match_operand 0 "arith_reg_dest" "")
12316         (match_operand 1 "sh_const_vec" ""))]
12317   "TARGET_SHMEDIA && reload_completed
12318    && GET_MODE (operands[0]) == GET_MODE (operands[1])
12319    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
12320   [(set (match_dup 0) (match_dup 1))]
12321   "
12323   rtx v = operands[1];
12324   enum machine_mode new_mode
12325     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
12327   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
12328   operands[1]
12329     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
12332 (define_expand "movv2hi"
12333   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
12334         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
12335   "TARGET_SHMEDIA"
12336   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
12338 (define_insn "movv2hi_i"
12339   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12340         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12341   "TARGET_SHMEDIA
12342    && (register_operand (operands[0], V2HImode)
12343        || sh_register_operand (operands[1], V2HImode))"
12344   "@
12345         add.l   %1, r63, %0
12346         movi    %1, %0
12347         #
12348         ld%M1.l %m1, %0
12349         st%M0.l %m0, %N1"
12350   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
12351    (set_attr "length" "4,4,16,4,4")
12352    (set (attr "highpart")
12353         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
12354                (const_string "user")]
12355               (const_string "ignore")))])
12357 (define_expand "movv4hi"
12358   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
12359         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
12360   "TARGET_SHMEDIA"
12361   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
12363 (define_insn "movv4hi_i"
12364   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
12365         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12366   "TARGET_SHMEDIA
12367    && (register_operand (operands[0], V4HImode)
12368        || sh_register_operand (operands[1], V4HImode))"
12369   "@
12370         add     %1, r63, %0
12371         movi    %1, %0
12372         #
12373         ld%M1.q %m1, %0
12374         st%M0.q %m0, %N1"
12375   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
12376    (set_attr "length" "4,4,16,4,4")
12377    (set_attr "highpart" "depend")])
12379 (define_expand "movv2si"
12380   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
12381         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
12382   "TARGET_SHMEDIA"
12383   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
12385 (define_insn "movv2si_i"
12386   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
12387         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
12388   "TARGET_SHMEDIA
12389    && (register_operand (operands[0], V2SImode)
12390        || sh_register_operand (operands[1], V2SImode))"
12391   "@
12392         add     %1, r63, %0
12393         #
12394         #
12395         ld%M1.q %m1, %0
12396         st%M0.q %m0, %N1"
12397   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
12398    (set_attr "length" "4,4,16,4,4")
12399    (set_attr "highpart" "depend")])
12401 ;; Multimedia Intrinsics
12403 (define_insn "absv2si2"
12404   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12405         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
12406   "TARGET_SHMEDIA"
12407   "mabs.l       %1, %0"
12408   [(set_attr "type" "mcmp_media")
12409    (set_attr "highpart" "depend")])
12411 (define_insn "absv4hi2"
12412   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12413         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
12414   "TARGET_SHMEDIA"
12415   "mabs.w       %1, %0"
12416   [(set_attr "type" "mcmp_media")
12417    (set_attr "highpart" "depend")])
12419 (define_insn "addv2si3"
12420   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12421         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12422                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12423   "TARGET_SHMEDIA"
12424   "madd.l       %1, %2, %0"
12425   [(set_attr "type" "arith_media")
12426    (set_attr "highpart" "depend")])
12428 (define_insn "addv4hi3"
12429   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12430         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12431                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12432   "TARGET_SHMEDIA"
12433   "madd.w       %1, %2, %0"
12434   [(set_attr "type" "arith_media")
12435    (set_attr "highpart" "depend")])
12437 (define_insn_and_split "addv2hi3"
12438   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12439         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
12440                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
12441   "TARGET_SHMEDIA"
12442   "#"
12443   "TARGET_SHMEDIA"
12444   [(const_int 0)]
12445   "
12447   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12448   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12449   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12450   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12451   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12453   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
12454   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12455   DONE;
12457   [(set_attr "highpart" "must_split")])
12459 (define_insn "ssaddv2si3"
12460   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12461         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
12462                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12463   "TARGET_SHMEDIA"
12464   "madds.l      %1, %2, %0"
12465   [(set_attr "type" "mcmp_media")
12466    (set_attr "highpart" "depend")])
12468 (define_insn "usaddv8qi3"
12469   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12470         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
12471                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12472   "TARGET_SHMEDIA"
12473   "madds.ub     %1, %2, %0"
12474   [(set_attr "type" "mcmp_media")
12475    (set_attr "highpart" "depend")])
12477 (define_insn "ssaddv4hi3"
12478   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12479         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
12480                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12481   "TARGET_SHMEDIA"
12482   "madds.w      %1, %2, %0"
12483   [(set_attr "type" "mcmp_media")
12484    (set_attr "highpart" "depend")])
12486 (define_insn "negcmpeqv8qi"
12487   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12488         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12489                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12490   "TARGET_SHMEDIA"
12491   "mcmpeq.b     %N1, %N2, %0"
12492   [(set_attr "type" "mcmp_media")
12493    (set_attr "highpart" "depend")])
12495 (define_insn "negcmpeqv2si"
12496   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12497         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12498                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12499   "TARGET_SHMEDIA"
12500   "mcmpeq.l     %N1, %N2, %0"
12501   [(set_attr "type" "mcmp_media")
12502    (set_attr "highpart" "depend")])
12504 (define_insn "negcmpeqv4hi"
12505   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12506         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12507                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12508   "TARGET_SHMEDIA"
12509   "mcmpeq.w     %N1, %N2, %0"
12510   [(set_attr "type" "mcmp_media")
12511    (set_attr "highpart" "depend")])
12513 (define_insn "negcmpgtuv8qi"
12514   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12515         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
12516                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
12517   "TARGET_SHMEDIA"
12518   "mcmpgt.ub    %N1, %N2, %0"
12519   [(set_attr "type" "mcmp_media")
12520    (set_attr "highpart" "depend")])
12522 (define_insn "negcmpgtv2si"
12523   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12524         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
12525                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12526   "TARGET_SHMEDIA"
12527   "mcmpgt.l     %N1, %N2, %0"
12528   [(set_attr "type" "mcmp_media")
12529    (set_attr "highpart" "depend")])
12531 (define_insn "negcmpgtv4hi"
12532   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12533         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
12534                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12535   "TARGET_SHMEDIA"
12536   "mcmpgt.w     %N1, %N2, %0"
12537   [(set_attr "type" "mcmp_media")
12538    (set_attr "highpart" "depend")])
12540 (define_insn "mcmv"
12541   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12542         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12543                         (match_operand:DI 2 "arith_reg_operand" "r"))
12544                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
12545                         (not:DI (match_dup 2)))))]
12546   "TARGET_SHMEDIA"
12547   "mcmv %N1, %2, %0"
12548   [(set_attr "type" "arith_media")
12549    (set_attr "highpart" "depend")])
12551 (define_insn "mcnvs_lw"
12552   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12553         (vec_concat:V4HI
12554          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
12555          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
12556   "TARGET_SHMEDIA"
12557   "mcnvs.lw     %N1, %N2, %0"
12558   [(set_attr "type" "mcmp_media")])
12560 (define_insn "mcnvs_wb"
12561   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12562         (vec_concat:V8QI
12563          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12564          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12565   "TARGET_SHMEDIA"
12566   "mcnvs.wb     %N1, %N2, %0"
12567   [(set_attr "type" "mcmp_media")])
12569 (define_insn "mcnvs_wub"
12570   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12571         (vec_concat:V8QI
12572          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
12573          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
12574   "TARGET_SHMEDIA"
12575   "mcnvs.wub    %N1, %N2, %0"
12576   [(set_attr "type" "mcmp_media")])
12578 (define_insn "mextr_rl"
12579   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12580         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12581                              (match_operand:HI 3 "mextr_bit_offset" "i"))
12582                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12583                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12584   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12585   "*
12587   static char templ[21];
12589   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
12590            (int) INTVAL (operands[3]) >> 3);
12591   return templ;
12593   [(set_attr "type" "arith_media")])
12595 (define_insn "*mextr_lr"
12596   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12597         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12598                            (match_operand:HI 3 "mextr_bit_offset" "i"))
12599                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12600                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
12601   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
12602   "*
12604   static char templ[21];
12606   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
12607            (int) INTVAL (operands[4]) >> 3);
12608   return templ;
12610   [(set_attr "type" "arith_media")])
12612 ; mextrN can be modelled with vec_select / vec_concat, but the selection
12613 ; vector then varies depending on endianness.
12614 (define_expand "mextr1"
12615   [(match_operand:DI 0 "arith_reg_dest" "")
12616    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12617    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12618   "TARGET_SHMEDIA"
12619   "
12621   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12622                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
12623   DONE;
12626 (define_expand "mextr2"
12627   [(match_operand:DI 0 "arith_reg_dest" "")
12628    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12629    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12630   "TARGET_SHMEDIA"
12631   "
12633   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12634                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
12635   DONE;
12638 (define_expand "mextr3"
12639   [(match_operand:DI 0 "arith_reg_dest" "")
12640    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12641    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12642   "TARGET_SHMEDIA"
12643   "
12645   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12646                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
12647   DONE;
12650 (define_expand "mextr4"
12651   [(match_operand:DI 0 "arith_reg_dest" "")
12652    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12653    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12654   "TARGET_SHMEDIA"
12655   "
12657   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12658                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
12659   DONE;
12662 (define_expand "mextr5"
12663   [(match_operand:DI 0 "arith_reg_dest" "")
12664    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12665    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12666   "TARGET_SHMEDIA"
12667   "
12669   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12670                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
12671   DONE;
12674 (define_expand "mextr6"
12675   [(match_operand:DI 0 "arith_reg_dest" "")
12676    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12677    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12678   "TARGET_SHMEDIA"
12679   "
12681   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12682                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
12683   DONE;
12686 (define_expand "mextr7"
12687   [(match_operand:DI 0 "arith_reg_dest" "")
12688    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12689    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
12690   "TARGET_SHMEDIA"
12691   "
12693   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
12694                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
12695   DONE;
12698 (define_expand "mmacfx_wl"
12699   [(match_operand:V2SI 0 "arith_reg_dest" "")
12700    (match_operand:V2HI 1 "extend_reg_operand" "")
12701    (match_operand:V2HI 2 "extend_reg_operand" "")
12702    (match_operand:V2SI 3 "arith_reg_operand" "")]
12703   "TARGET_SHMEDIA"
12704   "
12706   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
12707                               operands[1], operands[2]));
12708   DONE;
12711 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
12712 ;; is depend
12713 (define_insn "mmacfx_wl_i"
12714   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12715         (ss_plus:V2SI
12716          (match_operand:V2SI 1 "arith_reg_operand" "0")
12717          (ss_truncate:V2SI
12718           (ashift:V2DI
12719            (sign_extend:V2DI
12720             (mult:V2SI
12721              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12722              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12723            (const_int 1)))))]
12724   "TARGET_SHMEDIA"
12725   "mmacfx.wl    %2, %3, %0"
12726   [(set_attr "type" "mac_media")
12727    (set_attr "highpart" "depend")])
12729 (define_expand "mmacnfx_wl"
12730   [(match_operand:V2SI 0 "arith_reg_dest" "")
12731    (match_operand:V2HI 1 "extend_reg_operand" "")
12732    (match_operand:V2HI 2 "extend_reg_operand" "")
12733    (match_operand:V2SI 3 "arith_reg_operand" "")]
12734   "TARGET_SHMEDIA"
12735   "
12737   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
12738                                operands[1], operands[2]));
12739   DONE;
12742 (define_insn "mmacnfx_wl_i"
12743   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12744         (ss_minus:V2SI
12745          (match_operand:V2SI 1 "arith_reg_operand" "0")
12746          (ss_truncate:V2SI
12747           (ashift:V2DI
12748            (sign_extend:V2DI
12749             (mult:V2SI
12750              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
12751              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
12752            (const_int 1)))))]
12753   "TARGET_SHMEDIA"
12754   "mmacnfx.wl   %2, %3, %0"
12755   [(set_attr "type" "mac_media")
12756    (set_attr "highpart" "depend")])
12758 (define_insn "mulv2si3"
12759   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12760         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12761                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12762   "TARGET_SHMEDIA"
12763   "mmul.l       %1, %2, %0"
12764   [(set_attr "type" "d2mpy_media")
12765    (set_attr "highpart" "depend")])
12767 (define_insn "mulv4hi3"
12768   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12769         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12770                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12771   "TARGET_SHMEDIA"
12772   "mmul.w       %1, %2, %0"
12773   [(set_attr "type" "dmpy_media")
12774    (set_attr "highpart" "depend")])
12776 (define_insn "mmulfx_l"
12777   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12778         (ss_truncate:V2SI
12779          (ashiftrt:V2DI
12780           (mult:V2DI
12781            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12782            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12783           (const_int 31))))]
12784   "TARGET_SHMEDIA"
12785   "mmulfx.l     %1, %2, %0"
12786   [(set_attr "type" "d2mpy_media")
12787    (set_attr "highpart" "depend")])
12789 (define_insn "mmulfx_w"
12790   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12791         (ss_truncate:V4HI
12792          (ashiftrt:V4SI
12793           (mult:V4SI
12794            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12795            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12796           (const_int 15))))]
12797   "TARGET_SHMEDIA"
12798   "mmulfx.w     %1, %2, %0"
12799   [(set_attr "type" "dmpy_media")
12800    (set_attr "highpart" "depend")])
12802 (define_insn "mmulfxrp_w"
12803   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12804         (ss_truncate:V4HI
12805          (ashiftrt:V4SI
12806           (plus:V4SI
12807            (mult:V4SI
12808             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12809             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12810            (const_int 16384))
12811           (const_int 15))))]
12812   "TARGET_SHMEDIA"
12813   "mmulfxrp.w   %1, %2, %0"
12814   [(set_attr "type" "dmpy_media")
12815    (set_attr "highpart" "depend")])
12818 (define_expand "mmulhi_wl"
12819   [(match_operand:V2SI 0 "arith_reg_dest" "")
12820    (match_operand:V4HI 1 "arith_reg_operand" "")
12821    (match_operand:V4HI 2 "arith_reg_operand" "")]
12822   "TARGET_SHMEDIA"
12823   "
12825   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12826              (operands[0], operands[1], operands[2]));
12827   DONE;
12830 (define_expand "mmullo_wl"
12831   [(match_operand:V2SI 0 "arith_reg_dest" "")
12832    (match_operand:V4HI 1 "arith_reg_operand" "")
12833    (match_operand:V4HI 2 "arith_reg_operand" "")]
12834   "TARGET_SHMEDIA"
12835   "
12837   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12838              (operands[0], operands[1], operands[2]));
12839   DONE;
12842 (define_insn "mmul23_wl"
12843   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12844         (vec_select:V2SI
12845          (mult:V4SI
12846           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12847           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12848          (parallel [(const_int 2) (const_int 3)])))]
12849   "TARGET_SHMEDIA"
12850   "* return (TARGET_LITTLE_ENDIAN
12851              ? \"mmulhi.wl      %1, %2, %0\"
12852              : \"mmullo.wl      %1, %2, %0\");"
12853   [(set_attr "type" "dmpy_media")
12854    (set (attr "highpart")
12855         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12856          (const_string "user")))])
12858 (define_insn "mmul01_wl"
12859   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12860         (vec_select:V2SI
12861          (mult:V4SI
12862           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12863           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12864          (parallel [(const_int 0) (const_int 1)])))]
12865   "TARGET_SHMEDIA"
12866   "* return (TARGET_LITTLE_ENDIAN
12867              ? \"mmullo.wl      %1, %2, %0\"
12868              : \"mmulhi.wl      %1, %2, %0\");"
12869   [(set_attr "type" "dmpy_media")
12870    (set (attr "highpart")
12871         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12872          (const_string "user")))])
12875 (define_expand "mmulsum_wq"
12876   [(match_operand:DI 0 "arith_reg_dest" "")
12877    (match_operand:V4HI 1 "arith_reg_operand" "")
12878    (match_operand:V4HI 2 "arith_reg_operand" "")
12879    (match_operand:DI 3 "arith_reg_operand" "")]
12880   "TARGET_SHMEDIA"
12881   "
12883   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12884                                operands[1], operands[2]));
12885   DONE;
12888 (define_insn "mmulsum_wq_i"
12889   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12890         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12891          (plus:DI
12892           (plus:DI
12893            (vec_select:DI
12894             (mult:V4DI
12895              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12896              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12897             (parallel [(const_int 0)]))
12898            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12899                                      (sign_extend:V4DI (match_dup 3)))
12900                           (parallel [(const_int 1)])))
12901           (plus:DI
12902            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12903                                      (sign_extend:V4DI (match_dup 3)))
12904                           (parallel [(const_int 2)]))
12905            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12906                                      (sign_extend:V4DI (match_dup 3)))
12907                           (parallel [(const_int 3)]))))))]
12908   "TARGET_SHMEDIA"
12909   "mmulsum.wq   %2, %3, %0"
12910   [(set_attr "type" "mac_media")])
12912 (define_expand "mperm_w"
12913   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12914    (match_operand:V4HI 1 "arith_reg_operand" "r")
12915    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12916   "TARGET_SHMEDIA"
12917   "
12919   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12920              (operands[0], operands[1], operands[2]));
12921   DONE;
12924 ; This use of vec_select isn't exactly correct according to rtl.texi
12925 ; (because not constant), but it seems a straightforward extension.
12926 (define_insn "mperm_w_little"
12927   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12928         (vec_select:V4HI
12929          (match_operand:V4HI 1 "arith_reg_operand" "r")
12930          (parallel
12931           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12932                             (const_int 2) (const_int 0))
12933            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12934            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12935            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12936   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12937   "mperm.w      %1, %N2, %0"
12938   [(set_attr "type" "arith_media")])
12940 (define_insn "mperm_w_big"
12941   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12942         (vec_select:V4HI
12943          (match_operand:V4HI 1 "arith_reg_operand" "r")
12944          (parallel
12945           [(zero_extract:QI (not:QI (match_operand:QI 2
12946                                      "extend_reg_or_0_operand" "rZ"))
12947                             (const_int 2) (const_int 0))
12948            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12949            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12950            (zero_extract:QI (not:QI (match_dup 2))
12951                             (const_int 2) (const_int 6))])))]
12952   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12953   "mperm.w      %1, %N2, %0"
12954   [(set_attr "type" "arith_media")])
12956 (define_insn "mperm_w0"
12957   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12958         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12959                                           "trunc_hi_operand" "r"))))]
12960   "TARGET_SHMEDIA"
12961   "mperm.w      %1, r63, %0"
12962   [(set_attr "type" "arith_media")
12963    (set_attr "highpart" "ignore")])
12965 (define_expand "msad_ubq"
12966   [(match_operand:DI 0 "arith_reg_dest" "")
12967    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12968    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12969    (match_operand:DI 3 "arith_reg_operand" "")]
12970   "TARGET_SHMEDIA"
12971   "
12973   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12974                              operands[1], operands[2]));
12975   DONE;
12978 (define_insn "msad_ubq_i"
12979   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12980         (plus:DI
12981          (plus:DI
12982           (plus:DI
12983            (plus:DI
12984             (match_operand:DI 1 "arith_reg_operand" "0")
12985             (abs:DI (vec_select:DI
12986                      (minus:V8DI
12987                       (zero_extend:V8DI
12988                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12989                       (zero_extend:V8DI
12990                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12991                      (parallel [(const_int 0)]))))
12992            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12993                                               (zero_extend:V8DI (match_dup 3)))
12994                                   (parallel [(const_int 1)]))))
12995           (plus:DI
12996            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12997                                               (zero_extend:V8DI (match_dup 3)))
12998                                   (parallel [(const_int 2)])))
12999            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13000                                               (zero_extend:V8DI (match_dup 3)))
13001                                   (parallel [(const_int 3)])))))
13002          (plus:DI
13003           (plus:DI
13004            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13005                                               (zero_extend:V8DI (match_dup 3)))
13006                                   (parallel [(const_int 4)])))
13007            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13008                                               (zero_extend:V8DI (match_dup 3)))
13009                                   (parallel [(const_int 5)]))))
13010           (plus:DI
13011            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13012                                               (zero_extend:V8DI (match_dup 3)))
13013                                   (parallel [(const_int 6)])))
13014            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
13015                                               (zero_extend:V8DI (match_dup 3)))
13016                                   (parallel [(const_int 7)])))))))]
13017   "TARGET_SHMEDIA"
13018   "msad.ubq     %N2, %N3, %0"
13019   [(set_attr "type" "mac_media")])
13021 (define_insn "mshalds_l"
13022   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13023         (ss_truncate:V2SI
13024          (ashift:V2DI
13025           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
13026           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
13027                   (const_int 31)))))]
13028   "TARGET_SHMEDIA"
13029   "mshalds.l    %1, %2, %0"
13030   [(set_attr "type" "mcmp_media")
13031    (set_attr "highpart" "depend")])
13033 (define_insn "mshalds_w"
13034   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13035         (ss_truncate:V4HI
13036          (ashift:V4SI
13037           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
13038           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
13039                   (const_int 15)))))]
13040   "TARGET_SHMEDIA"
13041   "mshalds.w    %1, %2, %0"
13042   [(set_attr "type" "mcmp_media")
13043    (set_attr "highpart" "depend")])
13045 (define_insn "ashrv2si3"
13046   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13047         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13048                        (match_operand:DI 2 "arith_reg_operand" "r")))]
13049   "TARGET_SHMEDIA"
13050   "mshard.l     %1, %2, %0"
13051   [(set_attr "type" "arith_media")
13052    (set_attr "highpart" "depend")])
13054 (define_insn "ashrv4hi3"
13055   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13056         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13057                        (match_operand:DI 2 "arith_reg_operand" "r")))]
13058   "TARGET_SHMEDIA"
13059   "mshard.w     %1, %2, %0"
13060   [(set_attr "type" "arith_media")
13061    (set_attr "highpart" "depend")])
13063 (define_insn "mshards_q"
13064   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
13065         (ss_truncate:HI
13066          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
13067                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
13068   "TARGET_SHMEDIA"
13069   "mshards.q    %1, %N2, %0"
13070   [(set_attr "type" "mcmp_media")])
13072 (define_expand "mshfhi_b"
13073   [(match_operand:V8QI 0 "arith_reg_dest" "")
13074    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13075    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
13076   "TARGET_SHMEDIA"
13077   "
13079   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
13080              (operands[0], operands[1], operands[2]));
13081   DONE;
13084 (define_expand "mshflo_b"
13085   [(match_operand:V8QI 0 "arith_reg_dest" "")
13086    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13087    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
13088   "TARGET_SHMEDIA"
13089   "
13091   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
13092              (operands[0], operands[1], operands[2]));
13093   DONE;
13096 (define_insn "mshf4_b"
13097   [(set
13098     (match_operand:V8QI 0 "arith_reg_dest" "=r")
13099     (vec_select:V8QI
13100      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13101                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
13102      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
13103                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
13104   "TARGET_SHMEDIA"
13105   "* return (TARGET_LITTLE_ENDIAN
13106              ? \"mshfhi.b       %N1, %N2, %0\"
13107              : \"mshflo.b       %N1, %N2, %0\");"
13108   [(set_attr "type" "arith_media")
13109    (set (attr "highpart")
13110         (cond [(eq_attr "endian" "big") (const_string "ignore")]
13111          (const_string "user")))])
13113 (define_insn "mshf0_b"
13114   [(set
13115     (match_operand:V8QI 0 "arith_reg_dest" "=r")
13116     (vec_select:V8QI
13117      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13118                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
13119      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
13120                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
13121   "TARGET_SHMEDIA"
13122   "* return (TARGET_LITTLE_ENDIAN
13123              ? \"mshflo.b       %N1, %N2, %0\"
13124              : \"mshfhi.b       %N1, %N2, %0\");"
13125   [(set_attr "type" "arith_media")
13126    (set (attr "highpart")
13127         (cond [(eq_attr "endian" "little") (const_string "ignore")]
13128          (const_string "user")))])
13130 (define_expand "mshfhi_l"
13131   [(match_operand:V2SI 0 "arith_reg_dest" "")
13132    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13133    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
13134   "TARGET_SHMEDIA"
13135   "
13137   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
13138              (operands[0], operands[1], operands[2]));
13139   DONE;
13142 (define_expand "mshflo_l"
13143   [(match_operand:V2SI 0 "arith_reg_dest" "")
13144    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13145    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
13146   "TARGET_SHMEDIA"
13147   "
13149   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
13150              (operands[0], operands[1], operands[2]));
13151   DONE;
13154 (define_insn "mshf4_l"
13155   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13156         (vec_select:V2SI
13157          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13158                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
13159          (parallel [(const_int 1) (const_int 3)])))]
13160   "TARGET_SHMEDIA"
13161   "* return (TARGET_LITTLE_ENDIAN
13162              ? \"mshfhi.l       %N1, %N2, %0\"
13163              : \"mshflo.l       %N1, %N2, %0\");"
13164   [(set_attr "type" "arith_media")
13165    (set (attr "highpart")
13166         (cond [(eq_attr "endian" "big") (const_string "ignore")]
13167          (const_string "user")))])
13169 (define_insn "mshf0_l"
13170   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13171         (vec_select:V2SI
13172          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13173                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
13174          (parallel [(const_int 0) (const_int 2)])))]
13175   "TARGET_SHMEDIA"
13176   "* return (TARGET_LITTLE_ENDIAN
13177              ? \"mshflo.l       %N1, %N2, %0\"
13178              : \"mshfhi.l       %N1, %N2, %0\");"
13179   [(set_attr "type" "arith_media")
13180    (set (attr "highpart")
13181         (cond [(eq_attr "endian" "little") (const_string "ignore")]
13182          (const_string "user")))])
13184 (define_expand "mshfhi_w"
13185   [(match_operand:V4HI 0 "arith_reg_dest" "")
13186    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13187    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
13188   "TARGET_SHMEDIA"
13189   "
13191   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
13192              (operands[0], operands[1], operands[2]));
13193   DONE;
13196 (define_expand "mshflo_w"
13197   [(match_operand:V4HI 0 "arith_reg_dest" "")
13198    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13199    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
13200   "TARGET_SHMEDIA"
13201   "
13203   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
13204              (operands[0], operands[1], operands[2]));
13205   DONE;
13208 (define_insn "mshf4_w"
13209   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13210         (vec_select:V4HI
13211          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13212                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
13213          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
13214   "TARGET_SHMEDIA"
13215   "* return (TARGET_LITTLE_ENDIAN
13216              ? \"mshfhi.w       %N1, %N2, %0\"
13217              : \"mshflo.w       %N1, %N2, %0\");"
13218   [(set_attr "type" "arith_media")
13219    (set (attr "highpart")
13220         (cond [(eq_attr "endian" "big") (const_string "ignore")]
13221          (const_string "user")))])
13223 (define_insn "mshf0_w"
13224   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13225         (vec_select:V4HI
13226          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13227                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
13228          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
13229   "TARGET_SHMEDIA"
13230   "* return (TARGET_LITTLE_ENDIAN
13231              ? \"mshflo.w       %N1, %N2, %0\"
13232              : \"mshfhi.w       %N1, %N2, %0\");"
13233   [(set_attr "type" "arith_media")
13234    (set (attr "highpart")
13235         (cond [(eq_attr "endian" "little") (const_string "ignore")]
13236          (const_string "user")))])
13238 (define_insn "mshflo_w_x"
13239   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13240         (vec_select:V4HI
13241          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
13242                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
13243          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
13244   "TARGET_SHMEDIA"
13245   "mshflo.w     %N1, %N2, %0"
13246   [(set_attr "type" "arith_media")
13247    (set_attr "highpart" "ignore")])
13249 /* These are useful to expand ANDs and as combiner patterns.  */
13250 (define_insn_and_split "mshfhi_l_di"
13251   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
13252         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
13253                              (const_int 32))
13254                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
13255                         (const_int -4294967296))))]
13256   "TARGET_SHMEDIA"
13257   "@
13258         mshfhi.l        %N1, %N2, %0
13259         #"
13260   "TARGET_SHMEDIA && reload_completed
13261    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13262   [(set (match_dup 3) (match_dup 4))
13263    (set (match_dup 5) (match_dup 6))]
13264   "
13266   operands[3] = gen_lowpart (SImode, operands[0]);
13267   operands[4] = gen_highpart (SImode, operands[1]);
13268   operands[5] = gen_highpart (SImode, operands[0]);
13269   operands[6] = gen_highpart (SImode, operands[2]);
13271   [(set_attr "type" "arith_media")])
13273 (define_insn "*mshfhi_l_di_rev"
13274   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13275         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13276                         (const_int -4294967296))
13277                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13278                              (const_int 32))))]
13279   "TARGET_SHMEDIA"
13280   "mshfhi.l     %N2, %N1, %0"
13281   [(set_attr "type" "arith_media")])
13283 (define_split
13284   [(set (match_operand:DI 0 "arith_reg_dest" "")
13285         (ior:DI (zero_extend:DI (match_operand:SI 1
13286                                               "extend_reg_or_0_operand" ""))
13287                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
13288                         (const_int -4294967296))))
13289    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
13290   "TARGET_SHMEDIA"
13291   [(const_int 0)]
13292   "
13294   emit_insn (gen_ashldi3_media (operands[3],
13295                                 simplify_gen_subreg (DImode, operands[1],
13296                                                      SImode, 0),
13297                                 GEN_INT (32)));
13298   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
13299   DONE;
13302 (define_insn "mshflo_l_di"
13303   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13304         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13305                         (const_int 4294967295))
13306                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13307                            (const_int 32))))]
13309   "TARGET_SHMEDIA"
13310   "mshflo.l     %N1, %N2, %0"
13311   [(set_attr "type" "arith_media")
13312    (set_attr "highpart" "ignore")])
13314 (define_insn "*mshflo_l_di_rev"
13315   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13316         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13317                            (const_int 32))
13318                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13319                         (const_int 4294967295))))]
13321   "TARGET_SHMEDIA"
13322   "mshflo.l     %N2, %N1, %0"
13323   [(set_attr "type" "arith_media")
13324    (set_attr "highpart" "ignore")])
13326 ;; Combiner pattern for trampoline initialization.
13327 (define_insn_and_split "*double_shori"
13328   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13329         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
13330                            (const_int 32))
13331                 (match_operand:DI 2 "const_int_operand" "n")))]
13332   "TARGET_SHMEDIA
13333    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
13334   "#"
13335   "rtx_equal_p (operands[0], operands[1])"
13336   [(const_int 0)]
13337   "
13339   HOST_WIDE_INT v = INTVAL (operands[2]);
13341   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
13342   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
13343   DONE;
13345   [(set_attr "highpart" "ignore")])
13348 (define_insn "*mshflo_l_di_x"
13349   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13350         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
13351                                  "rZ"))
13352                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
13353                            (const_int 32))))]
13355   "TARGET_SHMEDIA"
13356   "mshflo.l     %N1, %N2, %0"
13357   [(set_attr "type" "arith_media")
13358    (set_attr "highpart" "ignore")])
13360 (define_insn_and_split "concat_v2sf"
13361   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
13362 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
13363         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
13364                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
13366   "TARGET_SHMEDIA"
13367   "@
13368         mshflo.l        %N1, %N2, %0
13369         #
13370         #"
13371   "TARGET_SHMEDIA && reload_completed
13372    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
13373   [(set (match_dup 3) (match_dup 1))
13374    (set (match_dup 4) (match_dup 2))]
13375   "
13377   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
13378   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
13380   [(set_attr "type" "arith_media")
13381    (set_attr "highpart" "ignore")])
13383 (define_insn "*mshflo_l_di_x_rev"
13384   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13385         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
13386                            (const_int 32))
13387                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
13389   "TARGET_SHMEDIA"
13390   "mshflo.l     %N2, %N1, %0"
13391   [(set_attr "type" "arith_media")
13392    (set_attr "highpart" "ignore")])
13394 (define_insn "ashlv2si3"
13395   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13396         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13397                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13398   "TARGET_SHMEDIA"
13399   "mshlld.l     %1, %2, %0"
13400   [(set_attr "type" "arith_media")
13401    (set_attr "highpart" "depend")])
13403 (define_split
13404   [(set (match_operand 0 "any_register_operand" "")
13405         (match_operator 3 "shift_operator"
13406           [(match_operand 1 "any_register_operand" "")
13407            (match_operand 2 "shift_count_reg_operand" "")]))]
13408   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
13409   [(set (match_dup 0) (match_dup 3))]
13410   "
13412   rtx count = operands[2];
13413   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
13415   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
13416          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
13417          || GET_CODE (count) == TRUNCATE)
13418     count = XEXP (count, 0);
13419   inner_mode = GET_MODE (count);
13420   count = simplify_gen_subreg (outer_mode, count, inner_mode,
13421                                subreg_lowpart_offset (outer_mode, inner_mode));
13422   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
13423                                 operands[1], count);
13426 (define_insn "ashlv4hi3"
13427   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13428         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13429                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13430   "TARGET_SHMEDIA"
13431   "mshlld.w     %1, %2, %0"
13432   [(set_attr "type" "arith_media")
13433    (set_attr "highpart" "depend")])
13435 (define_insn "lshrv2si3"
13436   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13437         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
13438                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13439   "TARGET_SHMEDIA"
13440   "mshlrd.l     %1, %2, %0"
13441   [(set_attr "type" "arith_media")
13442    (set_attr "highpart" "depend")])
13444 (define_insn "lshrv4hi3"
13445   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13446         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
13447                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
13448   "TARGET_SHMEDIA"
13449   "mshlrd.w     %1, %2, %0"
13450   [(set_attr "type" "arith_media")
13451    (set_attr "highpart" "depend")])
13453 (define_insn "subv2si3"
13454   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13455         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13456                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13457   "TARGET_SHMEDIA"
13458   "msub.l       %N1, %2, %0"
13459   [(set_attr "type" "arith_media")
13460    (set_attr "highpart" "depend")])
13462 (define_insn "subv4hi3"
13463   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13464         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13465                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13466   "TARGET_SHMEDIA"
13467   "msub.w       %N1, %2, %0"
13468   [(set_attr "type" "arith_media")
13469    (set_attr "highpart" "depend")])
13471 (define_insn_and_split "subv2hi3"
13472   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
13473         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
13474                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
13475   "TARGET_SHMEDIA"
13476   "#"
13477   "TARGET_SHMEDIA"
13478   [(const_int 0)]
13479   "
13481   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
13482   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
13483   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
13484   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
13485   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
13487   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
13488   emit_insn (gen_truncdisi2 (si_dst, di_dst));
13489   DONE;
13491   [(set_attr "highpart" "must_split")])
13493 (define_insn "sssubv2si3"
13494   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
13495         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
13496                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
13497   "TARGET_SHMEDIA"
13498   "msubs.l      %N1, %2, %0"
13499   [(set_attr "type" "mcmp_media")
13500    (set_attr "highpart" "depend")])
13502 (define_insn "ussubv8qi3"
13503   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13504         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
13505                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
13506   "TARGET_SHMEDIA"
13507   "msubs.ub     %N1, %2, %0"
13508   [(set_attr "type" "mcmp_media")
13509    (set_attr "highpart" "depend")])
13511 (define_insn "sssubv4hi3"
13512   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
13513         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
13514                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
13515   "TARGET_SHMEDIA"
13516   "msubs.w      %N1, %2, %0"
13517   [(set_attr "type" "mcmp_media")
13518    (set_attr "highpart" "depend")])
13520 ;; Floating Point Intrinsics
13522 (define_insn "fcosa_s"
13523   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13524         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13525                    UNSPEC_FCOSA))]
13526   "TARGET_SHMEDIA"
13527   "fcosa.s      %1, %0"
13528   [(set_attr "type" "atrans_media")])
13530 (define_insn "fsina_s"
13531   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13532         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
13533                    UNSPEC_FSINA))]
13534   "TARGET_SHMEDIA"
13535   "fsina.s      %1, %0"
13536   [(set_attr "type" "atrans_media")])
13538 (define_insn "fipr"
13539   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13540         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
13541                                                     "fp_arith_reg_operand" "f")
13542                                                    (match_operand:V4SF 2
13543                                                     "fp_arith_reg_operand" "f"))
13544                                          (parallel [(const_int 0)]))
13545                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13546                                          (parallel [(const_int 1)])))
13547                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13548                                          (parallel [(const_int 2)]))
13549                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
13550                                          (parallel [(const_int 3)])))))]
13551   "TARGET_SHMEDIA"
13552   "fipr.s       %1, %2, %0"
13553   [(set_attr "type" "fparith_media")])
13555 (define_insn "fsrra_s"
13556   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
13557         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
13558                    UNSPEC_FSRRA))]
13559   "TARGET_SHMEDIA"
13560   "fsrra.s      %1, %0"
13561   [(set_attr "type" "atrans_media")])
13563 (define_insn "ftrv"
13564   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
13565         (plus:V4SF
13566          (plus:V4SF
13567           (mult:V4SF
13568            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
13569                             (parallel [(const_int 0) (const_int 5)
13570                                        (const_int 10) (const_int 15)]))
13571            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
13572           (mult:V4SF
13573            (vec_select:V4SF (match_dup 1)
13574                             (parallel [(const_int 4) (const_int 9)
13575                                        (const_int 14) (const_int 3)]))
13576            (vec_select:V4SF (match_dup 2)
13577                             (parallel [(const_int 1) (const_int 2)
13578                                        (const_int 3) (const_int 0)]))))
13579          (plus:V4SF
13580           (mult:V4SF
13581            (vec_select:V4SF (match_dup 1)
13582                             (parallel [(const_int 8) (const_int 13)
13583                                        (const_int 2) (const_int 7)]))
13584            (vec_select:V4SF (match_dup 2)
13585                             (parallel [(const_int 2) (const_int 3)
13586                                        (const_int 0) (const_int 1)])))
13587           (mult:V4SF
13588            (vec_select:V4SF (match_dup 1)
13589                             (parallel [(const_int 12) (const_int 1)
13590                                        (const_int 6) (const_int 11)]))
13591            (vec_select:V4SF (match_dup 2)
13592                             (parallel [(const_int 3) (const_int 0)
13593                                        (const_int 1) (const_int 2)]))))))]
13594   "TARGET_SHMEDIA"
13595   "ftrv.s %1, %2, %0"
13596   [(set_attr "type" "fparith_media")])
13598 (define_insn "ldhi_l"
13599   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13600         (zero_extract:SI
13601          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13602                                   (const_int 3))
13603                           (const_int -3)))
13604          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
13605          (const_int 0)))]
13606   "TARGET_SHMEDIA32"
13607   "ldhi.l       %U1, %0"
13608   [(set_attr "type" "load_media")])
13610 (define_insn "ldhi_q"
13611   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13612         (zero_extract:DI
13613          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
13614                                   (const_int 7))
13615                           (const_int -7)))
13616          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
13617          (const_int 0)))]
13618   "TARGET_SHMEDIA32"
13619   "ldhi.q       %U1, %0"
13620   [(set_attr "type" "load_media")])
13622 (define_insn_and_split "*ldhi_q_comb0"
13623   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13624         (zero_extract:DI
13625          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13626                                             "register_operand" "r")
13627                                            (match_operand:SI 2
13628                                             "ua_offset" "I06"))
13629                                   (const_int 7))
13630                           (const_int -7)))
13631          (plus:SI (and:SI (match_dup 1) (const_int 7))
13632                   (const_int 1))
13633          (const_int 0)))]
13634   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13635   "#"
13636   ""
13637   [(pc)]
13638   "emit_insn (gen_ldhi_q (operands[0],
13639                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13640    DONE;")
13643 (define_insn_and_split "*ldhi_q_comb1"
13644   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13645         (zero_extract:DI
13646          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
13647                                             "register_operand" "r")
13648                                            (match_operand:SI 2
13649                                             "ua_offset" "I06"))
13650                                   (const_int 7))
13651                           (const_int -7)))
13652          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
13653                                                    "ua_offset" "I06"))
13654                           (const_int 7))
13655                   (const_int 1))
13656          (const_int 0)))]
13657   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13658    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13659   "#"
13660   ""
13661   [(pc)]
13662   "emit_insn (gen_ldhi_q (operands[0],
13663                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13664    DONE;")
13667 (define_insn "ldlo_l"
13668   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13669         (zero_extract:SI
13670          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13671                          (const_int -4)))
13672          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
13673          (and:SI (match_dup 1) (const_int 3))))]
13674   "TARGET_SHMEDIA32"
13675   "ldlo.l       %U1, %0"
13676   [(set_attr "type" "load_media")])
13678 (define_insn "ldlo_q"
13679   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13680         (zero_extract:DI
13681          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
13682                          (const_int -8)))
13683          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13684          (and:SI (match_dup 1) (const_int 7))))]
13685   "TARGET_SHMEDIA32"
13686   "ldlo.q       %U1, %0"
13687   [(set_attr "type" "load_media")])
13689 (define_insn_and_split "*ldlo_q_comb0"
13690   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13691         (zero_extract:DI
13692          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13693                                   (match_operand:SI 2 "ua_offset" "I06"))
13694                          (const_int -8)))
13695          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
13696          (and:SI (match_dup 1) (const_int 7))))]
13697   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
13698   "#"
13699   ""
13700   [(pc)]
13701   "emit_insn (gen_ldlo_q (operands[0],
13702                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13703    DONE;")
13705 (define_insn_and_split "*ldlo_q_comb1"
13706   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13707         (zero_extract:DI
13708          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
13709                                   (match_operand:SI 2 "ua_offset" "I06"))
13710                          (const_int -8)))
13711          (minus:SI (const_int 8)
13712                    (and:SI (plus:SI (match_dup 1)
13713                                     (match_operand:SI 3 "ua_offset" "I06"))
13714                            (const_int 7)))
13715          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
13716   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
13717    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
13718   "#"
13719   ""
13720   [(pc)]
13721   "emit_insn (gen_ldlo_q (operands[0],
13722                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
13723    DONE;")
13725 (define_insn "sthi_l"
13726   [(set (zero_extract:SI
13727          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13728                                   (const_int 3))
13729                           (const_int -3)))
13730          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
13731          (const_int 0))
13732         (match_operand:SI 1 "arith_reg_operand" "r"))]
13733   "TARGET_SHMEDIA32"
13734   "sthi.l       %U0, %1"
13735   [(set_attr "type" "ustore_media")])
13737 ;; All unaligned stores are considered to be 'narrow' because they typically
13738 ;; operate on less that a quadword, and when they operate on a full quadword,
13739 ;; the vanilla store high / store low sequence will cause a stall if not
13740 ;; scheduled apart.
13741 (define_insn "sthi_q"
13742   [(set (zero_extract:DI
13743          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
13744                                   (const_int 7))
13745                           (const_int -7)))
13746          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13747          (const_int 0))
13748         (match_operand:DI 1 "arith_reg_operand" "r"))]
13749   "TARGET_SHMEDIA32"
13750   "sthi.q       %U0, %1"
13751   [(set_attr "type" "ustore_media")])
13753 (define_insn_and_split "*sthi_q_comb0"
13754   [(set (zero_extract:DI
13755          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13756                                             "register_operand" "r")
13757                                            (match_operand:SI 1 "ua_offset"
13758                                             "I06"))
13759                                   (const_int 7))
13760                           (const_int -7)))
13761          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13762          (const_int 0))
13763         (match_operand:DI 2 "arith_reg_operand" "r"))]
13764   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13765   "#"
13766   ""
13767   [(pc)]
13768   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13769                           operands[2]));
13770    DONE;")
13772 (define_insn_and_split "*sthi_q_comb1"
13773   [(set (zero_extract:DI
13774          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13775                                             "register_operand" "r")
13776                                            (match_operand:SI 1 "ua_offset"
13777                                             "I06"))
13778                                   (const_int 7))
13779                           (const_int -7)))
13780          (plus:SI (and:SI (plus:SI (match_dup 0)
13781                                    (match_operand:SI 2 "ua_offset" "I06"))
13782                           (const_int 7))
13783                   (const_int 1))
13784          (const_int 0))
13785         (match_operand:DI 3 "arith_reg_operand" "r"))]
13786   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13787    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13788   "#"
13789   ""
13790   [(pc)]
13791   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13792                           operands[3]));
13793    DONE;")
13795 ;; This is highpart user because the address is used as full 64 bit.
13796 (define_insn "stlo_l"
13797   [(set (zero_extract:SI
13798          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13799                          (const_int -4)))
13800          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13801          (and:SI (match_dup 0) (const_int 3)))
13802         (match_operand:SI 1 "arith_reg_operand" "r"))]
13803   "TARGET_SHMEDIA32"
13804   "stlo.l       %U0, %1"
13805   [(set_attr "type" "ustore_media")])
13807 (define_insn "stlo_q"
13808   [(set (zero_extract:DI
13809          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13810                          (const_int -8)))
13811          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13812          (and:SI (match_dup 0) (const_int 7)))
13813         (match_operand:DI 1 "arith_reg_operand" "r"))]
13814   "TARGET_SHMEDIA32"
13815   "stlo.q       %U0, %1"
13816   [(set_attr "type" "ustore_media")])
13818 (define_insn_and_split "*stlo_q_comb0"
13819   [(set (zero_extract:DI
13820          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13821                                   (match_operand:SI 1 "ua_offset" "I06"))
13822                          (const_int -8)))
13823          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13824          (and:SI (match_dup 0) (const_int 7)))
13825         (match_operand:DI 2 "arith_reg_operand" "r"))]
13826   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13827   "#"
13828   ""
13829   [(pc)]
13830   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13831                           operands[2]));
13832    DONE;")
13834 (define_insn_and_split "*stlo_q_comb1"
13835   [(set (zero_extract:DI
13836          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13837                                   (match_operand:SI 1 "ua_offset" "I06"))
13838                          (const_int -8)))
13839          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13840                                                   (match_operand:SI 2
13841                                                    "ua_offset" "I06"))
13842                                          (const_int 7)))
13843          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13844         (match_operand:DI 3 "arith_reg_operand" "r"))]
13845   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13846   "#"
13847   ""
13848   [(pc)]
13849   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13850                           operands[3]));
13851    DONE;")
13853 (define_insn "ldhi_l64"
13854   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13855         (zero_extract:SI
13856          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13857                                   (const_int 3))
13858                           (const_int -3)))
13859          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13860          (const_int 0)))]
13861   "TARGET_SHMEDIA64"
13862   "ldhi.l       %U1, %0"
13863   [(set_attr "type" "load_media")])
13865 (define_insn "ldhi_q64"
13866   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13867         (zero_extract:DI
13868          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13869                                   (const_int 7))
13870                           (const_int -7)))
13871          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13872          (const_int 0)))]
13873   "TARGET_SHMEDIA64"
13874   "ldhi.q       %U1, %0"
13875   [(set_attr "type" "load_media")])
13877 (define_insn "ldlo_l64"
13878   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13879         (zero_extract:SI
13880          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13881                          (const_int -4)))
13882          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13883          (and:DI (match_dup 1) (const_int 3))))]
13884   "TARGET_SHMEDIA64"
13885   "ldlo.l       %U1, %0"
13886   [(set_attr "type" "load_media")])
13888 (define_insn "ldlo_q64"
13889   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13890         (zero_extract:DI
13891          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13892                          (const_int -8)))
13893          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13894          (and:DI (match_dup 1) (const_int 7))))]
13895   "TARGET_SHMEDIA64"
13896   "ldlo.q       %U1, %0"
13897   [(set_attr "type" "load_media")])
13899 (define_insn "sthi_l64"
13900   [(set (zero_extract:SI
13901          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13902                                   (const_int 3))
13903                           (const_int -3)))
13904          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13905          (const_int 0))
13906         (match_operand:SI 1 "arith_reg_operand" "r"))]
13907   "TARGET_SHMEDIA64"
13908   "sthi.l       %U0, %1"
13909   [(set_attr "type" "ustore_media")])
13911 (define_insn "sthi_q64"
13912   [(set (zero_extract:DI
13913          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13914                                   (const_int 7))
13915                           (const_int -7)))
13916          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13917          (const_int 0))
13918         (match_operand:DI 1 "arith_reg_operand" "r"))]
13919   "TARGET_SHMEDIA64"
13920   "sthi.q       %U0, %1"
13921   [(set_attr "type" "ustore_media")])
13923 (define_insn "stlo_l64"
13924   [(set (zero_extract:SI
13925          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13926                          (const_int -4)))
13927          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13928          (and:DI (match_dup 0) (const_int 3)))
13929         (match_operand:SI 1 "arith_reg_operand" "r"))]
13930   "TARGET_SHMEDIA64"
13931   "stlo.l       %U0, %1"
13932   [(set_attr "type" "ustore_media")])
13934 (define_insn "stlo_q64"
13935   [(set (zero_extract:DI
13936          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13937                          (const_int -8)))
13938          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13939          (and:DI (match_dup 0) (const_int 7)))
13940         (match_operand:DI 1 "arith_reg_operand" "r"))]
13941   "TARGET_SHMEDIA64"
13942   "stlo.q       %U0, %1"
13943   [(set_attr "type" "ustore_media")])
13945 (define_insn "nsb"
13946   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13947         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13948                    UNSPEC_NSB))]
13949   "TARGET_SHMEDIA"
13950   "nsb  %1, %0"
13951   [(set_attr "type" "arith_media")])
13953 (define_insn "nsbsi"
13954   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13955         (zero_extend:SI
13956          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13957                     UNSPEC_NSB)))]
13958   "TARGET_SHMEDIA"
13959   "nsb  %1, %0"
13960   [(set_attr "type" "arith_media")])
13962 (define_insn "nsbdi"
13963   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13964         (zero_extend:DI
13965          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13966                     UNSPEC_NSB)))]
13967   "TARGET_SHMEDIA"
13968   "nsb  %1, %0"
13969   [(set_attr "type" "arith_media")])
13971 (define_expand "ffsdi2"
13972   [(set (match_operand:DI 0 "arith_reg_dest" "")
13973         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13974   "TARGET_SHMEDIA"
13975   "
13977   rtx scratch = gen_reg_rtx (DImode);
13978   rtx last;
13980   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13981   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13982   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13983   emit_insn (gen_nsbdi (scratch, scratch));
13984   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13985   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13986   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13987   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13989   DONE;
13992 (define_expand "ffssi2"
13993   [(set (match_operand:SI 0 "arith_reg_dest" "")
13994         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13995   "TARGET_SHMEDIA"
13996   "
13998   rtx scratch = gen_reg_rtx (SImode);
13999   rtx discratch = gen_reg_rtx (DImode);
14000   rtx last;
14002   emit_insn (gen_adddi3 (discratch,
14003                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
14004                          constm1_rtx));
14005   emit_insn (gen_andcdi3 (discratch,
14006                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
14007                           discratch));
14008   emit_insn (gen_nsbsi (scratch, discratch));
14009   last = emit_insn (gen_subsi3 (operands[0],
14010                                 force_reg (SImode, GEN_INT (63)), scratch));
14011   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
14013   DONE;
14016 (define_insn "byterev"
14017   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
14018         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
14019                          (parallel [(const_int 7) (const_int 6) (const_int 5)
14020                                     (const_int 4) (const_int 3) (const_int 2)
14021                                     (const_int 1) (const_int 0)])))]
14022   "TARGET_SHMEDIA"
14023   "byterev      %1, %0"
14024   [(set_attr "type" "arith_media")])
14026 (define_insn "*prefetch_media"
14027   [(prefetch (match_operand:QI 0 "address_operand" "p")
14028              (match_operand:SI 1 "const_int_operand" "n")
14029              (match_operand:SI 2 "const_int_operand" "n"))]
14030   "TARGET_SHMEDIA"
14031   "*
14033   operands[0] = gen_rtx_MEM (QImode, operands[0]);
14034   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
14035   return \"\";
14037   [(set_attr "type" "other")])
14039 (define_insn "*prefetch_i4"
14040   [(prefetch (match_operand:SI 0 "register_operand" "r")
14041              (match_operand:SI 1 "const_int_operand" "n")
14042              (match_operand:SI 2 "const_int_operand" "n"))]
14043   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
14044   "*
14046   return \"pref @%0\";
14048   [(set_attr "type" "other")])
14050 ;; In user mode, the "pref" instruction will raise a RADDERR exception
14051 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
14052 ;; implementation of __builtin_prefetch for VxWorks RTPs.
14053 (define_expand "prefetch"
14054   [(prefetch (match_operand 0 "address_operand" "p")
14055              (match_operand:SI 1 "const_int_operand" "n")
14056              (match_operand:SI 2 "const_int_operand" "n"))]
14057   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
14058    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
14059   "
14061   if (GET_MODE (operands[0]) != Pmode
14062       || GET_CODE (operands[1]) != CONST_INT
14063       || GET_CODE (operands[2]) != CONST_INT)
14064     FAIL;
14065   if (! TARGET_SHMEDIA)
14066     operands[0] = force_reg (Pmode, operands[0]);
14069 (define_insn "prefetch_m2a"
14070   [(prefetch (match_operand:SI 0 "register_operand" "r")
14071              (match_operand:SI 1 "const_int_operand" "n")
14072              (match_operand:SI 2 "const_int_operand" "n"))]
14073   "TARGET_SH2A"
14074   "pref\\t@%0"
14075   [(set_attr "type" "other")])
14077 (define_insn "alloco_i"
14078   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
14079         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
14080   "TARGET_SHMEDIA32"
14081   "*
14083   rtx xops[2];
14085   if (GET_CODE (operands[0]) == PLUS)
14086     {
14087       xops[0] = XEXP (operands[0], 0);
14088       xops[1] = XEXP (operands[0], 1);
14089     }
14090   else
14091     {
14092       xops[0] = operands[0];
14093       xops[1] = const0_rtx;
14094     }
14095   output_asm_insn (\"alloco   %0, %1\", xops);
14096   return \"\";
14098   [(set_attr "type" "other")])
14100 (define_split
14101   [(set (match_operand 0 "any_register_operand" "")
14102         (match_operand 1 "" ""))]
14103   "TARGET_SHMEDIA && reload_completed"
14104   [(set (match_dup 0) (match_dup 1))]
14105   "
14107   int n_changes = 0;
14109   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
14110   if (!n_changes)
14111     FAIL;
14114 ; Stack Protector Patterns
14116 (define_expand "stack_protect_set"
14117   [(set (match_operand 0 "memory_operand" "")
14118         (match_operand 1 "memory_operand" ""))]
14119   ""
14121   if (TARGET_SHMEDIA)
14122     {
14123       if (TARGET_SHMEDIA64)
14124         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
14125       else
14126         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
14127     }
14128   else
14129     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
14131   DONE;
14134 (define_insn "stack_protect_set_si"
14135   [(set (match_operand:SI 0 "memory_operand" "=m")
14136         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14137    (set (match_scratch:SI 2 "=&r") (const_int 0))]
14138   "!TARGET_SHMEDIA"
14139   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
14140   [(set_attr "type" "other")
14141    (set_attr "length" "6")])
14143 (define_insn "stack_protect_set_si_media"
14144   [(set (match_operand:SI 0 "memory_operand" "=m")
14145         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14146    (set (match_scratch:SI 2 "=&r") (const_int 0))]
14147   "TARGET_SHMEDIA"
14148   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
14149   [(set_attr "type" "other")
14150    (set_attr "length" "12")])
14152 (define_insn "stack_protect_set_di_media"
14153   [(set (match_operand:DI 0 "memory_operand" "=m")
14154         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
14155    (set (match_scratch:DI 2 "=&r") (const_int 0))]
14156   "TARGET_SHMEDIA64"
14157   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
14158   [(set_attr "type" "other")
14159    (set_attr "length" "12")])
14161 (define_expand "stack_protect_test"
14162   [(match_operand 0 "memory_operand" "")
14163    (match_operand 1 "memory_operand" "")
14164    (match_operand 2 "" "")]
14165   ""
14167   if (TARGET_SHMEDIA)
14168     {
14169       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
14171       if (TARGET_SHMEDIA64)
14172         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
14173                                                     operands[1]));
14174       else
14175         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
14176                                                     operands[1]));
14178       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
14179     }
14180   else
14181     {
14182       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
14183       emit_jump_insn (gen_branch_true (operands[2]));
14184     }
14186   DONE;
14189 (define_insn "stack_protect_test_si"
14190   [(set (reg:SI T_REG)
14191         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
14192                     (match_operand:SI 1 "memory_operand" "m")]
14193                    UNSPEC_SP_TEST))
14194   (set (match_scratch:SI 2 "=&r") (const_int 0))
14195   (set (match_scratch:SI 3 "=&r") (const_int 0))]
14196   "!TARGET_SHMEDIA"
14197   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
14198   [(set_attr "type" "other")
14199    (set_attr "length" "10")])
14201 (define_insn "stack_protect_test_si_media"
14202   [(set (match_operand:SI 0 "register_operand" "=&r")
14203         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
14204                     (match_operand:SI 2 "memory_operand" "m")]
14205                    UNSPEC_SP_TEST))
14206   (set (match_scratch:SI 3 "=&r") (const_int 0))]
14207   "TARGET_SHMEDIA"
14208   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
14209   [(set_attr "type" "other")
14210    (set_attr "length" "16")])
14212 (define_insn "stack_protect_test_di_media"
14213   [(set (match_operand:DI 0 "register_operand" "=&r")
14214         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
14215                     (match_operand:DI 2 "memory_operand" "m")]
14216                    UNSPEC_SP_TEST))
14217   (set (match_scratch:DI 3 "=&r") (const_int 0))]
14218   "TARGET_SHMEDIA64"
14219   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
14220   [(set_attr "type" "other")
14221    (set_attr "length" "16")])