* config/sh/sh.md (*movqi_pop): New insn pattern.
[official-gcc.git] / gcc / config / sh / sh.md
blobd8d6ca7fbc0e4c516c9185f35d6790b1ce4a0f0b
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
6 ;;  Improved by Jim Wilson (wilson@cygnus.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
50 ;; Special formats used for outputting SH instructions:
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
60 ;; Special predicates:
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
82   (FPSCR_REG    151)
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
116   (XD0_REG      136)
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_TLSGD         20)
139   (UNSPEC_TLSLDM        21)
140   (UNSPEC_TLSIE         22)
141   (UNSPEC_DTPOFF        23)
142   (UNSPEC_GOTTPOFF      24)
143   (UNSPEC_TPOFF         25)
144   (UNSPEC_RA            26)
145   (UNSPEC_DIV_INV_M0    30)
146   (UNSPEC_DIV_INV_M1    31)
147   (UNSPEC_DIV_INV_M2    32)
148   (UNSPEC_DIV_INV_M3    33)
149   (UNSPEC_DIV_INV20     34)
150   (UNSPEC_DIV_INV_TABLE 37)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
153   (UNSPEC_SP_SET        40)
154   (UNSPEC_SP_TEST       41)
155   (UNSPEC_MOVUA         42)
157   ;; (unspec [VAL SHIFT] UNSPEC_EXTRACT_S16) computes (short) (VAL >> SHIFT).
158   ;; UNSPEC_EXTRACT_U16 is the unsigned equivalent.
159   (UNSPEC_EXTRACT_S16   43)
160   (UNSPEC_EXTRACT_U16   44)
162   ;; (unspec [TARGET ANCHOR] UNSPEC_SYMOFF) == TARGET - ANCHOR.
163   (UNSPEC_SYMOFF        45)
165   ;; (unspec [OFFSET ANCHOR] UNSPEC_PCREL_SYMOFF) == OFFSET - (ANCHOR - .).
166   (UNSPEC_PCREL_SYMOFF  46)
168   ;; These are used with unspec_volatile.
169   (UNSPECV_BLOCKAGE     0)
170   (UNSPECV_ALIGN        1)
171   (UNSPECV_CONST2       2)
172   (UNSPECV_CONST4       4)
173   (UNSPECV_CONST8       6)
174   (UNSPECV_WINDOW_END   10)
175   (UNSPECV_CONST_END    11)
176   (UNSPECV_EH_RETURN    12)
179 ;; -------------------------------------------------------------------------
180 ;; Attributes
181 ;; -------------------------------------------------------------------------
183 ;; Target CPU.
185 (define_attr "cpu"
186  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
187   (const (symbol_ref "sh_cpu_attr")))
189 (define_attr "endian" "big,little"
190  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
191                       (const_string "little") (const_string "big"))))
193 ;; Indicate if the default fpu mode is single precision.
194 (define_attr "fpu_single" "yes,no"
195   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
196                          (const_string "yes") (const_string "no"))))
198 (define_attr "fmovd" "yes,no"
199   (const (if_then_else (symbol_ref "TARGET_FMOVD")
200                        (const_string "yes") (const_string "no"))))
201 ;; pipeline model
202 (define_attr "pipe_model" "sh1,sh4,sh5media"
203   (const
204    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
205           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
206          (const_string "sh1"))))
208 ;; cbranch      conditional branch instructions
209 ;; jump         unconditional jumps
210 ;; arith        ordinary arithmetic
211 ;; arith3       a compound insn that behaves similarly to a sequence of
212 ;;              three insns of type arith
213 ;; arith3b      like above, but might end with a redirected branch
214 ;; load         from memory
215 ;; load_si      Likewise, SImode variant for general register.
216 ;; fload        Likewise, but load to fp register.
217 ;; store        to memory
218 ;; fstore       floating point register to memory
219 ;; move         general purpose register to register
220 ;; movi8        8-bit immediate to general purpose register
221 ;; mt_group     other sh4 mt instructions
222 ;; fmove        register to register, floating point
223 ;; smpy         word precision integer multiply
224 ;; dmpy         longword or doublelongword precision integer multiply
225 ;; return       rts
226 ;; pload        load of pr reg, which can't be put into delay slot of rts
227 ;; prset        copy register to pr reg, ditto
228 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
229 ;; prget        copy pr to register, ditto
230 ;; pcload       pc relative load of constant value
231 ;; pcfload      Likewise, but load to fp register.
232 ;; pcload_si    Likewise, SImode variant for general register.
233 ;; rte          return from exception
234 ;; sfunc        special function call with known used registers
235 ;; call         function call
236 ;; fp           floating point
237 ;; fpscr_toggle toggle a bit in the fpscr
238 ;; fdiv         floating point divide (or square root)
239 ;; gp_fpul      move from general purpose register to fpul
240 ;; fpul_gp      move from fpul to general purpose register
241 ;; mac_gp       move from mac[lh] to general purpose register
242 ;; gp_mac       move from general purpose register to mac[lh]
243 ;; mac_mem      move from mac[lh] to memory
244 ;; mem_mac      move from memory to mac[lh]
245 ;; dfp_arith,dfp_mul, fp_cmp,dfp_cmp,dfp_conv
246 ;; ftrc_s       fix_truncsfsi2_i4
247 ;; dfdiv        double precision floating point divide (or square root)
248 ;; cwb          ic_invalidate_line_i
249 ;; movua        SH4a unaligned load
250 ;; fsrra        square root reciprocal approximate
251 ;; fsca         sine and cosine approximate
252 ;; tls_load     load TLS related address
253 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
254 ;; cbranch_media SHmedia conditional branch instructions
255 ;; cmp_media    SHmedia compare instructions
256 ;; dfdiv_media  SHmedia double precision divide and square root
257 ;; dfmul_media  SHmedia double precision multiply instruction
258 ;; dfparith_media SHmedia double precision floating point arithmetic
259 ;; dfpconv_media SHmedia double precision floating point conversions
260 ;; dmpy_media   SHmedia longword multiply
261 ;; fcmp_media   SHmedia floating point compare instructions
262 ;; fdiv_media   SHmedia single precision divide and square root
263 ;; fload_media  SHmedia floating point register load instructions
264 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
265 ;; fparith_media SHmedia single precision floating point arithmetic
266 ;; fpconv_media SHmedia single precision floating point conversions
267 ;; fstore_media SHmedia floating point register store instructions
268 ;; gettr_media  SHmedia gettr instruction
269 ;; invalidate_line_media SHmedia invalidate_line sequence
270 ;; jump_media   SHmedia unconditional branch instructions
271 ;; load_media   SHmedia general register load instructions
272 ;; pt_media     SHmedia pt instruction (expanded by assembler)
273 ;; ptabs_media  SHmedia ptabs instruction
274 ;; store_media  SHmedia general register store instructions
275 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
276 ;; mac_media    SHmedia mac-style fixed point operations
277 ;; d2mpy_media  SHmedia: two 32-bit integer multiplies
278 ;; atrans_media SHmedia approximate transcendental functions
279 ;; ustore_media SHmedia unaligned stores
280 ;; nil          no-op move, will be deleted.
282 (define_attr "type"
283  "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"
284   (const_string "other"))
286 ;; We define a new attribute namely "insn_class".We use
287 ;; this for the DFA based pipeline description.
289 ;; mt_group      SH4 "mt" group instructions.
291 ;; ex_group      SH4 "ex" group instructions.
293 ;; ls_group      SH4 "ls" group instructions.
296 (define_attr "insn_class"
297   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
298   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
299          (eq_attr "type" "movi8,arith,dyn_shift") (const_string "ex_group")
300          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,fstore,gp_fpul,fpul_gp") (const_string "ls_group")
301          (eq_attr "type" "cbranch,jump") (const_string "br_group")
302          (eq_attr "type" "fp,fp_cmp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
303            (const_string "fe_group")
304          (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")]
305         (const_string "none")))
306 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
307 ;; so these do not belong in an insn group, although they are modeled
308 ;; with their own define_insn_reservations.
310 ;; Indicate what precision must be selected in fpscr for this insn, if any.
312 (define_attr "fp_mode" "single,double,none" (const_string "none"))
314 ;; Indicate if the fpu mode is set by this instruction
315 ;; "unknown" must have the value as "none" in fp_mode, and means
316 ;; that the instruction/abi has left the processor in an unknown
317 ;; state.
318 ;; "none" means that nothing has changed and no mode is set.
319 ;; This attribute is only used for the Renesas ABI.
320 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
322 ; If a conditional branch destination is within -252..258 bytes away
323 ; from the instruction it can be 2 bytes long.  Something in the
324 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
325 ; branches are initially assumed to be 16 bytes long.
326 ; In machine_dependent_reorg, we split all branches that are longer than
327 ; 2 bytes.
329 ;; The maximum range used for SImode constant pool entries is 1018.  A final
330 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
331 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
332 ;; instruction around the pool table, 2 bytes of alignment before the table,
333 ;; and 30 bytes of alignment after the table.  That gives a maximum total
334 ;; pool size of 1058 bytes.
335 ;; Worst case code/pool content size ratio is 1:2 (using asms).
336 ;; Thus, in the worst case, there is one instruction in front of a maximum
337 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
338 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
339 ;; If we have a forward branch, the initial table will be put after the
340 ;; unconditional branch.
342 ;; ??? We could do much better by keeping track of the actual pcloads within
343 ;; the branch range and in the pcload range in front of the branch range.
345 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
346 ;; inside an le.
347 (define_attr "short_cbranch_p" "no,yes"
348   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
349          (const_string "no")
350          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
351          (const_string "yes")
352          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
353          (const_string "no")
354          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
355          (const_string "yes")
356          ] (const_string "no")))
358 (define_attr "med_branch_p" "no,yes"
359   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
360               (const_int 1988))
361          (const_string "yes")
362          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
363          (const_string "no")
364          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
365               (const_int 8186))
366          (const_string "yes")
367          ] (const_string "no")))
369 (define_attr "med_cbranch_p" "no,yes"
370   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
371               (const_int 1986))
372          (const_string "yes")
373          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
374          (const_string "no")
375          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
376                (const_int 8184))
377          (const_string "yes")
378          ] (const_string "no")))
380 (define_attr "braf_branch_p" "no,yes"
381   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
382          (const_string "no")
383          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
384               (const_int 20660))
385          (const_string "yes")
386          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
387          (const_string "no")
388          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
389               (const_int 65530))
390          (const_string "yes")
391          ] (const_string "no")))
393 (define_attr "braf_cbranch_p" "no,yes"
394   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
395          (const_string "no")
396          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
397               (const_int 20658))
398          (const_string "yes")
399          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
400          (const_string "no")
401          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
402               (const_int 65528))
403          (const_string "yes")
404          ] (const_string "no")))
406 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
407 ; For wider ranges, we need a combination of a code and a data part.
408 ; If we can get a scratch register for a long range jump, the code
409 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
410 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
411 ; long; otherwise, it must be 6 bytes long.
413 ; All other instructions are two bytes long by default.
415 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
416 ;; but getattrtab doesn't understand this.
417 (define_attr "length" ""
418   (cond [(eq_attr "type" "cbranch")
419          (cond [(eq_attr "short_cbranch_p" "yes")
420                 (const_int 2)
421                 (eq_attr "med_cbranch_p" "yes")
422                 (const_int 6)
423                 (eq_attr "braf_cbranch_p" "yes")
424                 (const_int 12)
425 ;; ??? using pc is not computed transitively.
426                 (ne (match_dup 0) (match_dup 0))
427                 (const_int 14)
428                 (ne (symbol_ref ("flag_pic")) (const_int 0))
429                 (const_int 24)
430                 ] (const_int 16))
431          (eq_attr "type" "jump")
432          (cond [(eq_attr "med_branch_p" "yes")
433                 (const_int 2)
434                 (and (ne (symbol_ref "prev_nonnote_insn (insn)")
435                          (const_int 0))
436                      (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
437                               (symbol_ref "INSN"))
438                           (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
439                               (symbol_ref "code_for_indirect_jump_scratch"))))
440                 (cond [(eq_attr "braf_branch_p" "yes")
441                        (const_int 6)
442                        (eq (symbol_ref "flag_pic") (const_int 0))
443                        (const_int 10)
444                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
445                        (const_int 10)] (const_int 18))
446                 (eq_attr "braf_branch_p" "yes")
447                 (const_int 10)
448 ;; ??? using pc is not computed transitively.
449                 (ne (match_dup 0) (match_dup 0))
450                 (const_int 12)
451                 (ne (symbol_ref ("flag_pic")) (const_int 0))
452                 (const_int 22)
453                 ] (const_int 14))
454          (eq_attr "type" "pt_media")
455          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
456                        (const_int 20) (const_int 12))
457          (and (eq_attr "type" "jump_media")
458               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
459          (const_int 8)
460          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
461                          (const_int 4)
462                          (const_int 2))))
464 ;; DFA descriptions for the pipelines
466 (include "sh1.md")
467 (include "shmedia.md")
468 (include "sh4.md")
470 (include "predicates.md")
471 (include "constraints.md")
473 ;; Definitions for filling delay slots
475 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
477 (define_attr "banked" "yes,no" 
478         (cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
479                    (const_int 1))
480                (const_string "yes")]
481               (const_string "no")))
483 ;; ??? This should be (nil) instead of (const_int 0)
484 (define_attr "hit_stack" "yes,no"
485         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
486                    (const_int 0))
487                (const_string "no")]
488               (const_string "yes")))
490 (define_attr "interrupt_function" "no,yes"
491   (const (symbol_ref "current_function_interrupt")))
493 (define_attr "in_delay_slot" "yes,no"
494   (cond [(eq_attr "type" "cbranch") (const_string "no")
495          (eq_attr "type" "pcload,pcload_si") (const_string "no")
496          (eq_attr "needs_delay_slot" "yes") (const_string "no")
497          (eq_attr "length" "2") (const_string "yes")
498          ] (const_string "no")))
500 (define_attr "cond_delay_slot" "yes,no"
501   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
502          ] (const_string "no")))
504 (define_attr "is_sfunc" ""
505   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
507 (define_attr "is_mac_media" ""
508   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
510 (define_attr "branch_zero" "yes,no"
511   (cond [(eq_attr "type" "!cbranch") (const_string "no")
512          (ne (symbol_ref "(next_active_insn (insn)\
513                            == (prev_active_insn\
514                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
515                           && get_attr_length (next_active_insn (insn)) == 2")
516              (const_int 0))
517          (const_string "yes")]
518         (const_string "no")))
520 ;; SH4 Double-precision computation with double-precision result -
521 ;; the two halves are ready at different times.
522 (define_attr "dfp_comp" "yes,no"
523   (cond [(eq_attr "type" "dfp_arith,dfp_mul,dfp_conv,dfdiv") (const_string "yes")]
524         (const_string "no")))
526 ;; Insns for which the latency of a preceding fp insn is decreased by one.
527 (define_attr "late_fp_use" "yes,no" (const_string "no"))
528 ;; And feeding insns for which this relevant.
529 (define_attr "any_fp_comp" "yes,no"
530   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_mul,dfp_conv,dfdiv")
531          (const_string "yes")]
532         (const_string "no")))
534 (define_attr "any_int_load" "yes,no"
535   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
536          (const_string "yes")]
537         (const_string "no")))
539 (define_attr "highpart" "user, ignore, extend, depend, must_split"
540   (const_string "user"))
542 (define_delay
543   (eq_attr "needs_delay_slot" "yes")
544   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
546 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
547 ;; and thus we can't put a pop instruction in its delay slot.
548 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
549 ;; instruction can go in the delay slot.
551 ;; Since a normal return (rts) implicitly uses the PR register,
552 ;; we can't allow PR register loads in an rts delay slot.
554 (define_delay
555   (eq_attr "type" "return")
556   [(and (eq_attr "in_delay_slot" "yes")
557         (ior (and (eq_attr "interrupt_function" "no")
558                   (eq_attr "type" "!pload,prset"))
559              (and (eq_attr "interrupt_function" "yes")
560                   (ior
561                    (eq (symbol_ref "TARGET_SH3") (const_int 0))
562                    (eq_attr "hit_stack" "no")
563                    (eq_attr "banked" "no"))))) (nil) (nil)])
565 ;; Since a call implicitly uses the PR register, we can't allow
566 ;; a PR register store in a jsr delay slot.
568 (define_delay
569   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
570   [(and (eq_attr "in_delay_slot" "yes")
571         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
573 ;; Say that we have annulled true branches, since this gives smaller and
574 ;; faster code when branches are predicted as not taken.
576 ;; ??? The non-annulled condition should really be "in_delay_slot",
577 ;; but insns that can be filled in non-annulled get priority over insns
578 ;; that can only be filled in anulled.
580 (define_delay
581   (and (eq_attr "type" "cbranch")
582        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
583   ;; SH2e has a hardware bug that pretty much prohibits the use of
584   ;; annuled delay slots.
585   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
586                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
588 ;; -------------------------------------------------------------------------
589 ;; SImode signed integer comparisons
590 ;; -------------------------------------------------------------------------
592 (define_insn ""
593   [(set (reg:SI T_REG)
594         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
595                        (match_operand:SI 1 "logical_operand" "K08,r"))
596                (const_int 0)))]
597   "TARGET_SH1"
598   "tst  %1,%0"
599   [(set_attr "type" "mt_group")])
601 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
602 ;; That would still allow reload to create cmpi instructions, but would
603 ;; perhaps allow forcing the constant into a register when that is better.
604 ;; Probably should use r0 for mem/imm compares, but force constant into a
605 ;; register for pseudo/imm compares.
607 (define_insn "cmpeqsi_t"
608   [(set (reg:SI T_REG)
609         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
610                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
611   "TARGET_SH1"
612   "@
613         tst     %0,%0
614         cmp/eq  %1,%0
615         cmp/eq  %1,%0"
616    [(set_attr "type" "mt_group")])
618 (define_insn "cmpgtsi_t"
619   [(set (reg:SI T_REG)
620         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
621                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
622   "TARGET_SH1"
623   "@
624         cmp/gt  %1,%0
625         cmp/pl  %0"
626    [(set_attr "type" "mt_group")])
628 (define_insn "cmpgesi_t"
629   [(set (reg:SI T_REG)
630         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
631                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
632   "TARGET_SH1"
633   "@
634         cmp/ge  %1,%0
635         cmp/pz  %0"
636    [(set_attr "type" "mt_group")])
638 ;; -------------------------------------------------------------------------
639 ;; SImode compare and branch
640 ;; -------------------------------------------------------------------------
642 (define_expand "cbranchsi4"
643   [(set (pc)
644         (if_then_else (match_operator 0 "comparison_operator"
645                         [(match_operand:SI 1 "arith_operand" "")
646                          (match_operand:SI 2 "arith_operand" "")])
647                       (label_ref (match_operand 3 "" ""))
648                       (pc)))
649    (clobber (reg:SI T_REG))]
650   ""
651   "if (TARGET_SHMEDIA)
652       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
653                                              operands[2], operands[3]));
654    else if (TARGET_CBRANCHDI4)
655      expand_cbranchsi4 (operands, LAST_AND_UNUSED_RTX_CODE, -1);
656    else
657      sh_emit_compare_and_branch (operands, SImode);
658    DONE;")
660 ;; -------------------------------------------------------------------------
661 ;; SImode unsigned integer comparisons
662 ;; -------------------------------------------------------------------------
664 (define_insn_and_split "cmpgeusi_t"
665   [(set (reg:SI T_REG)
666         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
667                 (match_operand:SI 1 "arith_reg_or_0_operand" "rN")))]
668   "TARGET_SH1"
669   "cmp/hs       %1,%0"
670   "&& operands[1] == CONST0_RTX (SImode)"
671   [(pc)]
672   "
674   emit_insn (gen_sett ());
675   DONE;
677    [(set_attr "type" "mt_group")])
679 (define_insn "cmpgtusi_t"
680   [(set (reg:SI T_REG)
681         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
682                 (match_operand:SI 1 "arith_reg_operand" "r")))]
683   "TARGET_SH1"
684   "cmp/hi       %1,%0"
685    [(set_attr "type" "mt_group")])
688 ;; -------------------------------------------------------------------------
689 ;; DImode compare and branch
690 ;; -------------------------------------------------------------------------
693 ;; arith3 patterns don't work well with the sh4-300 branch prediction mechanism.
694 ;; Therefore, we aim to have a set of three branches that go straight to the
695 ;; destination, i.e. only one of them is taken at any one time.
696 ;; This mechanism should also be slightly better for the sh4-200.
698 (define_expand "cbranchdi4"
699   [(set (pc)
700         (if_then_else (match_operator 0 "comparison_operator"
701                         [(match_operand:DI 1 "arith_operand" "")
702                          (match_operand:DI 2 "arith_operand" "")])
703                       (label_ref (match_operand 3 "" ""))
704                       (pc)))
705    (clobber (match_dup 4))
706    (clobber (reg:SI T_REG))]
707   "TARGET_CBRANCHDI4 || TARGET_SH2 || TARGET_SHMEDIA"
708   "
710   enum rtx_code comparison;
712   if (TARGET_SHMEDIA)
713     {
714       emit_jump_insn (gen_cbranchint4_media (operands[0], operands[1],
715                                              operands[2], operands[3]));
716       DONE;
717     }
719   else if (!TARGET_CBRANCHDI4)
720     {
721       sh_emit_compare_and_branch (operands, DImode);
722       DONE;
723     }
725   else
726     {
727       if (expand_cbranchdi4 (operands, LAST_AND_UNUSED_RTX_CODE))
728         DONE;
730       comparison = prepare_cbranch_operands (operands, DImode,
731                                              LAST_AND_UNUSED_RTX_CODE);
732       if (comparison != GET_CODE (operands[0]))
733         operands[0]
734           = gen_rtx_fmt_ee (comparison, VOIDmode, operands[1], operands[2]);
735        operands[4] = gen_rtx_SCRATCH (SImode);
736     }
739 (define_insn_and_split "cbranchdi4_i"
740   [(set (pc)
741         (if_then_else (match_operator 0 "comparison_operator"
742                         [(match_operand:DI 1 "arith_operand" "r,r")
743                          (match_operand:DI 2 "arith_operand" "rN,I08")])
744                       (label_ref (match_operand 3 "" ""))
745                       (pc)))
746    (clobber (match_scratch:SI 4 "=X,&r"))
747    (clobber (reg:SI T_REG))]
748   "TARGET_CBRANCHDI4"
749   "#"
750   "&& reload_completed"
751   [(pc)]
752   "
754   if (!expand_cbranchdi4 (operands, GET_CODE (operands[0])))
755     FAIL;
756   DONE;
759 ;; -------------------------------------------------------------------------
760 ;; DImode signed integer comparisons
761 ;; -------------------------------------------------------------------------
763 (define_insn ""
764   [(set (reg:SI T_REG)
765         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
766                        (match_operand:DI 1 "arith_operand" "r"))
767                (const_int 0)))]
768   "TARGET_SH1"
769   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
770                                  insn, operands);"
771   [(set_attr "length" "6")
772    (set_attr "type" "arith3b")])
774 (define_insn "cmpeqdi_t"
775   [(set (reg:SI T_REG)
776         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
777                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
778   "TARGET_SH1"
779   "@
780         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
781         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
782   [(set_attr "length" "6")
783    (set_attr "type" "arith3b")])
785 (define_split
786   [(set (reg:SI T_REG)
787         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
788                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
789 ;; If we applied this split when not optimizing, it would only be
790 ;; applied during the machine-dependent reorg, when no new basic blocks
791 ;; may be created.
792   "TARGET_SH1 && reload_completed && optimize"
793   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
794    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
795                            (label_ref (match_dup 6))
796                            (pc)))
797    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
798    (match_dup 6)]
799   "
801   operands[2]
802     = gen_rtx_REG (SImode,
803                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
804   operands[3]
805     = (operands[1] == const0_rtx
806        ? const0_rtx
807        : gen_rtx_REG (SImode,
808                       true_regnum (operands[1])
809                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
810   operands[4] = gen_lowpart (SImode, operands[0]);
811   operands[5] = gen_lowpart (SImode, operands[1]);
812   operands[6] = gen_label_rtx ();
815 (define_insn "cmpgtdi_t"
816   [(set (reg:SI T_REG)
817         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
818                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
819   "TARGET_SH2"
820   "@
821         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
822         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
823   [(set_attr "length" "8")
824    (set_attr "type" "arith3")])
826 (define_insn "cmpgedi_t"
827   [(set (reg:SI T_REG)
828         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
829                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
830   "TARGET_SH2"
831   "@
832         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
833         cmp/pz\\t%S0"
834   [(set_attr "length" "8,2")
835    (set_attr "type" "arith3,mt_group")])
837 ;; -------------------------------------------------------------------------
838 ;; DImode unsigned integer comparisons
839 ;; -------------------------------------------------------------------------
841 (define_insn "cmpgeudi_t"
842   [(set (reg:SI T_REG)
843         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
844                 (match_operand:DI 1 "arith_reg_operand" "r")))]
845   "TARGET_SH2"
846   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
847   [(set_attr "length" "8")
848    (set_attr "type" "arith3")])
850 (define_insn "cmpgtudi_t"
851   [(set (reg:SI T_REG)
852         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
853                 (match_operand:DI 1 "arith_reg_operand" "r")))]
854   "TARGET_SH2"
855   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
856   [(set_attr "length" "8")
857    (set_attr "type" "arith3")])
859 (define_insn "cmpeqsi_media"
860   [(set (match_operand:SI 0 "register_operand" "=r")
861         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
862                (match_operand:SI 2 "cmp_operand" "Nr")))]
863   "TARGET_SHMEDIA"
864   "cmpeq        %1, %N2, %0"
865   [(set_attr "type" "cmp_media")])
867 (define_insn "cmpeqdi_media"
868   [(set (match_operand:SI 0 "register_operand" "=r")
869         (eq:SI (match_operand:DI 1 "register_operand" "%r")
870                (match_operand:DI 2 "cmp_operand" "Nr")))]
871   "TARGET_SHMEDIA"
872   "cmpeq        %1, %N2, %0"
873   [(set_attr "type" "cmp_media")])
875 (define_insn "cmpgtsi_media"
876   [(set (match_operand:SI 0 "register_operand" "=r")
877         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
878                (match_operand:SI 2 "cmp_operand" "rN")))]
879   "TARGET_SHMEDIA"
880   "cmpgt        %N1, %N2, %0"
881   [(set_attr "type" "cmp_media")])
883 (define_insn "cmpgtdi_media"
884   [(set (match_operand:SI 0 "register_operand" "=r")
885         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
886                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
887   "TARGET_SHMEDIA"
888   "cmpgt        %N1, %N2, %0"
889   [(set_attr "type" "cmp_media")])
891 (define_insn "cmpgtusi_media"
892   [(set (match_operand:SI 0 "register_operand" "=r")
893         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
894                 (match_operand:SI 2 "cmp_operand" "rN")))]
895   "TARGET_SHMEDIA"
896   "cmpgtu       %N1, %N2, %0"
897   [(set_attr "type" "cmp_media")])
899 (define_insn "cmpgtudi_media"
900   [(set (match_operand:SI 0 "register_operand" "=r")
901         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
902                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
903   "TARGET_SHMEDIA"
904   "cmpgtu       %N1, %N2, %0"
905   [(set_attr "type" "cmp_media")])
907 ; These two patterns are for combine.
908 (define_insn "*cmpne0sisi_media"
909   [(set (match_operand:SI 0 "register_operand" "=r")
910         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
911   "TARGET_SHMEDIA"
912   "cmpgtu       %1,r63,%0"
913   [(set_attr "type" "cmp_media")])
915 ;; -------------------------------------------------------------------------
916 ;; Conditional move instructions
917 ;; -------------------------------------------------------------------------
919 ;; The insn names may seem reversed, but note that cmveq performs the move
920 ;; if op1 == 0, and cmvne does it if op1 != 0.
922 (define_insn "movdicc_false"
923   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
924         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
925                              (const_int 0))
926          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
927          (match_operand:DI 3 "arith_reg_operand" "0")))]
928   "TARGET_SHMEDIA"
929   "cmveq        %1, %N2, %0"
930   [(set_attr "type" "arith_media")])
932 (define_insn "movdicc_true"
933   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
934         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
935                              (const_int 0))
936          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
937          (match_operand:DI 3 "arith_reg_operand" "0")))]
938   "TARGET_SHMEDIA"
939   "cmvne        %1, %N2, %0"
940   [(set_attr "type" "arith_media")])
942 (define_peephole2
943   [(set (match_operand:DI 0 "arith_reg_dest" "")
944         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
945                            [(match_operand:DI 1 "arith_reg_operand" "")
946                             (const_int 0)])
947          (match_operand:DI 2 "arith_reg_dest" "")
948          (match_dup 0)))
949    (set (match_dup 2) (match_dup 0))]
950   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
951   [(set (match_dup 2)
952         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
953   "
955   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
956                                 VOIDmode, operands[1], CONST0_RTX (DImode));
959 (define_peephole2
960   [(set (match_operand:DI 0 "general_movdst_operand" "")
961         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
962    (set (match_operand:DI 2 "arith_reg_dest" "")
963         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
964                            [(match_operand:DI 3 "arith_reg_operand" "")
965                             (const_int 0)])
966          (match_dup 0)
967          (match_dup 2)))]
968   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
969   [(set (match_dup 2)
970         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
971   "")
973 (define_expand "movdicc"
974   [(set (match_operand:DI 0 "register_operand" "")
975         (if_then_else:DI (match_operand 1 "comparison_operator" "")
976                          (match_operand:DI 2 "register_operand" "")
977                          (match_operand:DI 3 "register_operand" "")))]
978   "TARGET_SHMEDIA"
979   "
981   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
982       && GET_MODE (XEXP (operands[1], 0)) == DImode
983       && XEXP (operands[1], 1) == const0_rtx)
984     ;
985   else
986     {
987       if (!can_create_pseudo_p ())
988         FAIL;
990       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
991                                               GET_CODE (operands[1]),
992                                               XEXP (operands[1], 0),
993                                               XEXP (operands[1], 1));
994       if (!operands[1])
995         FAIL;
996     }
999 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1000 ;; SImode to DImode.
1001 (define_insn "movsicc_false"
1002   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1003         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1004                           (const_int 0))
1005          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1006          (match_operand:SI 3 "arith_reg_operand" "0")))]
1007   "TARGET_SHMEDIA"
1008   "cmveq        %1, %N2, %0"
1009   [(set_attr "type" "arith_media")])
1011 (define_insn "movsicc_true"
1012   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1013         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1014                           (const_int 0))
1015          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1016          (match_operand:SI 3 "arith_reg_operand" "0")))]
1017   "TARGET_SHMEDIA"
1018   "cmvne        %1, %N2, %0"
1019   [(set_attr "type" "arith_media")])
1021 (define_peephole2
1022   [(set (match_operand:SI 0 "arith_reg_dest" "")
1023         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1024                            [(match_operand:SI 1 "arith_reg_operand" "")
1025                             (const_int 0)])
1026          (match_operand:SI 2 "arith_reg_dest" "")
1027          (match_dup 0)))
1028    (set (match_dup 2) (match_dup 0))]
1029   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1030   [(set (match_dup 2)
1031         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1032   "
1034   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1035                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1038 (define_peephole2
1039   [(set (match_operand:SI 0 "general_movdst_operand" "")
1040         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1041    (set (match_operand:SI 2 "arith_reg_dest" "")
1042         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1043                            [(match_operand:SI 3 "arith_reg_operand" "")
1044                             (const_int 0)])
1045          (match_dup 0)
1046          (match_dup 2)))]
1047   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1048    && (!REG_P (operands[1]) || GENERAL_REGISTER_P (REGNO (operands[1])))"
1049   [(set (match_dup 2)
1050         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1051   "
1053   replace_rtx (operands[4], operands[0], operands[1]);
1056 (define_peephole2
1057   [(set (match_operand 0 "any_register_operand" "")
1058         (match_operand 1 "any_register_operand" ""))
1059    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1060    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1061   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1062     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1063    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1064    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[0])
1065    && ! FIND_REG_INC_NOTE (peep2_next_insn (2), operands[2])
1066    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1067    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1068    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1069    && (REGNO_REG_CLASS (REGNO (operands[0]))
1070        == REGNO_REG_CLASS (REGNO (operands[2])))
1071    && (REGNO_REG_CLASS (REGNO (operands[1]))
1072        == REGNO_REG_CLASS (REGNO (operands[0])))"
1073   [(set (match_dup 0) (match_dup 3))
1074    (set (match_dup 4) (match_dup 5))]
1075   "
1077   rtx set1, set2, insn2;
1078   rtx replacements[4];
1080   /* We want to replace occurrences of operands[0] with operands[1] and
1081      operands[2] with operands[0] in operands[4]/operands[5].
1082      Doing just two replace_rtx calls naively would result in the second
1083      replacement undoing all that the first did if operands[1] and operands[2]
1084      are identical, so we must do this simultaneously.  */
1085   replacements[0] = operands[0];
1086   replacements[1] = operands[1];
1087   replacements[2] = operands[2];
1088   replacements[3] = operands[0];
1089   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1090       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1091       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1092     FAIL;
1094   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1095   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1096   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1097   /* The operands array is aliased to recog_data.operand, which gets
1098      clobbered by extract_insn, so finish with it now.  */
1099   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1100   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1101   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1102      always uses emit_insn.  */
1103   /* Check that we don't violate matching constraints or earlyclobbers.  */
1104   extract_insn (emit_insn (set1));
1105   if (! constrain_operands (1))
1106     goto failure;
1107   insn2 = emit (set2);
1108   if (GET_CODE (insn2) == BARRIER)
1109     goto failure;
1110   extract_insn (insn2);
1111   if (! constrain_operands (1))
1112     {
1113       rtx tmp;
1114     failure:
1115       tmp = replacements[0];
1116       replacements[0] = replacements[1];
1117       replacements[1] = tmp;
1118       tmp = replacements[2];
1119       replacements[2] = replacements[3];
1120       replacements[3] = tmp;
1121       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1122       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1123       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1124       FAIL;
1125     }
1126   DONE;
1129 ;; The register allocator is rather clumsy in handling multi-way conditional
1130 ;; moves, so allow the combiner to make them, and we split them up after
1131 ;; reload.  */
1132 (define_insn_and_split "*movsicc_umin"
1133   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1134         (umin:SI (if_then_else:SI
1135                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1136                        (const_int 0))
1137                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1138                    (match_operand:SI 3 "register_operand" "0"))
1139                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1140    (clobber (match_scratch:SI 5 "=&r"))]
1141   "TARGET_SHMEDIA && !can_create_pseudo_p ()"
1142   "#"
1143   "TARGET_SHMEDIA && reload_completed"
1144   [(pc)]
1145   "
1147   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1148                                 operands[3]));
1149   emit_insn (gen_cmpgtusi_media (operands[5], operands[4], operands[0]));
1150   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1151                                 operands[0]));
1152   DONE;
1155 (define_insn "*movsicc_t_false"
1156   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1157         (if_then_else (eq (reg:SI T_REG) (const_int 0))
1158                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1159                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1160   "TARGET_PRETEND_CMOVE
1161    && (arith_reg_operand (operands[1], SImode)
1162        || (immediate_operand (operands[1], SImode)
1163            && satisfies_constraint_I08 (operands[1])))"
1164   "bt 0f\;mov %1,%0\\n0:"
1165   [(set_attr "type" "mt_group,arith") ;; poor approximation
1166    (set_attr "length" "4")])
1168 (define_insn "*movsicc_t_true"
1169   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1170         (if_then_else (ne (reg:SI T_REG) (const_int 0))
1171                       (match_operand:SI 1 "general_movsrc_operand" "r,I08")
1172                       (match_operand:SI 2 "arith_reg_operand" "0,0")))]
1173   "TARGET_PRETEND_CMOVE
1174    && (arith_reg_operand (operands[1], SImode)
1175        || (immediate_operand (operands[1], SImode)
1176            && satisfies_constraint_I08 (operands[1])))"
1177   "bf 0f\;mov %1,%0\\n0:"
1178   [(set_attr "type" "mt_group,arith") ;; poor approximation
1179    (set_attr "length" "4")])
1181 (define_expand "movsicc"
1182   [(set (match_operand:SI 0 "arith_reg_dest" "")
1183         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1184                          (match_operand:SI 2 "arith_reg_or_0_operand" "")
1185                          (match_operand:SI 3 "arith_reg_operand" "")))]
1186   "TARGET_SHMEDIA || TARGET_PRETEND_CMOVE"
1187   "
1189   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1190       && GET_MODE (XEXP (operands[1], 0)) == SImode
1191       && (TARGET_SHMEDIA
1192           || (REG_P (XEXP (operands[1], 0))
1193               && REGNO (XEXP (operands[1], 0)) == T_REG))
1194       && XEXP (operands[1], 1) == const0_rtx)
1195     ;
1197   else if (TARGET_PRETEND_CMOVE)
1198     {
1199       enum rtx_code code = GET_CODE (operands[1]);
1200       enum rtx_code new_code = code;
1201       rtx op0 = XEXP (operands[1], 0);
1202       rtx op1 = XEXP (operands[1], 1);
1204       if (! currently_expanding_to_rtl)
1205         FAIL;
1206       switch (code)
1207         {
1208         case LT: case LE: case LEU: case LTU:
1209           if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_INT)
1210             break;
1211         case NE:
1212           new_code = reverse_condition (code);
1213           break;
1214         case EQ: case GT: case GE: case GEU: case GTU:
1215           break;
1216         default:
1217           FAIL;
1218         }
1219       sh_emit_scc_to_t (new_code, op0, op1);
1220       operands[1] = gen_rtx_fmt_ee (new_code == code ? NE : EQ, VOIDmode,
1221                                     gen_rtx_REG (SImode, T_REG), const0_rtx);
1222     }
1223   else
1224     {
1225       if (!can_create_pseudo_p ())
1226         FAIL;
1228       operands[1] = sh_emit_cheap_store_flag (GET_MODE (operands[0]),
1229                                               GET_CODE (operands[1]),
1230                                               XEXP (operands[1], 0),
1231                                               XEXP (operands[1], 1));
1232       if (!operands[1])
1233         FAIL;
1234     }
1237 (define_expand "movqicc"
1238   [(set (match_operand:QI 0 "register_operand" "")
1239         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1240                          (match_operand:QI 2 "register_operand" "")
1241                          (match_operand:QI 3 "register_operand" "")))]
1242   "TARGET_SHMEDIA"
1243   "
1245   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1246   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1247   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1248   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1249   DONE;
1252 ;; -------------------------------------------------------------------------
1253 ;; Addition instructions
1254 ;; -------------------------------------------------------------------------
1256 (define_expand "adddi3"
1257   [(set (match_operand:DI 0 "arith_reg_operand" "")
1258         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1259                  (match_operand:DI 2 "arith_operand" "")))]
1260   ""
1261   "
1263   if (TARGET_SH1)
1264     {
1265       if (!can_create_pseudo_p () && ! arith_reg_operand (operands[2], DImode))
1266         FAIL;
1267       operands[2] = force_reg (DImode, operands[2]);
1268       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1269       DONE;
1270     }
1273 (define_insn "*adddi3_media"
1274   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1275         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1276                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1277   "TARGET_SHMEDIA"
1278   "@
1279         add     %1, %2, %0
1280         addi    %1, %2, %0"
1281   [(set_attr "type" "arith_media")])
1283 (define_insn "*adddisi3_media"
1284   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1285         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1286                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1287   "TARGET_SHMEDIA"
1288   "@
1289         add.l   %1, %2, %0
1290         addi.l  %1, %2, %0"
1291   [(set_attr "type" "arith_media")
1292    (set_attr "highpart" "ignore")])
1294 (define_insn "adddi3z_media"
1295   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1296         (zero_extend:DI
1297          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1298                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1299   "TARGET_SHMEDIA"
1300   "addz.l       %1, %N2, %0"
1301   [(set_attr "type" "arith_media")
1302    (set_attr "highpart" "ignore")])
1304 (define_insn "adddi3_compact"
1305   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1306         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1307                  (match_operand:DI 2 "arith_reg_operand" "r")))
1308    (clobber (reg:SI T_REG))]
1309   "TARGET_SH1"
1310   "#"
1311   [(set_attr "length" "6")])
1313 (define_split
1314   [(set (match_operand:DI 0 "arith_reg_dest" "")
1315         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1316                  (match_operand:DI 2 "arith_reg_operand" "")))
1317    (clobber (reg:SI T_REG))]
1318   "TARGET_SH1 && reload_completed"
1319   [(const_int 0)]
1320   "
1322   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1323   high0 = gen_rtx_REG (SImode,
1324                        true_regnum (operands[0])
1325                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1326   high2 = gen_rtx_REG (SImode,
1327                        true_regnum (operands[2])
1328                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1329   emit_insn (gen_clrt ());
1330   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1331   emit_insn (gen_addc1 (high0, high0, high2));
1332   DONE;
1335 (define_insn "addc"
1336   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1337         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1338                           (match_operand:SI 2 "arith_reg_operand" "r"))
1339                  (reg:SI T_REG)))
1340    (set (reg:SI T_REG)
1341         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1342   "TARGET_SH1"
1343   "addc %2,%0"
1344   [(set_attr "type" "arith")])
1346 (define_insn "addc1"
1347   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1348         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1349                           (match_operand:SI 2 "arith_reg_operand" "r"))
1350                  (reg:SI T_REG)))
1351    (clobber (reg:SI T_REG))]
1352   "TARGET_SH1"
1353   "addc %2,%0"
1354   [(set_attr "type" "arith")])
1356 (define_expand "addsi3"
1357   [(set (match_operand:SI 0 "arith_reg_operand" "")
1358         (plus:SI (match_operand:SI 1 "arith_operand" "")
1359                  (match_operand:SI 2 "arith_operand" "")))]
1360   ""
1361   "
1363   if (TARGET_SHMEDIA)
1364     operands[1] = force_reg (SImode, operands[1]);
1367 (define_insn "addsi3_media"
1368   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1369         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1370                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1371   "TARGET_SHMEDIA"
1372   "@
1373         add.l   %1, %2, %0
1374         addi.l  %1, %2, %0"
1375   [(set_attr "type" "arith_media")
1376    (set_attr "highpart" "ignore")])
1378 (define_insn "addsidi3_media"
1379   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1380         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1381                                   "%r,r")
1382                                  (match_operand:SI 2 "arith_operand"
1383                                   "r,I10"))))]
1384   "TARGET_SHMEDIA"
1385   "@
1386         add.l   %1, %2, %0
1387         addi.l  %1, %2, %0"
1388   [(set_attr "type" "arith_media")
1389    (set_attr "highpart" "ignore")])
1391 (define_insn "*addsi3_compact"
1392   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1393         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1394                  (match_operand:SI 2 "arith_operand" "rI08")))]
1395   "TARGET_SH1"
1396   "add  %2,%0"
1397   [(set_attr "type" "arith")])
1399 ;; -------------------------------------------------------------------------
1400 ;; Subtraction instructions
1401 ;; -------------------------------------------------------------------------
1403 (define_expand "subdi3"
1404   [(set (match_operand:DI 0 "arith_reg_operand" "")
1405         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1406                   (match_operand:DI 2 "arith_reg_operand" "")))]
1407   ""
1408   "
1410   if (TARGET_SH1)
1411     {
1412       operands[1] = force_reg (DImode, operands[1]);
1413       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1414       DONE;
1415     }
1418 (define_insn "*subdi3_media"
1419   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1420         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1421                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1422   "TARGET_SHMEDIA"
1423   "sub  %N1, %2, %0"
1424   [(set_attr "type" "arith_media")])
1425   
1426 (define_insn "subdisi3_media"
1427   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1428         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1429                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1430   "TARGET_SHMEDIA"
1431   "sub.l        %N1, %2, %0"
1432   [(set_attr "type" "arith_media")
1433    (set_attr "highpart" "ignore")])
1435 (define_insn "subdi3_compact"
1436   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1437         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1438                  (match_operand:DI 2 "arith_reg_operand" "r")))
1439    (clobber (reg:SI T_REG))]
1440   "TARGET_SH1"
1441   "#"
1442   [(set_attr "length" "6")])
1444 (define_split
1445   [(set (match_operand:DI 0 "arith_reg_dest" "")
1446         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1447                   (match_operand:DI 2 "arith_reg_operand" "")))
1448    (clobber (reg:SI T_REG))]
1449   "TARGET_SH1 && reload_completed"
1450   [(const_int 0)]
1451   "
1453   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1454   high0 = gen_rtx_REG (SImode,
1455                        true_regnum (operands[0])
1456                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1457   high2 = gen_rtx_REG (SImode,
1458                        true_regnum (operands[2])
1459                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1460   emit_insn (gen_clrt ());
1461   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1462   emit_insn (gen_subc1 (high0, high0, high2));
1463   DONE;
1466 (define_insn "subc"
1467   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1468         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1469                             (match_operand:SI 2 "arith_reg_operand" "r"))
1470                   (reg:SI T_REG)))
1471    (set (reg:SI T_REG)
1472         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1473                           (reg:SI T_REG))
1474                 (match_dup 1)))]
1475   "TARGET_SH1"
1476   "subc %2,%0"
1477   [(set_attr "type" "arith")])
1479 (define_insn "subc1"
1480   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1481         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1482                             (match_operand:SI 2 "arith_reg_operand" "r"))
1483                   (reg:SI T_REG)))
1484    (clobber (reg:SI T_REG))]
1485   "TARGET_SH1"
1486   "subc %2,%0"
1487   [(set_attr "type" "arith")])
1489 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1490 ;; pattern for this case.  This helps multimedia applications that compute
1491 ;; the sum of absolute differences.
1492 (define_insn "mov_neg_si_t"
1493   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1494   "TARGET_SH1"
1495   "subc %0,%0"
1496   [(set_attr "type" "arith")])
1498 (define_insn "*subsi3_internal"
1499   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1500         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1501                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1502   "TARGET_SH1"
1503   "sub  %2,%0"
1504   [(set_attr "type" "arith")])
1506 (define_insn_and_split "*subsi3_media"
1507   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1508         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1509                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1510   "TARGET_SHMEDIA
1511    && (operands[1] != constm1_rtx
1512        || (GET_CODE (operands[2]) != TRUNCATE
1513            && GET_CODE (operands[2]) != SUBREG))"
1514   "sub.l        %N1, %2, %0"
1515   "operands[1] == constm1_rtx"
1516   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1517   ""
1518   [(set_attr "type" "arith_media")
1519    (set_attr "highpart" "ignore")])
1521 (define_split
1522   [(set (match_operand:SI 0 "arith_reg_dest" "")
1523         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1524                                                        "general_extend_operand"
1525                                                        "") 0)) 0)))]
1526   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1527   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1528    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1529   "")
1531 (define_split
1532   [(set (match_operand:SI 0 "arith_reg_dest" "")
1533         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1534                                                        "general_extend_operand"
1535                                                        "") 0)) 3)))]
1536   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1537   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1538    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1539   "")
1540 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1541 ;; will sometimes save one instruction.  Otherwise we might get
1542 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1543 ;; are the same.
1545 (define_expand "subsi3"
1546   [(set (match_operand:SI 0 "arith_reg_operand" "")
1547         (minus:SI (match_operand:SI 1 "arith_operand" "")
1548                   (match_operand:SI 2 "arith_reg_operand" "")))]
1549   ""
1550   "
1552   if (TARGET_SH1 && CONST_INT_P (operands[1]))
1553     {
1554       emit_insn (gen_negsi2 (operands[0], operands[2]));
1555       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1556       DONE;
1557     }
1558   if (TARGET_SHMEDIA)
1559     {
1560       if (!can_create_pseudo_p ()
1561           && ! arith_reg_or_0_operand (operands[1], SImode))
1562         FAIL;
1563       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1564         operands[1] = force_reg (SImode, operands[1]);
1565     }
1568 ;; -------------------------------------------------------------------------
1569 ;; Division instructions
1570 ;; -------------------------------------------------------------------------
1572 ;; We take advantage of the library routines which don't clobber as many
1573 ;; registers as a normal function call would.
1575 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1576 ;; also has an effect on the register that holds the address of the sfunc.
1577 ;; To make this work, we have an extra dummy insn that shows the use
1578 ;; of this register for reorg.
1580 (define_insn "use_sfunc_addr"
1581   [(set (reg:SI PR_REG)
1582         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1583   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1584   ""
1585   [(set_attr "length" "0")])
1587 (define_insn "udivsi3_sh2a"
1588   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1589         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1590                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1591   "TARGET_SH2A"
1592   "divu %2,%1"
1593   [(set_attr "type" "arith")
1594    (set_attr "in_delay_slot" "no")])
1596 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1597 ;; hard register 0.  If we used hard register 0, then the next instruction
1598 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1599 ;; gets allocated to a stack slot that needs its address reloaded, then
1600 ;; there is nothing to prevent reload from using r0 to reload the address.
1601 ;; This reload would clobber the value in r0 we are trying to store.
1602 ;; If we let reload allocate r0, then this problem can never happen.
1604 (define_insn "udivsi3_i1"
1605   [(set (match_operand:SI 0 "register_operand" "=z")
1606         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1607    (clobber (reg:SI T_REG))
1608    (clobber (reg:SI PR_REG))
1609    (clobber (reg:SI R4_REG))
1610    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1611   "TARGET_SH1 && ! TARGET_SH4"
1612   "jsr  @%1%#"
1613   [(set_attr "type" "sfunc")
1614    (set_attr "needs_delay_slot" "yes")])
1616 ; Since shmedia-nofpu code could be linked against shcompact code, and
1617 ; the udivsi3 libcall has the same name, we must consider all registers
1618 ; clobbered that are in the union of the registers clobbered by the
1619 ; shmedia and the shcompact implementation.  Note, if the shcompact
1620 ; implementation actually used shcompact code, we'd need to clobber
1621 ; also r23 and fr23.
1622 (define_insn "udivsi3_i1_media"
1623   [(set (match_operand:SI 0 "register_operand" "=z")
1624         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1625    (clobber (reg:SI T_MEDIA_REG))
1626    (clobber (reg:SI PR_MEDIA_REG))
1627    (clobber (reg:SI R20_REG))
1628    (clobber (reg:SI R21_REG))
1629    (clobber (reg:SI R22_REG))
1630    (clobber (reg:DI TR0_REG))
1631    (clobber (reg:DI TR1_REG))
1632    (clobber (reg:DI TR2_REG))
1633    (use (match_operand 1 "target_reg_operand" "b"))]
1634   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1635   "blink        %1, r18"
1636   [(set_attr "type" "sfunc")
1637    (set_attr "needs_delay_slot" "yes")])
1639 (define_expand "udivsi3_i4_media"
1640   [(set (match_dup 3)
1641         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1642    (set (match_dup 4)
1643         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1644    (set (match_dup 5) (float:DF (match_dup 3)))
1645    (set (match_dup 6) (float:DF (match_dup 4)))
1646    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1647    (set (match_dup 8) (fix:DI (match_dup 7)))
1648    (set (match_operand:SI 0 "register_operand" "")
1649         (truncate:SI (match_dup 8)))]
1650   "TARGET_SHMEDIA_FPU"
1651   "
1653   operands[3] = gen_reg_rtx (DImode);
1654   operands[4] = gen_reg_rtx (DImode);
1655   operands[5] = gen_reg_rtx (DFmode);
1656   operands[6] = gen_reg_rtx (DFmode);
1657   operands[7] = gen_reg_rtx (DFmode);
1658   operands[8] = gen_reg_rtx (DImode);
1661 (define_insn "udivsi3_i4"
1662   [(set (match_operand:SI 0 "register_operand" "=y")
1663         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1664    (clobber (reg:SI T_REG))
1665    (clobber (reg:SI PR_REG))
1666    (clobber (reg:DF DR0_REG))
1667    (clobber (reg:DF DR2_REG))
1668    (clobber (reg:DF DR4_REG))
1669    (clobber (reg:SI R0_REG))
1670    (clobber (reg:SI R1_REG))
1671    (clobber (reg:SI R4_REG))
1672    (clobber (reg:SI R5_REG))
1673    (use (reg:PSI FPSCR_REG))
1674    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1675   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1676   "jsr  @%1%#"
1677   [(set_attr "type" "sfunc")
1678    (set_attr "fp_mode" "double")
1679    (set_attr "needs_delay_slot" "yes")])
1681 (define_insn "udivsi3_i4_single"
1682   [(set (match_operand:SI 0 "register_operand" "=y")
1683         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1684    (clobber (reg:SI T_REG))
1685    (clobber (reg:SI PR_REG))
1686    (clobber (reg:DF DR0_REG))
1687    (clobber (reg:DF DR2_REG))
1688    (clobber (reg:DF DR4_REG))
1689    (clobber (reg:SI R0_REG))
1690    (clobber (reg:SI R1_REG))
1691    (clobber (reg:SI R4_REG))
1692    (clobber (reg:SI R5_REG))
1693    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1694   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1695   "jsr  @%1%#"
1696   [(set_attr "type" "sfunc")
1697    (set_attr "needs_delay_slot" "yes")])
1699 (define_insn "udivsi3_i4_int"
1700   [(set (match_operand:SI 0 "register_operand" "=z")
1701         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1702    (clobber (reg:SI T_REG))
1703    (clobber (reg:SI R1_REG))
1704    (clobber (reg:SI PR_REG))
1705    (clobber (reg:SI MACH_REG))
1706    (clobber (reg:SI MACL_REG))
1707    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1708   "TARGET_SH1"
1709   "jsr  @%1%#"
1710   [(set_attr "type" "sfunc")
1711    (set_attr "needs_delay_slot" "yes")])
1714 (define_expand "udivsi3"
1715   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1716    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1717    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1718    (parallel [(set (match_operand:SI 0 "register_operand" "")
1719                    (udiv:SI (reg:SI R4_REG)
1720                             (reg:SI R5_REG)))
1721               (clobber (reg:SI T_REG))
1722               (clobber (reg:SI PR_REG))
1723               (clobber (reg:SI R4_REG))
1724               (use (match_dup 3))])]
1725   ""
1726   "
1728   rtx last;
1730   operands[3] = gen_reg_rtx (Pmode);
1731   /* Emit the move of the address to a pseudo outside of the libcall.  */
1732   if (TARGET_DIVIDE_CALL_TABLE)
1733     {
1734       /* libgcc2:__udivmoddi4 is not supposed to use an actual division, since
1735          that causes problems when the divide code is supposed to come from a
1736          separate library.  Division by zero is undefined, so dividing 1 can be
1737          implemented by comparing with the divisor.  */
1738       if (operands[1] == const1_rtx && currently_expanding_to_rtl)
1739         {
1740           rtx test = gen_rtx_GEU (VOIDmode, operands[1], operands[2]);
1741           emit_insn (gen_cstoresi4 (operands[0], test,
1742                                     operands[1], operands[2]));
1743           DONE;
1744         }
1745       else if (operands[2] == const0_rtx)
1746         {
1747           emit_move_insn (operands[0], operands[2]);
1748           DONE;
1749         }
1750       function_symbol (operands[3], \"__udivsi3_i4i\", SFUNC_GOT);
1751       last = gen_udivsi3_i4_int (operands[0], operands[3]);
1752     }
1753   else if (TARGET_DIVIDE_CALL_FP)
1754     {
1755       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1756       if (TARGET_FPU_SINGLE)
1757         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1758       else
1759         last = gen_udivsi3_i4 (operands[0], operands[3]);
1760     }
1761   else if (TARGET_SHMEDIA_FPU)
1762     {
1763       operands[1] = force_reg (SImode, operands[1]);
1764       operands[2] = force_reg (SImode, operands[2]);
1765       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1766       DONE;
1767     }
1768   else if (TARGET_SH2A)
1769     {
1770       operands[1] = force_reg (SImode, operands[1]);
1771       operands[2] = force_reg (SImode, operands[2]);
1772       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1773       DONE;
1774     }
1775   else if (TARGET_SH5)
1776     {
1777       function_symbol (operands[3],
1778                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1779                        SFUNC_STATIC);
1781       if (TARGET_SHMEDIA)
1782         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1783       else if (TARGET_FPU_ANY)
1784         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1785       else
1786         last = gen_udivsi3_i1 (operands[0], operands[3]);
1787     }
1788   else
1789     {
1790       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1791       last = gen_udivsi3_i1 (operands[0], operands[3]);
1792     }
1793   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1794   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1795   emit_insn (last);
1796   DONE;
1799 (define_insn "divsi3_sh2a"
1800   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1801         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1802                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1803   "TARGET_SH2A"
1804   "divs %2,%1"
1805   [(set_attr "type" "arith")
1806    (set_attr "in_delay_slot" "no")])
1808 (define_insn "divsi3_i1"
1809   [(set (match_operand:SI 0 "register_operand" "=z")
1810         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1811    (clobber (reg:SI T_REG))
1812    (clobber (reg:SI PR_REG))
1813    (clobber (reg:SI R1_REG))
1814    (clobber (reg:SI R2_REG))
1815    (clobber (reg:SI R3_REG))
1816    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1817   "TARGET_SH1 && ! TARGET_SH4"
1818   "jsr  @%1%#"
1819   [(set_attr "type" "sfunc")
1820    (set_attr "needs_delay_slot" "yes")])
1822 (define_insn "divsi3_i1_media"
1823   [(set (match_operand:SI 0 "register_operand" "=z")
1824         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1825    (clobber (reg:SI T_MEDIA_REG))
1826    (clobber (reg:SI PR_MEDIA_REG))
1827    (clobber (reg:SI R1_REG))
1828    (clobber (reg:SI R20_REG))
1829    (clobber (reg:SI R21_REG))
1830    (clobber (reg:SI TR0_REG))
1831    (use (match_operand 1 "target_reg_operand" "b"))]
1832   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1833   "blink        %1, r18"
1834   [(set_attr "type" "sfunc")])
1836 (define_insn "divsi3_media_2"
1837   [(set (match_operand:SI 0 "register_operand" "=z")
1838         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1839    (clobber (reg:SI T_MEDIA_REG))
1840    (clobber (reg:SI PR_MEDIA_REG))
1841    (clobber (reg:SI R1_REG))
1842    (clobber (reg:SI R21_REG))
1843    (clobber (reg:SI TR0_REG))
1844    (use (reg:SI R20_REG))
1845    (use (match_operand 1 "target_reg_operand" "b"))]
1846   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1847   "blink        %1, r18"
1848   [(set_attr "type" "sfunc")])
1850 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1851 ;; hard reg clobbers and data dependencies that we need when we want
1852 ;; to rematerialize the division into a call.
1853 (define_insn_and_split "divsi_inv_call"
1854   [(set (match_operand:SI 0 "register_operand" "=r")
1855         (div:SI (match_operand:SI 1 "register_operand" "r")
1856                 (match_operand:SI 2 "register_operand" "r")))
1857    (clobber (reg:SI R4_REG))
1858    (clobber (reg:SI R5_REG))
1859    (clobber (reg:SI T_MEDIA_REG))
1860    (clobber (reg:SI PR_MEDIA_REG))
1861    (clobber (reg:SI R1_REG))
1862    (clobber (reg:SI R21_REG))
1863    (clobber (reg:SI TR0_REG))
1864    (clobber (reg:SI R20_REG))
1865    (use (match_operand:SI 3 "register_operand" "r"))]
1866   "TARGET_SHMEDIA"
1867   "#"
1868   "&& (high_life_started || reload_completed)"
1869   [(set (match_dup 0) (match_dup 3))]
1870   ""
1871   [(set_attr "highpart" "must_split")])
1873 ;; This is the combiner pattern for -mdiv=inv:call .
1874 (define_insn_and_split "*divsi_inv_call_combine"
1875   [(set (match_operand:SI 0 "register_operand" "=z")
1876         (div:SI (match_operand:SI 1 "register_operand" "r")
1877                 (match_operand:SI 2 "register_operand" "r")))
1878    (clobber (reg:SI R4_REG))
1879    (clobber (reg:SI R5_REG))
1880    (clobber (reg:SI T_MEDIA_REG))
1881    (clobber (reg:SI PR_MEDIA_REG))
1882    (clobber (reg:SI R1_REG))
1883    (clobber (reg:SI R21_REG))
1884    (clobber (reg:SI TR0_REG))
1885    (clobber (reg:SI R20_REG))
1886    (use (unspec:SI [(match_dup 1)
1887                     (match_operand:SI 3 "" "")
1888                     (unspec:SI [(match_operand:SI 4 "" "")
1889                                 (match_dup 3)
1890                                 (match_operand:DI 5 "" "")]
1891                      UNSPEC_DIV_INV_M2)
1892                     (match_operand:DI 6 "" "")
1893                     (const_int 0)
1894                     (const_int 0)]
1895          UNSPEC_DIV_INV_M3))]
1896   "TARGET_SHMEDIA"
1897   "#"
1898   "&& (high_life_started || reload_completed)"
1899   [(pc)]
1900   "
1902   const char *name = sh_divsi3_libfunc;
1903   enum sh_function_kind kind = SFUNC_GOT;
1904   rtx sym;
1906   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1907   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1908   while (TARGET_DIVIDE_INV_CALL2)
1909     {
1910       rtx x = operands[3];
1912       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1913         break;
1914       x = XVECEXP (x, 0, 0);
1915       name = \"__sdivsi3_2\";
1916       kind = SFUNC_STATIC;
1917       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1918       break;
1919     }
1920   sym = function_symbol (NULL, name, kind);
1921   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1922   DONE;
1924   [(set_attr "highpart" "must_split")])
1926 (define_expand "divsi3_i4_media"
1927   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1928    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1929    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1930    (set (match_operand:SI 0 "register_operand" "=r")
1931         (fix:SI (match_dup 5)))]
1932   "TARGET_SHMEDIA_FPU"
1933   "
1935   operands[3] = gen_reg_rtx (DFmode);
1936   operands[4] = gen_reg_rtx (DFmode);
1937   operands[5] = gen_reg_rtx (DFmode);
1940 (define_insn "divsi3_i4"
1941   [(set (match_operand:SI 0 "register_operand" "=y")
1942         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1943    (clobber (reg:SI PR_REG))
1944    (clobber (reg:DF DR0_REG))
1945    (clobber (reg:DF DR2_REG))
1946    (use (reg:PSI FPSCR_REG))
1947    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1948   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1949   "jsr  @%1%#"
1950   [(set_attr "type" "sfunc")
1951    (set_attr "fp_mode" "double")
1952    (set_attr "needs_delay_slot" "yes")])
1954 (define_insn "divsi3_i4_single"
1955   [(set (match_operand:SI 0 "register_operand" "=y")
1956         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1957    (clobber (reg:SI PR_REG))
1958    (clobber (reg:DF DR0_REG))
1959    (clobber (reg:DF DR2_REG))
1960    (clobber (reg:SI R2_REG))
1961    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1962   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1963   "jsr  @%1%#"
1964   [(set_attr "type" "sfunc")
1965    (set_attr "needs_delay_slot" "yes")])
1967 (define_insn "divsi3_i4_int"
1968   [(set (match_operand:SI 0 "register_operand" "=z")
1969         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1970    (clobber (reg:SI T_REG))
1971    (clobber (reg:SI PR_REG))
1972    (clobber (reg:SI R1_REG))
1973    (clobber (reg:SI MACH_REG))
1974    (clobber (reg:SI MACL_REG))
1975    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1976   "TARGET_SH1"
1977   "jsr  @%1%#"
1978   [(set_attr "type" "sfunc")
1979    (set_attr "needs_delay_slot" "yes")])
1981 (define_expand "divsi3"
1982   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1983    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1984    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1985    (parallel [(set (match_operand:SI 0 "register_operand" "")
1986                    (div:SI (reg:SI R4_REG)
1987                            (reg:SI R5_REG)))
1988               (clobber (reg:SI T_REG))
1989               (clobber (reg:SI PR_REG))
1990               (clobber (reg:SI R1_REG))
1991               (clobber (reg:SI R2_REG))
1992               (clobber (reg:SI R3_REG))
1993               (use (match_dup 3))])]
1994   ""
1995   "
1997   rtx last;
1999   operands[3] = gen_reg_rtx (Pmode);
2000   /* Emit the move of the address to a pseudo outside of the libcall.  */
2001   if (TARGET_DIVIDE_CALL_TABLE)
2002     {
2003       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2004       last = gen_divsi3_i4_int (operands[0], operands[3]);
2005     }
2006   else if (TARGET_DIVIDE_CALL_FP)
2007     {
2008       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2009       if (TARGET_FPU_SINGLE)
2010         last = gen_divsi3_i4_single (operands[0], operands[3]);
2011       else
2012         last = gen_divsi3_i4 (operands[0], operands[3]);
2013     }
2014   else if (TARGET_SH2A)
2015     {
2016       operands[1] = force_reg (SImode, operands[1]);
2017       operands[2] = force_reg (SImode, operands[2]);
2018       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2019       DONE;
2020     }
2021   else if (TARGET_DIVIDE_INV)
2022     {
2023       rtx dividend = operands[1];
2024       rtx divisor = operands[2];
2025       rtx tab_base;
2026       rtx nsb_res = gen_reg_rtx (DImode);
2027       rtx norm64 = gen_reg_rtx (DImode);
2028       rtx tab_ix = gen_reg_rtx (DImode);
2029       rtx norm32 = gen_reg_rtx (SImode);
2030       rtx i92 = force_reg (DImode, GEN_INT (92));
2031       rtx scratch0a = gen_reg_rtx (DImode);
2032       rtx scratch0b = gen_reg_rtx (DImode);
2033       rtx inv0 = gen_reg_rtx (SImode);
2034       rtx scratch1a = gen_reg_rtx (DImode);
2035       rtx scratch1b = gen_reg_rtx (DImode);
2036       rtx shift = gen_reg_rtx (DImode);
2037       rtx i2p27, i43;
2038       rtx inv1 = gen_reg_rtx (SImode);
2039       rtx scratch2a = gen_reg_rtx (DImode);
2040       rtx scratch2b = gen_reg_rtx (SImode);
2041       rtx inv2 = gen_reg_rtx (SImode);
2042       rtx scratch3a = gen_reg_rtx (DImode);
2043       rtx scratch3b = gen_reg_rtx (DImode);
2044       rtx scratch3c = gen_reg_rtx (DImode);
2045       rtx scratch3d = gen_reg_rtx (SImode);
2046       rtx scratch3e = gen_reg_rtx (DImode);
2047       rtx result = gen_reg_rtx (SImode);
2049       if (! arith_reg_or_0_operand (dividend, SImode))
2050         dividend = force_reg (SImode, dividend);
2051       if (! arith_reg_operand (divisor, SImode))
2052         divisor = force_reg (SImode, divisor);
2053       if (flag_pic && Pmode != DImode)
2054         {
2055           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2056           tab_base = gen_datalabel_ref (tab_base);
2057           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2058         }
2059       else
2060         {
2061           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2062           tab_base = gen_datalabel_ref (tab_base);
2063           tab_base = force_reg (DImode, tab_base);
2064         }
2065       if (TARGET_DIVIDE_INV20U)
2066         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2067       else
2068         i2p27 = GEN_INT (0);
2069       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2070         i43 = force_reg (DImode, GEN_INT (43));
2071       else
2072         i43 = GEN_INT (0);
2073       emit_insn (gen_nsbdi (nsb_res,
2074                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2075       emit_insn (gen_ashldi3_media (norm64,
2076                                     gen_rtx_SUBREG (DImode, divisor, 0),
2077                                     nsb_res));
2078       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2079       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2080       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2081                                    inv0, scratch0a, scratch0b,
2082                                    scratch1a, scratch1b));
2083       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2084       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2085                                    scratch2a));
2086       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2087                                    i2p27, i43,
2088                                    scratch3a, scratch3b, scratch3c,
2089                                    scratch2a, scratch2b, scratch3d, scratch3e));
2090       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2091         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2092       else if (TARGET_DIVIDE_INV_FP)
2093         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2094                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2095                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2096                                      gen_reg_rtx (DFmode)));
2097       else
2098         emit_move_insn (operands[0], result);
2099       DONE;
2100     }
2101   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2102     {
2103       operands[1] = force_reg (SImode, operands[1]);
2104       operands[2] = force_reg (SImode, operands[2]);
2105       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2106       DONE;
2107     }
2108   else if (TARGET_SH5)
2109     {
2110       if (TARGET_DIVIDE_CALL2)
2111         {
2112           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2113           tab_base = gen_datalabel_ref (tab_base);
2114           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2115         }
2116       if (TARGET_FPU_ANY && TARGET_SH1)
2117         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2118       else if (TARGET_DIVIDE_CALL2)
2119         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2120       else
2121         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2123       if (TARGET_SHMEDIA)
2124         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2125                 (operands[0], operands[3]));
2126       else if (TARGET_FPU_ANY)
2127         last = gen_divsi3_i4_single (operands[0], operands[3]);
2128       else
2129         last = gen_divsi3_i1 (operands[0], operands[3]);
2130     }
2131   else
2132     {
2133       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2134       last = gen_divsi3_i1 (operands[0], operands[3]);
2135     }
2136   emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2137   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2138   emit_insn (last);
2139   DONE;
2142 ;; operands: scratch, tab_base, tab_ix
2143 ;; These are unspecs because we could generate an indexed addressing mode
2144 ;; even if -m5-32media, where INDEX_REG_CLASS == NO_REGS, and this would
2145 ;; confuse reload.  See PR27117.
2147 (define_insn "divsi_inv_qitable"
2148   [(set (match_operand:DI 0 "register_operand" "=r")
2149         (zero_extend:DI (unspec:QI [(match_operand:DI 1 "register_operand" "r")
2150                                     (match_operand:DI 2 "register_operand" "r")]
2151                          UNSPEC_DIV_INV_TABLE)))]
2152   "TARGET_SHMEDIA"
2153   "@
2154         ldx.ub  %1, %2, %0"
2155   [(set_attr "type" "load_media")
2156    (set_attr "highpart" "user")])
2158 ;; operands: scratch, tab_base, tab_ix
2159 (define_insn "divsi_inv_hitable"
2160   [(set (match_operand:DI 0 "register_operand" "=r")
2161         (sign_extend:DI (unspec:HI [(match_operand:DI 1 "register_operand" "r")
2162                                     (match_operand:DI 2 "register_operand" "r")]
2163                          UNSPEC_DIV_INV_TABLE)))]
2164   "TARGET_SHMEDIA"
2165   "@
2166         ldx.w   %1, %2, %0"
2167   [(set_attr "type" "load_media")
2168    (set_attr "highpart" "user")])
2170 ;; operands: inv0, tab_base, tab_ix, norm32
2171 ;; scratch equiv in sdivsi3_2: r19, r21
2172 (define_expand "divsi_inv_m0"
2173   [(set (match_operand:SI 0 "register_operand" "=r")
2174         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2175                     (match_operand:DI 2 "register_operand" "r")
2176                     (match_operand:SI 3 "register_operand" "r")]
2177          UNSPEC_DIV_INV_M0))
2178    (clobber (match_operand:DI 4 "register_operand" "=r"))
2179    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2180   "TARGET_SHMEDIA"
2181   "
2184 tab_base: r20
2185 tab_ix: r21
2186 norm32: r25
2187  ldx.ub r20, r21, r19 // u0.8
2188  shlli r21, 1, r21
2189  muls.l r25, r19, r19 // s2.38
2190  ldx.w r20, r21, r21  // s2.14
2191  shari r19, 24, r19   // truncate to s2.14
2192  sub r21, r19, r19    // some 11 bit inverse in s1.14
2195   rtx inv0 = operands[0];
2196   rtx tab_base = operands[1];
2197   rtx tab_ix = operands[2];
2198   rtx norm32 = operands[3];
2199   rtx scratch0 = operands[4];
2200   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2201   rtx scratch1 = operands[5];
2203   emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix));
2204   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2205   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2206   emit_insn (gen_divsi_inv_hitable (scratch1, tab_base, scratch1));
2207   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2208   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2209   DONE;
2212 ;; operands: inv1, tab_base, tab_ix, norm32
2213 (define_insn_and_split "divsi_inv_m1"
2214   [(set (match_operand:SI 0 "register_operand" "=r")
2215         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2216                     (match_operand:DI 2 "register_operand" "r")
2217                     (match_operand:SI 3 "register_operand" "r")]
2218          UNSPEC_DIV_INV_M1))
2219    (clobber (match_operand:SI 4 "register_operand" "=r"))
2220    (clobber (match_operand:DI 5 "register_operand" "=r"))
2221    (clobber (match_operand:DI 6 "register_operand" "=r"))
2222    (clobber (match_operand:DI 7 "register_operand" "=r"))
2223    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2224   "TARGET_SHMEDIA"
2225   "#"
2226   "&& !can_create_pseudo_p ()"
2227   [(pc)]
2228   "
2230 /* inv0: r19
2231  muls.l r19, r19, r18 // u0.28
2232  muls.l r25, r18, r18 // s2.58
2233  shlli r19, 45, r0    // multiply by two and convert to s2.58
2234  sub r0, r18, r18
2235  shari r18, 28, r18   // some 18 bit inverse in s1.30
2238   rtx inv1 = operands[0];
2239   rtx tab_base = operands[1];
2240   rtx tab_ix = operands[2];
2241   rtx norm32 = operands[3];
2242   rtx inv0 = operands[4];
2243   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2244   rtx scratch0a = operands[5];
2245   rtx scratch0b = operands[6];
2246   rtx scratch0 = operands[7];
2247   rtx scratch1 = operands[8];
2248   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2250   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2251                                scratch0a, scratch0b));
2252   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2253   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2254   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2255   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2256   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2257   DONE;
2260 ;; operands: inv2, norm32, inv1, i92
2261 (define_insn_and_split "divsi_inv_m2"
2262   [(set (match_operand:SI 0 "register_operand" "=r")
2263         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2264                     (match_operand:SI 2 "register_operand" "r")
2265                     (match_operand:DI 3 "register_operand" "r")]
2266          UNSPEC_DIV_INV_M2))
2267    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2268   "TARGET_SHMEDIA"
2269   "#"
2270   "&& !can_create_pseudo_p ()"
2271   [(pc)]
2272   "
2275  muls.l r18, r25, r0  // s2.60
2276  shari r0, 16, r0     // s-16.44
2277   sub
2278  muls.l r0, r18, r19  // s-16.74
2279  shari r19, 30, r19   // s-16.44
2281   rtx inv2 = operands[0];
2282   rtx norm32 = operands[1];
2283   rtx inv1 = operands[2];
2284   rtx i92 = operands[3];
2285   rtx scratch0 = operands[4];
2286   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2288   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2289   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2290   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2291   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2292   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2293   DONE;
2296 (define_insn_and_split "divsi_inv_m3"
2297   [(set (match_operand:SI 0 "register_operand" "=r")
2298         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2299                     (match_operand:SI 2 "register_operand" "r")
2300                     (match_operand:SI 3 "register_operand" "r")
2301                     (match_operand:DI 4 "register_operand" "r")
2302                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2303                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2304          UNSPEC_DIV_INV_M3))
2305    (clobber (match_operand:DI 7 "register_operand" "=r"))
2306    (clobber (match_operand:DI 8 "register_operand" "=r"))
2307    (clobber (match_operand:DI 9 "register_operand" "=r"))
2308    (clobber (match_operand:DI 10 "register_operand" "=r"))
2309    (clobber (match_operand:SI 11 "register_operand" "=r"))
2310    (clobber (match_operand:SI 12 "register_operand" "=r"))
2311    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2312   "TARGET_SHMEDIA"
2313   "#"
2314   "&& !can_create_pseudo_p ()"
2315   [(pc)]
2316   "
2319   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2320   r0: scratch0  r19: scratch1 r21: scratch2
2322   muls.l r18, r4, r25 // s32.30
2323  muls.l r19, r4, r19  // s15.30
2324  shari r25, 63, r21
2325   shari r19, 14, r19  // s18.-14
2326  sub r25, r19, r0
2327  shard r0, r1, r0
2328  sub r0, r21, r0
2331   rtx result = operands[0];
2332   rtx dividend = operands[1];
2333   rtx inv1 = operands[2];
2334   rtx inv2 = operands[3];
2335   rtx shift = operands[4];
2336   rtx scratch0 = operands[7];
2337   rtx scratch1 = operands[8];
2338   rtx scratch2 = operands[9];
2340   if (satisfies_constraint_N (dividend))
2341     {
2342       emit_move_insn (result, dividend);
2343       DONE;
2344     }
2346   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2347   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2348   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2349   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2350   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2351   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2352   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2353   DONE;
2356 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2357 ;; inv1: tab_base, tab_ix, norm32
2358 ;; inv2: norm32, inv1, i92
2359 (define_insn_and_split "divsi_inv_m1_3"
2360   [(set (match_operand:SI 0 "register_operand" "=r")
2361         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2362                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2363                                 (match_operand:DI 3 "register_operand" "r")
2364                                 (match_operand:SI 4 "register_operand" "r")]
2365                      UNSPEC_DIV_INV_M1)
2366                     (unspec:SI [(match_dup 4)
2367                                 (unspec:SI [(match_dup 2)
2368                                             (match_dup 3)
2369                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2370                                 (match_operand:SI 5 "" "")]
2371                      UNSPEC_DIV_INV_M2)
2372                     (match_operand:DI 6 "register_operand" "r")
2373                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2374                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2375          UNSPEC_DIV_INV_M3))
2376    (clobber (match_operand:DI 9 "register_operand" "=r"))
2377    (clobber (match_operand:DI 10 "register_operand" "=r"))
2378    (clobber (match_operand:DI 11 "register_operand" "=r"))
2379    (clobber (match_operand:DI 12 "register_operand" "=r"))
2380    (clobber (match_operand:SI 13 "register_operand" "=r"))
2381    (clobber (match_operand:SI 14 "register_operand" "=r"))
2382    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2383   "TARGET_SHMEDIA
2384    && (TARGET_DIVIDE_INV_MINLAT
2385        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2386   "#"
2387   "&& !can_create_pseudo_p ()"
2388   [(pc)]
2389   "
2391   rtx result = operands[0];
2392   rtx dividend = operands[1];
2393   rtx tab_base = operands[2];
2394   rtx tab_ix = operands[3];
2395   rtx norm32 = operands[4];
2396   /* rtx i92 = operands[5]; */
2397   rtx shift = operands[6];
2398   rtx i2p27 = operands[7];
2399   rtx i43 = operands[8];
2400   rtx scratch0 = operands[9];
2401   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2402   rtx scratch1 = operands[10];
2403   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2404   rtx scratch2 = operands[11];
2405   rtx scratch3 = operands[12];
2406   rtx scratch4 = operands[13];
2407   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2408   rtx scratch5 = operands[14];
2409   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2410   rtx scratch6 = operands[15];
2412   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2413                                scratch0, scratch1));
2414   /* inv0 == scratch4 */
2415   if (! TARGET_DIVIDE_INV20U)
2416     {
2417       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2418       i2p27 = scratch0;
2419       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2420     }
2421   else
2422     {
2423       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2424       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2425     }
2426   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2427   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2428   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2429   /* inv1 == scratch4 */
2431   if (TARGET_DIVIDE_INV_MINLAT)
2432     {
2433       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2434       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2435       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2436       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2437       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2438       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2439       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2440       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2441       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2442       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2443       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2444     }
2445   else
2446     {
2447       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2448       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2449       emit_insn (gen_nsbdi (scratch6,
2450                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2451       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2452       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2453       emit_insn (gen_divsi_inv20 (scratch2,
2454                                   norm32, scratch4, dividend,
2455                                   scratch6, scratch3, i43,
2456                                   /* scratch0 may be shared with i2p27.  */
2457                                   scratch0, scratch1, scratch5,
2458                                   label, label, i2p27));
2459     }
2460   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2461   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2462   DONE;
2465 (define_insn "divsi_inv20"
2466   [(set (match_operand:DI 0 "register_operand" "=&r")
2467         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2468                     (match_operand:SI 2 "register_operand" "r")
2469                     (match_operand:SI 3 "register_operand" "r")
2470                     (match_operand:DI 4 "register_operand" "r")
2471                     (match_operand:DI 5 "register_operand" "r")
2472                     (match_operand:DI 6 "register_operand" "r")
2473                     (match_operand:DI 12 "register_operand" "r")
2474                     (match_operand 10 "target_operand" "b")
2475                     (match_operand 11 "immediate_operand" "i")]
2476          UNSPEC_DIV_INV20))
2477    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2478    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2479    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2480   "TARGET_SHMEDIA
2481    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2482   "*
2484 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2485              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2486              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2487              %10 label (tr), %11 label (imm)
2489  muls.l inv1, norm32, scratch0  // s2.60
2490   muls.l inv1, dividend, result // s32.30
2491   xor i2p27, result_sign, round_scratch
2492  bge/u dividend_nsb, i43, tr.. (label)
2493  shari scratch0, 16, scratch0   // s-16.44
2494  muls.l sratch0_si, inv1, scratch0 // s-16.74
2495   sub result, round_scratch, result
2496   shari dividend, 14, scratch1   // s19.-14
2497  shari scratch0, 30, scratch0   // s-16.44
2498  muls.l scratch0, scratch1, round_scratch // s15.30
2499 label:
2500  sub result, round_scratch, result */
2502   int likely = TARGET_DIVIDE_INV20L;
2504   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2505   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2506   output_asm_insn (likely
2507                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2508                    : \"bge/u\t%4, %6, %10\", operands);
2509   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2510   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2511   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2512   return (likely
2513           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2514           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2517 (define_insn_and_split "divsi_inv_fp"
2518   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2519         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2520                 (match_operand:SI 2 "register_operand" "rf")))
2521    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2522    (clobber (match_operand:SI 4 "register_operand" "=r"))
2523    (clobber (match_operand:SI 5 "register_operand" "=r"))
2524    (clobber (match_operand:DF 6 "register_operand" "=r"))
2525    (clobber (match_operand:DF 7 "register_operand" "=r"))
2526    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2527   "TARGET_SHMEDIA_FPU"
2528   "#"
2529   "&& (high_life_started || reload_completed)"
2530   [(set (match_dup 0) (match_dup 3))]
2531   ""
2532   [(set_attr "highpart" "must_split")])
2534 ;; If a matching group of divide-by-inverse instructions is in the same
2535 ;; basic block after gcse & loop optimizations, we want to transform them
2536 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2537 (define_insn_and_split "*divsi_inv_fp_combine"
2538   [(set (match_operand:SI 0 "register_operand" "=f")
2539         (div:SI (match_operand:SI 1 "register_operand" "f")
2540                 (match_operand:SI 2 "register_operand" "f")))
2541    (use (unspec:SI [(match_dup 1)
2542                     (match_operand:SI 3 "" "")
2543                     (unspec:SI [(match_operand:SI 4 "" "")
2544                                 (match_dup 3)
2545                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2546                     (match_operand:DI 6 "" "")
2547                     (const_int 0)
2548                     (const_int 0)] UNSPEC_DIV_INV_M3))
2549    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2550    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2551    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2552    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2553    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2554   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && !can_create_pseudo_p ()"
2555   "#"
2556   "&& 1"
2557   [(set (match_dup 9) (float:DF (match_dup 1)))
2558    (set (match_dup 10) (float:DF (match_dup 2)))
2559    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2560    (set (match_dup 8)
2561         (fix:SI (match_dup 11)))
2562    (set (match_dup 0) (match_dup 8))]
2563   "
2565   if (! fp_arith_reg_operand (operands[1], SImode))
2566     {
2567       emit_move_insn (operands[7], operands[1]);
2568       operands[1] = operands[7];
2569     }
2570   if (! fp_arith_reg_operand (operands[2], SImode))
2571     {
2572       emit_move_insn (operands[8], operands[2]);
2573       operands[2] = operands[8];
2574     }
2576   [(set_attr "highpart" "must_split")])
2578 ;; -------------------------------------------------------------------------
2579 ;; Multiplication instructions
2580 ;; -------------------------------------------------------------------------
2582 (define_insn "umulhisi3_i"
2583   [(set (reg:SI MACL_REG)
2584         (mult:SI (zero_extend:SI
2585                   (match_operand:HI 0 "arith_reg_operand" "r"))
2586                  (zero_extend:SI
2587                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2588   "TARGET_SH1"
2589   "mulu.w       %1,%0"
2590   [(set_attr "type" "smpy")])
2592 (define_insn "mulhisi3_i"
2593   [(set (reg:SI MACL_REG)
2594         (mult:SI (sign_extend:SI
2595                   (match_operand:HI 0 "arith_reg_operand" "r"))
2596                  (sign_extend:SI
2597                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2598   "TARGET_SH1"
2599   "muls.w       %1,%0"
2600   [(set_attr "type" "smpy")])
2602 (define_expand "mulhisi3"
2603   [(set (reg:SI MACL_REG)
2604         (mult:SI (sign_extend:SI
2605                   (match_operand:HI 1 "arith_reg_operand" ""))
2606                  (sign_extend:SI
2607                   (match_operand:HI 2 "arith_reg_operand" ""))))
2608    (set (match_operand:SI 0 "arith_reg_operand" "")
2609         (reg:SI MACL_REG))]
2610   "TARGET_SH1"
2611   "
2613   rtx insn, macl;
2615   macl = gen_rtx_REG (SImode, MACL_REG);
2616   start_sequence ();
2617   emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2618   insn = get_insns ();  
2619   end_sequence ();
2620   /* expand_binop can't find a suitable code in umul_widen_optab to
2621      make a REG_EQUAL note from, so make one here.
2622      See also smulsi3_highpart.
2623      ??? Alternatively, we could put this at the calling site of expand_binop,
2624      i.e. expand_expr.  */
2625   /* Use emit_libcall_block for loop invariant code motion and to make
2626      a REG_EQUAL note.  */
2627   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2629   DONE;
2632 (define_expand "umulhisi3"
2633   [(set (reg:SI MACL_REG)
2634         (mult:SI (zero_extend:SI
2635                   (match_operand:HI 1 "arith_reg_operand" ""))
2636                  (zero_extend:SI
2637                   (match_operand:HI 2 "arith_reg_operand" ""))))
2638    (set (match_operand:SI 0 "arith_reg_operand" "")
2639         (reg:SI MACL_REG))]
2640   "TARGET_SH1"
2641   "
2643   rtx insn, macl;
2645   macl = gen_rtx_REG (SImode, MACL_REG);
2646   start_sequence ();
2647   emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2648   insn = get_insns ();  
2649   end_sequence ();
2650   /* expand_binop can't find a suitable code in umul_widen_optab to
2651      make a REG_EQUAL note from, so make one here.
2652      See also smulsi3_highpart.
2653      ??? Alternatively, we could put this at the calling site of expand_binop,
2654      i.e. expand_expr.  */
2655   /* Use emit_libcall_block for loop invariant code motion and to make
2656      a REG_EQUAL note.  */
2657   emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
2659   DONE;
2662 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2663 ;; a call to a routine which clobbers known registers.
2665 (define_insn ""
2666   [(set (match_operand:SI 1 "register_operand" "=z")
2667         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2668    (clobber (reg:SI MACL_REG))
2669    (clobber (reg:SI T_REG))
2670    (clobber (reg:SI PR_REG))
2671    (clobber (reg:SI R3_REG))
2672    (clobber (reg:SI R2_REG))
2673    (clobber (reg:SI R1_REG))
2674    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2675   "TARGET_SH1"
2676   "jsr  @%0%#"
2677   [(set_attr "type" "sfunc")
2678    (set_attr "needs_delay_slot" "yes")])
2680 (define_expand "mulsi3_call"
2681   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2682    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2683    (parallel[(set (match_operand:SI 0 "register_operand" "")
2684                   (mult:SI (reg:SI R4_REG)
2685                            (reg:SI R5_REG)))
2686              (clobber (reg:SI MACL_REG))
2687              (clobber (reg:SI T_REG))
2688              (clobber (reg:SI PR_REG))
2689              (clobber (reg:SI R3_REG))
2690              (clobber (reg:SI R2_REG))
2691              (clobber (reg:SI R1_REG))
2692              (use (match_operand:SI 3 "register_operand" ""))])]
2693   "TARGET_SH1"
2694   "")
2696 (define_insn "mul_r"
2697   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2698         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2699                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2700   "TARGET_SH2A"
2701   "mulr %2,%0"
2702   [(set_attr "type" "dmpy")])
2704 (define_insn "mul_l"
2705   [(set (reg:SI MACL_REG)
2706         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2707                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2708   "TARGET_SH2"
2709   "mul.l        %1,%0"
2710   [(set_attr "type" "dmpy")])
2712 (define_expand "mulsi3"
2713   [(set (reg:SI MACL_REG)
2714         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2715                   (match_operand:SI 2 "arith_reg_operand" "")))
2716    (set (match_operand:SI 0 "arith_reg_operand" "")
2717         (reg:SI MACL_REG))]
2718   "TARGET_SH1"
2719   "
2721   if (!TARGET_SH2)
2722     {
2723       /* The address must be set outside the libcall,
2724          since it goes into a pseudo.  */
2725       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2726       rtx addr = force_reg (SImode, sym);
2727       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2728                                    operands[2], addr);
2729       emit_insn (insns);
2730     }
2731   else
2732     {
2733       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2735       emit_insn (gen_mul_l (operands[1], operands[2]));
2736       /* consec_sets_giv can only recognize the first insn that sets a
2737          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2738          note.  */
2739       emit_insn (gen_movsi_i ((operands[0]), macl));
2740     }
2741   DONE;
2744 (define_insn "mulsidi3_i"
2745   [(set (reg:SI MACH_REG)
2746         (truncate:SI
2747          (lshiftrt:DI
2748           (mult:DI
2749            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2750            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2751           (const_int 32))))
2752    (set (reg:SI MACL_REG)
2753         (mult:SI (match_dup 0)
2754                  (match_dup 1)))]
2755   "TARGET_SH2"
2756   "dmuls.l      %1,%0"
2757   [(set_attr "type" "dmpy")])
2759 (define_expand "mulsidi3"
2760   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2761         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2762                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2763   "TARGET_SH2 || TARGET_SHMEDIA"
2764   "
2766   if (TARGET_SH2)
2767     {
2768        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2769                                         operands[2]));
2770        DONE;
2771     }
2774 (define_insn "mulsidi3_media"
2775   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2776         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2777                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2778   "TARGET_SHMEDIA"
2779   "muls.l       %1, %2, %0"
2780   [(set_attr "type" "dmpy_media")
2781    (set_attr "highpart" "ignore")])
2783 (define_insn "mulsidi3_compact"
2784   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2785         (mult:DI
2786          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2787          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2788    (clobber (reg:SI MACH_REG))
2789    (clobber (reg:SI MACL_REG))]
2790   "TARGET_SH2"
2791   "#")
2793 (define_split
2794   [(set (match_operand:DI 0 "arith_reg_dest" "")
2795         (mult:DI
2796          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2797          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2798    (clobber (reg:SI MACH_REG))
2799    (clobber (reg:SI MACL_REG))]
2800   "TARGET_SH2"
2801   [(const_int 0)]
2802   "
2804   rtx low_dst = gen_lowpart (SImode, operands[0]);
2805   rtx high_dst = gen_highpart (SImode, operands[0]);
2807   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2809   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2810   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2811   /* We need something to tag the possible REG_EQUAL notes on to.  */
2812   emit_move_insn (operands[0], operands[0]);
2813   DONE;
2816 (define_insn "umulsidi3_i"
2817   [(set (reg:SI MACH_REG)
2818         (truncate:SI
2819          (lshiftrt:DI
2820           (mult:DI
2821            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2822            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2823           (const_int 32))))
2824    (set (reg:SI MACL_REG)
2825         (mult:SI (match_dup 0)
2826                  (match_dup 1)))]
2827   "TARGET_SH2"
2828   "dmulu.l      %1,%0"
2829   [(set_attr "type" "dmpy")])
2831 (define_expand "umulsidi3"
2832   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2833         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2834                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2835   "TARGET_SH2 || TARGET_SHMEDIA"
2836   "
2838   if (TARGET_SH2)
2839     {
2840        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2841                                          operands[2]));
2842        DONE;
2843     }
2846 (define_insn "umulsidi3_media"
2847   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2848         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2849                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2850   "TARGET_SHMEDIA"
2851   "mulu.l       %1, %2, %0"
2852   [(set_attr "type" "dmpy_media")
2853    (set_attr "highpart" "ignore")])
2855 (define_insn "umulsidi3_compact"
2856   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2857         (mult:DI
2858          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2859          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2860    (clobber (reg:SI MACH_REG))
2861    (clobber (reg:SI MACL_REG))]
2862   "TARGET_SH2"
2863   "#")
2865 (define_split
2866   [(set (match_operand:DI 0 "arith_reg_dest" "")
2867         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2868                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2869    (clobber (reg:SI MACH_REG))
2870    (clobber (reg:SI MACL_REG))]
2871   "TARGET_SH2"
2872   [(const_int 0)]
2873   "
2875   rtx low_dst = gen_lowpart (SImode, operands[0]);
2876   rtx high_dst = gen_highpart (SImode, operands[0]);
2878   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2880   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2881   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2882   /* We need something to tag the possible REG_EQUAL notes on to.  */
2883   emit_move_insn (operands[0], operands[0]);
2884   DONE;
2887 (define_insn "smulsi3_highpart_i"
2888   [(set (reg:SI MACH_REG)
2889         (truncate:SI
2890          (lshiftrt:DI
2891           (mult:DI
2892            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2893            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2894           (const_int 32))))
2895    (clobber (reg:SI MACL_REG))]
2896   "TARGET_SH2"
2897   "dmuls.l      %1,%0"
2898   [(set_attr "type" "dmpy")])
2900 (define_expand "smulsi3_highpart"
2901   [(parallel
2902     [(set (reg:SI MACH_REG)
2903           (truncate:SI
2904            (lshiftrt:DI
2905             (mult:DI
2906              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2907              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2908             (const_int 32))))
2909     (clobber (reg:SI MACL_REG))])
2910    (set (match_operand:SI 0 "arith_reg_operand" "")
2911         (reg:SI MACH_REG))]
2912   "TARGET_SH2"
2913   "
2915   rtx insn, mach;
2917   mach = gen_rtx_REG (SImode, MACH_REG);
2918   start_sequence ();
2919   emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2920   insn = get_insns ();  
2921   end_sequence ();
2922   /* expand_binop can't find a suitable code in mul_highpart_optab to
2923      make a REG_EQUAL note from, so make one here.
2924      See also {,u}mulhisi.
2925      ??? Alternatively, we could put this at the calling site of expand_binop,
2926      i.e. expand_mult_highpart.  */
2927   /* Use emit_libcall_block for loop invariant code motion and to make
2928      a REG_EQUAL note.  */
2929   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2931   DONE;
2934 (define_insn "umulsi3_highpart_i"
2935   [(set (reg:SI MACH_REG)
2936         (truncate:SI
2937          (lshiftrt:DI
2938           (mult:DI
2939            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2940            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2941           (const_int 32))))
2942    (clobber (reg:SI MACL_REG))]
2943   "TARGET_SH2"
2944   "dmulu.l      %1,%0"
2945   [(set_attr "type" "dmpy")])
2947 (define_expand "umulsi3_highpart"
2948   [(parallel
2949     [(set (reg:SI MACH_REG)
2950           (truncate:SI
2951            (lshiftrt:DI
2952             (mult:DI
2953              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2954              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2955             (const_int 32))))
2956     (clobber (reg:SI MACL_REG))])
2957    (set (match_operand:SI 0 "arith_reg_operand" "")
2958         (reg:SI MACH_REG))]
2959   "TARGET_SH2"
2960   "
2962   rtx insn, mach;
2964   mach = gen_rtx_REG (SImode, MACH_REG);
2965   start_sequence ();
2966   emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2967   insn = get_insns ();  
2968   end_sequence ();
2969   /* Use emit_libcall_block for loop invariant code motion and to make
2970      a REG_EQUAL note.  */
2971   emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
2973   DONE;
2976 (define_insn_and_split "muldi3"
2977   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2978         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2979                  (match_operand:DI 2 "arith_reg_operand" "r")))
2980    (clobber (match_scratch:DI 3 "=&r"))
2981    (clobber (match_scratch:DI 4 "=r"))]
2982   "TARGET_SHMEDIA"
2983   "#"
2984   "reload_completed"
2985   [(const_int 0)]
2986   "
2988   rtx op3_v2si, op2_v2si;
2990   op3_v2si = operands[3];
2991   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2992     {
2993       op3_v2si = XEXP (op3_v2si, 0);
2994       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2995     }
2996   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2997   op2_v2si = operands[2];
2998   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2999     {
3000       op2_v2si = XEXP (op2_v2si, 0);
3001       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
3002     }
3003   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
3004   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
3005   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
3006   emit_insn (gen_umulsidi3_media (operands[4],
3007                                  sh_gen_truncate (SImode, operands[1], 0),
3008                                  sh_gen_truncate (SImode, operands[2], 0)));
3009   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
3010   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
3011   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
3012   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
3013   DONE;
3017 ;; -------------------------------------------------------------------------
3018 ;; Logical operations
3019 ;; -------------------------------------------------------------------------
3021 (define_insn "*andsi3_compact"
3022   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3023         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3024                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3025   "TARGET_SH1"
3026   "and  %2,%0"
3027   [(set_attr "type" "arith")])
3029 (define_insn "*andsi3_media"
3030   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3031         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3032                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3033   "TARGET_SHMEDIA"
3034   "@
3035         and     %1, %2, %0
3036         andi    %1, %2, %0"
3037   [(set_attr "type" "arith_media")])
3039 (define_insn "*andsi3_bclr"
3040   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3041         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3042                 (match_operand:SI 2 "const_int_operand" "Psz")))]
3043   "TARGET_SH2A && satisfies_constraint_Psz (operands[2])"
3044   "bclr\\t%W2,%0"
3045   [(set_attr "type" "arith")])
3047 ;; If the constant is 255, then emit an extu.b instruction instead of an
3048 ;; and, since that will give better code.
3050 (define_expand "andsi3"
3051   [(set (match_operand:SI 0 "arith_reg_operand" "")
3052         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3053                 (match_operand:SI 2 "logical_operand" "")))]
3054   ""
3055   "
3057   if (TARGET_SH1
3058       && CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 255)
3059     {
3060       emit_insn (gen_zero_extendqisi2 (operands[0],
3061                                        gen_lowpart (QImode, operands[1])));
3062       DONE;
3063     }
3066 (define_insn_and_split "anddi3"
3067   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3068         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3069                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3070   "TARGET_SHMEDIA"
3071   "@
3072         and     %1, %2, %0
3073         andi    %1, %2, %0
3074         #"
3075   "reload_completed
3076    && ! logical_operand (operands[2], DImode)"
3077   [(const_int 0)]
3078   "
3080   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3081     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3082   else
3083     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3084   DONE;
3086   [(set_attr "type" "arith_media")])
3088 (define_insn "andcsi3"
3089   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3090         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3091                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3092   "TARGET_SHMEDIA"
3093   "andc %1,%2,%0"
3094   [(set_attr "type" "arith_media")])
3096 (define_insn "andcdi3"
3097   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3098         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3099                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3100   "TARGET_SHMEDIA"
3101   "andc %1,%2,%0"
3102   [(set_attr "type" "arith_media")])
3104 (define_expand "iorsi3"
3105   [(set (match_operand:SI 0 "arith_reg_operand" "")
3106         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3107                 (match_operand:SI 2 "logical_operand" "")))]
3108   ""
3109   "")
3111 (define_insn "*iorsi3_compact"
3112   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3113         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3114                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3115   "TARGET_SH1
3116    && !(TARGET_SH2A && satisfies_constraint_Pso (operands[2]))"
3117   "or   %2,%0"
3118   [(set_attr "type" "arith")])
3120 (define_insn "*iorsi3_media"
3121   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3122         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3123                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3124   "TARGET_SHMEDIA"
3125   "@
3126         or      %1, %2, %0
3127         ori     %1, %2, %0"
3128   [(set_attr "type" "arith_media")])
3130 (define_insn "*iorsi3_bset"
3131   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3132         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0")
3133         (match_operand:SI 2 "const_int_operand" "Pso")))]
3134   "TARGET_SH2A && satisfies_constraint_Pso (operands[2])"
3135   "bset\\t%V2,%0"
3136   [(set_attr "type" "arith")])
3138 (define_insn "iordi3"
3139   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3140         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3141                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3142   "TARGET_SHMEDIA"
3143   "@
3144         or      %1, %2, %0
3145         ori     %1, %2, %0"
3146   [(set_attr "type" "arith_media")])
3148 (define_insn_and_split "*logical_sidi3"
3149   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3150         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3151                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3152                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3153   "TARGET_SHMEDIA"
3154   "#"
3155   "&& reload_completed"
3156   [(set (match_dup 0) (match_dup 3))]
3157   "
3159   operands[3]
3160     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3161                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3162                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3165 (define_insn_and_split "*logical_sidisi3"
3166   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3167         (truncate:SI (sign_extend:DI
3168                         (match_operator:SI 3 "logical_operator"
3169                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3170                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3171   "TARGET_SHMEDIA"
3172   "#"
3173   "&& 1"
3174   [(set (match_dup 0) (match_dup 3))])
3176 (define_insn_and_split "*logical_sidi3_2"
3177   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3178         (sign_extend:DI (truncate:SI (sign_extend:DI
3179                         (match_operator:SI 3 "logical_operator"
3180                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3181                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3182   "TARGET_SHMEDIA"
3183   "#"
3184   "&& 1"
3185   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3187 (define_expand "xorsi3"
3188   [(set (match_operand:SI 0 "arith_reg_operand" "")
3189         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3190                 (match_operand:SI 2 "xor_operand" "")))]
3191   ""
3192   "")
3194 (define_insn "*xorsi3_compact"
3195   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3196         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3197                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3198   "TARGET_SH1"
3199   "xor  %2,%0"
3200   [(set_attr "type" "arith")])
3202 (define_insn "*xorsi3_media"
3203   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3204         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3205                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3206   "TARGET_SHMEDIA"
3207   "@
3208         xor     %1, %2, %0
3209         xori    %1, %2, %0"
3210   [(set_attr "type" "arith_media")])
3212 ;; Store the complements of the T bit in a register.
3213 (define_insn "xorsi3_movrt"
3214   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3215         (xor:SI (reg:SI T_REG)
3216                 (const_int 1)))]
3217   "TARGET_SH2A"
3218   "movrt\\t%0"
3219   [(set_attr "type" "arith")])
3221 (define_insn "xordi3"
3222   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3223         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3224                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3225   "TARGET_SHMEDIA"
3226   "@
3227         xor     %1, %2, %0
3228         xori    %1, %2, %0"
3229   [(set_attr "type" "arith_media")])
3231 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3232 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3233 (define_split
3234   [(set (match_operand:DI 0 "arith_reg_dest" "")
3235         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3236                           [(match_operand 1 "any_register_operand" "")
3237                            (match_operand 2 "any_register_operand" "")])))]
3238   "TARGET_SHMEDIA"
3239   [(set (match_dup 5) (match_dup 4))
3240    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3243   enum machine_mode inmode = GET_MODE (operands[1]);
3244   int offset = 0;
3246   if (GET_CODE (operands[0]) == SUBREG)
3247     {
3248       offset = SUBREG_BYTE (operands[0]);
3249       operands[0] = SUBREG_REG (operands[0]);
3250     }
3251   gcc_assert (REG_P (operands[0]));
3252   if (! TARGET_LITTLE_ENDIAN)
3253     offset += 8 - GET_MODE_SIZE (inmode);
3254   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3257 ;; -------------------------------------------------------------------------
3258 ;; Shifts and rotates
3259 ;; -------------------------------------------------------------------------
3261 (define_expand "rotldi3"
3262   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3263         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3264                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3265   "TARGET_SHMEDIA"
3266   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3268 (define_insn "rotldi3_mextr"
3269   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3270         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3271                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3272   "TARGET_SHMEDIA"
3273   "*
3275   static char templ[16];
3277   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3278            8 - (int) (INTVAL (operands[2]) >> 3));
3279   return templ;
3281   [(set_attr "type" "arith_media")])
3283 (define_expand "rotrdi3"
3284   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3285         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3286                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3287   "TARGET_SHMEDIA"
3288   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3290 (define_insn "rotrdi3_mextr"
3291   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3292         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3293                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3294   "TARGET_SHMEDIA"
3295   "*
3297   static char templ[16];
3299   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3300   return templ;
3302   [(set_attr "type" "arith_media")])
3304 (define_split
3305   [(set (match_operand:DI 0 "arith_reg_dest" "")
3306         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3307                                          "ua_address_operand" "")))
3308                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3309                            (const_int 8))))
3310    (clobber (match_operand:DI 3 "register_operand" ""))]
3311   "TARGET_SHMEDIA"
3312   [(match_dup 4) (match_dup 5)]
3313   "
3315   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3316                  (operands[3], operands[1]));
3317   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3318                               GEN_INT (56), GEN_INT (8));
3321 (define_insn "rotlsi3_1"
3322   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3323         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3324                    (const_int 1)))
3325    (set (reg:SI T_REG)
3326         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3327   "TARGET_SH1"
3328   "rotl %0"
3329   [(set_attr "type" "arith")])
3331 (define_insn "rotlsi3_31"
3332   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3333         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3334                    (const_int 31)))
3335    (clobber (reg:SI T_REG))]
3336   "TARGET_SH1"
3337   "rotr %0"
3338   [(set_attr "type" "arith")])
3340 (define_insn "rotlsi3_16"
3341   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3342         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3343                    (const_int 16)))]
3344   "TARGET_SH1"
3345   "swap.w       %1,%0"
3346   [(set_attr "type" "arith")])
3348 (define_expand "rotlsi3"
3349   [(set (match_operand:SI 0 "arith_reg_dest" "")
3350         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3351                    (match_operand:SI 2 "immediate_operand" "")))]
3352   "TARGET_SH1"
3353   "
3355   static const char rot_tab[] = {
3356     000, 000, 000, 000, 000, 000, 010, 001,
3357     001, 001, 011, 013, 003, 003, 003, 003,
3358     003, 003, 003, 003, 003, 013, 012, 002,
3359     002, 002, 010, 000, 000, 000, 000, 000,
3360   };
3362   int count, choice;
3364   if (!CONST_INT_P (operands[2]))
3365     FAIL;
3366   count = INTVAL (operands[2]);
3367   choice = rot_tab[count];
3368   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3369     FAIL;
3370   choice &= 7;
3371   switch (choice)
3372     {
3373     case 0:
3374       emit_move_insn (operands[0], operands[1]);
3375       count -= (count & 16) * 2;
3376       break;
3377     case 3:
3378      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3379      count -= 16;
3380      break;
3381     case 1:
3382     case 2:
3383       {
3384         rtx parts[2];
3385         parts[0] = gen_reg_rtx (SImode);
3386         parts[1] = gen_reg_rtx (SImode);
3387         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3388         emit_move_insn (parts[choice-1], operands[1]);
3389         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3390         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3391         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3392         count = (count & ~16) - 8;
3393       }
3394     }
3396   for (; count > 0; count--)
3397     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3398   for (; count < 0; count++)
3399     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3401   DONE;
3404 (define_insn "*rotlhi3_8"
3405   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3406         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3407                    (const_int 8)))]
3408   "TARGET_SH1"
3409   "swap.b       %1,%0"
3410   [(set_attr "type" "arith")])
3412 (define_expand "rotlhi3"
3413   [(set (match_operand:HI 0 "arith_reg_operand" "")
3414         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3415                    (match_operand:HI 2 "immediate_operand" "")))]
3416   "TARGET_SH1"
3417   "
3419   if (!CONST_INT_P (operands[2]) || INTVAL (operands[2]) != 8)
3420     FAIL;
3424 ;; shift left
3426 (define_insn "ashlsi3_sh2a"
3427   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3428         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3429                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3430   "TARGET_SH2A"
3431   "shad %2,%0"
3432   [(set_attr "type" "arith")
3433    (set_attr "length" "4")])
3435 ;; This pattern is used by init_expmed for computing the costs of shift
3436 ;; insns.
3438 (define_insn_and_split "ashlsi3_std"
3439   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3440         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3441                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3442    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3443   "TARGET_SH3
3444    || (TARGET_SH1 && satisfies_constraint_P27 (operands[2]))"
3445   "@
3446    shld %2,%0
3447    add  %0,%0
3448    shll%O2      %0
3449    #"
3450   "TARGET_SH3
3451    && reload_completed
3452    && CONST_INT_P (operands[2])
3453    && ! satisfies_constraint_P27 (operands[2])"
3454   [(set (match_dup 3) (match_dup 2))
3455    (parallel
3456     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3457      (clobber (match_dup 4))])]
3458   "operands[4] = gen_rtx_SCRATCH (SImode);"
3459   [(set_attr "length" "*,*,*,4")
3460    (set_attr "type" "dyn_shift,arith,arith,arith")])
3462 (define_insn "ashlhi3_k"
3463   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3464         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3465                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3466   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])"
3467   "@
3468         add     %0,%0
3469         shll%O2 %0"
3470   [(set_attr "type" "arith")])
3472 (define_insn "ashlsi3_n"
3473   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3474         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3475                    (match_operand:SI 2 "const_int_operand" "n")))
3476    (clobber (reg:SI T_REG))]
3477   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3478   "#"
3479   [(set (attr "length")
3480         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3481                (const_string "2")
3482                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3483                (const_string "4")
3484                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3485                (const_string "6")]
3486               (const_string "8")))
3487    (set_attr "type" "arith")])
3489 (define_split
3490   [(set (match_operand:SI 0 "arith_reg_dest" "")
3491         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3492                    (match_operand:SI 2 "const_int_operand" "")))
3493    (clobber (reg:SI T_REG))]
3494   "TARGET_SH1 && reload_completed"
3495   [(use (reg:SI R0_REG))]
3496   "
3498   gen_shifty_op (ASHIFT, operands);
3499   DONE;
3502 (define_insn "ashlsi3_media"
3503   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3504         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3505                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3506   "TARGET_SHMEDIA"
3507   "@
3508         shlld.l %1, %2, %0
3509         shlli.l %1, %2, %0"
3510   [(set_attr "type" "arith_media")
3511    (set_attr "highpart" "ignore")])
3513 (define_expand "ashlsi3"
3514   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3515                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3516                               (match_operand:SI 2 "nonmemory_operand" "")))
3517               (clobber (reg:SI T_REG))])]
3518   ""
3519   "
3521   if (TARGET_SHMEDIA)
3522     {
3523       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3524       DONE;
3525     }
3526   if (CONST_INT_P (operands[2])
3527       && sh_dynamicalize_shift_p (operands[2]))
3528     operands[2] = force_reg (SImode, operands[2]);
3529   if (TARGET_SH3)
3530     {
3531       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3532       DONE;
3533     }
3534   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3535     FAIL;
3538 (define_insn "*ashlhi3_n"
3539   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3540         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3541                    (match_operand:HI 2 "const_int_operand" "n")))
3542    (clobber (reg:SI T_REG))]
3543   "TARGET_SH1"
3544   "#"
3545   [(set (attr "length")
3546         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3547                (const_string "2")
3548                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3549                (const_string "4")]
3550               (const_string "6")))
3551    (set_attr "type" "arith")])
3553 (define_expand "ashlhi3"
3554   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3555                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3556                               (match_operand:SI 2 "nonmemory_operand" "")))
3557               (clobber (reg:SI T_REG))])]
3558   "TARGET_SH1"
3559   "
3561   if (!CONST_INT_P (operands[2]))
3562     FAIL;
3563   /* It may be possible to call gen_ashlhi3 directly with more generic
3564      operands.  Make sure operands[1] is a HImode register here.  */
3565   if (!arith_reg_operand (operands[1], HImode))
3566     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3569 (define_split
3570   [(set (match_operand:HI 0 "arith_reg_dest" "")
3571         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3572                    (match_operand:HI 2 "const_int_operand" "")))
3573    (clobber (reg:SI T_REG))]
3574   "TARGET_SH1 && reload_completed"
3575   [(use (reg:SI R0_REG))]
3576   "
3578   gen_shifty_hi_op (ASHIFT, operands);
3579   DONE;
3583 ; arithmetic shift right
3586 (define_insn "ashrsi3_sh2a"
3587   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3588         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3589                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3590   "TARGET_SH2A"
3591   "shad %2,%0"
3592   [(set_attr "type" "dyn_shift")
3593    (set_attr "length" "4")])
3595 (define_insn "ashrsi3_k"
3596   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3597         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3598                      (match_operand:SI 2 "const_int_operand" "M")))
3599    (clobber (reg:SI T_REG))]
3600   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3601   "shar %0"
3602   [(set_attr "type" "arith")])
3604 ;; We can't do HImode right shifts correctly unless we start out with an
3605 ;; explicit zero / sign extension; doing that would result in worse overall
3606 ;; code, so just let the machine independent code widen the mode.
3607 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3610 ;; ??? This should be a define expand.
3612 (define_insn "ashrsi2_16"
3613   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3614         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3615                      (const_int 16)))]
3616   "TARGET_SH1"
3617   "#"
3618   [(set_attr "length" "4")])
3620 (define_split
3621   [(set (match_operand:SI 0 "arith_reg_dest" "")
3622         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3623                      (const_int 16)))]
3624   "TARGET_SH1"
3625   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3626    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3627   "operands[2] = gen_lowpart (HImode, operands[0]);")
3629 ;; ??? This should be a define expand.
3631 (define_insn "ashrsi2_31"
3632   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3633         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3634                      (const_int 31)))
3635    (clobber (reg:SI T_REG))]
3636   "TARGET_SH1"
3637   "#"
3638   [(set_attr "length" "4")])
3640 (define_split
3641   [(set (match_operand:SI 0 "arith_reg_dest" "")
3642         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3643                      (const_int 31)))
3644    (clobber (reg:SI T_REG))]
3645   "TARGET_SH1"
3646   [(const_int 0)]
3647   "
3649   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3650   emit_insn (gen_mov_neg_si_t (copy_rtx (operands[0])));
3651   DONE;
3654 (define_peephole2
3655   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3656    (set (reg:SI T_REG)
3657         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3658   "TARGET_SH1
3659    && peep2_reg_dead_p (2, operands[0])
3660    && peep2_reg_dead_p (2, operands[1])"
3661   [(const_int 0)]
3662   "
3664   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3665   DONE;
3668 (define_insn "ashlsi_c"
3669   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3670         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3671    (set (reg:SI T_REG)
3672         (lt:SI (match_dup 1) (const_int 0)))]
3673   "TARGET_SH1"
3674   "shll %0"
3675   [(set_attr "type" "arith")])
3677 (define_insn "*ashlsi_c_void"
3678   [(set (reg:SI T_REG)
3679         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3680    (clobber (match_scratch:SI 1 "=0"))]
3681   "TARGET_SH1 && cse_not_expected"
3682   "shll %0"
3683   [(set_attr "type" "arith")])
3685 (define_insn "ashrsi3_d"
3686   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3687         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3688                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3689   "TARGET_SH3"
3690   "shad %2,%0"
3691   [(set_attr "type" "dyn_shift")])
3693 (define_insn "ashrsi3_n"
3694   [(set (reg:SI R4_REG)
3695         (ashiftrt:SI (reg:SI R4_REG)
3696                      (match_operand:SI 0 "const_int_operand" "i")))
3697    (clobber (reg:SI T_REG))
3698    (clobber (reg:SI PR_REG))
3699    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3700   "TARGET_SH1"
3701   "jsr  @%1%#"
3702   [(set_attr "type" "sfunc")
3703    (set_attr "needs_delay_slot" "yes")])
3705 (define_insn "ashrsi3_media"
3706   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3707         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3708                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3709   "TARGET_SHMEDIA"
3710   "@
3711         shard.l %1, %2, %0
3712         shari.l %1, %2, %0"
3713   [(set_attr "type" "arith_media")
3714    (set_attr "highpart" "ignore")])
3716 (define_expand "ashrsi3"
3717   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3718                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3719                                 (match_operand:SI 2 "nonmemory_operand" "")))
3720               (clobber (reg:SI T_REG))])]
3721   ""
3722   "
3724   if (TARGET_SHMEDIA)
3725     {
3726       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3727       DONE;
3728     }
3729   if (expand_ashiftrt (operands))
3730     DONE;
3731   else
3732     FAIL;
3735 ;; logical shift right
3737 (define_insn "lshrsi3_sh2a"
3738   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3739         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3740                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3741   "TARGET_SH2A"
3742   "shld %2,%0"
3743   [(set_attr "type" "dyn_shift")
3744    (set_attr "length" "4")])
3746 (define_insn "lshrsi3_d"
3747   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3748         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3749                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3750   "TARGET_SH3"
3751   "shld %2,%0"
3752   [(set_attr "type" "dyn_shift")])
3754 ;;  Only the single bit shift clobbers the T bit.
3756 (define_insn "lshrsi3_m"
3757   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3758         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3759                      (match_operand:SI 2 "const_int_operand" "M")))
3760    (clobber (reg:SI T_REG))]
3761   "TARGET_SH1 && satisfies_constraint_M (operands[2])"
3762   "shlr %0"
3763   [(set_attr "type" "arith")])
3765 (define_insn "lshrsi3_k"
3766   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3767         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3768                      (match_operand:SI 2 "const_int_operand" "P27")))]
3769   "TARGET_SH1 && satisfies_constraint_P27 (operands[2])
3770    && ! satisfies_constraint_M (operands[2])"
3771   "shlr%O2      %0"
3772   [(set_attr "type" "arith")])
3774 (define_insn "lshrsi3_n"
3775   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3776         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3777                      (match_operand:SI 2 "const_int_operand" "n")))
3778    (clobber (reg:SI T_REG))]
3779   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3780   "#"
3781   [(set (attr "length")
3782         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3783                (const_string "2")
3784                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3785                (const_string "4")
3786                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3787                (const_string "6")]
3788               (const_string "8")))
3789    (set_attr "type" "arith")])
3791 (define_split
3792   [(set (match_operand:SI 0 "arith_reg_dest" "")
3793         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3794                      (match_operand:SI 2 "const_int_operand" "")))
3795    (clobber (reg:SI T_REG))]
3796   "TARGET_SH1 && reload_completed"
3797   [(use (reg:SI R0_REG))]
3798   "
3800   gen_shifty_op (LSHIFTRT, operands);
3801   DONE;
3804 (define_insn "lshrsi3_media"
3805   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3806         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3807                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3808   "TARGET_SHMEDIA"
3809   "@
3810         shlrd.l %1, %2, %0
3811         shlri.l %1, %2, %0"
3812   [(set_attr "type" "arith_media")
3813    (set_attr "highpart" "ignore")])
3815 (define_expand "lshrsi3"
3816   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3817                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3818                                 (match_operand:SI 2 "nonmemory_operand" "")))
3819               (clobber (reg:SI T_REG))])]
3820   ""
3821   "
3823   if (TARGET_SHMEDIA)
3824     {
3825       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3826       DONE;
3827     }
3828   if (CONST_INT_P (operands[2])
3829       && sh_dynamicalize_shift_p (operands[2]))
3830     operands[2] = force_reg (SImode, operands[2]);
3831   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3832     {
3833       rtx count = copy_to_mode_reg (SImode, operands[2]);
3834       emit_insn (gen_negsi2 (count, count));
3835       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3836       DONE;
3837     }
3838   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3839     FAIL;
3842 ;; ??? This should be a define expand.
3844 (define_insn "ashldi3_k"
3845   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3846         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3847                    (const_int 1)))
3848    (clobber (reg:SI T_REG))]
3849   "TARGET_SH1"
3850   "shll %R0\;rotcl      %S0"
3851   [(set_attr "length" "4")
3852    (set_attr "type" "arith")])
3854 ;; Expander for DImode shift left with SImode operations.
3856 (define_expand "ashldi3_std"
3857   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3858         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3859                    (match_operand:DI 2 "const_int_operand" "n")))]
3860   "TARGET_SH1 && INTVAL (operands[2]) < 32"
3861   "
3863   int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
3864   int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
3865   rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
3866   rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
3867   rtx dst = gen_reg_rtx (DImode);
3868   rtx low_dst = operand_subword (dst, low_word, 1, DImode);
3869   rtx high_dst = operand_subword (dst, high_word, 1, DImode);
3870   rtx tmp0, tmp1;
3872   tmp0 = gen_reg_rtx (SImode);
3873   tmp1 = gen_reg_rtx (SImode);
3874   emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2]))));
3875   emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2]));  
3876   emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2]));  
3877   emit_insn (gen_iorsi3 (high_dst, tmp0, tmp1));
3878   emit_move_insn (operands[0], dst);
3879   DONE;
3882 (define_insn "ashldi3_media"
3883   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3884         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3885                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3886   "TARGET_SHMEDIA"
3887   "@
3888         shlld   %1, %2, %0
3889         shlli   %1, %2, %0"
3890   [(set_attr "type" "arith_media")])
3892 (define_insn "*ashldisi3_media"
3893   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3894         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3895                    (match_operand:DI 2 "const_int_operand" "n")))]
3896   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3897   "shlli.l      %1, %2, %0"
3898   [(set_attr "type" "arith_media")
3899    (set_attr "highpart" "ignore")])
3901 (define_expand "ashldi3"
3902   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3903                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3904                               (match_operand:DI 2 "immediate_operand" "")))
3905               (clobber (reg:SI T_REG))])]
3906   ""
3907   "
3909   if (TARGET_SHMEDIA)
3910     {
3911       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3912       DONE;
3913     }
3914   if (CONST_INT_P (operands[2])
3915       && INTVAL (operands[2]) == 1)
3916     {
3917       emit_insn (gen_ashldi3_k (operands[0], operands[1]));
3918       DONE;
3919     }
3920   else if (CONST_INT_P (operands[2])
3921       && INTVAL (operands[2]) < 32)
3922     {
3923       emit_insn (gen_ashldi3_std (operands[0], operands[1], operands[2]));
3924       DONE;
3925     }
3926   else
3927     FAIL;
3930 ;; ??? This should be a define expand.
3932 (define_insn "lshrdi3_k"
3933   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3934         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3935                      (const_int 1)))
3936    (clobber (reg:SI T_REG))]
3937   "TARGET_SH1"
3938   "shlr %S0\;rotcr      %R0"
3939   [(set_attr "length" "4")
3940    (set_attr "type" "arith")])
3942 (define_insn "lshrdi3_media"
3943   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3944         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3945                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3946   "TARGET_SHMEDIA
3947    && (arith_reg_dest (operands[0], DImode)
3948        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 32))"
3949   "@
3950         shlrd   %1, %2, %0
3951         shlri   %1, %2, %0"
3952   [(set_attr "type" "arith_media")])
3954 (define_insn "*lshrdisi3_media"
3955   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3956         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3957                      (match_operand:DI 2 "const_int_operand" "n")))]
3958   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3959   "shlri.l      %1, %2, %0"
3960   [(set_attr "type" "arith_media")
3961    (set_attr "highpart" "ignore")])
3963 (define_expand "lshrdi3"
3964   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3965                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3966                                (match_operand:DI 2 "immediate_operand" "")))
3967              (clobber (reg:SI T_REG))])]
3968   ""
3969   "
3971   if (TARGET_SHMEDIA)
3972     {
3973       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3974       DONE;
3975     }
3976   if (!CONST_INT_P (operands[2])
3977       || INTVAL (operands[2]) != 1)
3978     FAIL;
3981 ;; ??? This should be a define expand.
3983 (define_insn "ashrdi3_k"
3984   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3985         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3986                      (const_int 1)))
3987    (clobber (reg:SI T_REG))]
3988   "TARGET_SH1"
3989   "shar %S0\;rotcr      %R0"
3990   [(set_attr "length" "4")
3991    (set_attr "type" "arith")])
3993 (define_insn "ashrdi3_media"
3994   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3995         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3996                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3997   "TARGET_SHMEDIA
3998    && (arith_reg_dest (operands[0], DImode)
3999        || (CONST_INT_P (operands[2]) && INTVAL (operands[2]) >= 32))"
4000   "@
4001         shard   %1, %2, %0
4002         shari   %1, %2, %0"
4003   [(set_attr "type" "arith_media")])
4005 (define_insn "*ashrdisi3_media"
4006   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
4007         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4008                      (match_operand:DI 2 "const_int_operand" "n")))]
4009   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
4010   "shari.l      %1, %2, %0"
4011   [(set_attr "type" "arith_media")
4012    (set_attr "highpart" "ignore")])
4014 (define_insn "ashrdisi3_media_high"
4015   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4016         (truncate:SI
4017            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
4018                         (match_operand:DI 2 "const_int_operand" "n"))))]
4019   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
4020   "shari        %1, %2, %0"
4021   [(set_attr "type" "arith_media")])
4023 (define_insn "ashrdisi3_media_opaque"
4024   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4025         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
4026                     (match_operand:DI 2 "const_int_operand" "n")]
4027          UNSPEC_ASHIFTRT))]
4028   "TARGET_SHMEDIA"
4029   "shari        %1, %2, %0"
4030   [(set_attr "type" "arith_media")])
4032 (define_expand "ashrdi3"
4033   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
4034                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
4035                                 (match_operand:DI 2 "immediate_operand" "")))
4036               (clobber (reg:SI T_REG))])]
4037   ""
4038   "
4040   if (TARGET_SHMEDIA)
4041     {
4042       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
4043       DONE;
4044     }
4045   if (!CONST_INT_P (operands[2])
4046       || INTVAL (operands[2]) != 1)
4047     FAIL;
4050 ;; combined left/right shift
4052 (define_split
4053   [(set (match_operand:SI 0 "register_operand" "")
4054         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4055                            (match_operand:SI 2 "const_int_operand" ""))
4056                 (match_operand:SI 3 "const_int_operand" "")))]
4057   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4058   [(use (reg:SI R0_REG))]
4059   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4060    DONE;")
4062 (define_split
4063   [(set (match_operand:SI 0 "register_operand" "")
4064         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
4065                            (match_operand:SI 2 "const_int_operand" ""))
4066                 (match_operand:SI 3 "const_int_operand" "")))
4067    (clobber (reg:SI T_REG))]
4068   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
4069   [(use (reg:SI R0_REG))]
4070   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
4071    DONE;")
4073 (define_insn ""
4074   [(set (match_operand:SI 0 "register_operand" "=r")
4075         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4076                            (match_operand:SI 2 "const_int_operand" "n"))
4077                 (match_operand:SI 3 "const_int_operand" "n")))
4078    (clobber (reg:SI T_REG))]
4079   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
4080  "#"
4081   [(set (attr "length")
4082         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4083                (const_string "4")
4084                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4085                (const_string "6")
4086                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4087                (const_string "8")
4088                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
4089                (const_string "10")
4090                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
4091                (const_string "12")
4092                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
4093                (const_string "14")
4094                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4095                (const_string "16")]
4096               (const_string "18")))
4097    (set_attr "type" "arith")])
4099 (define_insn ""
4100   [(set (match_operand:SI 0 "register_operand" "=z")
4101         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4102                            (match_operand:SI 2 "const_int_operand" "n"))
4103                 (match_operand:SI 3 "const_int_operand" "n")))
4104    (clobber (reg:SI T_REG))]
4105   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4106  "#"
4107   [(set (attr "length")
4108         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4109                (const_string "4")
4110                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4111                (const_string "6")
4112                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4113                (const_string "8")]
4114               (const_string "10")))
4115    (set_attr "type" "arith")])
4117 ;; shift left / and combination with a scratch register: The combine pass
4118 ;; does not accept the individual instructions, even though they are
4119 ;; cheap.  But it needs a precise description so that it is usable after
4120 ;; reload.
4121 (define_insn "and_shl_scratch"
4122   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4123         (lshiftrt:SI
4124          (ashift:SI
4125           (and:SI
4126            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4127                         (match_operand:SI 2 "const_int_operand" "N,n"))
4128            (match_operand:SI 3 "" "0,r"))
4129           (match_operand:SI 4 "const_int_operand" "n,n"))
4130          (match_operand:SI 5 "const_int_operand" "n,n")))
4131    (clobber (reg:SI T_REG))]
4132   "TARGET_SH1"
4133   "#"
4134   [(set (attr "length")
4135         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4136                (const_string "4")
4137                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4138                (const_string "6")
4139                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4140                (const_string "8")
4141                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4142                (const_string "10")]
4143               (const_string "12")))
4144    (set_attr "type" "arith")])
4146 (define_split
4147   [(set (match_operand:SI 0 "register_operand" "")
4148         (lshiftrt:SI
4149          (ashift:SI
4150           (and:SI
4151            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4152                         (match_operand:SI 2 "const_int_operand" ""))
4153            (match_operand:SI 3 "register_operand" ""))
4154           (match_operand:SI 4 "const_int_operand" ""))
4155          (match_operand:SI 5 "const_int_operand" "")))
4156    (clobber (reg:SI T_REG))]
4157   "TARGET_SH1"
4158   [(use (reg:SI R0_REG))]
4159   "
4161   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4163   if (INTVAL (operands[2]))
4164     {
4165       gen_shifty_op (LSHIFTRT, operands);
4166     }
4167   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4168   operands[2] = operands[4];
4169   gen_shifty_op (ASHIFT, operands);
4170   if (INTVAL (operands[5]))
4171     {
4172       operands[2] = operands[5];
4173       gen_shifty_op (LSHIFTRT, operands);
4174     }
4175   DONE;
4178 ;; signed left/right shift combination.
4179 (define_split
4180   [(set (match_operand:SI 0 "register_operand" "")
4181         (sign_extract:SI
4182          (ashift:SI (match_operand:SI 1 "register_operand" "")
4183                     (match_operand:SI 2 "const_int_operand" ""))
4184          (match_operand:SI 3 "const_int_operand" "")
4185          (const_int 0)))
4186    (clobber (reg:SI T_REG))]
4187   "TARGET_SH1"
4188   [(use (reg:SI R0_REG))]
4189   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4190    DONE;")
4192 (define_insn "shl_sext_ext"
4193   [(set (match_operand:SI 0 "register_operand" "=r")
4194         (sign_extract:SI
4195          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4196                     (match_operand:SI 2 "const_int_operand" "n"))
4197          (match_operand:SI 3 "const_int_operand" "n")
4198          (const_int 0)))
4199    (clobber (reg:SI T_REG))]
4200   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4201   "#"
4202   [(set (attr "length")
4203         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4204                (const_string "2")
4205                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4206                (const_string "4")
4207                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4208                (const_string "6")
4209                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4210                (const_string "8")
4211                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4212                (const_string "10")
4213                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4214                (const_string "12")
4215                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4216                (const_string "14")
4217                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4218                (const_string "16")]
4219               (const_string "18")))
4220     (set_attr "type" "arith")])
4222 (define_insn "shl_sext_sub"
4223   [(set (match_operand:SI 0 "register_operand" "=z")
4224         (sign_extract:SI
4225          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4226                     (match_operand:SI 2 "const_int_operand" "n"))
4227          (match_operand:SI 3 "const_int_operand" "n")
4228          (const_int 0)))
4229    (clobber (reg:SI T_REG))]
4230   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4231   "#"
4232   [(set (attr "length")
4233         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4234                (const_string "6")
4235                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4236                (const_string "8")
4237                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4238                (const_string "10")
4239                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4240                (const_string "12")]
4241               (const_string "14")))
4242     (set_attr "type" "arith")])
4244 ;; These patterns are found in expansions of DImode shifts by 16, and
4245 ;; allow the xtrct instruction to be generated from C source.
4247 (define_insn "xtrct_left"
4248   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4249         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4250                            (const_int 16))
4251                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4252                              (const_int 16))))]
4253   "TARGET_SH1"
4254   "xtrct        %1,%0"
4255   [(set_attr "type" "arith")])
4257 (define_insn "xtrct_right"
4258   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4259         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4260                              (const_int 16))
4261                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4262                            (const_int 16))))]
4263   "TARGET_SH1"
4264   "xtrct        %2,%0"
4265   [(set_attr "type" "arith")])
4267 ;; -------------------------------------------------------------------------
4268 ;; Unary arithmetic
4269 ;; -------------------------------------------------------------------------
4271 (define_insn "negc"
4272   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4273         (neg:SI (plus:SI (reg:SI T_REG)
4274                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4275    (set (reg:SI T_REG)
4276         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4277                (const_int 0)))]
4278   "TARGET_SH1"
4279   "negc %1,%0"
4280   [(set_attr "type" "arith")])
4282 (define_insn "*negdi_media"
4283   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4284         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4285   "TARGET_SHMEDIA"
4286   "sub  r63, %1, %0"
4287   [(set_attr "type" "arith_media")])
4289 (define_expand "negdi2"
4290   [(set (match_operand:DI 0 "arith_reg_operand" "")
4291         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4292   ""
4293   "
4295   if (TARGET_SH1)
4296     {
4297       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4298       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4300       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4301       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4303       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4304       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4306       emit_insn (gen_clrt ());
4307       emit_insn (gen_negc (low_dst, low_src));
4308       emit_insn (gen_negc (high_dst, high_src));
4309       DONE;
4310     }
4313 (define_insn "negsi2"
4314   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4315         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4316   "TARGET_SH1"
4317   "neg  %1,%0"
4318   [(set_attr "type" "arith")])
4320 (define_insn "one_cmplsi2"
4321   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4322         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4323   "TARGET_SH1"
4324   "not  %1,%0"
4325   [(set_attr "type" "arith")])
4327 (define_expand "one_cmpldi2"
4328   [(set (match_operand:DI 0 "arith_reg_dest" "")
4329         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4330                 (const_int -1)))]
4331   "TARGET_SHMEDIA" "")
4333 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4334    This can be used as some kind of conditional execution, which is useful
4335    for abs.  */
4336 (define_split
4337   [(set (match_operand:SI 0 "arith_reg_dest" "")
4338         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4339                          (match_operand:SI 1 "arith_reg_operand" ""))
4340                  (reg:SI T_REG)))]
4341   "TARGET_HARD_SH4"
4342   [(const_int 0)]
4343   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4344    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4345    DONE;")
4347 (define_insn "cneg"
4348   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4349         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4350                       (match_operand:SI 1 "arith_reg_operand" "0")
4351                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4352   "TARGET_HARD_SH4"
4353   "bf 0f\;neg %2,%0\\n0:"
4354   [(set_attr "type" "arith") ;; poor approximation
4355    (set_attr "length" "4")])
4358 ;; -------------------------------------------------------------------------
4359 ;; Zero extension instructions
4360 ;; -------------------------------------------------------------------------
4362 (define_insn "zero_extendsidi2"
4363   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4364         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4365   "TARGET_SHMEDIA"
4366   "addz.l       %1, r63, %0"
4367   [(set_attr "type" "arith_media")
4368    (set_attr "highpart" "extend")])
4370 (define_insn "zero_extendhidi2"
4371   [(set (match_operand:DI 0 "register_operand" "=r,r")
4372         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4373   "TARGET_SHMEDIA"
4374   "@
4375         #
4376         ld%M1.uw        %m1, %0"
4377   [(set_attr "type" "*,load_media")
4378    (set (attr "highpart")
4379         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4380                (const_string "user")]
4381               (const_string "ignore")))])
4383 (define_split
4384   [(set (match_operand:DI 0 "register_operand" "")
4385         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4386   "TARGET_SHMEDIA && reload_completed"
4387   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4388    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4389   "
4391   if (GET_CODE (operands[1]) == TRUNCATE)
4392     operands[1] = XEXP (operands[1], 0);
4395 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4396 ;; reload the entire truncate expression.
4397 (define_insn_and_split "*loaddi_trunc"
4398   [(set (match_operand 0 "any_register_operand" "=r")
4399         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4400   "TARGET_SHMEDIA && reload_completed"
4401   "#"
4402   "TARGET_SHMEDIA && reload_completed"
4403   [(set (match_dup 0) (match_dup 1))]
4404   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4406 (define_insn "zero_extendqidi2"
4407   [(set (match_operand:DI 0 "register_operand" "=r,r")
4408         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4409   "TARGET_SHMEDIA"
4410   "@
4411         andi    %1, 255, %0
4412         ld%M1.ub        %m1, %0"
4413   [(set_attr "type" "arith_media,load_media")
4414    (set (attr "highpart")
4415         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4416                (const_string "user")]
4417               (const_string "ignore")))])
4419 (define_expand "zero_extendhisi2"
4420   [(set (match_operand:SI 0 "arith_reg_operand" "")
4421         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4422   ""
4423   "
4425   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4426     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4429 (define_insn "*zero_extendhisi2_compact"
4430   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4431         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4432   "TARGET_SH1"
4433   "extu.w       %1,%0"
4434   [(set_attr "type" "arith")])
4436 (define_insn "*zero_extendhisi2_media"
4437   [(set (match_operand:SI 0 "register_operand" "=r,r")
4438         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4439   "TARGET_SHMEDIA"
4440   "@
4441         #
4442         ld%M1.uw        %m1, %0"
4443   [(set_attr "type" "arith_media,load_media")
4444    (set (attr "highpart")
4445         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4446                (const_string "user")]
4447               (const_string "ignore")))])
4449 (define_split
4450   [(set (match_operand:SI 0 "register_operand" "")
4451         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4452   "TARGET_SHMEDIA && reload_completed"
4453   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4454    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4455   "
4457   rtx op1 = operands[1];
4459   if (GET_CODE (op1) == TRUNCATE)
4460     op1 = XEXP (op1, 0);
4461   operands[2]
4462     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4463                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4466 (define_expand "zero_extendqisi2"
4467   [(set (match_operand:SI 0 "arith_reg_operand" "")
4468         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4469   ""
4470   "
4472   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4473     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4476 (define_insn "*zero_extendqisi2_compact"
4477   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4478         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4479   "TARGET_SH1"
4480   "extu.b       %1,%0"
4481   [(set_attr "type" "arith")])
4483 (define_insn "*zero_extendqisi2_media"
4484   [(set (match_operand:SI 0 "register_operand" "=r,r")
4485         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4486   "TARGET_SHMEDIA"
4487   "@
4488         andi    %1, 255, %0
4489         ld%M1.ub        %m1, %0"
4490   [(set_attr "type" "arith_media,load_media")
4491    (set (attr "highpart")
4492         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4493                (const_string "user")]
4494               (const_string "ignore")))])
4496 (define_insn "zero_extendqihi2"
4497   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4498         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4499   "TARGET_SH1"
4500   "extu.b       %1,%0"
4501   [(set_attr "type" "arith")])
4503 ;; -------------------------------------------------------------------------
4504 ;; Sign extension instructions
4505 ;; -------------------------------------------------------------------------
4507 ;; ??? This should be a define expand.
4508 ;; ??? Or perhaps it should be dropped?
4510 ;; convert_move generates good code for SH[1-4].
4511 (define_insn "extendsidi2"
4512   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4513         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4514   "TARGET_SHMEDIA"
4515   "@
4516         add.l   %1, r63, %0
4517         ld%M1.l %m1, %0
4518         fmov.sl %1, %0"
4519   [(set_attr "type" "arith_media,load_media,fpconv_media")
4520    (set (attr "highpart")
4521         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4522                (const_string "user")]
4523               (const_string "extend")))])
4525 (define_insn "extendhidi2"
4526   [(set (match_operand:DI 0 "register_operand" "=r,r")
4527         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4528   "TARGET_SHMEDIA"
4529   "@
4530         #
4531         ld%M1.w %m1, %0"
4532   [(set_attr "type" "*,load_media")
4533    (set (attr "highpart")
4534         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4535                (const_string "user")]
4536               (const_string "ignore")))])
4538 (define_split
4539   [(set (match_operand:DI 0 "register_operand" "")
4540         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4541   "TARGET_SHMEDIA && reload_completed"
4542   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4543    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4544   "
4546   if (GET_CODE (operands[1]) == TRUNCATE)
4547     operands[1] = XEXP (operands[1], 0);
4550 (define_insn "extendqidi2"
4551   [(set (match_operand:DI 0 "register_operand" "=r,r")
4552         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4553   "TARGET_SHMEDIA"
4554   "@
4555         #
4556         ld%M1.b %m1, %0"
4557   [(set_attr "type" "*,load_media")
4558    (set (attr "highpart")
4559         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4560                (const_string "user")]
4561               (const_string "ignore")))])
4563 (define_split
4564   [(set (match_operand:DI 0 "register_operand" "")
4565         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4566   "TARGET_SHMEDIA && reload_completed"
4567   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4568    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4569   "
4571   if (GET_CODE (operands[1]) == TRUNCATE)
4572     operands[1] = XEXP (operands[1], 0);
4575 (define_expand "extendhisi2"
4576   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4577         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4578   ""
4579   "")
4581 (define_insn "*extendhisi2_compact"
4582   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4583         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4584   "TARGET_SH1"
4585   "@
4586         exts.w  %1,%0
4587         mov.w   %1,%0"
4588   [(set_attr "type" "arith,load")])
4590 (define_insn "*extendhisi2_media"
4591   [(set (match_operand:SI 0 "register_operand" "=r,r")
4592         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4593   "TARGET_SHMEDIA"
4594   "@
4595         #
4596         ld%M1.w %m1, %0"
4597   [(set_attr "type" "arith_media,load_media")
4598    (set (attr "highpart")
4599         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4600                (const_string "user")]
4601               (const_string "ignore")))])
4603 (define_split
4604   [(set (match_operand:SI 0 "register_operand" "")
4605         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4606   "TARGET_SHMEDIA && reload_completed"
4607   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4608    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4609   "
4611   rtx op1 = operands[1];
4612   if (GET_CODE (op1) == TRUNCATE)
4613     op1 = XEXP (op1, 0);
4614   operands[2]
4615     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4616                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4619 (define_expand "extendqisi2"
4620   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4621         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4622   ""
4623   "")
4625 (define_insn "*extendqisi2_compact"
4626   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4627         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4628   "TARGET_SH1"
4629   "@
4630         exts.b  %1,%0
4631         mov.b   %1,%0"
4632   [(set_attr "type" "arith,load")
4633    (set_attr_alternative "length"
4634      [(const_int 2)
4635        (if_then_else
4636         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4637         (const_int 4) (const_int 2))])])
4639 (define_insn "*extendqisi2_media"
4640   [(set (match_operand:SI 0 "register_operand" "=r,r")
4641         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4642   "TARGET_SHMEDIA"
4643   "@
4644         #
4645         ld%M1.b %m1, %0"
4646   [(set_attr "type" "arith_media,load_media")
4647    (set (attr "highpart")
4648         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4649                (const_string "user")]
4650               (const_string "ignore")))])
4652 (define_split
4653   [(set (match_operand:SI 0 "register_operand" "")
4654         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4655   "TARGET_SHMEDIA && reload_completed"
4656   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4657    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4658    "
4660   rtx op1 = operands[1];
4661   if (GET_CODE (op1) == TRUNCATE)
4662     op1 = XEXP (op1, 0);
4663   operands[2]
4664     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4665                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4668 (define_insn "extendqihi2"
4669   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4670         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4671   "TARGET_SH1"
4672   "@
4673         exts.b  %1,%0
4674         mov.b   %1,%0"
4675   [(set_attr "type" "arith,load")
4676    (set_attr_alternative "length"
4677      [(const_int 2)
4678        (if_then_else
4679         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4680         (const_int 4) (const_int 2))])])
4682 /* It would seem useful to combine the truncXi patterns into the movXi
4683    patterns, but unary operators are ignored when matching constraints,
4684    so we need separate patterns.  */
4685 (define_insn "truncdisi2"
4686   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4687         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4688   "TARGET_SHMEDIA"
4689   "@
4690         add.l   %1, r63, %0
4691         st%M0.l %m0, %1
4692         fst%M0.s        %m0, %T1
4693         fmov.ls %1, %0
4694         fmov.sl %T1, %0
4695         fmov.s  %T1, %0"
4696   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4697    (set (attr "highpart")
4698         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4699                (const_string "user")]
4700               (const_string "extend")))])
4702 (define_insn "truncdihi2"
4703   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4704         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4705   "TARGET_SHMEDIA"
4706   "@
4707         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4708         st%M0.w %m0, %1"
4709   [(set_attr "type"   "arith_media,store_media")
4710    (set_attr "length" "8,4")
4711    (set (attr "highpart")
4712         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4713                (const_string "user")]
4714               (const_string "extend")))])
4716 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4717 ; Because we use zero extension, we can't provide signed QImode compares
4718 ; using a simple compare or conditional branch insn.
4719 (define_insn "truncdiqi2"
4720   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4721         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4722   "TARGET_SHMEDIA"
4723   "@
4724         andi    %1, 255, %0
4725         st%M0.b %m0, %1"
4726   [(set_attr "type"   "arith_media,store")
4727    (set (attr "highpart")
4728         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4729                (const_string "user")]
4730               (const_string "extend")))])
4731 ;; -------------------------------------------------------------------------
4732 ;; Move instructions
4733 ;; -------------------------------------------------------------------------
4735 ;; define push and pop so it is easy for sh.c
4736 ;; We can't use push and pop on SHcompact because the stack must always
4737 ;; be 8-byte aligned.
4739 (define_expand "push"
4740   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4741         (match_operand:SI 0 "register_operand" "r,l,x"))]
4742   "TARGET_SH1 && ! TARGET_SH5"
4743   "")
4745 (define_expand "pop"
4746   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4747         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4748   "TARGET_SH1 && ! TARGET_SH5"
4749   "")
4751 (define_expand "push_e"
4752   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4753                    (match_operand:SF 0 "" ""))
4754               (use (reg:PSI FPSCR_REG))
4755               (clobber (scratch:SI))])]
4756   "TARGET_SH1 && ! TARGET_SH5"
4757   "")
4759 (define_insn "push_fpul"
4760   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4761   "TARGET_SH2E && ! TARGET_SH5"
4762   "sts.l        fpul,@-r15"
4763   [(set_attr "type" "fstore")
4764    (set_attr "late_fp_use" "yes")
4765    (set_attr "hit_stack" "yes")])
4767 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4768 ;; so use that.
4769 (define_expand "push_4"
4770   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4771                    (match_operand:DF 0 "" ""))
4772               (use (reg:PSI FPSCR_REG))
4773               (clobber (scratch:SI))])]
4774   "TARGET_SH1 && ! TARGET_SH5"
4775   "")
4777 (define_expand "pop_e"
4778   [(parallel [(set (match_operand:SF 0 "" "")
4779               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4780               (use (reg:PSI FPSCR_REG))
4781               (clobber (scratch:SI))])]
4782   "TARGET_SH1 && ! TARGET_SH5"
4783   "")
4785 (define_insn "pop_fpul"
4786   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4787   "TARGET_SH2E && ! TARGET_SH5"
4788   "lds.l        @r15+,fpul"
4789   [(set_attr "type" "load")
4790    (set_attr "hit_stack" "yes")])
4792 (define_expand "pop_4"
4793   [(parallel [(set (match_operand:DF 0 "" "")
4794                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4795               (use (reg:PSI FPSCR_REG))
4796               (clobber (scratch:SI))])]
4797   "TARGET_SH1 && ! TARGET_SH5"
4798   "")
4800 (define_expand "push_fpscr"
4801   [(const_int 0)]
4802   "TARGET_SH2E"
4803   "
4805   rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode,
4806                                                  gen_rtx_PRE_DEC (Pmode,
4807                                                           stack_pointer_rtx)),
4808                                         get_fpscr_rtx ()));
4809   add_reg_note (insn, REG_INC, stack_pointer_rtx);
4810   DONE;
4813 (define_expand "pop_fpscr"
4814   [(const_int 0)]
4815   "TARGET_SH2E"
4816   "
4818   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4819                                         gen_frame_mem (PSImode,
4820                                                  gen_rtx_POST_INC (Pmode,
4821                                                           stack_pointer_rtx))));
4822   add_reg_note (insn, REG_INC, stack_pointer_rtx);
4823   DONE;
4826 ;; These two patterns can happen as the result of optimization, when
4827 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4828 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4830 (define_insn "clrt"
4831   [(set (reg:SI T_REG) (const_int 0))]
4832   "TARGET_SH1"
4833   "clrt")
4835 (define_insn "sett"
4836   [(set (reg:SI T_REG) (const_int 1))]
4837   "TARGET_SH1"
4838   "sett")
4840 ;; Define additional pop for SH1 and SH2 so it does not get 
4841 ;; placed in the delay slot.
4842 (define_insn "*movsi_pop"
4843   [(set (match_operand:SI 0 "register_operand" "=r,x,l")
4844         (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
4845   "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
4846    && ! TARGET_SH3"
4847   "@
4848    mov.l   %1,%0
4849    lds.l   %1,%0
4850    lds.l   %1,%0"
4851   [(set_attr "type" "load_si,mem_mac,pload")
4852    (set_attr "length" "2,2,2")
4853    (set_attr "in_delay_slot" "no,no,no")])
4855 ;; t/r must come after r/r, lest reload will try to reload stuff like
4856 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4857 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4858 (define_insn "movsi_i"
4859   [(set (match_operand:SI 0 "general_movdst_operand"
4860             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4861         (match_operand:SI 1 "general_movsrc_operand"
4862          "Q,r,I08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4863   "TARGET_SH1
4864    && ! TARGET_SH2E
4865    && ! TARGET_SH2A
4866    && (register_operand (operands[0], SImode)
4867        || register_operand (operands[1], SImode))"
4868   "@
4869         mov.l   %1,%0
4870         mov     %1,%0
4871         mov     %1,%0
4872         cmp/pl  %1
4873         mov.l   %1,%0
4874         sts     %1,%0
4875         sts     %1,%0
4876         movt    %0
4877         mov.l   %1,%0
4878         sts.l   %1,%0
4879         sts.l   %1,%0
4880         lds     %1,%0
4881         lds     %1,%0
4882         lds.l   %1,%0
4883         lds.l   %1,%0
4884         fake    %1,%0"
4885   [(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")
4886    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4888 ;; t/r must come after r/r, lest reload will try to reload stuff like
4889 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4890 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4891 ;; will require a reload.
4892 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4893 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4894 (define_insn "movsi_ie"
4895   [(set (match_operand:SI 0 "general_movdst_operand"
4896             "=r,r,r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4897         (match_operand:SI 1 "general_movsrc_operand"
4898          "Q,r,I08,I20,I28,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4899   "(TARGET_SH2E || TARGET_SH2A)
4900    && (register_operand (operands[0], SImode)
4901        || register_operand (operands[1], SImode))"
4902   "@
4903         mov.l   %1,%0
4904         mov     %1,%0
4905         mov     %1,%0
4906         movi20  %1,%0
4907         movi20s %1,%0
4908         cmp/pl  %1
4909         mov.l   %1,%0
4910         sts     %1,%0
4911         sts     %1,%0
4912         movt    %0
4913         mov.l   %1,%0
4914         sts.l   %1,%0
4915         sts.l   %1,%0
4916         lds     %1,%0
4917         lds     %1,%0
4918         lds.l   %1,%0
4919         lds.l   %1,%0
4920         lds.l   %1,%0
4921         sts.l   %1,%0
4922         fake    %1,%0
4923         lds     %1,%0
4924         sts     %1,%0
4925         fsts    fpul,%0
4926         flds    %1,fpul
4927         fmov    %1,%0
4928         ! move optimized away"
4929   [(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")
4930    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4931    (set_attr_alternative "length"
4932      [(const_int 2)
4933       (const_int 2)
4934       (const_int 2)
4935       (const_int 4)
4936       (const_int 4)
4937       (const_int 2)
4938       (if_then_else
4939         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4940         (const_int 4) (const_int 2))
4941       (const_int 2)
4942       (const_int 2)
4943       (const_int 2)
4944       (if_then_else
4945         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
4946         (const_int 4) (const_int 2))
4947       (const_int 2)
4948       (const_int 2)
4949       (const_int 2)
4950       (const_int 2)
4951       (const_int 2)
4952       (const_int 2)
4953       (const_int 2)
4954       (const_int 2)
4955       (const_int 2)
4956       (const_int 2)
4957       (const_int 2)
4958       (const_int 2)
4959       (const_int 2)
4960       (const_int 2)
4961       (const_int 0)])])
4963 (define_insn "movsi_i_lowpart"
4964   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,r,m,r"))
4965         (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,t,r,i"))]
4966    "TARGET_SH1
4967     && (register_operand (operands[0], SImode)
4968         || register_operand (operands[1], SImode))"
4969   "@
4970         mov.l   %1,%0
4971         mov     %1,%0
4972         mov     %1,%0
4973         mov.l   %1,%0
4974         sts     %1,%0
4975         sts     %1,%0
4976         movt    %0
4977         mov.l   %1,%0
4978         fake    %1,%0"
4979   [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,arith,store,pcload")])
4981 (define_insn_and_split "load_ra"
4982   [(set (match_operand:SI 0 "general_movdst_operand" "")
4983         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4984   "TARGET_SH1"
4985   "#"
4986   "&& ! currently_expanding_to_rtl"
4987   [(set (match_dup 0) (match_dup 1))]
4988   "
4990   if (TARGET_SHCOMPACT && crtl->saves_all_registers)
4991     operands[1] = gen_frame_mem (SImode, return_address_pointer_rtx);
4994 ;; The '?'s in the following constraints may not reflect the time taken
4995 ;; to perform the move. They are there to discourage the use of floating-
4996 ;; point registers for storing integer values.
4997 (define_insn "*movsi_media"
4998   [(set (match_operand:SI 0 "general_movdst_operand"
4999                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
5000         (match_operand:SI 1 "general_movsrc_operand"
5001          "r,I16Css,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5002   "TARGET_SHMEDIA_FPU
5003    && (register_operand (operands[0], SImode)
5004        || sh_register_operand (operands[1], SImode)
5005        || GET_CODE (operands[1]) == TRUNCATE)"
5006   "@
5007         add.l   %1, r63, %0
5008         movi    %1, %0
5009         #
5010         ld%M1.l %m1, %0
5011         st%M0.l %m0, %N1
5012         fld%M1.s        %m1, %0
5013         fst%M0.s        %m0, %1
5014         fmov.ls %N1, %0
5015         fmov.sl %1, %0
5016         fmov.s  %1, %0
5017         ptabs   %1, %0
5018         gettr   %1, %0
5019         pt      %1, %0"
5020   [(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")
5021    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
5022    (set (attr "highpart")
5023         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5024                (const_string "user")]
5025               (const_string "ignore")))])
5027 (define_insn "*movsi_media_nofpu"
5028   [(set (match_operand:SI 0 "general_movdst_operand"
5029                 "=r,r,r,r,m,*b,r,*b")
5030         (match_operand:SI 1 "general_movsrc_operand"
5031          "r,I16Css,nCpg,m,rZ,r,*b,Csy"))]
5032   "TARGET_SHMEDIA
5033    && (register_operand (operands[0], SImode)
5034        || sh_register_operand (operands[1], SImode)
5035        || GET_CODE (operands[1]) == TRUNCATE)"
5036   "@
5037         add.l   %1, r63, %0
5038         movi    %1, %0
5039         #
5040         ld%M1.l %m1, %0
5041         st%M0.l %m0, %N1
5042         ptabs   %1, %0
5043         gettr   %1, %0
5044         pt      %1, %0"
5045   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5046    (set_attr "length" "4,4,8,4,4,4,4,12")
5047    (set (attr "highpart")
5048         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5049                (const_string "user")]
5050               (const_string "ignore")))])
5052 (define_expand "movsi_const"
5053   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5054         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5055                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5056    (set (match_dup 0)
5057         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
5058                 (const:SI (unspec:SI [(match_dup 1)
5059                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5060   "TARGET_SHMEDIA && reload_completed
5061    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5062   "
5064   if (GET_CODE (operands[1]) == LABEL_REF
5065       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
5066     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
5067   else if (GOTOFF_P (operands[1]))
5068     {
5069       rtx unspec = XEXP (operands[1], 0);
5071       if (! UNSPEC_GOTOFF_P (unspec))
5072         {
5073           unspec = XEXP (unspec, 0);
5074           if (! UNSPEC_GOTOFF_P (unspec))
5075             abort ();
5076         }
5077       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
5078           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
5079         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
5080     }
5083 (define_expand "movsi_const_16bit"
5084   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
5085         (const:SI (unspec:SI [(match_operand:DI 1 "immediate_operand" "s")
5086                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5087   "TARGET_SHMEDIA && flag_pic && reload_completed
5088    && GET_CODE (operands[1]) == SYMBOL_REF"
5089   "")
5091 (define_split
5092   [(set (match_operand:SI 0 "arith_reg_dest" "")
5093         (match_operand:SI 1 "immediate_operand" ""))]
5094   "TARGET_SHMEDIA && reload_completed
5095    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5096   [(const_int 0)]
5097   "
5099   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
5101   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5103   DONE;
5106 (define_split
5107   [(set (match_operand:SI 0 "register_operand" "")
5108         (match_operand:SI 1 "immediate_operand" ""))]
5109   "TARGET_SHMEDIA && reload_completed
5110    && ((CONST_INT_P (operands[1])
5111         && ! satisfies_constraint_I16 (operands[1]))
5112        || GET_CODE (operands[1]) == CONST_DOUBLE)"
5113   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5115 (define_expand "movsi"
5116   [(set (match_operand:SI 0 "general_movdst_operand" "")
5117         (match_operand:SI 1 "general_movsrc_operand" ""))]
5118   ""
5119   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
5121 (define_expand "ic_invalidate_line"
5122   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
5123                                 (match_dup 1)] UNSPEC_ICACHE)
5124               (clobber (scratch:SI))])]
5125   "TARGET_HARD_SH4 || TARGET_SH5"
5126   "
5128   if (TARGET_SHMEDIA)
5129     {
5130       emit_insn (gen_ic_invalidate_line_media (operands[0]));
5131       DONE;
5132     }
5133   else if (TARGET_SHCOMPACT)
5134     {
5135       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
5136       operands[1] = force_reg (Pmode, operands[1]);
5137       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
5138       DONE;
5139     }
5140   else if (TARGET_SH4A_ARCH || TARGET_SH4_300)
5141     {
5142       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
5143       DONE;
5144     }
5145   operands[0] = force_reg (Pmode, operands[0]);
5146   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5147                                                                Pmode)));
5150 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5151 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5152 ;; the requirement *1*00 for associative address writes.  The alignment of
5153 ;; %0 implies that its least significant bit is cleared,
5154 ;; thus we clear the V bit of a matching entry if there is one.
5155 (define_insn "ic_invalidate_line_i"
5156   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5157                      (match_operand:SI 1 "register_operand" "r")]
5158                      UNSPEC_ICACHE)
5159    (clobber (match_scratch:SI 2 "=&r"))]
5160   "TARGET_HARD_SH4"
5161   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5162   [(set_attr "length" "8")
5163    (set_attr "type" "cwb")])
5165 (define_insn "ic_invalidate_line_sh4a"
5166   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5167                     UNSPEC_ICACHE)]
5168   "TARGET_SH4A_ARCH || TARGET_SH4_300"
5169   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5170   [(set_attr "length" "16")
5171    (set_attr "type" "cwb")])
5173 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5174 ;; an add in the code that calculates the address.
5175 (define_insn "ic_invalidate_line_media"
5176   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5177                     UNSPEC_ICACHE)]
5178   "TARGET_SHMEDIA"
5179   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5180   [(set_attr "length" "16")
5181    (set_attr "type" "invalidate_line_media")])
5183 (define_insn "ic_invalidate_line_compact"
5184   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5185                      (match_operand:SI 1 "register_operand" "r")]
5186                     UNSPEC_ICACHE)
5187    (clobber (reg:SI PR_REG))]
5188   "TARGET_SHCOMPACT"
5189   "jsr @%1%#"
5190   [(set_attr "type" "sfunc")
5191    (set_attr "needs_delay_slot" "yes")])
5193 (define_expand "initialize_trampoline"
5194   [(match_operand:SI 0 "" "")
5195    (match_operand:SI 1 "" "")
5196    (match_operand:SI 2 "" "")]
5197   "TARGET_SHCOMPACT"
5198   "
5200   rtx sfun, tramp;
5202   tramp = force_reg (Pmode, operands[0]);
5203   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5204                                             SFUNC_STATIC));
5205   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5206   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5208   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5209   DONE;
5212 (define_insn "initialize_trampoline_compact"
5213   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5214                      (match_operand:SI 1 "register_operand" "r")
5215                      (reg:SI R2_REG) (reg:SI R3_REG)]
5216                     UNSPEC_INIT_TRAMP)
5218    (clobber (reg:SI PR_REG))]
5219   "TARGET_SHCOMPACT"
5220   "jsr @%1%#"
5221   [(set_attr "type" "sfunc")
5222    (set_attr "needs_delay_slot" "yes")])
5224 (define_insn "movqi_i"
5225   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m,r,r,l")
5226         (match_operand:QI 1 "general_movsrc_operand"  "r,i,m,r,t,l,r"))]
5227   "TARGET_SH1
5228    && (arith_reg_operand (operands[0], QImode)
5229        || arith_reg_operand (operands[1], QImode))"
5230   "@
5231         mov     %1,%0
5232         mov     %1,%0
5233         mov.b   %1,%0
5234         mov.b   %1,%0
5235         movt    %0
5236         sts     %1,%0
5237         lds     %1,%0"
5238  [(set_attr "type" "move,movi8,load,store,arith,prget,prset")
5239   (set_attr_alternative "length"
5240      [(const_int 2)
5241       (const_int 2)
5242       (if_then_else
5243         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5244         (const_int 4) (const_int 2))
5245       (if_then_else
5246         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
5247         (const_int 4) (const_int 2))
5248       (const_int 2)
5249       (const_int 2)
5250       (const_int 2)])])
5252 (define_insn "*movqi_media"
5253   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5254         (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))]
5255   "TARGET_SHMEDIA
5256    && (arith_reg_operand (operands[0], QImode)
5257        || extend_reg_or_0_operand (operands[1], QImode))"
5258   "@
5259         add.l   %1, r63, %0
5260         movi    %1, %0
5261         ld%M1.ub        %m1, %0
5262         st%M0.b %m0, %N1"
5263   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5264    (set (attr "highpart")
5265         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5266                (const_string "user")]
5267               (const_string "ignore")))])
5269 (define_expand "movqi"
5270   [(set (match_operand:QI 0 "general_operand" "")
5271         (match_operand:QI 1 "general_operand"  ""))]
5272   ""
5273   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5275 (define_expand "reload_inqi"
5276   [(set (match_operand:SI 2 "" "=&r")
5277         (match_operand:QI 1 "inqhi_operand" ""))
5278    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5279         (truncate:QI (match_dup 3)))]
5280   "TARGET_SHMEDIA"
5281   "
5283   rtx inner = XEXP (operands[1], 0);
5284   int regno = REGNO (inner);
5286   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5287   operands[1] = gen_rtx_REG (SImode, regno);
5288   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5291 /* When storing r0, we have to avoid reg+reg addressing.  */
5292 (define_insn "movhi_i"
5293   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5294         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5295   "TARGET_SH1
5296    && (arith_reg_operand (operands[0], HImode)
5297        || arith_reg_operand (operands[1], HImode))
5298    && (!MEM_P (operands[0])
5299        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5300        || !REG_P (XEXP (XEXP (operands[0], 0), 1))
5301        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5302   "@
5303         mov.w   %1,%0
5304         mov     %1,%0
5305         mov.w   %1,%0
5306         movt    %0
5307         mov.w   %1,%0
5308         sts     %1,%0
5309         lds     %1,%0
5310         fake    %1,%0"
5311   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5313 (define_insn "*movhi_media"
5314   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5315         (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))]
5316   "TARGET_SHMEDIA
5317    && (arith_reg_operand (operands[0], HImode)
5318        || arith_reg_or_0_operand (operands[1], HImode))"
5319   "@
5320         add.l   %1, r63, %0
5321         movi    %1, %0
5322         #
5323         ld%M1.w %m1, %0
5324         st%M0.w %m0, %N1"
5325   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5326    (set (attr "highpart")
5327         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5328                (const_string "user")]
5329               (const_string "ignore")))])
5331 (define_split
5332   [(set (match_operand:HI 0 "register_operand" "")
5333         (match_operand:HI 1 "immediate_operand" ""))]
5334   "TARGET_SHMEDIA && reload_completed
5335    && ! satisfies_constraint_I16 (operands[1])"
5336   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5338 (define_expand "movhi"
5339   [(set (match_operand:HI 0 "general_movdst_operand" "")
5340         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5341   ""
5342   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5344 (define_expand "reload_inhi"
5345   [(set (match_operand:SI 2 "" "=&r")
5346         (match_operand:HI 1 "inqhi_operand" ""))
5347    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5348         (truncate:HI (match_dup 3)))]
5349   "TARGET_SHMEDIA"
5350   "
5352   rtx inner = XEXP (operands[1], 0);
5353   int regno = REGNO (inner);
5355   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5356   operands[1] = gen_rtx_REG (SImode, regno);
5357   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5360 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5361 ;; compiled with -m2 -ml -O3 -funroll-loops
5362 (define_insn "*movdi_i"
5363   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5364         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5365   "TARGET_SH1
5366    && (arith_reg_operand (operands[0], DImode)
5367        || arith_reg_operand (operands[1], DImode))"
5368   "* return output_movedouble (insn, operands, DImode);"
5369   [(set_attr "length" "4")
5370    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5372 ;; If the output is a register and the input is memory or a register, we have
5373 ;; to be careful and see which word needs to be loaded first.
5375 (define_split
5376   [(set (match_operand:DI 0 "general_movdst_operand" "")
5377         (match_operand:DI 1 "general_movsrc_operand" ""))]
5378   "TARGET_SH1 && reload_completed"
5379   [(set (match_dup 2) (match_dup 3))
5380    (set (match_dup 4) (match_dup 5))]
5381   "
5383   int regno;
5385   if ((MEM_P (operands[0])
5386        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5387       || (MEM_P (operands[1])
5388           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5389     FAIL;
5391   switch (GET_CODE (operands[0]))
5392     {
5393     case REG:
5394       regno = REGNO (operands[0]);
5395       break;
5396     case SUBREG:
5397       regno = subreg_regno (operands[0]);
5398       break;
5399     case MEM:
5400       regno = -1;
5401       break;
5402     default:
5403       gcc_unreachable ();
5404     }
5406   if (regno == -1
5407       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5408     {
5409       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5410       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5411       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5412       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5413     }
5414   else
5415     {
5416       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5417       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5418       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5419       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5420     }
5422   if (operands[2] == 0 || operands[3] == 0
5423       || operands[4] == 0 || operands[5] == 0)
5424     FAIL;
5427 ;; The '?'s in the following constraints may not reflect the time taken
5428 ;; to perform the move. They are there to discourage the use of floating-
5429 ;; point registers for storing integer values.
5430 (define_insn "*movdi_media"
5431   [(set (match_operand:DI 0 "general_movdst_operand"
5432                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5433         (match_operand:DI 1 "general_movsrc_operand"
5434          "r,I16Css,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5435   "TARGET_SHMEDIA_FPU
5436    && (register_operand (operands[0], DImode)
5437        || sh_register_operand (operands[1], DImode))"
5438   "@
5439         add     %1, r63, %0
5440         movi    %1, %0
5441         #
5442         ld%M1.q %m1, %0
5443         st%M0.q %m0, %N1
5444         fld%M1.d        %m1, %0
5445         fst%M0.d        %m0, %1
5446         fmov.qd %N1, %0
5447         fmov.dq %1, %0
5448         fmov.d  %1, %0
5449         ptabs   %1, %0
5450         gettr   %1, %0
5451         pt      %1, %0"
5452   [(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")
5453    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5455 (define_insn "*movdi_media_nofpu"
5456   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5457         (match_operand:DI 1 "general_movsrc_operand" "r,I16Css,nCpgF,m,rlZ,r,*b,Csy"))]
5458   "TARGET_SHMEDIA
5459    && (register_operand (operands[0], DImode)
5460        || sh_register_operand (operands[1], DImode))"
5461   "@
5462         add     %1, r63, %0
5463         movi    %1, %0
5464         #
5465         ld%M1.q %m1, %0
5466         st%M0.q %m0, %N1
5467         ptabs   %1, %0
5468         gettr   %1, %0
5469         pt      %1, %0"
5470   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5471    (set_attr "length" "4,4,16,4,4,4,4,*")])
5473 (define_insn "*movdi_media_I16"
5474   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5475         (match_operand:DI 1 "const_int_operand" "I16"))]
5476   "TARGET_SHMEDIA && reload_completed"
5477   "movi %1, %0"
5478   [(set_attr "type" "arith_media")
5479    (set_attr "length" "4")])
5481 (define_split
5482   [(set (match_operand:DI 0 "arith_reg_dest" "")
5483         (match_operand:DI 1 "immediate_operand" ""))]
5484   "TARGET_SHMEDIA && reload_completed
5485    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5486   [(set (match_dup 0) (match_dup 1))]
5487   "
5489   rtx insn;
5491   if (TARGET_SHMEDIA64)
5492     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5493   else
5494     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5496   set_unique_reg_note (insn, REG_EQUAL, copy_rtx (operands[1]));
5498   DONE;
5501 (define_expand "movdi_const"
5502   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5503         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5504                               (const_int 48)] UNSPEC_EXTRACT_S16)))
5505    (set (match_dup 0)
5506         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5507                 (const:DI (unspec:DI [(match_dup 1)
5508                                       (const_int 32)] UNSPEC_EXTRACT_U16))))
5509    (set (match_dup 0)
5510         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5511                 (const:DI (unspec:DI [(match_dup 1)
5512                                       (const_int 16)] UNSPEC_EXTRACT_U16))))
5513    (set (match_dup 0)
5514         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5515                 (const:DI (unspec:DI [(match_dup 1)
5516                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5517   "TARGET_SHMEDIA64 && reload_completed
5518    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5519   "
5521   sh_mark_label (operands[1], 4);
5524 (define_expand "movdi_const_32bit"
5525   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5526         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5527                               (const_int 16)] UNSPEC_EXTRACT_S16)))
5528    (set (match_dup 0)
5529         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5530                 (const:DI (unspec:DI [(match_dup 1)
5531                                       (const_int 0)] UNSPEC_EXTRACT_U16))))]
5532   "TARGET_SHMEDIA32 && reload_completed
5533    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5534   "
5536   sh_mark_label (operands[1], 2);
5539 (define_expand "movdi_const_16bit"
5540   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5541         (const:DI (unspec:DI [(match_operand:DI 1 "immediate_operand" "s")
5542                               (const_int 0)] UNSPEC_EXTRACT_S16)))]
5543   "TARGET_SHMEDIA && flag_pic && reload_completed
5544    && GET_CODE (operands[1]) == SYMBOL_REF"
5545   "")
5547 (define_split
5548   [(set (match_operand:DI 0 "ext_dest_operand" "")
5549         (match_operand:DI 1 "immediate_operand" ""))]
5550   "TARGET_SHMEDIA && reload_completed
5551    && CONST_INT_P (operands[1])
5552    && ! satisfies_constraint_I16 (operands[1])"
5553   [(set (match_dup 0) (match_dup 2))
5554    (match_dup 1)]
5555   "
5557   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5558   unsigned HOST_WIDE_INT low = val;
5559   unsigned HOST_WIDE_INT high = val;
5560   unsigned HOST_WIDE_INT sign;
5561   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5563   /* Zero-extend the 16 least-significant bits.  */
5564   low &= 0xffff;
5566   /* Arithmetic shift right the word by 16 bits.  */
5567   high >>= 16;
5568   if (GET_CODE (operands[0]) == SUBREG
5569       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5570     {
5571       high &= 0xffff;
5572       high ^= 0x8000;
5573       high -= 0x8000;
5574     }
5575   else
5576     {
5577       sign = 1;
5578       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5579       high ^= sign;
5580       high -= sign;
5581     }
5582   do
5583     {
5584       /* If we can't generate the constant with a two-insn movi / shori
5585          sequence, try some other strategies.  */
5586       if (! CONST_OK_FOR_I16 (high))
5587         {
5588           /* Try constant load / left shift.  We know VAL != 0.  */
5589           val2 = val ^ (val-1);
5590           if (val2 > 0x1ffff)
5591             {
5592               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5594               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5595                   || (! CONST_OK_FOR_I16 (high >> 16)
5596                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5597                 {
5598                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5599                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5600                                                    GEN_INT (trailing_zeroes));
5601                   break;
5602                 }
5603             }
5604           /* Try constant load / right shift.  */
5605           val2 = (val >> 15) + 1;
5606           if (val2 == (val2 & -val2))
5607             {
5608               int shift = 49 - exact_log2 (val2);
5610               val2 = trunc_int_for_mode (val << shift, DImode);
5611               if (CONST_OK_FOR_I16 (val2))
5612                 {
5613                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5614                                                    GEN_INT (shift));
5615                   break;
5616                 }
5617             }
5618           /* Try mperm.w .  */
5619           val2 = val & 0xffff;
5620           if ((val >> 16 & 0xffff) == val2
5621               && (val >> 32 & 0xffff) == val2
5622               && (val >> 48 & 0xffff) == val2)
5623             {
5624               val2 = (HOST_WIDE_INT) val >> 48;
5625               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5626               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5627               break;
5628             }
5629           /* Try movi / mshflo.l  */
5630           val2 = (HOST_WIDE_INT) val >> 32;
5631           if (val2 == ((unsigned HOST_WIDE_INT)
5632                         trunc_int_for_mode (val, SImode)))
5633             {
5634               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5635                                              operands[0]);
5636               break;
5637             }
5638           /* Try movi / mshflo.l w/ r63.  */
5639           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5640           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5641             {
5642               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5643                                              const0_rtx);
5644               break;
5645             }
5646         }
5647       val2 = high;
5648       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5649     }
5650   while (0);
5651   operands[2] = GEN_INT (val2);
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_DOUBLE"
5659   [(set (match_dup 0) (match_dup 2))
5660   (set (match_dup 0)
5661        (ior:DI (ashift:DI (match_dup 0) (const_int 16)) (match_dup 1)))]
5662   "
5664   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5665   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5666   unsigned HOST_WIDE_INT val = low;
5667   unsigned HOST_WIDE_INT sign;
5669   /* Zero-extend the 16 least-significant bits.  */
5670   val &= 0xffff;
5671   operands[1] = GEN_INT (val);
5673   /* Arithmetic shift right the double-word by 16 bits.  */
5674   low >>= 16;
5675   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5676   high >>= 16;
5677   sign = 1;
5678   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5679   high ^= sign;
5680   high -= sign;
5682   /* This will only be true if high is a sign-extension of low, i.e.,
5683      it must be either 0 or (unsigned)-1, and be zero iff the
5684      most-significant bit of low is set.  */
5685   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5686     operands[2] = GEN_INT (low);
5687   else
5688     operands[2] = immed_double_const (low, high, DImode);
5691 (define_insn "shori_media"
5692   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5693         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5694                            (const_int 16))
5695                 (match_operand:DI 2 "immediate_operand" "K16Csu,nF")))]
5696   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5697   "@
5698         shori   %u2, %0
5699         #"
5700   [(set_attr "type" "arith_media,*")])
5702 (define_insn "*shori_media_si"
5703   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5704         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5705                            (const_int 16))
5706                 (match_operand:SI 2 "immediate_operand" "K16Csu")))]
5707   "TARGET_SHMEDIA"
5708   "shori        %u2, %0")
5710 (define_expand "movdi"
5711   [(set (match_operand:DI 0 "general_movdst_operand" "")
5712         (match_operand:DI 1 "general_movsrc_operand" ""))]
5713   ""
5714   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5716 (define_insn "movdf_media"
5717   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5718         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5719   "TARGET_SHMEDIA_FPU
5720    && (register_operand (operands[0], DFmode)
5721        || sh_register_operand (operands[1], DFmode))"
5722   "@
5723         fmov.d  %1, %0
5724         fmov.qd %N1, %0
5725         fmov.dq %1, %0
5726         add     %1, r63, %0
5727         #
5728         fld%M1.d        %m1, %0
5729         fst%M0.d        %m0, %1
5730         ld%M1.q %m1, %0
5731         st%M0.q %m0, %N1"
5732   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5734 (define_insn "movdf_media_nofpu"
5735   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5736         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5737   "TARGET_SHMEDIA
5738    && (register_operand (operands[0], DFmode)
5739        || sh_register_operand (operands[1], DFmode))"
5740   "@
5741         add     %1, r63, %0
5742         #
5743         ld%M1.q %m1, %0
5744         st%M0.q %m0, %N1"
5745   [(set_attr "type" "arith_media,*,load_media,store_media")])
5747 (define_split
5748   [(set (match_operand:DF 0 "arith_reg_dest" "")
5749         (match_operand:DF 1 "immediate_operand" ""))]
5750   "TARGET_SHMEDIA && reload_completed"
5751   [(set (match_dup 3) (match_dup 2))]
5752   "
5754   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5755   long values[2];
5756   REAL_VALUE_TYPE value;
5758   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5759   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5761   if (HOST_BITS_PER_WIDE_INT >= 64)
5762     operands[2] = immed_double_const ((unsigned long) values[endian]
5763                                       | ((HOST_WIDE_INT) values[1 - endian]
5764                                          << 32), 0, DImode);
5765   else
5766     {
5767       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5768       operands[2] = immed_double_const (values[endian], values[1 - endian],
5769                                         DImode);
5770     }
5772   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5775 ;; ??? This should be a define expand.
5777 (define_insn "movdf_k"
5778   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5779         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5780   "TARGET_SH1
5781    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5782        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5783        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
5784        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
5785    && (arith_reg_operand (operands[0], DFmode)
5786        || arith_reg_operand (operands[1], DFmode))"
5787   "* return output_movedouble (insn, operands, DFmode);"
5788   [(set_attr "length" "4")
5789    (set_attr "type" "move,pcload,load,store")])
5791 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5792 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5793 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5794 ;; the d/m/c/X alternative, which is split later into single-precision
5795 ;; instructions.  And when not optimizing, no splits are done before fixing
5796 ;; up pcloads, so we need usable length information for that.
5797 (define_insn "movdf_i4"
5798   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5799         (match_operand:DF 1 "general_movsrc_operand"  "d,r,F,m,d,FQ,m,r,d,r"))
5800    (use (match_operand:PSI 2 "fpscr_operand"          "c,c,c,c,c,c,c,c,c,c"))
5801    (clobber (match_scratch:SI 3                      "=X,X,&z,X,X,X,X,X,X,X"))]
5802   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5803    && (arith_reg_operand (operands[0], DFmode)
5804        || arith_reg_operand (operands[1], DFmode))"
5805   {
5806     switch (which_alternative)
5807     {
5808     case 0:
5809       if (TARGET_FMOVD)
5810         return "fmov    %1,%0";
5811       else if (REGNO (operands[0]) != REGNO (operands[1]) + 1)
5812         return "fmov    %R1,%R0\n\tfmov %S1,%S0";
5813       else
5814         return "fmov    %S1,%S0\n\tfmov %R1,%R0";
5815     case 3:
5816     case 4:
5817       return "fmov.d    %1,%0";
5818     default:
5819       return "#";
5820     }
5821   }
5822   [(set_attr_alternative "length"
5823      [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
5824       (const_int 4)
5825       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5826       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5827       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5828       (const_int 4)
5829       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5830       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5831       ;; increment or decrement r15 explicitly.
5832       (if_then_else
5833        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5834        (const_int 10) (const_int 8))
5835       (if_then_else
5836        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5837        (const_int 10) (const_int 8))])
5838    (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
5839    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5840    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5841                                            (const_string "double")
5842                                            (const_string "none")))])
5844 ;; Moving DFmode between fp/general registers through memory
5845 ;; (the top of the stack) is faster than moving through fpul even for
5846 ;; little endian.  Because the type of an instruction is important for its
5847 ;; scheduling,  it is beneficial to split these operations, rather than
5848 ;; emitting them in one single chunk, even if this will expose a stack
5849 ;; use that will prevent scheduling of other stack accesses beyond this
5850 ;; instruction.
5851 (define_split
5852   [(set (match_operand:DF 0 "register_operand" "")
5853         (match_operand:DF 1 "register_operand" ""))
5854    (use (match_operand:PSI 2 "fpscr_operand" ""))
5855    (clobber (match_scratch:SI 3 "=X"))]
5856   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5857    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5858   [(const_int 0)]
5859   "
5861   rtx insn, tos;
5863   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5864     {
5865       emit_move_insn (stack_pointer_rtx,
5866                       plus_constant (stack_pointer_rtx, -8));
5867       tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5868     }
5869   else
5870     tos = gen_tmp_stack_mem (DFmode,
5871                              gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5872   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5873   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5874     add_reg_note (insn, REG_INC, stack_pointer_rtx);
5875   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5876     tos = gen_tmp_stack_mem (DFmode, stack_pointer_rtx);
5877   else
5878     tos = gen_tmp_stack_mem (DFmode,
5879                              gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5880   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5881   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5882     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5883   else
5884     add_reg_note (insn, REG_INC, stack_pointer_rtx);
5885   DONE;
5888 ;; local-alloc sometimes allocates scratch registers even when not required,
5889 ;; so we must be prepared to handle these.
5891 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5892 (define_split
5893   [(set (match_operand:DF 0 "general_movdst_operand" "")
5894         (match_operand:DF 1 "general_movsrc_operand"  ""))
5895    (use (match_operand:PSI 2 "fpscr_operand" ""))
5896    (clobber (match_scratch:SI 3 ""))]
5897   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5898    && reload_completed
5899    && true_regnum (operands[0]) < 16
5900    && true_regnum (operands[1]) < 16"
5901   [(set (match_dup 0) (match_dup 1))]
5902   "
5904   /* If this was a reg <-> mem operation with base + index reg addressing,
5905      we have to handle this in a special way.  */
5906   rtx mem = operands[0];
5907   int store_p = 1;
5908   if (! memory_operand (mem, DFmode))
5909     {
5910       mem = operands[1];
5911       store_p = 0;
5912     }
5913   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5914     mem = SUBREG_REG (mem);
5915   if (MEM_P (mem))
5916     {
5917       rtx addr = XEXP (mem, 0);
5918       if (GET_CODE (addr) == PLUS
5919           && REG_P (XEXP (addr, 0))
5920           && REG_P (XEXP (addr, 1)))
5921         {
5922           int offset;
5923           rtx reg0 = gen_rtx_REG (Pmode, 0);
5924           rtx regop = operands[store_p], word0 ,word1;
5926           if (GET_CODE (regop) == SUBREG)
5927             alter_subreg (&regop);
5928           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5929             offset = 2;
5930           else
5931             offset = 4;
5932           mem = copy_rtx (mem);
5933           PUT_MODE (mem, SImode);
5934           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5935           alter_subreg (&word0);
5936           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5937           alter_subreg (&word1);
5938           if (store_p || ! refers_to_regno_p (REGNO (word0),
5939                                               REGNO (word0) + 1, addr, 0))
5940             {
5941               emit_insn (store_p
5942                          ? gen_movsi_ie (mem, word0)
5943                          : gen_movsi_ie (word0, mem));
5944               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5945               mem = copy_rtx (mem);
5946               emit_insn (store_p
5947                          ? gen_movsi_ie (mem, word1)
5948                          : gen_movsi_ie (word1, mem));
5949               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5950             }
5951           else
5952             {
5953               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5954               emit_insn (gen_movsi_ie (word1, mem));
5955               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5956               mem = copy_rtx (mem);
5957               emit_insn (gen_movsi_ie (word0, mem));
5958             }
5959           DONE;
5960         }
5961     }
5964 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5965 (define_split
5966   [(set (match_operand:DF 0 "register_operand" "")
5967         (match_operand:DF 1 "memory_operand"  ""))
5968    (use (match_operand:PSI 2 "fpscr_operand" ""))
5969    (clobber (reg:SI R0_REG))]
5970   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5971   [(parallel [(set (match_dup 0) (match_dup 1))
5972               (use (match_dup 2))
5973               (clobber (scratch:SI))])]
5974   "")
5976 (define_expand "reload_indf__frn"
5977   [(parallel [(set (match_operand:DF 0 "register_operand" "=a")
5978                    (match_operand:DF 1 "immediate_operand" "FQ"))
5979               (use (reg:PSI FPSCR_REG))
5980               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5981   "TARGET_SH1"
5982   "")
5984 (define_expand "reload_outdf__RnFRm"
5985   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5986                    (match_operand:DF 1 "register_operand" "af,r"))
5987               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5988   "TARGET_SH1"
5989   "")
5991 ;; Simplify no-op moves.
5992 (define_split
5993   [(set (match_operand:SF 0 "register_operand" "")
5994         (match_operand:SF 1 "register_operand" ""))
5995    (use (match_operand:PSI 2 "fpscr_operand" ""))
5996    (clobber (match_scratch:SI 3 ""))]
5997   "TARGET_SH2E && reload_completed
5998    && true_regnum (operands[0]) == true_regnum (operands[1])"
5999   [(set (match_dup 0) (match_dup 0))]
6000   "")
6002 ;; fmovd substitute post-reload splits
6003 (define_split
6004   [(set (match_operand:DF 0 "register_operand" "")
6005         (match_operand:DF 1 "register_operand" ""))
6006    (use (match_operand:PSI 2 "fpscr_operand" ""))
6007    (clobber (match_scratch:SI 3 ""))]
6008   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
6009    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6010    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6011   [(const_int 0)]
6012   "
6014   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
6015   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
6016                            gen_rtx_REG (SFmode, src), operands[2]));
6017   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
6018                            gen_rtx_REG (SFmode, src + 1), operands[2]));
6019   DONE;
6022 (define_split
6023   [(set (match_operand:DF 0 "register_operand" "")
6024         (mem:DF (match_operand:SI 1 "register_operand" "")))
6025    (use (match_operand:PSI 2 "fpscr_operand" ""))
6026    (clobber (match_scratch:SI 3 ""))]
6027   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6028    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
6029    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
6030   [(const_int 0)]
6031   "
6033   int regno = true_regnum (operands[0]);
6034   rtx insn;
6035   rtx mem = SET_SRC (XVECEXP (PATTERN (curr_insn), 0, 0));
6036   rtx mem2
6037     = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
6038   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6039                                            regno + !! TARGET_LITTLE_ENDIAN),
6040                                   mem2, operands[2]));
6041   add_reg_note (insn, REG_INC, operands[1]);
6042   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
6043                                                regno + ! TARGET_LITTLE_ENDIAN),
6044                                   change_address (mem, SFmode, NULL_RTX),
6045                                   operands[2]));
6046   DONE;
6049 (define_split
6050   [(set (match_operand:DF 0 "register_operand" "")
6051         (match_operand:DF 1 "memory_operand" ""))
6052    (use (match_operand:PSI 2 "fpscr_operand" ""))
6053    (clobber (match_scratch:SI 3 ""))]
6054   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6055    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
6056   [(const_int 0)]
6058   int regno = true_regnum (operands[0]);
6059   rtx addr, insn;
6060   rtx mem2 = change_address (operands[1], SFmode, NULL_RTX);
6061   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6062   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6064   operands[1] = copy_rtx (mem2);
6065   addr = XEXP (mem2, 0);
6067   switch (GET_CODE (addr))
6068     {
6069     case REG:
6070       /* This is complicated.  If the register is an arithmetic register
6071          we can just fall through to the REG+DISP case below.  Otherwise
6072          we have to use a combination of POST_INC and REG addressing...  */
6073       if (! arith_reg_operand (operands[1], SFmode))
6074         {
6075           XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
6076           insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
6077           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6078           
6079           emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6081           /* If we have modified the stack pointer, the value that we have
6082              read with post-increment might be modified by an interrupt,
6083              so write it back.  */
6084           if (REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
6085             emit_insn (gen_push_e (reg0));
6086           else
6087             emit_insn (gen_addsi3 (XEXP (operands[1], 0), XEXP (operands[1], 0), GEN_INT (-4)));
6088           break;
6089         }
6090       /* Fall through.  */
6091          
6092     case PLUS:
6093       emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6094       operands[1] = copy_rtx (operands[1]);
6095       XEXP (operands[1], 0) = plus_constant (addr, 4);
6096       emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6097       break;
6098       
6099     case POST_INC:
6100       insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2]));
6101       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6102     
6103       insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
6104       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6105       break;
6107     default:
6108       debug_rtx (addr);
6109       gcc_unreachable ();
6110     }
6112   DONE;
6115 (define_split
6116   [(set (match_operand:DF 0 "memory_operand" "")
6117         (match_operand:DF 1 "register_operand" ""))
6118    (use (match_operand:PSI 2 "fpscr_operand" ""))
6119    (clobber (match_scratch:SI 3 ""))]
6120   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
6121    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
6122   [(const_int 0)]
6124   int regno = true_regnum (operands[1]);
6125   rtx insn, addr;
6126   rtx reg0 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 1 : 0));
6127   rtx reg1 = gen_rtx_REG (SFmode, regno + (TARGET_LITTLE_ENDIAN ? 0 : 1));
6129   operands[0] = copy_rtx (operands[0]);
6130   PUT_MODE (operands[0], SFmode);
6131   addr = XEXP (operands[0], 0);
6133   switch (GET_CODE (addr))
6134     {
6135     case REG:
6136       /* This is complicated.  If the register is an arithmetic register
6137          we can just fall through to the REG+DISP case below.  Otherwise
6138          we have to use a combination of REG and PRE_DEC addressing...  */
6139       if (! arith_reg_operand (operands[0], SFmode))
6140         {
6141           emit_insn (gen_addsi3 (addr, addr, GEN_INT (4)));
6142           emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6144           operands[0] = copy_rtx (operands[0]);
6145           XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
6146           
6147           insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6148           add_reg_note (insn, REG_INC, XEXP (addr, 0));
6149           break;
6150         }
6151       /* Fall through.  */
6152       
6153     case PLUS:
6154       /* Since REG+DISP addressing has already been decided upon by gcc
6155          we can rely upon it having chosen an arithmetic register as the
6156          register component of the address.  Just emit the lower numbered
6157          register first, to the lower address, then the higher numbered
6158          register to the higher address.  */
6159       emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6161       operands[0] = copy_rtx (operands[0]);
6162       XEXP (operands[0], 0) = plus_constant (addr, 4);
6164       emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));         
6165       break;
6166       
6167     case PRE_DEC:
6168       /* This is easy.  Output the word to go to the higher address
6169          first (ie the word in the higher numbered register) then the
6170          word to go to the lower address.  */
6172       insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2]));
6173       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6175       insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2]));
6176       add_reg_note (insn, REG_INC, XEXP (addr, 0));
6177       break;
6178       
6179     default:
6180       /* FAIL; */
6181       debug_rtx (addr);
6182       gcc_unreachable ();
6183     }
6185   DONE;
6188 ;; If the output is a register and the input is memory or a register, we have
6189 ;; to be careful and see which word needs to be loaded first.
6191 (define_split
6192   [(set (match_operand:DF 0 "general_movdst_operand" "")
6193         (match_operand:DF 1 "general_movsrc_operand" ""))]
6194   "TARGET_SH1 && reload_completed"
6195   [(set (match_dup 2) (match_dup 3))
6196    (set (match_dup 4) (match_dup 5))]
6197   "
6199   int regno;
6201   if ((MEM_P (operands[0])
6202        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6203       || (MEM_P (operands[1])
6204           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6205     FAIL;
6207   switch (GET_CODE (operands[0]))
6208     {
6209     case REG:
6210       regno = REGNO (operands[0]);
6211       break;
6212     case SUBREG:
6213       regno = subreg_regno (operands[0]);
6214       break;
6215     case MEM:
6216       regno = -1;
6217       break;
6218     default:
6219       gcc_unreachable ();
6220     }
6222   if (regno == -1
6223       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6224     {
6225       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6226       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6227       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6228       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6229     }
6230   else
6231     {
6232       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6233       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6234       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6235       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6236     }
6238   if (operands[2] == 0 || operands[3] == 0
6239       || operands[4] == 0 || operands[5] == 0)
6240     FAIL;
6243 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6244 ;; used only once, let combine add in the index again.
6246 (define_split
6247   [(set (match_operand:SI 0 "register_operand" "")
6248         (match_operand:SI 1 "" ""))
6249    (clobber (match_operand 2 "register_operand" ""))]
6250   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6251    && ALLOW_INDEXED_ADDRESS"
6252   [(use (reg:SI R0_REG))]
6253   "
6255   rtx addr, reg, const_int;
6257   if (!MEM_P (operands[1]))
6258     FAIL;
6259   addr = XEXP (operands[1], 0);
6260   if (GET_CODE (addr) != PLUS)
6261     FAIL;
6262   reg = XEXP (addr, 0);
6263   const_int = XEXP (addr, 1);
6264   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6265          && CONST_INT_P (const_int)))
6266     FAIL;
6267   emit_move_insn (operands[2], const_int);
6268   emit_move_insn (operands[0],
6269                   change_address (operands[1], VOIDmode,
6270                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6271   DONE;
6274 (define_split
6275   [(set (match_operand:SI 1 "" "")
6276         (match_operand:SI 0 "register_operand" ""))
6277    (clobber (match_operand 2 "register_operand" ""))]
6278   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6279    && ALLOW_INDEXED_ADDRESS"
6280   [(use (reg:SI R0_REG))]
6281   "
6283   rtx addr, reg, const_int;
6285   if (!MEM_P (operands[1]))
6286     FAIL;
6287   addr = XEXP (operands[1], 0);
6288   if (GET_CODE (addr) != PLUS)
6289     FAIL;
6290   reg = XEXP (addr, 0);
6291   const_int = XEXP (addr, 1);
6292   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6293          && CONST_INT_P (const_int)))
6294     FAIL;
6295   emit_move_insn (operands[2], const_int);
6296   emit_move_insn (change_address (operands[1], VOIDmode,
6297                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6298                   operands[0]);
6299   DONE;
6302 (define_expand "movdf"
6303   [(set (match_operand:DF 0 "general_movdst_operand" "")
6304         (match_operand:DF 1 "general_movsrc_operand" ""))]
6305   ""
6306   "
6308   if (prepare_move_operands (operands, DFmode)) DONE;
6309   if (TARGET_SHMEDIA)
6310     {
6311       if (TARGET_SHMEDIA_FPU)
6312         emit_insn (gen_movdf_media (operands[0], operands[1]));
6313       else
6314         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6315       DONE;
6316     }
6317   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6318     {
6319       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6320       DONE;
6321     }
6324 ;;This is incompatible with the way gcc uses subregs.
6325 ;;(define_insn "movv2sf_i"
6326 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6327 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6328 ;;  "TARGET_SHMEDIA_FPU
6329 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6330 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6331 ;;  "@
6332 ;;      #
6333 ;;      fld%M1.p        %m1, %0
6334 ;;      fst%M0.p        %m0, %1"
6335 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6337 (define_insn_and_split "movv2sf_i"
6338   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6339         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6340   "TARGET_SHMEDIA_FPU"
6341   "#"
6342   "TARGET_SHMEDIA_FPU && reload_completed"
6343   [(set (match_dup 0) (match_dup 1))]
6344   "
6346   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6347   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6350 (define_expand "movv2sf"
6351   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6352         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6353   "TARGET_SHMEDIA_FPU"
6354   "
6356   if (prepare_move_operands (operands, V2SFmode))
6357     DONE;
6360 (define_expand "addv2sf3"
6361   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6362    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6363    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6364   "TARGET_SHMEDIA_FPU"
6365   "
6367   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6368   DONE;
6371 (define_expand "subv2sf3"
6372   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6373    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6374    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6375   "TARGET_SHMEDIA_FPU"
6376   "
6378   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6379   DONE;
6382 (define_expand "mulv2sf3"
6383   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6384    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6385    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6386   "TARGET_SHMEDIA_FPU"
6387   "
6389   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6390   DONE;
6393 (define_expand "divv2sf3"
6394   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6395    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6396    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6397   "TARGET_SHMEDIA_FPU"
6398   "
6400   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6401   DONE;
6404 (define_insn_and_split "*movv4sf_i"
6405   [(set (match_operand:V4SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6406         (match_operand:V4SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6407   "TARGET_SHMEDIA_FPU"
6408   "#"
6409   "&& reload_completed"
6410   [(const_int 0)]
6411   "
6413   int i;
6415   for (i = 0; i < 4/2; i++)
6416     {
6417       rtx x, y;
6419       if (MEM_P (operands[0]))
6420         x = adjust_address (operands[0], V2SFmode,
6421                             i * GET_MODE_SIZE (V2SFmode));
6422       else
6423         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6425       if (MEM_P (operands[1]))
6426         y = adjust_address (operands[1], V2SFmode,
6427                             i * GET_MODE_SIZE (V2SFmode));
6428       else
6429         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6431       emit_insn (gen_movv2sf_i (x, y));
6432     }
6434   DONE;
6436   [(set_attr "length" "8")])
6438 (define_expand "movv4sf"
6439   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6440         (match_operand:V4SF 1 "general_operand" ""))]
6441   "TARGET_SHMEDIA_FPU"
6442   "
6444   if (prepare_move_operands (operands, V4SFmode))
6445     DONE;
6448 (define_insn_and_split "*movv16sf_i"
6449   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6450         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6451   "TARGET_SHMEDIA_FPU"
6452   "#"
6453   "&& reload_completed"
6454   [(const_int 0)]
6455   "
6457   int i;
6459   for (i = 0; i < 16/2; i++)
6460     {
6461       rtx x,y;
6463       if (MEM_P (operands[0]))
6464         x = adjust_address (operands[0], V2SFmode,
6465                             i * GET_MODE_SIZE (V2SFmode));
6466       else
6467         {
6468           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6469           alter_subreg (&x);
6470         }
6472       if (MEM_P (operands[1]))
6473         y = adjust_address (operands[1], V2SFmode,
6474                             i * GET_MODE_SIZE (V2SFmode));
6475       else
6476         {
6477           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6478           alter_subreg (&y);
6479         }
6481       emit_insn (gen_movv2sf_i (x, y));
6482     }
6484   DONE;
6486   [(set_attr "length" "32")])
6488 (define_expand "movv16sf"
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   "
6494   if (prepare_move_operands (operands, V16SFmode))
6495     DONE;
6498 (define_insn "movsf_media"
6499   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6500         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6501   "TARGET_SHMEDIA_FPU
6502    && (register_operand (operands[0], SFmode)
6503        || sh_register_operand (operands[1], SFmode))"
6504   "@
6505         fmov.s  %1, %0
6506         fmov.ls %N1, %0
6507         fmov.sl %1, %0
6508         add.l   %1, r63, %0
6509         #
6510         fld%M1.s        %m1, %0
6511         fst%M0.s        %m0, %1
6512         ld%M1.l %m1, %0
6513         st%M0.l %m0, %N1"
6514   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6515    (set (attr "highpart")
6516         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6517                (const_string "user")]
6518               (const_string "ignore")))])
6520 (define_insn "movsf_media_nofpu"
6521   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6522         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6523   "TARGET_SHMEDIA
6524    && (register_operand (operands[0], SFmode)
6525        || sh_register_operand (operands[1], SFmode))"
6526   "@
6527         add.l   %1, r63, %0
6528         #
6529         ld%M1.l %m1, %0
6530         st%M0.l %m0, %N1"
6531   [(set_attr "type" "arith_media,*,load_media,store_media")
6532    (set (attr "highpart")
6533         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6534                (const_string "user")]
6535               (const_string "ignore")))])
6537 (define_split
6538   [(set (match_operand:SF 0 "arith_reg_dest" "")
6539         (match_operand:SF 1 "immediate_operand" ""))]
6540   "TARGET_SHMEDIA && reload_completed
6541    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6542   [(set (match_dup 3) (match_dup 2))]
6543   "
6545   long values;
6546   REAL_VALUE_TYPE value;
6548   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6549   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6550   operands[2] = GEN_INT (values);
6552   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6555 (define_insn "movsf_i"
6556   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6557         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6558   "TARGET_SH1
6559    && (! TARGET_SH2E
6560        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6561        || (REG_P (operands[0]) && REGNO (operands[0]) == 3)
6562        || (REG_P (operands[1]) && REGNO (operands[1]) == 3))
6563    && (arith_reg_operand (operands[0], SFmode)
6564        || arith_reg_operand (operands[1], SFmode))"
6565   "@
6566         mov     %1,%0
6567         mov     #0,%0
6568         mov.l   %1,%0
6569         mov.l   %1,%0
6570         mov.l   %1,%0
6571         lds     %1,%0
6572         sts     %1,%0"
6573   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6575 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6576 ;; update_flow_info would not know where to put REG_EQUAL notes
6577 ;; when the destination changes mode.
6578 (define_insn "movsf_ie"
6579   [(set (match_operand:SF 0 "general_movdst_operand"
6580          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6581         (match_operand:SF 1 "general_movsrc_operand"
6582           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6583    (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"))
6584    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6586   "TARGET_SH2E
6587    && (arith_reg_operand (operands[0], SFmode)
6588        || arith_reg_operand (operands[1], SFmode)
6589        || arith_reg_operand (operands[3], SImode)
6590        || (fpul_operand (operands[0], SFmode)
6591            && memory_operand (operands[1], SFmode)
6592            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6593        || (fpul_operand (operands[1], SFmode)
6594            && memory_operand (operands[0], SFmode)
6595            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6596   "@
6597         fmov    %1,%0
6598         mov     %1,%0
6599         fldi0   %0
6600         fldi1   %0
6601         #
6602         fmov.s  %1,%0
6603         fmov.s  %1,%0
6604         mov.l   %1,%0
6605         mov.l   %1,%0
6606         mov.l   %1,%0
6607         fsts    fpul,%0
6608         flds    %1,fpul
6609         lds.l   %1,%0
6610         #
6611         sts     %1,%0
6612         lds     %1,%0
6613         sts.l   %1,%0
6614         lds.l   %1,%0
6615         ! move optimized away"
6616   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil")
6617    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6618    (set_attr_alternative "length"
6619      [(const_int 2)
6620       (const_int 2)
6621       (const_int 2)
6622       (const_int 2)
6623       (const_int 4)
6624       (if_then_else
6625         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6626         (const_int 4) (const_int 2))
6627       (if_then_else
6628         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6629         (const_int 4) (const_int 2))
6630       (const_int 2)
6631       (if_then_else
6632         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6633         (const_int 4) (const_int 2))
6634       (if_then_else
6635         (ne (symbol_ref "TARGET_SH2A") (const_int 0))
6636         (const_int 4) (const_int 2))
6637       (const_int 2)
6638       (const_int 2)
6639       (const_int 2)
6640       (const_int 4)
6641       (const_int 2)
6642       (const_int 2)
6643       (const_int 2)
6644       (const_int 2)
6645       (const_int 0)])
6646    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6647                                            (const_string "single")
6648                                            (const_string "single")))])
6650 (define_split
6651   [(set (match_operand:SF 0 "register_operand" "")
6652         (match_operand:SF 1 "register_operand" ""))
6653    (use (match_operand:PSI 2 "fpscr_operand" ""))
6654    (clobber (reg:SI FPUL_REG))]
6655   "TARGET_SH1"
6656   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6657               (use (match_dup 2))
6658               (clobber (scratch:SI))])
6659    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6660               (use (match_dup 2))
6661               (clobber (scratch:SI))])]
6662   "")
6664 (define_expand "movsf"
6665   [(set (match_operand:SF 0 "general_movdst_operand" "")
6666         (match_operand:SF 1 "general_movsrc_operand" ""))]
6667   ""
6668   "
6670   if (prepare_move_operands (operands, SFmode))
6671     DONE;
6672   if (TARGET_SHMEDIA)
6673     {
6674       if (TARGET_SHMEDIA_FPU)
6675         emit_insn (gen_movsf_media (operands[0], operands[1]));
6676       else
6677         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6678       DONE;
6679     }
6680   if (TARGET_SH2E)
6681     {
6682       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6683       DONE;
6684     }
6687 (define_insn "mov_nop"
6688   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6689   "TARGET_SH2E"
6690   ""
6691   [(set_attr "length" "0")
6692    (set_attr "type" "nil")])
6694 (define_expand "reload_insf__frn"
6695   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6696                    (match_operand:SF 1 "immediate_operand" "FQ"))
6697               (use (reg:PSI FPSCR_REG))
6698               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6699   "TARGET_SH1"
6700   "")
6702 (define_expand "reload_insi__i_fpul"
6703   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6704                    (match_operand:SI 1 "immediate_operand" "i"))
6705               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6706   "TARGET_SH1"
6707   "")
6709 (define_expand "ptabs"
6710   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6711   "TARGET_SHMEDIA"
6712   "
6714   if (!TARGET_PT_FIXED)
6715     {
6716       rtx eq = operands[1];
6718       /* ??? For canonical RTL we really should remove any CONST from EQ
6719          before wrapping it in the AND, and finally wrap the EQ into a
6720          const if is constant.  However, for reload we must expose the
6721          input register or symbolic constant, and we can't have
6722          different insn structures outside of the operands for different
6723          alternatives of the same pattern.  */
6724       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6725                        GEN_INT (3));
6726       operands[1]
6727         = (gen_rtx_IF_THEN_ELSE
6728             (PDImode,
6729              eq,
6730              gen_rtx_MEM (PDImode, operands[1]),
6731              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6732                             PDImode, operands[1])));
6733     }
6736 ;; expanded by ptabs expander.
6737 (define_insn "*extendsipdi_media"
6738   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6739         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6740                                                           "r,Csy")
6741                                       (const_int 3))
6742                               (const_int 3))
6743                           (mem:PDI (match_dup 1))
6744                           (sign_extend:PDI (match_dup 1))))]
6745   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6746   "@
6747         ptabs   %1, %0
6748         pt      %1, %0"
6749   [(set_attr "type"   "ptabs_media,pt_media")
6750    (set_attr "length" "4,*")])
6752 (define_insn "*truncdipdi_media"
6753   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6754         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6755                                                           "r,Csy")
6756                                       (const_int 3))
6757                               (const_int 3))
6758                           (mem:PDI (match_dup 1))
6759                           (truncate:PDI (match_dup 1))))]
6760   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6761   "@
6762         ptabs   %1, %0
6763         pt      %1, %0"
6764   [(set_attr "type"   "ptabs_media,pt_media")
6765    (set_attr "length" "4,*")])
6767 (define_insn "*movsi_y"
6768   [(set (match_operand:SI 0 "register_operand" "=y,y")
6769         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6770    (clobber (match_scratch:SI 2 "=&z,r"))]
6771   "TARGET_SH2E
6772    && (reload_in_progress || reload_completed)"
6773   "#"
6774   [(set_attr "length" "4")
6775    (set_attr "type" "pcload,move")])
6777 (define_split
6778   [(set (match_operand:SI 0 "register_operand" "")
6779         (match_operand:SI 1 "immediate_operand" ""))
6780    (clobber (match_operand:SI 2 "register_operand" ""))]
6781   "TARGET_SH1"
6782   [(set (match_dup 2) (match_dup 1))
6783    (set (match_dup 0) (match_dup 2))]
6784   "")
6786 (define_split
6787   [(set (match_operand:SI 0 "register_operand" "")
6788         (match_operand:SI 1 "memory_operand" ""))
6789    (clobber (reg:SI R0_REG))]
6790   "TARGET_SH1"
6791   [(set (match_dup 0) (match_dup 1))]
6792   "")
6794 ;; ------------------------------------------------------------------------
6795 ;; Define the real conditional branch instructions.
6796 ;; ------------------------------------------------------------------------
6798 (define_insn "branch_true"
6799   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6800                            (label_ref (match_operand 0 "" ""))
6801                            (pc)))]
6802   "TARGET_SH1"
6803   "* return output_branch (1, insn, operands);"
6804   [(set_attr "type" "cbranch")])
6806 (define_insn "branch_false"
6807   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6808                            (label_ref (match_operand 0 "" ""))
6809                            (pc)))]
6810   "TARGET_SH1"
6811   "* return output_branch (0, insn, operands);"
6812   [(set_attr "type" "cbranch")])
6814 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6815 ;; which destination is too far away.
6816 ;; The const_int_operand is distinct for each branch target; it avoids
6817 ;; unwanted matches with redundant_insn.
6818 (define_insn "block_branch_redirect"
6819   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6820   "TARGET_SH1"
6821   ""
6822   [(set_attr "length" "0")])
6824 ;; This one has the additional purpose to record a possible scratch register
6825 ;; for the following branch.
6826 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6827 ;; because the insn then might be deemed dead and deleted.  And we can't
6828 ;; make the use in the jump insn explicit because that would disable
6829 ;; delay slot scheduling from the target.
6830 (define_insn "indirect_jump_scratch"
6831   [(set (match_operand:SI 0 "register_operand" "=r")
6832         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6833    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6834   "TARGET_SH1"
6835   ""
6836   [(set_attr "length" "0")])
6838 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6839 ;; being pulled into the delay slot of a condbranch that has been made to
6840 ;; jump around the unconditional jump because it was out of range.
6841 (define_insn "stuff_delay_slot"
6842   [(set (pc)
6843         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)
6844                  (match_operand:SI 1 "const_int_operand" "")] UNSPEC_BBR))]
6845   "TARGET_SH1"
6846   ""
6847   [(set_attr "length" "0")
6848    (set_attr "cond_delay_slot" "yes")])
6850 ;; Conditional branch insns
6852 (define_expand "cbranchint4_media"
6853   [(set (pc)
6854         (if_then_else (match_operator 0 "shmedia_cbranch_comparison_operator"
6855                        [(match_operand 1 "" "")
6856                         (match_operand 2 "" "")])
6857                       (match_operand 3 "" "")
6858                       (pc)))]
6859   "TARGET_SHMEDIA"
6860   "
6862   enum machine_mode mode = GET_MODE (operands[1]);
6863   if (mode == VOIDmode)
6864     mode = GET_MODE (operands[2]);
6865   if (GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
6866     {
6867       operands[1] = force_reg (mode, operands[1]);
6868       if (CONSTANT_P (operands[2])
6869           && (! satisfies_constraint_I06 (operands[2])))
6870         operands[2] = force_reg (mode, operands[2]);
6871     }
6872   else
6873     {
6874       if (operands[1] != const0_rtx)
6875         operands[1] = force_reg (mode, operands[1]);
6876       if (operands[2] != const0_rtx)
6877         operands[2] = force_reg (mode, operands[2]);
6878     }
6879   switch (GET_CODE (operands[0]))
6880     {
6881     case LEU:
6882     case LE:
6883     case LTU:
6884     case LT:
6885       operands[0] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[0])),
6886                                     VOIDmode, operands[2], operands[1]);
6887       operands[1] = XEXP (operands[0], 0);
6888       operands[2] = XEXP (operands[0], 1);
6889       break;
6890     default:
6891       operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
6892                                     VOIDmode, operands[1], operands[2]);
6893       break;
6894     }
6895   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6898 (define_expand "cbranchfp4_media"
6899   [(set (pc)
6900         (if_then_else (match_operator 0 "sh_float_comparison_operator"
6901                        [(match_operand 1 "" "")
6902                         (match_operand 2 "" "")])
6903                       (match_operand 3 "" "")
6904                       (pc)))]
6905   "TARGET_SHMEDIA"
6906   "
6908   rtx tmp = gen_reg_rtx (SImode);
6909   rtx cmp;
6910   if (GET_CODE (operands[0]) == NE)
6911     cmp = gen_rtx_EQ (SImode, operands[1], operands[2]);
6912   else
6913     cmp = gen_rtx_fmt_ee (GET_CODE (operands[0]), SImode,
6914                           operands[1], operands[2]);
6916   emit_insn (gen_cstore4_media (tmp, cmp, operands[1], operands[2]));
6918   if (GET_CODE (cmp) == GET_CODE (operands[0]))
6919     operands[0] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
6920   else
6921     operands[0] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
6922   operands[1] = tmp;
6923   operands[2] = const0_rtx;
6924   operands[3] = gen_rtx_LABEL_REF (Pmode, operands[3]);
6927 (define_insn "*beq_media_i"
6928   [(set (pc)
6929         (if_then_else (match_operator 3 "equality_comparison_operator"
6930                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6931                          (match_operand:DI 2 "arith_operand" "r,I06")])
6932                       (match_operand 0 "target_operand" "b,b")
6933                       (pc)))]
6934   "TARGET_SHMEDIA"
6935   "@
6936         b%o3%'  %1, %2, %0%>
6937         b%o3i%' %1, %2, %0%>"
6938   [(set_attr "type" "cbranch_media")])
6940 (define_insn "*beq_media_i32"
6941   [(set (pc)
6942         (if_then_else (match_operator 3 "equality_comparison_operator"
6943                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6944                          (match_operand:SI 2 "arith_operand" "r,I06")])
6945                       (match_operand 0 "target_operand" "b,b")
6946                       (pc)))]
6947   "TARGET_SHMEDIA"
6948   "@
6949         b%o3%'  %1, %2, %0%>
6950         b%o3i%' %1, %2, %0%>"
6951   [(set_attr "type" "cbranch_media")])
6953 (define_insn "*bgt_media_i"
6954   [(set (pc)
6955         (if_then_else (match_operator 3 "greater_comparison_operator"
6956                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6957                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6958                       (match_operand 0 "target_operand" "b")
6959                       (pc)))]
6960   "TARGET_SHMEDIA"
6961   "b%o3%'       %N1, %N2, %0%>"
6962   [(set_attr "type" "cbranch_media")])
6964 (define_insn "*bgt_media_i32"
6965   [(set (pc)
6966         (if_then_else (match_operator 3 "greater_comparison_operator"
6967                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6968                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6969                       (match_operand 0 "target_operand" "b")
6970                       (pc)))]
6971   "TARGET_SHMEDIA"
6972   "b%o3%'       %N1, %N2, %0%>"
6973   [(set_attr "type" "cbranch_media")])
6975 ;; These are only needed to make invert_jump() happy - otherwise, jump
6976 ;; optimization will be silently disabled.
6977 (define_insn "*blt_media_i"
6978   [(set (pc)
6979         (if_then_else (match_operator 3 "less_comparison_operator"
6980                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6981                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6982                       (match_operand 0 "target_operand" "b")
6983                       (pc)))]
6984   "TARGET_SHMEDIA"
6985   "b%o3%'       %N2, %N1, %0%>"
6986   [(set_attr "type" "cbranch_media")])
6988 (define_insn "*blt_media_i32"
6989   [(set (pc)
6990         (if_then_else (match_operator 3 "less_comparison_operator"
6991                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6992                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6993                       (match_operand 0 "target_operand" "b")
6994                       (pc)))]
6995   "TARGET_SHMEDIA"
6996   "b%o3%'       %N2, %N1, %0%>"
6997   [(set_attr "type" "cbranch_media")])
6999 ;; combiner splitter for test-and-branch on single bit in register.  This
7000 ;; is endian dependent because the non-paradoxical subreg looks different
7001 ;; on big endian.
7002 (define_split
7003   [(set (pc)
7004         (if_then_else
7005           (match_operator 3 "equality_comparison_operator"
7006             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7007                                                       "extend_reg_operand" "")
7008                                                     0)
7009                                          (const_int 1)
7010                                          (match_operand 2
7011                                           "const_int_operand" "")) 0)
7012              (const_int 0)])
7013           (match_operand 0 "target_operand" "")
7014           (pc)))
7015    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7016   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7017   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7018    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7020   "
7022   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7023   operands[6] = (GET_CODE (operands[3]) == EQ
7024                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7025                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7028 ; operand 0 is the loop count pseudo register
7029 ; operand 1 is the number of loop iterations or 0 if it is unknown
7030 ; operand 2 is the maximum number of loop iterations
7031 ; operand 3 is the number of levels of enclosed loops
7032 ; operand 4 is the label to jump to at the top of the loop
7034 (define_expand "doloop_end"
7035   [(parallel [(set (pc) (if_then_else
7036                           (ne:SI (match_operand:SI 0 "" "")
7037                               (const_int 1))
7038                           (label_ref (match_operand 4 "" ""))
7039                           (pc)))
7040               (set (match_dup 0)
7041                    (plus:SI (match_dup 0) (const_int -1)))
7042               (clobber (reg:SI T_REG))])]
7043   "TARGET_SH2"
7044   "
7046   if (GET_MODE (operands[0]) != SImode)
7047     FAIL;
7051 (define_insn_and_split "doloop_end_split"
7052   [(set (pc)
7053         (if_then_else (ne:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7054                           (const_int 1))
7055                       (label_ref (match_operand 1 "" ""))
7056                       (pc)))
7057    (set (match_dup 0)
7058         (plus (match_dup 0) (const_int -1)))
7059    (clobber (reg:SI T_REG))]
7060   "TARGET_SH2"
7061   "#"
7062   ""
7063   [(parallel [(set (reg:SI T_REG)
7064                    (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r")
7065                           (const_int 1)))
7066               (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))])
7067    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7068                            (label_ref (match_operand 1 "" ""))
7069                            (pc)))]
7071    [(set_attr "type" "cbranch")])
7074 ;; ------------------------------------------------------------------------
7075 ;; Jump and linkage insns
7076 ;; ------------------------------------------------------------------------
7078 (define_insn "jump_compact"
7079   [(set (pc)
7080         (label_ref (match_operand 0 "" "")))]
7081   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7082   "*
7084   /* The length is 16 if the delay slot is unfilled.  */
7085   if (get_attr_length(insn) > 4)
7086     return output_far_jump(insn, operands[0]);
7087   else
7088     return   \"bra      %l0%#\";
7090   [(set_attr "type" "jump")
7091    (set_attr "needs_delay_slot" "yes")])
7093 ;; ??? It would be much saner to explicitly use the scratch register
7094 ;; in the jump insn, and have indirect_jump_scratch only set it,
7095 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7096 ;; from the target then, as it uses simplejump_p.
7097 ;;(define_insn "jump_compact_far"
7098 ;;  [(set (pc)
7099 ;;      (label_ref (match_operand 0 "" "")))
7100 ;;   (use (match_operand 1 "register_operand" "r")]
7101 ;;  "TARGET_SH1"
7102 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7103 ;;  [(set_attr "type" "jump")
7104 ;;   (set_attr "needs_delay_slot" "yes")])
7106 (define_insn "jump_media"
7107   [(set (pc)
7108         (match_operand 0 "target_operand" "b"))]
7109   "TARGET_SHMEDIA"
7110   "blink        %0, r63%>"
7111   [(set_attr "type" "jump_media")])
7113 (define_expand "jump"
7114   [(set (pc)
7115         (label_ref (match_operand 0 "" "")))]
7116   ""
7117   "
7119   if (TARGET_SH1)
7120     emit_jump_insn (gen_jump_compact (operands[0]));
7121   else if (TARGET_SHMEDIA)
7122     {
7123       if (reload_in_progress || reload_completed)
7124         FAIL;
7125       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7126                                                          operands[0])));
7127     }
7128   DONE;
7131 (define_insn "force_mode_for_call"
7132   [(use (reg:PSI FPSCR_REG))]
7133   "TARGET_SHCOMPACT"
7134   ""
7135   [(set_attr "length" "0")
7136    (set (attr "fp_mode")
7137         (if_then_else (eq_attr "fpu_single" "yes")
7138                       (const_string "single") (const_string "double")))])
7140 (define_insn "calli"
7141   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7142          (match_operand 1 "" ""))
7143    (use (reg:PSI FPSCR_REG))
7144    (clobber (reg:SI PR_REG))]
7145   "TARGET_SH1"
7146   "*
7147    {
7148      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7149         return \"jsr/n\\t@%0\";
7150      else
7151         return \"jsr\\t@%0%#\";
7152    }"
7154   [(set_attr "type" "call")
7155    (set (attr "fp_mode")
7156         (if_then_else (eq_attr "fpu_single" "yes")
7157                       (const_string "single") (const_string "double")))
7158    (set_attr "needs_delay_slot" "yes")
7159    (set_attr "fp_set" "unknown")])
7161 ;; This is TBR relative jump instruction for SH2A architecture.
7162 ;; Its use is enabled assigning an attribute "function_vector"
7163 ;; and the vector number to a function during its declaration.
7165 (define_insn "calli_tbr_rel"
7166   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7167          (match_operand 1 "" ""))
7168    (use (reg:PSI FPSCR_REG))
7169    (clobber (reg:SI PR_REG))]
7170   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7171   "*
7173   unsigned HOST_WIDE_INT vect_num;
7174   vect_num = sh2a_get_function_vector_number (operands[0]);
7175   operands[2] = GEN_INT (vect_num * 4);
7177   return \"jsr/n\\t@@(%O2,tbr)\";
7179   [(set_attr "type" "call")
7180    (set (attr "fp_mode")
7181         (if_then_else (eq_attr "fpu_single" "yes")
7182                       (const_string "single") (const_string "double")))
7183    (set_attr "needs_delay_slot" "no")
7184    (set_attr "fp_set" "unknown")])
7186 ;; This is a pc-rel call, using bsrf, for use with PIC.
7188 (define_insn "calli_pcrel"
7189   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7190          (match_operand 1 "" ""))
7191    (use (reg:PSI FPSCR_REG))
7192    (use (reg:SI PIC_REG))
7193    (use (match_operand 2 "" ""))
7194    (clobber (reg:SI PR_REG))]
7195   "TARGET_SH2"
7196   "bsrf %0\\n%O2:%#"
7197   [(set_attr "type" "call")
7198    (set (attr "fp_mode")
7199         (if_then_else (eq_attr "fpu_single" "yes")
7200                       (const_string "single") (const_string "double")))
7201    (set_attr "needs_delay_slot" "yes")
7202    (set_attr "fp_set" "unknown")])
7204 (define_insn_and_split "call_pcrel"
7205   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7206          (match_operand 1 "" ""))
7207    (use (reg:PSI FPSCR_REG))
7208    (use (reg:SI PIC_REG))
7209    (clobber (reg:SI PR_REG))
7210    (clobber (match_scratch:SI 2 "=r"))]
7211   "TARGET_SH2"
7212   "#"
7213   "reload_completed"
7214   [(const_int 0)]
7215   "
7217   rtx lab = PATTERN (gen_call_site ());
7219   if (SYMBOL_REF_LOCAL_P (operands[0]))
7220     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7221   else
7222     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7223   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7224   DONE;
7226   [(set_attr "type" "call")
7227    (set (attr "fp_mode")
7228         (if_then_else (eq_attr "fpu_single" "yes")
7229                       (const_string "single") (const_string "double")))
7230    (set_attr "needs_delay_slot" "yes")
7231    (set_attr "fp_set" "unknown")])
7233 (define_insn "call_compact"
7234   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7235          (match_operand 1 "" ""))
7236    (match_operand 2 "immediate_operand" "n")
7237    (use (reg:SI R0_REG))
7238    (use (reg:SI R1_REG))
7239    (use (reg:PSI FPSCR_REG))
7240    (clobber (reg:SI PR_REG))]
7241   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7242   "jsr  @%0%#"
7243   [(set_attr "type" "call")
7244    (set (attr "fp_mode")
7245         (if_then_else (eq_attr "fpu_single" "yes")
7246                       (const_string "single") (const_string "double")))
7247    (set_attr "needs_delay_slot" "yes")])
7249 (define_insn "call_compact_rettramp"
7250   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7251          (match_operand 1 "" ""))
7252    (match_operand 2 "immediate_operand" "n")
7253    (use (reg:SI R0_REG))
7254    (use (reg:SI R1_REG))
7255    (use (reg:PSI FPSCR_REG))
7256    (clobber (reg:SI R10_REG))
7257    (clobber (reg:SI PR_REG))]
7258   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7259   "jsr  @%0%#"
7260   [(set_attr "type" "call")
7261    (set (attr "fp_mode")
7262         (if_then_else (eq_attr "fpu_single" "yes")
7263                       (const_string "single") (const_string "double")))
7264    (set_attr "needs_delay_slot" "yes")])
7266 (define_insn "call_media"
7267   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7268          (match_operand 1 "" ""))
7269    (clobber (reg:DI PR_MEDIA_REG))]
7270   "TARGET_SHMEDIA"
7271   "blink        %0, r18"
7272   [(set_attr "type" "jump_media")])
7274 (define_insn "call_valuei"
7275   [(set (match_operand 0 "" "=rf")
7276         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7277               (match_operand 2 "" "")))
7278    (use (reg:PSI FPSCR_REG))
7279    (clobber (reg:SI PR_REG))]
7280   "TARGET_SH1"
7281   "*
7282    {
7283      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7284         return \"jsr/n\\t@%1\";
7285      else
7286         return \"jsr\\t@%1%#\";
7287    }"
7288   [(set_attr "type" "call")
7289    (set (attr "fp_mode")
7290         (if_then_else (eq_attr "fpu_single" "yes")
7291                       (const_string "single") (const_string "double")))
7292    (set_attr "needs_delay_slot" "yes")
7293    (set_attr "fp_set" "unknown")])
7295 ;; This is TBR relative jump instruction for SH2A architecture.
7296 ;; Its use is enabled assigning an attribute "function_vector"
7297 ;; and the vector number to a function during its declaration.
7299 (define_insn "call_valuei_tbr_rel"
7300   [(set (match_operand 0 "" "=rf")
7301         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7302               (match_operand 2 "" "")))
7303    (use (reg:PSI FPSCR_REG))
7304    (clobber (reg:SI PR_REG))]
7305   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7306   "*
7308   unsigned HOST_WIDE_INT vect_num;
7309   vect_num = sh2a_get_function_vector_number (operands[1]);
7310   operands[3] = GEN_INT (vect_num * 4);
7312   return \"jsr/n\\t@@(%O3,tbr)\";
7314   [(set_attr "type" "call")
7315    (set (attr "fp_mode")
7316         (if_then_else (eq_attr "fpu_single" "yes")
7317                       (const_string "single") (const_string "double")))
7318    (set_attr "needs_delay_slot" "no")
7319    (set_attr "fp_set" "unknown")])
7321 (define_insn "call_valuei_pcrel"
7322   [(set (match_operand 0 "" "=rf")
7323         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7324               (match_operand 2 "" "")))
7325    (use (reg:PSI FPSCR_REG))
7326    (use (reg:SI PIC_REG))
7327    (use (match_operand 3 "" ""))
7328    (clobber (reg:SI PR_REG))]
7329   "TARGET_SH2"
7330   "bsrf %1\\n%O3:%#"
7331   [(set_attr "type" "call")
7332    (set (attr "fp_mode")
7333         (if_then_else (eq_attr "fpu_single" "yes")
7334                       (const_string "single") (const_string "double")))
7335    (set_attr "needs_delay_slot" "yes")
7336    (set_attr "fp_set" "unknown")])
7338 (define_insn_and_split "call_value_pcrel"
7339   [(set (match_operand 0 "" "=rf")
7340         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7341               (match_operand 2 "" "")))
7342    (use (reg:PSI FPSCR_REG))
7343    (use (reg:SI PIC_REG))
7344    (clobber (reg:SI PR_REG))
7345    (clobber (match_scratch:SI 3 "=r"))]
7346   "TARGET_SH2"
7347   "#"
7348   "reload_completed"
7349   [(const_int 0)]
7350   "
7352   rtx lab = PATTERN (gen_call_site ());
7354   if (SYMBOL_REF_LOCAL_P (operands[1]))
7355     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7356   else
7357     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7358   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7359                                          operands[2], copy_rtx (lab)));
7360   DONE;
7362   [(set_attr "type" "call")
7363    (set (attr "fp_mode")
7364         (if_then_else (eq_attr "fpu_single" "yes")
7365                       (const_string "single") (const_string "double")))
7366    (set_attr "needs_delay_slot" "yes")
7367    (set_attr "fp_set" "unknown")])
7369 (define_insn "call_value_compact"
7370   [(set (match_operand 0 "" "=rf")
7371         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7372               (match_operand 2 "" "")))
7373    (match_operand 3 "immediate_operand" "n")
7374    (use (reg:SI R0_REG))
7375    (use (reg:SI R1_REG))
7376    (use (reg:PSI FPSCR_REG))
7377    (clobber (reg:SI PR_REG))]
7378   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7379   "jsr  @%1%#"
7380   [(set_attr "type" "call")
7381    (set (attr "fp_mode")
7382         (if_then_else (eq_attr "fpu_single" "yes")
7383                       (const_string "single") (const_string "double")))
7384    (set_attr "needs_delay_slot" "yes")])
7386 (define_insn "call_value_compact_rettramp"
7387   [(set (match_operand 0 "" "=rf")
7388         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7389               (match_operand 2 "" "")))
7390    (match_operand 3 "immediate_operand" "n")
7391    (use (reg:SI R0_REG))
7392    (use (reg:SI R1_REG))
7393    (use (reg:PSI FPSCR_REG))
7394    (clobber (reg:SI R10_REG))
7395    (clobber (reg:SI PR_REG))]
7396   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7397   "jsr  @%1%#"
7398   [(set_attr "type" "call")
7399    (set (attr "fp_mode")
7400         (if_then_else (eq_attr "fpu_single" "yes")
7401                       (const_string "single") (const_string "double")))
7402    (set_attr "needs_delay_slot" "yes")])
7404 (define_insn "call_value_media"
7405   [(set (match_operand 0 "" "=rf")
7406         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7407               (match_operand 2 "" "")))
7408    (clobber (reg:DI PR_MEDIA_REG))]
7409   "TARGET_SHMEDIA"
7410   "blink        %1, r18"
7411   [(set_attr "type" "jump_media")])
7413 (define_expand "call"
7414   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7415                             (match_operand 1 "" ""))
7416               (match_operand 2 "" "")
7417               (use (reg:PSI FPSCR_REG))
7418               (clobber (reg:SI PR_REG))])]
7419   ""
7420   "
7422   if (TARGET_SHMEDIA)
7423     {
7424       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7425       emit_call_insn (gen_call_media (operands[0], operands[1]));
7426       DONE;
7427     }
7428   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7429     {
7430       rtx cookie_rtx = operands[2];
7431       long cookie = INTVAL (cookie_rtx);
7432       rtx func = XEXP (operands[0], 0);
7433       rtx r0, r1;
7435       if (flag_pic)
7436         {
7437           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7438             {
7439               rtx reg = gen_reg_rtx (Pmode);
7441               emit_insn (gen_symGOTPLT2reg (reg, func));
7442               func = reg;
7443             }
7444           else
7445             func = legitimize_pic_address (func, Pmode, 0);
7446         }
7448       r0 = gen_rtx_REG (SImode, R0_REG);
7449       r1 = gen_rtx_REG (SImode, R1_REG);
7451       /* Since such a call function may use all call-clobbered
7452          registers, we force a mode switch earlier, so that we don't
7453          run out of registers when adjusting fpscr for the call.  */
7454       emit_insn (gen_force_mode_for_call ());
7456       operands[0]
7457         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7458                            SFUNC_GOT);
7459       operands[0] = force_reg (SImode, operands[0]);
7461       emit_move_insn (r0, func);
7462       emit_move_insn (r1, cookie_rtx);
7464       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7465         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7466                                                    operands[2]));
7467       else
7468         emit_call_insn (gen_call_compact (operands[0], operands[1],
7469                                           operands[2]));
7471       DONE;
7472     }
7473   else if (TARGET_SHCOMPACT && flag_pic
7474            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7475            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7476     {
7477       rtx reg = gen_reg_rtx (Pmode);
7479       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7480       XEXP (operands[0], 0) = reg;
7481     }
7482   if (!flag_pic && TARGET_SH2A
7483       && MEM_P (operands[0])
7484       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7485     {
7486       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7487         {
7488           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7489                                              operands[1]));
7490           DONE;
7491         }
7492     }
7493   if (flag_pic && TARGET_SH2
7494       && MEM_P (operands[0])
7495       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7496     {
7497       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7498       DONE;
7499     }
7500   else
7501   {
7502     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7503     operands[1] = operands[2];
7504   }
7506   emit_call_insn (gen_calli (operands[0], operands[1]));
7507   DONE;
7510 (define_insn "call_pop_compact"
7511   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7512          (match_operand 1 "" ""))
7513    (match_operand 2 "immediate_operand" "n")
7514    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7515                                  (match_operand 3 "immediate_operand" "n")))
7516    (use (reg:SI R0_REG))
7517    (use (reg:SI R1_REG))
7518    (use (reg:PSI FPSCR_REG))
7519    (clobber (reg:SI PR_REG))]
7520   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7521   "jsr  @%0%#"
7522   [(set_attr "type" "call")
7523    (set (attr "fp_mode")
7524         (if_then_else (eq_attr "fpu_single" "yes")
7525                       (const_string "single") (const_string "double")))
7526    (set_attr "needs_delay_slot" "yes")])
7528 (define_insn "call_pop_compact_rettramp"
7529   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7530          (match_operand 1 "" ""))
7531    (match_operand 2 "immediate_operand" "n")
7532    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7533                                  (match_operand 3 "immediate_operand" "n")))
7534    (use (reg:SI R0_REG))
7535    (use (reg:SI R1_REG))
7536    (use (reg:PSI FPSCR_REG))
7537    (clobber (reg:SI R10_REG))
7538    (clobber (reg:SI PR_REG))]
7539   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7540   "jsr  @%0%#"
7541   [(set_attr "type" "call")
7542    (set (attr "fp_mode")
7543         (if_then_else (eq_attr "fpu_single" "yes")
7544                       (const_string "single") (const_string "double")))
7545    (set_attr "needs_delay_slot" "yes")])
7547 (define_expand "call_pop"
7548   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7549                     (match_operand 1 "" ""))
7550              (match_operand 2 "" "")
7551              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7552                                            (match_operand 3 "" "")))])]
7553   "TARGET_SHCOMPACT"
7554   "
7556   rtx cookie_rtx;
7557   long cookie;
7558   rtx func;
7559   rtx r0, r1;
7561   gcc_assert (operands[2] && INTVAL (operands[2]));
7562   cookie_rtx = operands[2];
7563   cookie = INTVAL (cookie_rtx);
7564   func = XEXP (operands[0], 0);
7566   if (flag_pic)
7567     {
7568       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7569         {
7570           rtx reg = gen_reg_rtx (Pmode);
7571           emit_insn (gen_symGOTPLT2reg (reg, func));
7572           func = reg;
7573         }
7574       else
7575         func = legitimize_pic_address (func, Pmode, 0);
7576     }
7578   r0 = gen_rtx_REG (SImode, R0_REG);
7579   r1 = gen_rtx_REG (SImode, R1_REG);
7581   /* Since such a call function may use all call-clobbered
7582      registers, we force a mode switch earlier, so that we don't
7583      run out of registers when adjusting fpscr for the call.  */
7584   emit_insn (gen_force_mode_for_call ());
7586   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7587                                  SFUNC_GOT);
7588   operands[0] = force_reg (SImode, operands[0]);
7590   emit_move_insn (r0, func);
7591   emit_move_insn (r1, cookie_rtx);
7593   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7594     emit_call_insn (gen_call_pop_compact_rettramp
7595                      (operands[0], operands[1], operands[2], operands[3]));
7596   else
7597     emit_call_insn (gen_call_pop_compact
7598                      (operands[0], operands[1], operands[2], operands[3]));
7600   DONE;
7603 (define_expand "call_value"
7604   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7605                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7606                                  (match_operand 2 "" "")))
7607               (match_operand 3 "" "")
7608               (use (reg:PSI FPSCR_REG))
7609               (clobber (reg:SI PR_REG))])]
7610   ""
7611   "
7613   if (TARGET_SHMEDIA)
7614     {
7615       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7616       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7617                                             operands[2]));
7618       DONE;
7619     }
7620   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7621     {
7622       rtx cookie_rtx = operands[3];
7623       long cookie = INTVAL (cookie_rtx);
7624       rtx func = XEXP (operands[1], 0);
7625       rtx r0, r1;
7627       if (flag_pic)
7628         {
7629           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7630             {
7631               rtx reg = gen_reg_rtx (Pmode);
7633               emit_insn (gen_symGOTPLT2reg (reg, func));
7634               func = reg;
7635             }
7636           else
7637             func = legitimize_pic_address (func, Pmode, 0);
7638         }
7640       r0 = gen_rtx_REG (SImode, R0_REG);
7641       r1 = gen_rtx_REG (SImode, R1_REG);
7643       /* Since such a call function may use all call-clobbered
7644          registers, we force a mode switch earlier, so that we don't
7645          run out of registers when adjusting fpscr for the call.  */
7646       emit_insn (gen_force_mode_for_call ());
7648       operands[1]
7649         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7650                            SFUNC_GOT);
7651       operands[1] = force_reg (SImode, operands[1]);
7653       emit_move_insn (r0, func);
7654       emit_move_insn (r1, cookie_rtx);
7656       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7657         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7658                                                          operands[1],
7659                                                          operands[2],
7660                                                          operands[3]));
7661       else
7662         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7663                                                 operands[2], operands[3]));
7665       DONE;
7666     }
7667   else if (TARGET_SHCOMPACT && flag_pic
7668            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7669            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7670     {
7671       rtx reg = gen_reg_rtx (Pmode);
7673       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7674       XEXP (operands[1], 0) = reg;
7675     }
7676   if (!flag_pic && TARGET_SH2A
7677       && MEM_P (operands[1])
7678       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7679     {
7680       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7681         {
7682           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7683                                  XEXP (operands[1], 0), operands[2]));
7684           DONE;
7685         }
7686     }
7687   if (flag_pic && TARGET_SH2
7688       && MEM_P (operands[1])
7689       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7690     {
7691       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7692                                             operands[2]));
7693       DONE;
7694     }
7695   else
7696     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7698   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7699   DONE;
7702 (define_insn "sibcalli"
7703   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7704          (match_operand 1 "" ""))
7705    (use (reg:PSI FPSCR_REG))
7706    (return)]
7707   "TARGET_SH1"
7708   "jmp  @%0%#"
7709   [(set_attr "needs_delay_slot" "yes")
7710    (set (attr "fp_mode")
7711         (if_then_else (eq_attr "fpu_single" "yes")
7712                       (const_string "single") (const_string "double")))
7713    (set_attr "type" "jump_ind")])
7715 (define_insn "sibcalli_pcrel"
7716   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7717          (match_operand 1 "" ""))
7718    (use (match_operand 2 "" ""))
7719    (use (reg:PSI FPSCR_REG))
7720    (return)]
7721   "TARGET_SH2"
7722   "braf %0\\n%O2:%#"
7723   [(set_attr "needs_delay_slot" "yes")
7724    (set (attr "fp_mode")
7725         (if_then_else (eq_attr "fpu_single" "yes")
7726                       (const_string "single") (const_string "double")))
7727    (set_attr "type" "jump_ind")])
7729 ;; This uses an unspec to describe that the symbol_ref is very close.
7730 (define_insn "sibcalli_thunk"
7731   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7732                              UNSPEC_THUNK))
7733          (match_operand 1 "" ""))
7734    (use (reg:PSI FPSCR_REG))
7735    (return)]
7736   "TARGET_SH1"
7737   "bra  %O0"
7738   [(set_attr "needs_delay_slot" "yes")
7739    (set (attr "fp_mode")
7740         (if_then_else (eq_attr "fpu_single" "yes")
7741                       (const_string "single") (const_string "double")))
7742    (set_attr "type" "jump")
7743    (set_attr "length" "2")])
7745 (define_insn_and_split "sibcall_pcrel"
7746   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7747          (match_operand 1 "" ""))
7748    (use (reg:PSI FPSCR_REG))
7749    (clobber (match_scratch:SI 2 "=k"))
7750    (return)]
7751   "TARGET_SH2"
7752   "#"
7753   "reload_completed"
7754   [(const_int 0)]
7755   "
7757   rtx lab = PATTERN (gen_call_site ());
7758   rtx call_insn;
7760   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7761   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7762                                                   copy_rtx (lab)));
7763   SIBLING_CALL_P (call_insn) = 1;
7764   DONE;
7766   [(set_attr "needs_delay_slot" "yes")
7767    (set (attr "fp_mode")
7768         (if_then_else (eq_attr "fpu_single" "yes")
7769                       (const_string "single") (const_string "double")))
7770    (set_attr "type" "jump_ind")])
7772 (define_insn "sibcall_compact"
7773   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7774          (match_operand 1 "" ""))
7775    (return)
7776    (use (match_operand:SI 2 "register_operand" "z,x"))
7777    (use (reg:SI R1_REG))
7778    (use (reg:PSI FPSCR_REG))
7779    ;; We want to make sure the `x' above will only match MACH_REG
7780    ;; because sibcall_epilogue may clobber MACL_REG.
7781    (clobber (reg:SI MACL_REG))]
7782   "TARGET_SHCOMPACT"
7783   "@
7784         jmp     @%0%#
7785         jmp     @%0\\n  sts     %2, r0"
7786   [(set_attr "needs_delay_slot" "yes,no")
7787    (set_attr "length" "2,4")
7788    (set (attr "fp_mode") (const_string "single"))
7789    (set_attr "type" "jump_ind")])
7791 (define_insn "sibcall_media"
7792   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7793          (match_operand 1 "" ""))
7794    (use (reg:SI PR_MEDIA_REG))
7795    (return)]
7796   "TARGET_SHMEDIA"
7797   "blink        %0, r63"
7798   [(set_attr "type" "jump_media")])
7800 (define_expand "sibcall"
7801   [(parallel
7802     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7803            (match_operand 1 "" ""))
7804      (match_operand 2 "" "")
7805      (use (reg:PSI FPSCR_REG))
7806      (return)])]
7807   ""
7808   "
7810   if (TARGET_SHMEDIA)
7811     {
7812       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7813       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7814       DONE;
7815     }
7816   else if (TARGET_SHCOMPACT && operands[2]
7817            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7818     {
7819       rtx cookie_rtx = operands[2];
7820       long cookie = INTVAL (cookie_rtx);
7821       rtx func = XEXP (operands[0], 0);
7822       rtx mach, r1;
7824       if (flag_pic)
7825         {
7826           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7827             {
7828               rtx reg = gen_reg_rtx (Pmode);
7830               emit_insn (gen_symGOT2reg (reg, func));
7831               func = reg;
7832             }
7833           else
7834             func = legitimize_pic_address (func, Pmode, 0);
7835         }
7837       /* FIXME: if we could tell whether all argument registers are
7838          already taken, we could decide whether to force the use of
7839          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7840          simple way to tell.  We could use the CALL_COOKIE, but we
7841          can't currently tell a register used for regular argument
7842          passing from one that is unused.  If we leave it up to reload
7843          to decide which register to use, it seems to always choose
7844          R0_REG, which leaves no available registers in SIBCALL_REGS
7845          to hold the address of the trampoline.  */
7846       mach = gen_rtx_REG (SImode, MACH_REG);
7847       r1 = gen_rtx_REG (SImode, R1_REG);
7849       /* Since such a call function may use all call-clobbered
7850          registers, we force a mode switch earlier, so that we don't
7851          run out of registers when adjusting fpscr for the call.  */
7852       emit_insn (gen_force_mode_for_call ());
7854       operands[0]
7855         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7856                            SFUNC_GOT);
7857       operands[0] = force_reg (SImode, operands[0]);
7859       /* We don't need a return trampoline, since the callee will
7860          return directly to the upper caller.  */
7861       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7862         {
7863           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7864           cookie_rtx = GEN_INT (cookie);
7865         }
7867       emit_move_insn (mach, func);
7868       emit_move_insn (r1, cookie_rtx);
7870       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7871       DONE;
7872     }
7873   else if (TARGET_SHCOMPACT && flag_pic
7874            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7875            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7876     {
7877       rtx reg = gen_reg_rtx (Pmode);
7879       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7880       XEXP (operands[0], 0) = reg;
7881     }
7882   if (flag_pic && TARGET_SH2
7883       && MEM_P (operands[0])
7884       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7885       /* The PLT needs the PIC register, but the epilogue would have
7886          to restore it, so we can only use PC-relative PIC calls for
7887          static functions.  */
7888       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7889     {
7890       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7891       DONE;
7892     }
7893   else
7894     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7896   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7897   DONE;
7900 (define_insn "sibcall_valuei"
7901   [(set (match_operand 0 "" "=rf")
7902         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7903               (match_operand 2 "" "")))
7904    (use (reg:PSI FPSCR_REG))
7905    (return)]
7906   "TARGET_SH1"
7907   "jmp  @%1%#"
7908   [(set_attr "needs_delay_slot" "yes")
7909    (set (attr "fp_mode")
7910         (if_then_else (eq_attr "fpu_single" "yes")
7911                       (const_string "single") (const_string "double")))
7912    (set_attr "type" "jump_ind")])
7914 (define_insn "sibcall_valuei_pcrel"
7915   [(set (match_operand 0 "" "=rf")
7916         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7917               (match_operand 2 "" "")))
7918    (use (match_operand 3 "" ""))
7919    (use (reg:PSI FPSCR_REG))
7920    (return)]
7921   "TARGET_SH2"
7922   "braf %1\\n%O3:%#"
7923   [(set_attr "needs_delay_slot" "yes")
7924    (set (attr "fp_mode")
7925         (if_then_else (eq_attr "fpu_single" "yes")
7926                       (const_string "single") (const_string "double")))
7927    (set_attr "type" "jump_ind")])
7929 (define_insn_and_split "sibcall_value_pcrel"
7930   [(set (match_operand 0 "" "=rf")
7931         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7932               (match_operand 2 "" "")))
7933    (use (reg:PSI FPSCR_REG))
7934    (clobber (match_scratch:SI 3 "=k"))
7935    (return)]
7936   "TARGET_SH2"
7937   "#"
7938   "reload_completed"
7939   [(const_int 0)]
7940   "
7942   rtx lab = PATTERN (gen_call_site ());
7943   rtx call_insn;
7945   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7946   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7947                                                         operands[3],
7948                                                         operands[2],
7949                                                         copy_rtx (lab)));
7950   SIBLING_CALL_P (call_insn) = 1;
7951   DONE;
7953   [(set_attr "needs_delay_slot" "yes")
7954    (set (attr "fp_mode")
7955         (if_then_else (eq_attr "fpu_single" "yes")
7956                       (const_string "single") (const_string "double")))
7957    (set_attr "type" "jump_ind")])
7959 (define_insn "sibcall_value_compact"
7960   [(set (match_operand 0 "" "=rf,rf")
7961         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7962               (match_operand 2 "" "")))
7963    (return)
7964    (use (match_operand:SI 3 "register_operand" "z,x"))
7965    (use (reg:SI R1_REG))
7966    (use (reg:PSI FPSCR_REG))
7967    ;; We want to make sure the `x' above will only match MACH_REG
7968    ;; because sibcall_epilogue may clobber MACL_REG.
7969    (clobber (reg:SI MACL_REG))]
7970   "TARGET_SHCOMPACT"
7971   "@
7972         jmp     @%1%#
7973         jmp     @%1\\n  sts     %3, r0"
7974   [(set_attr "needs_delay_slot" "yes,no")
7975    (set_attr "length" "2,4")
7976    (set (attr "fp_mode") (const_string "single"))
7977    (set_attr "type" "jump_ind")])
7979 (define_insn "sibcall_value_media"
7980   [(set (match_operand 0 "" "=rf")
7981         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7982               (match_operand 2 "" "")))
7983    (use (reg:SI PR_MEDIA_REG))
7984    (return)]
7985   "TARGET_SHMEDIA"
7986   "blink        %1, r63"
7987   [(set_attr "type" "jump_media")])
7989 (define_expand "sibcall_value"
7990   [(parallel
7991     [(set (match_operand 0 "arith_reg_operand" "")
7992           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7993                 (match_operand 2 "" "")))
7994      (match_operand 3 "" "")
7995      (use (reg:PSI FPSCR_REG))
7996      (return)])]
7997   ""
7998   "
8000   if (TARGET_SHMEDIA)
8001     {
8002       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8003       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8004                                                operands[2]));
8005       DONE;
8006     }
8007   else if (TARGET_SHCOMPACT && operands[3]
8008            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8009     {
8010       rtx cookie_rtx = operands[3];
8011       long cookie = INTVAL (cookie_rtx);
8012       rtx func = XEXP (operands[1], 0);
8013       rtx mach, r1;
8015       if (flag_pic)
8016         {
8017           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8018             {
8019               rtx reg = gen_reg_rtx (Pmode);
8021               emit_insn (gen_symGOT2reg (reg, func));
8022               func = reg;
8023             }
8024           else
8025             func = legitimize_pic_address (func, Pmode, 0);
8026         }
8028       /* FIXME: if we could tell whether all argument registers are
8029          already taken, we could decide whether to force the use of
8030          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8031          simple way to tell.  We could use the CALL_COOKIE, but we
8032          can't currently tell a register used for regular argument
8033          passing from one that is unused.  If we leave it up to reload
8034          to decide which register to use, it seems to always choose
8035          R0_REG, which leaves no available registers in SIBCALL_REGS
8036          to hold the address of the trampoline.  */
8037       mach = gen_rtx_REG (SImode, MACH_REG);
8038       r1 = gen_rtx_REG (SImode, R1_REG);
8040       /* Since such a call function may use all call-clobbered
8041          registers, we force a mode switch earlier, so that we don't
8042          run out of registers when adjusting fpscr for the call.  */
8043       emit_insn (gen_force_mode_for_call ());
8045       operands[1]
8046         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8047                            SFUNC_GOT);
8048       operands[1] = force_reg (SImode, operands[1]);
8050       /* We don't need a return trampoline, since the callee will
8051          return directly to the upper caller.  */
8052       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8053         {
8054           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8055           cookie_rtx = GEN_INT (cookie);
8056         }
8058       emit_move_insn (mach, func);
8059       emit_move_insn (r1, cookie_rtx);
8061       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8062                                                  operands[2], mach));
8063       DONE;
8064     }
8065   else if (TARGET_SHCOMPACT && flag_pic
8066            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8067            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8068     {
8069       rtx reg = gen_reg_rtx (Pmode);
8071       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8072       XEXP (operands[1], 0) = reg;
8073     }
8074   if (flag_pic && TARGET_SH2
8075       && MEM_P (operands[1])
8076       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8077       /* The PLT needs the PIC register, but the epilogue would have
8078          to restore it, so we can only use PC-relative PIC calls for
8079          static functions.  */
8080       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8081     {
8082       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8083                                                XEXP (operands[1], 0),
8084                                                operands[2]));
8085       DONE;
8086     }
8087   else
8088     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8090   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8091   DONE;
8094 (define_insn "call_value_pop_compact"
8095   [(set (match_operand 0 "" "=rf")
8096         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8097               (match_operand 2 "" "")))
8098    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8099                                  (match_operand 4 "immediate_operand" "n")))
8100    (match_operand 3 "immediate_operand" "n")
8101    (use (reg:SI R0_REG))
8102    (use (reg:SI R1_REG))
8103    (use (reg:PSI FPSCR_REG))
8104    (clobber (reg:SI PR_REG))]
8105   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8106   "jsr  @%1%#"
8107   [(set_attr "type" "call")
8108    (set (attr "fp_mode")
8109         (if_then_else (eq_attr "fpu_single" "yes")
8110                       (const_string "single") (const_string "double")))
8111    (set_attr "needs_delay_slot" "yes")])
8113 (define_insn "call_value_pop_compact_rettramp"
8114   [(set (match_operand 0 "" "=rf")
8115         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8116               (match_operand 2 "" "")))
8117    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8118                                  (match_operand 4 "immediate_operand" "n")))
8119    (match_operand 3 "immediate_operand" "n")
8120    (use (reg:SI R0_REG))
8121    (use (reg:SI R1_REG))
8122    (use (reg:PSI FPSCR_REG))
8123    (clobber (reg:SI R10_REG))
8124    (clobber (reg:SI PR_REG))]
8125   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8126   "jsr  @%1%#"
8127   [(set_attr "type" "call")
8128    (set (attr "fp_mode")
8129         (if_then_else (eq_attr "fpu_single" "yes")
8130                       (const_string "single") (const_string "double")))
8131    (set_attr "needs_delay_slot" "yes")])
8133 (define_expand "call_value_pop"
8134   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8135                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8136                                  (match_operand 2 "" "")))
8137               (match_operand 3 "" "")
8138               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8139                                             (match_operand 4 "" "")))])]
8140   "TARGET_SHCOMPACT"
8141   "
8143   rtx cookie_rtx;
8144   long cookie;
8145   rtx func;
8146   rtx r0, r1;
8148   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8149   cookie_rtx = operands[3];
8150   cookie = INTVAL (cookie_rtx);
8151   func = XEXP (operands[1], 0);
8153   if (flag_pic)
8154     {
8155       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8156         {
8157           rtx reg = gen_reg_rtx (Pmode);
8159           emit_insn (gen_symGOTPLT2reg (reg, func));
8160           func = reg;
8161         }
8162       else
8163         func = legitimize_pic_address (func, Pmode, 0);
8164     }
8166   r0 = gen_rtx_REG (SImode, R0_REG);
8167   r1 = gen_rtx_REG (SImode, R1_REG);
8169   /* Since such a call function may use all call-clobbered
8170      registers, we force a mode switch earlier, so that we don't
8171      run out of registers when adjusting fpscr for the call.  */
8172   emit_insn (gen_force_mode_for_call ());
8174   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8175                                  SFUNC_GOT);
8176   operands[1] = force_reg (SImode, operands[1]);
8178   emit_move_insn (r0, func);
8179   emit_move_insn (r1, cookie_rtx);
8181   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8182     emit_call_insn (gen_call_value_pop_compact_rettramp
8183                         (operands[0], operands[1], operands[2],
8184                          operands[3], operands[4]));
8185   else
8186     emit_call_insn (gen_call_value_pop_compact
8187                         (operands[0], operands[1], operands[2],
8188                          operands[3], operands[4]));
8190   DONE;
8193 (define_expand "sibcall_epilogue"
8194   [(return)]
8195   ""
8196   "
8198   sh_expand_epilogue (1);
8199   if (TARGET_SHCOMPACT)
8200     {
8201       rtx insn, set;
8203       /* If epilogue clobbers r0, preserve it in macl.  */
8204       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8205         if ((set = single_set (insn))
8206             && REG_P (SET_DEST (set))
8207             && REGNO (SET_DEST (set)) == R0_REG)
8208           {
8209             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8210             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8212             /* We can't tell at this point whether the sibcall is a
8213                sibcall_compact and, if it is, whether it uses r0 or
8214                mach as operand 2, so let the instructions that
8215                preserve r0 be optimized away if r0 turns out to be
8216                dead.  */
8217             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8218             emit_move_insn (r0, tmp);
8219             break;
8220           }
8221     }
8222   DONE;
8225 (define_insn "indirect_jump_compact"
8226   [(set (pc)
8227         (match_operand:SI 0 "arith_reg_operand" "r"))]
8228   "TARGET_SH1"
8229   "jmp  @%0%#"
8230   [(set_attr "needs_delay_slot" "yes")
8231    (set_attr "type" "jump_ind")])
8233 (define_expand "indirect_jump"
8234   [(set (pc)
8235         (match_operand 0 "register_operand" ""))]
8236   ""
8237   "
8239   if (GET_MODE (operands[0]) != Pmode)
8240     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8243 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8244 ;; which can be present in structured code from indirect jumps which can not
8245 ;; be present in structured code.  This allows -fprofile-arcs to work.
8247 ;; For SH1 processors.
8248 (define_insn "casesi_jump_1"
8249   [(set (pc)
8250         (match_operand:SI 0 "register_operand" "r"))
8251    (use (label_ref (match_operand 1 "" "")))]
8252   "TARGET_SH1"
8253   "jmp  @%0%#"
8254   [(set_attr "needs_delay_slot" "yes")
8255    (set_attr "type" "jump_ind")])
8257 ;; For all later processors.
8258 (define_insn "casesi_jump_2"
8259   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8260                       (label_ref (match_operand 1 "" ""))))
8261    (use (label_ref (match_operand 2 "" "")))]
8262   "TARGET_SH2
8263    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8264   "braf %0%#"
8265   [(set_attr "needs_delay_slot" "yes")
8266    (set_attr "type" "jump_ind")])
8268 (define_insn "casesi_jump_media"
8269   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8270    (use (label_ref (match_operand 1 "" "")))]
8271   "TARGET_SHMEDIA"
8272   "blink        %0, r63"
8273   [(set_attr "type" "jump_media")])
8275 ;; Call subroutine returning any type.
8276 ;; ??? This probably doesn't work.
8278 (define_expand "untyped_call"
8279   [(parallel [(call (match_operand 0 "" "")
8280                     (const_int 0))
8281               (match_operand 1 "" "")
8282               (match_operand 2 "" "")])]
8283   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8284   "
8286   int i;
8288   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8290   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8291     {
8292       rtx set = XVECEXP (operands[2], 0, i);
8293       emit_move_insn (SET_DEST (set), SET_SRC (set));
8294     }
8296   /* The optimizer does not know that the call sets the function value
8297      registers we stored in the result block.  We avoid problems by
8298      claiming that all hard registers are used and clobbered at this
8299      point.  */
8300   emit_insn (gen_blockage ());
8302   DONE;
8305 ;; ------------------------------------------------------------------------
8306 ;; Misc insns
8307 ;; ------------------------------------------------------------------------
8309 (define_insn "dect"
8310   [(set (reg:SI T_REG)
8311         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8312    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8313   "TARGET_SH2"
8314   "dt   %0"
8315   [(set_attr "type" "arith")])
8317 (define_insn "nop"
8318   [(const_int 0)]
8319   ""
8320   "nop")
8322 ;; Load address of a label. This is only generated by the casesi expand,
8323 ;; and by machine_dependent_reorg (fixing up fp moves).
8324 ;; This must use unspec, because this only works for labels that are
8325 ;; within range,
8327 (define_insn "mova"
8328   [(set (reg:SI R0_REG)
8329         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8330   "TARGET_SH1"
8331   "mova %O0,r0"
8332   [(set_attr "in_delay_slot" "no")
8333    (set_attr "type" "arith")])
8335 ;; machine_dependent_reorg will make this a `mova'.
8336 (define_insn "mova_const"
8337   [(set (reg:SI R0_REG)
8338         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8339   "TARGET_SH1"
8340   "#"
8341   [(set_attr "in_delay_slot" "no")
8342    (set_attr "type" "arith")])
8344 (define_expand "GOTaddr2picreg"
8345   [(set (reg:SI R0_REG)
8346         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8347                    UNSPEC_MOVA))
8348    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8349    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8350   "" "
8352   if (TARGET_VXWORKS_RTP)
8353     {
8354       rtx gott_base = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_BASE);
8355       rtx gott_index = gen_rtx_SYMBOL_REF (Pmode, VXWORKS_GOTT_INDEX);
8356       emit_insn (gen_vxworks_picreg (gott_base, gott_index));
8357       DONE;
8358     }
8360   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8361   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8363   if (TARGET_SHMEDIA)
8364     {
8365       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8366       rtx pic = operands[0];
8367       rtx lab = PATTERN (gen_call_site ());
8368       rtx insn, equiv;
8370       equiv = operands[1];
8371       operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], lab),
8372                                     UNSPEC_PCREL_SYMOFF);
8373       operands[1] = gen_rtx_CONST (Pmode, operands[1]);
8375       if (Pmode == SImode)
8376         {
8377           emit_insn (gen_movsi_const (pic, operands[1]));
8378           emit_insn (gen_ptrel_si (tr, pic, copy_rtx (lab)));
8379         }
8380       else
8381         {
8382           emit_insn (gen_movdi_const (pic, operands[1]));
8383           emit_insn (gen_ptrel_di (tr, pic, copy_rtx (lab)));
8384         }
8386       insn = emit_move_insn (operands[0], tr);
8388       set_unique_reg_note (insn, REG_EQUAL, equiv);
8390       DONE;
8391     }
8395 ;; A helper for GOTaddr2picreg to finish up the initialization of the
8396 ;; PIC register.
8398 (define_expand "vxworks_picreg"
8399   [(set (reg:SI PIC_REG)
8400         (const:SI (unspec:SI [(match_operand:SI 0 "" "")] UNSPEC_PIC)))
8401    (set (reg:SI R0_REG)
8402         (const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC)))
8403    (set (reg:SI PIC_REG)
8404         (mem:SI (reg:SI PIC_REG)))
8405    (set (reg:SI PIC_REG)
8406         (mem:SI (plus:SI (reg:SI PIC_REG)
8407                          (reg:SI R0_REG))))]
8408   "TARGET_VXWORKS_RTP")
8410 (define_insn "*ptb"
8411   [(set (match_operand 0 "target_reg_operand" "=b")
8412         (const (unspec [(match_operand 1 "" "Csy")]
8413                              UNSPEC_DATALABEL)))]
8414   "TARGET_SHMEDIA && flag_pic
8415    && satisfies_constraint_Csy (operands[1])"
8416   "ptb/u        datalabel %1, %0"
8417   [(set_attr "type" "ptabs_media")
8418    (set_attr "length" "*")])
8420 (define_insn "ptrel_si"
8421   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8422         (plus:SI (match_operand:SI 1 "register_operand" "r")
8423               (pc)))
8424    (match_operand:SI 2 "" "")]
8425   "TARGET_SHMEDIA"
8426   "%O2: ptrel/u %1, %0"
8427   [(set_attr "type" "ptabs_media")])
8429 (define_insn "ptrel_di"
8430   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8431         (plus:DI (match_operand:DI 1 "register_operand" "r")
8432               (pc)))
8433    (match_operand:DI 2 "" "")]
8434   "TARGET_SHMEDIA"
8435   "%O2: ptrel/u %1, %0"
8436   [(set_attr "type" "ptabs_media")])
8438 (define_expand "builtin_setjmp_receiver"
8439   [(match_operand 0 "" "")]
8440   "flag_pic"
8441   "
8443   emit_insn (gen_GOTaddr2picreg ());
8444   DONE;
8447 (define_expand "call_site"
8448   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8449   "TARGET_SH1"
8450   "
8452   static HOST_WIDE_INT i = 0;
8453   operands[0] = GEN_INT (i);
8454   i++;
8457 (define_expand "sym_label2reg"
8458   [(set (match_operand:SI 0 "" "")
8459         (const:SI (unspec:SI [(match_operand:SI 1 "" "")
8460                               (const (plus:SI (match_operand:SI 2 "" "")
8461                                               (const_int 2)))]
8462                              UNSPEC_SYMOFF)))]
8463   "TARGET_SH1" "")
8465 (define_expand "symGOT_load"
8466   [(set (match_dup 2) (match_operand 1 "" ""))
8467    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8468    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8469   ""
8470   "
8472   rtx insn, mem;
8474   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8475   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
8477   if (TARGET_SHMEDIA)
8478     {
8479       rtx reg = operands[2];
8481       if (Pmode == DImode)
8482         {      
8483           if (flag_pic > 1)
8484             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8485           else
8486             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8487         }
8488       else
8489         {
8490           if (flag_pic > 1)
8491             emit_insn (gen_movsi_const (reg, operands[1]));
8492           else
8493             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8494         }
8495     }
8496   else
8497     emit_move_insn (operands[2], operands[1]);
8499   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8500                                              operands[2],
8501                                              gen_rtx_REG (Pmode, PIC_REG)));
8503   /* When stack protector inserts codes after the result is set to
8504      R0, @(rX, r12) will cause a spill failure for R0.  Don't schedule
8505      insns to avoid combining (set A (plus rX r12)) and (set op0 (mem A))
8506      when rX is a GOT address for the guard symbol.  Ugly but doesn't
8507      matter because this is a rare situation.  */
8508   if (!TARGET_SHMEDIA
8509       && flag_stack_protect
8510       && GET_CODE (operands[1]) == CONST
8511       && GET_CODE (XEXP (operands[1], 0)) == UNSPEC
8512       && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == SYMBOL_REF
8513       && strcmp (XSTR (XVECEXP (XEXP (operands[1], 0), 0, 0), 0),
8514                  \"__stack_chk_guard\") == 0)
8515     emit_insn (gen_blockage ());
8517   /* N.B. This is not constant for a GOTPLT relocation.  */
8518   mem = gen_rtx_MEM (Pmode, operands[3]);
8519   MEM_NOTRAP_P (mem) = 1;
8520   /* ??? Should we have a special alias set for the GOT?  */
8521   insn = emit_move_insn (operands[0], mem);
8523   DONE;
8526 (define_expand "sym2GOT"
8527   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8528   ""
8529   "")
8531 (define_expand "symGOT2reg"
8532   [(match_operand 0 "" "") (match_operand 1 "" "")]
8533   ""
8534   "
8536   rtx gotsym, insn;
8538   gotsym = gen_sym2GOT (operands[1]);
8539   PUT_MODE (gotsym, Pmode);
8540   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8542   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8544   DONE;
8547 (define_expand "symGOTPLT2reg"
8548   [(match_operand 0 "" "") (match_operand 1 "" "")]
8549   ""
8550   "
8552   rtx pltsym = gen_rtx_CONST (Pmode,
8553                               gen_rtx_UNSPEC (Pmode,
8554                                               gen_rtvec (1, operands[1]),
8555                                               UNSPEC_GOTPLT));
8556   emit_insn (gen_symGOT_load (operands[0], pltsym));
8557   DONE;
8560 (define_expand "sym2GOTOFF"
8561   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8562   ""
8563   "")
8565 (define_expand "symGOTOFF2reg"
8566   [(match_operand 0 "" "") (match_operand 1 "" "")]
8567   ""
8568   "
8570   rtx gotoffsym, insn;
8571   rtx t = (!can_create_pseudo_p ()
8572            ? operands[0]
8573            : gen_reg_rtx (GET_MODE (operands[0])));
8575   gotoffsym = gen_sym2GOTOFF (operands[1]);
8576   PUT_MODE (gotoffsym, Pmode);
8577   emit_move_insn (t, gotoffsym);
8578   insn = emit_move_insn (operands[0],
8579                          gen_rtx_PLUS (Pmode, t,
8580                                        gen_rtx_REG (Pmode, PIC_REG)));
8582   set_unique_reg_note (insn, REG_EQUAL, operands[1]);
8584   DONE;
8587 (define_expand "symPLT_label2reg"
8588   [(set (match_operand:SI 0 "" "")
8589         (const:SI
8590          (unspec:SI
8591           [(const:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8592            (const:SI (plus:SI (match_operand:SI 2 "" "")
8593                               (const_int 2)))] UNSPEC_PCREL_SYMOFF)))
8594    ;; Even though the PIC register is not really used by the call
8595    ;; sequence in which this is expanded, the PLT code assumes the PIC
8596    ;; register is set, so we must not skip its initialization.  Since
8597    ;; we only use this expand as part of calling sequences, and never
8598    ;; to take the address of a function, this is the best point to
8599    ;; insert the (use).  Using the PLT to take the address of a
8600    ;; function would be wrong, not only because the PLT entry could
8601    ;; then be called from a function that doesn't initialize the PIC
8602    ;; register to the proper GOT, but also because pointers to the
8603    ;; same function might not compare equal, should they be set by
8604    ;; different shared libraries.
8605    (use (reg:SI PIC_REG))]
8606   "TARGET_SH1"
8607   "")
8609 (define_expand "sym2PIC"
8610   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8611   ""
8612   "")
8614 ;; TLS code generation.
8615 ;; ??? this should be a define_insn_and_split
8616 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8617 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8618 ;; for details.
8620 (define_insn "tls_global_dynamic"
8621   [(set (match_operand:SI 0 "register_operand" "=&z")
8622         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8623                                   UNSPEC_TLSGD))
8624               (const_int 0)))
8625    (use (reg:PSI FPSCR_REG))
8626    (use (reg:SI PIC_REG))
8627    (clobber (reg:SI PR_REG))
8628    (clobber (scratch:SI))]
8629   "TARGET_SH1"
8630   "*
8632   return \"\\
8633 mov.l\\t1f,r4\\n\\
8634 \\tmova\\t2f,r0\\n\\
8635 \\tmov.l\\t2f,r1\\n\\
8636 \\tadd\\tr0,r1\\n\\
8637 \\tjsr\\t@r1\\n\\
8638 \\tadd\\tr12,r4\\n\\
8639 \\tbra\\t3f\\n\\
8640 \\tnop\\n\\
8641 \\t.align\\t2\\n\\
8642 1:\\t.long\\t%a1@TLSGD\\n\\
8643 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8644 3:\";
8646   [(set_attr "type" "tls_load")
8647    (set_attr "length" "26")])
8649 (define_insn "tls_local_dynamic"
8650   [(set (match_operand:SI 0 "register_operand" "=&z")
8651         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8652                                   UNSPEC_TLSLDM))
8653               (const_int 0)))
8654    (use (reg:PSI FPSCR_REG))
8655    (use (reg:SI PIC_REG))
8656    (clobber (reg:SI PR_REG))
8657    (clobber (scratch:SI))]
8658   "TARGET_SH1"
8659   "*
8661   return \"\\
8662 mov.l\\t1f,r4\\n\\
8663 \\tmova\\t2f,r0\\n\\
8664 \\tmov.l\\t2f,r1\\n\\
8665 \\tadd\\tr0,r1\\n\\
8666 \\tjsr\\t@r1\\n\\
8667 \\tadd\\tr12,r4\\n\\
8668 \\tbra\\t3f\\n\\
8669 \\tnop\\n\\
8670 \\t.align\\t2\\n\\
8671 1:\\t.long\\t%a1@TLSLDM\\n\\
8672 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8673 3:\";
8675   [(set_attr "type" "tls_load")
8676    (set_attr "length" "26")])
8678 (define_expand "sym2DTPOFF"
8679   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8680   ""
8681   "")
8683 (define_expand "symDTPOFF2reg"
8684   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8685   ""
8686   "
8688   rtx dtpoffsym, insn;
8689   rtx t = (!can_create_pseudo_p ()
8690            ? operands[0]
8691            : gen_reg_rtx (GET_MODE (operands[0])));
8693   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8694   PUT_MODE (dtpoffsym, Pmode);
8695   emit_move_insn (t, dtpoffsym);
8696   insn = emit_move_insn (operands[0],
8697                          gen_rtx_PLUS (Pmode, t, operands[2]));
8698   DONE;
8701 (define_expand "sym2GOTTPOFF"
8702   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8703   ""
8704   "")
8706 (define_insn "tls_initial_exec"
8707   [(set (match_operand:SI 0 "register_operand" "=&r")
8708         (unspec:SI [(match_operand:SI 1 "" "")]
8709                     UNSPEC_TLSIE))
8710    (use (reg:SI GBR_REG))
8711    (use (reg:SI PIC_REG))
8712    (clobber (reg:SI R0_REG))]
8713   ""
8714   "*
8716   return \"\\
8717 mov.l\\t1f,r0\\n\\
8718 \\tstc\\tgbr,%0\\n\\
8719 \\tmov.l\\t@(r0,r12),r0\\n\\
8720 \\tbra\\t2f\\n\\
8721 \\tadd\\tr0,%0\\n\\
8722 \\t.align\\t2\\n\\
8723 1:\\t.long\\t%a1\\n\\
8724 2:\";
8726   [(set_attr "type" "tls_load")
8727    (set_attr "length" "16")])
8729 (define_expand "sym2TPOFF"
8730   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8731   ""
8732   "")
8734 (define_expand "symTPOFF2reg"
8735   [(match_operand 0 "" "") (match_operand 1 "" "")]
8736   ""
8737   "
8739   rtx tpoffsym, insn;
8741   tpoffsym = gen_sym2TPOFF (operands[1]);
8742   PUT_MODE (tpoffsym, Pmode);
8743   insn = emit_move_insn (operands[0], tpoffsym);
8744   DONE;
8747 (define_insn "load_gbr"
8748   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8749    (use (reg:SI GBR_REG))]
8750   ""
8751   "stc  gbr,%0"
8752   [(set_attr "type" "tls_load")])
8754 ;; case instruction for switch statements.
8756 ;; Operand 0 is index
8757 ;; operand 1 is the minimum bound
8758 ;; operand 2 is the maximum bound - minimum bound + 1
8759 ;; operand 3 is CODE_LABEL for the table;
8760 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8762 (define_expand "casesi"
8763   [(match_operand:SI 0 "arith_reg_operand" "")
8764    (match_operand:SI 1 "arith_reg_operand" "")
8765    (match_operand:SI 2 "arith_reg_operand" "")
8766    (match_operand 3 "" "") (match_operand 4 "" "")]
8767   ""
8768   "
8770   rtx reg = gen_reg_rtx (SImode);
8771   rtx reg2 = gen_reg_rtx (SImode);
8772   if (TARGET_SHMEDIA)
8773     {
8774       rtx reg = gen_reg_rtx (DImode);
8775       rtx reg2 = gen_reg_rtx (DImode);
8776       rtx reg3 = gen_reg_rtx (Pmode);
8777       rtx reg4 = gen_reg_rtx (Pmode);
8778       rtx reg5 = gen_reg_rtx (Pmode);
8779       rtx load, test;
8781       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8782       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8783       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8785       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8786       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8787       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8788       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8789       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8790       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8791       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8792                                                (Pmode, operands[3])));
8793       /* Messy: can we subreg to clean this up? */
8794       if (Pmode == DImode)
8795         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8796       else
8797         load = gen_casesi_load_media (reg4,
8798                                       gen_rtx_SUBREG (DImode, reg3, 0),
8799                                       reg2, operands[3]);
8800       PUT_MODE (SET_SRC (load), Pmode);
8801       emit_insn (load);
8802       /* ??? The following add could be eliminated if we used ptrel.  */
8803       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8804       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8805       emit_barrier ();
8806       DONE;
8807     }
8808   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8809   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8810   /* If optimizing, casesi_worker depends on the mode of the instruction
8811      before label it 'uses' - operands[3].  */
8812   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8813                            reg));
8814   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8815   if (TARGET_SH2)
8816     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8817   else
8818     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8819   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8820      operands[3], but to lab.  We will fix this up in
8821      machine_dependent_reorg.  */
8822   emit_barrier ();
8823   DONE;
8826 (define_expand "casesi_0"
8827   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8828    (set (match_dup 4) (minus:SI (match_dup 4)
8829                                 (match_operand:SI 1 "arith_operand" "")))
8830    (set (reg:SI T_REG)
8831         (gtu:SI (match_dup 4)
8832                 (match_operand:SI 2 "arith_reg_operand" "")))
8833    (set (pc)
8834         (if_then_else (ne (reg:SI T_REG)
8835                           (const_int 0))
8836                       (label_ref (match_operand 3 "" ""))
8837                       (pc)))]
8838   "TARGET_SH1"
8839   "")
8841 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8842 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8843 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8845 (define_insn "casesi_worker_0"
8846   [(set (match_operand:SI 0 "register_operand" "=r,r")
8847         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8848                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8849    (clobber (match_scratch:SI 3 "=X,1"))
8850    (clobber (match_scratch:SI 4 "=&z,z"))]
8851   "TARGET_SH1"
8852   "#")
8854 (define_split
8855   [(set (match_operand:SI 0 "register_operand" "")
8856         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8857                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8858    (clobber (match_scratch:SI 3 ""))
8859    (clobber (match_scratch:SI 4 ""))]
8860   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8861   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8862    (parallel [(set (match_dup 0)
8863               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8864                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8865               (clobber (match_dup 3))])
8866    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8867   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8869 (define_split
8870   [(set (match_operand:SI 0 "register_operand" "")
8871         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8872                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8873    (clobber (match_scratch:SI 3 ""))
8874    (clobber (match_scratch:SI 4 ""))]
8875   "TARGET_SH2 && reload_completed"
8876   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8877    (parallel [(set (match_dup 0)
8878               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8879                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8880               (clobber (match_dup 3))])]
8881   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8883 (define_insn "casesi_worker_1"
8884   [(set (match_operand:SI 0 "register_operand" "=r,r")
8885         (unspec:SI [(reg:SI R0_REG)
8886                     (match_operand:SI 1 "register_operand" "0,r")
8887                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8888    (clobber (match_scratch:SI 3 "=X,1"))]
8889   "TARGET_SH1"
8890   "*
8892   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8894   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8896   switch (GET_MODE (diff_vec))
8897     {
8898     case SImode:
8899       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8900     case HImode:
8901       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8902     case QImode:
8903       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8904         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8905       return \"mov.b    @(r0,%1),%0\";
8906     default:
8907       gcc_unreachable ();
8908     }
8910   [(set_attr "length" "4")])
8912 (define_insn "casesi_worker_2"
8913   [(set (match_operand:SI 0 "register_operand" "=r,r")
8914         (unspec:SI [(reg:SI R0_REG)
8915                     (match_operand:SI 1 "register_operand" "0,r")
8916                     (label_ref (match_operand 2 "" ""))
8917                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8918    (clobber (match_operand:SI 4 "" "=X,1"))]
8919   "TARGET_SH2 && reload_completed && flag_pic"
8920   "*
8922   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8923   const char *load;
8925   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8927   switch (GET_MODE (diff_vec))
8928     {
8929     case SImode:
8930       output_asm_insn (\"shll2    %1\", operands);
8931       load = \"mov.l    @(r0,%1),%0\"; break;
8932     case HImode:
8933       output_asm_insn (\"add    %1,%1\", operands);
8934       load = \"mov.w    @(r0,%1),%0\"; break;
8935     case QImode:
8936       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8937         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8938       else
8939         load = \"mov.b  @(r0,%1),%0\";
8940       break;
8941     default:
8942       gcc_unreachable ();
8943     }
8944   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8945   return load;
8947   [(set_attr "length" "8")])
8949 (define_insn "casesi_shift_media"
8950   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8951         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8952                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8953                     UNSPEC_CASESI)))]
8954   "TARGET_SHMEDIA"
8955   "*
8957   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8959   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8961   switch (GET_MODE (diff_vec))
8962     {
8963     case SImode:
8964       return \"shlli    %1, 2, %0\";
8965     case HImode:
8966       return \"shlli    %1, 1, %0\";
8967     case QImode:
8968       if (rtx_equal_p (operands[0], operands[1]))
8969         return \"\";
8970       return \"add      %1, r63, %0\";
8971     default:
8972       gcc_unreachable ();
8973     }
8975   [(set_attr "type" "arith_media")])
8977 (define_insn "casesi_load_media"
8978   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8979         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8980                          (match_operand:DI 2 "arith_reg_operand" "r")
8981                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8982   "TARGET_SHMEDIA"
8983   "*
8985   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8987   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8989   switch (GET_MODE (diff_vec))
8990     {
8991     case SImode:
8992       return \"ldx.l    %1, %2, %0\";
8993     case HImode:
8994 #if 0
8995       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8996         return \"ldx.uw %1, %2, %0\";
8997 #endif
8998       return \"ldx.w    %1, %2, %0\";
8999     case QImode:
9000       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9001         return \"ldx.ub %1, %2, %0\";
9002       return \"ldx.b    %1, %2, %0\";
9003     default:
9004       gcc_unreachable ();
9005     }
9007   [(set_attr "type" "load_media")])
9009 (define_expand "return"
9010   [(return)]
9011   "reload_completed && ! sh_need_epilogue ()"
9012   "
9014   if (TARGET_SHMEDIA)
9015     {
9016       emit_jump_insn (gen_return_media ());
9017       DONE;
9018     }
9020   if (TARGET_SHCOMPACT
9021       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9022     {
9023       emit_jump_insn (gen_shcompact_return_tramp ());
9024       DONE;
9025     }
9028 (define_insn "*return_i"
9029   [(return)]
9030   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9031                     && (crtl->args.info.call_cookie
9032                         & CALL_COOKIE_RET_TRAMP (1)))
9033    && reload_completed
9034    && lookup_attribute (\"trap_exit\",
9035                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9036   "*
9037   {
9038     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9039                         && !current_function_interrupt)
9040        return \"rts/n\";
9041     else
9042        return \"%@      %#\";
9043   }"
9044   [(set_attr "type" "return")
9045    (set_attr "needs_delay_slot" "yes")])
9047 ;; trapa has no delay slot.
9048 (define_insn "*return_trapa"
9049   [(return)]
9050   "TARGET_SH1 && !TARGET_SHCOMPACT
9051    && reload_completed"
9052   "%@"
9053   [(set_attr "type" "return")])
9055 (define_expand "shcompact_return_tramp"
9056   [(return)]
9057   "TARGET_SHCOMPACT
9058    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9059   "
9061   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9063   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9064   emit_jump_insn (gen_shcompact_return_tramp_i ());
9065   DONE;
9068 (define_insn "shcompact_return_tramp_i"
9069   [(parallel [(return) (use (reg:SI R0_REG))])]
9070   "TARGET_SHCOMPACT
9071    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9072   "jmp  @r0%#"
9073   [(set_attr "type" "jump_ind")
9074    (set_attr "needs_delay_slot" "yes")])
9076 (define_insn "return_media_i"
9077   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9078   "TARGET_SHMEDIA && reload_completed"
9079   "blink        %0, r63"
9080   [(set_attr "type" "jump_media")])
9082 (define_insn "return_media_rte"
9083   [(return)]
9084   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9085   "rte"
9086   [(set_attr "type" "jump_media")])
9088 (define_expand "return_media"
9089   [(return)]
9090   "TARGET_SHMEDIA && reload_completed"
9091   "
9093   int tr_regno = sh_media_register_for_return ();
9094   rtx tr;
9096   if (current_function_interrupt)
9097     {
9098       emit_jump_insn (gen_return_media_rte ());
9099       DONE;
9100     }
9101   if (tr_regno < 0)
9102     {
9103       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9105       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9106       tr_regno = TR0_REG;
9107       tr = gen_rtx_REG (Pmode, tr_regno);
9108       emit_move_insn (tr, r18);
9109     }
9110   else
9111     tr = gen_rtx_REG (Pmode, tr_regno);
9113   emit_jump_insn (gen_return_media_i (tr));
9114   DONE;
9117 (define_insn "shcompact_preserve_incoming_args"
9118   [(set (match_operand:SI 0 "register_operand" "+r")
9119         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9120   "TARGET_SHCOMPACT"
9121   ""
9122   [(set_attr "length" "0")])
9124 (define_insn "shcompact_incoming_args"
9125   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9126    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9127    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9128    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9129    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9130    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9131    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9132    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9133    (set (mem:BLK (reg:SI MACL_REG))
9134         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9135    (use (reg:SI R0_REG))
9136    (clobber (reg:SI R0_REG))
9137    (clobber (reg:SI MACL_REG))
9138    (clobber (reg:SI MACH_REG))
9139    (clobber (reg:SI PR_REG))]
9140   "TARGET_SHCOMPACT"
9141   "jsr  @r0%#"
9142   [(set_attr "needs_delay_slot" "yes")])
9144 (define_insn "shmedia_save_restore_regs_compact"
9145   [(set (reg:SI SP_REG)
9146         (plus:SI (reg:SI SP_REG)
9147                  (match_operand:SI 0 "immediate_operand" "i")))
9148    (use (reg:SI R0_REG))
9149    (clobber (reg:SI PR_REG))]
9150   "TARGET_SHCOMPACT
9151    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9152        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9153   "jsr @r0%#"
9154   [(set_attr "needs_delay_slot" "yes")])
9156 (define_expand "prologue"
9157   [(const_int 0)]
9158   ""
9159   "sh_expand_prologue (); DONE;")
9161 (define_expand "epilogue"
9162   [(return)]
9163   ""
9164   "
9166   sh_expand_epilogue (0);
9167   emit_jump_insn (gen_return ());
9168   DONE;
9171 (define_expand "eh_return"
9172   [(use (match_operand 0 "register_operand" ""))]
9173   ""
9175   rtx ra = operands[0];
9177   if (TARGET_SHMEDIA64)
9178     emit_insn (gen_eh_set_ra_di (ra));
9179   else
9180     emit_insn (gen_eh_set_ra_si (ra));
9182   DONE;
9185 ;; Clobber the return address on the stack.  We can't expand this
9186 ;; until we know where it will be put in the stack frame.
9188 (define_insn "eh_set_ra_si"
9189   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9190       UNSPECV_EH_RETURN)
9191    (clobber (match_scratch:SI 1 "=&r"))]
9192   "! TARGET_SHMEDIA64"
9193   "#")
9195 (define_insn "eh_set_ra_di"
9196   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9197       UNSPECV_EH_RETURN)
9198    (clobber (match_scratch:DI 1 "=&r"))]
9199   "TARGET_SHMEDIA64"
9200   "#")
9202 (define_split
9203   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9204       UNSPECV_EH_RETURN)
9205    (clobber (match_scratch 1 ""))]
9206   "reload_completed"
9207   [(const_int 0)]
9208   "
9210   sh_set_return_address (operands[0], operands[1]);
9211   DONE;
9214 (define_insn "blockage"
9215   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9216   ""
9217   ""
9218   [(set_attr "length" "0")])
9220 ;; ------------------------------------------------------------------------
9221 ;; Scc instructions
9222 ;; ------------------------------------------------------------------------
9224 (define_insn "movt"
9225   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9226         (eq:SI (reg:SI T_REG) (const_int 1)))]
9227   "TARGET_SH1"
9228   "movt %0"
9229   [(set_attr "type" "arith")])
9231 (define_expand "cstore4_media"
9232   [(set (match_operand:SI 0 "register_operand" "=r")
9233         (match_operator:SI 1 "sh_float_comparison_operator"
9234          [(match_operand 2 "logical_operand" "")
9235           (match_operand 3 "cmp_operand" "")]))]
9236   "TARGET_SHMEDIA"
9237   "
9239   enum machine_mode mode = GET_MODE (operands[2]);
9240   enum rtx_code code = GET_CODE (operands[1]);
9241   bool invert, swap;
9242   if (mode == VOIDmode)
9243     mode = GET_MODE (operands[3]);
9244   if (operands[2] == const0_rtx)
9245     {
9246       if (code == EQ || code == NE)
9247         operands[2] = operands[3], operands[3] = const0_rtx;
9248     }
9249   else
9250     operands[2] = force_reg (mode, operands[2]);
9251   if (operands[3] != const0_rtx)
9252     operands[3] = force_reg (mode, operands[3]);
9254   switch (code)
9255     {
9256     case GEU:
9257     case GE:
9258       swap = invert = !FLOAT_MODE_P (mode);
9259       break;
9261     case LEU:
9262     case LE:
9263       swap = FLOAT_MODE_P (mode), invert = !swap;
9264       break;
9266     case LTU:
9267     case LT:
9268       swap = true, invert = false;
9269       break;
9271     case GTU:
9272     case GT:
9273     case EQ:
9274     case UNORDERED:
9275       swap = invert = false;
9276       break;
9278     case NE:
9279       swap = invert = true;
9280       break;
9282     default:
9283       gcc_unreachable ();
9284   }
9286   if (swap)
9287     {
9288       rtx tem = operands[2];
9289       operands[2] = operands[3];
9290       operands[3] = tem;
9291       code = swap_condition (code);
9292     }
9294   if (invert)
9295     {
9296       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9297       code = reverse_condition (code);
9298       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9299       emit_insn (gen_cstore4_media (tem, operands[1],
9300                                     operands[2], operands[3]));
9301       code = EQ;
9302       operands[2] = tem;
9303       operands[3] = const0_rtx;
9304     }
9306   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9309 (define_expand "cstoresi4"
9310   [(set (match_operand:SI 0 "register_operand" "=r")
9311         (match_operator:SI 1 "comparison_operator"
9312          [(match_operand:SI 2 "cmpsi_operand" "")
9313           (match_operand:SI 3 "arith_operand" "")]))]
9314   "TARGET_SH1 || TARGET_SHMEDIA"
9315   "if (TARGET_SHMEDIA)
9316     {
9317       emit_insn (gen_cstore4_media (operands[0], operands[1],
9318                                     operands[2], operands[3]));
9319       DONE;
9320     }
9322    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9323        && sh_expand_t_scc (operands))
9324      DONE;
9326    if (! currently_expanding_to_rtl)
9327      FAIL;
9328    
9329    sh_emit_compare_and_set (operands, SImode);
9330    DONE;
9333 (define_expand "cstoredi4"
9334   [(set (match_operand:SI 0 "register_operand" "=r")
9335         (match_operator:SI 1 "comparison_operator"
9336          [(match_operand:DI 2 "arith_operand" "")
9337           (match_operand:DI 3 "arith_operand" "")]))]
9338   "TARGET_SH2 || TARGET_SHMEDIA"
9339   "if (TARGET_SHMEDIA)
9340     {
9341       emit_insn (gen_cstore4_media (operands[0], operands[1],
9342                                     operands[2], operands[3]));
9343       DONE;
9344     }
9346    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9347        && sh_expand_t_scc (operands))
9348      DONE;
9350    if (! currently_expanding_to_rtl)
9351      FAIL;
9352    
9353    sh_emit_compare_and_set (operands, DImode);
9354    DONE;
9359 ;; sne moves the complement of the T reg to DEST like this:
9360 ;;      cmp/eq ...
9361 ;;      mov    #-1,temp
9362 ;;      negc   temp,dest
9363 ;;   This is better than xoring compare result with 1 because it does
9364 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9365 ;;   loop.
9367 (define_expand "movnegt"
9368   [(set (match_dup 1) (const_int -1))
9369    (parallel [(set (match_operand:SI 0 "" "")
9370                    (neg:SI (plus:SI (reg:SI T_REG)
9371                                     (match_dup 1))))
9372               (set (reg:SI T_REG)
9373                    (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9374                           (const_int 0)))])]
9375   ""
9376   "
9378   operands[1] = gen_reg_rtx (SImode);
9382 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9383 ;; This prevents a regression that occurred when we switched from xor to
9384 ;; mov/neg for sne.
9386 (define_split
9387   [(set (match_operand:SI 0 "arith_reg_dest" "")
9388         (plus:SI (reg:SI T_REG)
9389                  (const_int -1)))]
9390   "TARGET_SH1"
9391   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9392    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9393   "")
9395 (define_expand "cstoresf4"
9396   [(set (match_operand:SI 0 "register_operand" "=r")
9397         (match_operator:SI 1 "sh_float_comparison_operator"
9398          [(match_operand:SF 2 "arith_operand" "")
9399           (match_operand:SF 3 "arith_operand" "")]))]
9400   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9401   "if (TARGET_SHMEDIA)
9402      {
9403        emit_insn (gen_cstore4_media (operands[0], operands[1],
9404                                      operands[2], operands[3]));
9405        DONE;
9406      }
9408    if (! currently_expanding_to_rtl)
9409      FAIL;
9410    
9411    sh_emit_compare_and_set (operands, SFmode);
9412    DONE;
9415 (define_expand "cstoredf4"
9416   [(set (match_operand:SI 0 "register_operand" "=r")
9417         (match_operator:SI 1 "sh_float_comparison_operator"
9418          [(match_operand:DF 2 "arith_operand" "")
9419           (match_operand:DF 3 "arith_operand" "")]))]
9420   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9421   "if (TARGET_SHMEDIA)
9422      {
9423        emit_insn (gen_cstore4_media (operands[0], operands[1],
9424                                      operands[2], operands[3]));
9425        DONE;
9426      }
9428     if (! currently_expanding_to_rtl)
9429       FAIL;
9430    
9431    sh_emit_compare_and_set (operands, DFmode);
9432    DONE;
9436 ;; -------------------------------------------------------------------------
9437 ;; Instructions to cope with inline literal tables
9438 ;; -------------------------------------------------------------------------
9440 ; 2 byte integer in line
9442 (define_insn "consttable_2"
9443  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9444                     (match_operand 1 "" "")]
9445                    UNSPECV_CONST2)]
9446  ""
9447  "*
9449   if (operands[1] != const0_rtx)
9450     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9451   return \"\";
9453  [(set_attr "length" "2")
9454  (set_attr "in_delay_slot" "no")])
9456 ; 4 byte integer in line
9458 (define_insn "consttable_4"
9459  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9460                     (match_operand 1 "" "")]
9461                    UNSPECV_CONST4)]
9462  ""
9463  "*
9465   if (operands[1] != const0_rtx)
9466     {
9467       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9468       mark_symbol_refs_as_used (operands[0]);
9469     }
9470   return \"\";
9472  [(set_attr "length" "4")
9473   (set_attr "in_delay_slot" "no")])
9475 ; 8 byte integer in line
9477 (define_insn "consttable_8"
9478  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9479                     (match_operand 1 "" "")]
9480                    UNSPECV_CONST8)]
9481  ""
9482  "*
9484   if (operands[1] != const0_rtx)
9485     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9486   return \"\";
9488  [(set_attr "length" "8")
9489   (set_attr "in_delay_slot" "no")])
9491 ; 4 byte floating point
9493 (define_insn "consttable_sf"
9494  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9495                     (match_operand 1 "" "")]
9496                    UNSPECV_CONST4)]
9497  ""
9498  "*
9500   if (operands[1] != const0_rtx)
9501     {
9502       REAL_VALUE_TYPE d;
9503       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9504       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9505     }
9506   return \"\";
9508  [(set_attr "length" "4")
9509   (set_attr "in_delay_slot" "no")])
9511 ; 8 byte floating point
9513 (define_insn "consttable_df"
9514  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9515                     (match_operand 1 "" "")]
9516                    UNSPECV_CONST8)]
9517  ""
9518  "*
9520   if (operands[1] != const0_rtx)
9521     {
9522       REAL_VALUE_TYPE d;
9523       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9524       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9525     }
9526   return \"\";
9528  [(set_attr "length" "8")
9529   (set_attr "in_delay_slot" "no")])
9531 ;; Alignment is needed for some constant tables; it may also be added for
9532 ;; Instructions at the start of loops, or after unconditional branches.
9533 ;; ??? We would get more accurate lengths if we did instruction
9534 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9535 ;; here is too conservative.
9537 ; align to a two byte boundary
9539 (define_expand "align_2"
9540  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9541  ""
9542  "")
9544 ; align to a four byte boundary
9545 ;; align_4 and align_log are instructions for the starts of loops, or
9546 ;; after unconditional branches, which may take up extra room.
9548 (define_expand "align_4"
9549  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9550  ""
9551  "")
9553 ; align to a cache line boundary
9555 (define_insn "align_log"
9556  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9557  ""
9558  ""
9559  [(set_attr "length" "0")
9560   (set_attr "in_delay_slot" "no")])
9562 ; emitted at the end of the literal table, used to emit the
9563 ; 32bit branch labels if needed.
9565 (define_insn "consttable_end"
9566   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9567   ""
9568   "* return output_jump_label_table ();"
9569   [(set_attr "in_delay_slot" "no")])
9571 ; emitted at the end of the window in the literal table.
9573 (define_insn "consttable_window_end"
9574   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9575   ""
9576   ""
9577   [(set_attr "length" "0")
9578    (set_attr "in_delay_slot" "no")])
9580 ;; -------------------------------------------------------------------------
9581 ;; Misc
9582 ;; -------------------------------------------------------------------------
9584 ;; String/block move insn.
9586 (define_expand "movmemsi"
9587   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9588                    (mem:BLK (match_operand:BLK 1 "" "")))
9589               (use (match_operand:SI 2 "nonmemory_operand" ""))
9590               (use (match_operand:SI 3 "immediate_operand" ""))
9591               (clobber (reg:SI PR_REG))
9592               (clobber (reg:SI R4_REG))
9593               (clobber (reg:SI R5_REG))
9594               (clobber (reg:SI R0_REG))])]
9595   "TARGET_SH1 && ! TARGET_SH5"
9596   "
9598   if(expand_block_move (operands))
9599      DONE;
9600   else FAIL;
9603 (define_insn "block_move_real"
9604   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9605                    (mem:BLK (reg:SI R5_REG)))
9606               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9607               (clobber (reg:SI PR_REG))
9608               (clobber (reg:SI R0_REG))])]
9609   "TARGET_SH1 && ! TARGET_HARD_SH4"
9610   "jsr  @%0%#"
9611   [(set_attr "type" "sfunc")
9612    (set_attr "needs_delay_slot" "yes")])
9614 (define_insn "block_lump_real"
9615   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9616                    (mem:BLK (reg:SI R5_REG)))
9617               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9618               (use (reg:SI R6_REG))
9619               (clobber (reg:SI PR_REG))
9620               (clobber (reg:SI T_REG))
9621               (clobber (reg:SI R4_REG))
9622               (clobber (reg:SI R5_REG))
9623               (clobber (reg:SI R6_REG))
9624               (clobber (reg:SI R0_REG))])]
9625   "TARGET_SH1 && ! TARGET_HARD_SH4"
9626   "jsr  @%0%#"
9627   [(set_attr "type" "sfunc")
9628    (set_attr "needs_delay_slot" "yes")])
9630 (define_insn "block_move_real_i4"
9631   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9632                    (mem:BLK (reg:SI R5_REG)))
9633               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9634               (clobber (reg:SI PR_REG))
9635               (clobber (reg:SI R0_REG))
9636               (clobber (reg:SI R1_REG))
9637               (clobber (reg:SI R2_REG))])]
9638   "TARGET_HARD_SH4"
9639   "jsr  @%0%#"
9640   [(set_attr "type" "sfunc")
9641    (set_attr "needs_delay_slot" "yes")])
9643 (define_insn "block_lump_real_i4"
9644   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9645                    (mem:BLK (reg:SI R5_REG)))
9646               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9647               (use (reg:SI R6_REG))
9648               (clobber (reg:SI PR_REG))
9649               (clobber (reg:SI T_REG))
9650               (clobber (reg:SI R4_REG))
9651               (clobber (reg:SI R5_REG))
9652               (clobber (reg:SI R6_REG))
9653               (clobber (reg:SI R0_REG))
9654               (clobber (reg:SI R1_REG))
9655               (clobber (reg:SI R2_REG))
9656               (clobber (reg:SI R3_REG))])]
9657   "TARGET_HARD_SH4"
9658   "jsr  @%0%#"
9659   [(set_attr "type" "sfunc")
9660    (set_attr "needs_delay_slot" "yes")])
9662 ;; -------------------------------------------------------------------------
9663 ;; Floating point instructions.
9664 ;; -------------------------------------------------------------------------
9666 ;; ??? All patterns should have a type attribute.
9668 (define_expand "movpsi"
9669   [(set (match_operand:PSI 0 "register_operand" "")
9670         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9671   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9672   "")
9674 ;; The c / m alternative is a fake to guide reload to load directly into
9675 ;; fpscr, since reload doesn't know how to use post-increment.
9676 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9677 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9678 ;; predicate after reload.
9679 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9680 ;; like a mac -> gpr move.
9681 (define_insn "fpu_switch"
9682   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9683         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9684   "TARGET_SH2E
9685    && (! reload_completed
9686        || true_regnum (operands[0]) != FPSCR_REG
9687        || !MEM_P (operands[1])
9688        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9689   "@
9690         ! precision stays the same
9691         lds.l   %1,fpscr
9692         mov.l   %1,%0
9693         #
9694         lds     %1,fpscr
9695         mov     %1,%0
9696         mov.l   %1,%0
9697         sts     fpscr,%0
9698         sts.l   fpscr,%0"
9699   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9700    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9702 (define_peephole2
9703   [(set (reg:PSI FPSCR_REG)
9704         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9705   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9706   [(const_int 0)]
9708   rtx fpscr, mem, new_insn;
9710   fpscr = SET_DEST (PATTERN (curr_insn));
9711   mem = SET_SRC (PATTERN (curr_insn));
9712   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9714   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9715   add_reg_note (new_insn, REG_INC, operands[0]);
9716   DONE;
9719 (define_split
9720   [(set (reg:PSI FPSCR_REG)
9721         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9722   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9723    && (flag_peephole2 ? epilogue_completed : reload_completed)"
9724   [(const_int 0)]
9726   rtx fpscr, mem, new_insn;
9728   fpscr = SET_DEST (PATTERN (curr_insn));
9729   mem = SET_SRC (PATTERN (curr_insn));
9730   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9732   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9733   add_reg_note (new_insn, REG_INC, operands[0]);
9735   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9736     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9737   DONE;
9740 ;; ??? This uses the fp unit, but has no type indicating that.
9741 ;; If we did that, this would either give a bogus latency or introduce
9742 ;; a bogus FIFO constraint.
9743 ;; Since this insn is currently only used for prologues/epilogues,
9744 ;; it is probably best to claim no function unit, which matches the
9745 ;; current setting.
9746 (define_insn "toggle_sz"
9747   [(set (reg:PSI FPSCR_REG)
9748         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9749   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9750   "fschg"
9751   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9753 ;; There's no way we can use it today, since optimize mode switching
9754 ;; doesn't enable us to know from which mode we're switching to the
9755 ;; mode it requests, to tell whether we can use a relative mode switch
9756 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9757 ;; memory).
9758 (define_insn "toggle_pr"
9759   [(set (reg:PSI FPSCR_REG)
9760         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9761   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9762   "fpchg"
9763   [(set_attr "type" "fpscr_toggle")])
9765 (define_expand "addsf3"
9766   [(set (match_operand:SF 0 "arith_reg_operand" "")
9767         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9768                  (match_operand:SF 2 "arith_reg_operand" "")))]
9769   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9770   "
9772   if (TARGET_SH2E)
9773     {
9774       expand_sf_binop (&gen_addsf3_i, operands);
9775       DONE;
9776     }
9779 (define_insn "*addsf3_media"
9780   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9781         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9782                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9783   "TARGET_SHMEDIA_FPU"
9784   "fadd.s       %1, %2, %0"
9785   [(set_attr "type" "fparith_media")])
9787 (define_insn_and_split "unary_sf_op"
9788   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9789         (vec_select:V2SF
9790          (vec_concat:V2SF
9791           (vec_select:SF
9792            (match_dup 0)
9793            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9794           (match_operator:SF 2 "unary_float_operator"
9795             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9796                             (parallel [(match_operand 4
9797                                         "const_int_operand" "n")]))]))
9798          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9799   "TARGET_SHMEDIA_FPU"
9800   "#"
9801   "TARGET_SHMEDIA_FPU && reload_completed"
9802   [(set (match_dup 5) (match_dup 6))]
9803   "
9805   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9806   rtx op1 = gen_rtx_REG (SFmode,
9807                          (true_regnum (operands[1])
9808                           + (INTVAL (operands[4]) ^ endian)));
9810   operands[7] = gen_rtx_REG (SFmode,
9811                              (true_regnum (operands[0])
9812                               + (INTVAL (operands[3]) ^ endian)));
9813   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9815   [(set_attr "type" "fparith_media")])
9817 (define_insn_and_split "binary_sf_op0"
9818   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9819         (vec_concat:V2SF
9820           (match_operator:SF 3 "binary_float_operator"
9821             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9822                             (parallel [(const_int 0)]))
9823              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9824                             (parallel [(const_int 0)]))])
9825           (vec_select:SF
9826            (match_dup 0)
9827            (parallel [(const_int 1)]))))]
9828   "TARGET_SHMEDIA_FPU"
9829   "#"
9830   "&& reload_completed"
9831   [(set (match_dup 4) (match_dup 5))]
9832   "
9834   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9835   rtx op1 = gen_rtx_REG (SFmode,
9836                          true_regnum (operands[1]) + endian);
9837   rtx op2 = gen_rtx_REG (SFmode,
9838                          true_regnum (operands[2]) + endian);
9840   operands[4] = gen_rtx_REG (SFmode,
9841                              true_regnum (operands[0]) + endian);
9842   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9844   [(set_attr "type" "fparith_media")])
9846 (define_insn_and_split "binary_sf_op1"
9847   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9848         (vec_concat:V2SF
9849           (vec_select:SF
9850            (match_dup 0)
9851            (parallel [(const_int 0)]))
9852           (match_operator:SF 3 "binary_float_operator"
9853             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9854                             (parallel [(const_int 1)]))
9855              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9856                             (parallel [(const_int 1)]))])))]
9857   "TARGET_SHMEDIA_FPU"
9858   "#"
9859   "&& reload_completed"
9860   [(set (match_dup 4) (match_dup 5))]
9861   "
9863   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9864   rtx op1 = gen_rtx_REG (SFmode,
9865                          true_regnum (operands[1]) + (1 ^ endian));
9866   rtx op2 = gen_rtx_REG (SFmode,
9867                          true_regnum (operands[2]) + (1 ^ endian));
9869   operands[4] = gen_rtx_REG (SFmode,
9870                              true_regnum (operands[0]) + (1 ^ endian));
9871   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9873   [(set_attr "type" "fparith_media")])
9875 (define_insn "addsf3_i"
9876   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9877         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9878                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9879    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9880   "TARGET_SH2E"
9881   "fadd %2,%0"
9882   [(set_attr "type" "fp")
9883    (set_attr "fp_mode" "single")])
9885 (define_expand "subsf3"
9886   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9887         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9888                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9889   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9890   "
9892   if (TARGET_SH2E)
9893     {
9894       expand_sf_binop (&gen_subsf3_i, operands);
9895       DONE;
9896     }
9899 (define_insn "*subsf3_media"
9900   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9901         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9902                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9903   "TARGET_SHMEDIA_FPU"
9904   "fsub.s       %1, %2, %0"
9905   [(set_attr "type" "fparith_media")])
9907 (define_insn "subsf3_i"
9908   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9909         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9910                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9911    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9912   "TARGET_SH2E"
9913   "fsub %2,%0"
9914   [(set_attr "type" "fp")
9915    (set_attr "fp_mode" "single")])
9917 (define_expand "mulsf3"
9918   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9919         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9920                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9921   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9922   "")
9924 (define_insn "*mulsf3_media"
9925   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9926         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9927                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9928   "TARGET_SHMEDIA_FPU"
9929   "fmul.s       %1, %2, %0"
9930   [(set_attr "type" "fparith_media")])
9932 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9933 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
9934 ;; we start out with a mulsf pattern that does not depend on fpscr.
9935 ;; This is split after combine to introduce the dependency, in order to
9936 ;; get mode switching and scheduling right.
9937 (define_insn_and_split "mulsf3_ie"
9938   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9939         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9940                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9941   "TARGET_SH2E"
9942   "fmul %2,%0"
9943   "TARGET_SH4 || TARGET_SH2A_SINGLE"
9944   [(const_int 0)]
9945   "
9947   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9948              get_fpscr_rtx ()));
9949   DONE;
9951   [(set_attr "type" "fp")])
9953 (define_insn "mulsf3_i4"
9954   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9955         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9956                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9957    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9958   "TARGET_SH2E"
9959   "fmul %2,%0"
9960   [(set_attr "type" "fp")
9961    (set_attr "fp_mode" "single")])
9963 (define_insn "mac_media"
9964   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9965         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9966                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9967                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
9968   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
9969   "fmac.s %1, %2, %0"
9970   [(set_attr "type" "fparith_media")])
9972 (define_insn "*macsf3"
9973   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9974         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
9975                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9976                  (match_operand:SF 3 "arith_reg_operand" "0")))
9977    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
9978   "TARGET_SH2E && TARGET_FMAC"
9979   "fmac fr0,%2,%0"
9980   [(set_attr "type" "fp")
9981    (set_attr "fp_mode" "single")])
9983 (define_expand "divsf3"
9984   [(set (match_operand:SF 0 "arith_reg_operand" "")
9985         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
9986                 (match_operand:SF 2 "arith_reg_operand" "")))]
9987   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9988   "
9990   if (TARGET_SH2E)
9991     {
9992       expand_sf_binop (&gen_divsf3_i, operands);
9993       DONE;
9994     }
9997 (define_insn "*divsf3_media"
9998   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9999         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10000                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10001   "TARGET_SHMEDIA_FPU"
10002   "fdiv.s       %1, %2, %0"
10003   [(set_attr "type" "fdiv_media")])
10005 (define_insn "divsf3_i"
10006   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10007         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10008                  (match_operand:SF 2 "arith_reg_operand" "f")))
10009    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10010   "TARGET_SH2E"
10011   "fdiv %2,%0"
10012   [(set_attr "type" "fdiv")
10013    (set_attr "fp_mode" "single")])
10015 (define_insn "floatdisf2"
10016   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10017         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10018   "TARGET_SHMEDIA_FPU"
10019   "float.qs %1, %0"
10020   [(set_attr "type" "fpconv_media")])
10022 (define_expand "floatsisf2"
10023   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10024         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10025   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10026   "
10028   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10029     {
10030       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10031       DONE;
10032     }
10035 (define_insn "*floatsisf2_media"
10036   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10037         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10038   "TARGET_SHMEDIA_FPU"
10039   "float.ls     %1, %0"
10040   [(set_attr "type" "fpconv_media")])
10042 (define_insn "floatsisf2_i4"
10043   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10044         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10045    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10046   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10047   "float        %1,%0"
10048   [(set_attr "type" "fp")
10049    (set_attr "fp_mode" "single")])
10051 (define_insn "*floatsisf2_ie"
10052   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10053         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10054   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10055   "float        %1,%0"
10056   [(set_attr "type" "fp")])
10058 (define_insn "fix_truncsfdi2"
10059   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10060         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10061   "TARGET_SHMEDIA_FPU"
10062   "ftrc.sq %1, %0"
10063   [(set_attr "type" "fpconv_media")])
10065 (define_expand "fix_truncsfsi2"
10066   [(set (match_operand:SI 0 "fpul_operand" "=y")
10067         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10068   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10069   "
10071   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10072     {
10073       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10074       DONE;
10075     }
10078 (define_insn "*fix_truncsfsi2_media"
10079   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10080         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10081   "TARGET_SHMEDIA_FPU"
10082   "ftrc.sl      %1, %0"
10083   [(set_attr "type" "fpconv_media")])
10085 (define_insn "fix_truncsfsi2_i4"
10086   [(set (match_operand:SI 0 "fpul_operand" "=y")
10087         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10088    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10089   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10090   "ftrc %1,%0"
10091   [(set_attr "type" "ftrc_s")
10092    (set_attr "fp_mode" "single")])
10094 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10095 ;; fix_truncsfsi2_i4.
10096 ;; (define_insn "fix_truncsfsi2_i4_2"
10097 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10098 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10099 ;;   (use (reg:PSI FPSCR_REG))
10100 ;;   (clobber (reg:SI FPUL_REG))]
10101 ;;  "TARGET_SH4"
10102 ;;  "#"
10103 ;;  [(set_attr "length" "4")
10104 ;;   (set_attr "fp_mode" "single")])
10106 ;;(define_split
10107 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10108 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10109 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10110 ;;   (clobber (reg:SI FPUL_REG))]
10111 ;;  "TARGET_SH4"
10112 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10113 ;;            (use (match_dup 2))])
10114 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10116 (define_insn "*fixsfsi"
10117   [(set (match_operand:SI 0 "fpul_operand" "=y")
10118         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10119   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10120   "ftrc %1,%0"
10121   [(set_attr "type" "fp")])
10123 (define_insn "cmpgtsf_t"
10124   [(set (reg:SI T_REG)
10125         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10126                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10127   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10128   "fcmp/gt      %1,%0"
10129   [(set_attr "type" "fp_cmp")
10130    (set_attr "fp_mode" "single")])
10132 (define_insn "cmpeqsf_t"
10133   [(set (reg:SI T_REG)
10134         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10135                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10136   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10137   "fcmp/eq      %1,%0"
10138   [(set_attr "type" "fp_cmp")
10139    (set_attr "fp_mode" "single")])
10141 (define_insn "ieee_ccmpeqsf_t"
10142   [(set (reg:SI T_REG)
10143         (ior:SI (reg:SI T_REG)
10144                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10145                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10146   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10147   "* return output_ieee_ccmpeq (insn, operands);"
10148   [(set_attr "length" "4")])
10151 (define_insn "cmpgtsf_t_i4"
10152   [(set (reg:SI T_REG)
10153         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10154                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10155    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10156   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10157   "fcmp/gt      %1,%0"
10158   [(set_attr "type" "fp_cmp")
10159    (set_attr "fp_mode" "single")])
10161 (define_insn "cmpeqsf_t_i4"
10162   [(set (reg:SI T_REG)
10163         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10164                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10165    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10166   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10167   "fcmp/eq      %1,%0"
10168   [(set_attr "type" "fp_cmp")
10169    (set_attr "fp_mode" "single")])
10171 (define_insn "*ieee_ccmpeqsf_t_4"
10172   [(set (reg:SI T_REG)
10173         (ior:SI (reg:SI T_REG)
10174                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10175                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10176    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10177   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10178   "* return output_ieee_ccmpeq (insn, operands);"
10179   [(set_attr "length" "4")
10180    (set_attr "fp_mode" "single")])
10182 (define_insn "cmpeqsf_media"
10183   [(set (match_operand:SI 0 "register_operand" "=r")
10184         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10185                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10186   "TARGET_SHMEDIA_FPU"
10187   "fcmpeq.s     %1, %2, %0"
10188   [(set_attr "type" "fcmp_media")])
10190 (define_insn "cmpgtsf_media"
10191   [(set (match_operand:SI 0 "register_operand" "=r")
10192         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10193                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10194   "TARGET_SHMEDIA_FPU"
10195   "fcmpgt.s     %1, %2, %0"
10196   [(set_attr "type" "fcmp_media")])
10198 (define_insn "cmpgesf_media"
10199   [(set (match_operand:SI 0 "register_operand" "=r")
10200         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10201                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10202   "TARGET_SHMEDIA_FPU"
10203   "fcmpge.s     %1, %2, %0"
10204   [(set_attr "type" "fcmp_media")])
10206 (define_insn "cmpunsf_media"
10207   [(set (match_operand:SI 0 "register_operand" "=r")
10208         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10209                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10210   "TARGET_SHMEDIA_FPU"
10211   "fcmpun.s     %1, %2, %0"
10212   [(set_attr "type" "fcmp_media")])
10214 (define_expand "cbranchsf4"
10215   [(set (pc)
10216         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10217                        [(match_operand:SF 1 "arith_operand" "")
10218                         (match_operand:SF 2 "arith_operand" "")])
10219                       (match_operand 3 "" "")
10220                       (pc)))]
10221   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10222   "
10224   if (TARGET_SHMEDIA)
10225     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10226                                           operands[3]));
10227   else
10228     sh_emit_compare_and_branch (operands, SFmode);
10229   DONE;
10232 (define_expand "negsf2"
10233   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10234         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10235   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10236   "
10238   if (TARGET_SH2E)
10239     {
10240       expand_sf_unop (&gen_negsf2_i, operands);
10241       DONE;
10242     }
10245 (define_insn "*negsf2_media"
10246   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10247         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10248   "TARGET_SHMEDIA_FPU"
10249   "fneg.s       %1, %0"
10250   [(set_attr "type" "fmove_media")])
10252 (define_insn "negsf2_i"
10253   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10254         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10255    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10256   "TARGET_SH2E"
10257   "fneg %0"
10258   [(set_attr "type" "fmove")
10259    (set_attr "fp_mode" "single")])
10261 (define_expand "sqrtsf2"
10262   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10263         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10264   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10265   "
10267   if (TARGET_SH3E)
10268     {
10269       expand_sf_unop (&gen_sqrtsf2_i, operands);
10270       DONE;
10271     }
10274 (define_insn "*sqrtsf2_media"
10275   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10276         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10277   "TARGET_SHMEDIA_FPU"
10278   "fsqrt.s      %1, %0"
10279   [(set_attr "type" "fdiv_media")])
10281 (define_insn "sqrtsf2_i"
10282   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10283         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10284    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10285   "TARGET_SH3E"
10286   "fsqrt        %0"
10287   [(set_attr "type" "fdiv")
10288    (set_attr "fp_mode" "single")])
10290 (define_insn "rsqrtsf2"
10291   [(set (match_operand:SF 0 "register_operand" "=f")
10292         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10293                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10294    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10295   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10296    && operands[1] == CONST1_RTX (SFmode)"
10297   "fsrra        %0"
10298   [(set_attr "type" "fsrra")
10299    (set_attr "fp_mode" "single")])
10301 (define_insn "fsca"
10302   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10303         (vec_concat:V2SF
10304          (unspec:SF [(mult:SF
10305                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10306                       (match_operand:SF 2 "immediate_operand" "i"))
10307                     ] UNSPEC_FSINA)
10308          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10309                     ] UNSPEC_FCOSA)))
10310    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10311   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10312    && operands[2] == sh_fsca_int2sf ()"
10313   "fsca fpul,%d0"
10314   [(set_attr "type" "fsca")
10315    (set_attr "fp_mode" "single")])
10317 (define_expand "sinsf2"
10318   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10319         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10320                    UNSPEC_FSINA))]
10321   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10322   "
10324   rtx scaled = gen_reg_rtx (SFmode);
10325   rtx truncated = gen_reg_rtx (SImode);
10326   rtx fsca = gen_reg_rtx (V2SFmode);
10327   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10329   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10330   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10331   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10332                           get_fpscr_rtx ()));
10333   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10334   DONE;
10337 (define_expand "cossf2"
10338   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10339         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10340                    UNSPEC_FCOSA))]
10341   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10342   "
10344   rtx scaled = gen_reg_rtx (SFmode);
10345   rtx truncated = gen_reg_rtx (SImode);
10346   rtx fsca = gen_reg_rtx (V2SFmode);
10347   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10349   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10350   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10351   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10352                           get_fpscr_rtx ()));
10353   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10354   DONE;
10357 (define_expand "sindf2"
10358   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10359         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10360                    UNSPEC_FSINA))]
10361   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10362   "
10364   rtx scaled = gen_reg_rtx (DFmode);
10365   rtx truncated = gen_reg_rtx (SImode);
10366   rtx fsca = gen_reg_rtx (V2SFmode);
10367   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10368   rtx sfresult = gen_reg_rtx (SFmode);
10370   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10371   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10372   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10373                           get_fpscr_rtx ()));
10374   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10375   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10376   DONE;
10379 (define_expand "cosdf2"
10380   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10381         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10382                    UNSPEC_FCOSA))]
10383   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10384   "
10386   rtx scaled = gen_reg_rtx (DFmode);
10387   rtx truncated = gen_reg_rtx (SImode);
10388   rtx fsca = gen_reg_rtx (V2SFmode);
10389   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10390   rtx sfresult = gen_reg_rtx (SFmode);
10392   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10393   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10394   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10395                           get_fpscr_rtx ()));
10396   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10397   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10398   DONE;
10401 (define_expand "abssf2"
10402   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10403         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10404   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10405   "
10407   if (TARGET_SH2E)
10408     {
10409       expand_sf_unop (&gen_abssf2_i, operands);
10410       DONE;
10411     }
10414 (define_insn "*abssf2_media"
10415   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10416         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10417   "TARGET_SHMEDIA_FPU"
10418   "fabs.s       %1, %0"
10419   [(set_attr "type" "fmove_media")])
10421 (define_insn "abssf2_i"
10422   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10423         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10424    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10425   "TARGET_SH2E"
10426   "fabs %0"
10427   [(set_attr "type" "fmove")
10428    (set_attr "fp_mode" "single")])
10430 (define_expand "adddf3"
10431   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10432         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10433                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10434   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10435   "
10437   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10438     {
10439       expand_df_binop (&gen_adddf3_i, operands);
10440       DONE;
10441     }
10444 (define_insn "*adddf3_media"
10445   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10446         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10447                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10448   "TARGET_SHMEDIA_FPU"
10449   "fadd.d       %1, %2, %0"
10450   [(set_attr "type" "dfparith_media")])
10452 (define_insn "adddf3_i"
10453   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10454         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10455                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10456    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10457   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10458   "fadd %2,%0"
10459   [(set_attr "type" "dfp_arith")
10460    (set_attr "fp_mode" "double")])
10462 (define_expand "subdf3"
10463   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10464         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10465                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10466   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10467   "
10469   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10470     {
10471       expand_df_binop (&gen_subdf3_i, operands);
10472       DONE;
10473     }
10476 (define_insn "*subdf3_media"
10477   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10478         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10479                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10480   "TARGET_SHMEDIA_FPU"
10481   "fsub.d       %1, %2, %0"
10482   [(set_attr "type" "dfparith_media")])
10484 (define_insn "subdf3_i"
10485   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10486         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10487                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10488    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10489   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10490   "fsub %2,%0"
10491   [(set_attr "type" "dfp_arith")
10492    (set_attr "fp_mode" "double")])
10494 (define_expand "muldf3"
10495   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10496         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10497                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10498   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10499   "
10501   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10502     {
10503       expand_df_binop (&gen_muldf3_i, operands);
10504       DONE;
10505     }
10508 (define_insn "*muldf3_media"
10509   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10510         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10511                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10512   "TARGET_SHMEDIA_FPU"
10513   "fmul.d       %1, %2, %0"
10514   [(set_attr "type" "dfmul_media")])
10516 (define_insn "muldf3_i"
10517   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10518         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10519                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10520    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10521   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10522   "fmul %2,%0"
10523   [(set_attr "type" "dfp_mul")
10524    (set_attr "fp_mode" "double")])
10526 (define_expand "divdf3"
10527   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10528         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10529                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10530   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10531   "
10533   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10534     {
10535       expand_df_binop (&gen_divdf3_i, operands);
10536       DONE;
10537     }
10540 (define_insn "*divdf3_media"
10541   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10542         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10543                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10544   "TARGET_SHMEDIA_FPU"
10545   "fdiv.d       %1, %2, %0"
10546   [(set_attr "type" "dfdiv_media")])
10548 (define_insn "divdf3_i"
10549   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10550         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10551                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10552    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10553   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10554   "fdiv %2,%0"
10555   [(set_attr "type" "dfdiv")
10556    (set_attr "fp_mode" "double")])
10558 (define_insn "floatdidf2"
10559   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10560         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10561   "TARGET_SHMEDIA_FPU"
10562   "float.qd     %1, %0"
10563   [(set_attr "type" "dfpconv_media")])
10565 (define_expand "floatsidf2"
10566   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10567         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10568   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10569   "
10571   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10572     {
10573       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10574                                       get_fpscr_rtx ()));
10575       DONE;
10576     }
10579 (define_insn "*floatsidf2_media"
10580   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10581         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10582   "TARGET_SHMEDIA_FPU"
10583   "float.ld     %1, %0"
10584   [(set_attr "type" "dfpconv_media")])
10586 (define_insn "floatsidf2_i"
10587   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10588         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10589    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10590   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10591   "float        %1,%0"
10592   [(set_attr "type" "dfp_conv")
10593    (set_attr "fp_mode" "double")])
10595 (define_insn "fix_truncdfdi2"
10596   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10597         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10598   "TARGET_SHMEDIA_FPU"
10599   "ftrc.dq      %1, %0"
10600   [(set_attr "type" "dfpconv_media")])
10602 (define_expand "fix_truncdfsi2"
10603   [(set (match_operand:SI 0 "fpul_operand" "")
10604         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10605   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10606   "
10608   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10609     {
10610       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10611                                           get_fpscr_rtx ()));
10612       DONE;
10613     }
10616 (define_insn "*fix_truncdfsi2_media"
10617   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10618         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10619   "TARGET_SHMEDIA_FPU"
10620   "ftrc.dl      %1, %0"
10621   [(set_attr "type" "dfpconv_media")])
10623 (define_insn "fix_truncdfsi2_i"
10624   [(set (match_operand:SI 0 "fpul_operand" "=y")
10625         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10626    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10627   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10628   "ftrc %1,%0"
10629   [(set_attr "type" "dfp_conv")
10630    (set_attr "dfp_comp" "no")
10631    (set_attr "fp_mode" "double")])
10633 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10634 ;; fix_truncdfsi2_i.
10635 ;; (define_insn "fix_truncdfsi2_i4"
10636 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10637 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10638 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10639 ;;    (clobber (reg:SI FPUL_REG))]
10640 ;;   "TARGET_SH4"
10641 ;;   "#"
10642 ;;   [(set_attr "length" "4")
10643 ;;    (set_attr "fp_mode" "double")])
10645 ;; (define_split
10646 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10647 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10648 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10649 ;;    (clobber (reg:SI FPUL_REG))]
10650 ;;   "TARGET_SH4"
10651 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10652 ;;            (use (match_dup 2))])
10653 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10655 (define_insn "cmpgtdf_t"
10656   [(set (reg:SI T_REG)
10657         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10658                (match_operand:DF 1 "arith_reg_operand" "f")))
10659    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10660   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10661   "fcmp/gt      %1,%0"
10662   [(set_attr "type" "dfp_cmp")
10663    (set_attr "fp_mode" "double")])
10665 (define_insn "cmpeqdf_t"
10666   [(set (reg:SI T_REG)
10667         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10668                (match_operand:DF 1 "arith_reg_operand" "f")))
10669    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10670   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10671   "fcmp/eq      %1,%0"
10672   [(set_attr "type" "dfp_cmp")
10673    (set_attr "fp_mode" "double")])
10675 (define_insn "*ieee_ccmpeqdf_t"
10676   [(set (reg:SI T_REG)
10677         (ior:SI (reg:SI T_REG)
10678                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10679                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10680    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10681   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10682   "* return output_ieee_ccmpeq (insn, operands);"
10683   [(set_attr "length" "4")
10684    (set_attr "fp_mode" "double")])
10686 (define_insn "cmpeqdf_media"
10687   [(set (match_operand:SI 0 "register_operand" "=r")
10688         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10689                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10690   "TARGET_SHMEDIA_FPU"
10691   "fcmpeq.d     %1,%2,%0"
10692   [(set_attr "type" "fcmp_media")])
10694 (define_insn "cmpgtdf_media"
10695   [(set (match_operand:SI 0 "register_operand" "=r")
10696         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10697                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10698   "TARGET_SHMEDIA_FPU"
10699   "fcmpgt.d     %1,%2,%0"
10700   [(set_attr "type" "fcmp_media")])
10702 (define_insn "cmpgedf_media"
10703   [(set (match_operand:SI 0 "register_operand" "=r")
10704         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10705                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10706   "TARGET_SHMEDIA_FPU"
10707   "fcmpge.d     %1,%2,%0"
10708   [(set_attr "type" "fcmp_media")])
10710 (define_insn "cmpundf_media"
10711   [(set (match_operand:SI 0 "register_operand" "=r")
10712         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10713                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10714   "TARGET_SHMEDIA_FPU"
10715   "fcmpun.d     %1,%2,%0"
10716   [(set_attr "type" "fcmp_media")])
10718 (define_expand "cbranchdf4"
10719   [(set (pc)
10720         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10721                        [(match_operand:DF 1 "arith_operand" "")
10722                         (match_operand:DF 2 "arith_operand" "")])
10723                       (match_operand 3 "" "")
10724                       (pc)))]
10725   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10726   "
10728   if (TARGET_SHMEDIA)
10729     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10730                                           operands[3]));
10731   else
10732     sh_emit_compare_and_branch (operands, DFmode);
10733   DONE;
10737 (define_expand "negdf2"
10738   [(set (match_operand:DF 0 "arith_reg_operand" "")
10739         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10740   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10741   "
10743   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10744     {
10745       expand_df_unop (&gen_negdf2_i, operands);
10746       DONE;
10747     }
10750 (define_insn "*negdf2_media"
10751   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10752         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10753   "TARGET_SHMEDIA_FPU"
10754   "fneg.d       %1, %0"
10755   [(set_attr "type" "fmove_media")])
10757 (define_insn "negdf2_i"
10758   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10759         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10760    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10761   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10762   "fneg %0"
10763   [(set_attr "type" "fmove")
10764    (set_attr "fp_mode" "double")])
10766 (define_expand "sqrtdf2"
10767   [(set (match_operand:DF 0 "arith_reg_operand" "")
10768         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10769   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10770   "
10772   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10773     {
10774       expand_df_unop (&gen_sqrtdf2_i, operands);
10775       DONE;
10776     }
10779 (define_insn "*sqrtdf2_media"
10780   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10781         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10782   "TARGET_SHMEDIA_FPU"
10783   "fsqrt.d      %1, %0"
10784   [(set_attr "type" "dfdiv_media")])
10786 (define_insn "sqrtdf2_i"
10787   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10788         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10789    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10790   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10791   "fsqrt        %0"
10792   [(set_attr "type" "dfdiv")
10793    (set_attr "fp_mode" "double")])
10795 (define_expand "absdf2"
10796   [(set (match_operand:DF 0 "arith_reg_operand" "")
10797         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10798   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10799   "
10801   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10802     {
10803       expand_df_unop (&gen_absdf2_i, operands);
10804       DONE;
10805     }
10808 (define_insn "*absdf2_media"
10809   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10810         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10811   "TARGET_SHMEDIA_FPU"
10812   "fabs.d       %1, %0"
10813   [(set_attr "type" "fmove_media")])
10815 (define_insn "absdf2_i"
10816   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10817         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10818    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10819   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10820   "fabs %0"
10821   [(set_attr "type" "fmove")
10822    (set_attr "fp_mode" "double")])
10824 (define_expand "extendsfdf2"
10825   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10826         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10827   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10828   "
10830   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10831     {
10832       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10833                                         get_fpscr_rtx ()));
10834       DONE;
10835     }
10838 (define_insn "*extendsfdf2_media"
10839   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10840         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10841   "TARGET_SHMEDIA_FPU"
10842   "fcnv.sd      %1, %0"
10843   [(set_attr "type" "dfpconv_media")])
10845 (define_insn "extendsfdf2_i4"
10846   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10847         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10848    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10849   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10850   "fcnvsd  %1,%0"
10851   [(set_attr "type" "fp")
10852    (set_attr "fp_mode" "double")])
10854 (define_expand "truncdfsf2"
10855   [(set (match_operand:SF 0 "fpul_operand" "")
10856         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10857   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10858   "
10860   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10861     {
10862       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10863                                        get_fpscr_rtx ()));
10864       DONE;
10865     }
10868 (define_insn "*truncdfsf2_media"
10869   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10870         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10871   "TARGET_SHMEDIA_FPU"
10872   "fcnv.ds      %1, %0"
10873   [(set_attr "type" "dfpconv_media")])
10875 (define_insn "truncdfsf2_i4"
10876   [(set (match_operand:SF 0 "fpul_operand" "=y")
10877         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10878    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10879   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10880   "fcnvds  %1,%0"
10881   [(set_attr "type" "fp")
10882    (set_attr "fp_mode" "double")])
10884 ;; Bit field extract patterns.  These give better code for packed bitfields,
10885 ;; because they allow auto-increment addresses to be generated.
10887 (define_expand "insv"
10888   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10889                          (match_operand:SI 1 "immediate_operand" "")
10890                          (match_operand:SI 2 "immediate_operand" ""))
10891         (match_operand:SI 3 "general_operand" ""))]
10892   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10893   "
10895   rtx addr_target, orig_address, shift_reg, qi_val;
10896   HOST_WIDE_INT bitsize, size, v = 0;
10897   rtx x = operands[3];
10899   if (TARGET_SH2A && TARGET_BITOPS
10900       && (satisfies_constraint_Sbw (operands[0])
10901           || satisfies_constraint_Sbv (operands[0]))
10902       && satisfies_constraint_M (operands[1])
10903       && satisfies_constraint_K03 (operands[2]))
10904     {
10905       if (satisfies_constraint_N (operands[3]))
10906         {
10907           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10908           DONE;
10909         }
10910       else if (satisfies_constraint_M (operands[3]))
10911         {
10912           emit_insn (gen_bset_m2a (operands[0], operands[2]));
10913           DONE;
10914         }
10915       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10916                 && satisfies_constraint_M (operands[1]))
10917         {
10918           emit_insn (gen_bst_m2a (operands[0], operands[2]));
10919           DONE;
10920         }
10921       else if (REG_P (operands[3])
10922                && satisfies_constraint_M (operands[1]))
10923         {
10924           emit_insn (gen_bld_reg (operands[3], const0_rtx));
10925           emit_insn (gen_bst_m2a (operands[0], operands[2]));
10926           DONE;
10927         }
10928     }
10929   /* ??? expmed doesn't care for non-register predicates.  */
10930   if (! memory_operand (operands[0], VOIDmode)
10931       || ! immediate_operand (operands[1], VOIDmode)
10932       || ! immediate_operand (operands[2], VOIDmode)
10933       || ! general_operand (x, VOIDmode))
10934     FAIL;
10935   /* If this isn't a 16 / 24 / 32 bit field, or if
10936      it doesn't start on a byte boundary, then fail.  */
10937   bitsize = INTVAL (operands[1]);
10938   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10939       || (INTVAL (operands[2]) % 8) != 0)
10940     FAIL;
10942   size = bitsize / 8;
10943   orig_address = XEXP (operands[0], 0);
10944   shift_reg = gen_reg_rtx (SImode);
10945   if (CONST_INT_P (x))
10946     {
10947       v = INTVAL (x);
10948       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10949     }
10950   else
10951     {
10952       emit_insn (gen_movsi (shift_reg, operands[3]));
10953       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10954     }
10955   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10957   operands[0] = replace_equiv_address (operands[0], addr_target);
10958   emit_insn (gen_movqi (operands[0], qi_val));
10960   while (size -= 1)
10961     {
10962       if (CONST_INT_P (x))
10963         qi_val
10964           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
10965       else
10966         {
10967           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
10968           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10969         }
10970       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
10971       emit_insn (gen_movqi (operands[0], qi_val));
10972     }
10974   DONE;
10977 (define_insn "movua"
10978   [(set (match_operand:SI 0 "register_operand" "=z")
10979         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
10980                    UNSPEC_MOVUA))]
10981   "TARGET_SH4A_ARCH"
10982   "movua.l      %1,%0"
10983   [(set_attr "type" "movua")])
10985 ;; We shouldn't need this, but cse replaces increments with references
10986 ;; to other regs before flow has a chance to create post_inc
10987 ;; addressing modes, and only postreload's cse_move2add brings the
10988 ;; increments back to a usable form.
10989 (define_peephole2
10990   [(set (match_operand:SI 0 "register_operand" "")
10991         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
10992                          (const_int 32) (const_int 0)))
10993    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
10994   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
10995   [(set (match_operand:SI 0 "register_operand" "")
10996         (sign_extract:SI (mem:SI (post_inc:SI
10997                                   (match_operand:SI 1 "register_operand" "")))
10998                          (const_int 32) (const_int 0)))]
10999   "")
11001 (define_expand "extv"
11002   [(set (match_operand:SI 0 "register_operand" "")
11003         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11004                          (match_operand 2 "const_int_operand" "")
11005                          (match_operand 3 "const_int_operand" "")))]
11006   "TARGET_SH4A_ARCH || TARGET_SH2A"
11008   if (TARGET_SH2A && TARGET_BITOPS
11009       && (satisfies_constraint_Sbw (operands[1])
11010           || satisfies_constraint_Sbv (operands[1]))
11011       && satisfies_constraint_M (operands[2])
11012       && satisfies_constraint_K03 (operands[3]))
11013    {
11014       emit_insn (gen_bldsign_m2a (operands[1], operands[3]));
11015       if (REGNO (operands[0]) != T_REG)
11016         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11017       DONE;
11018    }
11019   if (TARGET_SH4A_ARCH
11020       && INTVAL (operands[2]) == 32
11021       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11022       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11023     {
11024       rtx src = adjust_address (operands[1], BLKmode, 0);
11025       set_mem_size (src, GEN_INT (4));
11026       emit_insn (gen_movua (operands[0], src));
11027       DONE;
11028     }
11030   FAIL;
11033 (define_expand "extzv"
11034   [(set (match_operand:SI 0 "register_operand" "")
11035         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11036                          (match_operand 2 "const_int_operand" "")
11037                          (match_operand 3 "const_int_operand" "")))]
11038   "TARGET_SH4A_ARCH || TARGET_SH2A"
11040   if (TARGET_SH2A && TARGET_BITOPS
11041       && (satisfies_constraint_Sbw (operands[1])
11042           || satisfies_constraint_Sbv (operands[1]))
11043       && satisfies_constraint_M (operands[2])
11044       && satisfies_constraint_K03 (operands[3]))
11045     {
11046       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11047       if (REGNO (operands[0]) != T_REG)
11048         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11049       DONE;
11050     }
11051   if (TARGET_SH4A_ARCH
11052       && INTVAL (operands[2]) == 32
11053       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11054       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11055     {
11056       rtx src = adjust_address (operands[1], BLKmode, 0);
11057       set_mem_size (src, GEN_INT (4));
11058       emit_insn (gen_movua (operands[0], src));
11059       DONE;
11060     }
11062   FAIL;
11065 ;; SH2A instructions for bitwise operations.
11067 ;; Clear a bit in a memory location.
11068 (define_insn "bclr_m2a"
11069   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11070         (and:QI
11071             (not:QI (ashift:QI (const_int 1)
11072                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11073             (match_dup 0)))]
11074   "TARGET_SH2A && TARGET_BITOPS"
11075   "@
11076         bclr.b\\t%1,%0
11077         bclr.b\\t%1,@(0,%t0)"
11078 [(set_attr "length" "4,4")])
11080 (define_insn "bclrmem_m2a"
11081   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11082         (and:QI (match_dup 0)
11083                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11084   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11085   "@
11086         bclr.b\\t%W1,%0
11087         bclr.b\\t%W1,@(0,%t0)"
11088   [(set_attr "length" "4,4")])
11090 ;; Set a bit in a memory location.
11091 (define_insn "bset_m2a"
11092   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11093         (ior:QI
11094             (ashift:QI (const_int 1)
11095                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11096             (match_dup 0)))]
11097   "TARGET_SH2A && TARGET_BITOPS"
11098   "@
11099         bset.b\\t%1,%0
11100         bset.b\\t%1,@(0,%t0)"
11101   [(set_attr "length" "4,4")])
11103 (define_insn "bsetmem_m2a"
11104   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11105         (ior:QI (match_dup 0)
11106                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11107   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11108   "@
11109         bset.b\\t%V1,%0
11110         bset.b\\t%V1,@(0,%t0)"
11111   [(set_attr "length" "4,4")])
11113 ;;; Transfer the contents of the T bit to a specified bit of memory.
11114 (define_insn "bst_m2a"
11115   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11116         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11117             (and:QI
11118                 (not:QI (ashift:QI (const_int 1)
11119                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11120                 (match_dup 0))
11121             (ior:QI
11122                 (ashift:QI (const_int 1) (match_dup 1))
11123                 (match_dup 0))))]
11124   "TARGET_SH2A && TARGET_BITOPS"
11125   "@
11126         bst.b\\t%1,%0
11127         bst.b\\t%1,@(0,%t0)"
11128   [(set_attr "length" "4")])
11130 ;; Store a specified bit of memory in the T bit.
11131 (define_insn "bld_m2a"
11132   [(set (reg:SI T_REG)
11133         (zero_extract:SI
11134             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11135             (const_int 1)
11136             (match_operand 1 "const_int_operand" "K03,K03")))]
11137   "TARGET_SH2A && TARGET_BITOPS"
11138   "@
11139         bld.b\\t%1,%0
11140         bld.b\\t%1,@(0,%t0)"
11141   [(set_attr "length" "4,4")])
11143 ;; Store a specified bit of memory in the T bit.
11144 (define_insn "bldsign_m2a"
11145   [(set (reg:SI T_REG)
11146         (sign_extract:SI
11147             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11148             (const_int 1)
11149             (match_operand 1 "const_int_operand" "K03,K03")))]
11150   "TARGET_SH2A && TARGET_BITOPS"
11151   "@
11152         bld.b\\t%1,%0
11153         bld.b\\t%1,@(0,%t0)"
11154   [(set_attr "length" "4,4")])
11156 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11157 (define_insn "bld_reg"
11158   [(set (reg:SI T_REG)
11159         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11160                          (const_int 1)
11161                          (match_operand 1 "const_int_operand" "K03")))]
11162   "TARGET_SH2A"
11163   "bld\\t%1,%0")
11165 (define_insn "*bld_regqi"
11166   [(set (reg:SI T_REG)
11167         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11168                          (const_int 1)
11169                          (match_operand 1 "const_int_operand" "K03")))]
11170   "TARGET_SH2A"
11171   "bld\\t%1,%0")
11173 ;; Take logical and of a specified bit of memory with the T bit and
11174 ;; store its result in the T bit.
11175 (define_insn "band_m2a"
11176   [(set (reg:SI T_REG)
11177         (and:SI (reg:SI T_REG)
11178                 (zero_extract:SI
11179                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11180                     (const_int 1)
11181                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11182   "TARGET_SH2A && TARGET_BITOPS"
11183   "@
11184         band.b\\t%1,%0
11185         band.b\\t%1,@(0,%t0)"
11186   [(set_attr "length" "4,4")])
11188 (define_insn "bandreg_m2a"
11189   [(set (match_operand:SI 0 "register_operand" "=r,r")
11190         (and:SI (zero_extract:SI
11191                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11192                     (const_int 1)
11193                     (match_operand 2 "const_int_operand" "K03,K03"))
11194                 (match_operand:SI 3 "register_operand" "r,r")))]
11195   "TARGET_SH2A && TARGET_BITOPS"
11196   "@
11197         band.b\\t%2,%1\;movt\\t%0
11198         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11199   [(set_attr "length" "6,6")])
11201 ;; Take logical or of a specified bit of memory with the T bit and
11202 ;; store its result in the T bit.
11203 (define_insn "bor_m2a"
11204   [(set (reg:SI T_REG)
11205         (ior:SI (reg:SI T_REG)
11206                 (zero_extract:SI
11207                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11208                     (const_int 1)
11209                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11210   "TARGET_SH2A && TARGET_BITOPS"
11211   "@
11212         bor.b\\t%1,%0
11213         bor.b\\t%1,@(0,%t0)"
11214   [(set_attr "length" "4,4")])
11216 (define_insn "borreg_m2a"
11217   [(set (match_operand:SI 0 "register_operand" "=r,r")
11218         (ior:SI (zero_extract:SI
11219                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11220                     (const_int 1)
11221                     (match_operand 2 "const_int_operand" "K03,K03"))
11222                 (match_operand:SI 3 "register_operand" "=r,r")))]
11223   "TARGET_SH2A && TARGET_BITOPS"
11224   "@
11225         bor.b\\t%2,%1\;movt\\t%0
11226         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11227   [(set_attr "length" "6,6")])
11229 ;; Take exclusive or of a specified bit of memory with the T bit and
11230 ;; store its result in the T bit.
11231 (define_insn "bxor_m2a"
11232   [(set (reg:SI T_REG)
11233         (xor:SI (reg:SI T_REG)
11234                 (zero_extract:SI
11235                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11236                     (const_int 1)
11237                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11238   "TARGET_SH2A && TARGET_BITOPS"
11239   "@
11240         bxor.b\\t%1,%0
11241         bxor.b\\t%1,@(0,%t0)"
11242   [(set_attr "length" "4,4")])
11244 (define_insn "bxorreg_m2a"
11245   [(set (match_operand:SI 0 "register_operand" "=r,r")
11246         (xor:SI (zero_extract:SI
11247                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11248                     (const_int 1)
11249                     (match_operand 2 "const_int_operand" "K03,K03"))
11250                 (match_operand:SI 3 "register_operand" "=r,r")))]
11251   "TARGET_SH2A && TARGET_BITOPS"
11252   "@
11253         bxor.b\\t%2,%1\;movt\\t%0
11254         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11255   [(set_attr "length" "6,6")])
11258 ;; -------------------------------------------------------------------------
11259 ;; Peepholes
11260 ;; -------------------------------------------------------------------------
11261 ;; This matches cases where the bit in a memory location is set.
11262 (define_peephole2
11263   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11264         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11265    (set (match_dup 0)
11266         (ior:SI (match_dup 0)
11267         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11268    (set (match_dup 1)
11269         (match_operand 3 "arith_reg_operand" "r,r"))]
11270   "TARGET_SH2A && TARGET_BITOPS
11271    && satisfies_constraint_Pso (operands[2])
11272    && REGNO (operands[0]) == REGNO (operands[3])"
11273   [(set (match_dup 1)
11274         (ior:QI (match_dup 1)
11275                 (match_dup 2)))]
11276   "")
11278 ;; This matches cases where the bit in a memory location is cleared.
11279 (define_peephole2
11280   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11281         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11282    (set (match_dup 0)
11283         (and:SI (match_dup 0)
11284         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11285    (set (match_dup 1)
11286         (match_operand 3 "arith_reg_operand" "r,r"))]
11287   "TARGET_SH2A && TARGET_BITOPS
11288    && satisfies_constraint_Psz (operands[2])
11289    && REGNO (operands[0]) == REGNO (operands[3])"
11290   [(set (match_dup 1)
11291         (and:QI (match_dup 1)
11292                 (match_dup 2)))]
11293   "")
11295 ;; This matches cases where a stack pointer increment at the start of the
11296 ;; epilogue combines with a stack slot read loading the return value.
11298 (define_peephole
11299   [(set (match_operand:SI 0 "arith_reg_operand" "")
11300         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11301    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11302   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11303   "mov.l        @%1+,%0")
11305 ;; See the comment on the dt combiner pattern above.
11307 (define_peephole
11308   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11309         (plus:SI (match_dup 0)
11310                  (const_int -1)))
11311    (set (reg:SI T_REG)
11312         (eq:SI (match_dup 0)
11313                (const_int 0)))]
11314   "TARGET_SH2"
11315   "dt   %0")
11317 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11318 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11319 ;; reload when the constant is too large for a reg+offset address.
11321 ;; ??? We would get much better code if this was done in reload.  This would
11322 ;; require modifying find_reloads_address to recognize that if the constant
11323 ;; is out-of-range for an immediate add, then we get better code by reloading
11324 ;; the constant into a register than by reloading the sum into a register,
11325 ;; since the former is one instruction shorter if the address does not need
11326 ;; to be offsettable.  Unfortunately this does not work, because there is
11327 ;; only one register, r0, that can be used as an index register.  This register
11328 ;; is also the function return value register.  So, if we try to force reload
11329 ;; to use double-reg addresses, then we end up with some instructions that
11330 ;; need to use r0 twice.  The only way to fix this is to change the calling
11331 ;; convention so that r0 is not used to return values.
11333 (define_peephole
11334   [(set (match_operand:SI 0 "register_operand" "=r")
11335         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11336    (set (mem:SI (match_dup 0))
11337         (match_operand:SI 2 "general_movsrc_operand" ""))]
11338   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11339   "mov.l        %2,@(%0,%1)")
11341 (define_peephole
11342   [(set (match_operand:SI 0 "register_operand" "=r")
11343         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11344    (set (match_operand:SI 2 "general_movdst_operand" "")
11345         (mem:SI (match_dup 0)))]
11346   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11347   "mov.l        @(%0,%1),%2")
11349 (define_peephole
11350   [(set (match_operand:SI 0 "register_operand" "=r")
11351         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11352    (set (mem:HI (match_dup 0))
11353         (match_operand:HI 2 "general_movsrc_operand" ""))]
11354   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11355   "mov.w        %2,@(%0,%1)")
11357 (define_peephole
11358   [(set (match_operand:SI 0 "register_operand" "=r")
11359         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11360    (set (match_operand:HI 2 "general_movdst_operand" "")
11361         (mem:HI (match_dup 0)))]
11362   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11363   "mov.w        @(%0,%1),%2")
11365 (define_peephole
11366   [(set (match_operand:SI 0 "register_operand" "=r")
11367         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11368    (set (mem:QI (match_dup 0))
11369         (match_operand:QI 2 "general_movsrc_operand" ""))]
11370   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11371   "mov.b        %2,@(%0,%1)")
11373 (define_peephole
11374   [(set (match_operand:SI 0 "register_operand" "=r")
11375         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11376    (set (match_operand:QI 2 "general_movdst_operand" "")
11377         (mem:QI (match_dup 0)))]
11378   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11379   "mov.b        @(%0,%1),%2")
11381 (define_peephole
11382   [(set (match_operand:SI 0 "register_operand" "=r")
11383         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11384    (set (mem:SF (match_dup 0))
11385         (match_operand:SF 2 "general_movsrc_operand" ""))]
11386   "TARGET_SH1 && REGNO (operands[0]) == 0
11387    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11388        || (GET_CODE (operands[2]) == SUBREG
11389            && REGNO (SUBREG_REG (operands[2])) < 16))
11390    && reg_unused_after (operands[0], insn)"
11391   "mov.l        %2,@(%0,%1)")
11393 (define_peephole
11394   [(set (match_operand:SI 0 "register_operand" "=r")
11395         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11396    (set (match_operand:SF 2 "general_movdst_operand" "")
11398         (mem:SF (match_dup 0)))]
11399   "TARGET_SH1 && REGNO (operands[0]) == 0
11400    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11401        || (GET_CODE (operands[2]) == SUBREG
11402            && REGNO (SUBREG_REG (operands[2])) < 16))
11403    && reg_unused_after (operands[0], insn)"
11404   "mov.l        @(%0,%1),%2")
11406 (define_peephole
11407   [(set (match_operand:SI 0 "register_operand" "=r")
11408         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11409    (set (mem:SF (match_dup 0))
11410         (match_operand:SF 2 "general_movsrc_operand" ""))]
11411   "TARGET_SH2E && REGNO (operands[0]) == 0
11412    && ((REG_P (operands[2])
11413         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11414        || (GET_CODE (operands[2]) == SUBREG
11415            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11416    && reg_unused_after (operands[0], insn)"
11417   "fmov{.s|}    %2,@(%0,%1)")
11419 (define_peephole
11420   [(set (match_operand:SI 0 "register_operand" "=r")
11421         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11422    (set (match_operand:SF 2 "general_movdst_operand" "")
11424         (mem:SF (match_dup 0)))]
11425   "TARGET_SH2E && REGNO (operands[0]) == 0
11426    && ((REG_P (operands[2])
11427         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11428        || (GET_CODE (operands[2]) == SUBREG
11429            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11430    && reg_unused_after (operands[0], insn)"
11431   "fmov{.s|}    @(%0,%1),%2")
11433 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11434 (define_insn "sp_switch_1"
11435   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11436   "TARGET_SH1"
11437   "*
11439   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11440   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11441   return \"mov r0,r15\";
11443   [(set_attr "length" "10")])
11445 ;; Switch back to the original stack for interrupt functions with the
11446 ;; sp_switch attribute.  */
11447 (define_insn "sp_switch_2"
11448   [(const_int 2)]
11449   "TARGET_SH1"
11450   "mov.l @r15+,r15\;mov.l @r15+,r0"
11451   [(set_attr "length" "4")])
11453 ;; Integer vector moves
11455 (define_expand "movv8qi"
11456   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11457         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11458   "TARGET_SHMEDIA"
11459   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11461 (define_insn "movv8qi_i"
11462   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11463         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11464   "TARGET_SHMEDIA
11465    && (register_operand (operands[0], V8QImode)
11466        || sh_register_operand (operands[1], V8QImode))"
11467   "@
11468         add     %1, r63, %0
11469         movi    %1, %0
11470         #
11471         ld%M1.q %m1, %0
11472         st%M0.q %m0, %N1"
11473   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11474    (set_attr "length" "4,4,16,4,4")])
11476 (define_split
11477   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11478         (subreg:V8QI (const_int 0) 0))]
11479   "TARGET_SHMEDIA"
11480   [(set (match_dup 0)
11481         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11482                             (const_int 0) (const_int 0) (const_int 0)
11483                             (const_int 0) (const_int 0)]))])
11485 (define_split
11486   [(set (match_operand 0 "arith_reg_dest" "")
11487         (match_operand 1 "sh_rep_vec" ""))]
11488   "TARGET_SHMEDIA && reload_completed
11489    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11490    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11491    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11492    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11493        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11494    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11495        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11496   [(set (match_dup 0) (match_dup 1))
11497    (match_dup 2)]
11498   "
11500   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11501   rtx elt1 = XVECEXP (operands[1], 0, 1);
11503   if (unit_size > 2)
11504     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11505   else
11506     {
11507       if (unit_size < 2)
11508         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11509       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11510     }
11511   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11512   operands[1] = XVECEXP (operands[1], 0, 0);
11513   if (unit_size < 2)
11514     {
11515       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11516         operands[1]
11517           = GEN_INT (TARGET_LITTLE_ENDIAN
11518                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11519                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11520       else
11521         {
11522           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11523           operands[1]
11524             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11525         }
11526     }
11529 (define_split
11530   [(set (match_operand 0 "arith_reg_dest" "")
11531         (match_operand 1 "sh_const_vec" ""))]
11532   "TARGET_SHMEDIA && reload_completed
11533    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11534    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11535   [(set (match_dup 0) (match_dup 1))]
11536   "
11538   rtx v = operands[1];
11539   enum machine_mode new_mode
11540     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11542   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11543   operands[1]
11544     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11547 (define_expand "movv2hi"
11548   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11549         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11550   "TARGET_SHMEDIA"
11551   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11553 (define_insn "movv2hi_i"
11554   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11555         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11556   "TARGET_SHMEDIA
11557    && (register_operand (operands[0], V2HImode)
11558        || sh_register_operand (operands[1], V2HImode))"
11559   "@
11560         add.l   %1, r63, %0
11561         movi    %1, %0
11562         #
11563         ld%M1.l %m1, %0
11564         st%M0.l %m0, %N1"
11565   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11566    (set_attr "length" "4,4,16,4,4")
11567    (set (attr "highpart")
11568         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11569                (const_string "user")]
11570               (const_string "ignore")))])
11572 (define_expand "movv4hi"
11573   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11574         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11575   "TARGET_SHMEDIA"
11576   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11578 (define_insn "movv4hi_i"
11579   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11580         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11581   "TARGET_SHMEDIA
11582    && (register_operand (operands[0], V4HImode)
11583        || sh_register_operand (operands[1], V4HImode))"
11584   "@
11585         add     %1, r63, %0
11586         movi    %1, %0
11587         #
11588         ld%M1.q %m1, %0
11589         st%M0.q %m0, %N1"
11590   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11591    (set_attr "length" "4,4,16,4,4")
11592    (set_attr "highpart" "depend")])
11594 (define_expand "movv2si"
11595   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11596         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11597   "TARGET_SHMEDIA"
11598   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11600 (define_insn "movv2si_i"
11601   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11602         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11603   "TARGET_SHMEDIA
11604    && (register_operand (operands[0], V2SImode)
11605        || sh_register_operand (operands[1], V2SImode))"
11606   "@
11607         add     %1, r63, %0
11608         #
11609         #
11610         ld%M1.q %m1, %0
11611         st%M0.q %m0, %N1"
11612   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11613    (set_attr "length" "4,4,16,4,4")
11614    (set_attr "highpart" "depend")])
11616 ;; Multimedia Intrinsics
11618 (define_insn "absv2si2"
11619   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11620         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11621   "TARGET_SHMEDIA"
11622   "mabs.l       %1, %0"
11623   [(set_attr "type" "mcmp_media")
11624    (set_attr "highpart" "depend")])
11626 (define_insn "absv4hi2"
11627   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11628         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11629   "TARGET_SHMEDIA"
11630   "mabs.w       %1, %0"
11631   [(set_attr "type" "mcmp_media")
11632    (set_attr "highpart" "depend")])
11634 (define_insn "addv2si3"
11635   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11636         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11637                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11638   "TARGET_SHMEDIA"
11639   "madd.l       %1, %2, %0"
11640   [(set_attr "type" "arith_media")
11641    (set_attr "highpart" "depend")])
11643 (define_insn "addv4hi3"
11644   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11645         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11646                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11647   "TARGET_SHMEDIA"
11648   "madd.w       %1, %2, %0"
11649   [(set_attr "type" "arith_media")
11650    (set_attr "highpart" "depend")])
11652 (define_insn_and_split "addv2hi3"
11653   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11654         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11655                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11656   "TARGET_SHMEDIA"
11657   "#"
11658   "TARGET_SHMEDIA"
11659   [(const_int 0)]
11660   "
11662   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11663   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11664   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11665   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11666   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11668   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11669   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11670   DONE;
11672   [(set_attr "highpart" "must_split")])
11674 (define_insn "ssaddv2si3"
11675   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11676         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11677                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11678   "TARGET_SHMEDIA"
11679   "madds.l      %1, %2, %0"
11680   [(set_attr "type" "mcmp_media")
11681    (set_attr "highpart" "depend")])
11683 (define_insn "usaddv8qi3"
11684   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11685         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11686                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11687   "TARGET_SHMEDIA"
11688   "madds.ub     %1, %2, %0"
11689   [(set_attr "type" "mcmp_media")
11690    (set_attr "highpart" "depend")])
11692 (define_insn "ssaddv4hi3"
11693   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11694         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11695                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11696   "TARGET_SHMEDIA"
11697   "madds.w      %1, %2, %0"
11698   [(set_attr "type" "mcmp_media")
11699    (set_attr "highpart" "depend")])
11701 (define_insn "negcmpeqv8qi"
11702   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11703         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11704                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11705   "TARGET_SHMEDIA"
11706   "mcmpeq.b     %N1, %N2, %0"
11707   [(set_attr "type" "mcmp_media")
11708    (set_attr "highpart" "depend")])
11710 (define_insn "negcmpeqv2si"
11711   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11712         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11713                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11714   "TARGET_SHMEDIA"
11715   "mcmpeq.l     %N1, %N2, %0"
11716   [(set_attr "type" "mcmp_media")
11717    (set_attr "highpart" "depend")])
11719 (define_insn "negcmpeqv4hi"
11720   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11721         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11722                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11723   "TARGET_SHMEDIA"
11724   "mcmpeq.w     %N1, %N2, %0"
11725   [(set_attr "type" "mcmp_media")
11726    (set_attr "highpart" "depend")])
11728 (define_insn "negcmpgtuv8qi"
11729   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11730         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11731                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11732   "TARGET_SHMEDIA"
11733   "mcmpgt.ub    %N1, %N2, %0"
11734   [(set_attr "type" "mcmp_media")
11735    (set_attr "highpart" "depend")])
11737 (define_insn "negcmpgtv2si"
11738   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11739         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11740                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11741   "TARGET_SHMEDIA"
11742   "mcmpgt.l     %N1, %N2, %0"
11743   [(set_attr "type" "mcmp_media")
11744    (set_attr "highpart" "depend")])
11746 (define_insn "negcmpgtv4hi"
11747   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11748         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11749                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11750   "TARGET_SHMEDIA"
11751   "mcmpgt.w     %N1, %N2, %0"
11752   [(set_attr "type" "mcmp_media")
11753    (set_attr "highpart" "depend")])
11755 (define_insn "mcmv"
11756   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11757         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11758                         (match_operand:DI 2 "arith_reg_operand" "r"))
11759                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11760                         (not:DI (match_dup 2)))))]
11761   "TARGET_SHMEDIA"
11762   "mcmv %N1, %2, %0"
11763   [(set_attr "type" "arith_media")
11764    (set_attr "highpart" "depend")])
11766 (define_insn "mcnvs_lw"
11767   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11768         (vec_concat:V4HI
11769          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11770          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11771   "TARGET_SHMEDIA"
11772   "mcnvs.lw     %N1, %N2, %0"
11773   [(set_attr "type" "mcmp_media")])
11775 (define_insn "mcnvs_wb"
11776   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11777         (vec_concat:V8QI
11778          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11779          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11780   "TARGET_SHMEDIA"
11781   "mcnvs.wb     %N1, %N2, %0"
11782   [(set_attr "type" "mcmp_media")])
11784 (define_insn "mcnvs_wub"
11785   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11786         (vec_concat:V8QI
11787          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11788          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11789   "TARGET_SHMEDIA"
11790   "mcnvs.wub    %N1, %N2, %0"
11791   [(set_attr "type" "mcmp_media")])
11793 (define_insn "mextr_rl"
11794   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11795         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11796                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11797                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11798                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11799   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11800   "*
11802   static char templ[21];
11804   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11805            (int) INTVAL (operands[3]) >> 3);
11806   return templ;
11808   [(set_attr "type" "arith_media")])
11810 (define_insn "*mextr_lr"
11811   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11812         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11813                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11814                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11815                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11816   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11817   "*
11819   static char templ[21];
11821   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11822            (int) INTVAL (operands[4]) >> 3);
11823   return templ;
11825   [(set_attr "type" "arith_media")])
11827 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11828 ; vector then varies depending on endianness.
11829 (define_expand "mextr1"
11830   [(match_operand:DI 0 "arith_reg_dest" "")
11831    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11832    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11833   "TARGET_SHMEDIA"
11834   "
11836   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11837                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11838   DONE;
11841 (define_expand "mextr2"
11842   [(match_operand:DI 0 "arith_reg_dest" "")
11843    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11844    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11845   "TARGET_SHMEDIA"
11846   "
11848   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11849                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11850   DONE;
11853 (define_expand "mextr3"
11854   [(match_operand:DI 0 "arith_reg_dest" "")
11855    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11856    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11857   "TARGET_SHMEDIA"
11858   "
11860   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11861                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11862   DONE;
11865 (define_expand "mextr4"
11866   [(match_operand:DI 0 "arith_reg_dest" "")
11867    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11868    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11869   "TARGET_SHMEDIA"
11870   "
11872   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11873                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11874   DONE;
11877 (define_expand "mextr5"
11878   [(match_operand:DI 0 "arith_reg_dest" "")
11879    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11880    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11881   "TARGET_SHMEDIA"
11882   "
11884   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11885                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11886   DONE;
11889 (define_expand "mextr6"
11890   [(match_operand:DI 0 "arith_reg_dest" "")
11891    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11892    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11893   "TARGET_SHMEDIA"
11894   "
11896   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11897                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11898   DONE;
11901 (define_expand "mextr7"
11902   [(match_operand:DI 0 "arith_reg_dest" "")
11903    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11904    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11905   "TARGET_SHMEDIA"
11906   "
11908   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11909                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11910   DONE;
11913 (define_expand "mmacfx_wl"
11914   [(match_operand:V2SI 0 "arith_reg_dest" "")
11915    (match_operand:V2HI 1 "extend_reg_operand" "")
11916    (match_operand:V2HI 2 "extend_reg_operand" "")
11917    (match_operand:V2SI 3 "arith_reg_operand" "")]
11918   "TARGET_SHMEDIA"
11919   "
11921   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11922                               operands[1], operands[2]));
11923   DONE;
11926 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11927 ;; is depend
11928 (define_insn "mmacfx_wl_i"
11929   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11930         (ss_plus:V2SI
11931          (match_operand:V2SI 1 "arith_reg_operand" "0")
11932          (ss_truncate:V2SI
11933           (ashift:V2DI
11934            (sign_extend:V2DI
11935             (mult:V2SI
11936              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11937              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11938            (const_int 1)))))]
11939   "TARGET_SHMEDIA"
11940   "mmacfx.wl    %2, %3, %0"
11941   [(set_attr "type" "mac_media")
11942    (set_attr "highpart" "depend")])
11944 (define_expand "mmacnfx_wl"
11945   [(match_operand:V2SI 0 "arith_reg_dest" "")
11946    (match_operand:V2HI 1 "extend_reg_operand" "")
11947    (match_operand:V2HI 2 "extend_reg_operand" "")
11948    (match_operand:V2SI 3 "arith_reg_operand" "")]
11949   "TARGET_SHMEDIA"
11950   "
11952   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11953                                operands[1], operands[2]));
11954   DONE;
11957 (define_insn "mmacnfx_wl_i"
11958   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11959         (ss_minus:V2SI
11960          (match_operand:V2SI 1 "arith_reg_operand" "0")
11961          (ss_truncate:V2SI
11962           (ashift:V2DI
11963            (sign_extend:V2DI
11964             (mult:V2SI
11965              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11966              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11967            (const_int 1)))))]
11968   "TARGET_SHMEDIA"
11969   "mmacnfx.wl   %2, %3, %0"
11970   [(set_attr "type" "mac_media")
11971    (set_attr "highpart" "depend")])
11973 (define_insn "mulv2si3"
11974   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11975         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11976                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11977   "TARGET_SHMEDIA"
11978   "mmul.l       %1, %2, %0"
11979   [(set_attr "type" "d2mpy_media")
11980    (set_attr "highpart" "depend")])
11982 (define_insn "mulv4hi3"
11983   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11984         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11985                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11986   "TARGET_SHMEDIA"
11987   "mmul.w       %1, %2, %0"
11988   [(set_attr "type" "dmpy_media")
11989    (set_attr "highpart" "depend")])
11991 (define_insn "mmulfx_l"
11992   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11993         (ss_truncate:V2SI
11994          (ashiftrt:V2DI
11995           (mult:V2DI
11996            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11997            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11998           (const_int 31))))]
11999   "TARGET_SHMEDIA"
12000   "mmulfx.l     %1, %2, %0"
12001   [(set_attr "type" "d2mpy_media")
12002    (set_attr "highpart" "depend")])
12004 (define_insn "mmulfx_w"
12005   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12006         (ss_truncate:V4HI
12007          (ashiftrt:V4SI
12008           (mult:V4SI
12009            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12010            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12011           (const_int 15))))]
12012   "TARGET_SHMEDIA"
12013   "mmulfx.w     %1, %2, %0"
12014   [(set_attr "type" "dmpy_media")
12015    (set_attr "highpart" "depend")])
12017 (define_insn "mmulfxrp_w"
12018   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12019         (ss_truncate:V4HI
12020          (ashiftrt:V4SI
12021           (plus:V4SI
12022            (mult:V4SI
12023             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12024             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12025            (const_int 16384))
12026           (const_int 15))))]
12027   "TARGET_SHMEDIA"
12028   "mmulfxrp.w   %1, %2, %0"
12029   [(set_attr "type" "dmpy_media")
12030    (set_attr "highpart" "depend")])
12033 (define_expand "mmulhi_wl"
12034   [(match_operand:V2SI 0 "arith_reg_dest" "")
12035    (match_operand:V4HI 1 "arith_reg_operand" "")
12036    (match_operand:V4HI 2 "arith_reg_operand" "")]
12037   "TARGET_SHMEDIA"
12038   "
12040   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12041              (operands[0], operands[1], operands[2]));
12042   DONE;
12045 (define_expand "mmullo_wl"
12046   [(match_operand:V2SI 0 "arith_reg_dest" "")
12047    (match_operand:V4HI 1 "arith_reg_operand" "")
12048    (match_operand:V4HI 2 "arith_reg_operand" "")]
12049   "TARGET_SHMEDIA"
12050   "
12052   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12053              (operands[0], operands[1], operands[2]));
12054   DONE;
12057 (define_insn "mmul23_wl"
12058   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12059         (vec_select:V2SI
12060          (mult:V4SI
12061           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12062           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12063          (parallel [(const_int 2) (const_int 3)])))]
12064   "TARGET_SHMEDIA"
12065   "* return (TARGET_LITTLE_ENDIAN
12066              ? \"mmulhi.wl      %1, %2, %0\"
12067              : \"mmullo.wl      %1, %2, %0\");"
12068   [(set_attr "type" "dmpy_media")
12069    (set (attr "highpart")
12070         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12071          (const_string "user")))])
12073 (define_insn "mmul01_wl"
12074   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12075         (vec_select:V2SI
12076          (mult:V4SI
12077           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12078           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12079          (parallel [(const_int 0) (const_int 1)])))]
12080   "TARGET_SHMEDIA"
12081   "* return (TARGET_LITTLE_ENDIAN
12082              ? \"mmullo.wl      %1, %2, %0\"
12083              : \"mmulhi.wl      %1, %2, %0\");"
12084   [(set_attr "type" "dmpy_media")
12085    (set (attr "highpart")
12086         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12087          (const_string "user")))])
12090 (define_expand "mmulsum_wq"
12091   [(match_operand:DI 0 "arith_reg_dest" "")
12092    (match_operand:V4HI 1 "arith_reg_operand" "")
12093    (match_operand:V4HI 2 "arith_reg_operand" "")
12094    (match_operand:DI 3 "arith_reg_operand" "")]
12095   "TARGET_SHMEDIA"
12096   "
12098   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12099                                operands[1], operands[2]));
12100   DONE;
12103 (define_insn "mmulsum_wq_i"
12104   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12105         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12106          (plus:DI
12107           (plus:DI
12108            (vec_select:DI
12109             (mult:V4DI
12110              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12111              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12112             (parallel [(const_int 0)]))
12113            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12114                                      (sign_extend:V4DI (match_dup 3)))
12115                           (parallel [(const_int 1)])))
12116           (plus:DI
12117            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12118                                      (sign_extend:V4DI (match_dup 3)))
12119                           (parallel [(const_int 2)]))
12120            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12121                                      (sign_extend:V4DI (match_dup 3)))
12122                           (parallel [(const_int 3)]))))))]
12123   "TARGET_SHMEDIA"
12124   "mmulsum.wq   %2, %3, %0"
12125   [(set_attr "type" "mac_media")])
12127 (define_expand "mperm_w"
12128   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12129    (match_operand:V4HI 1 "arith_reg_operand" "r")
12130    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12131   "TARGET_SHMEDIA"
12132   "
12134   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12135              (operands[0], operands[1], operands[2]));
12136   DONE;
12139 ; This use of vec_select isn't exactly correct according to rtl.texi
12140 ; (because not constant), but it seems a straightforward extension.
12141 (define_insn "mperm_w_little"
12142   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12143         (vec_select:V4HI
12144          (match_operand:V4HI 1 "arith_reg_operand" "r")
12145          (parallel
12146           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12147                             (const_int 2) (const_int 0))
12148            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12149            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12150            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12151   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12152   "mperm.w      %1, %N2, %0"
12153   [(set_attr "type" "arith_media")])
12155 (define_insn "mperm_w_big"
12156   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12157         (vec_select:V4HI
12158          (match_operand:V4HI 1 "arith_reg_operand" "r")
12159          (parallel
12160           [(zero_extract:QI (not:QI (match_operand:QI 2
12161                                      "extend_reg_or_0_operand" "rZ"))
12162                             (const_int 2) (const_int 0))
12163            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12164            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12165            (zero_extract:QI (not:QI (match_dup 2))
12166                             (const_int 2) (const_int 6))])))]
12167   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12168   "mperm.w      %1, %N2, %0"
12169   [(set_attr "type" "arith_media")])
12171 (define_insn "mperm_w0"
12172   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12173         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12174                                           "trunc_hi_operand" "r"))))]
12175   "TARGET_SHMEDIA"
12176   "mperm.w      %1, r63, %0"
12177   [(set_attr "type" "arith_media")
12178    (set_attr "highpart" "ignore")])
12180 (define_expand "msad_ubq"
12181   [(match_operand:DI 0 "arith_reg_dest" "")
12182    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12183    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12184    (match_operand:DI 3 "arith_reg_operand" "")]
12185   "TARGET_SHMEDIA"
12186   "
12188   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12189                              operands[1], operands[2]));
12190   DONE;
12193 (define_insn "msad_ubq_i"
12194   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12195         (plus:DI
12196          (plus:DI
12197           (plus:DI
12198            (plus:DI
12199             (match_operand:DI 1 "arith_reg_operand" "0")
12200             (abs:DI (vec_select:DI
12201                      (minus:V8DI
12202                       (zero_extend:V8DI
12203                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12204                       (zero_extend:V8DI
12205                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12206                      (parallel [(const_int 0)]))))
12207            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12208                                               (zero_extend:V8DI (match_dup 3)))
12209                                   (parallel [(const_int 1)]))))
12210           (plus:DI
12211            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12212                                               (zero_extend:V8DI (match_dup 3)))
12213                                   (parallel [(const_int 2)])))
12214            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12215                                               (zero_extend:V8DI (match_dup 3)))
12216                                   (parallel [(const_int 3)])))))
12217          (plus:DI
12218           (plus:DI
12219            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12220                                               (zero_extend:V8DI (match_dup 3)))
12221                                   (parallel [(const_int 4)])))
12222            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12223                                               (zero_extend:V8DI (match_dup 3)))
12224                                   (parallel [(const_int 5)]))))
12225           (plus:DI
12226            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12227                                               (zero_extend:V8DI (match_dup 3)))
12228                                   (parallel [(const_int 6)])))
12229            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12230                                               (zero_extend:V8DI (match_dup 3)))
12231                                   (parallel [(const_int 7)])))))))]
12232   "TARGET_SHMEDIA"
12233   "msad.ubq     %N2, %N3, %0"
12234   [(set_attr "type" "mac_media")])
12236 (define_insn "mshalds_l"
12237   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12238         (ss_truncate:V2SI
12239          (ashift:V2DI
12240           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12241           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12242                   (const_int 31)))))]
12243   "TARGET_SHMEDIA"
12244   "mshalds.l    %1, %2, %0"
12245   [(set_attr "type" "mcmp_media")
12246    (set_attr "highpart" "depend")])
12248 (define_insn "mshalds_w"
12249   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12250         (ss_truncate:V4HI
12251          (ashift:V4SI
12252           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12253           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12254                   (const_int 15)))))]
12255   "TARGET_SHMEDIA"
12256   "mshalds.w    %1, %2, %0"
12257   [(set_attr "type" "mcmp_media")
12258    (set_attr "highpart" "depend")])
12260 (define_insn "ashrv2si3"
12261   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12262         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12263                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12264   "TARGET_SHMEDIA"
12265   "mshard.l     %1, %2, %0"
12266   [(set_attr "type" "arith_media")
12267    (set_attr "highpart" "depend")])
12269 (define_insn "ashrv4hi3"
12270   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12271         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12272                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12273   "TARGET_SHMEDIA"
12274   "mshard.w     %1, %2, %0"
12275   [(set_attr "type" "arith_media")
12276    (set_attr "highpart" "depend")])
12278 (define_insn "mshards_q"
12279   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12280         (ss_truncate:HI
12281          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12282                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12283   "TARGET_SHMEDIA"
12284   "mshards.q    %1, %N2, %0"
12285   [(set_attr "type" "mcmp_media")])
12287 (define_expand "mshfhi_b"
12288   [(match_operand:V8QI 0 "arith_reg_dest" "")
12289    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12290    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12291   "TARGET_SHMEDIA"
12292   "
12294   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12295              (operands[0], operands[1], operands[2]));
12296   DONE;
12299 (define_expand "mshflo_b"
12300   [(match_operand:V8QI 0 "arith_reg_dest" "")
12301    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12302    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12303   "TARGET_SHMEDIA"
12304   "
12306   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12307              (operands[0], operands[1], operands[2]));
12308   DONE;
12311 (define_insn "mshf4_b"
12312   [(set
12313     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12314     (vec_select:V8QI
12315      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12316                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12317      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12318                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12319   "TARGET_SHMEDIA"
12320   "* return (TARGET_LITTLE_ENDIAN
12321              ? \"mshfhi.b       %N1, %N2, %0\"
12322              : \"mshflo.b       %N1, %N2, %0\");"
12323   [(set_attr "type" "arith_media")
12324    (set (attr "highpart")
12325         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12326          (const_string "user")))])
12328 (define_insn "mshf0_b"
12329   [(set
12330     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12331     (vec_select:V8QI
12332      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12333                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12334      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12335                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12336   "TARGET_SHMEDIA"
12337   "* return (TARGET_LITTLE_ENDIAN
12338              ? \"mshflo.b       %N1, %N2, %0\"
12339              : \"mshfhi.b       %N1, %N2, %0\");"
12340   [(set_attr "type" "arith_media")
12341    (set (attr "highpart")
12342         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12343          (const_string "user")))])
12345 (define_expand "mshfhi_l"
12346   [(match_operand:V2SI 0 "arith_reg_dest" "")
12347    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12348    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12349   "TARGET_SHMEDIA"
12350   "
12352   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12353              (operands[0], operands[1], operands[2]));
12354   DONE;
12357 (define_expand "mshflo_l"
12358   [(match_operand:V2SI 0 "arith_reg_dest" "")
12359    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12360    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12361   "TARGET_SHMEDIA"
12362   "
12364   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12365              (operands[0], operands[1], operands[2]));
12366   DONE;
12369 (define_insn "mshf4_l"
12370   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12371         (vec_select:V2SI
12372          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12373                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12374          (parallel [(const_int 1) (const_int 3)])))]
12375   "TARGET_SHMEDIA"
12376   "* return (TARGET_LITTLE_ENDIAN
12377              ? \"mshfhi.l       %N1, %N2, %0\"
12378              : \"mshflo.l       %N1, %N2, %0\");"
12379   [(set_attr "type" "arith_media")
12380    (set (attr "highpart")
12381         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12382          (const_string "user")))])
12384 (define_insn "mshf0_l"
12385   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12386         (vec_select:V2SI
12387          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12388                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12389          (parallel [(const_int 0) (const_int 2)])))]
12390   "TARGET_SHMEDIA"
12391   "* return (TARGET_LITTLE_ENDIAN
12392              ? \"mshflo.l       %N1, %N2, %0\"
12393              : \"mshfhi.l       %N1, %N2, %0\");"
12394   [(set_attr "type" "arith_media")
12395    (set (attr "highpart")
12396         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12397          (const_string "user")))])
12399 (define_expand "mshfhi_w"
12400   [(match_operand:V4HI 0 "arith_reg_dest" "")
12401    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12402    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12403   "TARGET_SHMEDIA"
12404   "
12406   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12407              (operands[0], operands[1], operands[2]));
12408   DONE;
12411 (define_expand "mshflo_w"
12412   [(match_operand:V4HI 0 "arith_reg_dest" "")
12413    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12414    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12415   "TARGET_SHMEDIA"
12416   "
12418   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12419              (operands[0], operands[1], operands[2]));
12420   DONE;
12423 (define_insn "mshf4_w"
12424   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12425         (vec_select:V4HI
12426          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12427                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12428          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12429   "TARGET_SHMEDIA"
12430   "* return (TARGET_LITTLE_ENDIAN
12431              ? \"mshfhi.w       %N1, %N2, %0\"
12432              : \"mshflo.w       %N1, %N2, %0\");"
12433   [(set_attr "type" "arith_media")
12434    (set (attr "highpart")
12435         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12436          (const_string "user")))])
12438 (define_insn "mshf0_w"
12439   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12440         (vec_select:V4HI
12441          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12442                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12443          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12444   "TARGET_SHMEDIA"
12445   "* return (TARGET_LITTLE_ENDIAN
12446              ? \"mshflo.w       %N1, %N2, %0\"
12447              : \"mshfhi.w       %N1, %N2, %0\");"
12448   [(set_attr "type" "arith_media")
12449    (set (attr "highpart")
12450         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12451          (const_string "user")))])
12453 (define_insn "mshflo_w_x"
12454   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12455         (vec_select:V4HI
12456          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12457                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12458          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12459   "TARGET_SHMEDIA"
12460   "mshflo.w     %N1, %N2, %0"
12461   [(set_attr "type" "arith_media")
12462    (set_attr "highpart" "ignore")])
12464 /* These are useful to expand ANDs and as combiner patterns.  */
12465 (define_insn_and_split "mshfhi_l_di"
12466   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12467         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12468                              (const_int 32))
12469                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12470                         (const_int -4294967296))))]
12471   "TARGET_SHMEDIA"
12472   "@
12473         mshfhi.l        %N1, %N2, %0
12474         #"
12475   "TARGET_SHMEDIA && reload_completed
12476    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12477   [(set (match_dup 3) (match_dup 4))
12478    (set (match_dup 5) (match_dup 6))]
12479   "
12481   operands[3] = gen_lowpart (SImode, operands[0]);
12482   operands[4] = gen_highpart (SImode, operands[1]);
12483   operands[5] = gen_highpart (SImode, operands[0]);
12484   operands[6] = gen_highpart (SImode, operands[2]);
12486   [(set_attr "type" "arith_media")])
12488 (define_insn "*mshfhi_l_di_rev"
12489   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12490         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12491                         (const_int -4294967296))
12492                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12493                              (const_int 32))))]
12494   "TARGET_SHMEDIA"
12495   "mshfhi.l     %N2, %N1, %0"
12496   [(set_attr "type" "arith_media")])
12498 (define_split
12499   [(set (match_operand:DI 0 "arith_reg_dest" "")
12500         (ior:DI (zero_extend:DI (match_operand:SI 1
12501                                               "extend_reg_or_0_operand" ""))
12502                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12503                         (const_int -4294967296))))
12504    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12505   "TARGET_SHMEDIA"
12506   [(const_int 0)]
12507   "
12509   emit_insn (gen_ashldi3_media (operands[3],
12510                                 simplify_gen_subreg (DImode, operands[1],
12511                                                      SImode, 0),
12512                                 GEN_INT (32)));
12513   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12514   DONE;
12517 (define_insn "mshflo_l_di"
12518   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12519         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12520                         (const_int 4294967295))
12521                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12522                            (const_int 32))))]
12524   "TARGET_SHMEDIA"
12525   "mshflo.l     %N1, %N2, %0"
12526   [(set_attr "type" "arith_media")
12527    (set_attr "highpart" "ignore")])
12529 (define_insn "*mshflo_l_di_rev"
12530   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12531         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12532                            (const_int 32))
12533                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12534                         (const_int 4294967295))))]
12536   "TARGET_SHMEDIA"
12537   "mshflo.l     %N2, %N1, %0"
12538   [(set_attr "type" "arith_media")
12539    (set_attr "highpart" "ignore")])
12541 ;; Combiner pattern for trampoline initialization.
12542 (define_insn_and_split "*double_shori"
12543   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12544         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12545                            (const_int 32))
12546                 (match_operand:DI 2 "const_int_operand" "n")))]
12547   "TARGET_SHMEDIA
12548    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12549   "#"
12550   "rtx_equal_p (operands[0], operands[1])"
12551   [(const_int 0)]
12552   "
12554   HOST_WIDE_INT v = INTVAL (operands[2]);
12556   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12557   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12558   DONE;
12560   [(set_attr "highpart" "ignore")])
12563 (define_insn "*mshflo_l_di_x"
12564   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12565         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12566                                  "rZ"))
12567                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12568                            (const_int 32))))]
12570   "TARGET_SHMEDIA"
12571   "mshflo.l     %N1, %N2, %0"
12572   [(set_attr "type" "arith_media")
12573    (set_attr "highpart" "ignore")])
12575 (define_insn_and_split "concat_v2sf"
12576   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12577 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12578         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12579                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12581   "TARGET_SHMEDIA"
12582   "@
12583         mshflo.l        %N1, %N2, %0
12584         #
12585         #"
12586   "TARGET_SHMEDIA && reload_completed
12587    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12588   [(set (match_dup 3) (match_dup 1))
12589    (set (match_dup 4) (match_dup 2))]
12590   "
12592   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12593   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12595   [(set_attr "type" "arith_media")
12596    (set_attr "highpart" "ignore")])
12598 (define_insn "*mshflo_l_di_x_rev"
12599   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12600         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12601                            (const_int 32))
12602                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12604   "TARGET_SHMEDIA"
12605   "mshflo.l     %N2, %N1, %0"
12606   [(set_attr "type" "arith_media")
12607    (set_attr "highpart" "ignore")])
12609 (define_insn "ashlv2si3"
12610   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12611         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12612                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12613   "TARGET_SHMEDIA"
12614   "mshlld.l     %1, %2, %0"
12615   [(set_attr "type" "arith_media")
12616    (set_attr "highpart" "depend")])
12618 (define_split
12619   [(set (match_operand 0 "any_register_operand" "")
12620         (match_operator 3 "shift_operator"
12621           [(match_operand 1 "any_register_operand" "")
12622            (match_operand 2 "shift_count_reg_operand" "")]))]
12623   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12624   [(set (match_dup 0) (match_dup 3))]
12625   "
12627   rtx count = operands[2];
12628   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12630   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12631          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12632          || GET_CODE (count) == TRUNCATE)
12633     count = XEXP (count, 0);
12634   inner_mode = GET_MODE (count);
12635   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12636                                subreg_lowpart_offset (outer_mode, inner_mode));
12637   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12638                                 operands[1], count);
12641 (define_insn "ashlv4hi3"
12642   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12643         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12644                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12645   "TARGET_SHMEDIA"
12646   "mshlld.w     %1, %2, %0"
12647   [(set_attr "type" "arith_media")
12648    (set_attr "highpart" "depend")])
12650 (define_insn "lshrv2si3"
12651   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12652         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12653                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12654   "TARGET_SHMEDIA"
12655   "mshlrd.l     %1, %2, %0"
12656   [(set_attr "type" "arith_media")
12657    (set_attr "highpart" "depend")])
12659 (define_insn "lshrv4hi3"
12660   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12661         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12662                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12663   "TARGET_SHMEDIA"
12664   "mshlrd.w     %1, %2, %0"
12665   [(set_attr "type" "arith_media")
12666    (set_attr "highpart" "depend")])
12668 (define_insn "subv2si3"
12669   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12670         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12671                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12672   "TARGET_SHMEDIA"
12673   "msub.l       %N1, %2, %0"
12674   [(set_attr "type" "arith_media")
12675    (set_attr "highpart" "depend")])
12677 (define_insn "subv4hi3"
12678   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12679         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12680                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12681   "TARGET_SHMEDIA"
12682   "msub.w       %N1, %2, %0"
12683   [(set_attr "type" "arith_media")
12684    (set_attr "highpart" "depend")])
12686 (define_insn_and_split "subv2hi3"
12687   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12688         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12689                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12690   "TARGET_SHMEDIA"
12691   "#"
12692   "TARGET_SHMEDIA"
12693   [(const_int 0)]
12694   "
12696   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12697   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12698   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12699   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12700   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12702   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12703   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12704   DONE;
12706   [(set_attr "highpart" "must_split")])
12708 (define_insn "sssubv2si3"
12709   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12710         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12711                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12712   "TARGET_SHMEDIA"
12713   "msubs.l      %N1, %2, %0"
12714   [(set_attr "type" "mcmp_media")
12715    (set_attr "highpart" "depend")])
12717 (define_insn "ussubv8qi3"
12718   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12719         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12720                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12721   "TARGET_SHMEDIA"
12722   "msubs.ub     %N1, %2, %0"
12723   [(set_attr "type" "mcmp_media")
12724    (set_attr "highpart" "depend")])
12726 (define_insn "sssubv4hi3"
12727   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12728         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12729                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12730   "TARGET_SHMEDIA"
12731   "msubs.w      %N1, %2, %0"
12732   [(set_attr "type" "mcmp_media")
12733    (set_attr "highpart" "depend")])
12735 ;; Floating Point Intrinsics
12737 (define_insn "fcosa_s"
12738   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12739         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12740                    UNSPEC_FCOSA))]
12741   "TARGET_SHMEDIA"
12742   "fcosa.s      %1, %0"
12743   [(set_attr "type" "atrans_media")])
12745 (define_insn "fsina_s"
12746   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12747         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12748                    UNSPEC_FSINA))]
12749   "TARGET_SHMEDIA"
12750   "fsina.s      %1, %0"
12751   [(set_attr "type" "atrans_media")])
12753 (define_insn "fipr"
12754   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12755         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12756                                                     "fp_arith_reg_operand" "f")
12757                                                    (match_operand:V4SF 2
12758                                                     "fp_arith_reg_operand" "f"))
12759                                          (parallel [(const_int 0)]))
12760                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12761                                          (parallel [(const_int 1)])))
12762                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12763                                          (parallel [(const_int 2)]))
12764                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12765                                          (parallel [(const_int 3)])))))]
12766   "TARGET_SHMEDIA"
12767   "fipr.s       %1, %2, %0"
12768   [(set_attr "type" "fparith_media")])
12770 (define_insn "fsrra_s"
12771   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12772         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12773                    UNSPEC_FSRRA))]
12774   "TARGET_SHMEDIA"
12775   "fsrra.s      %1, %0"
12776   [(set_attr "type" "atrans_media")])
12778 (define_insn "ftrv"
12779   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12780         (plus:V4SF
12781          (plus:V4SF
12782           (mult:V4SF
12783            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12784                             (parallel [(const_int 0) (const_int 5)
12785                                        (const_int 10) (const_int 15)]))
12786            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12787           (mult:V4SF
12788            (vec_select:V4SF (match_dup 1)
12789                             (parallel [(const_int 4) (const_int 9)
12790                                        (const_int 14) (const_int 3)]))
12791            (vec_select:V4SF (match_dup 2)
12792                             (parallel [(const_int 1) (const_int 2)
12793                                        (const_int 3) (const_int 0)]))))
12794          (plus:V4SF
12795           (mult:V4SF
12796            (vec_select:V4SF (match_dup 1)
12797                             (parallel [(const_int 8) (const_int 13)
12798                                        (const_int 2) (const_int 7)]))
12799            (vec_select:V4SF (match_dup 2)
12800                             (parallel [(const_int 2) (const_int 3)
12801                                        (const_int 0) (const_int 1)])))
12802           (mult:V4SF
12803            (vec_select:V4SF (match_dup 1)
12804                             (parallel [(const_int 12) (const_int 1)
12805                                        (const_int 6) (const_int 11)]))
12806            (vec_select:V4SF (match_dup 2)
12807                             (parallel [(const_int 3) (const_int 0)
12808                                        (const_int 1) (const_int 2)]))))))]
12809   "TARGET_SHMEDIA"
12810   "ftrv.s %1, %2, %0"
12811   [(set_attr "type" "fparith_media")])
12813 (define_insn "ldhi_l"
12814   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12815         (zero_extract:SI
12816          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12817                                   (const_int 3))
12818                           (const_int -3)))
12819          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12820          (const_int 0)))]
12821   "TARGET_SHMEDIA32"
12822   "ldhi.l       %U1, %0"
12823   [(set_attr "type" "load_media")])
12825 (define_insn "ldhi_q"
12826   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12827         (zero_extract:DI
12828          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12829                                   (const_int 7))
12830                           (const_int -7)))
12831          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12832          (const_int 0)))]
12833   "TARGET_SHMEDIA32"
12834   "ldhi.q       %U1, %0"
12835   [(set_attr "type" "load_media")])
12837 (define_insn_and_split "*ldhi_q_comb0"
12838   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12839         (zero_extract:DI
12840          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12841                                             "register_operand" "r")
12842                                            (match_operand:SI 2
12843                                             "ua_offset" "I06"))
12844                                   (const_int 7))
12845                           (const_int -7)))
12846          (plus:SI (and:SI (match_dup 1) (const_int 7))
12847                   (const_int 1))
12848          (const_int 0)))]
12849   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12850   "#"
12851   ""
12852   [(pc)]
12853   "emit_insn (gen_ldhi_q (operands[0],
12854                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12855    DONE;")
12858 (define_insn_and_split "*ldhi_q_comb1"
12859   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12860         (zero_extract:DI
12861          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12862                                             "register_operand" "r")
12863                                            (match_operand:SI 2
12864                                             "ua_offset" "I06"))
12865                                   (const_int 7))
12866                           (const_int -7)))
12867          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12868                                                    "ua_offset" "I06"))
12869                           (const_int 7))
12870                   (const_int 1))
12871          (const_int 0)))]
12872   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12873    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12874   "#"
12875   ""
12876   [(pc)]
12877   "emit_insn (gen_ldhi_q (operands[0],
12878                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12879    DONE;")
12882 (define_insn "ldlo_l"
12883   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12884         (zero_extract:SI
12885          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12886                          (const_int -4)))
12887          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12888          (and:SI (match_dup 1) (const_int 3))))]
12889   "TARGET_SHMEDIA32"
12890   "ldlo.l       %U1, %0"
12891   [(set_attr "type" "load_media")])
12893 (define_insn "ldlo_q"
12894   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12895         (zero_extract:DI
12896          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12897                          (const_int -8)))
12898          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12899          (and:SI (match_dup 1) (const_int 7))))]
12900   "TARGET_SHMEDIA32"
12901   "ldlo.q       %U1, %0"
12902   [(set_attr "type" "load_media")])
12904 (define_insn_and_split "*ldlo_q_comb0"
12905   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12906         (zero_extract:DI
12907          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12908                                   (match_operand:SI 2 "ua_offset" "I06"))
12909                          (const_int -8)))
12910          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12911          (and:SI (match_dup 1) (const_int 7))))]
12912   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12913   "#"
12914   ""
12915   [(pc)]
12916   "emit_insn (gen_ldlo_q (operands[0],
12917                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12918    DONE;")
12920 (define_insn_and_split "*ldlo_q_comb1"
12921   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12922         (zero_extract:DI
12923          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12924                                   (match_operand:SI 2 "ua_offset" "I06"))
12925                          (const_int -8)))
12926          (minus:SI (const_int 8)
12927                    (and:SI (plus:SI (match_dup 1)
12928                                     (match_operand:SI 3 "ua_offset" "I06"))
12929                            (const_int 7)))
12930          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12931   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12932    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12933   "#"
12934   ""
12935   [(pc)]
12936   "emit_insn (gen_ldlo_q (operands[0],
12937                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12938    DONE;")
12940 (define_insn "sthi_l"
12941   [(set (zero_extract:SI
12942          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12943                                   (const_int 3))
12944                           (const_int -3)))
12945          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12946          (const_int 0))
12947         (match_operand:SI 1 "arith_reg_operand" "r"))]
12948   "TARGET_SHMEDIA32"
12949   "sthi.l       %U0, %1"
12950   [(set_attr "type" "ustore_media")])
12952 ;; All unaligned stores are considered to be 'narrow' because they typically
12953 ;; operate on less that a quadword, and when they operate on a full quadword,
12954 ;; the vanilla store high / store low sequence will cause a stall if not
12955 ;; scheduled apart.
12956 (define_insn "sthi_q"
12957   [(set (zero_extract:DI
12958          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12959                                   (const_int 7))
12960                           (const_int -7)))
12961          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12962          (const_int 0))
12963         (match_operand:DI 1 "arith_reg_operand" "r"))]
12964   "TARGET_SHMEDIA32"
12965   "sthi.q       %U0, %1"
12966   [(set_attr "type" "ustore_media")])
12968 (define_insn_and_split "*sthi_q_comb0"
12969   [(set (zero_extract:DI
12970          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12971                                             "register_operand" "r")
12972                                            (match_operand:SI 1 "ua_offset"
12973                                             "I06"))
12974                                   (const_int 7))
12975                           (const_int -7)))
12976          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12977          (const_int 0))
12978         (match_operand:DI 2 "arith_reg_operand" "r"))]
12979   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12980   "#"
12981   ""
12982   [(pc)]
12983   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12984                           operands[2]));
12985    DONE;")
12987 (define_insn_and_split "*sthi_q_comb1"
12988   [(set (zero_extract:DI
12989          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12990                                             "register_operand" "r")
12991                                            (match_operand:SI 1 "ua_offset"
12992                                             "I06"))
12993                                   (const_int 7))
12994                           (const_int -7)))
12995          (plus:SI (and:SI (plus:SI (match_dup 0)
12996                                    (match_operand:SI 2 "ua_offset" "I06"))
12997                           (const_int 7))
12998                   (const_int 1))
12999          (const_int 0))
13000         (match_operand:DI 3 "arith_reg_operand" "r"))]
13001   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13002    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13003   "#"
13004   ""
13005   [(pc)]
13006   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13007                           operands[3]));
13008    DONE;")
13010 ;; This is highpart user because the address is used as full 64 bit.
13011 (define_insn "stlo_l"
13012   [(set (zero_extract:SI
13013          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13014                          (const_int -4)))
13015          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13016          (and:SI (match_dup 0) (const_int 3)))
13017         (match_operand:SI 1 "arith_reg_operand" "r"))]
13018   "TARGET_SHMEDIA32"
13019   "stlo.l       %U0, %1"
13020   [(set_attr "type" "ustore_media")])
13022 (define_insn "stlo_q"
13023   [(set (zero_extract:DI
13024          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13025                          (const_int -8)))
13026          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13027          (and:SI (match_dup 0) (const_int 7)))
13028         (match_operand:DI 1 "arith_reg_operand" "r"))]
13029   "TARGET_SHMEDIA32"
13030   "stlo.q       %U0, %1"
13031   [(set_attr "type" "ustore_media")])
13033 (define_insn_and_split "*stlo_q_comb0"
13034   [(set (zero_extract:DI
13035          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13036                                   (match_operand:SI 1 "ua_offset" "I06"))
13037                          (const_int -8)))
13038          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13039          (and:SI (match_dup 0) (const_int 7)))
13040         (match_operand:DI 2 "arith_reg_operand" "r"))]
13041   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13042   "#"
13043   ""
13044   [(pc)]
13045   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13046                           operands[2]));
13047    DONE;")
13049 (define_insn_and_split "*stlo_q_comb1"
13050   [(set (zero_extract:DI
13051          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13052                                   (match_operand:SI 1 "ua_offset" "I06"))
13053                          (const_int -8)))
13054          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13055                                                   (match_operand:SI 2
13056                                                    "ua_offset" "I06"))
13057                                          (const_int 7)))
13058          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13059         (match_operand:DI 3 "arith_reg_operand" "r"))]
13060   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13061   "#"
13062   ""
13063   [(pc)]
13064   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13065                           operands[3]));
13066    DONE;")
13068 (define_insn "ldhi_l64"
13069   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13070         (zero_extract:SI
13071          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13072                                   (const_int 3))
13073                           (const_int -3)))
13074          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13075          (const_int 0)))]
13076   "TARGET_SHMEDIA64"
13077   "ldhi.l       %U1, %0"
13078   [(set_attr "type" "load_media")])
13080 (define_insn "ldhi_q64"
13081   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13082         (zero_extract:DI
13083          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13084                                   (const_int 7))
13085                           (const_int -7)))
13086          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13087          (const_int 0)))]
13088   "TARGET_SHMEDIA64"
13089   "ldhi.q       %U1, %0"
13090   [(set_attr "type" "load_media")])
13092 (define_insn "ldlo_l64"
13093   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13094         (zero_extract:SI
13095          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13096                          (const_int -4)))
13097          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13098          (and:DI (match_dup 1) (const_int 3))))]
13099   "TARGET_SHMEDIA64"
13100   "ldlo.l       %U1, %0"
13101   [(set_attr "type" "load_media")])
13103 (define_insn "ldlo_q64"
13104   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13105         (zero_extract:DI
13106          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13107                          (const_int -8)))
13108          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13109          (and:DI (match_dup 1) (const_int 7))))]
13110   "TARGET_SHMEDIA64"
13111   "ldlo.q       %U1, %0"
13112   [(set_attr "type" "load_media")])
13114 (define_insn "sthi_l64"
13115   [(set (zero_extract:SI
13116          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13117                                   (const_int 3))
13118                           (const_int -3)))
13119          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13120          (const_int 0))
13121         (match_operand:SI 1 "arith_reg_operand" "r"))]
13122   "TARGET_SHMEDIA64"
13123   "sthi.l       %U0, %1"
13124   [(set_attr "type" "ustore_media")])
13126 (define_insn "sthi_q64"
13127   [(set (zero_extract:DI
13128          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13129                                   (const_int 7))
13130                           (const_int -7)))
13131          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13132          (const_int 0))
13133         (match_operand:DI 1 "arith_reg_operand" "r"))]
13134   "TARGET_SHMEDIA64"
13135   "sthi.q       %U0, %1"
13136   [(set_attr "type" "ustore_media")])
13138 (define_insn "stlo_l64"
13139   [(set (zero_extract:SI
13140          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13141                          (const_int -4)))
13142          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13143          (and:DI (match_dup 0) (const_int 3)))
13144         (match_operand:SI 1 "arith_reg_operand" "r"))]
13145   "TARGET_SHMEDIA64"
13146   "stlo.l       %U0, %1"
13147   [(set_attr "type" "ustore_media")])
13149 (define_insn "stlo_q64"
13150   [(set (zero_extract:DI
13151          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13152                          (const_int -8)))
13153          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13154          (and:DI (match_dup 0) (const_int 7)))
13155         (match_operand:DI 1 "arith_reg_operand" "r"))]
13156   "TARGET_SHMEDIA64"
13157   "stlo.q       %U0, %1"
13158   [(set_attr "type" "ustore_media")])
13160 (define_insn "nsb"
13161   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13162         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13163                    UNSPEC_NSB))]
13164   "TARGET_SHMEDIA"
13165   "nsb  %1, %0"
13166   [(set_attr "type" "arith_media")])
13168 (define_insn "nsbsi"
13169   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13170         (zero_extend:SI
13171          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13172                     UNSPEC_NSB)))]
13173   "TARGET_SHMEDIA"
13174   "nsb  %1, %0"
13175   [(set_attr "type" "arith_media")])
13177 (define_insn "nsbdi"
13178   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13179         (zero_extend:DI
13180          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13181                     UNSPEC_NSB)))]
13182   "TARGET_SHMEDIA"
13183   "nsb  %1, %0"
13184   [(set_attr "type" "arith_media")])
13186 (define_expand "ffsdi2"
13187   [(set (match_operand:DI 0 "arith_reg_dest" "")
13188         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13189   "TARGET_SHMEDIA"
13190   "
13192   rtx scratch = gen_reg_rtx (DImode);
13193   rtx last;
13195   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13196   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13197   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13198   emit_insn (gen_nsbdi (scratch, scratch));
13199   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13200   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13201   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13202   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13204   DONE;
13207 (define_expand "ffssi2"
13208   [(set (match_operand:SI 0 "arith_reg_dest" "")
13209         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13210   "TARGET_SHMEDIA"
13211   "
13213   rtx scratch = gen_reg_rtx (SImode);
13214   rtx discratch = gen_reg_rtx (DImode);
13215   rtx last;
13217   emit_insn (gen_adddi3 (discratch,
13218                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13219                          constm1_rtx));
13220   emit_insn (gen_andcdi3 (discratch,
13221                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13222                           discratch));
13223   emit_insn (gen_nsbsi (scratch, discratch));
13224   last = emit_insn (gen_subsi3 (operands[0],
13225                                 force_reg (SImode, GEN_INT (63)), scratch));
13226   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13228   DONE;
13231 (define_insn "byterev"
13232   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13233         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13234                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13235                                     (const_int 4) (const_int 3) (const_int 2)
13236                                     (const_int 1) (const_int 0)])))]
13237   "TARGET_SHMEDIA"
13238   "byterev      %1, %0"
13239   [(set_attr "type" "arith_media")])
13241 (define_insn "*prefetch_media"
13242   [(prefetch (match_operand:QI 0 "address_operand" "p")
13243              (match_operand:SI 1 "const_int_operand" "n")
13244              (match_operand:SI 2 "const_int_operand" "n"))]
13245   "TARGET_SHMEDIA"
13246   "*
13248   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13249   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13250   return \"\";
13252   [(set_attr "type" "other")])
13254 (define_insn "*prefetch_i4"
13255   [(prefetch (match_operand:SI 0 "register_operand" "r")
13256              (match_operand:SI 1 "const_int_operand" "n")
13257              (match_operand:SI 2 "const_int_operand" "n"))]
13258   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13259   "*
13261   return \"pref @%0\";
13263   [(set_attr "type" "other")])
13265 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13266 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13267 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13268 (define_expand "prefetch"
13269   [(prefetch (match_operand 0 "address_operand" "p")
13270              (match_operand:SI 1 "const_int_operand" "n")
13271              (match_operand:SI 2 "const_int_operand" "n"))]
13272   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13273    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13274   "
13276   if (GET_MODE (operands[0]) != Pmode
13277       || !CONST_INT_P (operands[1])
13278       || !CONST_INT_P (operands[2]))
13279     FAIL;
13280   if (! TARGET_SHMEDIA)
13281     operands[0] = force_reg (Pmode, operands[0]);
13284 (define_insn "prefetch_m2a"
13285   [(prefetch (match_operand:SI 0 "register_operand" "r")
13286              (match_operand:SI 1 "const_int_operand" "n")
13287              (match_operand:SI 2 "const_int_operand" "n"))]
13288   "TARGET_SH2A"
13289   "pref\\t@%0"
13290   [(set_attr "type" "other")])
13292 (define_insn "alloco_i"
13293   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13294         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13295   "TARGET_SHMEDIA32"
13296   "*
13298   rtx xops[2];
13300   if (GET_CODE (operands[0]) == PLUS)
13301     {
13302       xops[0] = XEXP (operands[0], 0);
13303       xops[1] = XEXP (operands[0], 1);
13304     }
13305   else
13306     {
13307       xops[0] = operands[0];
13308       xops[1] = const0_rtx;
13309     }
13310   output_asm_insn (\"alloco   %0, %1\", xops);
13311   return \"\";
13313   [(set_attr "type" "other")])
13315 (define_split
13316   [(set (match_operand 0 "any_register_operand" "")
13317         (match_operand 1 "" ""))]
13318   "TARGET_SHMEDIA && reload_completed"
13319   [(set (match_dup 0) (match_dup 1))]
13320   "
13322   int n_changes = 0;
13324   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13325   if (!n_changes)
13326     FAIL;
13329 ; Stack Protector Patterns
13331 (define_expand "stack_protect_set"
13332   [(set (match_operand 0 "memory_operand" "")
13333         (match_operand 1 "memory_operand" ""))]
13334   ""
13336   if (TARGET_SHMEDIA)
13337     {
13338       if (TARGET_SHMEDIA64)
13339         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13340       else
13341         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13342     }
13343   else
13344     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13346   DONE;
13349 (define_insn "stack_protect_set_si"
13350   [(set (match_operand:SI 0 "memory_operand" "=m")
13351         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13352    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13353   "!TARGET_SHMEDIA"
13354   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13355   [(set_attr "type" "other")
13356    (set_attr "length" "6")])
13358 (define_insn "stack_protect_set_si_media"
13359   [(set (match_operand:SI 0 "memory_operand" "=m")
13360         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13361    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13362   "TARGET_SHMEDIA"
13363   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13364   [(set_attr "type" "other")
13365    (set_attr "length" "12")])
13367 (define_insn "stack_protect_set_di_media"
13368   [(set (match_operand:DI 0 "memory_operand" "=m")
13369         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13370    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13371   "TARGET_SHMEDIA64"
13372   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13373   [(set_attr "type" "other")
13374    (set_attr "length" "12")])
13376 (define_expand "stack_protect_test"
13377   [(match_operand 0 "memory_operand" "")
13378    (match_operand 1 "memory_operand" "")
13379    (match_operand 2 "" "")]
13380   ""
13382   if (TARGET_SHMEDIA)
13383     {
13384       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13385       rtx test;
13387       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13388       if (TARGET_SHMEDIA64)
13389         {
13390           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13391                                                       operands[1]));
13392           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13393         }
13394       else
13395         {
13396           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13397                                                       operands[1]));
13398           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13399         }
13400     }
13401   else
13402     {
13403       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13404       emit_jump_insn (gen_branch_true (operands[2]));
13405     }
13407   DONE;
13410 (define_insn "stack_protect_test_si"
13411   [(set (reg:SI T_REG)
13412         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13413                     (match_operand:SI 1 "memory_operand" "m")]
13414                    UNSPEC_SP_TEST))
13415   (set (match_scratch:SI 2 "=&r") (const_int 0))
13416   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13417   "!TARGET_SHMEDIA"
13418   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13419   [(set_attr "type" "other")
13420    (set_attr "length" "10")])
13422 (define_insn "stack_protect_test_si_media"
13423   [(set (match_operand:SI 0 "register_operand" "=&r")
13424         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13425                     (match_operand:SI 2 "memory_operand" "m")]
13426                    UNSPEC_SP_TEST))
13427   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13428   "TARGET_SHMEDIA"
13429   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13430   [(set_attr "type" "other")
13431    (set_attr "length" "16")])
13433 (define_insn "stack_protect_test_di_media"
13434   [(set (match_operand:DI 0 "register_operand" "=&r")
13435         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13436                     (match_operand:DI 2 "memory_operand" "m")]
13437                    UNSPEC_SP_TEST))
13438   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13439   "TARGET_SHMEDIA64"
13440   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13441   [(set_attr "type" "other")
13442    (set_attr "length" "16")])