* config/sh/sh-protos.h (sh_function_arg): Delete.
[official-gcc.git] / gcc / config / sh / sh.md
blobdd63f63136fced60ee4866952eb7079a2d77bc83
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 2 "arith_reg_dest" "0")
7054                           (const_int 1))
7055                       (label_ref (match_operand 1 "" ""))
7056                       (pc)))
7057    (set (match_operand:SI 0 "arith_reg_dest" "=r")
7058         (plus (match_dup 2) (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_dup 2) (const_int 1)))
7065               (set (match_dup 0) (plus:SI (match_dup 2) (const_int -1)))])
7066    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
7067                            (label_ref (match_dup 1))
7068                            (pc)))]
7070    [(set_attr "type" "cbranch")])
7073 ;; ------------------------------------------------------------------------
7074 ;; Jump and linkage insns
7075 ;; ------------------------------------------------------------------------
7077 (define_insn "jump_compact"
7078   [(set (pc)
7079         (label_ref (match_operand 0 "" "")))]
7080   "TARGET_SH1 && !find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)"
7081   "*
7083   /* The length is 16 if the delay slot is unfilled.  */
7084   if (get_attr_length(insn) > 4)
7085     return output_far_jump(insn, operands[0]);
7086   else
7087     return   \"bra      %l0%#\";
7089   [(set_attr "type" "jump")
7090    (set_attr "needs_delay_slot" "yes")])
7092 ;; ??? It would be much saner to explicitly use the scratch register
7093 ;; in the jump insn, and have indirect_jump_scratch only set it,
7094 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7095 ;; from the target then, as it uses simplejump_p.
7096 ;;(define_insn "jump_compact_far"
7097 ;;  [(set (pc)
7098 ;;      (label_ref (match_operand 0 "" "")))
7099 ;;   (use (match_operand 1 "register_operand" "r")]
7100 ;;  "TARGET_SH1"
7101 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7102 ;;  [(set_attr "type" "jump")
7103 ;;   (set_attr "needs_delay_slot" "yes")])
7105 (define_insn "jump_media"
7106   [(set (pc)
7107         (match_operand 0 "target_operand" "b"))]
7108   "TARGET_SHMEDIA"
7109   "blink        %0, r63%>"
7110   [(set_attr "type" "jump_media")])
7112 (define_expand "jump"
7113   [(set (pc)
7114         (label_ref (match_operand 0 "" "")))]
7115   ""
7116   "
7118   if (TARGET_SH1)
7119     emit_jump_insn (gen_jump_compact (operands[0]));
7120   else if (TARGET_SHMEDIA)
7121     {
7122       if (reload_in_progress || reload_completed)
7123         FAIL;
7124       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7125                                                          operands[0])));
7126     }
7127   DONE;
7130 (define_insn "force_mode_for_call"
7131   [(use (reg:PSI FPSCR_REG))]
7132   "TARGET_SHCOMPACT"
7133   ""
7134   [(set_attr "length" "0")
7135    (set (attr "fp_mode")
7136         (if_then_else (eq_attr "fpu_single" "yes")
7137                       (const_string "single") (const_string "double")))])
7139 (define_insn "calli"
7140   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7141          (match_operand 1 "" ""))
7142    (use (reg:PSI FPSCR_REG))
7143    (clobber (reg:SI PR_REG))]
7144   "TARGET_SH1"
7145   "*
7146    {
7147      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7148         return \"jsr/n\\t@%0\";
7149      else
7150         return \"jsr\\t@%0%#\";
7151    }"
7153   [(set_attr "type" "call")
7154    (set (attr "fp_mode")
7155         (if_then_else (eq_attr "fpu_single" "yes")
7156                       (const_string "single") (const_string "double")))
7157    (set_attr "needs_delay_slot" "yes")
7158    (set_attr "fp_set" "unknown")])
7160 ;; This is TBR relative jump instruction for SH2A architecture.
7161 ;; Its use is enabled assigning an attribute "function_vector"
7162 ;; and the vector number to a function during its declaration.
7164 (define_insn "calli_tbr_rel"
7165   [(call (mem (match_operand:SI 0 "symbol_ref_operand" ""))
7166          (match_operand 1 "" ""))
7167    (use (reg:PSI FPSCR_REG))
7168    (clobber (reg:SI PR_REG))]
7169   "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])"
7170   "*
7172   unsigned HOST_WIDE_INT vect_num;
7173   vect_num = sh2a_get_function_vector_number (operands[0]);
7174   operands[2] = GEN_INT (vect_num * 4);
7176   return \"jsr/n\\t@@(%O2,tbr)\";
7178   [(set_attr "type" "call")
7179    (set (attr "fp_mode")
7180         (if_then_else (eq_attr "fpu_single" "yes")
7181                       (const_string "single") (const_string "double")))
7182    (set_attr "needs_delay_slot" "no")
7183    (set_attr "fp_set" "unknown")])
7185 ;; This is a pc-rel call, using bsrf, for use with PIC.
7187 (define_insn "calli_pcrel"
7188   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7189          (match_operand 1 "" ""))
7190    (use (reg:PSI FPSCR_REG))
7191    (use (reg:SI PIC_REG))
7192    (use (match_operand 2 "" ""))
7193    (clobber (reg:SI PR_REG))]
7194   "TARGET_SH2"
7195   "bsrf %0\\n%O2:%#"
7196   [(set_attr "type" "call")
7197    (set (attr "fp_mode")
7198         (if_then_else (eq_attr "fpu_single" "yes")
7199                       (const_string "single") (const_string "double")))
7200    (set_attr "needs_delay_slot" "yes")
7201    (set_attr "fp_set" "unknown")])
7203 (define_insn_and_split "call_pcrel"
7204   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7205          (match_operand 1 "" ""))
7206    (use (reg:PSI FPSCR_REG))
7207    (use (reg:SI PIC_REG))
7208    (clobber (reg:SI PR_REG))
7209    (clobber (match_scratch:SI 2 "=r"))]
7210   "TARGET_SH2"
7211   "#"
7212   "reload_completed"
7213   [(const_int 0)]
7214   "
7216   rtx lab = PATTERN (gen_call_site ());
7218   if (SYMBOL_REF_LOCAL_P (operands[0]))
7219     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7220   else
7221     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7222   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], copy_rtx (lab)));
7223   DONE;
7225   [(set_attr "type" "call")
7226    (set (attr "fp_mode")
7227         (if_then_else (eq_attr "fpu_single" "yes")
7228                       (const_string "single") (const_string "double")))
7229    (set_attr "needs_delay_slot" "yes")
7230    (set_attr "fp_set" "unknown")])
7232 (define_insn "call_compact"
7233   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7234          (match_operand 1 "" ""))
7235    (match_operand 2 "immediate_operand" "n")
7236    (use (reg:SI R0_REG))
7237    (use (reg:SI R1_REG))
7238    (use (reg:PSI FPSCR_REG))
7239    (clobber (reg:SI PR_REG))]
7240   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7241   "jsr  @%0%#"
7242   [(set_attr "type" "call")
7243    (set (attr "fp_mode")
7244         (if_then_else (eq_attr "fpu_single" "yes")
7245                       (const_string "single") (const_string "double")))
7246    (set_attr "needs_delay_slot" "yes")])
7248 (define_insn "call_compact_rettramp"
7249   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7250          (match_operand 1 "" ""))
7251    (match_operand 2 "immediate_operand" "n")
7252    (use (reg:SI R0_REG))
7253    (use (reg:SI R1_REG))
7254    (use (reg:PSI FPSCR_REG))
7255    (clobber (reg:SI R10_REG))
7256    (clobber (reg:SI PR_REG))]
7257   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7258   "jsr  @%0%#"
7259   [(set_attr "type" "call")
7260    (set (attr "fp_mode")
7261         (if_then_else (eq_attr "fpu_single" "yes")
7262                       (const_string "single") (const_string "double")))
7263    (set_attr "needs_delay_slot" "yes")])
7265 (define_insn "call_media"
7266   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7267          (match_operand 1 "" ""))
7268    (clobber (reg:DI PR_MEDIA_REG))]
7269   "TARGET_SHMEDIA"
7270   "blink        %0, r18"
7271   [(set_attr "type" "jump_media")])
7273 (define_insn "call_valuei"
7274   [(set (match_operand 0 "" "=rf")
7275         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7276               (match_operand 2 "" "")))
7277    (use (reg:PSI FPSCR_REG))
7278    (clobber (reg:SI PR_REG))]
7279   "TARGET_SH1"
7280   "*
7281    {
7282      if (TARGET_SH2A && (dbr_sequence_length () == 0))
7283         return \"jsr/n\\t@%1\";
7284      else
7285         return \"jsr\\t@%1%#\";
7286    }"
7287   [(set_attr "type" "call")
7288    (set (attr "fp_mode")
7289         (if_then_else (eq_attr "fpu_single" "yes")
7290                       (const_string "single") (const_string "double")))
7291    (set_attr "needs_delay_slot" "yes")
7292    (set_attr "fp_set" "unknown")])
7294 ;; This is TBR relative jump instruction for SH2A architecture.
7295 ;; Its use is enabled assigning an attribute "function_vector"
7296 ;; and the vector number to a function during its declaration.
7298 (define_insn "call_valuei_tbr_rel"
7299   [(set (match_operand 0 "" "=rf")
7300         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7301               (match_operand 2 "" "")))
7302    (use (reg:PSI FPSCR_REG))
7303    (clobber (reg:SI PR_REG))]
7304   "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])"
7305   "*
7307   unsigned HOST_WIDE_INT vect_num;
7308   vect_num = sh2a_get_function_vector_number (operands[1]);
7309   operands[3] = GEN_INT (vect_num * 4);
7311   return \"jsr/n\\t@@(%O3,tbr)\";
7313   [(set_attr "type" "call")
7314    (set (attr "fp_mode")
7315         (if_then_else (eq_attr "fpu_single" "yes")
7316                       (const_string "single") (const_string "double")))
7317    (set_attr "needs_delay_slot" "no")
7318    (set_attr "fp_set" "unknown")])
7320 (define_insn "call_valuei_pcrel"
7321   [(set (match_operand 0 "" "=rf")
7322         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7323               (match_operand 2 "" "")))
7324    (use (reg:PSI FPSCR_REG))
7325    (use (reg:SI PIC_REG))
7326    (use (match_operand 3 "" ""))
7327    (clobber (reg:SI PR_REG))]
7328   "TARGET_SH2"
7329   "bsrf %1\\n%O3:%#"
7330   [(set_attr "type" "call")
7331    (set (attr "fp_mode")
7332         (if_then_else (eq_attr "fpu_single" "yes")
7333                       (const_string "single") (const_string "double")))
7334    (set_attr "needs_delay_slot" "yes")
7335    (set_attr "fp_set" "unknown")])
7337 (define_insn_and_split "call_value_pcrel"
7338   [(set (match_operand 0 "" "=rf")
7339         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7340               (match_operand 2 "" "")))
7341    (use (reg:PSI FPSCR_REG))
7342    (use (reg:SI PIC_REG))
7343    (clobber (reg:SI PR_REG))
7344    (clobber (match_scratch:SI 3 "=r"))]
7345   "TARGET_SH2"
7346   "#"
7347   "reload_completed"
7348   [(const_int 0)]
7349   "
7351   rtx lab = PATTERN (gen_call_site ());
7353   if (SYMBOL_REF_LOCAL_P (operands[1]))
7354     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7355   else
7356     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7357   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7358                                          operands[2], copy_rtx (lab)));
7359   DONE;
7361   [(set_attr "type" "call")
7362    (set (attr "fp_mode")
7363         (if_then_else (eq_attr "fpu_single" "yes")
7364                       (const_string "single") (const_string "double")))
7365    (set_attr "needs_delay_slot" "yes")
7366    (set_attr "fp_set" "unknown")])
7368 (define_insn "call_value_compact"
7369   [(set (match_operand 0 "" "=rf")
7370         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7371               (match_operand 2 "" "")))
7372    (match_operand 3 "immediate_operand" "n")
7373    (use (reg:SI R0_REG))
7374    (use (reg:SI R1_REG))
7375    (use (reg:PSI FPSCR_REG))
7376    (clobber (reg:SI PR_REG))]
7377   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7378   "jsr  @%1%#"
7379   [(set_attr "type" "call")
7380    (set (attr "fp_mode")
7381         (if_then_else (eq_attr "fpu_single" "yes")
7382                       (const_string "single") (const_string "double")))
7383    (set_attr "needs_delay_slot" "yes")])
7385 (define_insn "call_value_compact_rettramp"
7386   [(set (match_operand 0 "" "=rf")
7387         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7388               (match_operand 2 "" "")))
7389    (match_operand 3 "immediate_operand" "n")
7390    (use (reg:SI R0_REG))
7391    (use (reg:SI R1_REG))
7392    (use (reg:PSI FPSCR_REG))
7393    (clobber (reg:SI R10_REG))
7394    (clobber (reg:SI PR_REG))]
7395   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7396   "jsr  @%1%#"
7397   [(set_attr "type" "call")
7398    (set (attr "fp_mode")
7399         (if_then_else (eq_attr "fpu_single" "yes")
7400                       (const_string "single") (const_string "double")))
7401    (set_attr "needs_delay_slot" "yes")])
7403 (define_insn "call_value_media"
7404   [(set (match_operand 0 "" "=rf")
7405         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7406               (match_operand 2 "" "")))
7407    (clobber (reg:DI PR_MEDIA_REG))]
7408   "TARGET_SHMEDIA"
7409   "blink        %1, r18"
7410   [(set_attr "type" "jump_media")])
7412 (define_expand "call"
7413   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7414                             (match_operand 1 "" ""))
7415               (match_operand 2 "" "")
7416               (use (reg:PSI FPSCR_REG))
7417               (clobber (reg:SI PR_REG))])]
7418   ""
7419   "
7421   if (TARGET_SHMEDIA)
7422     {
7423       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7424       emit_call_insn (gen_call_media (operands[0], operands[1]));
7425       DONE;
7426     }
7427   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7428     {
7429       rtx cookie_rtx = operands[2];
7430       long cookie = INTVAL (cookie_rtx);
7431       rtx func = XEXP (operands[0], 0);
7432       rtx r0, r1;
7434       if (flag_pic)
7435         {
7436           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7437             {
7438               rtx reg = gen_reg_rtx (Pmode);
7440               emit_insn (gen_symGOTPLT2reg (reg, func));
7441               func = reg;
7442             }
7443           else
7444             func = legitimize_pic_address (func, Pmode, 0);
7445         }
7447       r0 = gen_rtx_REG (SImode, R0_REG);
7448       r1 = gen_rtx_REG (SImode, R1_REG);
7450       /* Since such a call function may use all call-clobbered
7451          registers, we force a mode switch earlier, so that we don't
7452          run out of registers when adjusting fpscr for the call.  */
7453       emit_insn (gen_force_mode_for_call ());
7455       operands[0]
7456         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7457                            SFUNC_GOT);
7458       operands[0] = force_reg (SImode, operands[0]);
7460       emit_move_insn (r0, func);
7461       emit_move_insn (r1, cookie_rtx);
7463       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7464         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7465                                                    operands[2]));
7466       else
7467         emit_call_insn (gen_call_compact (operands[0], operands[1],
7468                                           operands[2]));
7470       DONE;
7471     }
7472   else if (TARGET_SHCOMPACT && flag_pic
7473            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7474            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7475     {
7476       rtx reg = gen_reg_rtx (Pmode);
7478       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7479       XEXP (operands[0], 0) = reg;
7480     }
7481   if (!flag_pic && TARGET_SH2A
7482       && MEM_P (operands[0])
7483       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7484     {
7485       if (sh2a_is_function_vector_call (XEXP (operands[0], 0)))
7486         {
7487           emit_call_insn (gen_calli_tbr_rel (XEXP (operands[0], 0),
7488                                              operands[1]));
7489           DONE;
7490         }
7491     }
7492   if (flag_pic && TARGET_SH2
7493       && MEM_P (operands[0])
7494       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7495     {
7496       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7497       DONE;
7498     }
7499   else
7500   {
7501     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7502     operands[1] = operands[2];
7503   }
7505   emit_call_insn (gen_calli (operands[0], operands[1]));
7506   DONE;
7509 (define_insn "call_pop_compact"
7510   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7511          (match_operand 1 "" ""))
7512    (match_operand 2 "immediate_operand" "n")
7513    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7514                                  (match_operand 3 "immediate_operand" "n")))
7515    (use (reg:SI R0_REG))
7516    (use (reg:SI R1_REG))
7517    (use (reg:PSI FPSCR_REG))
7518    (clobber (reg:SI PR_REG))]
7519   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7520   "jsr  @%0%#"
7521   [(set_attr "type" "call")
7522    (set (attr "fp_mode")
7523         (if_then_else (eq_attr "fpu_single" "yes")
7524                       (const_string "single") (const_string "double")))
7525    (set_attr "needs_delay_slot" "yes")])
7527 (define_insn "call_pop_compact_rettramp"
7528   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7529          (match_operand 1 "" ""))
7530    (match_operand 2 "immediate_operand" "n")
7531    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7532                                  (match_operand 3 "immediate_operand" "n")))
7533    (use (reg:SI R0_REG))
7534    (use (reg:SI R1_REG))
7535    (use (reg:PSI FPSCR_REG))
7536    (clobber (reg:SI R10_REG))
7537    (clobber (reg:SI PR_REG))]
7538   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7539   "jsr  @%0%#"
7540   [(set_attr "type" "call")
7541    (set (attr "fp_mode")
7542         (if_then_else (eq_attr "fpu_single" "yes")
7543                       (const_string "single") (const_string "double")))
7544    (set_attr "needs_delay_slot" "yes")])
7546 (define_expand "call_pop"
7547   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7548                     (match_operand 1 "" ""))
7549              (match_operand 2 "" "")
7550              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7551                                            (match_operand 3 "" "")))])]
7552   "TARGET_SHCOMPACT"
7553   "
7555   rtx cookie_rtx;
7556   long cookie;
7557   rtx func;
7558   rtx r0, r1;
7560   gcc_assert (operands[2] && INTVAL (operands[2]));
7561   cookie_rtx = operands[2];
7562   cookie = INTVAL (cookie_rtx);
7563   func = XEXP (operands[0], 0);
7565   if (flag_pic)
7566     {
7567       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7568         {
7569           rtx reg = gen_reg_rtx (Pmode);
7570           emit_insn (gen_symGOTPLT2reg (reg, func));
7571           func = reg;
7572         }
7573       else
7574         func = legitimize_pic_address (func, Pmode, 0);
7575     }
7577   r0 = gen_rtx_REG (SImode, R0_REG);
7578   r1 = gen_rtx_REG (SImode, R1_REG);
7580   /* Since such a call function may use all call-clobbered
7581      registers, we force a mode switch earlier, so that we don't
7582      run out of registers when adjusting fpscr for the call.  */
7583   emit_insn (gen_force_mode_for_call ());
7585   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7586                                  SFUNC_GOT);
7587   operands[0] = force_reg (SImode, operands[0]);
7589   emit_move_insn (r0, func);
7590   emit_move_insn (r1, cookie_rtx);
7592   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7593     emit_call_insn (gen_call_pop_compact_rettramp
7594                      (operands[0], operands[1], operands[2], operands[3]));
7595   else
7596     emit_call_insn (gen_call_pop_compact
7597                      (operands[0], operands[1], operands[2], operands[3]));
7599   DONE;
7602 (define_expand "call_value"
7603   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7604                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7605                                  (match_operand 2 "" "")))
7606               (match_operand 3 "" "")
7607               (use (reg:PSI FPSCR_REG))
7608               (clobber (reg:SI PR_REG))])]
7609   ""
7610   "
7612   if (TARGET_SHMEDIA)
7613     {
7614       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7615       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7616                                             operands[2]));
7617       DONE;
7618     }
7619   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7620     {
7621       rtx cookie_rtx = operands[3];
7622       long cookie = INTVAL (cookie_rtx);
7623       rtx func = XEXP (operands[1], 0);
7624       rtx r0, r1;
7626       if (flag_pic)
7627         {
7628           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7629             {
7630               rtx reg = gen_reg_rtx (Pmode);
7632               emit_insn (gen_symGOTPLT2reg (reg, func));
7633               func = reg;
7634             }
7635           else
7636             func = legitimize_pic_address (func, Pmode, 0);
7637         }
7639       r0 = gen_rtx_REG (SImode, R0_REG);
7640       r1 = gen_rtx_REG (SImode, R1_REG);
7642       /* Since such a call function may use all call-clobbered
7643          registers, we force a mode switch earlier, so that we don't
7644          run out of registers when adjusting fpscr for the call.  */
7645       emit_insn (gen_force_mode_for_call ());
7647       operands[1]
7648         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7649                            SFUNC_GOT);
7650       operands[1] = force_reg (SImode, operands[1]);
7652       emit_move_insn (r0, func);
7653       emit_move_insn (r1, cookie_rtx);
7655       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7656         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7657                                                          operands[1],
7658                                                          operands[2],
7659                                                          operands[3]));
7660       else
7661         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7662                                                 operands[2], operands[3]));
7664       DONE;
7665     }
7666   else if (TARGET_SHCOMPACT && flag_pic
7667            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7668            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7669     {
7670       rtx reg = gen_reg_rtx (Pmode);
7672       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7673       XEXP (operands[1], 0) = reg;
7674     }
7675   if (!flag_pic && TARGET_SH2A
7676       && MEM_P (operands[1])
7677       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7678     {
7679       if (sh2a_is_function_vector_call (XEXP (operands[1], 0)))
7680         {
7681           emit_call_insn (gen_call_valuei_tbr_rel (operands[0],
7682                                  XEXP (operands[1], 0), operands[2]));
7683           DONE;
7684         }
7685     }
7686   if (flag_pic && TARGET_SH2
7687       && MEM_P (operands[1])
7688       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7689     {
7690       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7691                                             operands[2]));
7692       DONE;
7693     }
7694   else
7695     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7697   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7698   DONE;
7701 (define_insn "sibcalli"
7702   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7703          (match_operand 1 "" ""))
7704    (use (reg:PSI FPSCR_REG))
7705    (return)]
7706   "TARGET_SH1"
7707   "jmp  @%0%#"
7708   [(set_attr "needs_delay_slot" "yes")
7709    (set (attr "fp_mode")
7710         (if_then_else (eq_attr "fpu_single" "yes")
7711                       (const_string "single") (const_string "double")))
7712    (set_attr "type" "jump_ind")])
7714 (define_insn "sibcalli_pcrel"
7715   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7716          (match_operand 1 "" ""))
7717    (use (match_operand 2 "" ""))
7718    (use (reg:PSI FPSCR_REG))
7719    (return)]
7720   "TARGET_SH2"
7721   "braf %0\\n%O2:%#"
7722   [(set_attr "needs_delay_slot" "yes")
7723    (set (attr "fp_mode")
7724         (if_then_else (eq_attr "fpu_single" "yes")
7725                       (const_string "single") (const_string "double")))
7726    (set_attr "type" "jump_ind")])
7728 ;; This uses an unspec to describe that the symbol_ref is very close.
7729 (define_insn "sibcalli_thunk"
7730   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7731                              UNSPEC_THUNK))
7732          (match_operand 1 "" ""))
7733    (use (reg:PSI FPSCR_REG))
7734    (return)]
7735   "TARGET_SH1"
7736   "bra  %O0"
7737   [(set_attr "needs_delay_slot" "yes")
7738    (set (attr "fp_mode")
7739         (if_then_else (eq_attr "fpu_single" "yes")
7740                       (const_string "single") (const_string "double")))
7741    (set_attr "type" "jump")
7742    (set_attr "length" "2")])
7744 (define_insn_and_split "sibcall_pcrel"
7745   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7746          (match_operand 1 "" ""))
7747    (use (reg:PSI FPSCR_REG))
7748    (clobber (match_scratch:SI 2 "=k"))
7749    (return)]
7750   "TARGET_SH2"
7751   "#"
7752   "reload_completed"
7753   [(const_int 0)]
7754   "
7756   rtx lab = PATTERN (gen_call_site ());
7757   rtx call_insn;
7759   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7760   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7761                                                   copy_rtx (lab)));
7762   SIBLING_CALL_P (call_insn) = 1;
7763   DONE;
7765   [(set_attr "needs_delay_slot" "yes")
7766    (set (attr "fp_mode")
7767         (if_then_else (eq_attr "fpu_single" "yes")
7768                       (const_string "single") (const_string "double")))
7769    (set_attr "type" "jump_ind")])
7771 (define_insn "sibcall_compact"
7772   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7773          (match_operand 1 "" ""))
7774    (return)
7775    (use (match_operand:SI 2 "register_operand" "z,x"))
7776    (use (reg:SI R1_REG))
7777    (use (reg:PSI FPSCR_REG))
7778    ;; We want to make sure the `x' above will only match MACH_REG
7779    ;; because sibcall_epilogue may clobber MACL_REG.
7780    (clobber (reg:SI MACL_REG))]
7781   "TARGET_SHCOMPACT"
7782   "@
7783         jmp     @%0%#
7784         jmp     @%0\\n  sts     %2, r0"
7785   [(set_attr "needs_delay_slot" "yes,no")
7786    (set_attr "length" "2,4")
7787    (set (attr "fp_mode") (const_string "single"))
7788    (set_attr "type" "jump_ind")])
7790 (define_insn "sibcall_media"
7791   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7792          (match_operand 1 "" ""))
7793    (use (reg:SI PR_MEDIA_REG))
7794    (return)]
7795   "TARGET_SHMEDIA"
7796   "blink        %0, r63"
7797   [(set_attr "type" "jump_media")])
7799 (define_expand "sibcall"
7800   [(parallel
7801     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7802            (match_operand 1 "" ""))
7803      (match_operand 2 "" "")
7804      (use (reg:PSI FPSCR_REG))
7805      (return)])]
7806   ""
7807   "
7809   if (TARGET_SHMEDIA)
7810     {
7811       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7812       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7813       DONE;
7814     }
7815   else if (TARGET_SHCOMPACT && operands[2]
7816            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7817     {
7818       rtx cookie_rtx = operands[2];
7819       long cookie = INTVAL (cookie_rtx);
7820       rtx func = XEXP (operands[0], 0);
7821       rtx mach, r1;
7823       if (flag_pic)
7824         {
7825           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7826             {
7827               rtx reg = gen_reg_rtx (Pmode);
7829               emit_insn (gen_symGOT2reg (reg, func));
7830               func = reg;
7831             }
7832           else
7833             func = legitimize_pic_address (func, Pmode, 0);
7834         }
7836       /* FIXME: if we could tell whether all argument registers are
7837          already taken, we could decide whether to force the use of
7838          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7839          simple way to tell.  We could use the CALL_COOKIE, but we
7840          can't currently tell a register used for regular argument
7841          passing from one that is unused.  If we leave it up to reload
7842          to decide which register to use, it seems to always choose
7843          R0_REG, which leaves no available registers in SIBCALL_REGS
7844          to hold the address of the trampoline.  */
7845       mach = gen_rtx_REG (SImode, MACH_REG);
7846       r1 = gen_rtx_REG (SImode, R1_REG);
7848       /* Since such a call function may use all call-clobbered
7849          registers, we force a mode switch earlier, so that we don't
7850          run out of registers when adjusting fpscr for the call.  */
7851       emit_insn (gen_force_mode_for_call ());
7853       operands[0]
7854         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7855                            SFUNC_GOT);
7856       operands[0] = force_reg (SImode, operands[0]);
7858       /* We don't need a return trampoline, since the callee will
7859          return directly to the upper caller.  */
7860       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7861         {
7862           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7863           cookie_rtx = GEN_INT (cookie);
7864         }
7866       emit_move_insn (mach, func);
7867       emit_move_insn (r1, cookie_rtx);
7869       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7870       DONE;
7871     }
7872   else if (TARGET_SHCOMPACT && flag_pic
7873            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7874            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7875     {
7876       rtx reg = gen_reg_rtx (Pmode);
7878       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7879       XEXP (operands[0], 0) = reg;
7880     }
7881   if (flag_pic && TARGET_SH2
7882       && MEM_P (operands[0])
7883       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7884       /* The PLT needs the PIC register, but the epilogue would have
7885          to restore it, so we can only use PC-relative PIC calls for
7886          static functions.  */
7887       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7888     {
7889       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7890       DONE;
7891     }
7892   else
7893     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7895   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7896   DONE;
7899 (define_insn "sibcall_valuei"
7900   [(set (match_operand 0 "" "=rf")
7901         (call (mem:SI (match_operand:SI 1 "register_operand" "k"))
7902               (match_operand 2 "" "")))
7903    (use (reg:PSI FPSCR_REG))
7904    (return)]
7905   "TARGET_SH1"
7906   "jmp  @%1%#"
7907   [(set_attr "needs_delay_slot" "yes")
7908    (set (attr "fp_mode")
7909         (if_then_else (eq_attr "fpu_single" "yes")
7910                       (const_string "single") (const_string "double")))
7911    (set_attr "type" "jump_ind")])
7913 (define_insn "sibcall_valuei_pcrel"
7914   [(set (match_operand 0 "" "=rf")
7915         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k"))
7916               (match_operand 2 "" "")))
7917    (use (match_operand 3 "" ""))
7918    (use (reg:PSI FPSCR_REG))
7919    (return)]
7920   "TARGET_SH2"
7921   "braf %1\\n%O3:%#"
7922   [(set_attr "needs_delay_slot" "yes")
7923    (set (attr "fp_mode")
7924         (if_then_else (eq_attr "fpu_single" "yes")
7925                       (const_string "single") (const_string "double")))
7926    (set_attr "type" "jump_ind")])
7928 (define_insn_and_split "sibcall_value_pcrel"
7929   [(set (match_operand 0 "" "=rf")
7930         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7931               (match_operand 2 "" "")))
7932    (use (reg:PSI FPSCR_REG))
7933    (clobber (match_scratch:SI 3 "=k"))
7934    (return)]
7935   "TARGET_SH2"
7936   "#"
7937   "reload_completed"
7938   [(const_int 0)]
7939   "
7941   rtx lab = PATTERN (gen_call_site ());
7942   rtx call_insn;
7944   emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7945   call_insn = emit_call_insn (gen_sibcall_valuei_pcrel (operands[0],
7946                                                         operands[3],
7947                                                         operands[2],
7948                                                         copy_rtx (lab)));
7949   SIBLING_CALL_P (call_insn) = 1;
7950   DONE;
7952   [(set_attr "needs_delay_slot" "yes")
7953    (set (attr "fp_mode")
7954         (if_then_else (eq_attr "fpu_single" "yes")
7955                       (const_string "single") (const_string "double")))
7956    (set_attr "type" "jump_ind")])
7958 (define_insn "sibcall_value_compact"
7959   [(set (match_operand 0 "" "=rf,rf")
7960         (call (mem:SI (match_operand:SI 1 "register_operand" "k,k"))
7961               (match_operand 2 "" "")))
7962    (return)
7963    (use (match_operand:SI 3 "register_operand" "z,x"))
7964    (use (reg:SI R1_REG))
7965    (use (reg:PSI FPSCR_REG))
7966    ;; We want to make sure the `x' above will only match MACH_REG
7967    ;; because sibcall_epilogue may clobber MACL_REG.
7968    (clobber (reg:SI MACL_REG))]
7969   "TARGET_SHCOMPACT"
7970   "@
7971         jmp     @%1%#
7972         jmp     @%1\\n  sts     %3, r0"
7973   [(set_attr "needs_delay_slot" "yes,no")
7974    (set_attr "length" "2,4")
7975    (set (attr "fp_mode") (const_string "single"))
7976    (set_attr "type" "jump_ind")])
7978 (define_insn "sibcall_value_media"
7979   [(set (match_operand 0 "" "=rf")
7980         (call (mem:DI (match_operand 1 "target_reg_operand" "k"))
7981               (match_operand 2 "" "")))
7982    (use (reg:SI PR_MEDIA_REG))
7983    (return)]
7984   "TARGET_SHMEDIA"
7985   "blink        %1, r63"
7986   [(set_attr "type" "jump_media")])
7988 (define_expand "sibcall_value"
7989   [(parallel
7990     [(set (match_operand 0 "arith_reg_operand" "")
7991           (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7992                 (match_operand 2 "" "")))
7993      (match_operand 3 "" "")
7994      (use (reg:PSI FPSCR_REG))
7995      (return)])]
7996   ""
7997   "
7999   if (TARGET_SHMEDIA)
8000     {
8001       operands[1] = shmedia_prepare_call_address (operands[1], 1);
8002       emit_call_insn (gen_sibcall_value_media (operands[0], operands[1],
8003                                                operands[2]));
8004       DONE;
8005     }
8006   else if (TARGET_SHCOMPACT && operands[3]
8007            && (INTVAL (operands[3]) & ~ CALL_COOKIE_RET_TRAMP (1)))
8008     {
8009       rtx cookie_rtx = operands[3];
8010       long cookie = INTVAL (cookie_rtx);
8011       rtx func = XEXP (operands[1], 0);
8012       rtx mach, r1;
8014       if (flag_pic)
8015         {
8016           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8017             {
8018               rtx reg = gen_reg_rtx (Pmode);
8020               emit_insn (gen_symGOT2reg (reg, func));
8021               func = reg;
8022             }
8023           else
8024             func = legitimize_pic_address (func, Pmode, 0);
8025         }
8027       /* FIXME: if we could tell whether all argument registers are
8028          already taken, we could decide whether to force the use of
8029          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
8030          simple way to tell.  We could use the CALL_COOKIE, but we
8031          can't currently tell a register used for regular argument
8032          passing from one that is unused.  If we leave it up to reload
8033          to decide which register to use, it seems to always choose
8034          R0_REG, which leaves no available registers in SIBCALL_REGS
8035          to hold the address of the trampoline.  */
8036       mach = gen_rtx_REG (SImode, MACH_REG);
8037       r1 = gen_rtx_REG (SImode, R1_REG);
8039       /* Since such a call function may use all call-clobbered
8040          registers, we force a mode switch earlier, so that we don't
8041          run out of registers when adjusting fpscr for the call.  */
8042       emit_insn (gen_force_mode_for_call ());
8044       operands[1]
8045         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8046                            SFUNC_GOT);
8047       operands[1] = force_reg (SImode, operands[1]);
8049       /* We don't need a return trampoline, since the callee will
8050          return directly to the upper caller.  */
8051       if (cookie & CALL_COOKIE_RET_TRAMP (1))
8052         {
8053           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
8054           cookie_rtx = GEN_INT (cookie);
8055         }
8057       emit_move_insn (mach, func);
8058       emit_move_insn (r1, cookie_rtx);
8060       emit_call_insn (gen_sibcall_value_compact (operands[0], operands[1],
8061                                                  operands[2], mach));
8062       DONE;
8063     }
8064   else if (TARGET_SHCOMPACT && flag_pic
8065            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8066            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8067     {
8068       rtx reg = gen_reg_rtx (Pmode);
8070       emit_insn (gen_symGOT2reg (reg, XEXP (operands[1], 0)));
8071       XEXP (operands[1], 0) = reg;
8072     }
8073   if (flag_pic && TARGET_SH2
8074       && MEM_P (operands[1])
8075       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
8076       /* The PLT needs the PIC register, but the epilogue would have
8077          to restore it, so we can only use PC-relative PIC calls for
8078          static functions.  */
8079       && SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
8080     {
8081       emit_call_insn (gen_sibcall_value_pcrel (operands[0],
8082                                                XEXP (operands[1], 0),
8083                                                operands[2]));
8084       DONE;
8085     }
8086   else
8087     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
8089   emit_call_insn (gen_sibcall_valuei (operands[0], operands[1], operands[2]));
8090   DONE;
8093 (define_insn "call_value_pop_compact"
8094   [(set (match_operand 0 "" "=rf")
8095         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8096               (match_operand 2 "" "")))
8097    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8098                                  (match_operand 4 "immediate_operand" "n")))
8099    (match_operand 3 "immediate_operand" "n")
8100    (use (reg:SI R0_REG))
8101    (use (reg:SI R1_REG))
8102    (use (reg:PSI FPSCR_REG))
8103    (clobber (reg:SI PR_REG))]
8104   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8105   "jsr  @%1%#"
8106   [(set_attr "type" "call")
8107    (set (attr "fp_mode")
8108         (if_then_else (eq_attr "fpu_single" "yes")
8109                       (const_string "single") (const_string "double")))
8110    (set_attr "needs_delay_slot" "yes")])
8112 (define_insn "call_value_pop_compact_rettramp"
8113   [(set (match_operand 0 "" "=rf")
8114         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
8115               (match_operand 2 "" "")))
8116    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8117                                  (match_operand 4 "immediate_operand" "n")))
8118    (match_operand 3 "immediate_operand" "n")
8119    (use (reg:SI R0_REG))
8120    (use (reg:SI R1_REG))
8121    (use (reg:PSI FPSCR_REG))
8122    (clobber (reg:SI R10_REG))
8123    (clobber (reg:SI PR_REG))]
8124   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
8125   "jsr  @%1%#"
8126   [(set_attr "type" "call")
8127    (set (attr "fp_mode")
8128         (if_then_else (eq_attr "fpu_single" "yes")
8129                       (const_string "single") (const_string "double")))
8130    (set_attr "needs_delay_slot" "yes")])
8132 (define_expand "call_value_pop"
8133   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
8134                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
8135                                  (match_operand 2 "" "")))
8136               (match_operand 3 "" "")
8137               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
8138                                             (match_operand 4 "" "")))])]
8139   "TARGET_SHCOMPACT"
8140   "
8142   rtx cookie_rtx;
8143   long cookie;
8144   rtx func;
8145   rtx r0, r1;
8147   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
8148   cookie_rtx = operands[3];
8149   cookie = INTVAL (cookie_rtx);
8150   func = XEXP (operands[1], 0);
8152   if (flag_pic)
8153     {
8154       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
8155         {
8156           rtx reg = gen_reg_rtx (Pmode);
8158           emit_insn (gen_symGOTPLT2reg (reg, func));
8159           func = reg;
8160         }
8161       else
8162         func = legitimize_pic_address (func, Pmode, 0);
8163     }
8165   r0 = gen_rtx_REG (SImode, R0_REG);
8166   r1 = gen_rtx_REG (SImode, R1_REG);
8168   /* Since such a call function may use all call-clobbered
8169      registers, we force a mode switch earlier, so that we don't
8170      run out of registers when adjusting fpscr for the call.  */
8171   emit_insn (gen_force_mode_for_call ());
8173   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
8174                                  SFUNC_GOT);
8175   operands[1] = force_reg (SImode, operands[1]);
8177   emit_move_insn (r0, func);
8178   emit_move_insn (r1, cookie_rtx);
8180   if (cookie & CALL_COOKIE_RET_TRAMP (1))
8181     emit_call_insn (gen_call_value_pop_compact_rettramp
8182                         (operands[0], operands[1], operands[2],
8183                          operands[3], operands[4]));
8184   else
8185     emit_call_insn (gen_call_value_pop_compact
8186                         (operands[0], operands[1], operands[2],
8187                          operands[3], operands[4]));
8189   DONE;
8192 (define_expand "sibcall_epilogue"
8193   [(return)]
8194   ""
8195   "
8197   sh_expand_epilogue (1);
8198   if (TARGET_SHCOMPACT)
8199     {
8200       rtx insn, set;
8202       /* If epilogue clobbers r0, preserve it in macl.  */
8203       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8204         if ((set = single_set (insn))
8205             && REG_P (SET_DEST (set))
8206             && REGNO (SET_DEST (set)) == R0_REG)
8207           {
8208             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8209             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8211             /* We can't tell at this point whether the sibcall is a
8212                sibcall_compact and, if it is, whether it uses r0 or
8213                mach as operand 2, so let the instructions that
8214                preserve r0 be optimized away if r0 turns out to be
8215                dead.  */
8216             emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8217             emit_move_insn (r0, tmp);
8218             break;
8219           }
8220     }
8221   DONE;
8224 (define_insn "indirect_jump_compact"
8225   [(set (pc)
8226         (match_operand:SI 0 "arith_reg_operand" "r"))]
8227   "TARGET_SH1"
8228   "jmp  @%0%#"
8229   [(set_attr "needs_delay_slot" "yes")
8230    (set_attr "type" "jump_ind")])
8232 (define_expand "indirect_jump"
8233   [(set (pc)
8234         (match_operand 0 "register_operand" ""))]
8235   ""
8236   "
8238   if (GET_MODE (operands[0]) != Pmode)
8239     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8242 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8243 ;; which can be present in structured code from indirect jumps which can not
8244 ;; be present in structured code.  This allows -fprofile-arcs to work.
8246 ;; For SH1 processors.
8247 (define_insn "casesi_jump_1"
8248   [(set (pc)
8249         (match_operand:SI 0 "register_operand" "r"))
8250    (use (label_ref (match_operand 1 "" "")))]
8251   "TARGET_SH1"
8252   "jmp  @%0%#"
8253   [(set_attr "needs_delay_slot" "yes")
8254    (set_attr "type" "jump_ind")])
8256 ;; For all later processors.
8257 (define_insn "casesi_jump_2"
8258   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8259                       (label_ref (match_operand 1 "" ""))))
8260    (use (label_ref (match_operand 2 "" "")))]
8261   "TARGET_SH2
8262    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8263   "braf %0%#"
8264   [(set_attr "needs_delay_slot" "yes")
8265    (set_attr "type" "jump_ind")])
8267 (define_insn "casesi_jump_media"
8268   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8269    (use (label_ref (match_operand 1 "" "")))]
8270   "TARGET_SHMEDIA"
8271   "blink        %0, r63"
8272   [(set_attr "type" "jump_media")])
8274 ;; Call subroutine returning any type.
8275 ;; ??? This probably doesn't work.
8277 (define_expand "untyped_call"
8278   [(parallel [(call (match_operand 0 "" "")
8279                     (const_int 0))
8280               (match_operand 1 "" "")
8281               (match_operand 2 "" "")])]
8282   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8283   "
8285   int i;
8287   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8289   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8290     {
8291       rtx set = XVECEXP (operands[2], 0, i);
8292       emit_move_insn (SET_DEST (set), SET_SRC (set));
8293     }
8295   /* The optimizer does not know that the call sets the function value
8296      registers we stored in the result block.  We avoid problems by
8297      claiming that all hard registers are used and clobbered at this
8298      point.  */
8299   emit_insn (gen_blockage ());
8301   DONE;
8304 ;; ------------------------------------------------------------------------
8305 ;; Misc insns
8306 ;; ------------------------------------------------------------------------
8308 (define_insn "dect"
8309   [(set (reg:SI T_REG)
8310         (eq:SI (match_operand:SI 1 "arith_reg_dest" "0") (const_int 1)))
8311    (set (match_operand:SI 0 "arith_reg_dest" "=r")
8312         (plus:SI (match_dup 1) (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 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   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;
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   emit_move_insn (operands[0], gen_rtx_PLUS (Pmode, t, operands[2]));
8697   DONE;
8700 (define_expand "sym2GOTTPOFF"
8701   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8702   ""
8703   "")
8705 (define_insn "tls_initial_exec"
8706   [(set (match_operand:SI 0 "register_operand" "=&r")
8707         (unspec:SI [(match_operand:SI 1 "" "")]
8708                     UNSPEC_TLSIE))
8709    (use (reg:SI GBR_REG))
8710    (use (reg:SI PIC_REG))
8711    (clobber (reg:SI R0_REG))]
8712   ""
8713   "*
8715   return \"\\
8716 mov.l\\t1f,r0\\n\\
8717 \\tstc\\tgbr,%0\\n\\
8718 \\tmov.l\\t@(r0,r12),r0\\n\\
8719 \\tbra\\t2f\\n\\
8720 \\tadd\\tr0,%0\\n\\
8721 \\t.align\\t2\\n\\
8722 1:\\t.long\\t%a1\\n\\
8723 2:\";
8725   [(set_attr "type" "tls_load")
8726    (set_attr "length" "16")])
8728 (define_expand "sym2TPOFF"
8729   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8730   ""
8731   "")
8733 (define_expand "symTPOFF2reg"
8734   [(match_operand 0 "" "") (match_operand 1 "" "")]
8735   ""
8736   "
8738   rtx tpoffsym;
8740   tpoffsym = gen_sym2TPOFF (operands[1]);
8741   PUT_MODE (tpoffsym, Pmode);
8742   emit_move_insn (operands[0], tpoffsym);
8743   DONE;
8746 (define_insn "load_gbr"
8747   [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
8748    (use (reg:SI GBR_REG))]
8749   ""
8750   "stc  gbr,%0"
8751   [(set_attr "type" "tls_load")])
8753 ;; case instruction for switch statements.
8755 ;; Operand 0 is index
8756 ;; operand 1 is the minimum bound
8757 ;; operand 2 is the maximum bound - minimum bound + 1
8758 ;; operand 3 is CODE_LABEL for the table;
8759 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8761 (define_expand "casesi"
8762   [(match_operand:SI 0 "arith_reg_operand" "")
8763    (match_operand:SI 1 "arith_reg_operand" "")
8764    (match_operand:SI 2 "arith_reg_operand" "")
8765    (match_operand 3 "" "") (match_operand 4 "" "")]
8766   ""
8767   "
8769   rtx reg = gen_reg_rtx (SImode);
8770   rtx reg2 = gen_reg_rtx (SImode);
8771   if (TARGET_SHMEDIA)
8772     {
8773       rtx reg = gen_reg_rtx (DImode);
8774       rtx reg2 = gen_reg_rtx (DImode);
8775       rtx reg3 = gen_reg_rtx (Pmode);
8776       rtx reg4 = gen_reg_rtx (Pmode);
8777       rtx reg5 = gen_reg_rtx (Pmode);
8778       rtx load, test;
8780       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8781       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8782       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8784       test = gen_rtx_GT (VOIDmode, operands[1], operands[0]);
8785       emit_jump_insn (gen_cbranchdi4 (test, operands[1], operands[0], operands[4]));
8786       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8787       test = gen_rtx_GTU (VOIDmode, reg, operands[2]);
8788       emit_jump_insn (gen_cbranchdi4 (test, reg, operands[2], operands[4]));
8789       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8790       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8791                                                (Pmode, operands[3])));
8792       /* Messy: can we subreg to clean this up? */
8793       if (Pmode == DImode)
8794         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8795       else
8796         load = gen_casesi_load_media (reg4,
8797                                       gen_rtx_SUBREG (DImode, reg3, 0),
8798                                       reg2, operands[3]);
8799       PUT_MODE (SET_SRC (load), Pmode);
8800       emit_insn (load);
8801       /* ??? The following add could be eliminated if we used ptrel.  */
8802       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8803       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8804       emit_barrier ();
8805       DONE;
8806     }
8807   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8808   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8809   /* If optimizing, casesi_worker depends on the mode of the instruction
8810      before label it 'uses' - operands[3].  */
8811   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8812                            reg));
8813   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8814   if (TARGET_SH2)
8815     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8816   else
8817     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8818   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8819      operands[3], but to lab.  We will fix this up in
8820      machine_dependent_reorg.  */
8821   emit_barrier ();
8822   DONE;
8825 (define_expand "casesi_0"
8826   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8827    (set (match_dup 4) (minus:SI (match_dup 4)
8828                                 (match_operand:SI 1 "arith_operand" "")))
8829    (set (reg:SI T_REG)
8830         (gtu:SI (match_dup 4)
8831                 (match_operand:SI 2 "arith_reg_operand" "")))
8832    (set (pc)
8833         (if_then_else (ne (reg:SI T_REG)
8834                           (const_int 0))
8835                       (label_ref (match_operand 3 "" ""))
8836                       (pc)))]
8837   "TARGET_SH1"
8838   "")
8840 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8841 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8842 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8844 (define_insn "casesi_worker_0"
8845   [(set (match_operand:SI 0 "register_operand" "=r,r")
8846         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8847                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8848    (clobber (match_scratch:SI 3 "=X,1"))
8849    (clobber (match_scratch:SI 4 "=&z,z"))]
8850   "TARGET_SH1"
8851   "#")
8853 (define_split
8854   [(set (match_operand:SI 0 "register_operand" "")
8855         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8856                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8857    (clobber (match_scratch:SI 3 ""))
8858    (clobber (match_scratch:SI 4 ""))]
8859   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8860   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8861    (parallel [(set (match_dup 0)
8862               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8863                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8864               (clobber (match_dup 3))])
8865    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8866   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8868 (define_split
8869   [(set (match_operand:SI 0 "register_operand" "")
8870         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8871                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8872    (clobber (match_scratch:SI 3 ""))
8873    (clobber (match_scratch:SI 4 ""))]
8874   "TARGET_SH2 && reload_completed"
8875   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8876    (parallel [(set (match_dup 0)
8877               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8878                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8879               (clobber (match_dup 3))])]
8880   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8882 (define_insn "casesi_worker_1"
8883   [(set (match_operand:SI 0 "register_operand" "=r,r")
8884         (unspec:SI [(reg:SI R0_REG)
8885                     (match_operand:SI 1 "register_operand" "0,r")
8886                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8887    (clobber (match_scratch:SI 3 "=X,1"))]
8888   "TARGET_SH1"
8889   "*
8891   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8893   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8895   switch (GET_MODE (diff_vec))
8896     {
8897     case SImode:
8898       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8899     case HImode:
8900       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8901     case QImode:
8902       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8903         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8904       return \"mov.b    @(r0,%1),%0\";
8905     default:
8906       gcc_unreachable ();
8907     }
8909   [(set_attr "length" "4")])
8911 (define_insn "casesi_worker_2"
8912   [(set (match_operand:SI 0 "register_operand" "=r,r")
8913         (unspec:SI [(reg:SI R0_REG)
8914                     (match_operand:SI 1 "register_operand" "0,r")
8915                     (label_ref (match_operand 2 "" ""))
8916                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8917    (clobber (match_operand:SI 4 "" "=X,1"))]
8918   "TARGET_SH2 && reload_completed && flag_pic"
8919   "*
8921   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8922   const char *load;
8924   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8926   switch (GET_MODE (diff_vec))
8927     {
8928     case SImode:
8929       output_asm_insn (\"shll2    %1\", operands);
8930       load = \"mov.l    @(r0,%1),%0\"; break;
8931     case HImode:
8932       output_asm_insn (\"add    %1,%1\", operands);
8933       load = \"mov.w    @(r0,%1),%0\"; break;
8934     case QImode:
8935       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8936         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8937       else
8938         load = \"mov.b  @(r0,%1),%0\";
8939       break;
8940     default:
8941       gcc_unreachable ();
8942     }
8943   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8944   return load;
8946   [(set_attr "length" "8")])
8948 (define_insn "casesi_shift_media"
8949   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8950         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8951                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8952                     UNSPEC_CASESI)))]
8953   "TARGET_SHMEDIA"
8954   "*
8956   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8958   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8960   switch (GET_MODE (diff_vec))
8961     {
8962     case SImode:
8963       return \"shlli    %1, 2, %0\";
8964     case HImode:
8965       return \"shlli    %1, 1, %0\";
8966     case QImode:
8967       if (rtx_equal_p (operands[0], operands[1]))
8968         return \"\";
8969       return \"add      %1, r63, %0\";
8970     default:
8971       gcc_unreachable ();
8972     }
8974   [(set_attr "type" "arith_media")])
8976 (define_insn "casesi_load_media"
8977   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8978         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8979                          (match_operand:DI 2 "arith_reg_operand" "r")
8980                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8981   "TARGET_SHMEDIA"
8982   "*
8984   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8986   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8988   switch (GET_MODE (diff_vec))
8989     {
8990     case SImode:
8991       return \"ldx.l    %1, %2, %0\";
8992     case HImode:
8993 #if 0
8994       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8995         return \"ldx.uw %1, %2, %0\";
8996 #endif
8997       return \"ldx.w    %1, %2, %0\";
8998     case QImode:
8999       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
9000         return \"ldx.ub %1, %2, %0\";
9001       return \"ldx.b    %1, %2, %0\";
9002     default:
9003       gcc_unreachable ();
9004     }
9006   [(set_attr "type" "load_media")])
9008 (define_expand "return"
9009   [(return)]
9010   "reload_completed && ! sh_need_epilogue ()"
9011   "
9013   if (TARGET_SHMEDIA)
9014     {
9015       emit_jump_insn (gen_return_media ());
9016       DONE;
9017     }
9019   if (TARGET_SHCOMPACT
9020       && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
9021     {
9022       emit_jump_insn (gen_shcompact_return_tramp ());
9023       DONE;
9024     }
9027 (define_insn "*return_i"
9028   [(return)]
9029   "TARGET_SH1 && ! (TARGET_SHCOMPACT
9030                     && (crtl->args.info.call_cookie
9031                         & CALL_COOKIE_RET_TRAMP (1)))
9032    && reload_completed
9033    && lookup_attribute (\"trap_exit\",
9034                         DECL_ATTRIBUTES (current_function_decl)) == NULL_TREE"
9035   "*
9036   {
9037     if (TARGET_SH2A && (dbr_sequence_length () == 0)
9038                         && !current_function_interrupt)
9039        return \"rts/n\";
9040     else
9041        return \"%@      %#\";
9042   }"
9043   [(set_attr "type" "return")
9044    (set_attr "needs_delay_slot" "yes")])
9046 ;; trapa has no delay slot.
9047 (define_insn "*return_trapa"
9048   [(return)]
9049   "TARGET_SH1 && !TARGET_SHCOMPACT
9050    && reload_completed"
9051   "%@"
9052   [(set_attr "type" "return")])
9054 (define_expand "shcompact_return_tramp"
9055   [(return)]
9056   "TARGET_SHCOMPACT
9057    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9058   "
9060   rtx reg = gen_rtx_REG (Pmode, R0_REG);
9062   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
9063   emit_jump_insn (gen_shcompact_return_tramp_i ());
9064   DONE;
9067 (define_insn "shcompact_return_tramp_i"
9068   [(parallel [(return) (use (reg:SI R0_REG))])]
9069   "TARGET_SHCOMPACT
9070    && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
9071   "jmp  @r0%#"
9072   [(set_attr "type" "jump_ind")
9073    (set_attr "needs_delay_slot" "yes")])
9075 (define_insn "return_media_i"
9076   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
9077   "TARGET_SHMEDIA && reload_completed"
9078   "blink        %0, r63"
9079   [(set_attr "type" "jump_media")])
9081 (define_insn "return_media_rte"
9082   [(return)]
9083   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
9084   "rte"
9085   [(set_attr "type" "jump_media")])
9087 (define_expand "return_media"
9088   [(return)]
9089   "TARGET_SHMEDIA && reload_completed"
9090   "
9092   int tr_regno = sh_media_register_for_return ();
9093   rtx tr;
9095   if (current_function_interrupt)
9096     {
9097       emit_jump_insn (gen_return_media_rte ());
9098       DONE;
9099     }
9100   if (tr_regno < 0)
9101     {
9102       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
9104       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
9105       tr_regno = TR0_REG;
9106       tr = gen_rtx_REG (Pmode, tr_regno);
9107       emit_move_insn (tr, r18);
9108     }
9109   else
9110     tr = gen_rtx_REG (Pmode, tr_regno);
9112   emit_jump_insn (gen_return_media_i (tr));
9113   DONE;
9116 (define_insn "shcompact_preserve_incoming_args"
9117   [(set (match_operand:SI 0 "register_operand" "+r")
9118         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
9119   "TARGET_SHCOMPACT"
9120   ""
9121   [(set_attr "length" "0")])
9123 (define_insn "shcompact_incoming_args"
9124   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
9125    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
9126    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
9127    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
9128    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
9129    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
9130    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
9131    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
9132    (set (mem:BLK (reg:SI MACL_REG))
9133         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
9134    (use (reg:SI R0_REG))
9135    (clobber (reg:SI R0_REG))
9136    (clobber (reg:SI MACL_REG))
9137    (clobber (reg:SI MACH_REG))
9138    (clobber (reg:SI PR_REG))]
9139   "TARGET_SHCOMPACT"
9140   "jsr  @r0%#"
9141   [(set_attr "needs_delay_slot" "yes")])
9143 (define_insn "shmedia_save_restore_regs_compact"
9144   [(set (reg:SI SP_REG)
9145         (plus:SI (reg:SI SP_REG)
9146                  (match_operand:SI 0 "immediate_operand" "i")))
9147    (use (reg:SI R0_REG))
9148    (clobber (reg:SI PR_REG))]
9149   "TARGET_SHCOMPACT
9150    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
9151        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
9152   "jsr @r0%#"
9153   [(set_attr "needs_delay_slot" "yes")])
9155 (define_expand "prologue"
9156   [(const_int 0)]
9157   ""
9158   "sh_expand_prologue (); DONE;")
9160 (define_expand "epilogue"
9161   [(return)]
9162   ""
9163   "
9165   sh_expand_epilogue (0);
9166   emit_jump_insn (gen_return ());
9167   DONE;
9170 (define_expand "eh_return"
9171   [(use (match_operand 0 "register_operand" ""))]
9172   ""
9174   rtx ra = operands[0];
9176   if (TARGET_SHMEDIA64)
9177     emit_insn (gen_eh_set_ra_di (ra));
9178   else
9179     emit_insn (gen_eh_set_ra_si (ra));
9181   DONE;
9184 ;; Clobber the return address on the stack.  We can't expand this
9185 ;; until we know where it will be put in the stack frame.
9187 (define_insn "eh_set_ra_si"
9188   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
9189       UNSPECV_EH_RETURN)
9190    (clobber (match_scratch:SI 1 "=&r"))]
9191   "! TARGET_SHMEDIA64"
9192   "#")
9194 (define_insn "eh_set_ra_di"
9195   [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
9196       UNSPECV_EH_RETURN)
9197    (clobber (match_scratch:DI 1 "=&r"))]
9198   "TARGET_SHMEDIA64"
9199   "#")
9201 (define_split
9202   [(unspec_volatile [(match_operand 0 "register_operand" "")]
9203       UNSPECV_EH_RETURN)
9204    (clobber (match_scratch 1 ""))]
9205   "reload_completed"
9206   [(const_int 0)]
9207   "
9209   sh_set_return_address (operands[0], operands[1]);
9210   DONE;
9213 (define_insn "blockage"
9214   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9215   ""
9216   ""
9217   [(set_attr "length" "0")])
9219 ;; Define movml instructions for SH2A target.  Currently they are
9220 ;; used to push and pop all banked registers only.
9222 (define_insn "movml_push_banked"
9223   [(set (match_operand:SI 0 "register_operand" "=r")
9224           (plus (match_dup 0) (const_int -32)))
9225    (set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
9226    (set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
9227    (set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
9228    (set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
9229    (set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
9230    (set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
9231    (set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
9232    (set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
9233   "TARGET_SH2A && REGNO (operands[0]) == 15"
9234   "movml.l\tr7,@-r15"
9235   [(set_attr "in_delay_slot" "no")])
9237 (define_insn "movml_pop_banked"
9238   [(set (match_operand:SI 0 "register_operand" "=r")
9239           (plus (match_dup 0) (const_int 32)))
9240    (set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
9241    (set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
9242    (set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
9243    (set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
9244    (set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
9245    (set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
9246    (set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
9247    (set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
9248   "TARGET_SH2A && REGNO (operands[0]) == 15"
9249   "movml.l\t@r15+,r7"
9250   [(set_attr "in_delay_slot" "no")])
9252 ;; ------------------------------------------------------------------------
9253 ;; Scc instructions
9254 ;; ------------------------------------------------------------------------
9256 (define_insn "movt"
9257   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
9258         (eq:SI (reg:SI T_REG) (const_int 1)))]
9259   "TARGET_SH1"
9260   "movt %0"
9261   [(set_attr "type" "arith")])
9263 (define_expand "cstore4_media"
9264   [(set (match_operand:SI 0 "register_operand" "=r")
9265         (match_operator:SI 1 "sh_float_comparison_operator"
9266          [(match_operand 2 "logical_operand" "")
9267           (match_operand 3 "cmp_operand" "")]))]
9268   "TARGET_SHMEDIA"
9269   "
9271   enum machine_mode mode = GET_MODE (operands[2]);
9272   enum rtx_code code = GET_CODE (operands[1]);
9273   bool invert, swap;
9274   if (mode == VOIDmode)
9275     mode = GET_MODE (operands[3]);
9276   if (operands[2] == const0_rtx)
9277     {
9278       if (code == EQ || code == NE)
9279         operands[2] = operands[3], operands[3] = const0_rtx;
9280     }
9281   else
9282     operands[2] = force_reg (mode, operands[2]);
9283   if (operands[3] != const0_rtx)
9284     operands[3] = force_reg (mode, operands[3]);
9286   switch (code)
9287     {
9288     case GEU:
9289     case GE:
9290       swap = invert = !FLOAT_MODE_P (mode);
9291       break;
9293     case LEU:
9294     case LE:
9295       swap = FLOAT_MODE_P (mode), invert = !swap;
9296       break;
9298     case LTU:
9299     case LT:
9300       swap = true, invert = false;
9301       break;
9303     case GTU:
9304     case GT:
9305     case EQ:
9306     case UNORDERED:
9307       swap = invert = false;
9308       break;
9310     case NE:
9311       swap = invert = true;
9312       break;
9314     default:
9315       gcc_unreachable ();
9316   }
9318   if (swap)
9319     {
9320       rtx tem = operands[2];
9321       operands[2] = operands[3];
9322       operands[3] = tem;
9323       code = swap_condition (code);
9324     }
9326   if (invert)
9327     {
9328       rtx tem = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];
9329       code = reverse_condition (code);
9330       operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9331       emit_insn (gen_cstore4_media (tem, operands[1],
9332                                     operands[2], operands[3]));
9333       code = EQ;
9334       operands[2] = tem;
9335       operands[3] = const0_rtx;
9336     }
9338   operands[1] = gen_rtx_fmt_ee (code, VOIDmode, operands[2], operands[3]);
9341 (define_expand "cstoresi4"
9342   [(set (match_operand:SI 0 "register_operand" "=r")
9343         (match_operator:SI 1 "comparison_operator"
9344          [(match_operand:SI 2 "cmpsi_operand" "")
9345           (match_operand:SI 3 "arith_operand" "")]))]
9346   "TARGET_SH1 || TARGET_SHMEDIA"
9347   "if (TARGET_SHMEDIA)
9348     {
9349       emit_insn (gen_cstore4_media (operands[0], operands[1],
9350                                     operands[2], operands[3]));
9351       DONE;
9352     }
9354    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9355        && sh_expand_t_scc (operands))
9356      DONE;
9358    if (! currently_expanding_to_rtl)
9359      FAIL;
9360    
9361    sh_emit_compare_and_set (operands, SImode);
9362    DONE;
9365 (define_expand "cstoredi4"
9366   [(set (match_operand:SI 0 "register_operand" "=r")
9367         (match_operator:SI 1 "comparison_operator"
9368          [(match_operand:DI 2 "arith_operand" "")
9369           (match_operand:DI 3 "arith_operand" "")]))]
9370   "TARGET_SH2 || TARGET_SHMEDIA"
9371   "if (TARGET_SHMEDIA)
9372     {
9373       emit_insn (gen_cstore4_media (operands[0], operands[1],
9374                                     operands[2], operands[3]));
9375       DONE;
9376     }
9378    if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
9379        && sh_expand_t_scc (operands))
9380      DONE;
9382    if (! currently_expanding_to_rtl)
9383      FAIL;
9384    
9385    sh_emit_compare_and_set (operands, DImode);
9386    DONE;
9391 ;; sne moves the complement of the T reg to DEST like this:
9392 ;;      cmp/eq ...
9393 ;;      mov    #-1,temp
9394 ;;      negc   temp,dest
9395 ;;   This is better than xoring compare result with 1 because it does
9396 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9397 ;;   loop.
9399 (define_expand "movnegt"
9400   [(set (match_dup 1) (const_int -1))
9401    (parallel [(set (match_operand:SI 0 "" "")
9402                    (neg:SI (plus:SI (reg:SI T_REG)
9403                                     (match_dup 1))))
9404               (set (reg:SI T_REG)
9405                    (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
9406                           (const_int 0)))])]
9407   ""
9408   "
9410   operands[1] = gen_reg_rtx (SImode);
9414 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9415 ;; This prevents a regression that occurred when we switched from xor to
9416 ;; mov/neg for sne.
9418 (define_split
9419   [(set (match_operand:SI 0 "arith_reg_dest" "")
9420         (plus:SI (reg:SI T_REG)
9421                  (const_int -1)))]
9422   "TARGET_SH1"
9423   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9424    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9425   "")
9427 (define_expand "cstoresf4"
9428   [(set (match_operand:SI 0 "register_operand" "=r")
9429         (match_operator:SI 1 "sh_float_comparison_operator"
9430          [(match_operand:SF 2 "arith_operand" "")
9431           (match_operand:SF 3 "arith_operand" "")]))]
9432   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9433   "if (TARGET_SHMEDIA)
9434      {
9435        emit_insn (gen_cstore4_media (operands[0], operands[1],
9436                                      operands[2], operands[3]));
9437        DONE;
9438      }
9440    if (! currently_expanding_to_rtl)
9441      FAIL;
9442    
9443    sh_emit_compare_and_set (operands, SFmode);
9444    DONE;
9447 (define_expand "cstoredf4"
9448   [(set (match_operand:SI 0 "register_operand" "=r")
9449         (match_operator:SI 1 "sh_float_comparison_operator"
9450          [(match_operand:DF 2 "arith_operand" "")
9451           (match_operand:DF 3 "arith_operand" "")]))]
9452   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
9453   "if (TARGET_SHMEDIA)
9454      {
9455        emit_insn (gen_cstore4_media (operands[0], operands[1],
9456                                      operands[2], operands[3]));
9457        DONE;
9458      }
9460     if (! currently_expanding_to_rtl)
9461       FAIL;
9462    
9463    sh_emit_compare_and_set (operands, DFmode);
9464    DONE;
9468 ;; -------------------------------------------------------------------------
9469 ;; Instructions to cope with inline literal tables
9470 ;; -------------------------------------------------------------------------
9472 ; 2 byte integer in line
9474 (define_insn "consttable_2"
9475  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9476                     (match_operand 1 "" "")]
9477                    UNSPECV_CONST2)]
9478  ""
9479  "*
9481   if (operands[1] != const0_rtx)
9482     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9483   return \"\";
9485  [(set_attr "length" "2")
9486  (set_attr "in_delay_slot" "no")])
9488 ; 4 byte integer in line
9490 (define_insn "consttable_4"
9491  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9492                     (match_operand 1 "" "")]
9493                    UNSPECV_CONST4)]
9494  ""
9495  "*
9497   if (operands[1] != const0_rtx)
9498     {
9499       assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9500       mark_symbol_refs_as_used (operands[0]);
9501     }
9502   return \"\";
9504  [(set_attr "length" "4")
9505   (set_attr "in_delay_slot" "no")])
9507 ; 8 byte integer in line
9509 (define_insn "consttable_8"
9510  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9511                     (match_operand 1 "" "")]
9512                    UNSPECV_CONST8)]
9513  ""
9514  "*
9516   if (operands[1] != const0_rtx)
9517     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9518   return \"\";
9520  [(set_attr "length" "8")
9521   (set_attr "in_delay_slot" "no")])
9523 ; 4 byte floating point
9525 (define_insn "consttable_sf"
9526  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9527                     (match_operand 1 "" "")]
9528                    UNSPECV_CONST4)]
9529  ""
9530  "*
9532   if (operands[1] != const0_rtx)
9533     {
9534       REAL_VALUE_TYPE d;
9535       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9536       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9537     }
9538   return \"\";
9540  [(set_attr "length" "4")
9541   (set_attr "in_delay_slot" "no")])
9543 ; 8 byte floating point
9545 (define_insn "consttable_df"
9546  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9547                     (match_operand 1 "" "")]
9548                    UNSPECV_CONST8)]
9549  ""
9550  "*
9552   if (operands[1] != const0_rtx)
9553     {
9554       REAL_VALUE_TYPE d;
9555       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9556       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9557     }
9558   return \"\";
9560  [(set_attr "length" "8")
9561   (set_attr "in_delay_slot" "no")])
9563 ;; Alignment is needed for some constant tables; it may also be added for
9564 ;; Instructions at the start of loops, or after unconditional branches.
9565 ;; ??? We would get more accurate lengths if we did instruction
9566 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9567 ;; here is too conservative.
9569 ; align to a two byte boundary
9571 (define_expand "align_2"
9572  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9573  ""
9574  "")
9576 ; align to a four byte boundary
9577 ;; align_4 and align_log are instructions for the starts of loops, or
9578 ;; after unconditional branches, which may take up extra room.
9580 (define_expand "align_4"
9581  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9582  ""
9583  "")
9585 ; align to a cache line boundary
9587 (define_insn "align_log"
9588  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9589  ""
9590  ""
9591  [(set_attr "length" "0")
9592   (set_attr "in_delay_slot" "no")])
9594 ; emitted at the end of the literal table, used to emit the
9595 ; 32bit branch labels if needed.
9597 (define_insn "consttable_end"
9598   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9599   ""
9600   "* return output_jump_label_table ();"
9601   [(set_attr "in_delay_slot" "no")])
9603 ; emitted at the end of the window in the literal table.
9605 (define_insn "consttable_window_end"
9606   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9607   ""
9608   ""
9609   [(set_attr "length" "0")
9610    (set_attr "in_delay_slot" "no")])
9612 ;; -------------------------------------------------------------------------
9613 ;; Misc
9614 ;; -------------------------------------------------------------------------
9616 ;; String/block move insn.
9618 (define_expand "movmemsi"
9619   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9620                    (mem:BLK (match_operand:BLK 1 "" "")))
9621               (use (match_operand:SI 2 "nonmemory_operand" ""))
9622               (use (match_operand:SI 3 "immediate_operand" ""))
9623               (clobber (reg:SI PR_REG))
9624               (clobber (reg:SI R4_REG))
9625               (clobber (reg:SI R5_REG))
9626               (clobber (reg:SI R0_REG))])]
9627   "TARGET_SH1 && ! TARGET_SH5"
9628   "
9630   if(expand_block_move (operands))
9631      DONE;
9632   else FAIL;
9635 (define_insn "block_move_real"
9636   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9637                    (mem:BLK (reg:SI R5_REG)))
9638               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9639               (clobber (reg:SI PR_REG))
9640               (clobber (reg:SI R0_REG))])]
9641   "TARGET_SH1 && ! TARGET_HARD_SH4"
9642   "jsr  @%0%#"
9643   [(set_attr "type" "sfunc")
9644    (set_attr "needs_delay_slot" "yes")])
9646 (define_insn "block_lump_real"
9647   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9648                    (mem:BLK (reg:SI R5_REG)))
9649               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9650               (use (reg:SI R6_REG))
9651               (clobber (reg:SI PR_REG))
9652               (clobber (reg:SI T_REG))
9653               (clobber (reg:SI R4_REG))
9654               (clobber (reg:SI R5_REG))
9655               (clobber (reg:SI R6_REG))
9656               (clobber (reg:SI R0_REG))])]
9657   "TARGET_SH1 && ! TARGET_HARD_SH4"
9658   "jsr  @%0%#"
9659   [(set_attr "type" "sfunc")
9660    (set_attr "needs_delay_slot" "yes")])
9662 (define_insn "block_move_real_i4"
9663   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9664                    (mem:BLK (reg:SI R5_REG)))
9665               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9666               (clobber (reg:SI PR_REG))
9667               (clobber (reg:SI R0_REG))
9668               (clobber (reg:SI R1_REG))
9669               (clobber (reg:SI R2_REG))])]
9670   "TARGET_HARD_SH4"
9671   "jsr  @%0%#"
9672   [(set_attr "type" "sfunc")
9673    (set_attr "needs_delay_slot" "yes")])
9675 (define_insn "block_lump_real_i4"
9676   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9677                    (mem:BLK (reg:SI R5_REG)))
9678               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9679               (use (reg:SI R6_REG))
9680               (clobber (reg:SI PR_REG))
9681               (clobber (reg:SI T_REG))
9682               (clobber (reg:SI R4_REG))
9683               (clobber (reg:SI R5_REG))
9684               (clobber (reg:SI R6_REG))
9685               (clobber (reg:SI R0_REG))
9686               (clobber (reg:SI R1_REG))
9687               (clobber (reg:SI R2_REG))
9688               (clobber (reg:SI R3_REG))])]
9689   "TARGET_HARD_SH4"
9690   "jsr  @%0%#"
9691   [(set_attr "type" "sfunc")
9692    (set_attr "needs_delay_slot" "yes")])
9694 ;; -------------------------------------------------------------------------
9695 ;; Floating point instructions.
9696 ;; -------------------------------------------------------------------------
9698 ;; ??? All patterns should have a type attribute.
9700 (define_expand "movpsi"
9701   [(set (match_operand:PSI 0 "register_operand" "")
9702         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9703   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9704   "")
9706 ;; The c / m alternative is a fake to guide reload to load directly into
9707 ;; fpscr, since reload doesn't know how to use post-increment.
9708 ;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload,
9709 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9710 ;; predicate after reload.
9711 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9712 ;; like a mac -> gpr move.
9713 (define_insn "fpu_switch"
9714   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9715         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9716   "TARGET_SH2E
9717    && (! reload_completed
9718        || true_regnum (operands[0]) != FPSCR_REG
9719        || !MEM_P (operands[1])
9720        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9721   "@
9722         ! precision stays the same
9723         lds.l   %1,fpscr
9724         mov.l   %1,%0
9725         #
9726         lds     %1,fpscr
9727         mov     %1,%0
9728         mov.l   %1,%0
9729         sts     fpscr,%0
9730         sts.l   fpscr,%0"
9731   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9732    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,fstore")])
9734 (define_peephole2
9735   [(set (reg:PSI FPSCR_REG)
9736         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9737   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])"
9738   [(const_int 0)]
9740   rtx fpscr, mem, new_insn;
9742   fpscr = SET_DEST (PATTERN (curr_insn));
9743   mem = SET_SRC (PATTERN (curr_insn));
9744   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9746   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9747   add_reg_note (new_insn, REG_INC, operands[0]);
9748   DONE;
9751 (define_split
9752   [(set (reg:PSI FPSCR_REG)
9753         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9754   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
9755    && (flag_peephole2 ? epilogue_completed : reload_completed)"
9756   [(const_int 0)]
9758   rtx fpscr, mem, new_insn;
9760   fpscr = SET_DEST (PATTERN (curr_insn));
9761   mem = SET_SRC (PATTERN (curr_insn));
9762   mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0]));
9764   new_insn = emit_insn (gen_fpu_switch (fpscr, mem));
9765   add_reg_note (new_insn, REG_INC, operands[0]);
9767   if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0])))
9768     emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4)));
9769   DONE;
9772 ;; ??? This uses the fp unit, but has no type indicating that.
9773 ;; If we did that, this would either give a bogus latency or introduce
9774 ;; a bogus FIFO constraint.
9775 ;; Since this insn is currently only used for prologues/epilogues,
9776 ;; it is probably best to claim no function unit, which matches the
9777 ;; current setting.
9778 (define_insn "toggle_sz"
9779   [(set (reg:PSI FPSCR_REG)
9780         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9781   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9782   "fschg"
9783   [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")])
9785 ;; There's no way we can use it today, since optimize mode switching
9786 ;; doesn't enable us to know from which mode we're switching to the
9787 ;; mode it requests, to tell whether we can use a relative mode switch
9788 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9789 ;; memory).
9790 (define_insn "toggle_pr"
9791   [(set (reg:PSI FPSCR_REG)
9792         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9793   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9794   "fpchg"
9795   [(set_attr "type" "fpscr_toggle")])
9797 (define_expand "addsf3"
9798   [(set (match_operand:SF 0 "arith_reg_operand" "")
9799         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9800                  (match_operand:SF 2 "arith_reg_operand" "")))]
9801   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9802   "
9804   if (TARGET_SH2E)
9805     {
9806       expand_sf_binop (&gen_addsf3_i, operands);
9807       DONE;
9808     }
9811 (define_insn "*addsf3_media"
9812   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9813         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9814                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9815   "TARGET_SHMEDIA_FPU"
9816   "fadd.s       %1, %2, %0"
9817   [(set_attr "type" "fparith_media")])
9819 (define_insn_and_split "unary_sf_op"
9820   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9821         (vec_select:V2SF
9822          (vec_concat:V2SF
9823           (vec_select:SF
9824            (match_dup 0)
9825            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9826           (match_operator:SF 2 "unary_float_operator"
9827             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9828                             (parallel [(match_operand 4
9829                                         "const_int_operand" "n")]))]))
9830          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9831   "TARGET_SHMEDIA_FPU"
9832   "#"
9833   "TARGET_SHMEDIA_FPU && reload_completed"
9834   [(set (match_dup 5) (match_dup 6))]
9835   "
9837   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9838   rtx op1 = gen_rtx_REG (SFmode,
9839                          (true_regnum (operands[1])
9840                           + (INTVAL (operands[4]) ^ endian)));
9842   operands[7] = gen_rtx_REG (SFmode,
9843                              (true_regnum (operands[0])
9844                               + (INTVAL (operands[3]) ^ endian)));
9845   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9847   [(set_attr "type" "fparith_media")])
9849 (define_insn_and_split "binary_sf_op0"
9850   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9851         (vec_concat:V2SF
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 0)]))
9855              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9856                             (parallel [(const_int 0)]))])
9857           (vec_select:SF
9858            (match_dup 0)
9859            (parallel [(const_int 1)]))))]
9860   "TARGET_SHMEDIA_FPU"
9861   "#"
9862   "&& reload_completed"
9863   [(set (match_dup 4) (match_dup 5))]
9864   "
9866   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9867   rtx op1 = gen_rtx_REG (SFmode,
9868                          true_regnum (operands[1]) + endian);
9869   rtx op2 = gen_rtx_REG (SFmode,
9870                          true_regnum (operands[2]) + endian);
9872   operands[4] = gen_rtx_REG (SFmode,
9873                              true_regnum (operands[0]) + endian);
9874   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9876   [(set_attr "type" "fparith_media")])
9878 (define_insn_and_split "binary_sf_op1"
9879   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9880         (vec_concat:V2SF
9881           (vec_select:SF
9882            (match_dup 0)
9883            (parallel [(const_int 0)]))
9884           (match_operator:SF 3 "binary_float_operator"
9885             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9886                             (parallel [(const_int 1)]))
9887              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9888                             (parallel [(const_int 1)]))])))]
9889   "TARGET_SHMEDIA_FPU"
9890   "#"
9891   "&& reload_completed"
9892   [(set (match_dup 4) (match_dup 5))]
9893   "
9895   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9896   rtx op1 = gen_rtx_REG (SFmode,
9897                          true_regnum (operands[1]) + (1 ^ endian));
9898   rtx op2 = gen_rtx_REG (SFmode,
9899                          true_regnum (operands[2]) + (1 ^ endian));
9901   operands[4] = gen_rtx_REG (SFmode,
9902                              true_regnum (operands[0]) + (1 ^ endian));
9903   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9905   [(set_attr "type" "fparith_media")])
9907 (define_insn "addsf3_i"
9908   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9909         (plus: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   "fadd %2,%0"
9914   [(set_attr "type" "fp")
9915    (set_attr "fp_mode" "single")])
9917 (define_expand "subsf3"
9918   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9919         (minus: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   if (TARGET_SH2E)
9925     {
9926       expand_sf_binop (&gen_subsf3_i, operands);
9927       DONE;
9928     }
9931 (define_insn "*subsf3_media"
9932   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9933         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9934                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9935   "TARGET_SHMEDIA_FPU"
9936   "fsub.s       %1, %2, %0"
9937   [(set_attr "type" "fparith_media")])
9939 (define_insn "subsf3_i"
9940   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9941         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9942                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9943    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9944   "TARGET_SH2E"
9945   "fsub %2,%0"
9946   [(set_attr "type" "fp")
9947    (set_attr "fp_mode" "single")])
9949 (define_expand "mulsf3"
9950   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9951         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9952                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9953   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9954   "")
9956 (define_insn "*mulsf3_media"
9957   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9958         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9959                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9960   "TARGET_SHMEDIA_FPU"
9961   "fmul.s       %1, %2, %0"
9962   [(set_attr "type" "fparith_media")])
9964 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
9965 ;; register in feeding fp instructions.  Thus, in order to generate fmac,
9966 ;; we start out with a mulsf pattern that does not depend on fpscr.
9967 ;; This is split after combine to introduce the dependency, in order to
9968 ;; get mode switching and scheduling right.
9969 (define_insn_and_split "mulsf3_ie"
9970   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9971         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9972                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9973   "TARGET_SH2E"
9974   "fmul %2,%0"
9975   "TARGET_SH4 || TARGET_SH2A_SINGLE"
9976   [(const_int 0)]
9977   "
9979   emit_insn (gen_mulsf3_i4 (operands[0], operands[1], operands[2],
9980              get_fpscr_rtx ()));
9981   DONE;
9983   [(set_attr "type" "fp")])
9985 (define_insn "mulsf3_i4"
9986   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9987         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9988                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9989    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9990   "TARGET_SH2E"
9991   "fmul %2,%0"
9992   [(set_attr "type" "fp")
9993    (set_attr "fp_mode" "single")])
9995 (define_insn "mac_media"
9996   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9997         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9998                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
9999                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10000   "TARGET_SHMEDIA_FPU && TARGET_FMAC"
10001   "fmac.s %1, %2, %0"
10002   [(set_attr "type" "fparith_media")])
10004 (define_insn "*macsf3"
10005   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10006         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10007                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10008                  (match_operand:SF 3 "arith_reg_operand" "0")))
10009    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10010   "TARGET_SH2E && TARGET_FMAC"
10011   "fmac fr0,%2,%0"
10012   [(set_attr "type" "fp")
10013    (set_attr "fp_mode" "single")])
10015 (define_expand "divsf3"
10016   [(set (match_operand:SF 0 "arith_reg_operand" "")
10017         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10018                 (match_operand:SF 2 "arith_reg_operand" "")))]
10019   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10020   "
10022   if (TARGET_SH2E)
10023     {
10024       expand_sf_binop (&gen_divsf3_i, operands);
10025       DONE;
10026     }
10029 (define_insn "*divsf3_media"
10030   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10031         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10032                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10033   "TARGET_SHMEDIA_FPU"
10034   "fdiv.s       %1, %2, %0"
10035   [(set_attr "type" "fdiv_media")])
10037 (define_insn "divsf3_i"
10038   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10039         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10040                  (match_operand:SF 2 "arith_reg_operand" "f")))
10041    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10042   "TARGET_SH2E"
10043   "fdiv %2,%0"
10044   [(set_attr "type" "fdiv")
10045    (set_attr "fp_mode" "single")])
10047 (define_insn "floatdisf2"
10048   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10049         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10050   "TARGET_SHMEDIA_FPU"
10051   "float.qs %1, %0"
10052   [(set_attr "type" "fpconv_media")])
10054 (define_expand "floatsisf2"
10055   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10056         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10057   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10058   "
10060   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10061     {
10062       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10063       DONE;
10064     }
10067 (define_insn "*floatsisf2_media"
10068   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10069         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10070   "TARGET_SHMEDIA_FPU"
10071   "float.ls     %1, %0"
10072   [(set_attr "type" "fpconv_media")])
10074 (define_insn "floatsisf2_i4"
10075   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10076         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10077    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10078   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10079   "float        %1,%0"
10080   [(set_attr "type" "fp")
10081    (set_attr "fp_mode" "single")])
10083 (define_insn "*floatsisf2_ie"
10084   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10085         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10086   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10087   "float        %1,%0"
10088   [(set_attr "type" "fp")])
10090 (define_insn "fix_truncsfdi2"
10091   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10092         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10093   "TARGET_SHMEDIA_FPU"
10094   "ftrc.sq %1, %0"
10095   [(set_attr "type" "fpconv_media")])
10097 (define_expand "fix_truncsfsi2"
10098   [(set (match_operand:SI 0 "fpul_operand" "=y")
10099         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10100   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10101   "
10103   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10104     {
10105       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10106       DONE;
10107     }
10110 (define_insn "*fix_truncsfsi2_media"
10111   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10112         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10113   "TARGET_SHMEDIA_FPU"
10114   "ftrc.sl      %1, %0"
10115   [(set_attr "type" "fpconv_media")])
10117 (define_insn "fix_truncsfsi2_i4"
10118   [(set (match_operand:SI 0 "fpul_operand" "=y")
10119         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10120    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10121   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10122   "ftrc %1,%0"
10123   [(set_attr "type" "ftrc_s")
10124    (set_attr "fp_mode" "single")])
10126 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10127 ;; fix_truncsfsi2_i4.
10128 ;; (define_insn "fix_truncsfsi2_i4_2"
10129 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10130 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10131 ;;   (use (reg:PSI FPSCR_REG))
10132 ;;   (clobber (reg:SI FPUL_REG))]
10133 ;;  "TARGET_SH4"
10134 ;;  "#"
10135 ;;  [(set_attr "length" "4")
10136 ;;   (set_attr "fp_mode" "single")])
10138 ;;(define_split
10139 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10140 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10141 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10142 ;;   (clobber (reg:SI FPUL_REG))]
10143 ;;  "TARGET_SH4"
10144 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10145 ;;            (use (match_dup 2))])
10146 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10148 (define_insn "*fixsfsi"
10149   [(set (match_operand:SI 0 "fpul_operand" "=y")
10150         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10151   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10152   "ftrc %1,%0"
10153   [(set_attr "type" "fp")])
10155 (define_insn "cmpgtsf_t"
10156   [(set (reg:SI T_REG)
10157         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10158                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10159   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10160   "fcmp/gt      %1,%0"
10161   [(set_attr "type" "fp_cmp")
10162    (set_attr "fp_mode" "single")])
10164 (define_insn "cmpeqsf_t"
10165   [(set (reg:SI T_REG)
10166         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10167                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10168   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10169   "fcmp/eq      %1,%0"
10170   [(set_attr "type" "fp_cmp")
10171    (set_attr "fp_mode" "single")])
10173 (define_insn "ieee_ccmpeqsf_t"
10174   [(set (reg:SI T_REG)
10175         (ior:SI (reg:SI T_REG)
10176                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10177                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10178   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10179   "* return output_ieee_ccmpeq (insn, operands);"
10180   [(set_attr "length" "4")])
10183 (define_insn "cmpgtsf_t_i4"
10184   [(set (reg:SI T_REG)
10185         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10186                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10187    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10188   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10189   "fcmp/gt      %1,%0"
10190   [(set_attr "type" "fp_cmp")
10191    (set_attr "fp_mode" "single")])
10193 (define_insn "cmpeqsf_t_i4"
10194   [(set (reg:SI T_REG)
10195         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10196                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10197    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10198   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10199   "fcmp/eq      %1,%0"
10200   [(set_attr "type" "fp_cmp")
10201    (set_attr "fp_mode" "single")])
10203 (define_insn "*ieee_ccmpeqsf_t_4"
10204   [(set (reg:SI T_REG)
10205         (ior:SI (reg:SI T_REG)
10206                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10207                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10208    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10209   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10210   "* return output_ieee_ccmpeq (insn, operands);"
10211   [(set_attr "length" "4")
10212    (set_attr "fp_mode" "single")])
10214 (define_insn "cmpeqsf_media"
10215   [(set (match_operand:SI 0 "register_operand" "=r")
10216         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10217                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10218   "TARGET_SHMEDIA_FPU"
10219   "fcmpeq.s     %1, %2, %0"
10220   [(set_attr "type" "fcmp_media")])
10222 (define_insn "cmpgtsf_media"
10223   [(set (match_operand:SI 0 "register_operand" "=r")
10224         (gt:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10225                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10226   "TARGET_SHMEDIA_FPU"
10227   "fcmpgt.s     %1, %2, %0"
10228   [(set_attr "type" "fcmp_media")])
10230 (define_insn "cmpgesf_media"
10231   [(set (match_operand:SI 0 "register_operand" "=r")
10232         (ge:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10233                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10234   "TARGET_SHMEDIA_FPU"
10235   "fcmpge.s     %1, %2, %0"
10236   [(set_attr "type" "fcmp_media")])
10238 (define_insn "cmpunsf_media"
10239   [(set (match_operand:SI 0 "register_operand" "=r")
10240         (unordered:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10241                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10242   "TARGET_SHMEDIA_FPU"
10243   "fcmpun.s     %1, %2, %0"
10244   [(set_attr "type" "fcmp_media")])
10246 (define_expand "cbranchsf4"
10247   [(set (pc)
10248         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10249                        [(match_operand:SF 1 "arith_operand" "")
10250                         (match_operand:SF 2 "arith_operand" "")])
10251                       (match_operand 3 "" "")
10252                       (pc)))]
10253   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10254   "
10256   if (TARGET_SHMEDIA)
10257     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10258                                           operands[3]));
10259   else
10260     sh_emit_compare_and_branch (operands, SFmode);
10261   DONE;
10264 (define_expand "negsf2"
10265   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10266         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10267   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10268   "
10270   if (TARGET_SH2E)
10271     {
10272       expand_sf_unop (&gen_negsf2_i, operands);
10273       DONE;
10274     }
10277 (define_insn "*negsf2_media"
10278   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10279         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10280   "TARGET_SHMEDIA_FPU"
10281   "fneg.s       %1, %0"
10282   [(set_attr "type" "fmove_media")])
10284 (define_insn "negsf2_i"
10285   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10286         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10287    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10288   "TARGET_SH2E"
10289   "fneg %0"
10290   [(set_attr "type" "fmove")
10291    (set_attr "fp_mode" "single")])
10293 (define_expand "sqrtsf2"
10294   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10295         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10296   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10297   "
10299   if (TARGET_SH3E)
10300     {
10301       expand_sf_unop (&gen_sqrtsf2_i, operands);
10302       DONE;
10303     }
10306 (define_insn "*sqrtsf2_media"
10307   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10308         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10309   "TARGET_SHMEDIA_FPU"
10310   "fsqrt.s      %1, %0"
10311   [(set_attr "type" "fdiv_media")])
10313 (define_insn "sqrtsf2_i"
10314   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10315         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10316    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10317   "TARGET_SH3E"
10318   "fsqrt        %0"
10319   [(set_attr "type" "fdiv")
10320    (set_attr "fp_mode" "single")])
10322 (define_insn "rsqrtsf2"
10323   [(set (match_operand:SF 0 "register_operand" "=f")
10324         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10325                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10326    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10327   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10328    && operands[1] == CONST1_RTX (SFmode)"
10329   "fsrra        %0"
10330   [(set_attr "type" "fsrra")
10331    (set_attr "fp_mode" "single")])
10333 (define_insn "fsca"
10334   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10335         (vec_concat:V2SF
10336          (unspec:SF [(mult:SF
10337                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10338                       (match_operand:SF 2 "immediate_operand" "i"))
10339                     ] UNSPEC_FSINA)
10340          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10341                     ] UNSPEC_FCOSA)))
10342    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10343   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10344    && operands[2] == sh_fsca_int2sf ()"
10345   "fsca fpul,%d0"
10346   [(set_attr "type" "fsca")
10347    (set_attr "fp_mode" "single")])
10349 (define_expand "sinsf2"
10350   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10351         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10352                    UNSPEC_FSINA))]
10353   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10354   "
10356   rtx scaled = gen_reg_rtx (SFmode);
10357   rtx truncated = gen_reg_rtx (SImode);
10358   rtx fsca = gen_reg_rtx (V2SFmode);
10359   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10361   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10362   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10363   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10364                           get_fpscr_rtx ()));
10365   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10366   DONE;
10369 (define_expand "cossf2"
10370   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10371         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10372                    UNSPEC_FCOSA))]
10373   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10374   "
10376   rtx scaled = gen_reg_rtx (SFmode);
10377   rtx truncated = gen_reg_rtx (SImode);
10378   rtx fsca = gen_reg_rtx (V2SFmode);
10379   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10381   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10382   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10383   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10384                           get_fpscr_rtx ()));
10385   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10386   DONE;
10389 (define_expand "sindf2"
10390   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10391         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10392                    UNSPEC_FSINA))]
10393   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10394   "
10396   rtx scaled = gen_reg_rtx (DFmode);
10397   rtx truncated = gen_reg_rtx (SImode);
10398   rtx fsca = gen_reg_rtx (V2SFmode);
10399   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10400   rtx sfresult = gen_reg_rtx (SFmode);
10402   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10403   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10404   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10405                           get_fpscr_rtx ()));
10406   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10407   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10408   DONE;
10411 (define_expand "cosdf2"
10412   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10413         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10414                    UNSPEC_FCOSA))]
10415   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10416   "
10418   rtx scaled = gen_reg_rtx (DFmode);
10419   rtx truncated = gen_reg_rtx (SImode);
10420   rtx fsca = gen_reg_rtx (V2SFmode);
10421   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10422   rtx sfresult = gen_reg_rtx (SFmode);
10424   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10425   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10426   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10427                           get_fpscr_rtx ()));
10428   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10429   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10430   DONE;
10433 (define_expand "abssf2"
10434   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10435         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10436   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10437   "
10439   if (TARGET_SH2E)
10440     {
10441       expand_sf_unop (&gen_abssf2_i, operands);
10442       DONE;
10443     }
10446 (define_insn "*abssf2_media"
10447   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10448         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10449   "TARGET_SHMEDIA_FPU"
10450   "fabs.s       %1, %0"
10451   [(set_attr "type" "fmove_media")])
10453 (define_insn "abssf2_i"
10454   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10455         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10456    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10457   "TARGET_SH2E"
10458   "fabs %0"
10459   [(set_attr "type" "fmove")
10460    (set_attr "fp_mode" "single")])
10462 (define_expand "adddf3"
10463   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10464         (plus: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_adddf3_i, operands);
10472       DONE;
10473     }
10476 (define_insn "*adddf3_media"
10477   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10478         (plus: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   "fadd.d       %1, %2, %0"
10482   [(set_attr "type" "dfparith_media")])
10484 (define_insn "adddf3_i"
10485   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10486         (plus: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   "fadd %2,%0"
10491   [(set_attr "type" "dfp_arith")
10492    (set_attr "fp_mode" "double")])
10494 (define_expand "subdf3"
10495   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10496         (minus: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_subdf3_i, operands);
10504       DONE;
10505     }
10508 (define_insn "*subdf3_media"
10509   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10510         (minus: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   "fsub.d       %1, %2, %0"
10514   [(set_attr "type" "dfparith_media")])
10516 (define_insn "subdf3_i"
10517   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10518         (minus: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   "fsub %2,%0"
10523   [(set_attr "type" "dfp_arith")
10524    (set_attr "fp_mode" "double")])
10526 (define_expand "muldf3"
10527   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10528         (mult: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_muldf3_i, operands);
10536       DONE;
10537     }
10540 (define_insn "*muldf3_media"
10541   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10542         (mult: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   "fmul.d       %1, %2, %0"
10546   [(set_attr "type" "dfmul_media")])
10548 (define_insn "muldf3_i"
10549   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10550         (mult: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   "fmul %2,%0"
10555   [(set_attr "type" "dfp_mul")
10556    (set_attr "fp_mode" "double")])
10558 (define_expand "divdf3"
10559   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10560         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10561                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10562   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10563   "
10565   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10566     {
10567       expand_df_binop (&gen_divdf3_i, operands);
10568       DONE;
10569     }
10572 (define_insn "*divdf3_media"
10573   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10574         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10575                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10576   "TARGET_SHMEDIA_FPU"
10577   "fdiv.d       %1, %2, %0"
10578   [(set_attr "type" "dfdiv_media")])
10580 (define_insn "divdf3_i"
10581   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10582         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10583                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10584    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10585   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10586   "fdiv %2,%0"
10587   [(set_attr "type" "dfdiv")
10588    (set_attr "fp_mode" "double")])
10590 (define_insn "floatdidf2"
10591   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10592         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10593   "TARGET_SHMEDIA_FPU"
10594   "float.qd     %1, %0"
10595   [(set_attr "type" "dfpconv_media")])
10597 (define_expand "floatsidf2"
10598   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10599         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10600   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10601   "
10603   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10604     {
10605       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10606                                       get_fpscr_rtx ()));
10607       DONE;
10608     }
10611 (define_insn "*floatsidf2_media"
10612   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10613         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10614   "TARGET_SHMEDIA_FPU"
10615   "float.ld     %1, %0"
10616   [(set_attr "type" "dfpconv_media")])
10618 (define_insn "floatsidf2_i"
10619   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10620         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10621    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10622   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10623   "float        %1,%0"
10624   [(set_attr "type" "dfp_conv")
10625    (set_attr "fp_mode" "double")])
10627 (define_insn "fix_truncdfdi2"
10628   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10629         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10630   "TARGET_SHMEDIA_FPU"
10631   "ftrc.dq      %1, %0"
10632   [(set_attr "type" "dfpconv_media")])
10634 (define_expand "fix_truncdfsi2"
10635   [(set (match_operand:SI 0 "fpul_operand" "")
10636         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10637   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10638   "
10640   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10641     {
10642       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10643                                           get_fpscr_rtx ()));
10644       DONE;
10645     }
10648 (define_insn "*fix_truncdfsi2_media"
10649   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10650         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10651   "TARGET_SHMEDIA_FPU"
10652   "ftrc.dl      %1, %0"
10653   [(set_attr "type" "dfpconv_media")])
10655 (define_insn "fix_truncdfsi2_i"
10656   [(set (match_operand:SI 0 "fpul_operand" "=y")
10657         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10658    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10659   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10660   "ftrc %1,%0"
10661   [(set_attr "type" "dfp_conv")
10662    (set_attr "dfp_comp" "no")
10663    (set_attr "fp_mode" "double")])
10665 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10666 ;; fix_truncdfsi2_i.
10667 ;; (define_insn "fix_truncdfsi2_i4"
10668 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10669 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10670 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10671 ;;    (clobber (reg:SI FPUL_REG))]
10672 ;;   "TARGET_SH4"
10673 ;;   "#"
10674 ;;   [(set_attr "length" "4")
10675 ;;    (set_attr "fp_mode" "double")])
10677 ;; (define_split
10678 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10679 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10680 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10681 ;;    (clobber (reg:SI FPUL_REG))]
10682 ;;   "TARGET_SH4"
10683 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10684 ;;            (use (match_dup 2))])
10685 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10687 (define_insn "cmpgtdf_t"
10688   [(set (reg:SI T_REG)
10689         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10690                (match_operand:DF 1 "arith_reg_operand" "f")))
10691    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10692   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10693   "fcmp/gt      %1,%0"
10694   [(set_attr "type" "dfp_cmp")
10695    (set_attr "fp_mode" "double")])
10697 (define_insn "cmpeqdf_t"
10698   [(set (reg:SI T_REG)
10699         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10700                (match_operand:DF 1 "arith_reg_operand" "f")))
10701    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10702   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10703   "fcmp/eq      %1,%0"
10704   [(set_attr "type" "dfp_cmp")
10705    (set_attr "fp_mode" "double")])
10707 (define_insn "*ieee_ccmpeqdf_t"
10708   [(set (reg:SI T_REG)
10709         (ior:SI (reg:SI T_REG)
10710                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10711                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10712    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10713   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10714   "* return output_ieee_ccmpeq (insn, operands);"
10715   [(set_attr "length" "4")
10716    (set_attr "fp_mode" "double")])
10718 (define_insn "cmpeqdf_media"
10719   [(set (match_operand:SI 0 "register_operand" "=r")
10720         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10721                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10722   "TARGET_SHMEDIA_FPU"
10723   "fcmpeq.d     %1,%2,%0"
10724   [(set_attr "type" "fcmp_media")])
10726 (define_insn "cmpgtdf_media"
10727   [(set (match_operand:SI 0 "register_operand" "=r")
10728         (gt:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10729                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10730   "TARGET_SHMEDIA_FPU"
10731   "fcmpgt.d     %1,%2,%0"
10732   [(set_attr "type" "fcmp_media")])
10734 (define_insn "cmpgedf_media"
10735   [(set (match_operand:SI 0 "register_operand" "=r")
10736         (ge:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10737                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10738   "TARGET_SHMEDIA_FPU"
10739   "fcmpge.d     %1,%2,%0"
10740   [(set_attr "type" "fcmp_media")])
10742 (define_insn "cmpundf_media"
10743   [(set (match_operand:SI 0 "register_operand" "=r")
10744         (unordered:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10745                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10746   "TARGET_SHMEDIA_FPU"
10747   "fcmpun.d     %1,%2,%0"
10748   [(set_attr "type" "fcmp_media")])
10750 (define_expand "cbranchdf4"
10751   [(set (pc)
10752         (if_then_else (match_operator 0 "sh_float_comparison_operator"
10753                        [(match_operand:DF 1 "arith_operand" "")
10754                         (match_operand:DF 2 "arith_operand" "")])
10755                       (match_operand 3 "" "")
10756                       (pc)))]
10757   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10758   "
10760   if (TARGET_SHMEDIA)
10761     emit_jump_insn (gen_cbranchfp4_media (operands[0], operands[1], operands[2],
10762                                           operands[3]));
10763   else
10764     sh_emit_compare_and_branch (operands, DFmode);
10765   DONE;
10769 (define_expand "negdf2"
10770   [(set (match_operand:DF 0 "arith_reg_operand" "")
10771         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10772   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10773   "
10775   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10776     {
10777       expand_df_unop (&gen_negdf2_i, operands);
10778       DONE;
10779     }
10782 (define_insn "*negdf2_media"
10783   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10784         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10785   "TARGET_SHMEDIA_FPU"
10786   "fneg.d       %1, %0"
10787   [(set_attr "type" "fmove_media")])
10789 (define_insn "negdf2_i"
10790   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10791         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10792    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10793   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10794   "fneg %0"
10795   [(set_attr "type" "fmove")
10796    (set_attr "fp_mode" "double")])
10798 (define_expand "sqrtdf2"
10799   [(set (match_operand:DF 0 "arith_reg_operand" "")
10800         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10801   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10802   "
10804   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10805     {
10806       expand_df_unop (&gen_sqrtdf2_i, operands);
10807       DONE;
10808     }
10811 (define_insn "*sqrtdf2_media"
10812   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10813         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10814   "TARGET_SHMEDIA_FPU"
10815   "fsqrt.d      %1, %0"
10816   [(set_attr "type" "dfdiv_media")])
10818 (define_insn "sqrtdf2_i"
10819   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10820         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10821    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10822   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10823   "fsqrt        %0"
10824   [(set_attr "type" "dfdiv")
10825    (set_attr "fp_mode" "double")])
10827 (define_expand "absdf2"
10828   [(set (match_operand:DF 0 "arith_reg_operand" "")
10829         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10830   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10831   "
10833   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10834     {
10835       expand_df_unop (&gen_absdf2_i, operands);
10836       DONE;
10837     }
10840 (define_insn "*absdf2_media"
10841   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10842         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10843   "TARGET_SHMEDIA_FPU"
10844   "fabs.d       %1, %0"
10845   [(set_attr "type" "fmove_media")])
10847 (define_insn "absdf2_i"
10848   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10849         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10850    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10851   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10852   "fabs %0"
10853   [(set_attr "type" "fmove")
10854    (set_attr "fp_mode" "double")])
10856 (define_expand "extendsfdf2"
10857   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10858         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10859   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10860   "
10862   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10863     {
10864       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10865                                         get_fpscr_rtx ()));
10866       DONE;
10867     }
10870 (define_insn "*extendsfdf2_media"
10871   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10872         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10873   "TARGET_SHMEDIA_FPU"
10874   "fcnv.sd      %1, %0"
10875   [(set_attr "type" "dfpconv_media")])
10877 (define_insn "extendsfdf2_i4"
10878   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10879         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10880    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10881   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10882   "fcnvsd  %1,%0"
10883   [(set_attr "type" "fp")
10884    (set_attr "fp_mode" "double")])
10886 (define_expand "truncdfsf2"
10887   [(set (match_operand:SF 0 "fpul_operand" "")
10888         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10889   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10890   "
10892   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10893     {
10894       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10895                                        get_fpscr_rtx ()));
10896       DONE;
10897     }
10900 (define_insn "*truncdfsf2_media"
10901   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10902         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10903   "TARGET_SHMEDIA_FPU"
10904   "fcnv.ds      %1, %0"
10905   [(set_attr "type" "dfpconv_media")])
10907 (define_insn "truncdfsf2_i4"
10908   [(set (match_operand:SF 0 "fpul_operand" "=y")
10909         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10910    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10911   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10912   "fcnvds  %1,%0"
10913   [(set_attr "type" "fp")
10914    (set_attr "fp_mode" "double")])
10916 ;; Bit field extract patterns.  These give better code for packed bitfields,
10917 ;; because they allow auto-increment addresses to be generated.
10919 (define_expand "insv"
10920   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10921                          (match_operand:SI 1 "immediate_operand" "")
10922                          (match_operand:SI 2 "immediate_operand" ""))
10923         (match_operand:SI 3 "general_operand" ""))]
10924   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10925   "
10927   rtx addr_target, orig_address, shift_reg, qi_val;
10928   HOST_WIDE_INT bitsize, size, v = 0;
10929   rtx x = operands[3];
10931   if (TARGET_SH2A && TARGET_BITOPS
10932       && (satisfies_constraint_Sbw (operands[0])
10933           || satisfies_constraint_Sbv (operands[0]))
10934       && satisfies_constraint_M (operands[1])
10935       && satisfies_constraint_K03 (operands[2]))
10936     {
10937       if (satisfies_constraint_N (operands[3]))
10938         {
10939           emit_insn (gen_bclr_m2a (operands[0], operands[2]));
10940           DONE;
10941         }
10942       else if (satisfies_constraint_M (operands[3]))
10943         {
10944           emit_insn (gen_bset_m2a (operands[0], operands[2]));
10945           DONE;
10946         }
10947       else if ((REG_P (operands[3]) && REGNO (operands[3]) == T_REG)
10948                 && satisfies_constraint_M (operands[1]))
10949         {
10950           emit_insn (gen_bst_m2a (operands[0], operands[2]));
10951           DONE;
10952         }
10953       else if (REG_P (operands[3])
10954                && satisfies_constraint_M (operands[1]))
10955         {
10956           emit_insn (gen_bld_reg (operands[3], const0_rtx));
10957           emit_insn (gen_bst_m2a (operands[0], operands[2]));
10958           DONE;
10959         }
10960     }
10961   /* ??? expmed doesn't care for non-register predicates.  */
10962   if (! memory_operand (operands[0], VOIDmode)
10963       || ! immediate_operand (operands[1], VOIDmode)
10964       || ! immediate_operand (operands[2], VOIDmode)
10965       || ! general_operand (x, VOIDmode))
10966     FAIL;
10967   /* If this isn't a 16 / 24 / 32 bit field, or if
10968      it doesn't start on a byte boundary, then fail.  */
10969   bitsize = INTVAL (operands[1]);
10970   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10971       || (INTVAL (operands[2]) % 8) != 0)
10972     FAIL;
10974   size = bitsize / 8;
10975   orig_address = XEXP (operands[0], 0);
10976   shift_reg = gen_reg_rtx (SImode);
10977   if (CONST_INT_P (x))
10978     {
10979       v = INTVAL (x);
10980       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
10981     }
10982   else
10983     {
10984       emit_insn (gen_movsi (shift_reg, operands[3]));
10985       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
10986     }
10987   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
10989   operands[0] = replace_equiv_address (operands[0], addr_target);
10990   emit_insn (gen_movqi (operands[0], qi_val));
10992   while (size -= 1)
10993     {
10994       if (CONST_INT_P (x))
10995         qi_val
10996           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
10997       else
10998         {
10999           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11000           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11001         }
11002       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11003       emit_insn (gen_movqi (operands[0], qi_val));
11004     }
11006   DONE;
11009 (define_insn "movua"
11010   [(set (match_operand:SI 0 "register_operand" "=z")
11011         (unspec:SI [(match_operand:BLK 1 "unaligned_load_operand" "Sua>")]
11012                    UNSPEC_MOVUA))]
11013   "TARGET_SH4A_ARCH"
11014   "movua.l      %1,%0"
11015   [(set_attr "type" "movua")])
11017 ;; We shouldn't need this, but cse replaces increments with references
11018 ;; to other regs before flow has a chance to create post_inc
11019 ;; addressing modes, and only postreload's cse_move2add brings the
11020 ;; increments back to a usable form.
11021 (define_peephole2
11022   [(set (match_operand:SI 0 "register_operand" "")
11023         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11024                          (const_int 32) (const_int 0)))
11025    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11026   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11027   [(set (match_operand:SI 0 "register_operand" "")
11028         (sign_extract:SI (mem:SI (post_inc:SI
11029                                   (match_operand:SI 1 "register_operand" "")))
11030                          (const_int 32) (const_int 0)))]
11031   "")
11033 (define_expand "extv"
11034   [(set (match_operand:SI 0 "register_operand" "")
11035         (sign_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_bldsign_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 (define_expand "extzv"
11066   [(set (match_operand:SI 0 "register_operand" "")
11067         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11068                          (match_operand 2 "const_int_operand" "")
11069                          (match_operand 3 "const_int_operand" "")))]
11070   "TARGET_SH4A_ARCH || TARGET_SH2A"
11072   if (TARGET_SH2A && TARGET_BITOPS
11073       && (satisfies_constraint_Sbw (operands[1])
11074           || satisfies_constraint_Sbv (operands[1]))
11075       && satisfies_constraint_M (operands[2])
11076       && satisfies_constraint_K03 (operands[3]))
11077     {
11078       emit_insn (gen_bld_m2a (operands[1], operands[3]));
11079       if (REGNO (operands[0]) != T_REG)
11080         emit_insn (gen_movsi (operands[0], gen_rtx_REG (SImode, T_REG)));
11081       DONE;
11082     }
11083   if (TARGET_SH4A_ARCH
11084       && INTVAL (operands[2]) == 32
11085       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11086       && MEM_P (operands[1]) && MEM_ALIGN (operands[1]) < 32)
11087     {
11088       rtx src = adjust_address (operands[1], BLKmode, 0);
11089       set_mem_size (src, GEN_INT (4));
11090       emit_insn (gen_movua (operands[0], src));
11091       DONE;
11092     }
11094   FAIL;
11097 ;; SH2A instructions for bitwise operations.
11099 ;; Clear a bit in a memory location.
11100 (define_insn "bclr_m2a"
11101   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11102         (and:QI
11103             (not:QI (ashift:QI (const_int 1)
11104                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11105             (match_dup 0)))]
11106   "TARGET_SH2A && TARGET_BITOPS"
11107   "@
11108         bclr.b\\t%1,%0
11109         bclr.b\\t%1,@(0,%t0)"
11110 [(set_attr "length" "4,4")])
11112 (define_insn "bclrmem_m2a"
11113   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11114         (and:QI (match_dup 0)
11115                 (match_operand:QI 1 "const_int_operand" "Psz,Psz")))]
11116   "TARGET_SH2A && satisfies_constraint_Psz (operands[1]) && TARGET_BITOPS"
11117   "@
11118         bclr.b\\t%W1,%0
11119         bclr.b\\t%W1,@(0,%t0)"
11120   [(set_attr "length" "4,4")])
11122 ;; Set a bit in a memory location.
11123 (define_insn "bset_m2a"
11124   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11125         (ior:QI
11126             (ashift:QI (const_int 1)
11127                        (match_operand:QI 1 "const_int_operand" "K03,K03"))
11128             (match_dup 0)))]
11129   "TARGET_SH2A && TARGET_BITOPS"
11130   "@
11131         bset.b\\t%1,%0
11132         bset.b\\t%1,@(0,%t0)"
11133   [(set_attr "length" "4,4")])
11135 (define_insn "bsetmem_m2a"
11136   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,Sbv")
11137         (ior:QI (match_dup 0)
11138                 (match_operand:QI 1 "const_int_operand" "Pso,Pso")))]
11139   "TARGET_SH2A && satisfies_constraint_Pso (operands[1]) && TARGET_BITOPS"
11140   "@
11141         bset.b\\t%V1,%0
11142         bset.b\\t%V1,@(0,%t0)"
11143   [(set_attr "length" "4,4")])
11145 ;;; Transfer the contents of the T bit to a specified bit of memory.
11146 (define_insn "bst_m2a"
11147   [(set (match_operand:QI 0 "bitwise_memory_operand" "+Sbw,m")
11148         (if_then_else (eq (reg:SI T_REG) (const_int 0))
11149             (and:QI
11150                 (not:QI (ashift:QI (const_int 1)
11151                         (match_operand:QI 1 "const_int_operand" "K03,K03")))
11152                 (match_dup 0))
11153             (ior:QI
11154                 (ashift:QI (const_int 1) (match_dup 1))
11155                 (match_dup 0))))]
11156   "TARGET_SH2A && TARGET_BITOPS"
11157   "@
11158         bst.b\\t%1,%0
11159         bst.b\\t%1,@(0,%t0)"
11160   [(set_attr "length" "4")])
11162 ;; Store a specified bit of memory in the T bit.
11163 (define_insn "bld_m2a"
11164   [(set (reg:SI T_REG)
11165         (zero_extract:SI
11166             (match_operand:QI 0 "bitwise_memory_operand" "Sbw,Sbv")
11167             (const_int 1)
11168             (match_operand 1 "const_int_operand" "K03,K03")))]
11169   "TARGET_SH2A && TARGET_BITOPS"
11170   "@
11171         bld.b\\t%1,%0
11172         bld.b\\t%1,@(0,%t0)"
11173   [(set_attr "length" "4,4")])
11175 ;; Store a specified bit of memory in the T bit.
11176 (define_insn "bldsign_m2a"
11177   [(set (reg:SI T_REG)
11178         (sign_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         bld.b\\t%1,%0
11185         bld.b\\t%1,@(0,%t0)"
11186   [(set_attr "length" "4,4")])
11188 ;; Store a specified bit of the LSB 8 bits of a register in the T bit.
11189 (define_insn "bld_reg"
11190   [(set (reg:SI T_REG)
11191         (zero_extract:SI (match_operand:SI 0 "arith_reg_operand" "r")
11192                          (const_int 1)
11193                          (match_operand 1 "const_int_operand" "K03")))]
11194   "TARGET_SH2A"
11195   "bld\\t%1,%0")
11197 (define_insn "*bld_regqi"
11198   [(set (reg:SI T_REG)
11199         (zero_extract:SI (match_operand:QI 0 "arith_reg_operand" "r")
11200                          (const_int 1)
11201                          (match_operand 1 "const_int_operand" "K03")))]
11202   "TARGET_SH2A"
11203   "bld\\t%1,%0")
11205 ;; Take logical and of a specified bit of memory with the T bit and
11206 ;; store its result in the T bit.
11207 (define_insn "band_m2a"
11208   [(set (reg:SI T_REG)
11209         (and:SI (reg:SI T_REG)
11210                 (zero_extract:SI
11211                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11212                     (const_int 1)
11213                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11214   "TARGET_SH2A && TARGET_BITOPS"
11215   "@
11216         band.b\\t%1,%0
11217         band.b\\t%1,@(0,%t0)"
11218   [(set_attr "length" "4,4")])
11220 (define_insn "bandreg_m2a"
11221   [(set (match_operand:SI 0 "register_operand" "=r,r")
11222         (and:SI (zero_extract:SI
11223                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11224                     (const_int 1)
11225                     (match_operand 2 "const_int_operand" "K03,K03"))
11226                 (match_operand:SI 3 "register_operand" "r,r")))]
11227   "TARGET_SH2A && TARGET_BITOPS"
11228   "@
11229         band.b\\t%2,%1\;movt\\t%0
11230         band.b\\t%2,@(0,%t1)\;movt\\t%0"
11231   [(set_attr "length" "6,6")])
11233 ;; Take logical or of a specified bit of memory with the T bit and
11234 ;; store its result in the T bit.
11235 (define_insn "bor_m2a"
11236   [(set (reg:SI T_REG)
11237         (ior:SI (reg:SI T_REG)
11238                 (zero_extract:SI
11239                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11240                     (const_int 1)
11241                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11242   "TARGET_SH2A && TARGET_BITOPS"
11243   "@
11244         bor.b\\t%1,%0
11245         bor.b\\t%1,@(0,%t0)"
11246   [(set_attr "length" "4,4")])
11248 (define_insn "borreg_m2a"
11249   [(set (match_operand:SI 0 "register_operand" "=r,r")
11250         (ior:SI (zero_extract:SI
11251                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11252                     (const_int 1)
11253                     (match_operand 2 "const_int_operand" "K03,K03"))
11254                 (match_operand:SI 3 "register_operand" "=r,r")))]
11255   "TARGET_SH2A && TARGET_BITOPS"
11256   "@
11257         bor.b\\t%2,%1\;movt\\t%0
11258         bor.b\\t%2,@(0,%t1)\;movt\\t%0"
11259   [(set_attr "length" "6,6")])
11261 ;; Take exclusive or of a specified bit of memory with the T bit and
11262 ;; store its result in the T bit.
11263 (define_insn "bxor_m2a"
11264   [(set (reg:SI T_REG)
11265         (xor:SI (reg:SI T_REG)
11266                 (zero_extract:SI
11267                     (match_operand:QI 0 "bitwise_memory_operand" "Sbw,m")
11268                     (const_int 1)
11269                     (match_operand 1 "const_int_operand" "K03,K03"))))]
11270   "TARGET_SH2A && TARGET_BITOPS"
11271   "@
11272         bxor.b\\t%1,%0
11273         bxor.b\\t%1,@(0,%t0)"
11274   [(set_attr "length" "4,4")])
11276 (define_insn "bxorreg_m2a"
11277   [(set (match_operand:SI 0 "register_operand" "=r,r")
11278         (xor:SI (zero_extract:SI
11279                     (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")
11280                     (const_int 1)
11281                     (match_operand 2 "const_int_operand" "K03,K03"))
11282                 (match_operand:SI 3 "register_operand" "=r,r")))]
11283   "TARGET_SH2A && TARGET_BITOPS"
11284   "@
11285         bxor.b\\t%2,%1\;movt\\t%0
11286         bxor.b\\t%2,@(0,%t1)\;movt\\t%0"
11287   [(set_attr "length" "6,6")])
11290 ;; -------------------------------------------------------------------------
11291 ;; Peepholes
11292 ;; -------------------------------------------------------------------------
11293 ;; This matches cases where the bit in a memory location is set.
11294 (define_peephole2
11295   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11296         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11297    (set (match_dup 0)
11298         (ior:SI (match_dup 0)
11299         (match_operand:SI 2 "const_int_operand" "Pso,Pso")))
11300    (set (match_dup 1)
11301         (match_operand 3 "arith_reg_operand" "r,r"))]
11302   "TARGET_SH2A && TARGET_BITOPS
11303    && satisfies_constraint_Pso (operands[2])
11304    && REGNO (operands[0]) == REGNO (operands[3])"
11305   [(set (match_dup 1)
11306         (ior:QI (match_dup 1)
11307                 (match_dup 2)))]
11308   "")
11310 ;; This matches cases where the bit in a memory location is cleared.
11311 (define_peephole2
11312   [(set (match_operand:SI 0 "arith_reg_operand" "r,r")
11313         (sign_extend:SI (match_operand:QI 1 "bitwise_memory_operand" "Sbw,Sbv")))
11314    (set (match_dup 0)
11315         (and:SI (match_dup 0)
11316         (match_operand:SI 2 "const_int_operand" "Psz,Psz")))
11317    (set (match_dup 1)
11318         (match_operand 3 "arith_reg_operand" "r,r"))]
11319   "TARGET_SH2A && TARGET_BITOPS
11320    && satisfies_constraint_Psz (operands[2])
11321    && REGNO (operands[0]) == REGNO (operands[3])"
11322   [(set (match_dup 1)
11323         (and:QI (match_dup 1)
11324                 (match_dup 2)))]
11325   "")
11327 ;; This matches cases where a stack pointer increment at the start of the
11328 ;; epilogue combines with a stack slot read loading the return value.
11330 (define_peephole
11331   [(set (match_operand:SI 0 "arith_reg_operand" "")
11332         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11333    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11334   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11335   "mov.l        @%1+,%0")
11337 ;; See the comment on the dt combiner pattern above.
11339 (define_peephole
11340   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11341         (plus:SI (match_dup 0)
11342                  (const_int -1)))
11343    (set (reg:SI T_REG)
11344         (eq:SI (match_dup 0)
11345                (const_int 0)))]
11346   "TARGET_SH2"
11347   "dt   %0")
11349 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11350 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11351 ;; reload when the constant is too large for a reg+offset address.
11353 ;; ??? We would get much better code if this was done in reload.  This would
11354 ;; require modifying find_reloads_address to recognize that if the constant
11355 ;; is out-of-range for an immediate add, then we get better code by reloading
11356 ;; the constant into a register than by reloading the sum into a register,
11357 ;; since the former is one instruction shorter if the address does not need
11358 ;; to be offsettable.  Unfortunately this does not work, because there is
11359 ;; only one register, r0, that can be used as an index register.  This register
11360 ;; is also the function return value register.  So, if we try to force reload
11361 ;; to use double-reg addresses, then we end up with some instructions that
11362 ;; need to use r0 twice.  The only way to fix this is to change the calling
11363 ;; convention so that r0 is not used to return values.
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:SI (match_dup 0))
11369         (match_operand:SI 2 "general_movsrc_operand" ""))]
11370   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11371   "mov.l        %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:SI 2 "general_movdst_operand" "")
11377         (mem:SI (match_dup 0)))]
11378   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11379   "mov.l        @(%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:HI (match_dup 0))
11385         (match_operand:HI 2 "general_movsrc_operand" ""))]
11386   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11387   "mov.w        %2,@(%0,%1)")
11389 (define_peephole
11390   [(set (match_operand:SI 0 "register_operand" "=r")
11391         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11392    (set (match_operand:HI 2 "general_movdst_operand" "")
11393         (mem:HI (match_dup 0)))]
11394   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11395   "mov.w        @(%0,%1),%2")
11397 (define_peephole
11398   [(set (match_operand:SI 0 "register_operand" "=r")
11399         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11400    (set (mem:QI (match_dup 0))
11401         (match_operand:QI 2 "general_movsrc_operand" ""))]
11402   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11403   "mov.b        %2,@(%0,%1)")
11405 (define_peephole
11406   [(set (match_operand:SI 0 "register_operand" "=r")
11407         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11408    (set (match_operand:QI 2 "general_movdst_operand" "")
11409         (mem:QI (match_dup 0)))]
11410   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11411   "mov.b        @(%0,%1),%2")
11413 (define_peephole
11414   [(set (match_operand:SI 0 "register_operand" "=r")
11415         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11416    (set (mem:SF (match_dup 0))
11417         (match_operand:SF 2 "general_movsrc_operand" ""))]
11418   "TARGET_SH1 && REGNO (operands[0]) == 0
11419    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11420        || (GET_CODE (operands[2]) == SUBREG
11421            && REGNO (SUBREG_REG (operands[2])) < 16))
11422    && reg_unused_after (operands[0], insn)"
11423   "mov.l        %2,@(%0,%1)")
11425 (define_peephole
11426   [(set (match_operand:SI 0 "register_operand" "=r")
11427         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11428    (set (match_operand:SF 2 "general_movdst_operand" "")
11430         (mem:SF (match_dup 0)))]
11431   "TARGET_SH1 && REGNO (operands[0]) == 0
11432    && ((REG_P (operands[2]) && REGNO (operands[2]) < 16)
11433        || (GET_CODE (operands[2]) == SUBREG
11434            && REGNO (SUBREG_REG (operands[2])) < 16))
11435    && reg_unused_after (operands[0], insn)"
11436   "mov.l        @(%0,%1),%2")
11438 (define_peephole
11439   [(set (match_operand:SI 0 "register_operand" "=r")
11440         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11441    (set (mem:SF (match_dup 0))
11442         (match_operand:SF 2 "general_movsrc_operand" ""))]
11443   "TARGET_SH2E && REGNO (operands[0]) == 0
11444    && ((REG_P (operands[2])
11445         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11446        || (GET_CODE (operands[2]) == SUBREG
11447            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11448    && reg_unused_after (operands[0], insn)"
11449   "fmov{.s|}    %2,@(%0,%1)")
11451 (define_peephole
11452   [(set (match_operand:SI 0 "register_operand" "=r")
11453         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11454    (set (match_operand:SF 2 "general_movdst_operand" "")
11456         (mem:SF (match_dup 0)))]
11457   "TARGET_SH2E && REGNO (operands[0]) == 0
11458    && ((REG_P (operands[2])
11459         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11460        || (GET_CODE (operands[2]) == SUBREG
11461            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11462    && reg_unused_after (operands[0], insn)"
11463   "fmov{.s|}    @(%0,%1),%2")
11465 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11466 (define_insn "sp_switch_1"
11467   [(const_int 1) (match_operand:SI 0 "symbol_ref_operand" "s")]
11468   "TARGET_SH1"
11469   "*
11471   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", operands);
11472   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", operands);
11473   return \"mov r0,r15\";
11475   [(set_attr "length" "10")])
11477 ;; Switch back to the original stack for interrupt functions with the
11478 ;; sp_switch attribute.  */
11479 (define_insn "sp_switch_2"
11480   [(const_int 2)]
11481   "TARGET_SH1"
11482   "mov.l @r15+,r15\;mov.l @r15+,r0"
11483   [(set_attr "length" "4")])
11485 ;; Integer vector moves
11487 (define_expand "movv8qi"
11488   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11489         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11490   "TARGET_SHMEDIA"
11491   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11493 (define_insn "movv8qi_i"
11494   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11495         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11496   "TARGET_SHMEDIA
11497    && (register_operand (operands[0], V8QImode)
11498        || sh_register_operand (operands[1], V8QImode))"
11499   "@
11500         add     %1, r63, %0
11501         movi    %1, %0
11502         #
11503         ld%M1.q %m1, %0
11504         st%M0.q %m0, %N1"
11505   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11506    (set_attr "length" "4,4,16,4,4")])
11508 (define_split
11509   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11510         (subreg:V8QI (const_int 0) 0))]
11511   "TARGET_SHMEDIA"
11512   [(set (match_dup 0)
11513         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11514                             (const_int 0) (const_int 0) (const_int 0)
11515                             (const_int 0) (const_int 0)]))])
11517 (define_split
11518   [(set (match_operand 0 "arith_reg_dest" "")
11519         (match_operand 1 "sh_rep_vec" ""))]
11520   "TARGET_SHMEDIA && reload_completed
11521    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11522    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11523    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11524    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11525        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11526    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11527        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11528   [(set (match_dup 0) (match_dup 1))
11529    (match_dup 2)]
11530   "
11532   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11533   rtx elt1 = XVECEXP (operands[1], 0, 1);
11535   if (unit_size > 2)
11536     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11537   else
11538     {
11539       if (unit_size < 2)
11540         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11541       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11542     }
11543   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11544   operands[1] = XVECEXP (operands[1], 0, 0);
11545   if (unit_size < 2)
11546     {
11547       if (CONST_INT_P (operands[1]) && CONST_INT_P (elt1))
11548         operands[1]
11549           = GEN_INT (TARGET_LITTLE_ENDIAN
11550                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11551                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11552       else
11553         {
11554           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11555           operands[1]
11556             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11557         }
11558     }
11561 (define_split
11562   [(set (match_operand 0 "arith_reg_dest" "")
11563         (match_operand 1 "sh_const_vec" ""))]
11564   "TARGET_SHMEDIA && reload_completed
11565    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11566    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11567   [(set (match_dup 0) (match_dup 1))]
11568   "
11570   rtx v = operands[1];
11571   enum machine_mode new_mode
11572     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11574   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11575   operands[1]
11576     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11579 (define_expand "movv2hi"
11580   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11581         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11582   "TARGET_SHMEDIA"
11583   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11585 (define_insn "movv2hi_i"
11586   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11587         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11588   "TARGET_SHMEDIA
11589    && (register_operand (operands[0], V2HImode)
11590        || sh_register_operand (operands[1], V2HImode))"
11591   "@
11592         add.l   %1, r63, %0
11593         movi    %1, %0
11594         #
11595         ld%M1.l %m1, %0
11596         st%M0.l %m0, %N1"
11597   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11598    (set_attr "length" "4,4,16,4,4")
11599    (set (attr "highpart")
11600         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11601                (const_string "user")]
11602               (const_string "ignore")))])
11604 (define_expand "movv4hi"
11605   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11606         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11607   "TARGET_SHMEDIA"
11608   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11610 (define_insn "movv4hi_i"
11611   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11612         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11613   "TARGET_SHMEDIA
11614    && (register_operand (operands[0], V4HImode)
11615        || sh_register_operand (operands[1], V4HImode))"
11616   "@
11617         add     %1, r63, %0
11618         movi    %1, %0
11619         #
11620         ld%M1.q %m1, %0
11621         st%M0.q %m0, %N1"
11622   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11623    (set_attr "length" "4,4,16,4,4")
11624    (set_attr "highpart" "depend")])
11626 (define_expand "movv2si"
11627   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11628         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11629   "TARGET_SHMEDIA"
11630   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11632 (define_insn "movv2si_i"
11633   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11634         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16CssZ,nW,m,rlZ"))]
11635   "TARGET_SHMEDIA
11636    && (register_operand (operands[0], V2SImode)
11637        || sh_register_operand (operands[1], V2SImode))"
11638   "@
11639         add     %1, r63, %0
11640         #
11641         #
11642         ld%M1.q %m1, %0
11643         st%M0.q %m0, %N1"
11644   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11645    (set_attr "length" "4,4,16,4,4")
11646    (set_attr "highpart" "depend")])
11648 ;; Multimedia Intrinsics
11650 (define_insn "absv2si2"
11651   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11652         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11653   "TARGET_SHMEDIA"
11654   "mabs.l       %1, %0"
11655   [(set_attr "type" "mcmp_media")
11656    (set_attr "highpart" "depend")])
11658 (define_insn "absv4hi2"
11659   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11660         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11661   "TARGET_SHMEDIA"
11662   "mabs.w       %1, %0"
11663   [(set_attr "type" "mcmp_media")
11664    (set_attr "highpart" "depend")])
11666 (define_insn "addv2si3"
11667   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11668         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11669                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11670   "TARGET_SHMEDIA"
11671   "madd.l       %1, %2, %0"
11672   [(set_attr "type" "arith_media")
11673    (set_attr "highpart" "depend")])
11675 (define_insn "addv4hi3"
11676   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11677         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11678                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11679   "TARGET_SHMEDIA"
11680   "madd.w       %1, %2, %0"
11681   [(set_attr "type" "arith_media")
11682    (set_attr "highpart" "depend")])
11684 (define_insn_and_split "addv2hi3"
11685   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11686         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11687                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11688   "TARGET_SHMEDIA"
11689   "#"
11690   "TARGET_SHMEDIA"
11691   [(const_int 0)]
11692   "
11694   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11695   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11696   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11697   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11698   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11700   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11701   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11702   DONE;
11704   [(set_attr "highpart" "must_split")])
11706 (define_insn "ssaddv2si3"
11707   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11708         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11709                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11710   "TARGET_SHMEDIA"
11711   "madds.l      %1, %2, %0"
11712   [(set_attr "type" "mcmp_media")
11713    (set_attr "highpart" "depend")])
11715 (define_insn "usaddv8qi3"
11716   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11717         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11718                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11719   "TARGET_SHMEDIA"
11720   "madds.ub     %1, %2, %0"
11721   [(set_attr "type" "mcmp_media")
11722    (set_attr "highpart" "depend")])
11724 (define_insn "ssaddv4hi3"
11725   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11726         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11727                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11728   "TARGET_SHMEDIA"
11729   "madds.w      %1, %2, %0"
11730   [(set_attr "type" "mcmp_media")
11731    (set_attr "highpart" "depend")])
11733 (define_insn "negcmpeqv8qi"
11734   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11735         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11736                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11737   "TARGET_SHMEDIA"
11738   "mcmpeq.b     %N1, %N2, %0"
11739   [(set_attr "type" "mcmp_media")
11740    (set_attr "highpart" "depend")])
11742 (define_insn "negcmpeqv2si"
11743   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11744         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11745                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11746   "TARGET_SHMEDIA"
11747   "mcmpeq.l     %N1, %N2, %0"
11748   [(set_attr "type" "mcmp_media")
11749    (set_attr "highpart" "depend")])
11751 (define_insn "negcmpeqv4hi"
11752   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11753         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11754                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11755   "TARGET_SHMEDIA"
11756   "mcmpeq.w     %N1, %N2, %0"
11757   [(set_attr "type" "mcmp_media")
11758    (set_attr "highpart" "depend")])
11760 (define_insn "negcmpgtuv8qi"
11761   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11762         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11763                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11764   "TARGET_SHMEDIA"
11765   "mcmpgt.ub    %N1, %N2, %0"
11766   [(set_attr "type" "mcmp_media")
11767    (set_attr "highpart" "depend")])
11769 (define_insn "negcmpgtv2si"
11770   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11771         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11772                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11773   "TARGET_SHMEDIA"
11774   "mcmpgt.l     %N1, %N2, %0"
11775   [(set_attr "type" "mcmp_media")
11776    (set_attr "highpart" "depend")])
11778 (define_insn "negcmpgtv4hi"
11779   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11780         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11781                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11782   "TARGET_SHMEDIA"
11783   "mcmpgt.w     %N1, %N2, %0"
11784   [(set_attr "type" "mcmp_media")
11785    (set_attr "highpart" "depend")])
11787 (define_insn "mcmv"
11788   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11789         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11790                         (match_operand:DI 2 "arith_reg_operand" "r"))
11791                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11792                         (not:DI (match_dup 2)))))]
11793   "TARGET_SHMEDIA"
11794   "mcmv %N1, %2, %0"
11795   [(set_attr "type" "arith_media")
11796    (set_attr "highpart" "depend")])
11798 (define_insn "mcnvs_lw"
11799   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11800         (vec_concat:V4HI
11801          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11802          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11803   "TARGET_SHMEDIA"
11804   "mcnvs.lw     %N1, %N2, %0"
11805   [(set_attr "type" "mcmp_media")])
11807 (define_insn "mcnvs_wb"
11808   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11809         (vec_concat:V8QI
11810          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11811          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11812   "TARGET_SHMEDIA"
11813   "mcnvs.wb     %N1, %N2, %0"
11814   [(set_attr "type" "mcmp_media")])
11816 (define_insn "mcnvs_wub"
11817   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11818         (vec_concat:V8QI
11819          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11820          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11821   "TARGET_SHMEDIA"
11822   "mcnvs.wub    %N1, %N2, %0"
11823   [(set_attr "type" "mcmp_media")])
11825 (define_insn "mextr_rl"
11826   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11827         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11828                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11829                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11830                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11831   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11832   "*
11834   static char templ[21];
11836   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11837            (int) INTVAL (operands[3]) >> 3);
11838   return templ;
11840   [(set_attr "type" "arith_media")])
11842 (define_insn "*mextr_lr"
11843   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11844         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11845                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11846                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11847                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11848   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11849   "*
11851   static char templ[21];
11853   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11854            (int) INTVAL (operands[4]) >> 3);
11855   return templ;
11857   [(set_attr "type" "arith_media")])
11859 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11860 ; vector then varies depending on endianness.
11861 (define_expand "mextr1"
11862   [(match_operand:DI 0 "arith_reg_dest" "")
11863    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11864    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11865   "TARGET_SHMEDIA"
11866   "
11868   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11869                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11870   DONE;
11873 (define_expand "mextr2"
11874   [(match_operand:DI 0 "arith_reg_dest" "")
11875    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11876    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11877   "TARGET_SHMEDIA"
11878   "
11880   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11881                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11882   DONE;
11885 (define_expand "mextr3"
11886   [(match_operand:DI 0 "arith_reg_dest" "")
11887    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11888    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11889   "TARGET_SHMEDIA"
11890   "
11892   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11893                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11894   DONE;
11897 (define_expand "mextr4"
11898   [(match_operand:DI 0 "arith_reg_dest" "")
11899    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11900    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11901   "TARGET_SHMEDIA"
11902   "
11904   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11905                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11906   DONE;
11909 (define_expand "mextr5"
11910   [(match_operand:DI 0 "arith_reg_dest" "")
11911    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11912    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11913   "TARGET_SHMEDIA"
11914   "
11916   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11917                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11918   DONE;
11921 (define_expand "mextr6"
11922   [(match_operand:DI 0 "arith_reg_dest" "")
11923    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11924    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11925   "TARGET_SHMEDIA"
11926   "
11928   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11929                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11930   DONE;
11933 (define_expand "mextr7"
11934   [(match_operand:DI 0 "arith_reg_dest" "")
11935    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11936    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11937   "TARGET_SHMEDIA"
11938   "
11940   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11941                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11942   DONE;
11945 (define_expand "mmacfx_wl"
11946   [(match_operand:V2SI 0 "arith_reg_dest" "")
11947    (match_operand:V2HI 1 "extend_reg_operand" "")
11948    (match_operand:V2HI 2 "extend_reg_operand" "")
11949    (match_operand:V2SI 3 "arith_reg_operand" "")]
11950   "TARGET_SHMEDIA"
11951   "
11953   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11954                               operands[1], operands[2]));
11955   DONE;
11958 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11959 ;; is depend
11960 (define_insn "mmacfx_wl_i"
11961   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11962         (ss_plus:V2SI
11963          (match_operand:V2SI 1 "arith_reg_operand" "0")
11964          (ss_truncate:V2SI
11965           (ashift:V2DI
11966            (sign_extend:V2DI
11967             (mult:V2SI
11968              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11969              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11970            (const_int 1)))))]
11971   "TARGET_SHMEDIA"
11972   "mmacfx.wl    %2, %3, %0"
11973   [(set_attr "type" "mac_media")
11974    (set_attr "highpart" "depend")])
11976 (define_expand "mmacnfx_wl"
11977   [(match_operand:V2SI 0 "arith_reg_dest" "")
11978    (match_operand:V2HI 1 "extend_reg_operand" "")
11979    (match_operand:V2HI 2 "extend_reg_operand" "")
11980    (match_operand:V2SI 3 "arith_reg_operand" "")]
11981   "TARGET_SHMEDIA"
11982   "
11984   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11985                                operands[1], operands[2]));
11986   DONE;
11989 (define_insn "mmacnfx_wl_i"
11990   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11991         (ss_minus:V2SI
11992          (match_operand:V2SI 1 "arith_reg_operand" "0")
11993          (ss_truncate:V2SI
11994           (ashift:V2DI
11995            (sign_extend:V2DI
11996             (mult:V2SI
11997              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11998              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11999            (const_int 1)))))]
12000   "TARGET_SHMEDIA"
12001   "mmacnfx.wl   %2, %3, %0"
12002   [(set_attr "type" "mac_media")
12003    (set_attr "highpart" "depend")])
12005 (define_insn "mulv2si3"
12006   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12007         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12008                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12009   "TARGET_SHMEDIA"
12010   "mmul.l       %1, %2, %0"
12011   [(set_attr "type" "d2mpy_media")
12012    (set_attr "highpart" "depend")])
12014 (define_insn "mulv4hi3"
12015   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12016         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12017                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12018   "TARGET_SHMEDIA"
12019   "mmul.w       %1, %2, %0"
12020   [(set_attr "type" "dmpy_media")
12021    (set_attr "highpart" "depend")])
12023 (define_insn "mmulfx_l"
12024   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12025         (ss_truncate:V2SI
12026          (ashiftrt:V2DI
12027           (mult:V2DI
12028            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12029            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
12030           (const_int 31))))]
12031   "TARGET_SHMEDIA"
12032   "mmulfx.l     %1, %2, %0"
12033   [(set_attr "type" "d2mpy_media")
12034    (set_attr "highpart" "depend")])
12036 (define_insn "mmulfx_w"
12037   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12038         (ss_truncate:V4HI
12039          (ashiftrt:V4SI
12040           (mult:V4SI
12041            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12042            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12043           (const_int 15))))]
12044   "TARGET_SHMEDIA"
12045   "mmulfx.w     %1, %2, %0"
12046   [(set_attr "type" "dmpy_media")
12047    (set_attr "highpart" "depend")])
12049 (define_insn "mmulfxrp_w"
12050   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12051         (ss_truncate:V4HI
12052          (ashiftrt:V4SI
12053           (plus:V4SI
12054            (mult:V4SI
12055             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12056             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12057            (const_int 16384))
12058           (const_int 15))))]
12059   "TARGET_SHMEDIA"
12060   "mmulfxrp.w   %1, %2, %0"
12061   [(set_attr "type" "dmpy_media")
12062    (set_attr "highpart" "depend")])
12065 (define_expand "mmulhi_wl"
12066   [(match_operand:V2SI 0 "arith_reg_dest" "")
12067    (match_operand:V4HI 1 "arith_reg_operand" "")
12068    (match_operand:V4HI 2 "arith_reg_operand" "")]
12069   "TARGET_SHMEDIA"
12070   "
12072   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
12073              (operands[0], operands[1], operands[2]));
12074   DONE;
12077 (define_expand "mmullo_wl"
12078   [(match_operand:V2SI 0 "arith_reg_dest" "")
12079    (match_operand:V4HI 1 "arith_reg_operand" "")
12080    (match_operand:V4HI 2 "arith_reg_operand" "")]
12081   "TARGET_SHMEDIA"
12082   "
12084   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
12085              (operands[0], operands[1], operands[2]));
12086   DONE;
12089 (define_insn "mmul23_wl"
12090   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12091         (vec_select:V2SI
12092          (mult:V4SI
12093           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12094           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12095          (parallel [(const_int 2) (const_int 3)])))]
12096   "TARGET_SHMEDIA"
12097   "* return (TARGET_LITTLE_ENDIAN
12098              ? \"mmulhi.wl      %1, %2, %0\"
12099              : \"mmullo.wl      %1, %2, %0\");"
12100   [(set_attr "type" "dmpy_media")
12101    (set (attr "highpart")
12102         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12103          (const_string "user")))])
12105 (define_insn "mmul01_wl"
12106   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12107         (vec_select:V2SI
12108          (mult:V4SI
12109           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12110           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
12111          (parallel [(const_int 0) (const_int 1)])))]
12112   "TARGET_SHMEDIA"
12113   "* return (TARGET_LITTLE_ENDIAN
12114              ? \"mmullo.wl      %1, %2, %0\"
12115              : \"mmulhi.wl      %1, %2, %0\");"
12116   [(set_attr "type" "dmpy_media")
12117    (set (attr "highpart")
12118         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12119          (const_string "user")))])
12122 (define_expand "mmulsum_wq"
12123   [(match_operand:DI 0 "arith_reg_dest" "")
12124    (match_operand:V4HI 1 "arith_reg_operand" "")
12125    (match_operand:V4HI 2 "arith_reg_operand" "")
12126    (match_operand:DI 3 "arith_reg_operand" "")]
12127   "TARGET_SHMEDIA"
12128   "
12130   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
12131                                operands[1], operands[2]));
12132   DONE;
12135 (define_insn "mmulsum_wq_i"
12136   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12137         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
12138          (plus:DI
12139           (plus:DI
12140            (vec_select:DI
12141             (mult:V4DI
12142              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
12143              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
12144             (parallel [(const_int 0)]))
12145            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12146                                      (sign_extend:V4DI (match_dup 3)))
12147                           (parallel [(const_int 1)])))
12148           (plus:DI
12149            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12150                                      (sign_extend:V4DI (match_dup 3)))
12151                           (parallel [(const_int 2)]))
12152            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
12153                                      (sign_extend:V4DI (match_dup 3)))
12154                           (parallel [(const_int 3)]))))))]
12155   "TARGET_SHMEDIA"
12156   "mmulsum.wq   %2, %3, %0"
12157   [(set_attr "type" "mac_media")])
12159 (define_expand "mperm_w"
12160   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
12161    (match_operand:V4HI 1 "arith_reg_operand" "r")
12162    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
12163   "TARGET_SHMEDIA"
12164   "
12166   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
12167              (operands[0], operands[1], operands[2]));
12168   DONE;
12171 ; This use of vec_select isn't exactly correct according to rtl.texi
12172 ; (because not constant), but it seems a straightforward extension.
12173 (define_insn "mperm_w_little"
12174   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12175         (vec_select:V4HI
12176          (match_operand:V4HI 1 "arith_reg_operand" "r")
12177          (parallel
12178           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
12179                             (const_int 2) (const_int 0))
12180            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
12181            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
12182            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
12183   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
12184   "mperm.w      %1, %N2, %0"
12185   [(set_attr "type" "arith_media")])
12187 (define_insn "mperm_w_big"
12188   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12189         (vec_select:V4HI
12190          (match_operand:V4HI 1 "arith_reg_operand" "r")
12191          (parallel
12192           [(zero_extract:QI (not:QI (match_operand:QI 2
12193                                      "extend_reg_or_0_operand" "rZ"))
12194                             (const_int 2) (const_int 0))
12195            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
12196            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
12197            (zero_extract:QI (not:QI (match_dup 2))
12198                             (const_int 2) (const_int 6))])))]
12199   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
12200   "mperm.w      %1, %N2, %0"
12201   [(set_attr "type" "arith_media")])
12203 (define_insn "mperm_w0"
12204   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12205         (vec_duplicate:V4HI (truncate:HI (match_operand 1
12206                                           "trunc_hi_operand" "r"))))]
12207   "TARGET_SHMEDIA"
12208   "mperm.w      %1, r63, %0"
12209   [(set_attr "type" "arith_media")
12210    (set_attr "highpart" "ignore")])
12212 (define_expand "msad_ubq"
12213   [(match_operand:DI 0 "arith_reg_dest" "")
12214    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
12215    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12216    (match_operand:DI 3 "arith_reg_operand" "")]
12217   "TARGET_SHMEDIA"
12218   "
12220   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12221                              operands[1], operands[2]));
12222   DONE;
12225 (define_insn "msad_ubq_i"
12226   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12227         (plus:DI
12228          (plus:DI
12229           (plus:DI
12230            (plus:DI
12231             (match_operand:DI 1 "arith_reg_operand" "0")
12232             (abs:DI (vec_select:DI
12233                      (minus:V8DI
12234                       (zero_extend:V8DI
12235                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12236                       (zero_extend:V8DI
12237                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12238                      (parallel [(const_int 0)]))))
12239            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12240                                               (zero_extend:V8DI (match_dup 3)))
12241                                   (parallel [(const_int 1)]))))
12242           (plus:DI
12243            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12244                                               (zero_extend:V8DI (match_dup 3)))
12245                                   (parallel [(const_int 2)])))
12246            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12247                                               (zero_extend:V8DI (match_dup 3)))
12248                                   (parallel [(const_int 3)])))))
12249          (plus:DI
12250           (plus:DI
12251            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12252                                               (zero_extend:V8DI (match_dup 3)))
12253                                   (parallel [(const_int 4)])))
12254            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12255                                               (zero_extend:V8DI (match_dup 3)))
12256                                   (parallel [(const_int 5)]))))
12257           (plus:DI
12258            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12259                                               (zero_extend:V8DI (match_dup 3)))
12260                                   (parallel [(const_int 6)])))
12261            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12262                                               (zero_extend:V8DI (match_dup 3)))
12263                                   (parallel [(const_int 7)])))))))]
12264   "TARGET_SHMEDIA"
12265   "msad.ubq     %N2, %N3, %0"
12266   [(set_attr "type" "mac_media")])
12268 (define_insn "mshalds_l"
12269   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12270         (ss_truncate:V2SI
12271          (ashift:V2DI
12272           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12273           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12274                   (const_int 31)))))]
12275   "TARGET_SHMEDIA"
12276   "mshalds.l    %1, %2, %0"
12277   [(set_attr "type" "mcmp_media")
12278    (set_attr "highpart" "depend")])
12280 (define_insn "mshalds_w"
12281   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12282         (ss_truncate:V4HI
12283          (ashift:V4SI
12284           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12285           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12286                   (const_int 15)))))]
12287   "TARGET_SHMEDIA"
12288   "mshalds.w    %1, %2, %0"
12289   [(set_attr "type" "mcmp_media")
12290    (set_attr "highpart" "depend")])
12292 (define_insn "ashrv2si3"
12293   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12294         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12295                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12296   "TARGET_SHMEDIA"
12297   "mshard.l     %1, %2, %0"
12298   [(set_attr "type" "arith_media")
12299    (set_attr "highpart" "depend")])
12301 (define_insn "ashrv4hi3"
12302   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12303         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12304                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12305   "TARGET_SHMEDIA"
12306   "mshard.w     %1, %2, %0"
12307   [(set_attr "type" "arith_media")
12308    (set_attr "highpart" "depend")])
12310 (define_insn "mshards_q"
12311   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12312         (ss_truncate:HI
12313          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12314                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12315   "TARGET_SHMEDIA"
12316   "mshards.q    %1, %N2, %0"
12317   [(set_attr "type" "mcmp_media")])
12319 (define_expand "mshfhi_b"
12320   [(match_operand:V8QI 0 "arith_reg_dest" "")
12321    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12322    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12323   "TARGET_SHMEDIA"
12324   "
12326   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12327              (operands[0], operands[1], operands[2]));
12328   DONE;
12331 (define_expand "mshflo_b"
12332   [(match_operand:V8QI 0 "arith_reg_dest" "")
12333    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12334    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12335   "TARGET_SHMEDIA"
12336   "
12338   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12339              (operands[0], operands[1], operands[2]));
12340   DONE;
12343 (define_insn "mshf4_b"
12344   [(set
12345     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12346     (vec_select:V8QI
12347      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12348                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12349      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12350                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12351   "TARGET_SHMEDIA"
12352   "* return (TARGET_LITTLE_ENDIAN
12353              ? \"mshfhi.b       %N1, %N2, %0\"
12354              : \"mshflo.b       %N1, %N2, %0\");"
12355   [(set_attr "type" "arith_media")
12356    (set (attr "highpart")
12357         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12358          (const_string "user")))])
12360 (define_insn "mshf0_b"
12361   [(set
12362     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12363     (vec_select:V8QI
12364      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12365                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12366      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12367                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12368   "TARGET_SHMEDIA"
12369   "* return (TARGET_LITTLE_ENDIAN
12370              ? \"mshflo.b       %N1, %N2, %0\"
12371              : \"mshfhi.b       %N1, %N2, %0\");"
12372   [(set_attr "type" "arith_media")
12373    (set (attr "highpart")
12374         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12375          (const_string "user")))])
12377 (define_expand "mshfhi_l"
12378   [(match_operand:V2SI 0 "arith_reg_dest" "")
12379    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12380    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12381   "TARGET_SHMEDIA"
12382   "
12384   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12385              (operands[0], operands[1], operands[2]));
12386   DONE;
12389 (define_expand "mshflo_l"
12390   [(match_operand:V2SI 0 "arith_reg_dest" "")
12391    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12392    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12393   "TARGET_SHMEDIA"
12394   "
12396   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12397              (operands[0], operands[1], operands[2]));
12398   DONE;
12401 (define_insn "mshf4_l"
12402   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12403         (vec_select:V2SI
12404          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12405                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12406          (parallel [(const_int 1) (const_int 3)])))]
12407   "TARGET_SHMEDIA"
12408   "* return (TARGET_LITTLE_ENDIAN
12409              ? \"mshfhi.l       %N1, %N2, %0\"
12410              : \"mshflo.l       %N1, %N2, %0\");"
12411   [(set_attr "type" "arith_media")
12412    (set (attr "highpart")
12413         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12414          (const_string "user")))])
12416 (define_insn "mshf0_l"
12417   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12418         (vec_select:V2SI
12419          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12420                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12421          (parallel [(const_int 0) (const_int 2)])))]
12422   "TARGET_SHMEDIA"
12423   "* return (TARGET_LITTLE_ENDIAN
12424              ? \"mshflo.l       %N1, %N2, %0\"
12425              : \"mshfhi.l       %N1, %N2, %0\");"
12426   [(set_attr "type" "arith_media")
12427    (set (attr "highpart")
12428         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12429          (const_string "user")))])
12431 (define_expand "mshfhi_w"
12432   [(match_operand:V4HI 0 "arith_reg_dest" "")
12433    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12434    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12435   "TARGET_SHMEDIA"
12436   "
12438   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12439              (operands[0], operands[1], operands[2]));
12440   DONE;
12443 (define_expand "mshflo_w"
12444   [(match_operand:V4HI 0 "arith_reg_dest" "")
12445    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12446    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12447   "TARGET_SHMEDIA"
12448   "
12450   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12451              (operands[0], operands[1], operands[2]));
12452   DONE;
12455 (define_insn "mshf4_w"
12456   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12457         (vec_select:V4HI
12458          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12459                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12460          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12461   "TARGET_SHMEDIA"
12462   "* return (TARGET_LITTLE_ENDIAN
12463              ? \"mshfhi.w       %N1, %N2, %0\"
12464              : \"mshflo.w       %N1, %N2, %0\");"
12465   [(set_attr "type" "arith_media")
12466    (set (attr "highpart")
12467         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12468          (const_string "user")))])
12470 (define_insn "mshf0_w"
12471   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12472         (vec_select:V4HI
12473          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12474                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12475          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12476   "TARGET_SHMEDIA"
12477   "* return (TARGET_LITTLE_ENDIAN
12478              ? \"mshflo.w       %N1, %N2, %0\"
12479              : \"mshfhi.w       %N1, %N2, %0\");"
12480   [(set_attr "type" "arith_media")
12481    (set (attr "highpart")
12482         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12483          (const_string "user")))])
12485 (define_insn "mshflo_w_x"
12486   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12487         (vec_select:V4HI
12488          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12489                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12490          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12491   "TARGET_SHMEDIA"
12492   "mshflo.w     %N1, %N2, %0"
12493   [(set_attr "type" "arith_media")
12494    (set_attr "highpart" "ignore")])
12496 /* These are useful to expand ANDs and as combiner patterns.  */
12497 (define_insn_and_split "mshfhi_l_di"
12498   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12499         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12500                              (const_int 32))
12501                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12502                         (const_int -4294967296))))]
12503   "TARGET_SHMEDIA"
12504   "@
12505         mshfhi.l        %N1, %N2, %0
12506         #"
12507   "TARGET_SHMEDIA && reload_completed
12508    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12509   [(set (match_dup 3) (match_dup 4))
12510    (set (match_dup 5) (match_dup 6))]
12511   "
12513   operands[3] = gen_lowpart (SImode, operands[0]);
12514   operands[4] = gen_highpart (SImode, operands[1]);
12515   operands[5] = gen_highpart (SImode, operands[0]);
12516   operands[6] = gen_highpart (SImode, operands[2]);
12518   [(set_attr "type" "arith_media")])
12520 (define_insn "*mshfhi_l_di_rev"
12521   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12522         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12523                         (const_int -4294967296))
12524                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12525                              (const_int 32))))]
12526   "TARGET_SHMEDIA"
12527   "mshfhi.l     %N2, %N1, %0"
12528   [(set_attr "type" "arith_media")])
12530 (define_split
12531   [(set (match_operand:DI 0 "arith_reg_dest" "")
12532         (ior:DI (zero_extend:DI (match_operand:SI 1
12533                                               "extend_reg_or_0_operand" ""))
12534                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12535                         (const_int -4294967296))))
12536    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12537   "TARGET_SHMEDIA"
12538   [(const_int 0)]
12539   "
12541   emit_insn (gen_ashldi3_media (operands[3],
12542                                 simplify_gen_subreg (DImode, operands[1],
12543                                                      SImode, 0),
12544                                 GEN_INT (32)));
12545   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12546   DONE;
12549 (define_insn "mshflo_l_di"
12550   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12551         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12552                         (const_int 4294967295))
12553                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12554                            (const_int 32))))]
12556   "TARGET_SHMEDIA"
12557   "mshflo.l     %N1, %N2, %0"
12558   [(set_attr "type" "arith_media")
12559    (set_attr "highpart" "ignore")])
12561 (define_insn "*mshflo_l_di_rev"
12562   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12563         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12564                            (const_int 32))
12565                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12566                         (const_int 4294967295))))]
12568   "TARGET_SHMEDIA"
12569   "mshflo.l     %N2, %N1, %0"
12570   [(set_attr "type" "arith_media")
12571    (set_attr "highpart" "ignore")])
12573 ;; Combiner pattern for trampoline initialization.
12574 (define_insn_and_split "*double_shori"
12575   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12576         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12577                            (const_int 32))
12578                 (match_operand:DI 2 "const_int_operand" "n")))]
12579   "TARGET_SHMEDIA
12580    && ! (INTVAL (operands[2]) & ~(unsigned HOST_WIDE_INT) 0xffffffffUL)"
12581   "#"
12582   "rtx_equal_p (operands[0], operands[1])"
12583   [(const_int 0)]
12584   "
12586   HOST_WIDE_INT v = INTVAL (operands[2]);
12588   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v >> 16)));
12589   emit_insn (gen_shori_media (operands[0], operands[0], GEN_INT (v & 65535)));
12590   DONE;
12592   [(set_attr "highpart" "ignore")])
12595 (define_insn "*mshflo_l_di_x"
12596   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12597         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12598                                  "rZ"))
12599                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12600                            (const_int 32))))]
12602   "TARGET_SHMEDIA"
12603   "mshflo.l     %N1, %N2, %0"
12604   [(set_attr "type" "arith_media")
12605    (set_attr "highpart" "ignore")])
12607 (define_insn_and_split "concat_v2sf"
12608   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12609 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12610         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12611                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12613   "TARGET_SHMEDIA"
12614   "@
12615         mshflo.l        %N1, %N2, %0
12616         #
12617         #"
12618   "TARGET_SHMEDIA && reload_completed
12619    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12620   [(set (match_dup 3) (match_dup 1))
12621    (set (match_dup 4) (match_dup 2))]
12622   "
12624   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12625   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12627   [(set_attr "type" "arith_media")
12628    (set_attr "highpart" "ignore")])
12630 (define_insn "*mshflo_l_di_x_rev"
12631   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12632         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12633                            (const_int 32))
12634                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12636   "TARGET_SHMEDIA"
12637   "mshflo.l     %N2, %N1, %0"
12638   [(set_attr "type" "arith_media")
12639    (set_attr "highpart" "ignore")])
12641 (define_insn "ashlv2si3"
12642   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12643         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12644                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12645   "TARGET_SHMEDIA"
12646   "mshlld.l     %1, %2, %0"
12647   [(set_attr "type" "arith_media")
12648    (set_attr "highpart" "depend")])
12650 (define_split
12651   [(set (match_operand 0 "any_register_operand" "")
12652         (match_operator 3 "shift_operator"
12653           [(match_operand 1 "any_register_operand" "")
12654            (match_operand 2 "shift_count_reg_operand" "")]))]
12655   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12656   [(set (match_dup 0) (match_dup 3))]
12657   "
12659   rtx count = operands[2];
12660   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12662   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12663          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12664          || GET_CODE (count) == TRUNCATE)
12665     count = XEXP (count, 0);
12666   inner_mode = GET_MODE (count);
12667   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12668                                subreg_lowpart_offset (outer_mode, inner_mode));
12669   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12670                                 operands[1], count);
12673 (define_insn "ashlv4hi3"
12674   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12675         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12676                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12677   "TARGET_SHMEDIA"
12678   "mshlld.w     %1, %2, %0"
12679   [(set_attr "type" "arith_media")
12680    (set_attr "highpart" "depend")])
12682 (define_insn "lshrv2si3"
12683   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12684         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12685                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12686   "TARGET_SHMEDIA"
12687   "mshlrd.l     %1, %2, %0"
12688   [(set_attr "type" "arith_media")
12689    (set_attr "highpart" "depend")])
12691 (define_insn "lshrv4hi3"
12692   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12693         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12694                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12695   "TARGET_SHMEDIA"
12696   "mshlrd.w     %1, %2, %0"
12697   [(set_attr "type" "arith_media")
12698    (set_attr "highpart" "depend")])
12700 (define_insn "subv2si3"
12701   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12702         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12703                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12704   "TARGET_SHMEDIA"
12705   "msub.l       %N1, %2, %0"
12706   [(set_attr "type" "arith_media")
12707    (set_attr "highpart" "depend")])
12709 (define_insn "subv4hi3"
12710   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12711         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12712                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12713   "TARGET_SHMEDIA"
12714   "msub.w       %N1, %2, %0"
12715   [(set_attr "type" "arith_media")
12716    (set_attr "highpart" "depend")])
12718 (define_insn_and_split "subv2hi3"
12719   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12720         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12721                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12722   "TARGET_SHMEDIA"
12723   "#"
12724   "TARGET_SHMEDIA"
12725   [(const_int 0)]
12726   "
12728   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12729   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12730   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12731   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12732   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12734   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12735   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12736   DONE;
12738   [(set_attr "highpart" "must_split")])
12740 (define_insn "sssubv2si3"
12741   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12742         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12743                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12744   "TARGET_SHMEDIA"
12745   "msubs.l      %N1, %2, %0"
12746   [(set_attr "type" "mcmp_media")
12747    (set_attr "highpart" "depend")])
12749 (define_insn "ussubv8qi3"
12750   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12751         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12752                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12753   "TARGET_SHMEDIA"
12754   "msubs.ub     %N1, %2, %0"
12755   [(set_attr "type" "mcmp_media")
12756    (set_attr "highpart" "depend")])
12758 (define_insn "sssubv4hi3"
12759   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12760         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12761                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12762   "TARGET_SHMEDIA"
12763   "msubs.w      %N1, %2, %0"
12764   [(set_attr "type" "mcmp_media")
12765    (set_attr "highpart" "depend")])
12767 ;; Floating Point Intrinsics
12769 (define_insn "fcosa_s"
12770   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12771         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12772                    UNSPEC_FCOSA))]
12773   "TARGET_SHMEDIA"
12774   "fcosa.s      %1, %0"
12775   [(set_attr "type" "atrans_media")])
12777 (define_insn "fsina_s"
12778   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12779         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12780                    UNSPEC_FSINA))]
12781   "TARGET_SHMEDIA"
12782   "fsina.s      %1, %0"
12783   [(set_attr "type" "atrans_media")])
12785 (define_insn "fipr"
12786   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12787         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12788                                                     "fp_arith_reg_operand" "f")
12789                                                    (match_operand:V4SF 2
12790                                                     "fp_arith_reg_operand" "f"))
12791                                          (parallel [(const_int 0)]))
12792                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12793                                          (parallel [(const_int 1)])))
12794                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12795                                          (parallel [(const_int 2)]))
12796                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12797                                          (parallel [(const_int 3)])))))]
12798   "TARGET_SHMEDIA"
12799   "fipr.s       %1, %2, %0"
12800   [(set_attr "type" "fparith_media")])
12802 (define_insn "fsrra_s"
12803   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12804         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12805                    UNSPEC_FSRRA))]
12806   "TARGET_SHMEDIA"
12807   "fsrra.s      %1, %0"
12808   [(set_attr "type" "atrans_media")])
12810 (define_insn "ftrv"
12811   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12812         (plus:V4SF
12813          (plus:V4SF
12814           (mult:V4SF
12815            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12816                             (parallel [(const_int 0) (const_int 5)
12817                                        (const_int 10) (const_int 15)]))
12818            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12819           (mult:V4SF
12820            (vec_select:V4SF (match_dup 1)
12821                             (parallel [(const_int 4) (const_int 9)
12822                                        (const_int 14) (const_int 3)]))
12823            (vec_select:V4SF (match_dup 2)
12824                             (parallel [(const_int 1) (const_int 2)
12825                                        (const_int 3) (const_int 0)]))))
12826          (plus:V4SF
12827           (mult:V4SF
12828            (vec_select:V4SF (match_dup 1)
12829                             (parallel [(const_int 8) (const_int 13)
12830                                        (const_int 2) (const_int 7)]))
12831            (vec_select:V4SF (match_dup 2)
12832                             (parallel [(const_int 2) (const_int 3)
12833                                        (const_int 0) (const_int 1)])))
12834           (mult:V4SF
12835            (vec_select:V4SF (match_dup 1)
12836                             (parallel [(const_int 12) (const_int 1)
12837                                        (const_int 6) (const_int 11)]))
12838            (vec_select:V4SF (match_dup 2)
12839                             (parallel [(const_int 3) (const_int 0)
12840                                        (const_int 1) (const_int 2)]))))))]
12841   "TARGET_SHMEDIA"
12842   "ftrv.s %1, %2, %0"
12843   [(set_attr "type" "fparith_media")])
12845 (define_insn "ldhi_l"
12846   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12847         (zero_extract:SI
12848          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12849                                   (const_int 3))
12850                           (const_int -3)))
12851          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12852          (const_int 0)))]
12853   "TARGET_SHMEDIA32"
12854   "ldhi.l       %U1, %0"
12855   [(set_attr "type" "load_media")])
12857 (define_insn "ldhi_q"
12858   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12859         (zero_extract:DI
12860          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12861                                   (const_int 7))
12862                           (const_int -7)))
12863          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12864          (const_int 0)))]
12865   "TARGET_SHMEDIA32"
12866   "ldhi.q       %U1, %0"
12867   [(set_attr "type" "load_media")])
12869 (define_insn_and_split "*ldhi_q_comb0"
12870   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12871         (zero_extract:DI
12872          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12873                                             "register_operand" "r")
12874                                            (match_operand:SI 2
12875                                             "ua_offset" "I06"))
12876                                   (const_int 7))
12877                           (const_int -7)))
12878          (plus:SI (and:SI (match_dup 1) (const_int 7))
12879                   (const_int 1))
12880          (const_int 0)))]
12881   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12882   "#"
12883   ""
12884   [(pc)]
12885   "emit_insn (gen_ldhi_q (operands[0],
12886                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12887    DONE;")
12890 (define_insn_and_split "*ldhi_q_comb1"
12891   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12892         (zero_extract:DI
12893          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12894                                             "register_operand" "r")
12895                                            (match_operand:SI 2
12896                                             "ua_offset" "I06"))
12897                                   (const_int 7))
12898                           (const_int -7)))
12899          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12900                                                    "ua_offset" "I06"))
12901                           (const_int 7))
12902                   (const_int 1))
12903          (const_int 0)))]
12904   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12905    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12906   "#"
12907   ""
12908   [(pc)]
12909   "emit_insn (gen_ldhi_q (operands[0],
12910                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12911    DONE;")
12914 (define_insn "ldlo_l"
12915   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12916         (zero_extract:SI
12917          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12918                          (const_int -4)))
12919          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12920          (and:SI (match_dup 1) (const_int 3))))]
12921   "TARGET_SHMEDIA32"
12922   "ldlo.l       %U1, %0"
12923   [(set_attr "type" "load_media")])
12925 (define_insn "ldlo_q"
12926   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12927         (zero_extract:DI
12928          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12929                          (const_int -8)))
12930          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12931          (and:SI (match_dup 1) (const_int 7))))]
12932   "TARGET_SHMEDIA32"
12933   "ldlo.q       %U1, %0"
12934   [(set_attr "type" "load_media")])
12936 (define_insn_and_split "*ldlo_q_comb0"
12937   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12938         (zero_extract:DI
12939          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12940                                   (match_operand:SI 2 "ua_offset" "I06"))
12941                          (const_int -8)))
12942          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12943          (and:SI (match_dup 1) (const_int 7))))]
12944   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12945   "#"
12946   ""
12947   [(pc)]
12948   "emit_insn (gen_ldlo_q (operands[0],
12949                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12950    DONE;")
12952 (define_insn_and_split "*ldlo_q_comb1"
12953   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12954         (zero_extract:DI
12955          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12956                                   (match_operand:SI 2 "ua_offset" "I06"))
12957                          (const_int -8)))
12958          (minus:SI (const_int 8)
12959                    (and:SI (plus:SI (match_dup 1)
12960                                     (match_operand:SI 3 "ua_offset" "I06"))
12961                            (const_int 7)))
12962          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12963   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12964    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12965   "#"
12966   ""
12967   [(pc)]
12968   "emit_insn (gen_ldlo_q (operands[0],
12969                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12970    DONE;")
12972 (define_insn "sthi_l"
12973   [(set (zero_extract:SI
12974          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12975                                   (const_int 3))
12976                           (const_int -3)))
12977          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12978          (const_int 0))
12979         (match_operand:SI 1 "arith_reg_operand" "r"))]
12980   "TARGET_SHMEDIA32"
12981   "sthi.l       %U0, %1"
12982   [(set_attr "type" "ustore_media")])
12984 ;; All unaligned stores are considered to be 'narrow' because they typically
12985 ;; operate on less that a quadword, and when they operate on a full quadword,
12986 ;; the vanilla store high / store low sequence will cause a stall if not
12987 ;; scheduled apart.
12988 (define_insn "sthi_q"
12989   [(set (zero_extract:DI
12990          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12991                                   (const_int 7))
12992                           (const_int -7)))
12993          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12994          (const_int 0))
12995         (match_operand:DI 1 "arith_reg_operand" "r"))]
12996   "TARGET_SHMEDIA32"
12997   "sthi.q       %U0, %1"
12998   [(set_attr "type" "ustore_media")])
13000 (define_insn_and_split "*sthi_q_comb0"
13001   [(set (zero_extract:DI
13002          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13003                                             "register_operand" "r")
13004                                            (match_operand:SI 1 "ua_offset"
13005                                             "I06"))
13006                                   (const_int 7))
13007                           (const_int -7)))
13008          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
13009          (const_int 0))
13010         (match_operand:DI 2 "arith_reg_operand" "r"))]
13011   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13012   "#"
13013   ""
13014   [(pc)]
13015   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13016                           operands[2]));
13017    DONE;")
13019 (define_insn_and_split "*sthi_q_comb1"
13020   [(set (zero_extract:DI
13021          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
13022                                             "register_operand" "r")
13023                                            (match_operand:SI 1 "ua_offset"
13024                                             "I06"))
13025                                   (const_int 7))
13026                           (const_int -7)))
13027          (plus:SI (and:SI (plus:SI (match_dup 0)
13028                                    (match_operand:SI 2 "ua_offset" "I06"))
13029                           (const_int 7))
13030                   (const_int 1))
13031          (const_int 0))
13032         (match_operand:DI 3 "arith_reg_operand" "r"))]
13033   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
13034    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13035   "#"
13036   ""
13037   [(pc)]
13038   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13039                           operands[3]));
13040    DONE;")
13042 ;; This is highpart user because the address is used as full 64 bit.
13043 (define_insn "stlo_l"
13044   [(set (zero_extract:SI
13045          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13046                          (const_int -4)))
13047          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
13048          (and:SI (match_dup 0) (const_int 3)))
13049         (match_operand:SI 1 "arith_reg_operand" "r"))]
13050   "TARGET_SHMEDIA32"
13051   "stlo.l       %U0, %1"
13052   [(set_attr "type" "ustore_media")])
13054 (define_insn "stlo_q"
13055   [(set (zero_extract:DI
13056          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
13057                          (const_int -8)))
13058          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13059          (and:SI (match_dup 0) (const_int 7)))
13060         (match_operand:DI 1 "arith_reg_operand" "r"))]
13061   "TARGET_SHMEDIA32"
13062   "stlo.q       %U0, %1"
13063   [(set_attr "type" "ustore_media")])
13065 (define_insn_and_split "*stlo_q_comb0"
13066   [(set (zero_extract:DI
13067          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13068                                   (match_operand:SI 1 "ua_offset" "I06"))
13069                          (const_int -8)))
13070          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
13071          (and:SI (match_dup 0) (const_int 7)))
13072         (match_operand:DI 2 "arith_reg_operand" "r"))]
13073   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
13074   "#"
13075   ""
13076   [(pc)]
13077   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13078                           operands[2]));
13079    DONE;")
13081 (define_insn_and_split "*stlo_q_comb1"
13082   [(set (zero_extract:DI
13083          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
13084                                   (match_operand:SI 1 "ua_offset" "I06"))
13085                          (const_int -8)))
13086          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
13087                                                   (match_operand:SI 2
13088                                                    "ua_offset" "I06"))
13089                                          (const_int 7)))
13090          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
13091         (match_operand:DI 3 "arith_reg_operand" "r"))]
13092   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
13093   "#"
13094   ""
13095   [(pc)]
13096   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
13097                           operands[3]));
13098    DONE;")
13100 (define_insn "ldhi_l64"
13101   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13102         (zero_extract:SI
13103          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13104                                   (const_int 3))
13105                           (const_int -3)))
13106          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
13107          (const_int 0)))]
13108   "TARGET_SHMEDIA64"
13109   "ldhi.l       %U1, %0"
13110   [(set_attr "type" "load_media")])
13112 (define_insn "ldhi_q64"
13113   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13114         (zero_extract:DI
13115          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
13116                                   (const_int 7))
13117                           (const_int -7)))
13118          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
13119          (const_int 0)))]
13120   "TARGET_SHMEDIA64"
13121   "ldhi.q       %U1, %0"
13122   [(set_attr "type" "load_media")])
13124 (define_insn "ldlo_l64"
13125   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13126         (zero_extract:SI
13127          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13128                          (const_int -4)))
13129          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
13130          (and:DI (match_dup 1) (const_int 3))))]
13131   "TARGET_SHMEDIA64"
13132   "ldlo.l       %U1, %0"
13133   [(set_attr "type" "load_media")])
13135 (define_insn "ldlo_q64"
13136   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13137         (zero_extract:DI
13138          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
13139                          (const_int -8)))
13140          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
13141          (and:DI (match_dup 1) (const_int 7))))]
13142   "TARGET_SHMEDIA64"
13143   "ldlo.q       %U1, %0"
13144   [(set_attr "type" "load_media")])
13146 (define_insn "sthi_l64"
13147   [(set (zero_extract:SI
13148          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13149                                   (const_int 3))
13150                           (const_int -3)))
13151          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
13152          (const_int 0))
13153         (match_operand:SI 1 "arith_reg_operand" "r"))]
13154   "TARGET_SHMEDIA64"
13155   "sthi.l       %U0, %1"
13156   [(set_attr "type" "ustore_media")])
13158 (define_insn "sthi_q64"
13159   [(set (zero_extract:DI
13160          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
13161                                   (const_int 7))
13162                           (const_int -7)))
13163          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
13164          (const_int 0))
13165         (match_operand:DI 1 "arith_reg_operand" "r"))]
13166   "TARGET_SHMEDIA64"
13167   "sthi.q       %U0, %1"
13168   [(set_attr "type" "ustore_media")])
13170 (define_insn "stlo_l64"
13171   [(set (zero_extract:SI
13172          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13173                          (const_int -4)))
13174          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
13175          (and:DI (match_dup 0) (const_int 3)))
13176         (match_operand:SI 1 "arith_reg_operand" "r"))]
13177   "TARGET_SHMEDIA64"
13178   "stlo.l       %U0, %1"
13179   [(set_attr "type" "ustore_media")])
13181 (define_insn "stlo_q64"
13182   [(set (zero_extract:DI
13183          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
13184                          (const_int -8)))
13185          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
13186          (and:DI (match_dup 0) (const_int 7)))
13187         (match_operand:DI 1 "arith_reg_operand" "r"))]
13188   "TARGET_SHMEDIA64"
13189   "stlo.q       %U0, %1"
13190   [(set_attr "type" "ustore_media")])
13192 (define_insn "nsb"
13193   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
13194         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13195                    UNSPEC_NSB))]
13196   "TARGET_SHMEDIA"
13197   "nsb  %1, %0"
13198   [(set_attr "type" "arith_media")])
13200 (define_insn "nsbsi"
13201   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
13202         (zero_extend:SI
13203          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13204                     UNSPEC_NSB)))]
13205   "TARGET_SHMEDIA"
13206   "nsb  %1, %0"
13207   [(set_attr "type" "arith_media")])
13209 (define_insn "nsbdi"
13210   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
13211         (zero_extend:DI
13212          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
13213                     UNSPEC_NSB)))]
13214   "TARGET_SHMEDIA"
13215   "nsb  %1, %0"
13216   [(set_attr "type" "arith_media")])
13218 (define_expand "ffsdi2"
13219   [(set (match_operand:DI 0 "arith_reg_dest" "")
13220         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13221   "TARGET_SHMEDIA"
13222   "
13224   rtx scratch = gen_reg_rtx (DImode);
13225   rtx last;
13227   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13228   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13229   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13230   emit_insn (gen_nsbdi (scratch, scratch));
13231   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13232   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13233   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13234   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (DImode, operands[0]));
13236   DONE;
13239 (define_expand "ffssi2"
13240   [(set (match_operand:SI 0 "arith_reg_dest" "")
13241         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13242   "TARGET_SHMEDIA"
13243   "
13245   rtx scratch = gen_reg_rtx (SImode);
13246   rtx discratch = gen_reg_rtx (DImode);
13247   rtx last;
13249   emit_insn (gen_adddi3 (discratch,
13250                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13251                          constm1_rtx));
13252   emit_insn (gen_andcdi3 (discratch,
13253                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13254                           discratch));
13255   emit_insn (gen_nsbsi (scratch, discratch));
13256   last = emit_insn (gen_subsi3 (operands[0],
13257                                 force_reg (SImode, GEN_INT (63)), scratch));
13258   set_unique_reg_note (last, REG_EQUAL, gen_rtx_FFS (SImode, operands[0]));
13260   DONE;
13263 (define_insn "byterev"
13264   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13265         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13266                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13267                                     (const_int 4) (const_int 3) (const_int 2)
13268                                     (const_int 1) (const_int 0)])))]
13269   "TARGET_SHMEDIA"
13270   "byterev      %1, %0"
13271   [(set_attr "type" "arith_media")])
13273 (define_insn "*prefetch_media"
13274   [(prefetch (match_operand:QI 0 "address_operand" "p")
13275              (match_operand:SI 1 "const_int_operand" "n")
13276              (match_operand:SI 2 "const_int_operand" "n"))]
13277   "TARGET_SHMEDIA"
13278   "*
13280   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13281   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13282   return \"\";
13284   [(set_attr "type" "other")])
13286 (define_insn "*prefetch_i4"
13287   [(prefetch (match_operand:SI 0 "register_operand" "r")
13288              (match_operand:SI 1 "const_int_operand" "n")
13289              (match_operand:SI 2 "const_int_operand" "n"))]
13290   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && !TARGET_VXWORKS_RTP"
13291   "*
13293   return \"pref @%0\";
13295   [(set_attr "type" "other")])
13297 ;; In user mode, the "pref" instruction will raise a RADDERR exception
13298 ;; for accesses to [0x80000000,0xffffffff].  This makes it an unsuitable
13299 ;; implementation of __builtin_prefetch for VxWorks RTPs.
13300 (define_expand "prefetch"
13301   [(prefetch (match_operand 0 "address_operand" "p")
13302              (match_operand:SI 1 "const_int_operand" "n")
13303              (match_operand:SI 2 "const_int_operand" "n"))]
13304   "TARGET_SH2A || ((TARGET_HARD_SH4 || TARGET_SH5)
13305    && (TARGET_SHMEDIA || !TARGET_VXWORKS_RTP))"
13306   "
13308   if (GET_MODE (operands[0]) != Pmode
13309       || !CONST_INT_P (operands[1])
13310       || !CONST_INT_P (operands[2]))
13311     FAIL;
13312   if (! TARGET_SHMEDIA)
13313     operands[0] = force_reg (Pmode, operands[0]);
13316 (define_insn "prefetch_m2a"
13317   [(prefetch (match_operand:SI 0 "register_operand" "r")
13318              (match_operand:SI 1 "const_int_operand" "n")
13319              (match_operand:SI 2 "const_int_operand" "n"))]
13320   "TARGET_SH2A"
13321   "pref\\t@%0"
13322   [(set_attr "type" "other")])
13324 (define_insn "alloco_i"
13325   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13326         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13327   "TARGET_SHMEDIA32"
13328   "*
13330   rtx xops[2];
13332   if (GET_CODE (operands[0]) == PLUS)
13333     {
13334       xops[0] = XEXP (operands[0], 0);
13335       xops[1] = XEXP (operands[0], 1);
13336     }
13337   else
13338     {
13339       xops[0] = operands[0];
13340       xops[1] = const0_rtx;
13341     }
13342   output_asm_insn (\"alloco   %0, %1\", xops);
13343   return \"\";
13345   [(set_attr "type" "other")])
13347 (define_split
13348   [(set (match_operand 0 "any_register_operand" "")
13349         (match_operand 1 "" ""))]
13350   "TARGET_SHMEDIA && reload_completed"
13351   [(set (match_dup 0) (match_dup 1))]
13352   "
13354   int n_changes = 0;
13356   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13357   if (!n_changes)
13358     FAIL;
13361 ; Stack Protector Patterns
13363 (define_expand "stack_protect_set"
13364   [(set (match_operand 0 "memory_operand" "")
13365         (match_operand 1 "memory_operand" ""))]
13366   ""
13368   if (TARGET_SHMEDIA)
13369     {
13370       if (TARGET_SHMEDIA64)
13371         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13372       else
13373         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13374     }
13375   else
13376     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13378   DONE;
13381 (define_insn "stack_protect_set_si"
13382   [(set (match_operand:SI 0 "memory_operand" "=m")
13383         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13384    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13385   "!TARGET_SHMEDIA"
13386   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13387   [(set_attr "type" "other")
13388    (set_attr "length" "6")])
13390 (define_insn "stack_protect_set_si_media"
13391   [(set (match_operand:SI 0 "memory_operand" "=m")
13392         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13393    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13394   "TARGET_SHMEDIA"
13395   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13396   [(set_attr "type" "other")
13397    (set_attr "length" "12")])
13399 (define_insn "stack_protect_set_di_media"
13400   [(set (match_operand:DI 0 "memory_operand" "=m")
13401         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13402    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13403   "TARGET_SHMEDIA64"
13404   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13405   [(set_attr "type" "other")
13406    (set_attr "length" "12")])
13408 (define_expand "stack_protect_test"
13409   [(match_operand 0 "memory_operand" "")
13410    (match_operand 1 "memory_operand" "")
13411    (match_operand 2 "" "")]
13412   ""
13414   if (TARGET_SHMEDIA)
13415     {
13416       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13417       rtx test;
13419       test = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
13420       if (TARGET_SHMEDIA64)
13421         {
13422           emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13423                                                       operands[1]));
13424           emit_jump_insn (gen_cbranchdi4 (test, tmp, const0_rtx, operands[2]));
13425         }
13426       else
13427         {
13428           emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13429                                                       operands[1]));
13430           emit_jump_insn (gen_cbranchsi4 (test, tmp, const0_rtx, operands[2]));
13431         }
13432     }
13433   else
13434     {
13435       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13436       emit_jump_insn (gen_branch_true (operands[2]));
13437     }
13439   DONE;
13442 (define_insn "stack_protect_test_si"
13443   [(set (reg:SI T_REG)
13444         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13445                     (match_operand:SI 1 "memory_operand" "m")]
13446                    UNSPEC_SP_TEST))
13447   (set (match_scratch:SI 2 "=&r") (const_int 0))
13448   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13449   "!TARGET_SHMEDIA"
13450   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13451   [(set_attr "type" "other")
13452    (set_attr "length" "10")])
13454 (define_insn "stack_protect_test_si_media"
13455   [(set (match_operand:SI 0 "register_operand" "=&r")
13456         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13457                     (match_operand:SI 2 "memory_operand" "m")]
13458                    UNSPEC_SP_TEST))
13459   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13460   "TARGET_SHMEDIA"
13461   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13462   [(set_attr "type" "other")
13463    (set_attr "length" "16")])
13465 (define_insn "stack_protect_test_di_media"
13466   [(set (match_operand:DI 0 "register_operand" "=&r")
13467         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13468                     (match_operand:DI 2 "memory_operand" "m")]
13469                    UNSPEC_SP_TEST))
13470   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13471   "TARGET_SHMEDIA64"
13472   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13473   [(set_attr "type" "other")
13474    (set_attr "length" "16")])