Update FSF address.
[official-gcc.git] / gcc / config / sh / sh.md
blobad2e0e78b0dc99ef216da0d7c602bfb0875f97c8
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004, 2005 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 ;; Boston, MA 02110-1301, USA.
25 ;; ??? Should prepend a * to all pattern names which are not used.
26 ;; This will make the compiler smaller, and rebuilds after changes faster.
28 ;; ??? Should be enhanced to include support for many more GNU superoptimizer
29 ;; sequences.  Especially the sequences for arithmetic right shifts.
31 ;; ??? Should check all DImode patterns for consistency and usefulness.
33 ;; ??? The MAC.W and MAC.L instructions are not supported.  There is no
34 ;; way to generate them.
36 ;; ??? The cmp/str instruction is not supported.  Perhaps it can be used
37 ;; for a str* inline function.
39 ;; BSR is not generated by the compiler proper, but when relaxing, it
40 ;; generates .uses pseudo-ops that allow linker relaxation to create
41 ;; BSR.  This is actually implemented in bfd/{coff,elf32}-sh.c
43 ;; Special constraints for SH machine description:
45 ;;    t -- T
46 ;;    x -- mac
47 ;;    l -- pr
48 ;;    z -- r0
50 ;; Special formats used for outputting SH instructions:
52 ;;   %.  --  print a .s if insn needs delay slot
53 ;;   %@  --  print rte/rts if is/isn't an interrupt function
54 ;;   %#  --  output a nop if there is nothing to put in the delay slot
55 ;;   %O  --  print a constant without the #
56 ;;   %R  --  print the lsw reg of a double
57 ;;   %S  --  print the msw reg of a double
58 ;;   %T  --  print next word of a double REG or MEM
60 ;; Special predicates:
62 ;;  arith_operand          -- operand is valid source for arithmetic op
63 ;;  arith_reg_operand      -- operand is valid register for arithmetic op
64 ;;  general_movdst_operand -- operand is valid move destination
65 ;;  general_movsrc_operand -- operand is valid move source
66 ;;  logical_operand        -- operand is valid source for logical op
68 ;; -------------------------------------------------------------------------
69 ;; Constants
70 ;; -------------------------------------------------------------------------
72 (define_constants [
73   (AP_REG       145)
74   (PR_REG       146)
75   (T_REG        147)
76   (GBR_REG      144)
77   (MACH_REG     148)
78   (MACL_REG     149)
79   (FPUL_REG     150)
80   (RAP_REG      152)
82   (FPSCR_REG    151)
84   (PIC_REG      12)
85   (FP_REG       14)
86   (SP_REG       15)
88   (PR_MEDIA_REG 18)
89   (T_MEDIA_REG  19)
91   (R0_REG       0)
92   (R1_REG       1)
93   (R2_REG       2)
94   (R3_REG       3)
95   (R4_REG       4)
96   (R5_REG       5)
97   (R6_REG       6)
98   (R7_REG       7)
99   (R8_REG       8)
100   (R9_REG       9)
101   (R10_REG      10)
102   (R20_REG      20)
103   (R21_REG      21)
104   (R22_REG      22)
105   (R23_REG      23)
107   (DR0_REG      64)
108   (DR2_REG      66)
109   (DR4_REG      68)
110   (FR23_REG     87)
112   (TR0_REG      128)
113   (TR1_REG      129)
114   (TR2_REG      130)
116   (XD0_REG      136)
118   ;; These are used with unspec.
119   (UNSPEC_COMPACT_ARGS  0)
120   (UNSPEC_MOVA          1)
121   (UNSPEC_CASESI        2)
122   (UNSPEC_DATALABEL     3)
123   (UNSPEC_BBR           4)
124   (UNSPEC_SFUNC         5)
125   (UNSPEC_PIC           6)
126   (UNSPEC_GOT           7)
127   (UNSPEC_GOTOFF        8)
128   (UNSPEC_PLT           9)
129   (UNSPEC_CALLER        10)
130   (UNSPEC_GOTPLT        11)
131   (UNSPEC_ICACHE        12)
132   (UNSPEC_INIT_TRAMP    13)
133   (UNSPEC_FCOSA         14)
134   (UNSPEC_FSRRA         15)
135   (UNSPEC_FSINA         16)
136   (UNSPEC_NSB           17)
137   (UNSPEC_ALLOCO        18)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
146   (UNSPEC_DIV_INV_M0    30)
147   (UNSPEC_DIV_INV_M1    31)
148   (UNSPEC_DIV_INV_M2    32)
149   (UNSPEC_DIV_INV_M3    33)
150   (UNSPEC_DIV_INV20     34)
151   (UNSPEC_ASHIFTRT      35)
152   (UNSPEC_THUNK         36)
154   ;; These are used with unspec_volatile.
155   (UNSPECV_BLOCKAGE     0)
156   (UNSPECV_ALIGN        1)
157   (UNSPECV_CONST2       2)
158   (UNSPECV_CONST4       4)
159   (UNSPECV_CONST8       6)
160   (UNSPECV_WINDOW_END   10)
161   (UNSPECV_CONST_END    11)
164 ;; -------------------------------------------------------------------------
165 ;; Attributes
166 ;; -------------------------------------------------------------------------
168 ;; Target CPU.
170 (define_attr "cpu"
171  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
172   (const (symbol_ref "sh_cpu_attr")))
174 (define_attr "endian" "big,little"
175  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
176                       (const_string "little") (const_string "big"))))
178 ;; Indicate if the default fpu mode is single precision.
179 (define_attr "fpu_single" "yes,no"
180   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
181                          (const_string "yes") (const_string "no"))))
183 (define_attr "fmovd" "yes,no"
184   (const (if_then_else (symbol_ref "TARGET_FMOVD")
185                        (const_string "yes") (const_string "no"))))
186 ;; pipeline model
187 (define_attr "pipe_model" "sh1,sh4,sh5media"
188   (const
189    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
190           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
191          (const_string "sh1"))))
193 ;; cbranch      conditional branch instructions
194 ;; jump         unconditional jumps
195 ;; arith        ordinary arithmetic
196 ;; arith3       a compound insn that behaves similarly to a sequence of
197 ;;              three insns of type arith
198 ;; arith3b      like above, but might end with a redirected branch
199 ;; load         from memory
200 ;; load_si      Likewise, SImode variant for general register.
201 ;; fload        Likewise, but load to fp register.
202 ;; store        to memory
203 ;; move         general purpose register to register
204 ;; mt_group     other sh4 mt instructions
205 ;; fmove        register to register, floating point
206 ;; smpy         word precision integer multiply
207 ;; dmpy         longword or doublelongword precision integer multiply
208 ;; return       rts
209 ;; pload        load of pr reg, which can't be put into delay slot of rts
210 ;; prset        copy register to pr reg, ditto
211 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
212 ;; prget        copy pr to register, ditto
213 ;; pcload       pc relative load of constant value
214 ;; pcfload      Likewise, but load to fp register.
215 ;; pcload_si    Likewise, SImode variant for general register.
216 ;; rte          return from exception
217 ;; sfunc        special function call with known used registers
218 ;; call         function call
219 ;; fp           floating point
220 ;; fdiv         floating point divide (or square root)
221 ;; gp_fpul      move from general purpose register to fpul
222 ;; fpul_gp      move from fpul to general purpose register
223 ;; mac_gp       move from mac[lh] to general purpose register
224 ;; dfp_arith, dfp_cmp,dfp_conv
225 ;; ftrc_s       fix_truncsfsi2_i4
226 ;; dfdiv        double precision floating point divide (or square root)
227 ;; cwb          ic_invalidate_line_i
228 ;; movua        SH4a unaligned load
229 ;; fsrra        square root reciprocal approximate
230 ;; fsca         sine and cosine approximate
231 ;; tls_load     load TLS related address
232 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
233 ;; cbranch_media SHmedia conditional branch instructions
234 ;; cmp_media    SHmedia compare instructions
235 ;; dfdiv_media  SHmedia double precision divide and square root
236 ;; dfmul_media  SHmedia double precision multiply instruction
237 ;; dfparith_media SHmedia double precision floating point arithmetic
238 ;; dfpconv_media SHmedia double precision floating point conversions
239 ;; dmpy_media   SHmedia longword multiply
240 ;; fcmp_media   SHmedia floating point compare instructions
241 ;; fdiv_media   SHmedia single precision divide and square root
242 ;; fload_media  SHmedia floating point register load instructions
243 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
244 ;; fparith_media SHmedia single precision floating point arithmetic
245 ;; fpconv_media SHmedia single precision floating point conversions
246 ;; fstore_media SHmedia floating point register store instructions
247 ;; gettr_media  SHmedia gettr instruction
248 ;; invalidate_line_media SHmedia invalidate_line sequence
249 ;; jump_media   SHmedia unconditional branch instructions
250 ;; load_media   SHmedia general register load instructions
251 ;; pt_media     SHmedia pt instruction (expanded by assembler)
252 ;; ptabs_media  SHmedia ptabs instruction
253 ;; store_media  SHmedia general register store instructions
254 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
255 ;; mac_media    SHmedia mac-style fixed point operations
256 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
257 ;; atrans_media SHmedia approximate transcendental functions
258 ;; ustore_media SHmedia unaligned stores
259 ;; nil          no-op move, will be deleted.
261 (define_attr "type"
262  "mt_group,cbranch,jump,jump_ind,arith,arith3,arith3b,dyn_shift,load,load_si,fload,store,move,fmove,smpy,dmpy,return,pload,prset,pstore,prget,pcload,pcload_si,pcfload,rte,sfunc,call,fp,fdiv,ftrc_s,dfp_arith,dfp_cmp,dfp_conv,dfdiv,gp_fpul,fpul_gp,mac_gp,mem_fpscr,gp_fpscr,cwb,movua,fsrra,fsca,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
263   (const_string "other"))
265 ;; We define a new attribute namely "insn_class".We use
266 ;; this for the DFA based pipeline description.
268 ;; mt_group      SH4 "mt" group instructions.
270 ;; ex_group      SH4 "ex" group instructions.
272 ;; ls_group      SH4 "ls" group instructions.
275 (define_attr "insn_class"
276   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
277   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
278          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
279          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
280          (eq_attr "type" "cbranch,jump") (const_string "br_group")
281          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
282            (const_string "fe_group")
283          (eq_attr "type" "jump_ind,smpy,dmpy,mac_gp,return,pload,prset,pstore,prget,rte,sfunc,call,dfp_cmp,mem_fpscr,gp_fpscr,cwb") (const_string "co_group")]
284         (const_string "none")))
285 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
286 ;; so these do not belong in an insn group, although they are modeled
287 ;; with their own define_insn_reservations.
289 ;; Indicate what precision must be selected in fpscr for this insn, if any.
291 (define_attr "fp_mode" "single,double,none" (const_string "none"))
293 ;; Indicate if the fpu mode is set by this instruction
294 ;; "unknown" must have the value as "none" in fp_mode, and means
295 ;; that the instruction/abi has left the processor in an unknown
296 ;; state.
297 ;; "none" means that nothing has changed and no mode is set.
298 ;; This attribute is only used for the Renesas ABI.
299 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
301 ; If a conditional branch destination is within -252..258 bytes away
302 ; from the instruction it can be 2 bytes long.  Something in the
303 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
304 ; branches are initially assumed to be 16 bytes long.
305 ; In machine_dependent_reorg, we split all branches that are longer than
306 ; 2 bytes.
308 ;; The maximum range used for SImode constant pool entries is 1018.  A final
309 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
310 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
311 ;; instruction around the pool table, 2 bytes of alignment before the table,
312 ;; and 30 bytes of alignment after the table.  That gives a maximum total
313 ;; pool size of 1058 bytes.
314 ;; Worst case code/pool content size ratio is 1:2 (using asms).
315 ;; Thus, in the worst case, there is one instruction in front of a maximum
316 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
317 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
318 ;; If we have a forward branch, the initial table will be put after the
319 ;; unconditional branch.
321 ;; ??? We could do much better by keeping track of the actual pcloads within
322 ;; the branch range and in the pcload range in front of the branch range.
324 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
325 ;; inside an le.
326 (define_attr "short_cbranch_p" "no,yes"
327   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
328          (const_string "no")
329          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
330          (const_string "yes")
331          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
332          (const_string "no")
333          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
334          (const_string "yes")
335          ] (const_string "no")))
337 (define_attr "med_branch_p" "no,yes"
338   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
339               (const_int 1988))
340          (const_string "yes")
341          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
342          (const_string "no")
343          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
344               (const_int 8186))
345          (const_string "yes")
346          ] (const_string "no")))
348 (define_attr "med_cbranch_p" "no,yes"
349   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
350               (const_int 1986))
351          (const_string "yes")
352          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
353          (const_string "no")
354          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
355                (const_int 8184))
356          (const_string "yes")
357          ] (const_string "no")))
359 (define_attr "braf_branch_p" "no,yes"
360   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
361          (const_string "no")
362          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
363               (const_int 20660))
364          (const_string "yes")
365          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
366          (const_string "no")
367          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
368               (const_int 65530))
369          (const_string "yes")
370          ] (const_string "no")))
372 (define_attr "braf_cbranch_p" "no,yes"
373   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
374          (const_string "no")
375          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
376               (const_int 20658))
377          (const_string "yes")
378          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
379          (const_string "no")
380          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
381               (const_int 65528))
382          (const_string "yes")
383          ] (const_string "no")))
385 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
386 ; For wider ranges, we need a combination of a code and a data part.
387 ; If we can get a scratch register for a long range jump, the code
388 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
389 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
390 ; long; otherwise, it must be 6 bytes long.
392 ; All other instructions are two bytes long by default.
394 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
395 ;; but getattrtab doesn't understand this.
396 (define_attr "length" ""
397   (cond [(eq_attr "type" "cbranch")
398          (cond [(eq_attr "short_cbranch_p" "yes")
399                 (const_int 2)
400                 (eq_attr "med_cbranch_p" "yes")
401                 (const_int 6)
402                 (eq_attr "braf_cbranch_p" "yes")
403                 (const_int 12)
404 ;; ??? using pc is not computed transitively.
405                 (ne (match_dup 0) (match_dup 0))
406                 (const_int 14)
407                 (ne (symbol_ref ("flag_pic")) (const_int 0))
408                 (const_int 24)
409                 ] (const_int 16))
410          (eq_attr "type" "jump")
411          (cond [(eq_attr "med_branch_p" "yes")
412                 (const_int 2)
413                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
414                          (symbol_ref "INSN"))
415                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
416                          (symbol_ref "code_for_indirect_jump_scratch")))
417                 (cond [(eq_attr "braf_branch_p" "yes")
418                        (const_int 6)
419                        (eq (symbol_ref "flag_pic") (const_int 0))
420                        (const_int 10)
421                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
422                        (const_int 10)] (const_int 18))
423                 (eq_attr "braf_branch_p" "yes")
424                 (const_int 10)
425 ;; ??? using pc is not computed transitively.
426                 (ne (match_dup 0) (match_dup 0))
427                 (const_int 12)
428                 (ne (symbol_ref ("flag_pic")) (const_int 0))
429                 (const_int 22)
430                 ] (const_int 14))
431          (eq_attr "type" "pt_media")
432          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
433                        (const_int 20) (const_int 12))
434          (and (eq_attr "type" "jump_media")
435               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
436          (const_int 8)
437          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
438                          (const_int 4)
439                          (const_int 2))))
441 ;; DFA descriptions for the pipelines
443 (include "sh1.md")
444 (include "shmedia.md")
445 (include "sh4.md")
447 (include "predicates.md")
449 ;; Definitions for filling delay slots
451 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
453 ;; ??? This should be (nil) instead of (const_int 0)
454 (define_attr "hit_stack" "yes,no"
455         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
456                    (const_int 0))
457                (const_string "no")]
458               (const_string "yes")))
460 (define_attr "interrupt_function" "no,yes"
461   (const (symbol_ref "current_function_interrupt")))
463 (define_attr "in_delay_slot" "yes,no"
464   (cond [(eq_attr "type" "cbranch") (const_string "no")
465          (eq_attr "type" "pcload,pcload_si") (const_string "no")
466          (eq_attr "needs_delay_slot" "yes") (const_string "no")
467          (eq_attr "length" "2") (const_string "yes")
468          ] (const_string "no")))
470 (define_attr "cond_delay_slot" "yes,no"
471   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
472          ] (const_string "no")))
474 (define_attr "is_sfunc" ""
475   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
477 (define_attr "is_mac_media" ""
478   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
480 (define_attr "branch_zero" "yes,no"
481   (cond [(eq_attr "type" "!cbranch") (const_string "no")
482          (ne (symbol_ref "(next_active_insn (insn)\
483                            == (prev_active_insn\
484                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
485                           && get_attr_length (next_active_insn (insn)) == 2")
486              (const_int 0))
487          (const_string "yes")]
488         (const_string "no")))
490 ;; SH4 Double-precision computation with double-precision result -
491 ;; the two halves are ready at different times.
492 (define_attr "dfp_comp" "yes,no"
493   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
494         (const_string "no")))
496 ;; Insns for which the latency of a preceding fp insn is decreased by one.
497 (define_attr "late_fp_use" "yes,no" (const_string "no"))
498 ;; And feeding insns for which this relevant.
499 (define_attr "any_fp_comp" "yes,no"
500   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
501          (const_string "yes")]
502         (const_string "no")))
504 (define_attr "any_int_load" "yes,no"
505   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
506          (const_string "yes")]
507         (const_string "no")))
509 (define_attr "highpart" "user, ignore, extend, depend, must_split"
510   (const_string "user"))
512 (define_delay
513   (eq_attr "needs_delay_slot" "yes")
514   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
516 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
517 ;; and thus we can't put a pop instruction in its delay slot.
518 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
519 ;; instruction can go in the delay slot.
521 ;; Since a normal return (rts) implicitly uses the PR register,
522 ;; we can't allow PR register loads in an rts delay slot.
524 (define_delay
525   (eq_attr "type" "return")
526   [(and (eq_attr "in_delay_slot" "yes")
527         (ior (and (eq_attr "interrupt_function" "no")
528                   (eq_attr "type" "!pload,prset"))
529              (and (eq_attr "interrupt_function" "yes")
530                   (ior
531                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
532                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
534 ;; Since a call implicitly uses the PR register, we can't allow
535 ;; a PR register store in a jsr delay slot.
537 (define_delay
538   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
539   [(and (eq_attr "in_delay_slot" "yes")
540         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
542 ;; Say that we have annulled true branches, since this gives smaller and
543 ;; faster code when branches are predicted as not taken.
545 ;; ??? The non-annulled condition should really be "in_delay_slot",
546 ;; but insns that can be filled in non-annulled get priority over insns
547 ;; that can only be filled in anulled.
549 (define_delay
550   (and (eq_attr "type" "cbranch")
551        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
552   ;; SH2e has a hardware bug that pretty much prohibits the use of
553   ;; annuled delay slots.
554   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
555                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
557 ;; -------------------------------------------------------------------------
558 ;; SImode signed integer comparisons
559 ;; -------------------------------------------------------------------------
561 (define_insn ""
562   [(set (reg:SI T_REG)
563         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
564                        (match_operand:SI 1 "arith_operand" "K08,r"))
565                (const_int 0)))]
566   "TARGET_SH1"
567   "tst  %1,%0"
568   [(set_attr "type" "mt_group")])
570 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
571 ;; That would still allow reload to create cmpi instructions, but would
572 ;; perhaps allow forcing the constant into a register when that is better.
573 ;; Probably should use r0 for mem/imm compares, but force constant into a
574 ;; register for pseudo/imm compares.
576 (define_insn "cmpeqsi_t"
577   [(set (reg:SI T_REG)
578         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
579                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
580   "TARGET_SH1"
581   "@
582         tst     %0,%0
583         cmp/eq  %1,%0
584         cmp/eq  %1,%0"
585    [(set_attr "type" "mt_group")])
587 (define_insn "cmpgtsi_t"
588   [(set (reg:SI T_REG)
589         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
590                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
591   "TARGET_SH1"
592   "@
593         cmp/gt  %1,%0
594         cmp/pl  %0"
595    [(set_attr "type" "mt_group")])
597 (define_insn "cmpgesi_t"
598   [(set (reg:SI T_REG)
599         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
600                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
601   "TARGET_SH1"
602   "@
603         cmp/ge  %1,%0
604         cmp/pz  %0"
605    [(set_attr "type" "mt_group")])
607 ;; -------------------------------------------------------------------------
608 ;; SImode unsigned integer comparisons
609 ;; -------------------------------------------------------------------------
611 (define_insn "cmpgeusi_t"
612   [(set (reg:SI T_REG)
613         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
614                 (match_operand:SI 1 "arith_reg_operand" "r")))]
615   "TARGET_SH1"
616   "cmp/hs       %1,%0"
617    [(set_attr "type" "mt_group")])
619 (define_insn "cmpgtusi_t"
620   [(set (reg:SI T_REG)
621         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
622                 (match_operand:SI 1 "arith_reg_operand" "r")))]
623   "TARGET_SH1"
624   "cmp/hi       %1,%0"
625    [(set_attr "type" "mt_group")])
627 ;; We save the compare operands in the cmpxx patterns and use them when
628 ;; we generate the branch.
630 (define_expand "cmpsi"
631   [(set (reg:SI T_REG)
632         (compare (match_operand:SI 0 "cmpsi_operand" "")
633                  (match_operand:SI 1 "arith_operand" "")))]
634   "TARGET_SH1 || TARGET_SHMEDIA"
635   "
637   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
638       && GET_CODE (operands[1]) != CONST_INT)
639     operands[0] = copy_to_mode_reg (SImode, operands[0]);
640   sh_compare_op0 = operands[0];
641   sh_compare_op1 = operands[1];
642   DONE;
645 ;; -------------------------------------------------------------------------
646 ;; DImode signed integer comparisons
647 ;; -------------------------------------------------------------------------
649 ;; ??? Could get better scheduling by splitting the initial test from the
650 ;; rest of the insn after reload.  However, the gain would hardly justify
651 ;; the sh.md size increase necessary to do that.
653 (define_insn ""
654   [(set (reg:SI T_REG)
655         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
656                        (match_operand:DI 1 "arith_operand" "r"))
657                (const_int 0)))]
658   "TARGET_SH1"
659   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
660                                  insn, operands);"
661   [(set_attr "length" "6")
662    (set_attr "type" "arith3b")])
664 (define_insn "cmpeqdi_t"
665   [(set (reg:SI T_REG)
666         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
667                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
668   "TARGET_SH1"
669   "@
670         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
671         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
672   [(set_attr "length" "6")
673    (set_attr "type" "arith3b")])
675 (define_split
676   [(set (reg:SI T_REG)
677         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
678                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
679 ;; If we applied this split when not optimizing, it would only be
680 ;; applied during the machine-dependent reorg, when no new basic blocks
681 ;; may be created.
682   "TARGET_SH1 && reload_completed && optimize"
683   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
684    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
685                            (label_ref (match_dup 6))
686                            (pc)))
687    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
688    (match_dup 6)]
689   "
691   operands[2]
692     = gen_rtx_REG (SImode,
693                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
694   operands[3]
695     = (operands[1] == const0_rtx
696        ? const0_rtx
697        : gen_rtx_REG (SImode,
698                       true_regnum (operands[1])
699                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
700   operands[4] = gen_lowpart (SImode, operands[0]);
701   operands[5] = gen_lowpart (SImode, operands[1]);
702   operands[6] = gen_label_rtx ();
705 (define_insn "cmpgtdi_t"
706   [(set (reg:SI T_REG)
707         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
708                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
709   "TARGET_SH2"
710   "@
711         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
712         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
713   [(set_attr "length" "8")
714    (set_attr "type" "arith3")])
716 (define_insn "cmpgedi_t"
717   [(set (reg:SI T_REG)
718         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
719                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
720   "TARGET_SH2"
721   "@
722         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
723         cmp/pz\\t%S0"
724   [(set_attr "length" "8,2")
725    (set_attr "type" "arith3,mt_group")])
727 ;; -------------------------------------------------------------------------
728 ;; DImode unsigned integer comparisons
729 ;; -------------------------------------------------------------------------
731 (define_insn "cmpgeudi_t"
732   [(set (reg:SI T_REG)
733         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
734                 (match_operand:DI 1 "arith_reg_operand" "r")))]
735   "TARGET_SH2"
736   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
737   [(set_attr "length" "8")
738    (set_attr "type" "arith3")])
740 (define_insn "cmpgtudi_t"
741   [(set (reg:SI T_REG)
742         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
743                 (match_operand:DI 1 "arith_reg_operand" "r")))]
744   "TARGET_SH2"
745   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
746   [(set_attr "length" "8")
747    (set_attr "type" "arith3")])
749 (define_insn "cmpeqsi_media"
750   [(set (match_operand:DI 0 "register_operand" "=r")
751         (eq:DI (match_operand:SI 1 "logical_operand" "%r")
752                (match_operand:SI 2 "cmp_operand" "Nr")))]
753   "TARGET_SHMEDIA"
754   "cmpeq        %1, %N2, %0"
755   [(set_attr "type" "cmp_media")])
757 (define_insn "cmpeqdi_media"
758   [(set (match_operand:DI 0 "register_operand" "=r")
759         (eq:DI (match_operand:DI 1 "register_operand" "%r")
760                (match_operand:DI 2 "cmp_operand" "Nr")))]
761   "TARGET_SHMEDIA"
762   "cmpeq        %1, %N2, %0"
763   [(set_attr "type" "cmp_media")])
765 (define_insn "cmpgtsi_media"
766   [(set (match_operand:DI 0 "register_operand" "=r")
767         (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
768                (match_operand:SI 2 "cmp_operand" "rN")))]
769   "TARGET_SHMEDIA"
770   "cmpgt        %N1, %N2, %0"
771   [(set_attr "type" "cmp_media")])
773 (define_insn "cmpgtdi_media"
774   [(set (match_operand:DI 0 "register_operand" "=r")
775         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
776                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
777   "TARGET_SHMEDIA"
778   "cmpgt        %N1, %N2, %0"
779   [(set_attr "type" "cmp_media")])
781 (define_insn "cmpgtusi_media"
782   [(set (match_operand:DI 0 "register_operand" "=r")
783         (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
784                 (match_operand:SI 2 "cmp_operand" "rN")))]
785   "TARGET_SHMEDIA"
786   "cmpgtu       %N1, %N2, %0"
787   [(set_attr "type" "cmp_media")])
789 (define_insn "cmpgtudi_media"
790   [(set (match_operand:DI 0 "register_operand" "=r")
791         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
792                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
793   "TARGET_SHMEDIA"
794   "cmpgtu       %N1, %N2, %0"
795   [(set_attr "type" "cmp_media")])
797 (define_insn "cmpsieqsi_media"
798   [(set (match_operand:SI 0 "register_operand" "=r")
799         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
800                (match_operand:SI 2 "cmp_operand" "Nr")))]
801   "TARGET_SHMEDIA"
802   "cmpeq        %1, %N2, %0"
803   [(set_attr "type" "cmp_media")])
805 (define_insn "cmpsieqdi_media"
806   [(set (match_operand:SI 0 "register_operand" "=r")
807         (eq:SI (match_operand:DI 1 "register_operand" "%r")
808                (match_operand:DI 2 "cmp_operand" "Nr")))]
809   "TARGET_SHMEDIA"
810   "cmpeq        %1, %N2, %0"
811   [(set_attr "type" "cmp_media")])
813 (define_insn "cmpsigtsi_media"
814   [(set (match_operand:SI 0 "register_operand" "=r")
815         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
816                (match_operand:SI 2 "cmp_operand" "rN")))]
817   "TARGET_SHMEDIA"
818   "cmpgt        %N1, %N2, %0"
819   [(set_attr "type" "cmp_media")])
821 (define_insn "cmpsigtdi_media"
822   [(set (match_operand:SI 0 "register_operand" "=r")
823         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
824                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
825   "TARGET_SHMEDIA"
826   "cmpgt        %N1, %N2, %0"
827   [(set_attr "type" "cmp_media")])
829 (define_insn "cmpsigtusi_media"
830   [(set (match_operand:SI 0 "register_operand" "=r")
831         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
832                 (match_operand:SI 2 "cmp_operand" "rN")))]
833   "TARGET_SHMEDIA"
834   "cmpgtu       %N1, %N2, %0"
835   [(set_attr "type" "cmp_media")])
837 (define_insn "cmpsigtudi_media"
838   [(set (match_operand:SI 0 "register_operand" "=r")
839         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
840                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
841   "TARGET_SHMEDIA"
842   "cmpgtu       %N1, %N2, %0"
843   [(set_attr "type" "cmp_media")])
845 ; These two patterns are for combine.
846 (define_insn "*cmpne0si_media"
847   [(set (match_operand:DI 0 "register_operand" "=r")
848         (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
849   "TARGET_SHMEDIA"
850   "cmpgtu       %1,r63,%0"
851   [(set_attr "type" "cmp_media")])
853 (define_insn "*cmpne0sisi_media"
854   [(set (match_operand:SI 0 "register_operand" "=r")
855         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
856   "TARGET_SHMEDIA"
857   "cmpgtu       %1,r63,%0"
858   [(set_attr "type" "cmp_media")])
860 ;; We save the compare operands in the cmpxx patterns and use them when
861 ;; we generate the branch.
863 (define_expand "cmpdi"
864   [(set (reg:SI T_REG)
865         (compare (match_operand:DI 0 "arith_operand" "")
866                  (match_operand:DI 1 "arith_operand" "")))]
867   "TARGET_SH2 || TARGET_SHMEDIA"
868   "
870   sh_compare_op0 = operands[0];
871   sh_compare_op1 = operands[1];
872   DONE;
874 ;; -------------------------------------------------------------------------
875 ;; Conditional move instructions
876 ;; -------------------------------------------------------------------------
878 ;; The insn names may seem reversed, but note that cmveq performs the move
879 ;; if op1 == 0, and cmvne does it if op1 != 0.
881 (define_insn "movdicc_false"
882   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
883         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
884                              (const_int 0))
885          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
886          (match_operand:DI 3 "arith_reg_operand" "0")))]
887   "TARGET_SHMEDIA"
888   "cmveq        %1, %N2, %0"
889   [(set_attr "type" "arith_media")])
891 (define_insn "movdicc_true"
892   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
893         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
894                              (const_int 0))
895          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
896          (match_operand:DI 3 "arith_reg_operand" "0")))]
897   "TARGET_SHMEDIA"
898   "cmvne        %1, %N2, %0"
899   [(set_attr "type" "arith_media")])
901 (define_peephole2
902   [(set (match_operand:DI 0 "arith_reg_dest" "")
903         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
904                            [(match_operand:DI 1 "arith_reg_operand" "")
905                             (const_int 0)])
906          (match_operand:DI 2 "arith_reg_dest" "")
907          (match_dup 0)))
908    (set (match_dup 2) (match_dup 0))]
909   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
910   [(set (match_dup 2)
911         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
912   "
914   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
915                                 VOIDmode, operands[1], CONST0_RTX (DImode));
918 (define_peephole2
919   [(set (match_operand:DI 0 "general_movdst_operand" "")
920         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
921    (set (match_operand:DI 2 "arith_reg_dest" "")
922         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
923                            [(match_operand:DI 3 "arith_reg_operand" "")
924                             (const_int 0)])
925          (match_dup 0)
926          (match_dup 2)))]
927   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
928   [(set (match_dup 2)
929         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
930   "")
932 (define_expand "movdicc"
933   [(set (match_operand:DI 0 "register_operand" "")
934         (if_then_else:DI (match_operand 1 "comparison_operator" "")
935                          (match_operand:DI 2 "register_operand" "")
936                          (match_operand:DI 3 "register_operand" "")))]
937   "TARGET_SHMEDIA"
938   "
940   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
941       && GET_MODE (sh_compare_op0) == DImode
942       && sh_compare_op1 == const0_rtx)
943     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
944                                   sh_compare_op0, sh_compare_op1);
945   else
946     {
947       rtx tmp;
949       if (no_new_pseudos)
950         FAIL;
952       tmp = gen_reg_rtx (DImode);
954       switch (GET_CODE (operands[1]))
955         {
956         case EQ:
957           emit_insn (gen_seq (tmp));
958           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
959           break;
961         case NE:
962           emit_insn (gen_seq (tmp));
963           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
964           break;
966         case GT:
967           emit_insn (gen_sgt (tmp));
968           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
969           break;
971         case LT:
972           emit_insn (gen_slt (tmp));
973           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
974           break;
976         case GE:
977           emit_insn (gen_slt (tmp));
978           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
979           break;
981         case LE:
982           emit_insn (gen_sgt (tmp));
983           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
984           break;
986         case GTU:
987           emit_insn (gen_sgtu (tmp));
988           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
989           break;
991         case LTU:
992           emit_insn (gen_sltu (tmp));
993           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
994           break;
996         case GEU:
997           emit_insn (gen_sltu (tmp));
998           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
999           break;
1001         case LEU:
1002           emit_insn (gen_sgtu (tmp));
1003           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1004           break;
1006         case UNORDERED:
1007           emit_insn (gen_sunordered (tmp));
1008           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1009           break;
1011         case ORDERED:
1012           emit_insn (gen_sunordered (tmp));
1013           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1014           break;
1016         case UNEQ:
1017         case UNGE:
1018         case UNGT:
1019         case UNLE:
1020         case UNLT:
1021         case LTGT:
1022           FAIL;
1024         default:
1025           gcc_unreachable ();
1026         }
1027     }
1030 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1031 ;; SImode to DImode.
1032 (define_insn "movsicc_false"
1033   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1034         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1035                           (const_int 0))
1036          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1037          (match_operand:SI 3 "arith_reg_operand" "0")))]
1038   "TARGET_SHMEDIA"
1039   "cmveq        %1, %N2, %0"
1040   [(set_attr "type" "arith_media")])
1042 (define_insn "movsicc_true"
1043   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1044         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1045                           (const_int 0))
1046          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1047          (match_operand:SI 3 "arith_reg_operand" "0")))]
1048   "TARGET_SHMEDIA"
1049   "cmvne        %1, %N2, %0"
1050   [(set_attr "type" "arith_media")])
1052 (define_peephole2
1053   [(set (match_operand:SI 0 "arith_reg_dest" "")
1054         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1055                            [(match_operand:SI 1 "arith_reg_operand" "")
1056                             (const_int 0)])
1057          (match_operand:SI 2 "arith_reg_dest" "")
1058          (match_dup 0)))
1059    (set (match_dup 2) (match_dup 0))]
1060   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1061   [(set (match_dup 2)
1062         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1063   "
1065   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1066                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1069 (define_peephole2
1070   [(set (match_operand:SI 0 "general_movdst_operand" "")
1071         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1072    (set (match_operand:SI 2 "arith_reg_dest" "")
1073         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1074                            [(match_operand:SI 3 "arith_reg_operand" "")
1075                             (const_int 0)])
1076          (match_dup 0)
1077          (match_dup 2)))]
1078   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1079    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1080   [(set (match_dup 2)
1081         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1082   "
1084   replace_rtx (operands[4], operands[0], operands[1]);
1087 (define_peephole2
1088   [(set (match_operand 0 "any_register_operand" "")
1089         (match_operand 1 "any_register_operand" ""))
1090    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1091    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1092   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1093     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1094    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1095    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1096    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1097    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1098    && (REGNO_REG_CLASS (REGNO (operands[0]))
1099        == REGNO_REG_CLASS (REGNO (operands[2])))
1100    && (REGNO_REG_CLASS (REGNO (operands[1]))
1101        == REGNO_REG_CLASS (REGNO (operands[0])))"
1102   [(set (match_dup 0) (match_dup 3))
1103    (set (match_dup 4) (match_dup 5))]
1104   "
1106   rtx set1, set2;
1107   rtx replacements[4];
1109   /* We want to replace occurrences of operands[0] with operands[1] and
1110      operands[2] with operands[0] in operands[4]/operands[5].
1111      Doing just two replace_rtx calls naively would result in the second
1112      replacement undoing all that the first did if operands[1] and operands[2]
1113      are identical, so we must do this simultaneously.  */
1114   replacements[0] = operands[0];
1115   replacements[1] = operands[1];
1116   replacements[2] = operands[2];
1117   replacements[3] = operands[0];
1118   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1119       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1120       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1121     FAIL;
1123   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1124   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1125   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1126   /* The operands array is aliased to recog_data.operand, which gets
1127      clobbered by extract_insn, so finish with it now.  */
1128   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1129   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1130   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1131      always uses emit_insn.  */
1132   /* Check that we don't violate matching constraints or earlyclobbers.  */
1133   extract_insn (emit_insn (set1));
1134   if (! constrain_operands (1))
1135     goto failure;
1136   extract_insn (emit (set2));
1137   if (! constrain_operands (1))
1138     {
1139       rtx tmp;
1140     failure:
1141       tmp = replacements[0];
1142       replacements[0] = replacements[1];
1143       replacements[1] = tmp;
1144       tmp = replacements[2];
1145       replacements[2] = replacements[3];
1146       replacements[3] = tmp;
1147       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1148       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1149       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1150       FAIL;
1151     }
1152   DONE;
1155 ;; The register allocator is rather clumsy in handling multi-way conditional
1156 ;; moves, so allow the combiner to make them, and we split them up after
1157 ;; reload.  */
1158 (define_insn_and_split "*movsicc_umin"
1159   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1160         (umin:SI (if_then_else:SI
1161                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1162                        (const_int 0))
1163                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1164                    (match_operand:SI 3 "register_operand" "0"))
1165                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1166    (clobber (match_scratch:SI 5 "=&r"))]
1167   "TARGET_SHMEDIA && no_new_pseudos"
1168   "#"
1169   "TARGET_SHMEDIA && reload_completed"
1170   [(pc)]
1171   "
1173   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1174                                 operands[3]));
1175   emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1176   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1177                                 operands[0]));
1178   DONE;
1181 (define_expand "movsicc"
1182   [(set (match_operand:SI 0 "register_operand" "")
1183         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1184                          (match_operand:SI 2 "register_operand" "")
1185                          (match_operand:SI 3 "register_operand" "")))]
1186   "TARGET_SHMEDIA"
1187   "
1189   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1190       && GET_MODE (sh_compare_op0) == SImode
1191       && sh_compare_op1 == const0_rtx)
1192     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1193                                   sh_compare_op0, sh_compare_op1);
1194   else
1195     {
1196       rtx tmp;
1198       if (no_new_pseudos)
1199         FAIL;
1201       tmp = gen_reg_rtx (SImode);
1203       switch (GET_CODE (operands[1]))
1204         {
1205         case EQ:
1206           emit_insn (gen_seq (tmp));
1207           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1208           break;
1210         case NE:
1211           emit_insn (gen_seq (tmp));
1212           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1213           break;
1215         case GT:
1216           emit_insn (gen_sgt (tmp));
1217           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1218           break;
1220         case LT:
1221           emit_insn (gen_slt (tmp));
1222           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1223           break;
1225         case GE:
1226           emit_insn (gen_slt (tmp));
1227           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1228           break;
1230         case LE:
1231           emit_insn (gen_sgt (tmp));
1232           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1233           break;
1235         case GTU:
1236           emit_insn (gen_sgtu (tmp));
1237           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1238           break;
1240         case LTU:
1241           emit_insn (gen_sltu (tmp));
1242           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1243           break;
1245         case GEU:
1246           emit_insn (gen_sltu (tmp));
1247           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1248           break;
1250         case LEU:
1251           emit_insn (gen_sgtu (tmp));
1252           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1253           break;
1255         case UNORDERED:
1256           emit_insn (gen_sunordered (tmp));
1257           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1258           break;
1260         case ORDERED:
1261           emit_insn (gen_sunordered (tmp));
1262           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1263           break;
1265         case UNEQ:
1266         case UNGE:
1267         case UNGT:
1268         case UNLE:
1269         case UNLT:
1270         case LTGT:
1271           FAIL;
1273         default:
1274           abort ();
1275         }
1276     }
1279 (define_expand "movqicc"
1280   [(set (match_operand:QI 0 "register_operand" "")
1281         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1282                          (match_operand:QI 2 "register_operand" "")
1283                          (match_operand:QI 3 "register_operand" "")))]
1284   "TARGET_SHMEDIA"
1285   "
1287   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1288   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1289   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1290   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1291   DONE;
1294 ;; -------------------------------------------------------------------------
1295 ;; Addition instructions
1296 ;; -------------------------------------------------------------------------
1298 (define_expand "adddi3"
1299   [(set (match_operand:DI 0 "arith_reg_operand" "")
1300         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1301                  (match_operand:DI 2 "arith_operand" "")))]
1302   ""
1303   "
1305   if (TARGET_SH1)
1306     {
1307       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1308         FAIL;
1309       operands[2] = force_reg (DImode, operands[2]);
1310       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1311       DONE;
1312     }
1315 (define_insn "*adddi3_media"
1316   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1317         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1318                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1319   "TARGET_SHMEDIA"
1320   "@
1321         add     %1, %2, %0
1322         addi    %1, %2, %0"
1323   [(set_attr "type" "arith_media")])
1325 (define_insn "*adddisi3_media"
1326   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1327         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1328                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1329   "TARGET_SHMEDIA"
1330   "@
1331         add.l   %1, %2, %0
1332         addi.l  %1, %2, %0"
1333   [(set_attr "type" "arith_media")
1334    (set_attr "highpart" "ignore")])
1336 (define_insn "adddi3z_media"
1337   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1338         (zero_extend:DI
1339          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1340                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1341   "TARGET_SHMEDIA"
1342   "addz.l       %1, %N2, %0"
1343   [(set_attr "type" "arith_media")
1344    (set_attr "highpart" "ignore")])
1346 (define_insn "adddi3_compact"
1347   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1348         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1349                  (match_operand:DI 2 "arith_reg_operand" "r")))
1350    (clobber (reg:SI T_REG))]
1351   "TARGET_SH1"
1352   "#"
1353   [(set_attr "length" "6")])
1355 (define_split
1356   [(set (match_operand:DI 0 "arith_reg_dest" "")
1357         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1358                  (match_operand:DI 2 "arith_reg_operand" "")))
1359    (clobber (reg:SI T_REG))]
1360   "TARGET_SH1 && reload_completed"
1361   [(const_int 0)]
1362   "
1364   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1365   high0 = gen_rtx_REG (SImode,
1366                        true_regnum (operands[0])
1367                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1368   high2 = gen_rtx_REG (SImode,
1369                        true_regnum (operands[2])
1370                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1371   emit_insn (gen_clrt ());
1372   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1373   emit_insn (gen_addc1 (high0, high0, high2));
1374   DONE;
1377 (define_insn "addc"
1378   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1379         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1380                           (match_operand:SI 2 "arith_reg_operand" "r"))
1381                  (reg:SI T_REG)))
1382    (set (reg:SI T_REG)
1383         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1384   "TARGET_SH1"
1385   "addc %2,%0"
1386   [(set_attr "type" "arith")])
1388 (define_insn "addc1"
1389   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1390         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1391                           (match_operand:SI 2 "arith_reg_operand" "r"))
1392                  (reg:SI T_REG)))
1393    (clobber (reg:SI T_REG))]
1394   "TARGET_SH1"
1395   "addc %2,%0"
1396   [(set_attr "type" "arith")])
1398 (define_expand "addsi3"
1399   [(set (match_operand:SI 0 "arith_reg_operand" "")
1400         (plus:SI (match_operand:SI 1 "arith_operand" "")
1401                  (match_operand:SI 2 "arith_operand" "")))]
1402   ""
1403   "
1405   if (TARGET_SHMEDIA)
1406     operands[1] = force_reg (SImode, operands[1]);
1409 (define_insn "addsi3_media"
1410   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1411         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1412                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1413   "TARGET_SHMEDIA"
1414   "@
1415         add.l   %1, %2, %0
1416         addi.l  %1, %2, %0"
1417   [(set_attr "type" "arith_media")
1418    (set_attr "highpart" "ignore")])
1420 (define_insn "addsidi3_media"
1421   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1422         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1423                                   "%r,r")
1424                                  (match_operand:SI 2 "arith_operand"
1425                                   "r,I10"))))]
1426   "TARGET_SHMEDIA"
1427   "@
1428         add.l   %1, %2, %0
1429         addi.l  %1, %2, %0"
1430   [(set_attr "type" "arith_media")
1431    (set_attr "highpart" "ignore")])
1433 (define_insn "*addsi3_compact"
1434   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1435         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1436                  (match_operand:SI 2 "arith_operand" "rI08")))]
1437   "TARGET_SH1"
1438   "add  %2,%0"
1439   [(set_attr "type" "arith")])
1441 ;; -------------------------------------------------------------------------
1442 ;; Subtraction instructions
1443 ;; -------------------------------------------------------------------------
1445 (define_expand "subdi3"
1446   [(set (match_operand:DI 0 "arith_reg_operand" "")
1447         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1448                   (match_operand:DI 2 "arith_reg_operand" "")))]
1449   ""
1450   "
1452   if (TARGET_SH1)
1453     {
1454       operands[1] = force_reg (DImode, operands[1]);
1455       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1456       DONE;
1457     }
1460 (define_insn "*subdi3_media"
1461   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1462         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1463                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1464   "TARGET_SHMEDIA"
1465   "sub  %N1, %2, %0"
1466   [(set_attr "type" "arith_media")])
1467   
1468 (define_insn "subdisi3_media"
1469   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1470         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1471                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1472   "TARGET_SHMEDIA"
1473   "sub.l        %N1, %2, %0"
1474   [(set_attr "type" "arith_media")
1475    (set_attr "highpart" "ignore")])
1477 (define_insn "subdi3_compact"
1478   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1479         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1480                  (match_operand:DI 2 "arith_reg_operand" "r")))
1481    (clobber (reg:SI T_REG))]
1482   "TARGET_SH1"
1483   "#"
1484   [(set_attr "length" "6")])
1486 (define_split
1487   [(set (match_operand:DI 0 "arith_reg_dest" "")
1488         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1489                   (match_operand:DI 2 "arith_reg_operand" "")))
1490    (clobber (reg:SI T_REG))]
1491   "TARGET_SH1 && reload_completed"
1492   [(const_int 0)]
1493   "
1495   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1496   high0 = gen_rtx_REG (SImode,
1497                        true_regnum (operands[0])
1498                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1499   high2 = gen_rtx_REG (SImode,
1500                        true_regnum (operands[2])
1501                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1502   emit_insn (gen_clrt ());
1503   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1504   emit_insn (gen_subc1 (high0, high0, high2));
1505   DONE;
1508 (define_insn "subc"
1509   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1510         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1511                             (match_operand:SI 2 "arith_reg_operand" "r"))
1512                   (reg:SI T_REG)))
1513    (set (reg:SI T_REG)
1514         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1515                           (reg:SI T_REG))
1516                 (match_dup 1)))]
1517   "TARGET_SH1"
1518   "subc %2,%0"
1519   [(set_attr "type" "arith")])
1521 (define_insn "subc1"
1522   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1523         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1524                             (match_operand:SI 2 "arith_reg_operand" "r"))
1525                   (reg:SI T_REG)))
1526    (clobber (reg:SI T_REG))]
1527   "TARGET_SH1"
1528   "subc %2,%0"
1529   [(set_attr "type" "arith")])
1531 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1532 ;; pattern for this case.  This helps multimedia applications that compute
1533 ;; the sum of absolute differences.
1534 (define_insn "mov_neg_si_t"
1535   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1536   "TARGET_SH1"
1537   "subc %0,%0"
1538   [(set_attr "type" "arith")])
1540 (define_insn "*subsi3_internal"
1541   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1542         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1543                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1544   "TARGET_SH1"
1545   "sub  %2,%0"
1546   [(set_attr "type" "arith")])
1548 (define_insn_and_split "*subsi3_media"
1549   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1550         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1551                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1552   "TARGET_SHMEDIA
1553    && (operands[1] != constm1_rtx
1554        || (GET_CODE (operands[2]) != TRUNCATE
1555            && GET_CODE (operands[2]) != SUBREG))"
1556   "sub.l        %N1, %2, %0"
1557   "operands[1] == constm1_rtx"
1558   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1559   ""
1560   [(set_attr "type" "arith_media")
1561    (set_attr "highpart" "ignore")])
1563 (define_split
1564   [(set (match_operand:SI 0 "arith_reg_dest" "")
1565         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1566                                                        "general_extend_operand"
1567                                                        "") 0)) 0)))]
1568   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1569   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1570    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1571   "")
1573 (define_split
1574   [(set (match_operand:SI 0 "arith_reg_dest" "")
1575         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1576                                                        "general_extend_operand"
1577                                                        "") 0)) 3)))]
1578   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1579   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1580    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1581   "")
1582 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1583 ;; will sometimes save one instruction.  Otherwise we might get
1584 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1585 ;; are the same.
1587 (define_expand "subsi3"
1588   [(set (match_operand:SI 0 "arith_reg_operand" "")
1589         (minus:SI (match_operand:SI 1 "arith_operand" "")
1590                   (match_operand:SI 2 "arith_reg_operand" "")))]
1591   ""
1592   "
1594   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1595     {
1596       emit_insn (gen_negsi2 (operands[0], operands[2]));
1597       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1598       DONE;
1599     }
1600   if (TARGET_SHMEDIA)
1601     {
1602       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1603         FAIL;
1604       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1605         operands[1] = force_reg (SImode, operands[1]);
1606     }
1609 ;; -------------------------------------------------------------------------
1610 ;; Division instructions
1611 ;; -------------------------------------------------------------------------
1613 ;; We take advantage of the library routines which don't clobber as many
1614 ;; registers as a normal function call would.
1616 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1617 ;; also has an effect on the register that holds the address of the sfunc.
1618 ;; To make this work, we have an extra dummy insn that shows the use
1619 ;; of this register for reorg.
1621 (define_insn "use_sfunc_addr"
1622   [(set (reg:SI PR_REG)
1623         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1624   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1625   ""
1626   [(set_attr "length" "0")])
1628 (define_insn "udivsi3_sh2a"
1629   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1630         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1631                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1632   "TARGET_SH2A"
1633   "divu %2,%1"
1634   [(set_attr "type" "arith")
1635    (set_attr "in_delay_slot" "no")])
1637 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1638 ;; hard register 0.  If we used hard register 0, then the next instruction
1639 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1640 ;; gets allocated to a stack slot that needs its address reloaded, then
1641 ;; there is nothing to prevent reload from using r0 to reload the address.
1642 ;; This reload would clobber the value in r0 we are trying to store.
1643 ;; If we let reload allocate r0, then this problem can never happen.
1645 (define_insn "udivsi3_i1"
1646   [(set (match_operand:SI 0 "register_operand" "=z")
1647         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1648    (clobber (reg:SI T_REG))
1649    (clobber (reg:SI PR_REG))
1650    (clobber (reg:SI R4_REG))
1651    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1652   "TARGET_SH1 && ! TARGET_SH4"
1653   "jsr  @%1%#"
1654   [(set_attr "type" "sfunc")
1655    (set_attr "needs_delay_slot" "yes")])
1657 ; Since shmedia-nofpu code could be linked against shcompact code, and
1658 ; the udivsi3 libcall has the same name, we must consider all registers
1659 ; clobbered that are in the union of the registers clobbered by the
1660 ; shmedia and the shcompact implementation.  Note, if the shcompact
1661 ; implementation actually used shcompact code, we'd need to clobber
1662 ; also r23 and fr23.
1663 (define_insn "udivsi3_i1_media"
1664   [(set (match_operand:SI 0 "register_operand" "=z")
1665         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1666    (clobber (reg:SI T_MEDIA_REG))
1667    (clobber (reg:SI PR_MEDIA_REG))
1668    (clobber (reg:SI R20_REG))
1669    (clobber (reg:SI R21_REG))
1670    (clobber (reg:SI R22_REG))
1671    (clobber (reg:DI TR0_REG))
1672    (clobber (reg:DI TR1_REG))
1673    (clobber (reg:DI TR2_REG))
1674    (use (match_operand 1 "target_operand" "b"))]
1675   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1676   "blink        %1, r18"
1677   [(set_attr "type" "sfunc")
1678    (set_attr "needs_delay_slot" "yes")])
1680 (define_expand "udivsi3_i4_media"
1681   [(set (match_dup 3)
1682         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1683    (set (match_dup 4)
1684         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1685    (set (match_dup 5) (float:DF (match_dup 3)))
1686    (set (match_dup 6) (float:DF (match_dup 4)))
1687    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1688    (set (match_dup 8) (fix:DI (match_dup 7)))
1689    (set (match_operand:SI 0 "register_operand" "")
1690         (truncate:SI (match_dup 8)))]
1691   "TARGET_SHMEDIA_FPU"
1692   "
1694   operands[3] = gen_reg_rtx (DImode);
1695   operands[4] = gen_reg_rtx (DImode);
1696   operands[5] = gen_reg_rtx (DFmode);
1697   operands[6] = gen_reg_rtx (DFmode);
1698   operands[7] = gen_reg_rtx (DFmode);
1699   operands[8] = gen_reg_rtx (DImode);
1702 (define_insn "udivsi3_i4"
1703   [(set (match_operand:SI 0 "register_operand" "=y")
1704         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1705    (clobber (reg:SI T_REG))
1706    (clobber (reg:SI PR_REG))
1707    (clobber (reg:DF DR0_REG))
1708    (clobber (reg:DF DR2_REG))
1709    (clobber (reg:DF DR4_REG))
1710    (clobber (reg:SI R0_REG))
1711    (clobber (reg:SI R1_REG))
1712    (clobber (reg:SI R4_REG))
1713    (clobber (reg:SI R5_REG))
1714    (use (reg:PSI FPSCR_REG))
1715    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1716   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1717   "jsr  @%1%#"
1718   [(set_attr "type" "sfunc")
1719    (set_attr "fp_mode" "double")
1720    (set_attr "needs_delay_slot" "yes")])
1722 (define_insn "udivsi3_i4_single"
1723   [(set (match_operand:SI 0 "register_operand" "=y")
1724         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1725    (clobber (reg:SI T_REG))
1726    (clobber (reg:SI PR_REG))
1727    (clobber (reg:DF DR0_REG))
1728    (clobber (reg:DF DR2_REG))
1729    (clobber (reg:DF DR4_REG))
1730    (clobber (reg:SI R0_REG))
1731    (clobber (reg:SI R1_REG))
1732    (clobber (reg:SI R4_REG))
1733    (clobber (reg:SI R5_REG))
1734    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1735   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1736   "jsr  @%1%#"
1737   [(set_attr "type" "sfunc")
1738    (set_attr "needs_delay_slot" "yes")])
1740 (define_expand "udivsi3"
1741   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1742    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1743    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1744    (parallel [(set (match_operand:SI 0 "register_operand" "")
1745                    (udiv:SI (reg:SI R4_REG)
1746                             (reg:SI R5_REG)))
1747               (clobber (reg:SI T_REG))
1748               (clobber (reg:SI PR_REG))
1749               (clobber (reg:SI R4_REG))
1750               (use (match_dup 3))])]
1751   ""
1752   "
1754   rtx first, last;
1756   operands[3] = gen_reg_rtx (Pmode);
1757   /* Emit the move of the address to a pseudo outside of the libcall.  */
1758   if (TARGET_HARD_SH4 && TARGET_SH2E)
1759     {
1760       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1761       if (TARGET_FPU_SINGLE)
1762         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1763       else
1764         last = gen_udivsi3_i4 (operands[0], operands[3]);
1765     }
1766   else if (TARGET_SHMEDIA_FPU)
1767     {
1768       operands[1] = force_reg (SImode, operands[1]);
1769       operands[2] = force_reg (SImode, operands[2]);
1770       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1771       DONE;
1772     }
1773   else if (TARGET_SH2A)
1774     {
1775       operands[1] = force_reg (SImode, operands[1]);
1776       operands[2] = force_reg (SImode, operands[2]);
1777       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1778       DONE;
1779     }
1780   else if (TARGET_SH5)
1781     {
1782       function_symbol (operands[3],
1783                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1784                        SFUNC_STATIC);
1786       if (TARGET_SHMEDIA)
1787         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1788       else if (TARGET_FPU_ANY)
1789         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1790       else
1791         last = gen_udivsi3_i1 (operands[0], operands[3]);
1792     }
1793   else
1794     {
1795       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1796       last = gen_udivsi3_i1 (operands[0], operands[3]);
1797     }
1798   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1799   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1800   last = emit_insn (last);
1801   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1802      invariant code motion can move it.  */
1803   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1804   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1805   DONE;
1808 (define_insn "divsi3_sh2a"
1809   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1810         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1811                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1812   "TARGET_SH2A"
1813   "divs %2,%1"
1814   [(set_attr "type" "arith")
1815    (set_attr "in_delay_slot" "no")])
1817 (define_insn "divsi3_i1"
1818   [(set (match_operand:SI 0 "register_operand" "=z")
1819         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1820    (clobber (reg:SI T_REG))
1821    (clobber (reg:SI PR_REG))
1822    (clobber (reg:SI R1_REG))
1823    (clobber (reg:SI R2_REG))
1824    (clobber (reg:SI R3_REG))
1825    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1826   "TARGET_SH1 && ! TARGET_SH4"
1827   "jsr  @%1%#"
1828   [(set_attr "type" "sfunc")
1829    (set_attr "needs_delay_slot" "yes")])
1831 (define_insn "divsi3_i1_media"
1832   [(set (match_operand:SI 0 "register_operand" "=z")
1833         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1834    (clobber (reg:SI T_MEDIA_REG))
1835    (clobber (reg:SI PR_MEDIA_REG))
1836    (clobber (reg:SI R1_REG))
1837    (clobber (reg:SI R20_REG))
1838    (clobber (reg:SI R21_REG))
1839    (clobber (reg:SI TR0_REG))
1840    (use (match_operand 1 "target_operand" "b"))]
1841   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1842   "blink        %1, r18"
1843   [(set_attr "type" "sfunc")])
1845 (define_insn "divsi3_media_2"
1846   [(set (match_operand:SI 0 "register_operand" "=z")
1847         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1848    (clobber (reg:SI T_MEDIA_REG))
1849    (clobber (reg:SI PR_MEDIA_REG))
1850    (clobber (reg:SI R1_REG))
1851    (clobber (reg:SI R21_REG))
1852    (clobber (reg:SI TR0_REG))
1853    (use (reg:SI R20_REG))
1854    (use (match_operand 1 "target_operand" "b"))]
1855   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1856   "blink        %1, r18"
1857   [(set_attr "type" "sfunc")])
1859 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1860 ;; hard reg clobbers and data dependencies that we need when we want
1861 ;; to rematerialize the division into a call.
1862 (define_insn_and_split "divsi_inv_call"
1863   [(set (match_operand:SI 0 "register_operand" "=r")
1864         (div:SI (match_operand:SI 1 "register_operand" "r")
1865                 (match_operand:SI 2 "register_operand" "r")))
1866    (clobber (reg:SI R4_REG))
1867    (clobber (reg:SI R5_REG))
1868    (clobber (reg:SI T_MEDIA_REG))
1869    (clobber (reg:SI PR_MEDIA_REG))
1870    (clobber (reg:SI R1_REG))
1871    (clobber (reg:SI R21_REG))
1872    (clobber (reg:SI TR0_REG))
1873    (clobber (reg:SI R20_REG))
1874    (use (match_operand:SI 3 "register_operand" "r"))]
1875   "TARGET_SHMEDIA"
1876   "#"
1877   "&& (high_life_started || reload_completed)"
1878   [(set (match_dup 0) (match_dup 3))]
1879   ""
1880   [(set_attr "highpart" "must_split")])
1882 ;; This is the combiner pattern for -mdiv=inv:call .
1883 (define_insn_and_split "*divsi_inv_call_combine"
1884   [(set (match_operand:SI 0 "register_operand" "=z")
1885         (div:SI (match_operand:SI 1 "register_operand" "r")
1886                 (match_operand:SI 2 "register_operand" "r")))
1887    (clobber (reg:SI R4_REG))
1888    (clobber (reg:SI R5_REG))
1889    (clobber (reg:SI T_MEDIA_REG))
1890    (clobber (reg:SI PR_MEDIA_REG))
1891    (clobber (reg:SI R1_REG))
1892    (clobber (reg:SI R21_REG))
1893    (clobber (reg:SI TR0_REG))
1894    (clobber (reg:SI R20_REG))
1895    (use (unspec:SI [(match_dup 1)
1896                     (match_operand:SI 3 "" "")
1897                     (unspec:SI [(match_operand:SI 4 "" "")
1898                                 (match_dup 3)
1899                                 (match_operand:DI 5 "" "")]
1900                      UNSPEC_DIV_INV_M2)
1901                     (match_operand:DI 6 "" "")
1902                     (const_int 0)
1903                     (const_int 0)]
1904          UNSPEC_DIV_INV_M3))]
1905   "TARGET_SHMEDIA"
1906   "#"
1907   "&& (high_life_started || reload_completed)"
1908   [(pc)]
1909   "
1911   const char *name = sh_divsi3_libfunc;
1912   enum sh_function_kind kind = SFUNC_GOT;
1913   rtx sym;
1915   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1916   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1917   while (TARGET_DIVIDE_INV_CALL2)
1918     {
1919       rtx x = operands[3];
1921       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1922         break;
1923       x = XVECEXP (x, 0, 0);
1924       name = \"__sdivsi3_2\";
1925       kind = SFUNC_STATIC;
1926       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1927       break;
1928     }
1929   sym = function_symbol (NULL, name, kind);
1930   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1931   DONE;
1933   [(set_attr "highpart" "must_split")])
1935 (define_expand "divsi3_i4_media"
1936   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1937    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1938    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1939    (set (match_operand:SI 0 "register_operand" "=r")
1940         (fix:SI (match_dup 5)))]
1941   "TARGET_SHMEDIA_FPU"
1942   "
1944   operands[3] = gen_reg_rtx (DFmode);
1945   operands[4] = gen_reg_rtx (DFmode);
1946   operands[5] = gen_reg_rtx (DFmode);
1949 (define_insn "divsi3_i4"
1950   [(set (match_operand:SI 0 "register_operand" "=y")
1951         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1952    (clobber (reg:SI PR_REG))
1953    (clobber (reg:DF DR0_REG))
1954    (clobber (reg:DF DR2_REG))
1955    (use (reg:PSI FPSCR_REG))
1956    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1957   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1958   "jsr  @%1%#"
1959   [(set_attr "type" "sfunc")
1960    (set_attr "fp_mode" "double")
1961    (set_attr "needs_delay_slot" "yes")])
1963 (define_insn "divsi3_i4_single"
1964   [(set (match_operand:SI 0 "register_operand" "=y")
1965         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1966    (clobber (reg:SI PR_REG))
1967    (clobber (reg:DF DR0_REG))
1968    (clobber (reg:DF DR2_REG))
1969    (clobber (reg:SI R2_REG))
1970    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1971   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1972   "jsr  @%1%#"
1973   [(set_attr "type" "sfunc")
1974    (set_attr "needs_delay_slot" "yes")])
1976 (define_expand "divsi3"
1977   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1978    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1979    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1980    (parallel [(set (match_operand:SI 0 "register_operand" "")
1981                    (div:SI (reg:SI R4_REG)
1982                            (reg:SI R5_REG)))
1983               (clobber (reg:SI T_REG))
1984               (clobber (reg:SI PR_REG))
1985               (clobber (reg:SI R1_REG))
1986               (clobber (reg:SI R2_REG))
1987               (clobber (reg:SI R3_REG))
1988               (use (match_dup 3))])]
1989   ""
1990   "
1992   rtx first, last;
1994   operands[3] = gen_reg_rtx (Pmode);
1995   /* Emit the move of the address to a pseudo outside of the libcall.  */
1996   if (TARGET_HARD_SH4 && TARGET_SH2E)
1997     {
1998       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
1999       if (TARGET_FPU_SINGLE)
2000         last = gen_divsi3_i4_single (operands[0], operands[3]);
2001       else
2002         last = gen_divsi3_i4 (operands[0], operands[3]);
2003     }
2004   else if (TARGET_SH2A)
2005     {
2006       operands[1] = force_reg (SImode, operands[1]);
2007       operands[2] = force_reg (SImode, operands[2]);
2008       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2009       DONE;
2010     }
2011   else if (TARGET_DIVIDE_INV)
2012     {
2013       rtx dividend = operands[1];
2014       rtx divisor = operands[2];
2015       rtx tab_base;
2016       rtx nsb_res = gen_reg_rtx (DImode);
2017       rtx norm64 = gen_reg_rtx (DImode);
2018       rtx tab_ix = gen_reg_rtx (DImode);
2019       rtx norm32 = gen_reg_rtx (SImode);
2020       rtx i92 = force_reg (DImode, GEN_INT (92));
2021       rtx scratch0a = gen_reg_rtx (DImode);
2022       rtx scratch0b = gen_reg_rtx (DImode);
2023       rtx inv0 = gen_reg_rtx (SImode);
2024       rtx scratch1a = gen_reg_rtx (DImode);
2025       rtx scratch1b = gen_reg_rtx (DImode);
2026       rtx shift = gen_reg_rtx (DImode);
2027       rtx i2p27, i43;
2028       rtx inv1 = gen_reg_rtx (SImode);
2029       rtx scratch2a = gen_reg_rtx (DImode);
2030       rtx scratch2b = gen_reg_rtx (SImode);
2031       rtx inv2 = gen_reg_rtx (SImode);
2032       rtx scratch3a = gen_reg_rtx (DImode);
2033       rtx scratch3b = gen_reg_rtx (DImode);
2034       rtx scratch3c = gen_reg_rtx (DImode);
2035       rtx scratch3d = gen_reg_rtx (SImode);
2036       rtx scratch3e = gen_reg_rtx (DImode);
2037       rtx result = gen_reg_rtx (SImode);
2039       if (! arith_reg_or_0_operand (dividend, SImode))
2040         dividend = force_reg (SImode, dividend);
2041       if (! arith_reg_operand (divisor, SImode))
2042         divisor = force_reg (SImode, divisor);
2043       if (flag_pic && Pmode != DImode)
2044         {
2045           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2046           tab_base = gen_datalabel_ref (tab_base);
2047           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2048         }
2049       else
2050         {
2051           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2052           tab_base = gen_datalabel_ref (tab_base);
2053           tab_base = force_reg (DImode, tab_base);
2054         }
2055       if (TARGET_DIVIDE_INV20U)
2056         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2057       else
2058         i2p27 = GEN_INT (0);
2059       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2060         i43 = force_reg (DImode, GEN_INT (43));
2061       else
2062         i43 = GEN_INT (0);
2063       emit_insn (gen_nsbdi (nsb_res,
2064                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2065       emit_insn (gen_ashldi3_media (norm64,
2066                                     gen_rtx_SUBREG (DImode, divisor, 0),
2067                                     nsb_res));
2068       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2069       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2070       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2071                                    inv0, scratch0a, scratch0b,
2072                                    scratch1a, scratch1b));
2073       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2074       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2075                                    scratch2a));
2076       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2077                                    i2p27, i43,
2078                                    scratch3a, scratch3b, scratch3c,
2079                                    scratch2a, scratch2b, scratch3d, scratch3e));
2080       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2081         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2082       else if (TARGET_DIVIDE_INV_FP)
2083         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2084                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2085                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2086                                      gen_reg_rtx (DFmode)));
2087       else
2088         emit_move_insn (operands[0], result);
2089       DONE;
2090     }
2091   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2092     {
2093       operands[1] = force_reg (SImode, operands[1]);
2094       operands[2] = force_reg (SImode, operands[2]);
2095       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2096       DONE;
2097     }
2098   else if (TARGET_SH5)
2099     {
2100       if (TARGET_DIVIDE_CALL2)
2101         {
2102           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2103           tab_base = gen_datalabel_ref (tab_base);
2104           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2105         }
2106       if (TARGET_FPU_ANY && TARGET_SH1)
2107         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2108       else if (TARGET_DIVIDE_CALL2)
2109         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2110       else
2111         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2113       if (TARGET_SHMEDIA)
2114         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2115                 (operands[0], operands[3]));
2116       else if (TARGET_FPU_ANY)
2117         last = gen_divsi3_i4_single (operands[0], operands[3]);
2118       else
2119         last = gen_divsi3_i1 (operands[0], operands[3]);
2120     }
2121   else
2122     {
2123       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2124       last = gen_divsi3_i1 (operands[0], operands[3]);
2125     }
2126   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2127   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2128   last = emit_insn (last);
2129   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2130      invariant code motion can move it.  */
2131   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2132   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2133   DONE;
2136 ;; operands: inv0, tab_base, tab_ix, norm32
2137 ;; scratch equiv in sdivsi3_2: r19, r21
2138 (define_expand "divsi_inv_m0"
2139   [(set (match_operand:SI 0 "register_operand" "=r")
2140         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2141                     (match_operand:DI 2 "register_operand" "r")
2142                     (match_operand:SI 3 "register_operand" "r")]
2143          UNSPEC_DIV_INV_M0))
2144    (clobber (match_operand:DI 4 "register_operand" "=r"))
2145    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2146   "TARGET_SHMEDIA"
2147   "
2150 tab_base: r20
2151 tab_ix: r21
2152 norm32: r25
2153  ldx.ub r20, r21, r19 // u0.8
2154  shlli r21, 1, r21
2155  muls.l r25, r19, r19 // s2.38
2156  ldx.w r20, r21, r21  // s2.14
2157  shari r19, 24, r19   // truncate to s2.14
2158  sub r21, r19, r19    // some 11 bit inverse in s1.14
2161   rtx inv0 = operands[0];
2162   rtx tab_base = operands[1];
2163   rtx tab_ix = operands[2];
2164   rtx norm32 = operands[3];
2165   rtx scratch0 = operands[4];
2166   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2167   rtx scratch1 = operands[5];
2168   rtx mem;
2170   mem = gen_rtx_MEM (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2171   emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2172   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2173   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2174   mem = gen_rtx_MEM (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2175   emit_insn (gen_extendhidi2 (scratch1, mem));
2176   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2177   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2178   DONE;
2181 ;; operands: inv1, tab_base, tab_ix, norm32
2182 (define_insn_and_split "divsi_inv_m1"
2183   [(set (match_operand:SI 0 "register_operand" "=r")
2184         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2185                     (match_operand:DI 2 "register_operand" "r")
2186                     (match_operand:SI 3 "register_operand" "r")]
2187          UNSPEC_DIV_INV_M1))
2188    (clobber (match_operand:SI 4 "register_operand" "=r"))
2189    (clobber (match_operand:DI 5 "register_operand" "=r"))
2190    (clobber (match_operand:DI 6 "register_operand" "=r"))
2191    (clobber (match_operand:DI 7 "register_operand" "=r"))
2192    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2193   "TARGET_SHMEDIA"
2194   "#"
2195   "&& no_new_pseudos"
2196   [(pc)]
2197   "
2199 /* inv0: r19
2200  muls.l r19, r19, r18 // u0.28
2201  muls.l r25, r18, r18 // s2.58
2202  shlli r19, 45, r0    // multiply by two and convert to s2.58
2203  sub r0, r18, r18
2204  shari r18, 28, r18   // some 18 bit inverse in s1.30
2207   rtx inv1 = operands[0];
2208   rtx tab_base = operands[1];
2209   rtx tab_ix = operands[2];
2210   rtx norm32 = operands[3];
2211   rtx inv0 = operands[4];
2212   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2213   rtx scratch0a = operands[5];
2214   rtx scratch0b = operands[6];
2215   rtx scratch0 = operands[7];
2216   rtx scratch1 = operands[8];
2217   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2219   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2220                                scratch0a, scratch0b));
2221   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2222   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2223   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2224   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2225   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2226   DONE;
2229 ;; operands: inv2, norm32, inv1, i92
2230 (define_insn_and_split "divsi_inv_m2"
2231   [(set (match_operand:SI 0 "register_operand" "=r")
2232         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2233                     (match_operand:SI 2 "register_operand" "r")
2234                     (match_operand:DI 3 "register_operand" "r")]
2235          UNSPEC_DIV_INV_M2))
2236    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2237   "TARGET_SHMEDIA"
2238   "#"
2239   "&& no_new_pseudos"
2240   [(pc)]
2241   "
2244  muls.l r18, r25, r0  // s2.60
2245  shari r0, 16, r0     // s-16.44
2246   sub
2247  muls.l r0, r18, r19  // s-16.74
2248  shari r19, 30, r19   // s-16.44
2250   rtx inv2 = operands[0];
2251   rtx norm32 = operands[1];
2252   rtx inv1 = operands[2];
2253   rtx i92 = operands[3];
2254   rtx scratch0 = operands[4];
2255   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2257   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2258   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2259   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2260   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2261   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2262   DONE;
2265 (define_insn_and_split "divsi_inv_m3"
2266   [(set (match_operand:SI 0 "register_operand" "=r")
2267         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2268                     (match_operand:SI 2 "register_operand" "r")
2269                     (match_operand:SI 3 "register_operand" "r")
2270                     (match_operand:DI 4 "register_operand" "r")
2271                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2272                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2273          UNSPEC_DIV_INV_M3))
2274    (clobber (match_operand:DI 7 "register_operand" "=r"))
2275    (clobber (match_operand:DI 8 "register_operand" "=r"))
2276    (clobber (match_operand:DI 9 "register_operand" "=r"))
2277    (clobber (match_operand:DI 10 "register_operand" "=r"))
2278    (clobber (match_operand:SI 11 "register_operand" "=r"))
2279    (clobber (match_operand:SI 12 "register_operand" "=r"))
2280    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2281   "TARGET_SHMEDIA"
2282   "#"
2283   "&& no_new_pseudos"
2284   [(pc)]
2285   "
2288   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2289   r0: scratch0  r19: scratch1 r21: scratch2
2291   muls.l r18, r4, r25 // s32.30
2292  muls.l r19, r4, r19  // s15.30
2293  shari r25, 63, r21
2294   shari r19, 14, r19  // s18.-14
2295  sub r25, r19, r0
2296  shard r0, r1, r0
2297  sub r0, r21, r0
2300   rtx result = operands[0];
2301   rtx dividend = operands[1];
2302   rtx inv1 = operands[2];
2303   rtx inv2 = operands[3];
2304   rtx shift = operands[4];
2305   rtx scratch0 = operands[7];
2306   rtx scratch1 = operands[8];
2307   rtx scratch2 = operands[9];
2309   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2310   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2311   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2312   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2313   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2314   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2315   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2316   DONE;
2319 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2320 ;; inv1: tab_base, tab_ix, norm32
2321 ;; inv2: norm32, inv1, i92
2322 (define_insn_and_split "divsi_inv_m1_3"
2323   [(set (match_operand:SI 0 "register_operand" "=r")
2324         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2325                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2326                                 (match_operand:DI 3 "register_operand" "r")
2327                                 (match_operand:SI 4 "register_operand" "r")]
2328                      UNSPEC_DIV_INV_M1)
2329                     (unspec:SI [(match_dup 4)
2330                                 (unspec:SI [(match_dup 2)
2331                                             (match_dup 3)
2332                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2333                                 (match_operand:SI 5 "" "")]
2334                      UNSPEC_DIV_INV_M2)
2335                     (match_operand:DI 6 "register_operand" "r")
2336                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2337                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2338          UNSPEC_DIV_INV_M3))
2339    (clobber (match_operand:DI 9 "register_operand" "=r"))
2340    (clobber (match_operand:DI 10 "register_operand" "=r"))
2341    (clobber (match_operand:DI 11 "register_operand" "=r"))
2342    (clobber (match_operand:DI 12 "register_operand" "=r"))
2343    (clobber (match_operand:SI 13 "register_operand" "=r"))
2344    (clobber (match_operand:SI 14 "register_operand" "=r"))
2345    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2346   "TARGET_SHMEDIA
2347    && (TARGET_DIVIDE_INV_MINLAT
2348        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2349   "#"
2350   "&& no_new_pseudos"
2351   [(pc)]
2352   "
2354   rtx result = operands[0];
2355   rtx dividend = operands[1];
2356   rtx tab_base = operands[2];
2357   rtx tab_ix = operands[3];
2358   rtx norm32 = operands[4];
2359   /* rtx i92 = operands[5]; */
2360   rtx shift = operands[6];
2361   rtx i2p27 = operands[7];
2362   rtx i43 = operands[8];
2363   rtx scratch0 = operands[9];
2364   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2365   rtx scratch1 = operands[10];
2366   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2367   rtx scratch2 = operands[11];
2368   rtx scratch3 = operands[12];
2369   rtx scratch4 = operands[13];
2370   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2371   rtx scratch5 = operands[14];
2372   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2373   rtx scratch6 = operands[15];
2375   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2376                                scratch0, scratch1));
2377   /* inv0 == scratch4 */
2378   if (! TARGET_DIVIDE_INV20U)
2379     {
2380       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2381       i2p27 = scratch0;
2382       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2383     }
2384   else
2385     {
2386       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2387       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2388     }
2389   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2390   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2391   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2392   /* inv1 == scratch4 */
2394   if (TARGET_DIVIDE_INV_MINLAT)
2395     {
2396       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2397       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2398       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2399       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2400       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2401       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2402       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2403       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2404       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2405       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2406       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2407     }
2408   else
2409     {
2410       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2411       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2412       emit_insn (gen_nsbdi (scratch6,
2413                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2414       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2415       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2416       emit_insn (gen_divsi_inv20 (scratch2,
2417                                   norm32, scratch4, dividend,
2418                                   scratch6, scratch3, i43,
2419                                   /* scratch0 may be shared with i2p27.  */
2420                                   scratch0, scratch1, scratch5,
2421                                   label, label, i2p27));
2422     }
2423   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2424   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2425   DONE;
2428 (define_insn "divsi_inv20"
2429   [(set (match_operand:DI 0 "register_operand" "=&r")
2430         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2431                     (match_operand:SI 2 "register_operand" "r")
2432                     (match_operand:SI 3 "register_operand" "r")
2433                     (match_operand:DI 4 "register_operand" "r")
2434                     (match_operand:DI 5 "register_operand" "r")
2435                     (match_operand:DI 6 "register_operand" "r")
2436                     (match_operand:DI 12 "register_operand" "r")
2437                     (match_operand 10 "target_operand" "b")
2438                     (match_operand 11 "immediate_operand" "i")]
2439          UNSPEC_DIV_INV20))
2440    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2441    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2442    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2443   "TARGET_SHMEDIA
2444    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2445   "*
2447 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2448              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2449              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2450              %10 label (tr), %11 label (imm)
2452  muls.l inv1, norm32, scratch0  // s2.60
2453   muls.l inv1, dividend, result // s32.30
2454   xor i2p27, result_sign, round_scratch
2455  bge/u dividend_nsb, i43, tr.. (label)
2456  shari scratch0, 16, scratch0   // s-16.44
2457  muls.l sratch0_si, inv1, scratch0 // s-16.74
2458   sub result, round_scratch, result
2459   shari dividend, 14, scratch1   // s19.-14
2460  shari scratch0, 30, scratch0   // s-16.44
2461  muls.l scratch0, scratch1, round_scratch // s15.30
2462 label:
2463  sub result, round_scratch, result */
2465   int likely = TARGET_DIVIDE_INV20L;
2467   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2468   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2469   output_asm_insn (likely
2470                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2471                    : \"bge/u\t%4, %6, %10\", operands);
2472   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2473   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2474   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2475   return (likely
2476           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2477           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2480 (define_insn_and_split "divsi_inv_fp"
2481   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2482         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2483                 (match_operand:SI 2 "register_operand" "rf")))
2484    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2485    (clobber (match_operand:SI 4 "register_operand" "=r"))
2486    (clobber (match_operand:SI 5 "register_operand" "=r"))
2487    (clobber (match_operand:DF 6 "register_operand" "=r"))
2488    (clobber (match_operand:DF 7 "register_operand" "=r"))
2489    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2490   "TARGET_SHMEDIA_FPU"
2491   "#"
2492   "&& (high_life_started || reload_completed)"
2493   [(set (match_dup 0) (match_dup 3))]
2494   ""
2495   [(set_attr "highpart" "must_split")])
2497 ;; If a matching group of divide-by-inverse instructions is in the same
2498 ;; basic block after gcse & loop optimizations, we want to transform them
2499 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2500 (define_insn_and_split "*divsi_inv_fp_combine"
2501   [(set (match_operand:SI 0 "register_operand" "=f")
2502         (div:SI (match_operand:SI 1 "register_operand" "f")
2503                 (match_operand:SI 2 "register_operand" "f")))
2504    (use (unspec:SI [(match_dup 1)
2505                     (match_operand:SI 3 "" "")
2506                     (unspec:SI [(match_operand:SI 4 "" "")
2507                                 (match_dup 3)
2508                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2509                     (match_operand:DI 6 "" "")
2510                     (const_int 0)
2511                     (const_int 0)] UNSPEC_DIV_INV_M3))
2512    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2513    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2514    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2515    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2516    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2517   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2518   "#"
2519   "&& 1"
2520   [(set (match_dup 9) (float:DF (match_dup 1)))
2521    (set (match_dup 10) (float:DF (match_dup 2)))
2522    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2523    (set (match_dup 8)
2524         (fix:SI (match_dup 11)))
2525    (set (match_dup 0) (match_dup 8))]
2526   "
2528   if (! fp_arith_reg_operand (operands[1], SImode))
2529     {
2530       emit_move_insn (operands[7], operands[1]);
2531       operands[1] = operands[7];
2532     }
2533   if (! fp_arith_reg_operand (operands[2], SImode))
2534     {
2535       emit_move_insn (operands[8], operands[2]);
2536       operands[2] = operands[8];
2537     }
2539   [(set_attr "highpart" "must_split")])
2541 ;; -------------------------------------------------------------------------
2542 ;; Multiplication instructions
2543 ;; -------------------------------------------------------------------------
2545 (define_insn "umulhisi3_i"
2546   [(set (reg:SI MACL_REG)
2547         (mult:SI (zero_extend:SI
2548                   (match_operand:HI 0 "arith_reg_operand" "r"))
2549                  (zero_extend:SI
2550                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2551   "TARGET_SH1"
2552   "mulu.w       %1,%0"
2553   [(set_attr "type" "smpy")])
2555 (define_insn "mulhisi3_i"
2556   [(set (reg:SI MACL_REG)
2557         (mult:SI (sign_extend:SI
2558                   (match_operand:HI 0 "arith_reg_operand" "r"))
2559                  (sign_extend:SI
2560                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2561   "TARGET_SH1"
2562   "muls.w       %1,%0"
2563   [(set_attr "type" "smpy")])
2565 (define_expand "mulhisi3"
2566   [(set (reg:SI MACL_REG)
2567         (mult:SI (sign_extend:SI
2568                   (match_operand:HI 1 "arith_reg_operand" ""))
2569                  (sign_extend:SI
2570                   (match_operand:HI 2 "arith_reg_operand" ""))))
2571    (set (match_operand:SI 0 "arith_reg_operand" "")
2572         (reg:SI MACL_REG))]
2573   "TARGET_SH1"
2574   "
2576   rtx first, last;
2578   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2579   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2580   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2581      invariant code motion can move it.  */
2582   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2583   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2584   /* expand_binop can't find a suitable code in umul_widen_optab to
2585      make a REG_EQUAL note from, so make one here.
2586      See also smulsi3_highpart.
2587      ??? Alternatively, we could put this at the calling site of expand_binop,
2588      i.e. expand_expr.  */
2589   REG_NOTES (last)
2590     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2591                          REG_NOTES (last));
2592   DONE;
2595 (define_expand "umulhisi3"
2596   [(set (reg:SI MACL_REG)
2597         (mult:SI (zero_extend:SI
2598                   (match_operand:HI 1 "arith_reg_operand" ""))
2599                  (zero_extend:SI
2600                   (match_operand:HI 2 "arith_reg_operand" ""))))
2601    (set (match_operand:SI 0 "arith_reg_operand" "")
2602         (reg:SI MACL_REG))]
2603   "TARGET_SH1"
2604   "
2606   rtx first, last;
2608   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2609   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2610   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2611      invariant code motion can move it.  */
2612   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2613   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2614   /* expand_binop can't find a suitable code in umul_widen_optab to
2615      make a REG_EQUAL note from, so make one here.
2616      See also smulsi3_highpart.
2617      ??? Alternatively, we could put this at the calling site of expand_binop,
2618      i.e. expand_expr.  */
2619   REG_NOTES (last)
2620     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2621                          REG_NOTES (last));
2622   DONE;
2625 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2626 ;; a call to a routine which clobbers known registers.
2628 (define_insn ""
2629   [(set (match_operand:SI 1 "register_operand" "=z")
2630         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2631    (clobber (reg:SI MACL_REG))
2632    (clobber (reg:SI T_REG))
2633    (clobber (reg:SI PR_REG))
2634    (clobber (reg:SI R3_REG))
2635    (clobber (reg:SI R2_REG))
2636    (clobber (reg:SI R1_REG))
2637    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2638   "TARGET_SH1"
2639   "jsr  @%0%#"
2640   [(set_attr "type" "sfunc")
2641    (set_attr "needs_delay_slot" "yes")])
2643 (define_expand "mulsi3_call"
2644   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2645    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2646    (parallel[(set (match_operand:SI 0 "register_operand" "")
2647                   (mult:SI (reg:SI R4_REG)
2648                            (reg:SI R5_REG)))
2649              (clobber (reg:SI MACL_REG))
2650              (clobber (reg:SI T_REG))
2651              (clobber (reg:SI PR_REG))
2652              (clobber (reg:SI R3_REG))
2653              (clobber (reg:SI R2_REG))
2654              (clobber (reg:SI R1_REG))
2655              (use (match_operand:SI 3 "register_operand" ""))])]
2656   "TARGET_SH1"
2657   "")
2659 (define_insn "mul_r"
2660   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2661         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2662                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2663   "TARGET_SH2A"
2664   "mulr %2,%0"
2665   [(set_attr "type" "dmpy")])
2667 (define_insn "mul_l"
2668   [(set (reg:SI MACL_REG)
2669         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2670                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2671   "TARGET_SH2"
2672   "mul.l        %1,%0"
2673   [(set_attr "type" "dmpy")])
2675 (define_expand "mulsi3"
2676   [(set (reg:SI MACL_REG)
2677         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2678                   (match_operand:SI 2 "arith_reg_operand" "")))
2679    (set (match_operand:SI 0 "arith_reg_operand" "")
2680         (reg:SI MACL_REG))]
2681   "TARGET_SH1"
2682   "
2684   rtx first, last;
2686   if (!TARGET_SH2)
2687     {
2688       /* The address must be set outside the libcall,
2689          since it goes into a pseudo.  */
2690       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2691       rtx addr = force_reg (SImode, sym);
2692       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2693                                    operands[2], addr);
2694       first = insns;
2695       last = emit_insn (insns);
2696     }
2697   else
2698     {
2699       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2701       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2702       /* consec_sets_giv can only recognize the first insn that sets a
2703          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2704          note.  */
2705       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2706     }
2707   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2708      invariant code motion can move it.  */
2709   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2710   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2711   DONE;
2714 (define_insn "mulsidi3_i"
2715   [(set (reg:SI MACH_REG)
2716         (truncate:SI
2717          (lshiftrt:DI
2718           (mult:DI
2719            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2720            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2721           (const_int 32))))
2722    (set (reg:SI MACL_REG)
2723         (mult:SI (match_dup 0)
2724                  (match_dup 1)))]
2725   "TARGET_SH2"
2726   "dmuls.l      %1,%0"
2727   [(set_attr "type" "dmpy")])
2729 (define_expand "mulsidi3"
2730   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2731         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2732                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2733   "TARGET_SH2 || TARGET_SHMEDIA"
2734   "
2736   if (TARGET_SH2)
2737     {
2738        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2739                                         operands[2]));
2740        DONE;
2741     }
2744 (define_insn "mulsidi3_media"
2745   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2746         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2747                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2748   "TARGET_SHMEDIA"
2749   "muls.l       %1, %2, %0"
2750   [(set_attr "type" "dmpy_media")
2751    (set_attr "highpart" "ignore")])
2753 (define_insn "mulsidi3_compact"
2754   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2755         (mult:DI
2756          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2757          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2758    (clobber (reg:SI MACH_REG))
2759    (clobber (reg:SI MACL_REG))]
2760   "TARGET_SH2"
2761   "#")
2763 (define_split
2764   [(set (match_operand:DI 0 "arith_reg_dest" "")
2765         (mult:DI
2766          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2767          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2768    (clobber (reg:SI MACH_REG))
2769    (clobber (reg:SI MACL_REG))]
2770   "TARGET_SH2"
2771   [(const_int 0)]
2772   "
2774   rtx low_dst = gen_lowpart (SImode, operands[0]);
2775   rtx high_dst = gen_highpart (SImode, operands[0]);
2777   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2779   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2780   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2781   /* We need something to tag the possible REG_EQUAL notes on to.  */
2782   emit_move_insn (operands[0], operands[0]);
2783   DONE;
2786 (define_insn "umulsidi3_i"
2787   [(set (reg:SI MACH_REG)
2788         (truncate:SI
2789          (lshiftrt:DI
2790           (mult:DI
2791            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2792            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2793           (const_int 32))))
2794    (set (reg:SI MACL_REG)
2795         (mult:SI (match_dup 0)
2796                  (match_dup 1)))]
2797   "TARGET_SH2"
2798   "dmulu.l      %1,%0"
2799   [(set_attr "type" "dmpy")])
2801 (define_expand "umulsidi3"
2802   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2803         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2804                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2805   "TARGET_SH2 || TARGET_SHMEDIA"
2806   "
2808   if (TARGET_SH2)
2809     {
2810        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2811                                          operands[2]));
2812        DONE;
2813     }
2816 (define_insn "umulsidi3_media"
2817   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2818         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2819                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2820   "TARGET_SHMEDIA"
2821   "mulu.l       %1, %2, %0"
2822   [(set_attr "type" "dmpy_media")
2823    (set_attr "highpart" "ignore")])
2825 (define_insn "umulsidi3_compact"
2826   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2827         (mult:DI
2828          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2829          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2830    (clobber (reg:SI MACH_REG))
2831    (clobber (reg:SI MACL_REG))]
2832   "TARGET_SH2"
2833   "#")
2835 (define_split
2836   [(set (match_operand:DI 0 "arith_reg_dest" "")
2837         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2838                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2839    (clobber (reg:SI MACH_REG))
2840    (clobber (reg:SI MACL_REG))]
2841   "TARGET_SH2"
2842   [(const_int 0)]
2843   "
2845   rtx low_dst = gen_lowpart (SImode, operands[0]);
2846   rtx high_dst = gen_highpart (SImode, operands[0]);
2848   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2850   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2851   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2852   /* We need something to tag the possible REG_EQUAL notes on to.  */
2853   emit_move_insn (operands[0], operands[0]);
2854   DONE;
2857 (define_insn "smulsi3_highpart_i"
2858   [(set (reg:SI MACH_REG)
2859         (truncate:SI
2860          (lshiftrt:DI
2861           (mult:DI
2862            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2863            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2864           (const_int 32))))
2865    (clobber (reg:SI MACL_REG))]
2866   "TARGET_SH2"
2867   "dmuls.l      %1,%0"
2868   [(set_attr "type" "dmpy")])
2870 (define_expand "smulsi3_highpart"
2871   [(parallel
2872     [(set (reg:SI MACH_REG)
2873           (truncate:SI
2874            (lshiftrt:DI
2875             (mult:DI
2876              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2877              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2878             (const_int 32))))
2879     (clobber (reg:SI MACL_REG))])
2880    (set (match_operand:SI 0 "arith_reg_operand" "")
2881         (reg:SI MACH_REG))]
2882   "TARGET_SH2"
2883   "
2885   rtx first, last;
2887   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2888   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2889   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2890      invariant code motion can move it.  */
2891   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2892   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2893   /* expand_binop can't find a suitable code in mul_highpart_optab to
2894      make a REG_EQUAL note from, so make one here.
2895      See also {,u}mulhisi.
2896      ??? Alternatively, we could put this at the calling site of expand_binop,
2897      i.e. expand_mult_highpart.  */
2898   REG_NOTES (last)
2899     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2900                          REG_NOTES (last));
2901   DONE;
2904 (define_insn "umulsi3_highpart_i"
2905   [(set (reg:SI MACH_REG)
2906         (truncate:SI
2907          (lshiftrt:DI
2908           (mult:DI
2909            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2910            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2911           (const_int 32))))
2912    (clobber (reg:SI MACL_REG))]
2913   "TARGET_SH2"
2914   "dmulu.l      %1,%0"
2915   [(set_attr "type" "dmpy")])
2917 (define_expand "umulsi3_highpart"
2918   [(parallel
2919     [(set (reg:SI MACH_REG)
2920           (truncate:SI
2921            (lshiftrt:DI
2922             (mult:DI
2923              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2924              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2925             (const_int 32))))
2926     (clobber (reg:SI MACL_REG))])
2927    (set (match_operand:SI 0 "arith_reg_operand" "")
2928         (reg:SI MACH_REG))]
2929   "TARGET_SH2"
2930   "
2932   rtx first, last;
2934   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2935   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2936   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2937      invariant code motion can move it.  */
2938   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2939   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2940   DONE;
2943 (define_insn_and_split "muldi3"
2944   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2945         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2946                  (match_operand:DI 2 "arith_reg_operand" "r")))
2947    (clobber (match_scratch:DI 3 "=&r"))
2948    (clobber (match_scratch:DI 4 "=r"))]
2949   "TARGET_SHMEDIA"
2950   "#"
2951   "reload_completed"
2952   [(const_int 0)]
2953   "
2955   rtx op3_v2si, op2_v2si;
2957   op3_v2si = operands[3];
2958   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2959     {
2960       op3_v2si = XEXP (op3_v2si, 0);
2961       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2962     }
2963   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2964   op2_v2si = operands[2];
2965   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2966     {
2967       op2_v2si = XEXP (op2_v2si, 0);
2968       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2969     }
2970   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2971   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2972   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2973   emit_insn (gen_umulsidi3_media (operands[4],
2974                                  sh_gen_truncate (SImode, operands[1], 0),
2975                                  sh_gen_truncate (SImode, operands[2], 0)));
2976   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2977   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2978   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2979   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2980   DONE;
2984 ;; -------------------------------------------------------------------------
2985 ;; Logical operations
2986 ;; -------------------------------------------------------------------------
2988 (define_insn "*andsi3_compact"
2989   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2990         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2991                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2992   "TARGET_SH1"
2993   "and  %2,%0"
2994   [(set_attr "type" "arith")])
2996 (define_insn "*andsi3_media"
2997   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
2998         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
2999                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3000   "TARGET_SHMEDIA"
3001   "@
3002         and     %1, %2, %0
3003         andi    %1, %2, %0"
3004   [(set_attr "type" "arith_media")])
3006 ;; If the constant is 255, then emit an extu.b instruction instead of an
3007 ;; and, since that will give better code.
3009 (define_expand "andsi3"
3010   [(set (match_operand:SI 0 "arith_reg_operand" "")
3011         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3012                 (match_operand:SI 2 "logical_operand" "")))]
3013   ""
3014   "
3016   if (TARGET_SH1
3017       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3018     {
3019       emit_insn (gen_zero_extendqisi2 (operands[0],
3020                                        gen_lowpart (QImode, operands[1])));
3021       DONE;
3022     }
3025 (define_insn_and_split "anddi3"
3026   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3027         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3028                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3029   "TARGET_SHMEDIA"
3030   "@
3031         and     %1, %2, %0
3032         andi    %1, %2, %0
3033         #"
3034   "reload_completed
3035    && ! logical_operand (operands[2], DImode)"
3036   [(const_int 0)]
3037   "
3039   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3040     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3041   else
3042     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3043   DONE;
3045   [(set_attr "type" "arith_media")])
3047 (define_insn "andcsi3"
3048   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3049         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3050                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3051   "TARGET_SHMEDIA"
3052   "andc %1,%2,%0"
3053   [(set_attr "type" "arith_media")])
3055 (define_insn "andcdi3"
3056   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3057         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3058                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3059   "TARGET_SHMEDIA"
3060   "andc %1,%2,%0"
3061   [(set_attr "type" "arith_media")])
3063 (define_expand "iorsi3"
3064   [(set (match_operand:SI 0 "arith_reg_operand" "")
3065         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3066                 (match_operand:SI 2 "logical_operand" "")))]
3067   ""
3068   "")
3070 (define_insn "*iorsi3_compact"
3071   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3072         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3073                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3074   "TARGET_SH1"
3075   "or   %2,%0"
3076   [(set_attr "type" "arith")])
3078 (define_insn "*iorsi3_media"
3079   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3080         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3081                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3082   "TARGET_SHMEDIA"
3083   "@
3084         or      %1, %2, %0
3085         ori     %1, %2, %0"
3086   [(set_attr "type" "arith_media")])
3088 (define_insn "iordi3"
3089   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3090         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3091                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3092   "TARGET_SHMEDIA"
3093   "@
3094         or      %1, %2, %0
3095         ori     %1, %2, %0"
3096   [(set_attr "type" "arith_media")])
3098 (define_insn_and_split "*logical_sidi3"
3099   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3100         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3101                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3102                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3103   "TARGET_SHMEDIA"
3104   "#"
3105   "&& reload_completed"
3106   [(set (match_dup 0) (match_dup 3))]
3107   "
3109   operands[3]
3110     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3111                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3112                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3115 (define_insn_and_split "*logical_sidisi3"
3116   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3117         (truncate:SI (sign_extend:DI
3118                         (match_operator:SI 3 "logical_operator"
3119                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3120                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3121   "TARGET_SHMEDIA"
3122   "#"
3123   "&& 1"
3124   [(set (match_dup 0) (match_dup 3))])
3126 (define_insn_and_split "*logical_sidi3_2"
3127   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3128         (sign_extend:DI (truncate:SI (sign_extend:DI
3129                         (match_operator:SI 3 "logical_operator"
3130                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3131                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3132   "TARGET_SHMEDIA"
3133   "#"
3134   "&& 1"
3135   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3137 (define_expand "xorsi3"
3138   [(set (match_operand:SI 0 "arith_reg_operand" "")
3139         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3140                 (match_operand:SI 2 "xor_operand" "")))]
3141   ""
3142   "")
3144 (define_insn "*xorsi3_compact"
3145   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3146         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3147                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3148   "TARGET_SH1"
3149   "xor  %2,%0"
3150   [(set_attr "type" "arith")])
3152 (define_insn "*xorsi3_media"
3153   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3154         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3155                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3156   "TARGET_SHMEDIA"
3157   "@
3158         xor     %1, %2, %0
3159         xori    %1, %2, %0"
3160   [(set_attr "type" "arith_media")])
3162 (define_insn "xordi3"
3163   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3164         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3165                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3166   "TARGET_SHMEDIA"
3167   "@
3168         xor     %1, %2, %0
3169         xori    %1, %2, %0"
3170   [(set_attr "type" "arith_media")])
3172 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3173 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3174 (define_split
3175   [(set (match_operand:DI 0 "arith_reg_dest" "")
3176         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3177                           [(match_operand 1 "any_register_operand" "")
3178                            (match_operand 2 "any_register_operand" "")])))]
3179   "TARGET_SHMEDIA"
3180   [(set (match_dup 5) (match_dup 4))
3181    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3184   enum machine_mode inmode = GET_MODE (operands[1]);
3185   int offset = 0;
3187   if (GET_CODE (operands[0]) == SUBREG)
3188     {
3189       offset = SUBREG_BYTE (operands[0]);
3190       operands[0] = SUBREG_REG (operands[0]);
3191     }
3192   gcc_assert (GET_CODE (operands[0]) == REG);
3193   if (! TARGET_LITTLE_ENDIAN)
3194     offset += 8 - GET_MODE_SIZE (inmode);
3195   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3198 ;; -------------------------------------------------------------------------
3199 ;; Shifts and rotates
3200 ;; -------------------------------------------------------------------------
3202 (define_expand "rotldi3"
3203   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3204         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3205                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3206   "TARGET_SHMEDIA"
3207   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3209 (define_insn "rotldi3_mextr"
3210   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3211         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3212                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3213   "TARGET_SHMEDIA"
3214   "*
3216   static char templ[16];
3218   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3219            8 - (int) (INTVAL (operands[2]) >> 3));
3220   return templ;
3222   [(set_attr "type" "arith_media")])
3224 (define_expand "rotrdi3"
3225   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3226         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3227                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3228   "TARGET_SHMEDIA"
3229   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3231 (define_insn "rotrdi3_mextr"
3232   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3233         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3234                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3235   "TARGET_SHMEDIA"
3236   "*
3238   static char templ[16];
3240   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3241   return templ;
3243   [(set_attr "type" "arith_media")])
3245 (define_split
3246   [(set (match_operand:DI 0 "arith_reg_dest" "")
3247         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3248                                          "ua_address_operand" "")))
3249                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3250                            (const_int 8))))
3251    (clobber (match_operand:DI 3 "register_operand" ""))]
3252   "TARGET_SHMEDIA"
3253   [(match_dup 4) (match_dup 5)]
3254   "
3256   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3257                  (operands[3], operands[1]));
3258   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3259                               GEN_INT (56), GEN_INT (8));
3262 (define_insn "rotlsi3_1"
3263   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3264         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3265                    (const_int 1)))
3266    (set (reg:SI T_REG)
3267         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3268   "TARGET_SH1"
3269   "rotl %0"
3270   [(set_attr "type" "arith")])
3272 (define_insn "rotlsi3_31"
3273   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3274         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3275                    (const_int 31)))
3276    (clobber (reg:SI T_REG))]
3277   "TARGET_SH1"
3278   "rotr %0"
3279   [(set_attr "type" "arith")])
3281 (define_insn "rotlsi3_16"
3282   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3283         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3284                    (const_int 16)))]
3285   "TARGET_SH1"
3286   "swap.w       %1,%0"
3287   [(set_attr "type" "arith")])
3289 (define_expand "rotlsi3"
3290   [(set (match_operand:SI 0 "arith_reg_dest" "")
3291         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3292                    (match_operand:SI 2 "immediate_operand" "")))]
3293   "TARGET_SH1"
3294   "
3296   static const char rot_tab[] = {
3297     000, 000, 000, 000, 000, 000, 010, 001,
3298     001, 001, 011, 013, 003, 003, 003, 003,
3299     003, 003, 003, 003, 003, 013, 012, 002,
3300     002, 002, 010, 000, 000, 000, 000, 000,
3301   };
3303   int count, choice;
3305   if (GET_CODE (operands[2]) != CONST_INT)
3306     FAIL;
3307   count = INTVAL (operands[2]);
3308   choice = rot_tab[count];
3309   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3310     FAIL;
3311   choice &= 7;
3312   switch (choice)
3313     {
3314     case 0:
3315       emit_move_insn (operands[0], operands[1]);
3316       count -= (count & 16) * 2;
3317       break;
3318     case 3:
3319      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3320      count -= 16;
3321      break;
3322     case 1:
3323     case 2:
3324       {
3325         rtx parts[2];
3326         parts[0] = gen_reg_rtx (SImode);
3327         parts[1] = gen_reg_rtx (SImode);
3328         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3329         emit_move_insn (parts[choice-1], operands[1]);
3330         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3331         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3332         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3333         count = (count & ~16) - 8;
3334       }
3335     }
3337   for (; count > 0; count--)
3338     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3339   for (; count < 0; count++)
3340     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3342   DONE;
3345 (define_insn "*rotlhi3_8"
3346   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3347         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3348                    (const_int 8)))]
3349   "TARGET_SH1"
3350   "swap.b       %1,%0"
3351   [(set_attr "type" "arith")])
3353 (define_expand "rotlhi3"
3354   [(set (match_operand:HI 0 "arith_reg_operand" "")
3355         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3356                    (match_operand:HI 2 "immediate_operand" "")))]
3357   "TARGET_SH1"
3358   "
3360   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3361     FAIL;
3365 ;; shift left
3367 (define_insn "ashlsi3_sh2a"
3368   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3369         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3370                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3371   "TARGET_SH2A"
3372   "shad %2,%0"
3373   [(set_attr "type" "arith")
3374    (set_attr "length" "4")])
3376 ;; This pattern is used by init_expmed for computing the costs of shift
3377 ;; insns.
3379 (define_insn_and_split "ashlsi3_std"
3380   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3381         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3382                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3383    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3384   "TARGET_SH3
3385    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3386        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3387   "@
3388    shld %2,%0
3389    add  %0,%0
3390    shll%O2      %0
3391    #"
3392   "TARGET_SH3
3393    && reload_completed
3394    && GET_CODE (operands[2]) == CONST_INT
3395    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3396   [(set (match_dup 3) (match_dup 2))
3397    (parallel
3398     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3399      (clobber (match_dup 4))])]
3400   "operands[4] = gen_rtx_SCRATCH (SImode);"
3401   [(set_attr "length" "*,*,*,4")
3402    (set_attr "type" "dyn_shift,arith,arith,arith")])
3404 (define_insn "ashlhi3_k"
3405   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3406         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3407                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3408   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3409   "@
3410         add     %0,%0
3411         shll%O2 %0"
3412   [(set_attr "type" "arith")])
3414 (define_insn "ashlsi3_n"
3415   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3416         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3417                    (match_operand:SI 2 "const_int_operand" "n")))
3418    (clobber (reg:SI T_REG))]
3419   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3420   "#"
3421   [(set (attr "length")
3422         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3423                (const_string "2")
3424                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3425                (const_string "4")
3426                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3427                (const_string "6")]
3428               (const_string "8")))
3429    (set_attr "type" "arith")])
3431 (define_split
3432   [(set (match_operand:SI 0 "arith_reg_dest" "")
3433         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3434                    (match_operand:SI 2 "const_int_operand" "")))
3435    (clobber (reg:SI T_REG))]
3436   "TARGET_SH1 && reload_completed"
3437   [(use (reg:SI R0_REG))]
3438   "
3440   gen_shifty_op (ASHIFT, operands);
3441   DONE;
3444 (define_insn "ashlsi3_media"
3445   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3446         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3447                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3448   "TARGET_SHMEDIA"
3449   "@
3450         shlld.l %1, %2, %0
3451         shlli.l %1, %2, %0"
3452   [(set_attr "type" "arith_media")
3453    (set_attr "highpart" "ignore")])
3455 (define_expand "ashlsi3"
3456   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3457                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3458                               (match_operand:SI 2 "nonmemory_operand" "")))
3459               (clobber (reg:SI T_REG))])]
3460   ""
3461   "
3463   if (TARGET_SHMEDIA)
3464     {
3465       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3466       DONE;
3467     }
3468   if (GET_CODE (operands[2]) == CONST_INT
3469       && sh_dynamicalize_shift_p (operands[2]))
3470     operands[2] = force_reg (SImode, operands[2]);
3471   if (TARGET_SH3)
3472     {
3473       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3474       DONE;
3475     }
3476   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3477     FAIL;
3480 (define_insn "*ashlhi3_n"
3481   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3482         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3483                    (match_operand:HI 2 "const_int_operand" "n")))
3484    (clobber (reg:SI T_REG))]
3485   "TARGET_SH1"
3486   "#"
3487   [(set (attr "length")
3488         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3489                (const_string "2")
3490                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3491                (const_string "4")]
3492               (const_string "6")))
3493    (set_attr "type" "arith")])
3495 (define_expand "ashlhi3"
3496   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3497                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3498                               (match_operand:SI 2 "nonmemory_operand" "")))
3499               (clobber (reg:SI T_REG))])]
3500   "TARGET_SH1"
3501   "
3503   if (GET_CODE (operands[2]) != CONST_INT)
3504     FAIL;
3505   /* It may be possible to call gen_ashlhi3 directly with more generic
3506      operands.  Make sure operands[1] is a HImode register here.  */
3507   if (!arith_reg_operand (operands[1], HImode))
3508     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3511 (define_split
3512   [(set (match_operand:HI 0 "arith_reg_dest" "")
3513         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3514                    (match_operand:HI 2 "const_int_operand" "")))
3515    (clobber (reg:SI T_REG))]
3516   "TARGET_SH1 && reload_completed"
3517   [(use (reg:SI R0_REG))]
3518   "
3520   gen_shifty_hi_op (ASHIFT, operands);
3521   DONE;
3525 ; arithmetic shift right
3528 (define_insn "ashrsi3_sh2a"
3529   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3530         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3531                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3532   "TARGET_SH2A"
3533   "shad %2,%0"
3534   [(set_attr "type" "dyn_shift")
3535    (set_attr "length" "4")])
3537 (define_insn "ashrsi3_k"
3538   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3539         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3540                      (match_operand:SI 2 "const_int_operand" "M")))
3541    (clobber (reg:SI T_REG))]
3542   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3543   "shar %0"
3544   [(set_attr "type" "arith")])
3546 ;; We can't do HImode right shifts correctly unless we start out with an
3547 ;; explicit zero / sign extension; doing that would result in worse overall
3548 ;; code, so just let the machine independent code widen the mode.
3549 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3552 ;; ??? This should be a define expand.
3554 (define_insn "ashrsi2_16"
3555   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3556         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3557                      (const_int 16)))]
3558   "TARGET_SH1"
3559   "#"
3560   [(set_attr "length" "4")])
3562 (define_split
3563   [(set (match_operand:SI 0 "arith_reg_dest" "")
3564         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3565                      (const_int 16)))]
3566   "TARGET_SH1"
3567   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3568    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3569   "operands[2] = gen_lowpart (HImode, operands[0]);")
3571 ;; ??? This should be a define expand.
3573 (define_insn "ashrsi2_31"
3574   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3575         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3576                      (const_int 31)))
3577    (clobber (reg:SI T_REG))]
3578   "TARGET_SH1"
3579   "#"
3580   [(set_attr "length" "4")])
3582 (define_split
3583   [(set (match_operand:SI 0 "arith_reg_dest" "")
3584         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3585                      (const_int 31)))
3586    (clobber (reg:SI T_REG))]
3587   "TARGET_SH1"
3588   [(const_int 0)]
3589   "
3591   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3592   emit_insn (gen_mov_neg_si_t (operands[0]));
3593   DONE;
3596 (define_peephole2
3597   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3598    (set (reg:SI T_REG)
3599         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3600   "TARGET_SH1
3601    && peep2_reg_dead_p (2, operands[0])
3602    && peep2_reg_dead_p (2, operands[1])"
3603   [(const_int 0)]
3604   "
3606   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3607   DONE;
3610 (define_insn "ashlsi_c"
3611   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3612         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3613    (set (reg:SI T_REG)
3614         (lt:SI (match_dup 1) (const_int 0)))]
3615   "TARGET_SH1"
3616   "shll %0"
3617   [(set_attr "type" "arith")])
3619 (define_insn "*ashlsi_c_void"
3620   [(set (reg:SI T_REG)
3621         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3622    (clobber (match_scratch:SI 1 "=0"))]
3623   "TARGET_SH1 && cse_not_expected"
3624   "shll %0"
3625   [(set_attr "type" "arith")])
3627 (define_insn "ashrsi3_d"
3628   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3629         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3630                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3631   "TARGET_SH3"
3632   "shad %2,%0"
3633   [(set_attr "type" "dyn_shift")])
3635 (define_insn "ashrsi3_n"
3636   [(set (reg:SI R4_REG)
3637         (ashiftrt:SI (reg:SI R4_REG)
3638                      (match_operand:SI 0 "const_int_operand" "i")))
3639    (clobber (reg:SI T_REG))
3640    (clobber (reg:SI PR_REG))
3641    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3642   "TARGET_SH1"
3643   "jsr  @%1%#"
3644   [(set_attr "type" "sfunc")
3645    (set_attr "needs_delay_slot" "yes")])
3647 (define_insn "ashrsi3_media"
3648   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3649         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3650                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3651   "TARGET_SHMEDIA"
3652   "@
3653         shard.l %1, %2, %0
3654         shari.l %1, %2, %0"
3655   [(set_attr "type" "arith_media")
3656    (set_attr "highpart" "ignore")])
3658 (define_expand "ashrsi3"
3659   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3660                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3661                                 (match_operand:SI 2 "nonmemory_operand" "")))
3662               (clobber (reg:SI T_REG))])]
3663   ""
3664   "
3666   if (TARGET_SHMEDIA)
3667     {
3668       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3669       DONE;
3670     }
3671   if (expand_ashiftrt (operands))
3672     DONE;
3673   else
3674     FAIL;
3677 ;; logical shift right
3679 (define_insn "lshrsi3_sh2a"
3680   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3681         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3682                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3683   "TARGET_SH2A"
3684   "shld %2,%0"
3685   [(set_attr "type" "dyn_shift")
3686    (set_attr "length" "4")])
3688 (define_insn "lshrsi3_d"
3689   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3690         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3691                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3692   "TARGET_SH3"
3693   "shld %2,%0"
3694   [(set_attr "type" "dyn_shift")])
3696 ;;  Only the single bit shift clobbers the T bit.
3698 (define_insn "lshrsi3_m"
3699   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3700         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3701                      (match_operand:SI 2 "const_int_operand" "M")))
3702    (clobber (reg:SI T_REG))]
3703   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3704   "shlr %0"
3705   [(set_attr "type" "arith")])
3707 (define_insn "lshrsi3_k"
3708   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3709         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3710                      (match_operand:SI 2 "const_int_operand" "P27")))]
3711   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3712    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3713   "shlr%O2      %0"
3714   [(set_attr "type" "arith")])
3716 (define_insn "lshrsi3_n"
3717   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3718         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3719                      (match_operand:SI 2 "const_int_operand" "n")))
3720    (clobber (reg:SI T_REG))]
3721   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3722   "#"
3723   [(set (attr "length")
3724         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3725                (const_string "2")
3726                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3727                (const_string "4")
3728                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3729                (const_string "6")]
3730               (const_string "8")))
3731    (set_attr "type" "arith")])
3733 (define_split
3734   [(set (match_operand:SI 0 "arith_reg_dest" "")
3735         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3736                      (match_operand:SI 2 "const_int_operand" "")))
3737    (clobber (reg:SI T_REG))]
3738   "TARGET_SH1 && reload_completed"
3739   [(use (reg:SI R0_REG))]
3740   "
3742   gen_shifty_op (LSHIFTRT, operands);
3743   DONE;
3746 (define_insn "lshrsi3_media"
3747   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3748         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3749                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3750   "TARGET_SHMEDIA"
3751   "@
3752         shlrd.l %1, %2, %0
3753         shlri.l %1, %2, %0"
3754   [(set_attr "type" "arith_media")
3755    (set_attr "highpart" "ignore")])
3757 (define_expand "lshrsi3"
3758   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3759                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3760                                 (match_operand:SI 2 "nonmemory_operand" "")))
3761               (clobber (reg:SI T_REG))])]
3762   ""
3763   "
3765   if (TARGET_SHMEDIA)
3766     {
3767       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3768       DONE;
3769     }
3770   if (GET_CODE (operands[2]) == CONST_INT
3771       && sh_dynamicalize_shift_p (operands[2]))
3772     operands[2] = force_reg (SImode, operands[2]);
3773   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3774     {
3775       rtx count = copy_to_mode_reg (SImode, operands[2]);
3776       emit_insn (gen_negsi2 (count, count));
3777       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3778       DONE;
3779     }
3780   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3781     FAIL;
3784 ;; ??? This should be a define expand.
3786 (define_insn "ashldi3_k"
3787   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3788         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3789                    (const_int 1)))
3790    (clobber (reg:SI T_REG))]
3791   "TARGET_SH1"
3792   "shll %R0\;rotcl      %S0"
3793   [(set_attr "length" "4")
3794    (set_attr "type" "arith")])
3796 (define_insn "ashldi3_media"
3797   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3798         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3799                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3800   "TARGET_SHMEDIA"
3801   "@
3802         shlld   %1, %2, %0
3803         shlli   %1, %2, %0"
3804   [(set_attr "type" "arith_media")])
3806 (define_insn "*ashldisi3_media"
3807   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3808         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3809                    (match_operand:DI 2 "const_int_operand" "n")))]
3810   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3811   "shlli.l      %1, %2, %0"
3812   [(set_attr "type" "arith_media")
3813    (set_attr "highpart" "ignore")])
3815 (define_expand "ashldi3"
3816   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3817                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3818                               (match_operand:DI 2 "immediate_operand" "")))
3819               (clobber (reg:SI T_REG))])]
3820   ""
3821   "
3823   if (TARGET_SHMEDIA)
3824     {
3825       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3826       DONE;
3827     }
3828   if (GET_CODE (operands[2]) != CONST_INT
3829       || INTVAL (operands[2]) != 1)
3830     FAIL;
3833 ;; ??? This should be a define expand.
3835 (define_insn "lshrdi3_k"
3836   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3837         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3838                      (const_int 1)))
3839    (clobber (reg:SI T_REG))]
3840   "TARGET_SH1"
3841   "shlr %S0\;rotcr      %R0"
3842   [(set_attr "length" "4")
3843    (set_attr "type" "arith")])
3845 (define_insn "lshrdi3_media"
3846   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3847         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3848                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3849   "TARGET_SHMEDIA
3850    && (arith_reg_dest (operands[0], DImode)
3851        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3852   "@
3853         shlrd   %1, %2, %0
3854         shlri   %1, %2, %0"
3855   [(set_attr "type" "arith_media")])
3857 (define_insn "*lshrdisi3_media"
3858   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3859         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3860                      (match_operand:DI 2 "const_int_operand" "n")))]
3861   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3862   "shlri.l      %1, %2, %0"
3863   [(set_attr "type" "arith_media")
3864    (set_attr "highpart" "ignore")])
3866 (define_expand "lshrdi3"
3867   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3868                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3869                                (match_operand:DI 2 "immediate_operand" "")))
3870              (clobber (reg:SI T_REG))])]
3871   ""
3872   "
3874   if (TARGET_SHMEDIA)
3875     {
3876       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3877       DONE;
3878     }
3879   if (GET_CODE (operands[2]) != CONST_INT
3880       || INTVAL (operands[2]) != 1)
3881     FAIL;
3884 ;; ??? This should be a define expand.
3886 (define_insn "ashrdi3_k"
3887   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3888         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3889                      (const_int 1)))
3890    (clobber (reg:SI T_REG))]
3891   "TARGET_SH1"
3892   "shar %S0\;rotcr      %R0"
3893   [(set_attr "length" "4")
3894    (set_attr "type" "arith")])
3896 (define_insn "ashrdi3_media"
3897   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3898         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3899                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3900   "TARGET_SHMEDIA
3901    && (arith_reg_dest (operands[0], DImode)
3902        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3903   "@
3904         shard   %1, %2, %0
3905         shari   %1, %2, %0"
3906   [(set_attr "type" "arith_media")])
3908 (define_insn "*ashrdisi3_media"
3909   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3910         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3911                      (match_operand:DI 2 "const_int_operand" "n")))]
3912   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3913   "shari.l      %1, %2, %0"
3914   [(set_attr "type" "arith_media")
3915    (set_attr "highpart" "ignore")])
3917 (define_insn "ashrdisi3_media_high"
3918   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3919         (truncate:SI
3920            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3921                         (match_operand:DI 2 "const_int_operand" "n"))))]
3922   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3923   "shari        %1, %2, %0"
3924   [(set_attr "type" "arith_media")])
3926 (define_insn "ashrdisi3_media_opaque"
3927   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3928         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3929                     (match_operand:DI 2 "const_int_operand" "n")]
3930          UNSPEC_ASHIFTRT))]
3931   "TARGET_SHMEDIA"
3932   "shari        %1, %2, %0"
3933   [(set_attr "type" "arith_media")])
3935 (define_expand "ashrdi3"
3936   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3937                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3938                                 (match_operand:DI 2 "immediate_operand" "")))
3939               (clobber (reg:SI T_REG))])]
3940   ""
3941   "
3943   if (TARGET_SHMEDIA)
3944     {
3945       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3946       DONE;
3947     }
3948   if (GET_CODE (operands[2]) != CONST_INT
3949       || INTVAL (operands[2]) != 1)
3950     FAIL;
3953 ;; combined left/right shift
3955 (define_split
3956   [(set (match_operand:SI 0 "register_operand" "")
3957         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3958                            (match_operand:SI 2 "const_int_operand" ""))
3959                 (match_operand:SI 3 "const_int_operand" "")))]
3960   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3961   [(use (reg:SI R0_REG))]
3962   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3963    DONE;")
3965 (define_split
3966   [(set (match_operand:SI 0 "register_operand" "")
3967         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3968                            (match_operand:SI 2 "const_int_operand" ""))
3969                 (match_operand:SI 3 "const_int_operand" "")))
3970    (clobber (reg:SI T_REG))]
3971   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3972   [(use (reg:SI R0_REG))]
3973   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3974    DONE;")
3976 (define_insn ""
3977   [(set (match_operand:SI 0 "register_operand" "=r")
3978         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3979                            (match_operand:SI 2 "const_int_operand" "n"))
3980                 (match_operand:SI 3 "const_int_operand" "n")))
3981    (clobber (reg:SI T_REG))]
3982   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3983  "#"
3984   [(set (attr "length")
3985         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3986                (const_string "4")
3987                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3988                (const_string "6")
3989                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3990                (const_string "8")
3991                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
3992                (const_string "10")
3993                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
3994                (const_string "12")
3995                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
3996                (const_string "14")
3997                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
3998                (const_string "16")]
3999               (const_string "18")))
4000    (set_attr "type" "arith")])
4002 (define_insn ""
4003   [(set (match_operand:SI 0 "register_operand" "=z")
4004         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4005                            (match_operand:SI 2 "const_int_operand" "n"))
4006                 (match_operand:SI 3 "const_int_operand" "n")))
4007    (clobber (reg:SI T_REG))]
4008   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4009  "#"
4010   [(set (attr "length")
4011         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4012                (const_string "4")
4013                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4014                (const_string "6")
4015                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4016                (const_string "8")]
4017               (const_string "10")))
4018    (set_attr "type" "arith")])
4020 ;; shift left / and combination with a scratch register: The combine pass
4021 ;; does not accept the individual instructions, even though they are
4022 ;; cheap.  But it needs a precise description so that it is usable after
4023 ;; reload.
4024 (define_insn "and_shl_scratch"
4025   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4026         (lshiftrt:SI
4027          (ashift:SI
4028           (and:SI
4029            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4030                         (match_operand:SI 2 "const_int_operand" "N,n"))
4031            (match_operand:SI 3 "" "0,r"))
4032           (match_operand:SI 4 "const_int_operand" "n,n"))
4033          (match_operand:SI 5 "const_int_operand" "n,n")))
4034    (clobber (reg:SI T_REG))]
4035   "TARGET_SH1"
4036   "#"
4037   [(set (attr "length")
4038         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4039                (const_string "4")
4040                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4041                (const_string "6")
4042                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4043                (const_string "8")
4044                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4045                (const_string "10")]
4046               (const_string "12")))
4047    (set_attr "type" "arith")])
4049 (define_split
4050   [(set (match_operand:SI 0 "register_operand" "")
4051         (lshiftrt:SI
4052          (ashift:SI
4053           (and:SI
4054            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4055                         (match_operand:SI 2 "const_int_operand" ""))
4056            (match_operand:SI 3 "register_operand" ""))
4057           (match_operand:SI 4 "const_int_operand" ""))
4058          (match_operand:SI 5 "const_int_operand" "")))
4059    (clobber (reg:SI T_REG))]
4060   "TARGET_SH1"
4061   [(use (reg:SI R0_REG))]
4062   "
4064   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4066   if (INTVAL (operands[2]))
4067     {
4068       gen_shifty_op (LSHIFTRT, operands);
4069     }
4070   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4071   operands[2] = operands[4];
4072   gen_shifty_op (ASHIFT, operands);
4073   if (INTVAL (operands[5]))
4074     {
4075       operands[2] = operands[5];
4076       gen_shifty_op (LSHIFTRT, operands);
4077     }
4078   DONE;
4081 ;; signed left/right shift combination.
4082 (define_split
4083   [(set (match_operand:SI 0 "register_operand" "")
4084         (sign_extract:SI
4085          (ashift:SI (match_operand:SI 1 "register_operand" "")
4086                     (match_operand:SI 2 "const_int_operand" ""))
4087          (match_operand:SI 3 "const_int_operand" "")
4088          (const_int 0)))
4089    (clobber (reg:SI T_REG))]
4090   "TARGET_SH1"
4091   [(use (reg:SI R0_REG))]
4092   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4093    DONE;")
4095 (define_insn "shl_sext_ext"
4096   [(set (match_operand:SI 0 "register_operand" "=r")
4097         (sign_extract:SI
4098          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4099                     (match_operand:SI 2 "const_int_operand" "n"))
4100          (match_operand:SI 3 "const_int_operand" "n")
4101          (const_int 0)))
4102    (clobber (reg:SI T_REG))]
4103   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4104   "#"
4105   [(set (attr "length")
4106         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4107                (const_string "2")
4108                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4109                (const_string "4")
4110                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4111                (const_string "6")
4112                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4113                (const_string "8")
4114                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4115                (const_string "10")
4116                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4117                (const_string "12")
4118                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4119                (const_string "14")
4120                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4121                (const_string "16")]
4122               (const_string "18")))
4123     (set_attr "type" "arith")])
4125 (define_insn "shl_sext_sub"
4126   [(set (match_operand:SI 0 "register_operand" "=z")
4127         (sign_extract:SI
4128          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4129                     (match_operand:SI 2 "const_int_operand" "n"))
4130          (match_operand:SI 3 "const_int_operand" "n")
4131          (const_int 0)))
4132    (clobber (reg:SI T_REG))]
4133   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4134   "#"
4135   [(set (attr "length")
4136         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4137                (const_string "6")
4138                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4139                (const_string "8")
4140                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4141                (const_string "10")
4142                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4143                (const_string "12")]
4144               (const_string "14")))
4145     (set_attr "type" "arith")])
4147 ;; These patterns are found in expansions of DImode shifts by 16, and
4148 ;; allow the xtrct instruction to be generated from C source.
4150 (define_insn "xtrct_left"
4151   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4152         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4153                            (const_int 16))
4154                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4155                              (const_int 16))))]
4156   "TARGET_SH1"
4157   "xtrct        %1,%0"
4158   [(set_attr "type" "arith")])
4160 (define_insn "xtrct_right"
4161   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4162         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4163                              (const_int 16))
4164                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4165                            (const_int 16))))]
4166   "TARGET_SH1"
4167   "xtrct        %2,%0"
4168   [(set_attr "type" "arith")])
4170 ;; -------------------------------------------------------------------------
4171 ;; Unary arithmetic
4172 ;; -------------------------------------------------------------------------
4174 (define_insn "negc"
4175   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4176         (neg:SI (plus:SI (reg:SI T_REG)
4177                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4178    (set (reg:SI T_REG)
4179         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4180                (const_int 0)))]
4181   "TARGET_SH1"
4182   "negc %1,%0"
4183   [(set_attr "type" "arith")])
4185 (define_insn "*negdi_media"
4186   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4187         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4188   "TARGET_SHMEDIA"
4189   "sub  r63, %1, %0"
4190   [(set_attr "type" "arith_media")])
4192 (define_expand "negdi2"
4193   [(set (match_operand:DI 0 "arith_reg_operand" "")
4194         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4195   ""
4196   "
4198   if (TARGET_SH1)
4199     {
4200       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4201       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4203       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4204       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4206       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4207       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4209       emit_insn (gen_clrt ());
4210       emit_insn (gen_negc (low_dst, low_src));
4211       emit_insn (gen_negc (high_dst, high_src));
4212       DONE;
4213     }
4216 (define_insn "negsi2"
4217   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4218         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4219   "TARGET_SH1"
4220   "neg  %1,%0"
4221   [(set_attr "type" "arith")])
4223 (define_insn "one_cmplsi2"
4224   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4225         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4226   "TARGET_SH1"
4227   "not  %1,%0"
4228   [(set_attr "type" "arith")])
4230 (define_expand "one_cmpldi2"
4231   [(set (match_operand:DI 0 "arith_reg_dest" "")
4232         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4233                 (const_int -1)))]
4234   "TARGET_SHMEDIA" "")
4236 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4237    This can be used as some kind of conditional execution, which is useful
4238    for abs.  */
4239 (define_split
4240   [(set (match_operand:SI 0 "arith_reg_dest" "")
4241         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4242                          (match_operand:SI 1 "arith_reg_operand" ""))
4243                  (reg:SI T_REG)))]
4244   "TARGET_HARD_SH4"
4245   [(const_int 0)]
4246   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4247    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4248    DONE;")
4250 (define_insn "cneg"
4251   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4252         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4253                       (match_operand:SI 1 "arith_reg_operand" "0")
4254                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4255   "TARGET_HARD_SH4"
4256   "bf 0f\;neg %2,%0\\n0:"
4257   [(set_attr "type" "arith") ;; poor approximation
4258    (set_attr "length" "4")])
4261 ;; -------------------------------------------------------------------------
4262 ;; Zero extension instructions
4263 ;; -------------------------------------------------------------------------
4265 (define_insn "zero_extendsidi2"
4266   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4267         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4268   "TARGET_SHMEDIA"
4269   "addz.l       %1, r63, %0"
4270   [(set_attr "type" "arith_media")
4271    (set_attr "highpart" "extend")])
4273 (define_insn "zero_extendhidi2"
4274   [(set (match_operand:DI 0 "register_operand" "=r,r")
4275         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4276   "TARGET_SHMEDIA"
4277   "@
4278         #
4279         ld%M1.uw        %m1, %0"
4280   [(set_attr "type" "*,load_media")
4281    (set (attr "highpart")
4282         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4283                (const_string "user")]
4284               (const_string "ignore")))])
4286 (define_split
4287   [(set (match_operand:DI 0 "register_operand" "")
4288         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4289   "TARGET_SHMEDIA && reload_completed"
4290   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4291    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4292   "
4294   if (GET_CODE (operands[1]) == TRUNCATE)
4295     operands[1] = XEXP (operands[1], 0);
4298 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4299 ;; reload the entire truncate expression.
4300 (define_insn_and_split "*loaddi_trunc"
4301   [(set (match_operand 0 "any_register_operand" "=r")
4302         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4303   "TARGET_SHMEDIA && reload_completed"
4304   "#"
4305   "TARGET_SHMEDIA && reload_completed"
4306   [(set (match_dup 0) (match_dup 1))]
4307   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4309 (define_insn "zero_extendqidi2"
4310   [(set (match_operand:DI 0 "register_operand" "=r,r")
4311         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4312   "TARGET_SHMEDIA"
4313   "@
4314         andi    %1, 255, %0
4315         ld%M1.ub        %m1, %0"
4316   [(set_attr "type" "arith_media,load_media")
4317    (set (attr "highpart")
4318         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4319                (const_string "user")]
4320               (const_string "ignore")))])
4322 (define_expand "zero_extendhisi2"
4323   [(set (match_operand:SI 0 "arith_reg_operand" "")
4324         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4325   ""
4326   "
4328   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4329     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4332 (define_insn "*zero_extendhisi2_compact"
4333   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4334         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4335   "TARGET_SH1"
4336   "extu.w       %1,%0"
4337   [(set_attr "type" "arith")])
4339 (define_insn "*zero_extendhisi2_media"
4340   [(set (match_operand:SI 0 "register_operand" "=r,r")
4341         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4342   "TARGET_SHMEDIA"
4343   "@
4344         #
4345         ld%M1.uw        %m1, %0"
4346   [(set_attr "type" "arith_media,load_media")
4347    (set (attr "highpart")
4348         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4349                (const_string "user")]
4350               (const_string "ignore")))])
4352 (define_split
4353   [(set (match_operand:SI 0 "register_operand" "")
4354         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4355   "TARGET_SHMEDIA && reload_completed"
4356   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4357    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4358   "
4360   rtx op1 = operands[1];
4362   if (GET_CODE (op1) == TRUNCATE)
4363     op1 = XEXP (op1, 0);
4364   operands[2]
4365     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4366                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4369 (define_expand "zero_extendqisi2"
4370   [(set (match_operand:SI 0 "arith_reg_operand" "")
4371         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4372   ""
4373   "
4375   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4376     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4379 (define_insn "*zero_extendqisi2_compact"
4380   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4381         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4382   "TARGET_SH1"
4383   "extu.b       %1,%0"
4384   [(set_attr "type" "arith")])
4386 (define_insn "*zero_extendqisi2_media"
4387   [(set (match_operand:SI 0 "register_operand" "=r,r")
4388         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4389   "TARGET_SHMEDIA"
4390   "@
4391         andi    %1, 255, %0
4392         ld%M1.ub        %m1, %0"
4393   [(set_attr "type" "arith_media,load_media")
4394    (set (attr "highpart")
4395         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4396                (const_string "user")]
4397               (const_string "ignore")))])
4399 (define_insn "zero_extendqihi2"
4400   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4401         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4402   "TARGET_SH1"
4403   "extu.b       %1,%0"
4404   [(set_attr "type" "arith")])
4406 ;; -------------------------------------------------------------------------
4407 ;; Sign extension instructions
4408 ;; -------------------------------------------------------------------------
4410 ;; ??? This should be a define expand.
4411 ;; ??? Or perhaps it should be dropped?
4413 ;; convert_move generates good code for SH[1-4].
4414 (define_insn "extendsidi2"
4415   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4416         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4417   "TARGET_SHMEDIA"
4418   "@
4419         add.l   %1, r63, %0
4420         ld%M1.l %m1, %0
4421         fmov.sl %1, %0"
4422   [(set_attr "type" "arith_media,load_media,fpconv_media")
4423    (set (attr "highpart")
4424         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4425                (const_string "user")]
4426               (const_string "extend")))])
4428 (define_insn "extendhidi2"
4429   [(set (match_operand:DI 0 "register_operand" "=r,r")
4430         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4431   "TARGET_SHMEDIA"
4432   "@
4433         #
4434         ld%M1.w %m1, %0"
4435   [(set_attr "type" "*,load_media")
4436    (set (attr "highpart")
4437         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4438                (const_string "user")]
4439               (const_string "ignore")))])
4441 (define_split
4442   [(set (match_operand:DI 0 "register_operand" "")
4443         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4444   "TARGET_SHMEDIA && reload_completed"
4445   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4446    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4447   "
4449   if (GET_CODE (operands[1]) == TRUNCATE)
4450     operands[1] = XEXP (operands[1], 0);
4453 (define_insn "extendqidi2"
4454   [(set (match_operand:DI 0 "register_operand" "=r,r")
4455         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4456   "TARGET_SHMEDIA"
4457   "@
4458         #
4459         ld%M1.b %m1, %0"
4460   [(set_attr "type" "*,load_media")
4461    (set (attr "highpart")
4462         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4463                (const_string "user")]
4464               (const_string "ignore")))])
4466 (define_split
4467   [(set (match_operand:DI 0 "register_operand" "")
4468         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4469   "TARGET_SHMEDIA && reload_completed"
4470   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4471    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4472   "
4474   if (GET_CODE (operands[1]) == TRUNCATE)
4475     operands[1] = XEXP (operands[1], 0);
4478 (define_expand "extendhisi2"
4479   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4480         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4481   ""
4482   "")
4484 (define_insn "*extendhisi2_compact"
4485   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4486         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4487   "TARGET_SH1"
4488   "@
4489         exts.w  %1,%0
4490         mov.w   %1,%0"
4491   [(set_attr "type" "arith,load")])
4493 (define_insn "*extendhisi2_media"
4494   [(set (match_operand:SI 0 "register_operand" "=r,r")
4495         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4496   "TARGET_SHMEDIA"
4497   "@
4498         #
4499         ld%M1.w %m1, %0"
4500   [(set_attr "type" "arith_media,load_media")
4501    (set (attr "highpart")
4502         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4503                (const_string "user")]
4504               (const_string "ignore")))])
4506 (define_split
4507   [(set (match_operand:SI 0 "register_operand" "")
4508         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4509   "TARGET_SHMEDIA && reload_completed"
4510   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4511    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4512   "
4514   rtx op1 = operands[1];
4515   if (GET_CODE (op1) == TRUNCATE)
4516     op1 = XEXP (op1, 0);
4517   operands[2]
4518     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4519                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4522 (define_expand "extendqisi2"
4523   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4524         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4525   ""
4526   "")
4528 (define_insn "*extendqisi2_compact"
4529   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4530         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4531   "TARGET_SH1"
4532   "@
4533         exts.b  %1,%0
4534         mov.b   %1,%0"
4535   [(set_attr "type" "arith,load")])
4537 (define_insn "*extendqisi2_media"
4538   [(set (match_operand:SI 0 "register_operand" "=r,r")
4539         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4540   "TARGET_SHMEDIA"
4541   "@
4542         #
4543         ld%M1.b %m1, %0"
4544   [(set_attr "type" "arith_media,load_media")
4545    (set (attr "highpart")
4546         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4547                (const_string "user")]
4548               (const_string "ignore")))])
4550 (define_split
4551   [(set (match_operand:SI 0 "register_operand" "")
4552         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4553   "TARGET_SHMEDIA && reload_completed"
4554   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4555    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4556    "
4558   rtx op1 = operands[1];
4559   if (GET_CODE (op1) == TRUNCATE)
4560     op1 = XEXP (op1, 0);
4561   operands[2]
4562     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4563                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4566 (define_insn "extendqihi2"
4567   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4568         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4569   "TARGET_SH1"
4570   "@
4571         exts.b  %1,%0
4572         mov.b   %1,%0"
4573   [(set_attr "type" "arith,load")])
4575 /* It would seem useful to combine the truncXi patterns into the movXi
4576    patterns, but unary operators are ignored when matching constraints,
4577    so we need separate patterns.  */
4578 (define_insn "truncdisi2"
4579   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4580         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4581   "TARGET_SHMEDIA"
4582   "@
4583         add.l   %1, r63, %0
4584         st%M0.l %m0, %1
4585         fst%M0.s        %m0, %T1
4586         fmov.ls %1, %0
4587         fmov.sl %T1, %0
4588         fmov.s  %T1, %0"
4589   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4590    (set (attr "highpart")
4591         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4592                (const_string "user")]
4593               (const_string "extend")))])
4595 (define_insn "truncdihi2"
4596   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4597         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4598   "TARGET_SHMEDIA"
4599   "@
4600         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4601         st%M0.w %m0, %1"
4602   [(set_attr "type"   "arith_media,store_media")
4603    (set_attr "length" "8,4")
4604    (set (attr "highpart")
4605         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4606                (const_string "user")]
4607               (const_string "extend")))])
4609 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4610 ; Because we use zero extension, we can't provide signed QImode compares
4611 ; using a simple compare or conditional banch insn.
4612 (define_insn "truncdiqi2"
4613   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4614         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4615   "TARGET_SHMEDIA"
4616   "@
4617         andi    %1, 255, %0
4618         st%M0.b %m0, %1"
4619   [(set_attr "type"   "arith_media,store")
4620    (set (attr "highpart")
4621         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4622                (const_string "user")]
4623               (const_string "extend")))])
4624 ;; -------------------------------------------------------------------------
4625 ;; Move instructions
4626 ;; -------------------------------------------------------------------------
4628 ;; define push and pop so it is easy for sh.c
4629 ;; We can't use push and pop on SHcompact because the stack must always
4630 ;; be 8-byte aligned.
4632 (define_expand "push"
4633   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4634         (match_operand:SI 0 "register_operand" "r,l,x"))]
4635   "TARGET_SH1 && ! TARGET_SH5"
4636   "")
4638 (define_expand "pop"
4639   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4640         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4641   "TARGET_SH1 && ! TARGET_SH5"
4642   "")
4644 (define_expand "push_e"
4645   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4646                    (match_operand:SF 0 "" ""))
4647               (use (reg:PSI FPSCR_REG))
4648               (clobber (scratch:SI))])]
4649   "TARGET_SH1 && ! TARGET_SH5"
4650   "")
4652 (define_insn "push_fpul"
4653   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4654   "TARGET_SH2E && ! TARGET_SH5"
4655   "sts.l        fpul,@-r15"
4656   [(set_attr "type" "store")
4657    (set_attr "late_fp_use" "yes")
4658    (set_attr "hit_stack" "yes")])
4660 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4661 ;; so use that.
4662 (define_expand "push_4"
4663   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4664                    (match_operand:DF 0 "" ""))
4665               (use (reg:PSI FPSCR_REG))
4666               (clobber (scratch:SI))])]
4667   "TARGET_SH1 && ! TARGET_SH5"
4668   "")
4670 (define_expand "pop_e"
4671   [(parallel [(set (match_operand:SF 0 "" "")
4672               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4673               (use (reg:PSI FPSCR_REG))
4674               (clobber (scratch:SI))])]
4675   "TARGET_SH1 && ! TARGET_SH5"
4676   "")
4678 (define_insn "pop_fpul"
4679   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4680   "TARGET_SH2E && ! TARGET_SH5"
4681   "lds.l        @r15+,fpul"
4682   [(set_attr "type" "load")
4683    (set_attr "hit_stack" "yes")])
4685 (define_expand "pop_4"
4686   [(parallel [(set (match_operand:DF 0 "" "")
4687                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4688               (use (reg:PSI FPSCR_REG))
4689               (clobber (scratch:SI))])]
4690   "TARGET_SH1 && ! TARGET_SH5"
4691   "")
4693 (define_expand "push_fpscr"
4694   [(const_int 0)]
4695   "TARGET_SH2E"
4696   "
4698   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
4699                                                  gen_rtx_PRE_DEC (Pmode,
4700                                                           stack_pointer_rtx)),
4701                                         get_fpscr_rtx ()));
4702   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4703   DONE;
4706 (define_expand "pop_fpscr"
4707   [(const_int 0)]
4708   "TARGET_SH2E"
4709   "
4711   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4712                                         gen_rtx_MEM (PSImode,
4713                                                  gen_rtx_POST_INC (Pmode,
4714                                                           stack_pointer_rtx))));
4715   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4716   DONE;
4719 ;; These two patterns can happen as the result of optimization, when
4720 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4721 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4723 (define_insn "clrt"
4724   [(set (reg:SI T_REG) (const_int 0))]
4725   "TARGET_SH1"
4726   "clrt")
4728 (define_insn "sett"
4729   [(set (reg:SI T_REG) (const_int 1))]
4730   "TARGET_SH1"
4731   "sett")
4733 ;; t/r must come after r/r, lest reload will try to reload stuff like
4734 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4735 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4736 (define_insn "movsi_i"
4737   [(set (match_operand:SI 0 "general_movdst_operand"
4738             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4739         (match_operand:SI 1 "general_movsrc_operand"
4740          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4741   "TARGET_SH1
4742    && ! TARGET_SH2E
4743    && ! TARGET_SH2A
4744    && (register_operand (operands[0], SImode)
4745        || register_operand (operands[1], SImode))"
4746   "@
4747         mov.l   %1,%0
4748         mov     %1,%0
4749         cmp/pl  %1
4750         mov.l   %1,%0
4751         sts     %1,%0
4752         sts     %1,%0
4753         movt    %0
4754         mov.l   %1,%0
4755         sts.l   %1,%0
4756         sts.l   %1,%0
4757         lds     %1,%0
4758         lds     %1,%0
4759         lds.l   %1,%0
4760         lds.l   %1,%0
4761         fake    %1,%0"
4762   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4763    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4765 ;; t/r must come after r/r, lest reload will try to reload stuff like
4766 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4767 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4768 ;; will require a reload.
4769 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4770 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4771 (define_insn "movsi_ie"
4772   [(set (match_operand:SI 0 "general_movdst_operand"
4773             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4774         (match_operand:SI 1 "general_movsrc_operand"
4775          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4776   "(TARGET_SH2E || TARGET_SH2A)
4777    && (register_operand (operands[0], SImode)
4778        || register_operand (operands[1], SImode))"
4779   "@
4780         mov.l   %1,%0
4781         mov     %1,%0
4782         movi20  %1,%0
4783         cmp/pl  %1
4784         mov.l   %1,%0
4785         sts     %1,%0
4786         sts     %1,%0
4787         movt    %0
4788         mov.l   %1,%0
4789         sts.l   %1,%0
4790         sts.l   %1,%0
4791         lds     %1,%0
4792         lds     %1,%0
4793         lds.l   %1,%0
4794         lds.l   %1,%0
4795         lds.l   %1,%0
4796         sts.l   %1,%0
4797         fake    %1,%0
4798         lds     %1,%0
4799         sts     %1,%0
4800         fsts    fpul,%0
4801         flds    %1,fpul
4802         fmov    %1,%0
4803         ! move optimized away"
4804   [(set_attr "type" "pcload_si,move,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,fmove,fmove,fmove,nil")
4805    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4806    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4808 (define_insn "movsi_i_lowpart"
4809   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4810         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4811    "TARGET_SH1
4812     && (register_operand (operands[0], SImode)
4813         || register_operand (operands[1], SImode))"
4814   "@
4815         mov.l   %1,%0
4816         mov     %1,%0
4817         mov.l   %1,%0
4818         sts     %1,%0
4819         sts     %1,%0
4820         movt    %0
4821         mov.l   %1,%0
4822         fake    %1,%0"
4823   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4825 (define_insn_and_split "load_ra"
4826   [(set (match_operand:SI 0 "general_movdst_operand" "")
4827         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4828   "TARGET_SH1"
4829   "#"
4830   "&& ! currently_expanding_to_rtl"
4831   [(set (match_dup 0) (match_dup 1))]
4832   "
4834   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4835     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
4838 ;; The '?'s in the following constraints may not reflect the time taken
4839 ;; to perform the move. They are there to discourage the use of floating-
4840 ;; point registers for storing integer values.
4841 (define_insn "*movsi_media"
4842   [(set (match_operand:SI 0 "general_movdst_operand"
4843                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4844         (match_operand:SI 1 "general_movsrc_operand"
4845          "r,I16C16,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4846   "TARGET_SHMEDIA_FPU
4847    && (register_operand (operands[0], SImode)
4848        || sh_register_operand (operands[1], SImode)
4849        || GET_CODE (operands[1]) == TRUNCATE)"
4850   "@
4851         add.l   %1, r63, %0
4852         movi    %1, %0
4853         #
4854         ld%M1.l %m1, %0
4855         st%M0.l %m0, %N1
4856         fld%M1.s        %m1, %0
4857         fst%M0.s        %m0, %1
4858         fmov.ls %N1, %0
4859         fmov.sl %1, %0
4860         fmov.s  %1, %0
4861         ptabs   %1, %0
4862         gettr   %1, %0
4863         pt      %1, %0"
4864   [(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")
4865    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4866    (set (attr "highpart")
4867         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4868                (const_string "user")]
4869               (const_string "ignore")))])
4871 (define_insn "*movsi_media_nofpu"
4872   [(set (match_operand:SI 0 "general_movdst_operand"
4873                 "=r,r,r,r,m,*b,r,*b")
4874         (match_operand:SI 1 "general_movsrc_operand"
4875          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
4876   "TARGET_SHMEDIA
4877    && (register_operand (operands[0], SImode)
4878        || sh_register_operand (operands[1], SImode)
4879        || GET_CODE (operands[1]) == TRUNCATE)"
4880   "@
4881         add.l   %1, r63, %0
4882         movi    %1, %0
4883         #
4884         ld%M1.l %m1, %0
4885         st%M0.l %m0, %N1
4886         ptabs   %1, %0
4887         gettr   %1, %0
4888         pt      %1, %0"
4889   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4890    (set_attr "length" "4,4,8,4,4,4,4,12")
4891    (set (attr "highpart")
4892         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4893                (const_string "user")]
4894               (const_string "ignore")))])
4896 (define_expand "movsi_const"
4897   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4898         (const:SI (sign_extend:SI
4899                    (truncate:HI
4900                     (ashiftrt:SI
4901                      (match_operand:DI 1 "immediate_operand" "s")
4902                      (const_int 16))))))
4903    (set (match_dup 0)
4904         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4905                 (zero_extend:SI
4906                  (truncate:HI
4907                   (const:SI
4908                    (sign_extend:SI
4909                     (truncate:HI (match_dup 1))))))))]
4910   "TARGET_SHMEDIA && reload_completed
4911    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4912   "
4914   if (GET_CODE (operands[1]) == LABEL_REF
4915       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4916     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4917   else if (GOTOFF_P (operands[1]))
4918     {
4919       rtx unspec = XEXP (operands[1], 0);
4921       if (! UNSPEC_GOTOFF_P (unspec))
4922         {
4923           unspec = XEXP (unspec, 0);
4924           if (! UNSPEC_GOTOFF_P (unspec))
4925             abort ();
4926         }
4927       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4928           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4929         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4930     }
4933 (define_expand "movsi_const_16bit"
4934   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4935         (const:SI (sign_extend:SI
4936                    (truncate:HI
4937                     (match_operand:DI 1 "immediate_operand" "s")))))]
4938   "TARGET_SHMEDIA && flag_pic && reload_completed
4939    && GET_CODE (operands[1]) == SYMBOL_REF"
4940   "")
4942 (define_split
4943   [(set (match_operand:SI 0 "arith_reg_dest" "")
4944         (match_operand:SI 1 "immediate_operand" ""))]
4945   "TARGET_SHMEDIA && reload_completed
4946    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4947   [(const_int 0)]
4948   "
4950   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4952   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4953                                         REG_NOTES (insn));
4955   DONE;
4958 (define_split
4959   [(set (match_operand:SI 0 "register_operand" "")
4960         (match_operand:SI 1 "immediate_operand" ""))]
4961   "TARGET_SHMEDIA && reload_completed
4962    && ((GET_CODE (operands[1]) == CONST_INT
4963         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4964        || GET_CODE (operands[1]) == CONST_DOUBLE)"
4965   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4967 (define_expand "movsi"
4968   [(set (match_operand:SI 0 "general_movdst_operand" "")
4969         (match_operand:SI 1 "general_movsrc_operand" ""))]
4970   ""
4971   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4973 (define_expand "ic_invalidate_line"
4974   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4975                                 (match_dup 1)] UNSPEC_ICACHE)
4976               (clobber (scratch:SI))])]
4977   "TARGET_HARD_SH4 || TARGET_SH5"
4978   "
4980   if (TARGET_SHMEDIA)
4981     {
4982       emit_insn (gen_ic_invalidate_line_media (operands[0]));
4983       DONE;
4984     }
4985   else if (TARGET_SHCOMPACT)
4986     {
4987       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4988       operands[1] = force_reg (Pmode, operands[1]);
4989       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
4990       DONE;
4991     }
4992   else if (TARGET_SH4A_ARCH)
4993     {
4994       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
4995       DONE;
4996     }
4997   operands[0] = force_reg (Pmode, operands[0]);
4998   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
4999                                                                Pmode)));
5002 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5003 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5004 ;; the requirement *1*00 for associative address writes.  The alignment of
5005 ;; %0 implies that its least significant bit is cleared,
5006 ;; thus we clear the V bit of a matching entry if there is one.
5007 (define_insn "ic_invalidate_line_i"
5008   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5009                      (match_operand:SI 1 "register_operand" "r")]
5010                      UNSPEC_ICACHE)
5011    (clobber (match_scratch:SI 2 "=&r"))]
5012   "TARGET_HARD_SH4"
5013   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5014   [(set_attr "length" "8")
5015    (set_attr "type" "cwb")])
5017 (define_insn "ic_invalidate_line_sh4a"
5018   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5019                     UNSPEC_ICACHE)]
5020   "TARGET_SH4A_ARCH"
5021   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5022   [(set_attr "length" "16")
5023    (set_attr "type" "cwb")])
5025 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5026 ;; an add in the code that calculates the address.
5027 (define_insn "ic_invalidate_line_media"
5028   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5029                     UNSPEC_ICACHE)]
5030   "TARGET_SHMEDIA"
5031   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5032   [(set_attr "length" "16")
5033    (set_attr "type" "invalidate_line_media")])
5035 (define_insn "ic_invalidate_line_compact"
5036   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5037                      (match_operand:SI 1 "register_operand" "r")]
5038                     UNSPEC_ICACHE)
5039    (clobber (reg:SI PR_REG))]
5040   "TARGET_SHCOMPACT"
5041   "jsr @%1%#"
5042   [(set_attr "type" "sfunc")
5043    (set_attr "needs_delay_slot" "yes")])
5045 (define_expand "initialize_trampoline"
5046   [(match_operand:SI 0 "" "")
5047    (match_operand:SI 1 "" "")
5048    (match_operand:SI 2 "" "")]
5049   "TARGET_SHCOMPACT"
5050   "
5052   rtx sfun, tramp;
5054   tramp = force_reg (Pmode, operands[0]);
5055   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5056                                             SFUNC_STATIC));
5057   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5058   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5060   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5061   DONE;
5064 (define_insn "initialize_trampoline_compact"
5065   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5066                      (match_operand:SI 1 "register_operand" "r")
5067                      (reg:SI R2_REG) (reg:SI R3_REG)]
5068                     UNSPEC_INIT_TRAMP)
5070    (clobber (reg:SI PR_REG))]
5071   "TARGET_SHCOMPACT"
5072   "jsr @%1%#"
5073   [(set_attr "type" "sfunc")
5074    (set_attr "needs_delay_slot" "yes")])
5076 (define_insn "movqi_i"
5077   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5078         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
5079   "TARGET_SH1
5080    && (arith_reg_operand (operands[0], QImode)
5081        || arith_reg_operand (operands[1], QImode))"
5082   "@
5083         mov     %1,%0
5084         mov.b   %1,%0
5085         mov.b   %1,%0
5086         movt    %0
5087         sts     %1,%0
5088         lds     %1,%0"
5089  [(set_attr "type" "move,load,store,move,move,move")])
5091 (define_insn "*movqi_media"
5092   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5093         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
5094   "TARGET_SHMEDIA
5095    && (arith_reg_operand (operands[0], QImode)
5096        || extend_reg_or_0_operand (operands[1], QImode))"
5097   "@
5098         add.l   %1, r63, %0
5099         movi    %1, %0
5100         ld%M1.ub        %m1, %0
5101         st%M0.b %m0, %N1"
5102   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5103    (set (attr "highpart")
5104         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5105                (const_string "user")]
5106               (const_string "ignore")))])
5108 (define_expand "movqi"
5109   [(set (match_operand:QI 0 "general_operand" "")
5110         (match_operand:QI 1 "general_operand"  ""))]
5111   ""
5112   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5114 (define_expand "reload_inqi"
5115   [(set (match_operand:SI 2 "" "=&r")
5116         (match_operand:QI 1 "inqhi_operand" ""))
5117    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5118         (truncate:QI (match_dup 3)))]
5119   "TARGET_SHMEDIA"
5120   "
5122   rtx inner = XEXP (operands[1], 0);
5123   int regno = REGNO (inner);
5125   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5126   operands[1] = gen_rtx_REG (SImode, regno);
5127   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5130 /* When storing r0, we have to avoid reg+reg addressing.  */
5131 (define_insn "movhi_i"
5132   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5133         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5134   "TARGET_SH1
5135    && (arith_reg_operand (operands[0], HImode)
5136        || arith_reg_operand (operands[1], HImode))
5137    && (GET_CODE (operands[0]) != MEM
5138        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5139        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5140        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5141   "@
5142         mov.w   %1,%0
5143         mov     %1,%0
5144         mov.w   %1,%0
5145         movt    %0
5146         mov.w   %1,%0
5147         sts     %1,%0
5148         lds     %1,%0
5149         fake    %1,%0"
5150   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5152 (define_insn "*movhi_media"
5153   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5154         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
5155   "TARGET_SHMEDIA
5156    && (arith_reg_operand (operands[0], HImode)
5157        || arith_reg_or_0_operand (operands[1], HImode))"
5158   "@
5159         add.l   %1, r63, %0
5160         movi    %1, %0
5161         #
5162         ld%M1.w %m1, %0
5163         st%M0.w %m0, %N1"
5164   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5165    (set (attr "highpart")
5166         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5167                (const_string "user")]
5168               (const_string "ignore")))])
5170 (define_split
5171   [(set (match_operand:HI 0 "register_operand" "")
5172         (match_operand:HI 1 "immediate_operand" ""))]
5173   "TARGET_SHMEDIA && reload_completed
5174    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5175   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5177 (define_expand "movhi"
5178   [(set (match_operand:HI 0 "general_movdst_operand" "")
5179         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5180   ""
5181   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5183 (define_expand "reload_inhi"
5184   [(set (match_operand:SI 2 "" "=&r")
5185         (match_operand:HI 1 "inqhi_operand" ""))
5186    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5187         (truncate:HI (match_dup 3)))]
5188   "TARGET_SHMEDIA"
5189   "
5191   rtx inner = XEXP (operands[1], 0);
5192   int regno = REGNO (inner);
5194   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5195   operands[1] = gen_rtx_REG (SImode, regno);
5196   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5199 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5200 ;; compiled with -m2 -ml -O3 -funroll-loops
5201 (define_insn "*movdi_i"
5202   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5203         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5204   "TARGET_SH1
5205    && (arith_reg_operand (operands[0], DImode)
5206        || arith_reg_operand (operands[1], DImode))"
5207   "* return output_movedouble (insn, operands, DImode);"
5208   [(set_attr "length" "4")
5209    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5211 ;; If the output is a register and the input is memory or a register, we have
5212 ;; to be careful and see which word needs to be loaded first.
5214 (define_split
5215   [(set (match_operand:DI 0 "general_movdst_operand" "")
5216         (match_operand:DI 1 "general_movsrc_operand" ""))]
5217   "TARGET_SH1 && reload_completed"
5218   [(set (match_dup 2) (match_dup 3))
5219    (set (match_dup 4) (match_dup 5))]
5220   "
5222   int regno;
5224   if ((GET_CODE (operands[0]) == MEM
5225        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5226       || (GET_CODE (operands[1]) == MEM
5227           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5228     FAIL;
5230   switch (GET_CODE (operands[0]))
5231     {
5232     case REG:
5233       regno = REGNO (operands[0]);
5234       break;
5235     case SUBREG:
5236       regno = subreg_regno (operands[0]);
5237       break;
5238     case MEM:
5239       regno = -1;
5240       break;
5241     default:
5242       gcc_unreachable ();
5243     }
5245   if (regno == -1
5246       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5247     {
5248       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5249       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5250       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5251       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5252     }
5253   else
5254     {
5255       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5256       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5257       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5258       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5259     }
5261   if (operands[2] == 0 || operands[3] == 0
5262       || operands[4] == 0 || operands[5] == 0)
5263     FAIL;
5266 ;; The '?'s in the following constraints may not reflect the time taken
5267 ;; to perform the move. They are there to discourage the use of floating-
5268 ;; point registers for storing integer values.
5269 (define_insn "*movdi_media"
5270   [(set (match_operand:DI 0 "general_movdst_operand"
5271                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5272         (match_operand:DI 1 "general_movsrc_operand"
5273          "r,I16C16,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5274   "TARGET_SHMEDIA_FPU
5275    && (register_operand (operands[0], DImode)
5276        || sh_register_operand (operands[1], DImode))"
5277   "@
5278         add     %1, r63, %0
5279         movi    %1, %0
5280         #
5281         ld%M1.q %m1, %0
5282         st%M0.q %m0, %N1
5283         fld%M1.d        %m1, %0
5284         fst%M0.d        %m0, %1
5285         fmov.qd %N1, %0
5286         fmov.dq %1, %0
5287         fmov.d  %1, %0
5288         ptabs   %1, %0
5289         gettr   %1, %0
5290         pt      %1, %0"
5291   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,fload_media,fstore_media,fload_media,dfpconv_media,fmove_media,ptabs_media,gettr_media,pt_media")
5292    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5294 (define_insn "*movdi_media_nofpu"
5295   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5296         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
5297   "TARGET_SHMEDIA
5298    && (register_operand (operands[0], DImode)
5299        || sh_register_operand (operands[1], DImode))"
5300   "@
5301         add     %1, r63, %0
5302         movi    %1, %0
5303         #
5304         ld%M1.q %m1, %0
5305         st%M0.q %m0, %N1
5306         ptabs   %1, %0
5307         gettr   %1, %0
5308         pt      %1, %0"
5309   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5310    (set_attr "length" "4,4,16,4,4,4,4,*")])
5312 (define_insn "*movdi_media_I16"
5313   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5314         (match_operand:DI 1 "const_int_operand" "I16"))]
5315   "TARGET_SHMEDIA && reload_completed"
5316   "movi %1, %0"
5317   [(set_attr "type" "arith_media")
5318    (set_attr "length" "4")])
5320 (define_split
5321   [(set (match_operand:DI 0 "arith_reg_dest" "")
5322         (match_operand:DI 1 "immediate_operand" ""))]
5323   "TARGET_SHMEDIA && reload_completed
5324    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5325   [(set (match_dup 0) (match_dup 1))]
5326   "
5328   rtx insn;
5330   if (TARGET_SHMEDIA64)
5331     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5332   else
5333     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5335   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5336                                         REG_NOTES (insn));
5338   DONE;
5341 (define_expand "movdi_const"
5342   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5343         (const:DI (sign_extend:DI
5344                    (truncate:HI
5345                     (ashiftrt:DI
5346                      (match_operand:DI 1 "immediate_operand" "s")
5347                      (const_int 48))))))
5348    (set (match_dup 0)
5349         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5350                 (zero_extend:DI
5351                  (truncate:HI
5352                   (const:DI
5353                    (sign_extend:DI
5354                     (truncate:HI
5355                      (ashiftrt:SI
5356                       (match_dup 1)
5357                       (const_int 32)))))))))
5358    (set (match_dup 0)
5359         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5360                 (zero_extend:DI
5361                  (truncate:HI
5362                   (const:DI
5363                    (sign_extend:DI
5364                     (truncate:HI
5365                      (ashiftrt:SI
5366                       (match_dup 1)
5367                       (const_int 16)))))))))
5368    (set (match_dup 0)
5369         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5370                 (zero_extend:DI
5371                  (truncate:HI
5372                   (const:DI
5373                    (sign_extend:DI
5374                     (truncate:HI
5375                      (match_dup 1))))))))]
5376   "TARGET_SHMEDIA64 && reload_completed
5377    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5378   "
5380   sh_mark_label (operands[1], 4);
5383 (define_expand "movdi_const_32bit"
5384   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5385         (const:DI (sign_extend:DI
5386                    (truncate:HI
5387                     (ashiftrt:DI
5388                      (match_operand:DI 1 "immediate_operand" "s")
5389                      (const_int 16))))))
5390    (set (match_dup 0)
5391         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5392                 (zero_extend:DI
5393                  (truncate:HI
5394                   (const:DI
5395                    (sign_extend:DI
5396                     (truncate:HI
5397                      (match_dup 1))))))))]
5398   "TARGET_SHMEDIA32 && reload_completed
5399    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5400   "
5402   sh_mark_label (operands[1], 2);
5405 (define_expand "movdi_const_16bit"
5406   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5407         (const:DI (sign_extend:DI
5408                    (truncate:HI
5409                     (match_operand:DI 1 "immediate_operand" "s")))))]
5410   "TARGET_SHMEDIA && flag_pic && reload_completed
5411    && GET_CODE (operands[1]) == SYMBOL_REF"
5412   "")
5414 (define_split
5415   [(set (match_operand:DI 0 "ext_dest_operand" "")
5416         (match_operand:DI 1 "immediate_operand" ""))]
5417   "TARGET_SHMEDIA && reload_completed
5418    && GET_CODE (operands[1]) == CONST_INT
5419    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5420   [(set (match_dup 0) (match_dup 2))
5421    (match_dup 1)]
5422   "
5424   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5425   unsigned HOST_WIDE_INT low = val;
5426   unsigned HOST_WIDE_INT high = val;
5427   unsigned HOST_WIDE_INT sign;
5428   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5430   /* Sign-extend the 16 least-significant bits.  */
5431   low &= 0xffff;
5432   low ^= 0x8000;
5433   low -= 0x8000;
5435   /* Arithmetic shift right the word by 16 bits.  */
5436   high >>= 16;
5437   if (GET_CODE (operands[0]) == SUBREG
5438       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5439     {
5440       high &= 0xffff;
5441       high ^= 0x8000;
5442       high -= 0x8000;
5443     }
5444   else
5445     {
5446       sign = 1;
5447       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5448       high ^= sign;
5449       high -= sign;
5450     }
5451   do
5452     {
5453       /* If we can't generate the constant with a two-insn movi / shori
5454          sequence, try some other strategies.  */
5455       if (! CONST_OK_FOR_I16 (high))
5456         {
5457           /* Try constant load / left shift.  We know VAL != 0.  */
5458           val2 = val ^ (val-1);
5459           if (val2 > 0x1ffff)
5460             {
5461               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5463               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5464                   || (! CONST_OK_FOR_I16 (high >> 16)
5465                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5466                 {
5467                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5468                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5469                                                    GEN_INT (trailing_zeroes));
5470                   break;
5471                 }
5472             }
5473           /* Try constant load / right shift.  */
5474           val2 = (val >> 15) + 1;
5475           if (val2 == (val2 & -val2))
5476             {
5477               int shift = 49 - exact_log2 (val2);
5479               val2 = trunc_int_for_mode (val << shift, DImode);
5480               if (CONST_OK_FOR_I16 (val2))
5481                 {
5482                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5483                                                    GEN_INT (shift));
5484                   break;
5485                 }
5486             }
5487           /* Try mperm.w .  */
5488           val2 = val & 0xffff;
5489           if ((val >> 16 & 0xffff) == val2
5490               && (val >> 32 & 0xffff) == val2
5491               && (val >> 48 & 0xffff) == val2)
5492             {
5493               val2 = (HOST_WIDE_INT) val >> 48;
5494               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5495               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5496               break;
5497             }
5498           /* Try movi / mshflo.l  */
5499           val2 = (HOST_WIDE_INT) val >> 32;
5500           if (val2 == ((unsigned HOST_WIDE_INT)
5501                         trunc_int_for_mode (val, SImode)))
5502             {
5503               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5504                                              operands[0]);
5505               break;
5506             }
5507           /* Try movi / mshflo.l w/ r63.  */
5508           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5509           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5510             {
5511               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5512                                              const0_rtx);
5513               break;
5514             }
5515         }
5516       val2 = high;
5517       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5518     }
5519   while (0);
5520   operands[2] = GEN_INT (val2);
5523 (define_split
5524   [(set (match_operand:DI 0 "ext_dest_operand" "")
5525         (match_operand:DI 1 "immediate_operand" ""))]
5526   "TARGET_SHMEDIA && reload_completed
5527    && GET_CODE (operands[1]) == CONST_DOUBLE"
5528   [(set (match_dup 0) (match_dup 2))
5529   (set (match_dup 0)
5530        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5531                (zero_extend:DI (truncate:HI (match_dup 1)))))]
5532   "
5534   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5535   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5536   unsigned HOST_WIDE_INT val = low;
5537   unsigned HOST_WIDE_INT sign;
5539   /* Sign-extend the 16 least-significant bits.  */
5540   val &= 0xffff;
5541   val ^= 0x8000;
5542   val -= 0x8000;
5543   operands[1] = GEN_INT (val);
5545   /* Arithmetic shift right the double-word by 16 bits.  */
5546   low >>= 16;
5547   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5548   high >>= 16;
5549   sign = 1;
5550   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5551   high ^= sign;
5552   high -= sign;
5554   /* This will only be true if high is a sign-extension of low, i.e.,
5555      it must be either 0 or (unsigned)-1, and be zero iff the
5556      most-significant bit of low is set.  */
5557   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5558     operands[2] = GEN_INT (low);
5559   else
5560     operands[2] = immed_double_const (low, high, DImode);
5563 (define_insn "shori_media"
5564   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5565         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5566                            (const_int 16))
5567                 (zero_extend:DI
5568                  (truncate:HI
5569                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
5570   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5571   "@
5572         shori   %u2, %0
5573         #"
5574   [(set_attr "type" "arith_media,*")])
5576 (define_insn "*shori_media_si"
5577   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5578         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5579                            (const_int 16))
5580                 (zero_extend:SI
5581                  (truncate:HI
5582                   (match_operand:SI 2 "immediate_operand" "I16C16")))))]
5583   "TARGET_SHMEDIA"
5584   "shori        %u2, %0")
5586 (define_expand "movdi"
5587   [(set (match_operand:DI 0 "general_movdst_operand" "")
5588         (match_operand:DI 1 "general_movsrc_operand" ""))]
5589   ""
5590   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5592 (define_insn "movdf_media"
5593   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5594         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5595   "TARGET_SHMEDIA_FPU
5596    && (register_operand (operands[0], DFmode)
5597        || sh_register_operand (operands[1], DFmode))"
5598   "@
5599         fmov.d  %1, %0
5600         fmov.qd %N1, %0
5601         fmov.dq %1, %0
5602         add     %1, r63, %0
5603         #
5604         fld%M1.d        %m1, %0
5605         fst%M0.d        %m0, %1
5606         ld%M1.q %m1, %0
5607         st%M0.q %m0, %N1"
5608   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5610 (define_insn "movdf_media_nofpu"
5611   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5612         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5613   "TARGET_SHMEDIA
5614    && (register_operand (operands[0], DFmode)
5615        || sh_register_operand (operands[1], DFmode))"
5616   "@
5617         add     %1, r63, %0
5618         #
5619         ld%M1.q %m1, %0
5620         st%M0.q %m0, %N1"
5621   [(set_attr "type" "arith_media,*,load_media,store_media")])
5623 (define_split
5624   [(set (match_operand:DF 0 "arith_reg_dest" "")
5625         (match_operand:DF 1 "immediate_operand" ""))]
5626   "TARGET_SHMEDIA && reload_completed"
5627   [(set (match_dup 3) (match_dup 2))]
5628   "
5630   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5631   long values[2];
5632   REAL_VALUE_TYPE value;
5634   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5635   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5637   if (HOST_BITS_PER_WIDE_INT >= 64)
5638     operands[2] = immed_double_const ((unsigned long) values[endian]
5639                                       | ((HOST_WIDE_INT) values[1 - endian]
5640                                          << 32), 0, DImode);
5641   else
5642     {
5643       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5644       operands[2] = immed_double_const (values[endian], values[1 - endian],
5645                                         DImode);
5646     }
5648   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5651 ;; ??? This should be a define expand.
5653 (define_insn "movdf_k"
5654   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5655         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5656   "TARGET_SH1
5657    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5658        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5659        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5660        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5661    && (arith_reg_operand (operands[0], DFmode)
5662        || arith_reg_operand (operands[1], DFmode))"
5663   "* return output_movedouble (insn, operands, DFmode);"
5664   [(set_attr "length" "4")
5665    (set_attr "type" "move,pcload,load,store")])
5667 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5668 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5669 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5670 ;; the d/m/c/X alternative, which is split later into single-precision
5671 ;; instructions.  And when not optimizing, no splits are done before fixing
5672 ;; up pcloads, so we need usable length information for that.
5673 (define_insn "movdf_i4"
5674   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5675         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5676    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5677    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5678   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5679    && (arith_reg_operand (operands[0], DFmode)
5680        || arith_reg_operand (operands[1], DFmode))"
5681   "@
5682         fmov    %1,%0
5683         #
5684         #
5685         fmov.d  %1,%0
5686         fmov.d  %1,%0
5687         #
5688         #
5689         #
5690         #
5691         #"
5692   [(set_attr_alternative "length"
5693      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5694       (const_int 4)
5695       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5696       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5697       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5698       (const_int 4)
5699       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5700       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5701       ;; increment or decrement r15 explicitly.
5702       (if_then_else
5703        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5704        (const_int 10) (const_int 8))
5705       (if_then_else
5706        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5707        (const_int 10) (const_int 8))])
5708    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5709    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5710    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5711                                            (const_string "double")
5712                                            (const_string "none")))])
5714 ;; Moving DFmode between fp/general registers through memory
5715 ;; (the top of the stack) is faster than moving through fpul even for
5716 ;; little endian.  Because the type of an instruction is important for its
5717 ;; scheduling,  it is beneficial to split these operations, rather than
5718 ;; emitting them in one single chunk, even if this will expose a stack
5719 ;; use that will prevent scheduling of other stack accesses beyond this
5720 ;; instruction.
5721 (define_split
5722   [(set (match_operand:DF 0 "register_operand" "")
5723         (match_operand:DF 1 "register_operand" ""))
5724    (use (match_operand:PSI 2 "fpscr_operand" ""))
5725    (clobber (match_scratch:SI 3 "=X"))]
5726   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5727    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5728   [(const_int 0)]
5729   "
5731   rtx insn, tos;
5733   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5734     {
5735       emit_move_insn (stack_pointer_rtx,
5736                       plus_constant (stack_pointer_rtx, -8));
5737       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
5738     }
5739   else
5740     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5741   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5742   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5743     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5744   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5745     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
5746   else
5747     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5748   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5749   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5750     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5751   else
5752     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5753   DONE;
5756 ;; local-alloc sometimes allocates scratch registers even when not required,
5757 ;; so we must be prepared to handle these.
5759 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5760 (define_split
5761   [(set (match_operand:DF 0 "general_movdst_operand" "")
5762         (match_operand:DF 1 "general_movsrc_operand"  ""))
5763    (use (match_operand:PSI 2 "fpscr_operand" ""))
5764    (clobber (match_scratch:SI 3 ""))]
5765   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5766    && reload_completed
5767    && true_regnum (operands[0]) < 16
5768    && true_regnum (operands[1]) < 16"
5769   [(set (match_dup 0) (match_dup 1))]
5770   "
5772   /* If this was a reg <-> mem operation with base + index reg addressing,
5773      we have to handle this in a special way.  */
5774   rtx mem = operands[0];
5775   int store_p = 1;
5776   if (! memory_operand (mem, DFmode))
5777     {
5778       mem = operands[1];
5779       store_p = 0;
5780     }
5781   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5782     mem = SUBREG_REG (mem);
5783   if (GET_CODE (mem) == MEM)
5784     {
5785       rtx addr = XEXP (mem, 0);
5786       if (GET_CODE (addr) == PLUS
5787           && GET_CODE (XEXP (addr, 0)) == REG
5788           && GET_CODE (XEXP (addr, 1)) == REG)
5789         {
5790           int offset;
5791           rtx reg0 = gen_rtx_REG (Pmode, 0);
5792           rtx regop = operands[store_p], word0 ,word1;
5794           if (GET_CODE (regop) == SUBREG)
5795             alter_subreg (&regop);
5796           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5797             offset = 2;
5798           else
5799             offset = 4;
5800           mem = copy_rtx (mem);
5801           PUT_MODE (mem, SImode);
5802           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5803           alter_subreg (&word0);
5804           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5805           alter_subreg (&word1);
5806           if (store_p || ! refers_to_regno_p (REGNO (word0),
5807                                               REGNO (word0) + 1, addr, 0))
5808             {
5809               emit_insn (store_p
5810                          ? gen_movsi_ie (mem, word0)
5811                          : gen_movsi_ie (word0, mem));
5812               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5813               mem = copy_rtx (mem);
5814               emit_insn (store_p
5815                          ? gen_movsi_ie (mem, word1)
5816                          : gen_movsi_ie (word1, mem));
5817               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5818             }
5819           else
5820             {
5821               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5822               emit_insn (gen_movsi_ie (word1, mem));
5823               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5824               mem = copy_rtx (mem);
5825               emit_insn (gen_movsi_ie (word0, mem));
5826             }
5827           DONE;
5828         }
5829     }
5832 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5833 (define_split
5834   [(set (match_operand:DF 0 "register_operand" "")
5835         (match_operand:DF 1 "memory_operand"  ""))
5836    (use (match_operand:PSI 2 "fpscr_operand" ""))
5837    (clobber (reg:SI R0_REG))]
5838   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5839   [(parallel [(set (match_dup 0) (match_dup 1))
5840               (use (match_dup 2))
5841               (clobber (scratch:SI))])]
5842   "")
5844 (define_expand "reload_indf"
5845   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
5846                    (match_operand:DF 1 "immediate_operand" "FQ"))
5847               (use (reg:PSI FPSCR_REG))
5848               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5849   "TARGET_SH1"
5850   "")
5852 (define_expand "reload_outdf"
5853   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5854                    (match_operand:DF 1 "register_operand" "af,r"))
5855               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5856   "TARGET_SH1"
5857   "")
5859 ;; Simplify no-op moves.
5860 (define_split
5861   [(set (match_operand:SF 0 "register_operand" "")
5862         (match_operand:SF 1 "register_operand" ""))
5863    (use (match_operand:PSI 2 "fpscr_operand" ""))
5864    (clobber (match_scratch:SI 3 ""))]
5865   "TARGET_SH2E && reload_completed
5866    && true_regnum (operands[0]) == true_regnum (operands[1])"
5867   [(set (match_dup 0) (match_dup 0))]
5868   "")
5870 ;; fmovd substitute post-reload splits
5871 (define_split
5872   [(set (match_operand:DF 0 "register_operand" "")
5873         (match_operand:DF 1 "register_operand" ""))
5874    (use (match_operand:PSI 2 "fpscr_operand" ""))
5875    (clobber (match_scratch:SI 3 ""))]
5876   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5877    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5878    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5879   [(const_int 0)]
5880   "
5882   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5883   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5884                            gen_rtx_REG (SFmode, src), operands[2]));
5885   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5886                            gen_rtx_REG (SFmode, src + 1), operands[2]));
5887   DONE;
5890 (define_split
5891   [(set (match_operand:DF 0 "register_operand" "")
5892         (mem:DF (match_operand:SI 1 "register_operand" "")))
5893    (use (match_operand:PSI 2 "fpscr_operand" ""))
5894    (clobber (match_scratch:SI 3 ""))]
5895   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5896    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5897    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5898   [(const_int 0)]
5899   "
5901   int regno = true_regnum (operands[0]);
5902   rtx insn;
5903   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5905   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5906                                            regno + !! TARGET_LITTLE_ENDIAN),
5907                                   mem2, operands[2]));
5908   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5909   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5910                                            regno + ! TARGET_LITTLE_ENDIAN),
5911                                   gen_rtx_MEM (SFmode, operands[1]),
5912                                   operands[2]));
5913   DONE;
5916 (define_split
5917   [(set (match_operand:DF 0 "register_operand" "")
5918         (match_operand:DF 1 "memory_operand" ""))
5919    (use (match_operand:PSI 2 "fpscr_operand" ""))
5920    (clobber (match_scratch:SI 3 ""))]
5921   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5922    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5923   [(const_int 0)]
5924   "
5926   int regno = true_regnum (operands[0]);
5927   rtx addr, insn, adjust = NULL_RTX;
5928   rtx mem2 = copy_rtx (operands[1]);
5929   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5930   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5932   PUT_MODE (mem2, SFmode);
5933   operands[1] = copy_rtx (mem2);
5934   addr = XEXP (mem2, 0);
5935   if (GET_CODE (addr) != POST_INC)
5936     {
5937       /* If we have to modify the stack pointer, the value that we have
5938          read with post-increment might be modified by an interrupt,
5939          so write it back.  */
5940       if (REGNO (addr) == STACK_POINTER_REGNUM)
5941         adjust = gen_push_e (reg0);
5942       else
5943         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5944       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5945     }
5946   addr = XEXP (addr, 0);
5947   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5948   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5949   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5950   if (adjust)
5951     emit_insn (adjust);
5952   else
5953     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5954   DONE;
5957 (define_split
5958   [(set (match_operand:DF 0 "memory_operand" "")
5959         (match_operand:DF 1 "register_operand" ""))
5960    (use (match_operand:PSI 2 "fpscr_operand" ""))
5961    (clobber (match_scratch:SI 3 ""))]
5962   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5963    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5964   [(const_int 0)]
5965   "
5967   int regno = true_regnum (operands[1]);
5968   rtx insn, addr, adjust = NULL_RTX;
5970   operands[0] = copy_rtx (operands[0]);
5971   PUT_MODE (operands[0], SFmode);
5972   insn = emit_insn (gen_movsf_ie (operands[0],
5973                                   gen_rtx_REG (SFmode,
5974                                            regno + ! TARGET_LITTLE_ENDIAN),
5975                                   operands[2]));
5976   operands[0] = copy_rtx (operands[0]);
5977   addr = XEXP (operands[0], 0);
5978   if (GET_CODE (addr) != PRE_DEC)
5979     {
5980       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5981       emit_insn_before (adjust, insn);
5982       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5983     }
5984   addr = XEXP (addr, 0);
5985   if (! adjust)
5986     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5987   insn = emit_insn (gen_movsf_ie (operands[0],
5988                                   gen_rtx_REG (SFmode,
5989                                            regno + !! TARGET_LITTLE_ENDIAN),
5990                                   operands[2]));
5991   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5992   DONE;
5995 ;; If the output is a register and the input is memory or a register, we have
5996 ;; to be careful and see which word needs to be loaded first.
5998 (define_split
5999   [(set (match_operand:DF 0 "general_movdst_operand" "")
6000         (match_operand:DF 1 "general_movsrc_operand" ""))]
6001   "TARGET_SH1 && reload_completed"
6002   [(set (match_dup 2) (match_dup 3))
6003    (set (match_dup 4) (match_dup 5))]
6004   "
6006   int regno;
6008   if ((GET_CODE (operands[0]) == MEM
6009        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6010       || (GET_CODE (operands[1]) == MEM
6011           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6012     FAIL;
6014   switch (GET_CODE (operands[0]))
6015     {
6016     case REG:
6017       regno = REGNO (operands[0]);
6018       break;
6019     case SUBREG:
6020       regno = subreg_regno (operands[0]);
6021       break;
6022     case MEM:
6023       regno = -1;
6024       break;
6025     default:
6026       gcc_unreachable ();
6027     }
6029   if (regno == -1
6030       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6031     {
6032       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6033       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6034       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6035       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6036     }
6037   else
6038     {
6039       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6040       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6041       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6042       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6043     }
6045   if (operands[2] == 0 || operands[3] == 0
6046       || operands[4] == 0 || operands[5] == 0)
6047     FAIL;
6050 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6051 ;; used only once, let combine add in the index again.
6053 (define_split
6054   [(set (match_operand:SI 0 "register_operand" "")
6055         (match_operand:SI 1 "" ""))
6056    (clobber (match_operand 2 "register_operand" ""))]
6057   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6058    && ALLOW_INDEXED_ADDRESS"
6059   [(use (reg:SI R0_REG))]
6060   "
6062   rtx addr, reg, const_int;
6064   if (GET_CODE (operands[1]) != MEM)
6065     FAIL;
6066   addr = XEXP (operands[1], 0);
6067   if (GET_CODE (addr) != PLUS)
6068     FAIL;
6069   reg = XEXP (addr, 0);
6070   const_int = XEXP (addr, 1);
6071   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6072          && GET_CODE (const_int) == CONST_INT))
6073     FAIL;
6074   emit_move_insn (operands[2], const_int);
6075   emit_move_insn (operands[0],
6076                   change_address (operands[1], VOIDmode,
6077                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6078   DONE;
6081 (define_split
6082   [(set (match_operand:SI 1 "" "")
6083         (match_operand:SI 0 "register_operand" ""))
6084    (clobber (match_operand 2 "register_operand" ""))]
6085   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6086    && ALLOW_INDEXED_ADDRESS"
6087   [(use (reg:SI R0_REG))]
6088   "
6090   rtx addr, reg, const_int;
6092   if (GET_CODE (operands[1]) != MEM)
6093     FAIL;
6094   addr = XEXP (operands[1], 0);
6095   if (GET_CODE (addr) != PLUS)
6096     FAIL;
6097   reg = XEXP (addr, 0);
6098   const_int = XEXP (addr, 1);
6099   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6100          && GET_CODE (const_int) == CONST_INT))
6101     FAIL;
6102   emit_move_insn (operands[2], const_int);
6103   emit_move_insn (change_address (operands[1], VOIDmode,
6104                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6105                   operands[0]);
6106   DONE;
6109 (define_expand "movdf"
6110   [(set (match_operand:DF 0 "general_movdst_operand" "")
6111         (match_operand:DF 1 "general_movsrc_operand" ""))]
6112   ""
6113   "
6115   if (prepare_move_operands (operands, DFmode)) DONE;
6116   if (TARGET_SHMEDIA)
6117     {
6118       if (TARGET_SHMEDIA_FPU)
6119         emit_insn (gen_movdf_media (operands[0], operands[1]));
6120       else
6121         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6122       DONE;
6123     }
6124   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6125     {
6126       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6127       DONE;
6128     }
6131 ;;This is incompatible with the way gcc uses subregs.
6132 ;;(define_insn "movv2sf_i"
6133 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6134 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6135 ;;  "TARGET_SHMEDIA_FPU
6136 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6137 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6138 ;;  "@
6139 ;;      #
6140 ;;      fld%M1.p        %m1, %0
6141 ;;      fst%M0.p        %m0, %1"
6142 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6144 (define_insn_and_split "movv2sf_i"
6145   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6146         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6147   "TARGET_SHMEDIA_FPU"
6148   "#"
6149   "TARGET_SHMEDIA_FPU && reload_completed"
6150   [(set (match_dup 0) (match_dup 1))]
6151   "
6153   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6154   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6157 (define_expand "movv2sf"
6158   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6159         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6160   "TARGET_SHMEDIA_FPU"
6161   "
6163   if (prepare_move_operands (operands, V2SFmode))
6164     DONE;
6167 (define_expand "addv2sf3"
6168   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6169    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6170    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6171   "TARGET_SHMEDIA_FPU"
6172   "
6174   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6175   DONE;
6178 (define_expand "subv2sf3"
6179   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6180    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6181    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6182   "TARGET_SHMEDIA_FPU"
6183   "
6185   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6186   DONE;
6189 (define_expand "mulv2sf3"
6190   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6191    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6192    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6193   "TARGET_SHMEDIA_FPU"
6194   "
6196   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6197   DONE;
6200 (define_expand "divv2sf3"
6201   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6202    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6203    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6204   "TARGET_SHMEDIA_FPU"
6205   "
6207   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6208   DONE;
6211 (define_insn_and_split "*movv4sf_i"
6212   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
6213         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
6214   "TARGET_SHMEDIA_FPU"
6215   "#"
6216   "&& reload_completed"
6217   [(const_int 0)]
6218   "
6220   int i;
6222   for (i = 0; i < 4/2; i++)
6223     {
6224       rtx x, y;
6226       if (GET_CODE (operands[0]) == MEM)
6227         x = gen_rtx_MEM (V2SFmode,
6228                          plus_constant (XEXP (operands[0], 0),
6229                                         i * GET_MODE_SIZE (V2SFmode)));
6230       else
6231         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6233       if (GET_CODE (operands[1]) == MEM)
6234         y = gen_rtx_MEM (V2SFmode,
6235                          plus_constant (XEXP (operands[1], 0),
6236                                         i * GET_MODE_SIZE (V2SFmode)));
6237       else
6238         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6240       emit_insn (gen_movv2sf_i (x, y));
6241     }
6243   DONE;
6245   [(set_attr "length" "8")])
6247 (define_expand "movv4sf"
6248   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6249         (match_operand:V4SF 1 "general_operand" ""))]
6250   "TARGET_SHMEDIA_FPU"
6251   "
6253   if (prepare_move_operands (operands, V4SFmode))
6254     DONE;
6257 (define_insn_and_split "*movv16sf_i"
6258   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6259         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6260   "TARGET_SHMEDIA_FPU"
6261   "#"
6262   "&& reload_completed"
6263   [(const_int 0)]
6264   "
6266   int i;
6268   for (i = 0; i < 16/2; i++)
6269     {
6270       rtx x,y;
6272       if (GET_CODE (operands[0]) == MEM)
6273         x = gen_rtx_MEM (V2SFmode,
6274                          plus_constant (XEXP (operands[0], 0),
6275                                         i * GET_MODE_SIZE (V2SFmode)));
6276       else
6277         {
6278           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6279           alter_subreg (&x);
6280         }
6282       if (GET_CODE (operands[1]) == MEM)
6283         y = gen_rtx_MEM (V2SFmode,
6284                          plus_constant (XEXP (operands[1], 0),
6285                                         i * GET_MODE_SIZE (V2SFmode)));
6286       else
6287         {
6288           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6289           alter_subreg (&y);
6290         }
6292       emit_insn (gen_movv2sf_i (x, y));
6293     }
6295   DONE;
6297   [(set_attr "length" "32")])
6299 (define_expand "movv16sf"
6300   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6301         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6302   "TARGET_SHMEDIA_FPU"
6303   "
6305   if (prepare_move_operands (operands, V16SFmode))
6306     DONE;
6309 (define_insn "movsf_media"
6310   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6311         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6312   "TARGET_SHMEDIA_FPU
6313    && (register_operand (operands[0], SFmode)
6314        || sh_register_operand (operands[1], SFmode))"
6315   "@
6316         fmov.s  %1, %0
6317         fmov.ls %N1, %0
6318         fmov.sl %1, %0
6319         add.l   %1, r63, %0
6320         #
6321         fld%M1.s        %m1, %0
6322         fst%M0.s        %m0, %1
6323         ld%M1.l %m1, %0
6324         st%M0.l %m0, %N1"
6325   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6326    (set (attr "highpart")
6327         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6328                (const_string "user")]
6329               (const_string "ignore")))])
6331 (define_insn "movsf_media_nofpu"
6332   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6333         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6334   "TARGET_SHMEDIA
6335    && (register_operand (operands[0], SFmode)
6336        || sh_register_operand (operands[1], SFmode))"
6337   "@
6338         add.l   %1, r63, %0
6339         #
6340         ld%M1.l %m1, %0
6341         st%M0.l %m0, %N1"
6342   [(set_attr "type" "arith_media,*,load_media,store_media")
6343    (set (attr "highpart")
6344         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6345                (const_string "user")]
6346               (const_string "ignore")))])
6348 (define_split
6349   [(set (match_operand:SF 0 "arith_reg_dest" "")
6350         (match_operand:SF 1 "immediate_operand" ""))]
6351   "TARGET_SHMEDIA && reload_completed
6352    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6353   [(set (match_dup 3) (match_dup 2))]
6354   "
6356   long values;
6357   REAL_VALUE_TYPE value;
6359   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6360   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6361   operands[2] = GEN_INT (values);
6363   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6366 (define_insn "movsf_i"
6367   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6368         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6369   "TARGET_SH1
6370    && (! TARGET_SH2E
6371        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6372        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6373        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6374    && (arith_reg_operand (operands[0], SFmode)
6375        || arith_reg_operand (operands[1], SFmode))"
6376   "@
6377         mov     %1,%0
6378         mov     #0,%0
6379         mov.l   %1,%0
6380         mov.l   %1,%0
6381         mov.l   %1,%0
6382         lds     %1,%0
6383         sts     %1,%0"
6384   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6386 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6387 ;; update_flow_info would not know where to put REG_EQUAL notes
6388 ;; when the destination changes mode.
6389 (define_insn "movsf_ie"
6390   [(set (match_operand:SF 0 "general_movdst_operand"
6391          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6392         (match_operand:SF 1 "general_movsrc_operand"
6393           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6394    (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"))
6395    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6397   "TARGET_SH2E
6398    && (arith_reg_operand (operands[0], SFmode)
6399        || arith_reg_operand (operands[1], SFmode)
6400        || arith_reg_operand (operands[3], SImode)
6401        || (fpul_operand (operands[0], SFmode)
6402            && memory_operand (operands[1], SFmode)
6403            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6404        || (fpul_operand (operands[1], SFmode)
6405            && memory_operand (operands[0], SFmode)
6406            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6407   "@
6408         fmov    %1,%0
6409         mov     %1,%0
6410         fldi0   %0
6411         fldi1   %0
6412         #
6413         fmov.s  %1,%0
6414         fmov.s  %1,%0
6415         mov.l   %1,%0
6416         mov.l   %1,%0
6417         mov.l   %1,%0
6418         fsts    fpul,%0
6419         flds    %1,fpul
6420         lds.l   %1,%0
6421         #
6422         sts     %1,%0
6423         lds     %1,%0
6424         sts.l   %1,%0
6425         lds.l   %1,%0
6426         ! move optimized away"
6427   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6428    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6429    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6430    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6431                                            (const_string "single")
6432                                            (const_string "none")))])
6434 (define_split
6435   [(set (match_operand:SF 0 "register_operand" "")
6436         (match_operand:SF 1 "register_operand" ""))
6437    (use (match_operand:PSI 2 "fpscr_operand" ""))
6438    (clobber (reg:SI FPUL_REG))]
6439   "TARGET_SH1"
6440   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6441               (use (match_dup 2))
6442               (clobber (scratch:SI))])
6443    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6444               (use (match_dup 2))
6445               (clobber (scratch:SI))])]
6446   "")
6448 (define_expand "movsf"
6449   [(set (match_operand:SF 0 "general_movdst_operand" "")
6450         (match_operand:SF 1 "general_movsrc_operand" ""))]
6451   ""
6452   "
6454   if (prepare_move_operands (operands, SFmode))
6455     DONE;
6456   if (TARGET_SHMEDIA)
6457     {
6458       if (TARGET_SHMEDIA_FPU)
6459         emit_insn (gen_movsf_media (operands[0], operands[1]));
6460       else
6461         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6462       DONE;
6463     }
6464   if (TARGET_SH2E)
6465     {
6466       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6467       DONE;
6468     }
6471 (define_insn "mov_nop"
6472   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6473   "TARGET_SH2E"
6474   ""
6475   [(set_attr "length" "0")
6476    (set_attr "type" "nil")])
6478 (define_expand "reload_insf"
6479   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6480                    (match_operand:SF 1 "immediate_operand" "FQ"))
6481               (use (reg:PSI FPSCR_REG))
6482               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6483   "TARGET_SH1"
6484   "")
6486 (define_expand "reload_insi"
6487   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6488                    (match_operand:SI 1 "immediate_operand" "i"))
6489               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6490   "TARGET_SH1"
6491   "")
6493 (define_expand "ptabs"
6494   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6495   "TARGET_SHMEDIA"
6496   "
6498   if (!TARGET_PT_FIXED)
6499     {
6500       rtx eq = operands[1];
6502       /* ??? For canonical RTL we really should remove any CONST from EQ
6503          before wrapping it in the AND, and finally wrap the EQ into a
6504          const if is constant.  However, for reload we must expose the
6505          input register or symbolic constant, and we can't have
6506          different insn structures outside of the operands for different
6507          alternatives of the same pattern.  */
6508       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6509                        GEN_INT (3));
6510       operands[1]
6511         = (gen_rtx_IF_THEN_ELSE
6512             (PDImode,
6513              eq,
6514              gen_rtx_MEM (PDImode, operands[1]),
6515              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6516                             PDImode, operands[1])));
6517     }
6520 ;; expanded by ptabs expander.
6521 (define_insn "*extendsipdi_media"
6522   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6523         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6524                                                           "r,Csy")
6525                                       (const_int 3))
6526                               (const_int 3))
6527                           (mem:PDI (match_dup 1))
6528                           (sign_extend:PDI (match_dup 1))))]
6529   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6530   "@
6531         ptabs   %1, %0
6532         pt      %1, %0"
6533   [(set_attr "type"   "ptabs_media,pt_media")
6534    (set_attr "length" "4,*")])
6536 (define_insn "*truncdipdi_media"
6537   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6538         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6539                                                           "r,Csy")
6540                                       (const_int 3))
6541                               (const_int 3))
6542                           (mem:PDI (match_dup 1))
6543                           (truncate:PDI (match_dup 1))))]
6544   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6545   "@
6546         ptabs   %1, %0
6547         pt      %1, %0"
6548   [(set_attr "type"   "ptabs_media,pt_media")
6549    (set_attr "length" "4,*")])
6551 (define_insn "*movsi_y"
6552   [(set (match_operand:SI 0 "register_operand" "=y,y")
6553         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6554    (clobber (match_scratch:SI 2 "=&z,r"))]
6555   "TARGET_SH2E
6556    && (reload_in_progress || reload_completed)"
6557   "#"
6558   [(set_attr "length" "4")
6559    (set_attr "type" "pcload,move")])
6561 (define_split
6562   [(set (match_operand:SI 0 "register_operand" "")
6563         (match_operand:SI 1 "immediate_operand" ""))
6564    (clobber (match_operand:SI 2 "register_operand" ""))]
6565   "TARGET_SH1"
6566   [(set (match_dup 2) (match_dup 1))
6567    (set (match_dup 0) (match_dup 2))]
6568   "")
6570 (define_split
6571   [(set (match_operand:SI 0 "register_operand" "")
6572         (match_operand:SI 1 "memory_operand" ""))
6573    (clobber (reg:SI R0_REG))]
6574   "TARGET_SH1"
6575   [(set (match_dup 0) (match_dup 1))]
6576   "")
6578 ;; ------------------------------------------------------------------------
6579 ;; Define the real conditional branch instructions.
6580 ;; ------------------------------------------------------------------------
6582 (define_insn "branch_true"
6583   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6584                            (label_ref (match_operand 0 "" ""))
6585                            (pc)))]
6586   "TARGET_SH1"
6587   "* return output_branch (1, insn, operands);"
6588   [(set_attr "type" "cbranch")])
6590 (define_insn "branch_false"
6591   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6592                            (label_ref (match_operand 0 "" ""))
6593                            (pc)))]
6594   "TARGET_SH1"
6595   "* return output_branch (0, insn, operands);"
6596   [(set_attr "type" "cbranch")])
6598 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6599 ;; which destination is too far away.
6600 ;; The const_int_operand is distinct for each branch target; it avoids
6601 ;; unwanted matches with redundant_insn.
6602 (define_insn "block_branch_redirect"
6603   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6604   "TARGET_SH1"
6605   ""
6606   [(set_attr "length" "0")])
6608 ;; This one has the additional purpose to record a possible scratch register
6609 ;; for the following branch.
6610 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6611 ;; because the insn then might be deemed dead and deleted.  And we can't
6612 ;; make the use in the jump insn explicit because that would disable
6613 ;; delay slot scheduling from the target.
6614 (define_insn "indirect_jump_scratch"
6615   [(set (match_operand:SI 0 "register_operand" "=r")
6616         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6617    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6618   "TARGET_SH1"
6619   ""
6620   [(set_attr "length" "0")])
6622 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6623 ;; being pulled into the delay slot of a condbranch that has been made to
6624 ;; jump around the unconditional jump because it was out of range.
6625 (define_insn "stuff_delay_slot"
6626   [(set (pc)
6627         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6628    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6629   "TARGET_SH1"
6630   ""
6631   [(set_attr "length" "0")
6632    (set_attr "cond_delay_slot" "yes")])
6634 ;; Conditional branch insns
6636 (define_expand "beq_media"
6637   [(set (pc)
6638         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6639                           (match_operand:DI 2 "arith_operand" "r,I06"))
6640                       (match_operand 0 "" "")
6641                       (pc)))]
6642   "TARGET_SHMEDIA"
6643   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6645 (define_insn "*beq_media_i"
6646   [(set (pc)
6647         (if_then_else (match_operator 3 "equality_comparison_operator"
6648                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6649                          (match_operand:DI 2 "arith_operand" "r,I06")])
6650                       (match_operand 0 "target_operand" "b,b")
6651                       (pc)))]
6652   "TARGET_SHMEDIA"
6653   "@
6654         b%o3%'  %1, %2, %0%>
6655         b%o3i%' %1, %2, %0%>"
6656   [(set_attr "type" "cbranch_media")])
6658 (define_insn "*beq_media_i32"
6659   [(set (pc)
6660         (if_then_else (match_operator 3 "equality_comparison_operator"
6661                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6662                          (match_operand:SI 2 "arith_operand" "r,I06")])
6663                       (match_operand 0 "target_operand" "b,b")
6664                       (pc)))]
6665   "TARGET_SHMEDIA"
6666   "@
6667         b%o3%'  %1, %2, %0%>
6668         b%o3i%' %1, %2, %0%>"
6669   [(set_attr "type" "cbranch_media")])
6671 (define_expand "bne_media"
6672   [(set (pc)
6673         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6674                           (match_operand:DI 2 "arith_operand" "r,I06"))
6675                       (match_operand 0 "" "")
6676                       (pc)))]
6677   "TARGET_SHMEDIA"
6678   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6680 (define_expand "bgt_media"
6681   [(set (pc)
6682         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6683                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6684                       (match_operand 0 "" "")
6685                       (pc)))]
6686   "TARGET_SHMEDIA"
6687   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6689 (define_expand "bge_media"
6690   [(set (pc)
6691         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6692                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6693                       (match_operand 0 "" "")
6694                       (pc)))]
6695   "TARGET_SHMEDIA"
6696   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6698 (define_expand "bgtu_media"
6699   [(set (pc)
6700         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6701                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6702                       (match_operand 0 "" "")
6703                       (pc)))]
6704   "TARGET_SHMEDIA"
6705   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6707 (define_expand "bgeu_media"
6708   [(set (pc)
6709         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6710                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6711                       (match_operand 0 "" "")
6712                       (pc)))]
6713   "TARGET_SHMEDIA"
6714   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6716 (define_insn "*bgt_media_i"
6717   [(set (pc)
6718         (if_then_else (match_operator 3 "greater_comparison_operator"
6719                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6720                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6721                       (match_operand 0 "target_operand" "b")
6722                       (pc)))]
6723   "TARGET_SHMEDIA"
6724   "b%o3%'       %N1, %N2, %0%>"
6725   [(set_attr "type" "cbranch_media")])
6727 (define_insn "*bgt_media_i32"
6728   [(set (pc)
6729         (if_then_else (match_operator 3 "greater_comparison_operator"
6730                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6731                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6732                       (match_operand 0 "target_operand" "b")
6733                       (pc)))]
6734   "TARGET_SHMEDIA"
6735   "b%o3%'       %N1, %N2, %0%>"
6736   [(set_attr "type" "cbranch_media")])
6738 ;; These are only needed to make invert_jump() happy - otherwise, jump
6739 ;; optimization will be silently disabled.
6740 (define_insn "*blt_media_i"
6741   [(set (pc)
6742         (if_then_else (match_operator 3 "less_comparison_operator"
6743                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6744                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6745                       (match_operand 0 "target_operand" "b")
6746                       (pc)))]
6747   "TARGET_SHMEDIA"
6748   "b%o3%'       %N2, %N1, %0%>"
6749   [(set_attr "type" "cbranch_media")])
6751 (define_insn "*blt_media_i32"
6752   [(set (pc)
6753         (if_then_else (match_operator 3 "less_comparison_operator"
6754                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6755                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6756                       (match_operand 0 "target_operand" "b")
6757                       (pc)))]
6758   "TARGET_SHMEDIA"
6759   "b%o3%'       %N2, %N1, %0%>"
6760   [(set_attr "type" "cbranch_media")])
6762 (define_expand "beq"
6763   [(set (pc)
6764         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6765                       (label_ref (match_operand 0 "" ""))
6766                       (pc)))]
6767   ""
6768   "
6770   if (TARGET_SHMEDIA)
6771     {
6772       enum machine_mode mode = GET_MODE (sh_compare_op0);
6774       if (mode != DImode && mode != SImode)
6775         {
6776           rtx tmp = gen_reg_rtx (DImode);
6778           emit_insn (gen_seq (tmp));
6779           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6780           DONE;
6781         }
6783       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6784       if (CONSTANT_P (sh_compare_op1)
6785           && (GET_CODE (sh_compare_op1) != CONST_INT
6786               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6787         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6788       emit_jump_insn (gen_beq_media (operands[0],
6789                                      sh_compare_op0, sh_compare_op1));
6790       DONE;
6791     }
6793   from_compare (operands, EQ);
6796 (define_expand "bne"
6797   [(set (pc)
6798         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6799                       (label_ref (match_operand 0 "" ""))
6800                       (pc)))]
6801   ""
6802   "
6804   if (TARGET_SHMEDIA)
6805     {
6806       enum machine_mode mode = GET_MODE (sh_compare_op0);
6808       if (mode != DImode && mode != SImode)
6809         {
6810           rtx tmp = gen_reg_rtx (DImode);
6812           emit_insn (gen_seq (tmp));
6813           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6814           DONE;
6815         }
6817       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6818       if (CONSTANT_P (sh_compare_op1)
6819           && (GET_CODE (sh_compare_op1) != CONST_INT
6820               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6821         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6822       emit_jump_insn (gen_bne_media (operands[0],
6823                                      sh_compare_op0, sh_compare_op1));
6824       DONE;
6825     }
6827   from_compare (operands, EQ);
6830 (define_expand "bgt"
6831   [(set (pc)
6832         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6833                       (label_ref (match_operand 0 "" ""))
6834                       (pc)))]
6835   ""
6836   "
6838   if (TARGET_SHMEDIA)
6839     {
6840       enum machine_mode mode = GET_MODE (sh_compare_op0);
6842       if (mode != DImode && mode != SImode)
6843         {
6844           rtx tmp = gen_reg_rtx (DImode);
6846           emit_insn (gen_sgt (tmp));
6847           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6848           DONE;
6849         }
6851       if (sh_compare_op0 != const0_rtx)
6852         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6853       if (sh_compare_op1 != const0_rtx)
6854         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6855       emit_jump_insn (gen_bgt_media (operands[0],
6856                                      sh_compare_op0, sh_compare_op1));
6857       DONE;
6858     }
6860   from_compare (operands, GT);
6863 (define_expand "blt"
6864   [(set (pc)
6865         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6866                       (label_ref (match_operand 0 "" ""))
6867                       (pc)))]
6868   ""
6869   "
6871   if (TARGET_SHMEDIA)
6872     {
6873       enum machine_mode mode = GET_MODE (sh_compare_op0);
6875       if (mode != DImode && mode != SImode)
6876         {
6877           rtx tmp = gen_reg_rtx (DImode);
6879           emit_insn (gen_slt (tmp));
6880           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6881           DONE;
6882         }
6884       if (sh_compare_op0 != const0_rtx)
6885         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6886       if (sh_compare_op1 != const0_rtx)
6887         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6888       emit_jump_insn (gen_bgt_media (operands[0],
6889                                      sh_compare_op1, sh_compare_op0));
6890       DONE;
6891     }
6893   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6894     {
6895       rtx tmp = sh_compare_op0;
6896       sh_compare_op0 = sh_compare_op1;
6897       sh_compare_op1 = tmp;
6898       emit_insn (gen_bgt (operands[0]));
6899       DONE;
6900     }
6901   from_compare (operands, GE);
6904 (define_expand "ble"
6905   [(set (pc)
6906         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6907                       (label_ref (match_operand 0 "" ""))
6908                       (pc)))]
6909   ""
6910   "
6912   if (TARGET_SHMEDIA)
6913     {
6914       enum machine_mode mode = GET_MODE (sh_compare_op0);
6916       if (mode != DImode && mode != SImode)
6917         {
6918           rtx tmp = gen_reg_rtx (DImode);
6920           emit_insn (gen_sle (tmp));
6921           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6922           DONE;
6923         }
6925       if (sh_compare_op0 != const0_rtx)
6926         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6927       if (sh_compare_op1 != const0_rtx)
6928         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6929       emit_jump_insn (gen_bge_media (operands[0],
6930                                      sh_compare_op1, sh_compare_op0));
6931       DONE;
6932     }
6934   if (TARGET_SH2E
6935       && TARGET_IEEE
6936       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6937     {
6938       rtx tmp = sh_compare_op0;
6939       sh_compare_op0 = sh_compare_op1;
6940       sh_compare_op1 = tmp;
6941       emit_insn (gen_bge (operands[0]));
6942       DONE;
6943     }
6944   from_compare (operands, GT);
6947 (define_expand "bge"
6948   [(set (pc)
6949         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6950                       (label_ref (match_operand 0 "" ""))
6951                       (pc)))]
6952   ""
6953   "
6955   if (TARGET_SHMEDIA)
6956     {
6957       enum machine_mode mode = GET_MODE (sh_compare_op0);
6959       if (mode != DImode && mode != SImode)
6960         {
6961           rtx tmp = gen_reg_rtx (DImode);
6963           emit_insn (gen_sge (tmp));
6964           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6965           DONE;
6966         }
6968       if (sh_compare_op0 != const0_rtx)
6969         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6970       if (sh_compare_op1 != const0_rtx)
6971         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6972       emit_jump_insn (gen_bge_media (operands[0],
6973                                      sh_compare_op0, sh_compare_op1));
6974       DONE;
6975     }
6977   if (TARGET_SH2E
6978       && ! TARGET_IEEE
6979       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6980     {
6981       rtx tmp = sh_compare_op0;
6982       sh_compare_op0 = sh_compare_op1;
6983       sh_compare_op1 = tmp;
6984       emit_insn (gen_ble (operands[0]));
6985       DONE;
6986     }
6987   from_compare (operands, GE);
6990 (define_expand "bgtu"
6991   [(set (pc)
6992         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6993                       (label_ref (match_operand 0 "" ""))
6994                       (pc)))]
6995   ""
6996   "
6998   if (TARGET_SHMEDIA)
6999     {
7000       enum machine_mode mode = GET_MODE (sh_compare_op0);
7002       if (sh_compare_op0 != const0_rtx)
7003         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7004       if (sh_compare_op1 != const0_rtx)
7005         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7006       emit_jump_insn (gen_bgtu_media (operands[0],
7007                                       sh_compare_op0, sh_compare_op1));
7008       DONE;
7009     }
7011   from_compare (operands, GTU);
7014 (define_expand "bltu"
7015   [(set (pc)
7016         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7017                       (label_ref (match_operand 0 "" ""))
7018                       (pc)))]
7019   ""
7020   "
7022   if (TARGET_SHMEDIA)
7023     {
7024       enum machine_mode mode = GET_MODE (sh_compare_op0);
7026       if (sh_compare_op0 != const0_rtx)
7027         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7028       if (sh_compare_op1 != const0_rtx)
7029         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7030       emit_jump_insn (gen_bgtu_media (operands[0],
7031                                       sh_compare_op1, sh_compare_op0));
7032       DONE;
7033     }
7035   from_compare (operands, GEU);
7038 (define_expand "bgeu"
7039   [(set (pc)
7040         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7041                       (label_ref (match_operand 0 "" ""))
7042                       (pc)))]
7043   ""
7044   "
7046   if (TARGET_SHMEDIA)
7047     {
7048       enum machine_mode mode = GET_MODE (sh_compare_op0);
7050       if (sh_compare_op0 != const0_rtx)
7051         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7052       if (sh_compare_op1 != const0_rtx)
7053         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7054       emit_jump_insn (gen_bgeu_media (operands[0],
7055                                       sh_compare_op0, sh_compare_op1));
7056       DONE;
7057     }
7059   from_compare (operands, GEU);
7062 (define_expand "bleu"
7063   [(set (pc)
7064         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7065                       (label_ref (match_operand 0 "" ""))
7066                       (pc)))]
7067   ""
7068   "
7070   if (TARGET_SHMEDIA)
7071     {
7072       enum machine_mode mode = GET_MODE (sh_compare_op0);
7074       if (sh_compare_op0 != const0_rtx)
7075         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7076       if (sh_compare_op1 != const0_rtx)
7077         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7078       emit_jump_insn (gen_bgeu_media (operands[0],
7079                                       sh_compare_op1, sh_compare_op0));
7080       DONE;
7081     }
7083   from_compare (operands, GTU);
7086 (define_expand "bunordered"
7087   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7088    (set (pc)
7089         (if_then_else (ne (match_dup 1) (const_int 0))
7090                       (match_operand 0 "" "")
7091                       (pc)))]
7092   "TARGET_SHMEDIA"
7093   "
7095   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7096   operands[1] = gen_reg_rtx (DImode);
7097   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7098   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7101 ;; combiner splitter for test-and-branch on single bit in register.  This
7102 ;; is endian dependent because the non-paradoxical subreg looks different
7103 ;; on big endian.
7104 (define_split
7105   [(set (pc)
7106         (if_then_else
7107           (match_operator 3 "equality_comparison_operator"
7108             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7109                                                       "extend_reg_operand" "")
7110                                                     0)
7111                                          (const_int 1)
7112                                          (match_operand 2
7113                                           "const_int_operand" "")) 0)
7114              (const_int 0)])
7115           (match_operand 0 "target_operand" "")
7116           (pc)))
7117    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7118   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7119   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7120    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7122   "
7124   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7125   operands[6] = (GET_CODE (operands[3]) == EQ
7126                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7127                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7130 ;; ------------------------------------------------------------------------
7131 ;; Jump and linkage insns
7132 ;; ------------------------------------------------------------------------
7134 (define_insn "jump_compact"
7135   [(set (pc)
7136         (label_ref (match_operand 0 "" "")))]
7137   "TARGET_SH1"
7138   "*
7140   /* The length is 16 if the delay slot is unfilled.  */
7141   if (get_attr_length(insn) > 4)
7142     return output_far_jump(insn, operands[0]);
7143   else
7144     return   \"bra      %l0%#\";
7146   [(set_attr "type" "jump")
7147    (set_attr "needs_delay_slot" "yes")])
7149 ;; ??? It would be much saner to explicitly use the scratch register
7150 ;; in the jump insn, and have indirect_jump_scratch only set it,
7151 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7152 ;; from the target then, as it uses simplejump_p.
7153 ;;(define_insn "jump_compact_far"
7154 ;;  [(set (pc)
7155 ;;      (label_ref (match_operand 0 "" "")))
7156 ;;   (use (match_operand 1 "register_operand" "r")]
7157 ;;  "TARGET_SH1"
7158 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7159 ;;  [(set_attr "type" "jump")
7160 ;;   (set_attr "needs_delay_slot" "yes")])
7162 (define_insn "jump_media"
7163   [(set (pc)
7164         (match_operand 0 "target_operand" "b"))]
7165   "TARGET_SHMEDIA"
7166   "blink        %0, r63%>"
7167   [(set_attr "type" "jump_media")])
7169 (define_expand "jump"
7170   [(set (pc)
7171         (label_ref (match_operand 0 "" "")))]
7172   ""
7173   "
7175   if (TARGET_SH1)
7176     emit_jump_insn (gen_jump_compact (operands[0]));
7177   else if (TARGET_SHMEDIA)
7178     {
7179       if (reload_in_progress || reload_completed)
7180         FAIL;
7181       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7182                                                          operands[0])));
7183     }
7184   DONE;
7187 (define_insn "force_mode_for_call"
7188   [(use (reg:PSI FPSCR_REG))]
7189   "TARGET_SHCOMPACT"
7190   ""
7191   [(set_attr "length" "0")
7192    (set (attr "fp_mode")
7193         (if_then_else (eq_attr "fpu_single" "yes")
7194                       (const_string "single") (const_string "double")))])
7196 (define_insn "calli"
7197   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7198          (match_operand 1 "" ""))
7199    (use (reg:PSI FPSCR_REG))
7200    (clobber (reg:SI PR_REG))]
7201   "TARGET_SH1"
7202   "jsr  @%0%#"
7203   [(set_attr "type" "call")
7204    (set (attr "fp_mode")
7205         (if_then_else (eq_attr "fpu_single" "yes")
7206                       (const_string "single") (const_string "double")))
7207    (set_attr "needs_delay_slot" "yes")
7208    (set_attr "fp_set" "unknown")])
7210 ;; This is a pc-rel call, using bsrf, for use with PIC.
7212 (define_insn "calli_pcrel"
7213   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7214          (match_operand 1 "" ""))
7215    (use (reg:PSI FPSCR_REG))
7216    (use (reg:SI PIC_REG))
7217    (use (match_operand 2 "" ""))
7218    (clobber (reg:SI PR_REG))]
7219   "TARGET_SH2"
7220   "bsrf %0\\n%O2:%#"
7221   [(set_attr "type" "call")
7222    (set (attr "fp_mode")
7223         (if_then_else (eq_attr "fpu_single" "yes")
7224                       (const_string "single") (const_string "double")))
7225    (set_attr "needs_delay_slot" "yes")
7226    (set_attr "fp_set" "unknown")])
7228 (define_insn_and_split "call_pcrel"
7229   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7230          (match_operand 1 "" ""))
7231    (use (reg:PSI FPSCR_REG))
7232    (use (reg:SI PIC_REG))
7233    (clobber (reg:SI PR_REG))
7234    (clobber (match_scratch:SI 2 "=r"))]
7235   "TARGET_SH2"
7236   "#"
7237   "reload_completed"
7238   [(const_int 0)]
7239   "
7241   rtx lab = PATTERN (gen_call_site ());
7243   if (SYMBOL_REF_LOCAL_P (operands[0]))
7244     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7245   else
7246     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7247   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7248   DONE;
7250   [(set_attr "type" "call")
7251    (set (attr "fp_mode")
7252         (if_then_else (eq_attr "fpu_single" "yes")
7253                       (const_string "single") (const_string "double")))
7254    (set_attr "needs_delay_slot" "yes")
7255    (set_attr "fp_set" "unknown")])
7257 (define_insn "call_compact"
7258   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7259          (match_operand 1 "" ""))
7260    (match_operand 2 "immediate_operand" "n")
7261    (use (reg:SI R0_REG))
7262    (use (reg:SI R1_REG))
7263    (use (reg:PSI FPSCR_REG))
7264    (clobber (reg:SI PR_REG))]
7265   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7266   "jsr  @%0%#"
7267   [(set_attr "type" "call")
7268    (set (attr "fp_mode")
7269         (if_then_else (eq_attr "fpu_single" "yes")
7270                       (const_string "single") (const_string "double")))
7271    (set_attr "needs_delay_slot" "yes")])
7273 (define_insn "call_compact_rettramp"
7274   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7275          (match_operand 1 "" ""))
7276    (match_operand 2 "immediate_operand" "n")
7277    (use (reg:SI R0_REG))
7278    (use (reg:SI R1_REG))
7279    (use (reg:PSI FPSCR_REG))
7280    (clobber (reg:SI R10_REG))
7281    (clobber (reg:SI PR_REG))]
7282   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7283   "jsr  @%0%#"
7284   [(set_attr "type" "call")
7285    (set (attr "fp_mode")
7286         (if_then_else (eq_attr "fpu_single" "yes")
7287                       (const_string "single") (const_string "double")))
7288    (set_attr "needs_delay_slot" "yes")])
7290 (define_insn "call_media"
7291   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7292          (match_operand 1 "" ""))
7293    (clobber (reg:DI PR_MEDIA_REG))]
7294   "TARGET_SHMEDIA"
7295   "blink        %0, r18"
7296   [(set_attr "type" "jump_media")])
7298 (define_insn "call_valuei"
7299   [(set (match_operand 0 "" "=rf")
7300         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7301               (match_operand 2 "" "")))
7302    (use (reg:PSI FPSCR_REG))
7303    (clobber (reg:SI PR_REG))]
7304   "TARGET_SH1"
7305   "jsr  @%1%#"
7306   [(set_attr "type" "call")
7307    (set (attr "fp_mode")
7308         (if_then_else (eq_attr "fpu_single" "yes")
7309                       (const_string "single") (const_string "double")))
7310    (set_attr "needs_delay_slot" "yes")
7311    (set_attr "fp_set" "unknown")])
7313 (define_insn "call_valuei_pcrel"
7314   [(set (match_operand 0 "" "=rf")
7315         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7316               (match_operand 2 "" "")))
7317    (use (reg:PSI FPSCR_REG))
7318    (use (reg:SI PIC_REG))
7319    (use (match_operand 3 "" ""))
7320    (clobber (reg:SI PR_REG))]
7321   "TARGET_SH2"
7322   "bsrf %1\\n%O3:%#"
7323   [(set_attr "type" "call")
7324    (set (attr "fp_mode")
7325         (if_then_else (eq_attr "fpu_single" "yes")
7326                       (const_string "single") (const_string "double")))
7327    (set_attr "needs_delay_slot" "yes")
7328    (set_attr "fp_set" "unknown")])
7330 (define_insn_and_split "call_value_pcrel"
7331   [(set (match_operand 0 "" "=rf")
7332         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7333               (match_operand 2 "" "")))
7334    (use (reg:PSI FPSCR_REG))
7335    (use (reg:SI PIC_REG))
7336    (clobber (reg:SI PR_REG))
7337    (clobber (match_scratch:SI 3 "=r"))]
7338   "TARGET_SH2"
7339   "#"
7340   "reload_completed"
7341   [(const_int 0)]
7342   "
7344   rtx lab = PATTERN (gen_call_site ());
7346   if (SYMBOL_REF_LOCAL_P (operands[1]))
7347     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7348   else
7349     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7350   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7351                                          operands[2], lab));
7352   DONE;
7354   [(set_attr "type" "call")
7355    (set (attr "fp_mode")
7356         (if_then_else (eq_attr "fpu_single" "yes")
7357                       (const_string "single") (const_string "double")))
7358    (set_attr "needs_delay_slot" "yes")
7359    (set_attr "fp_set" "unknown")])
7361 (define_insn "call_value_compact"
7362   [(set (match_operand 0 "" "=rf")
7363         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7364               (match_operand 2 "" "")))
7365    (match_operand 3 "immediate_operand" "n")
7366    (use (reg:SI R0_REG))
7367    (use (reg:SI R1_REG))
7368    (use (reg:PSI FPSCR_REG))
7369    (clobber (reg:SI PR_REG))]
7370   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7371   "jsr  @%1%#"
7372   [(set_attr "type" "call")
7373    (set (attr "fp_mode")
7374         (if_then_else (eq_attr "fpu_single" "yes")
7375                       (const_string "single") (const_string "double")))
7376    (set_attr "needs_delay_slot" "yes")])
7378 (define_insn "call_value_compact_rettramp"
7379   [(set (match_operand 0 "" "=rf")
7380         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7381               (match_operand 2 "" "")))
7382    (match_operand 3 "immediate_operand" "n")
7383    (use (reg:SI R0_REG))
7384    (use (reg:SI R1_REG))
7385    (use (reg:PSI FPSCR_REG))
7386    (clobber (reg:SI R10_REG))
7387    (clobber (reg:SI PR_REG))]
7388   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7389   "jsr  @%1%#"
7390   [(set_attr "type" "call")
7391    (set (attr "fp_mode")
7392         (if_then_else (eq_attr "fpu_single" "yes")
7393                       (const_string "single") (const_string "double")))
7394    (set_attr "needs_delay_slot" "yes")])
7396 (define_insn "call_value_media"
7397   [(set (match_operand 0 "" "=rf")
7398         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7399               (match_operand 2 "" "")))
7400    (clobber (reg:DI PR_MEDIA_REG))]
7401   "TARGET_SHMEDIA"
7402   "blink        %1, r18"
7403   [(set_attr "type" "jump_media")])
7405 (define_expand "call"
7406   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7407                             (match_operand 1 "" ""))
7408               (match_operand 2 "" "")
7409               (use (reg:PSI FPSCR_REG))
7410               (clobber (reg:SI PR_REG))])]
7411   ""
7412   "
7414   if (TARGET_SHMEDIA)
7415     {
7416       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7417       emit_call_insn (gen_call_media (operands[0], operands[1]));
7418       DONE;
7419     }
7420   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7421     {
7422       rtx cookie_rtx = operands[2];
7423       long cookie = INTVAL (cookie_rtx);
7424       rtx func = XEXP (operands[0], 0);
7425       rtx r0, r1;
7427       if (flag_pic)
7428         {
7429           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7430             {
7431               rtx reg = gen_reg_rtx (Pmode);
7433               emit_insn (gen_symGOTPLT2reg (reg, func));
7434               func = reg;
7435             }
7436           else
7437             func = legitimize_pic_address (func, Pmode, 0);
7438         }
7440       r0 = gen_rtx_REG (SImode, R0_REG);
7441       r1 = gen_rtx_REG (SImode, R1_REG);
7443       /* Since such a call function may use all call-clobbered
7444          registers, we force a mode switch earlier, so that we don't
7445          run out of registers when adjusting fpscr for the call.  */
7446       emit_insn (gen_force_mode_for_call ());
7448       operands[0]
7449         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7450                            SFUNC_GOT);
7451       operands[0] = force_reg (SImode, operands[0]);
7453       emit_move_insn (r0, func);
7454       emit_move_insn (r1, cookie_rtx);
7456       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7457         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7458                                                    operands[2]));
7459       else
7460         emit_call_insn (gen_call_compact (operands[0], operands[1],
7461                                           operands[2]));
7463       DONE;
7464     }
7465   else if (TARGET_SHCOMPACT && flag_pic
7466            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7467            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7468     {
7469       rtx reg = gen_reg_rtx (Pmode);
7471       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7472       XEXP (operands[0], 0) = reg;
7473     }
7474   if (flag_pic && TARGET_SH2
7475       && GET_CODE (operands[0]) == MEM
7476       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7477     {
7478       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7479       DONE;
7480     }
7481   else
7482   {
7483     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7484     operands[1] = operands[2];
7485   }
7487   emit_call_insn (gen_calli (operands[0], operands[1]));
7488   DONE;
7491 (define_insn "call_pop_compact"
7492   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7493          (match_operand 1 "" ""))
7494    (match_operand 2 "immediate_operand" "n")
7495    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7496                                  (match_operand 3 "immediate_operand" "n")))
7497    (use (reg:SI R0_REG))
7498    (use (reg:SI R1_REG))
7499    (use (reg:PSI FPSCR_REG))
7500    (clobber (reg:SI PR_REG))]
7501   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7502   "jsr  @%0%#"
7503   [(set_attr "type" "call")
7504    (set (attr "fp_mode")
7505         (if_then_else (eq_attr "fpu_single" "yes")
7506                       (const_string "single") (const_string "double")))
7507    (set_attr "needs_delay_slot" "yes")])
7509 (define_insn "call_pop_compact_rettramp"
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 R10_REG))
7519    (clobber (reg:SI PR_REG))]
7520   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7521   "jsr  @%0%#"
7522   [(set_attr "type" "call")
7523    (set (attr "fp_mode")
7524         (if_then_else (eq_attr "fpu_single" "yes")
7525                       (const_string "single") (const_string "double")))
7526    (set_attr "needs_delay_slot" "yes")])
7528 (define_expand "call_pop"
7529   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7530                     (match_operand 1 "" ""))
7531              (match_operand 2 "" "")
7532              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7533                                            (match_operand 3 "" "")))])]
7534   "TARGET_SHCOMPACT"
7535   "
7537   rtx cookie_rtx;
7538   long cookie;
7539   rtx func;
7540   rtx r0, r1;
7542   gcc_assert (operands[2] && INTVAL (operands[2]));
7543   cookie_rtx = operands[2];
7544   cookie = INTVAL (cookie_rtx);
7545   func = XEXP (operands[0], 0);
7547   if (flag_pic)
7548     {
7549       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7550         {
7551           rtx reg = gen_reg_rtx (Pmode);
7552           emit_insn (gen_symGOTPLT2reg (reg, func));
7553           func = reg;
7554         }
7555       else
7556         func = legitimize_pic_address (func, Pmode, 0);
7557     }
7559   r0 = gen_rtx_REG (SImode, R0_REG);
7560   r1 = gen_rtx_REG (SImode, R1_REG);
7562   /* Since such a call function may use all call-clobbered
7563      registers, we force a mode switch earlier, so that we don't
7564      run out of registers when adjusting fpscr for the call.  */
7565   emit_insn (gen_force_mode_for_call ());
7567   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7568                                  SFUNC_GOT);
7569   operands[0] = force_reg (SImode, operands[0]);
7571   emit_move_insn (r0, func);
7572   emit_move_insn (r1, cookie_rtx);
7574   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7575     emit_call_insn (gen_call_pop_compact_rettramp
7576                      (operands[0], operands[1], operands[2], operands[3]));
7577   else
7578     emit_call_insn (gen_call_pop_compact
7579                      (operands[0], operands[1], operands[2], operands[3]));
7581   DONE;
7584 (define_expand "call_value"
7585   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7586                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7587                                  (match_operand 2 "" "")))
7588               (match_operand 3 "" "")
7589               (use (reg:PSI FPSCR_REG))
7590               (clobber (reg:SI PR_REG))])]
7591   ""
7592   "
7594   if (TARGET_SHMEDIA)
7595     {
7596       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7597       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7598                                             operands[2]));
7599       DONE;
7600     }
7601   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7602     {
7603       rtx cookie_rtx = operands[3];
7604       long cookie = INTVAL (cookie_rtx);
7605       rtx func = XEXP (operands[1], 0);
7606       rtx r0, r1;
7608       if (flag_pic)
7609         {
7610           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7611             {
7612               rtx reg = gen_reg_rtx (Pmode);
7614               emit_insn (gen_symGOTPLT2reg (reg, func));
7615               func = reg;
7616             }
7617           else
7618             func = legitimize_pic_address (func, Pmode, 0);
7619         }
7621       r0 = gen_rtx_REG (SImode, R0_REG);
7622       r1 = gen_rtx_REG (SImode, R1_REG);
7624       /* Since such a call function may use all call-clobbered
7625          registers, we force a mode switch earlier, so that we don't
7626          run out of registers when adjusting fpscr for the call.  */
7627       emit_insn (gen_force_mode_for_call ());
7629       operands[1]
7630         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7631                            SFUNC_GOT);
7632       operands[1] = force_reg (SImode, operands[1]);
7634       emit_move_insn (r0, func);
7635       emit_move_insn (r1, cookie_rtx);
7637       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7638         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7639                                                          operands[1],
7640                                                          operands[2],
7641                                                          operands[3]));
7642       else
7643         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7644                                                 operands[2], operands[3]));
7646       DONE;
7647     }
7648   else if (TARGET_SHCOMPACT && flag_pic
7649            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7650            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7651     {
7652       rtx reg = gen_reg_rtx (Pmode);
7654       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7655       XEXP (operands[1], 0) = reg;
7656     }
7657   if (flag_pic && TARGET_SH2
7658       && GET_CODE (operands[1]) == MEM
7659       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7660     {
7661       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7662                                             operands[2]));
7663       DONE;
7664     }
7665   else
7666     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7668   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7669   DONE;
7672 (define_insn "sibcalli"
7673   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7674          (match_operand 1 "" ""))
7675    (use (reg:PSI FPSCR_REG))
7676    (return)]
7677   "TARGET_SH1"
7678   "jmp  @%0%#"
7679   [(set_attr "needs_delay_slot" "yes")
7680    (set (attr "fp_mode")
7681         (if_then_else (eq_attr "fpu_single" "yes")
7682                       (const_string "single") (const_string "double")))
7683    (set_attr "type" "jump_ind")])
7685 (define_insn "sibcalli_pcrel"
7686   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7687          (match_operand 1 "" ""))
7688    (use (match_operand 2 "" ""))
7689    (use (reg:PSI FPSCR_REG))
7690    (return)]
7691   "TARGET_SH2"
7692   "braf %0\\n%O2:%#"
7693   [(set_attr "needs_delay_slot" "yes")
7694    (set (attr "fp_mode")
7695         (if_then_else (eq_attr "fpu_single" "yes")
7696                       (const_string "single") (const_string "double")))
7697    (set_attr "type" "jump_ind")])
7699 ;; This uses an unspec to describe that the symbol_ref is very close.
7700 (define_insn "sibcalli_thunk"
7701   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7702                              UNSPEC_THUNK))
7703          (match_operand 1 "" ""))
7704    (use (reg:PSI FPSCR_REG))
7705    (return)]
7706   "TARGET_SH1"
7707   "bra  %O0"
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")
7713    (set_attr "length" "2")])
7715 (define_insn_and_split "sibcall_pcrel"
7716   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7717          (match_operand 1 "" ""))
7718    (use (reg:PSI FPSCR_REG))
7719    (clobber (match_scratch:SI 2 "=k"))
7720    (return)]
7721   "TARGET_SH2"
7722   "#"
7723   "reload_completed"
7724   [(const_int 0)]
7725   "
7727   rtx lab = PATTERN (gen_call_site ());
7728   rtx call_insn;
7730   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7731   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7732                                                   lab));
7733   SIBLING_CALL_P (call_insn) = 1;
7734   DONE;
7736   [(set_attr "needs_delay_slot" "yes")
7737    (set (attr "fp_mode")
7738         (if_then_else (eq_attr "fpu_single" "yes")
7739                       (const_string "single") (const_string "double")))
7740    (set_attr "type" "jump_ind")])
7742 (define_insn "sibcall_compact"
7743   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7744          (match_operand 1 "" ""))
7745    (return)
7746    (use (match_operand:SI 2 "register_operand" "z,x"))
7747    (use (reg:SI R1_REG))
7748    (use (reg:PSI FPSCR_REG))
7749    ;; We want to make sure the `x' above will only match MACH_REG
7750    ;; because sibcall_epilogue may clobber MACL_REG.
7751    (clobber (reg:SI MACL_REG))]
7752   "TARGET_SHCOMPACT"
7753   "@
7754         jmp     @%0%#
7755         jmp     @%0\\n  sts     %2, r0"
7756   [(set_attr "needs_delay_slot" "yes,no")
7757    (set_attr "length" "2,4")
7758    (set (attr "fp_mode") (const_string "single"))
7759    (set_attr "type" "jump_ind")])
7761 (define_insn "sibcall_media"
7762   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7763          (match_operand 1 "" ""))
7764    (use (reg:SI PR_MEDIA_REG))
7765    (return)]
7766   "TARGET_SHMEDIA"
7767   "blink        %0, r63"
7768   [(set_attr "type" "jump_media")])
7770 (define_expand "sibcall"
7771   [(parallel
7772     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7773            (match_operand 1 "" ""))
7774      (match_operand 2 "" "")
7775      (use (reg:PSI FPSCR_REG))
7776      (return)])]
7777   ""
7778   "
7780   if (TARGET_SHMEDIA)
7781     {
7782       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7783       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7784       DONE;
7785     }
7786   else if (TARGET_SHCOMPACT && operands[2]
7787            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7788     {
7789       rtx cookie_rtx = operands[2];
7790       long cookie = INTVAL (cookie_rtx);
7791       rtx func = XEXP (operands[0], 0);
7792       rtx mach, r1;
7794       if (flag_pic)
7795         {
7796           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7797             {
7798               rtx reg = gen_reg_rtx (Pmode);
7800               emit_insn (gen_symGOT2reg (reg, func));
7801               func = reg;
7802             }
7803           else
7804             func = legitimize_pic_address (func, Pmode, 0);
7805         }
7807       /* FIXME: if we could tell whether all argument registers are
7808          already taken, we could decide whether to force the use of
7809          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7810          simple way to tell.  We could use the CALL_COOKIE, but we
7811          can't currently tell a register used for regular argument
7812          passing from one that is unused.  If we leave it up to reload
7813          to decide which register to use, it seems to always choose
7814          R0_REG, which leaves no available registers in SIBCALL_REGS
7815          to hold the address of the trampoline.  */
7816       mach = gen_rtx_REG (SImode, MACH_REG);
7817       r1 = gen_rtx_REG (SImode, R1_REG);
7819       /* Since such a call function may use all call-clobbered
7820          registers, we force a mode switch earlier, so that we don't
7821          run out of registers when adjusting fpscr for the call.  */
7822       emit_insn (gen_force_mode_for_call ());
7824       operands[0]
7825         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7826                            SFUNC_GOT);
7827       operands[0] = force_reg (SImode, operands[0]);
7829       /* We don't need a return trampoline, since the callee will
7830          return directly to the upper caller.  */
7831       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7832         {
7833           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7834           cookie_rtx = GEN_INT (cookie);
7835         }
7837       emit_move_insn (mach, func);
7838       emit_move_insn (r1, cookie_rtx);
7840       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7841       DONE;
7842     }
7843   else if (TARGET_SHCOMPACT && flag_pic
7844            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7845            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7846     {
7847       rtx reg = gen_reg_rtx (Pmode);
7849       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7850       XEXP (operands[0], 0) = reg;
7851     }
7852   if (flag_pic && TARGET_SH2
7853       && GET_CODE (operands[0]) == MEM
7854       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7855       /* The PLT needs the PIC register, but the epilogue would have
7856          to restore it, so we can only use PC-relative PIC calls for
7857          static functions.  */
7858       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7859     {
7860       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7861       DONE;
7862     }
7863   else
7864     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7866   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7867   DONE;
7870 (define_expand "sibcall_value"
7871   [(set (match_operand 0 "" "")
7872         (call (match_operand 1 "" "")
7873               (match_operand 2 "" "")))
7874    (match_operand 3 "" "")]
7875   ""
7876   "
7878   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7879   DONE;
7882 (define_insn "call_value_pop_compact"
7883   [(set (match_operand 0 "" "=rf")
7884         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7885               (match_operand 2 "" "")))
7886    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7887                                  (match_operand 4 "immediate_operand" "n")))
7888    (match_operand 3 "immediate_operand" "n")
7889    (use (reg:SI R0_REG))
7890    (use (reg:SI R1_REG))
7891    (use (reg:PSI FPSCR_REG))
7892    (clobber (reg:SI PR_REG))]
7893   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7894   "jsr  @%1%#"
7895   [(set_attr "type" "call")
7896    (set (attr "fp_mode")
7897         (if_then_else (eq_attr "fpu_single" "yes")
7898                       (const_string "single") (const_string "double")))
7899    (set_attr "needs_delay_slot" "yes")])
7901 (define_insn "call_value_pop_compact_rettramp"
7902   [(set (match_operand 0 "" "=rf")
7903         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7904               (match_operand 2 "" "")))
7905    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7906                                  (match_operand 4 "immediate_operand" "n")))
7907    (match_operand 3 "immediate_operand" "n")
7908    (use (reg:SI R0_REG))
7909    (use (reg:SI R1_REG))
7910    (use (reg:PSI FPSCR_REG))
7911    (clobber (reg:SI R10_REG))
7912    (clobber (reg:SI PR_REG))]
7913   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7914   "jsr  @%1%#"
7915   [(set_attr "type" "call")
7916    (set (attr "fp_mode")
7917         (if_then_else (eq_attr "fpu_single" "yes")
7918                       (const_string "single") (const_string "double")))
7919    (set_attr "needs_delay_slot" "yes")])
7921 (define_expand "call_value_pop"
7922   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7923                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7924                                  (match_operand 2 "" "")))
7925               (match_operand 3 "" "")
7926               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7927                                             (match_operand 4 "" "")))])]
7928   "TARGET_SHCOMPACT"
7929   "
7931   rtx cookie_rtx;
7932   long cookie;
7933   rtx func;
7934   rtx r0, r1;
7936   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7937   cookie_rtx = operands[3];
7938   cookie = INTVAL (cookie_rtx);
7939   func = XEXP (operands[1], 0);
7941   if (flag_pic)
7942     {
7943       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7944         {
7945           rtx reg = gen_reg_rtx (Pmode);
7947           emit_insn (gen_symGOTPLT2reg (reg, func));
7948           func = reg;
7949         }
7950       else
7951         func = legitimize_pic_address (func, Pmode, 0);
7952     }
7954   r0 = gen_rtx_REG (SImode, R0_REG);
7955   r1 = gen_rtx_REG (SImode, R1_REG);
7957   /* Since such a call function may use all call-clobbered
7958      registers, we force a mode switch earlier, so that we don't
7959      run out of registers when adjusting fpscr for the call.  */
7960   emit_insn (gen_force_mode_for_call ());
7962   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7963                                  SFUNC_GOT);
7964   operands[1] = force_reg (SImode, operands[1]);
7966   emit_move_insn (r0, func);
7967   emit_move_insn (r1, cookie_rtx);
7969   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7970     emit_call_insn (gen_call_value_pop_compact_rettramp
7971                         (operands[0], operands[1], operands[2],
7972                          operands[3], operands[4]));
7973   else
7974     emit_call_insn (gen_call_value_pop_compact
7975                         (operands[0], operands[1], operands[2],
7976                          operands[3], operands[4]));
7978   DONE;
7981 (define_expand "sibcall_epilogue"
7982   [(return)]
7983   ""
7984   "
7986   sh_expand_epilogue (1);
7987   if (TARGET_SHCOMPACT)
7988     {
7989       rtx insn, set;
7991       /* If epilogue clobbers r0, preserve it in macl.  */
7992       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7993         if ((set = single_set (insn))
7994             && GET_CODE (SET_DEST (set)) == REG
7995             && REGNO (SET_DEST (set)) == R0_REG)
7996           {
7997             rtx r0 = gen_rtx_REG (SImode, R0_REG);
7998             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
7999             rtx i;
8001             /* We can't tell at this point whether the sibcall is a
8002                sibcall_compact and, if it is, whether it uses r0 or
8003                mach as operand 2, so let the instructions that
8004                preserve r0 be optimized away if r0 turns out to be
8005                dead.  */
8006             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8007             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8008                                                REG_NOTES (i));
8009             i = emit_move_insn (r0, tmp);
8010             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8011                                                REG_NOTES (i));
8012             break;
8013           }
8014     }
8015   DONE;
8018 (define_insn "indirect_jump_compact"
8019   [(set (pc)
8020         (match_operand:SI 0 "arith_reg_operand" "r"))]
8021   "TARGET_SH1"
8022   "jmp  @%0%#"
8023   [(set_attr "needs_delay_slot" "yes")
8024    (set_attr "type" "jump_ind")])
8026 (define_expand "indirect_jump"
8027   [(set (pc)
8028         (match_operand 0 "register_operand" ""))]
8029   ""
8030   "
8032   if (GET_MODE (operands[0]) != Pmode)
8033     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8036 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8037 ;; which can be present in structured code from indirect jumps which can not
8038 ;; be present in structured code.  This allows -fprofile-arcs to work.
8040 ;; For SH1 processors.
8041 (define_insn "casesi_jump_1"
8042   [(set (pc)
8043         (match_operand:SI 0 "register_operand" "r"))
8044    (use (label_ref (match_operand 1 "" "")))]
8045   "TARGET_SH1"
8046   "jmp  @%0%#"
8047   [(set_attr "needs_delay_slot" "yes")
8048    (set_attr "type" "jump_ind")])
8050 ;; For all later processors.
8051 (define_insn "casesi_jump_2"
8052   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8053                       (label_ref (match_operand 1 "" ""))))
8054    (use (label_ref (match_operand 2 "" "")))]
8055   "TARGET_SH2
8056    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8057   "braf %0%#"
8058   [(set_attr "needs_delay_slot" "yes")
8059    (set_attr "type" "jump_ind")])
8061 (define_insn "casesi_jump_media"
8062   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8063    (use (label_ref (match_operand 1 "" "")))]
8064   "TARGET_SHMEDIA"
8065   "blink        %0, r63"
8066   [(set_attr "type" "jump_media")])
8068 ;; Call subroutine returning any type.
8069 ;; ??? This probably doesn't work.
8071 (define_expand "untyped_call"
8072   [(parallel [(call (match_operand 0 "" "")
8073                     (const_int 0))
8074               (match_operand 1 "" "")
8075               (match_operand 2 "" "")])]
8076   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8077   "
8079   int i;
8081   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8083   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8084     {
8085       rtx set = XVECEXP (operands[2], 0, i);
8086       emit_move_insn (SET_DEST (set), SET_SRC (set));
8087     }
8089   /* The optimizer does not know that the call sets the function value
8090      registers we stored in the result block.  We avoid problems by
8091      claiming that all hard registers are used and clobbered at this
8092      point.  */
8093   emit_insn (gen_blockage ());
8095   DONE;
8098 ;; ------------------------------------------------------------------------
8099 ;; Misc insns
8100 ;; ------------------------------------------------------------------------
8102 (define_insn "dect"
8103   [(set (reg:SI T_REG)
8104         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8105    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8106   "TARGET_SH2"
8107   "dt   %0"
8108   [(set_attr "type" "arith")])
8110 (define_insn "nop"
8111   [(const_int 0)]
8112   ""
8113   "nop")
8115 ;; Load address of a label. This is only generated by the casesi expand,
8116 ;; and by machine_dependent_reorg (fixing up fp moves).
8117 ;; This must use unspec, because this only works for labels that are
8118 ;; within range,
8120 (define_insn "mova"
8121   [(set (reg:SI R0_REG)
8122         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8123   "TARGET_SH1"
8124   "mova %O0,r0"
8125   [(set_attr "in_delay_slot" "no")
8126    (set_attr "type" "arith")])
8128 ;; machine_dependent_reorg will make this a `mova'.
8129 (define_insn "mova_const"
8130   [(set (reg:SI R0_REG)
8131         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8132   "TARGET_SH1"
8133   "#"
8134   [(set_attr "in_delay_slot" "no")
8135    (set_attr "type" "arith")])
8137 (define_expand "GOTaddr2picreg"
8138   [(set (reg:SI R0_REG)
8139         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8140                    UNSPEC_MOVA))
8141    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8142    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8143   "" "
8145   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8146   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8148   if (TARGET_SHMEDIA)
8149     {
8150       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8151       rtx pic = operands[0];
8152       rtx lab = PATTERN (gen_call_site ());
8153       rtx insn, equiv;
8155       equiv = operands[1];
8156       operands[1] = gen_rtx_MINUS (Pmode,
8157                                    operands[1],
8158                                    gen_rtx_CONST
8159                                    (Pmode,
8160                                     gen_rtx_MINUS (Pmode,
8161                                                    gen_rtx_CONST (Pmode,
8162                                                                   lab),
8163                                                    pc_rtx)));
8164       operands[1] = gen_sym2PIC (operands[1]);
8165       PUT_MODE (operands[1], Pmode);
8167       if (Pmode == SImode)
8168         {
8169           emit_insn (gen_movsi_const (pic, operands[1]));
8170           emit_insn (gen_ptrel_si (tr, pic, lab));
8171         }
8172       else
8173         {
8174           emit_insn (gen_movdi_const (pic, operands[1]));
8175           emit_insn (gen_ptrel_di (tr, pic, lab));
8176         }
8178       insn = emit_move_insn (operands[0], tr);
8180       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8181                                             REG_NOTES (insn));
8183       DONE;
8184     }
8188 (define_insn "*ptb"
8189   [(set (match_operand 0 "target_reg_operand" "=b")
8190         (const (unspec [(match_operand 1 "" "Csy")]
8191                              UNSPEC_DATALABEL)))]
8192   "TARGET_SHMEDIA && flag_pic
8193    && EXTRA_CONSTRAINT_Csy (operands[1])"
8194   "ptb/u        datalabel %1, %0"
8195   [(set_attr "type" "ptabs_media")
8196    (set_attr "length" "*")])
8198 (define_insn "ptrel_si"
8199   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8200         (plus:SI (match_operand:SI 1 "register_operand" "r")
8201               (pc)))
8202    (match_operand:SI 2 "" "")]
8203   "TARGET_SHMEDIA"
8204   "%O2: ptrel/u %1, %0"
8205   [(set_attr "type" "ptabs_media")])
8207 (define_insn "ptrel_di"
8208   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8209         (plus:DI (match_operand:DI 1 "register_operand" "r")
8210               (pc)))
8211    (match_operand:DI 2 "" "")]
8212   "TARGET_SHMEDIA"
8213   "%O2: ptrel/u %1, %0"
8214   [(set_attr "type" "ptabs_media")])
8216 (define_expand "builtin_setjmp_receiver"
8217   [(match_operand 0 "" "")]
8218   "flag_pic"
8219   "
8221   emit_insn (gen_GOTaddr2picreg ());
8222   DONE;
8225 (define_expand "call_site"
8226   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8227   "TARGET_SH1"
8228   "
8230   static HOST_WIDE_INT i = 0;
8231   operands[0] = GEN_INT (i);
8232   i++;
8235 (define_expand "sym_label2reg"
8236   [(set (match_operand:SI 0 "" "")
8237         (const:SI (minus:SI
8238                    (const:SI
8239                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8240                    (const:SI
8241                     (plus:SI
8242                      (match_operand:SI 2 "" "")
8243                      (const_int 2))))))]
8244   "TARGET_SH1" "")
8246 (define_expand "symGOT_load"
8247   [(set (match_dup 2) (match_operand 1 "" ""))
8248    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8249    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8250   ""
8251   "
8253   rtx insn;
8255   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8256   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8258   if (TARGET_SHMEDIA)
8259     {
8260       rtx reg = operands[2];
8262       if (Pmode == DImode)
8263         {      
8264           if (flag_pic > 1)
8265             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8266           else
8267             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8268         }
8269       else
8270         {
8271           if (flag_pic > 1)
8272             emit_insn (gen_movsi_const (reg, operands[1]));
8273           else
8274             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8275         }
8276     }
8277   else
8278     emit_move_insn (operands[2], operands[1]);
8280   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8281                                              operands[2],
8282                                              gen_rtx_REG (Pmode, PIC_REG)));
8284   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
8286   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8287                                                                   0), 0, 0),
8288                                         REG_NOTES (insn));
8290   DONE;
8293 (define_expand "sym2GOT"
8294   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8295   ""
8296   "")
8298 (define_expand "symGOT2reg"
8299   [(match_operand 0 "" "") (match_operand 1 "" "")]
8300   ""
8301   "
8303   rtx gotsym, insn;
8305   gotsym = gen_sym2GOT (operands[1]);
8306   PUT_MODE (gotsym, Pmode);
8307   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8309   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8311   DONE;
8314 (define_expand "sym2GOTPLT"
8315   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
8316   ""
8317   "")
8319 (define_expand "symGOTPLT2reg"
8320   [(match_operand 0 "" "") (match_operand 1 "" "")]
8321   ""
8322   "
8324   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
8325   DONE;
8328 (define_expand "sym2GOTOFF"
8329   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8330   ""
8331   "")
8333 (define_expand "symGOTOFF2reg"
8334   [(match_operand 0 "" "") (match_operand 1 "" "")]
8335   ""
8336   "
8338   rtx gotoffsym, insn;
8339   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8341   gotoffsym = gen_sym2GOTOFF (operands[1]);
8342   PUT_MODE (gotoffsym, Pmode);
8343   emit_move_insn (t, gotoffsym);
8344   insn = emit_move_insn (operands[0],
8345                          gen_rtx_PLUS (Pmode, t,
8346                                        gen_rtx_REG (Pmode, PIC_REG)));
8348   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8349                                         REG_NOTES (insn));
8351   DONE;
8354 (define_expand "symPLT_label2reg"
8355   [(set (match_operand:SI 0 "" "")
8356         (const:SI (minus:SI
8357                    (const:SI
8358                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8359                    (const:SI
8360                     (minus:SI
8361                      (const:SI (plus:SI
8362                                 (match_operand:SI 2 "" "")
8363                                 (const_int 2)))
8364                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8365    ;; Even though the PIC register is not really used by the call
8366    ;; sequence in which this is expanded, the PLT code assumes the PIC
8367    ;; register is set, so we must not skip its initialization.  Since
8368    ;; we only use this expand as part of calling sequences, and never
8369    ;; to take the address of a function, this is the best point to
8370    ;; insert the (use).  Using the PLT to take the address of a
8371    ;; function would be wrong, not only because the PLT entry could
8372    ;; then be called from a function that doesn't initialize the PIC
8373    ;; register to the proper GOT, but also because pointers to the
8374    ;; same function might not compare equal, should they be set by
8375    ;; different shared libraries.
8376    (use (reg:SI PIC_REG))]
8377   "TARGET_SH1"
8378   "")
8380 (define_expand "sym2PIC"
8381   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8382   ""
8383   "")
8385 ;; TLS code generation.
8386 ;; ??? this should be a define_insn_and_split
8387 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8388 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8389 ;; for details.
8391 (define_insn "tls_global_dynamic"
8392   [(set (match_operand:SI 0 "register_operand" "=&z")
8393         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8394                                   UNSPEC_TLSGD))
8395               (const_int 0)))
8396    (use (reg:PSI FPSCR_REG))
8397    (use (reg:SI PIC_REG))
8398    (clobber (reg:SI PR_REG))
8399    (clobber (scratch:SI))]
8400   "TARGET_SH1"
8401   "*
8403   return \"\\
8404 mov.l\\t1f,r4\\n\\
8405 \\tmova\\t2f,r0\\n\\
8406 \\tmov.l\\t2f,r1\\n\\
8407 \\tadd\\tr0,r1\\n\\
8408 \\tjsr\\t@r1\\n\\
8409 \\tadd\\tr12,r4\\n\\
8410 \\tbra\\t3f\\n\\
8411 \\tnop\\n\\
8412 \\t.align\\t2\\n\\
8413 1:\\t.long\\t%a1@TLSGD\\n\\
8414 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8415 3:\";
8417   [(set_attr "type" "tls_load")
8418    (set_attr "length" "26")])
8420 (define_insn "tls_local_dynamic"
8421   [(set (match_operand:SI 0 "register_operand" "=&z")
8422         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8423                                   UNSPEC_TLSLDM))
8424               (const_int 0)))
8425    (use (reg:PSI FPSCR_REG))
8426    (use (reg:SI PIC_REG))
8427    (clobber (reg:SI PR_REG))
8428    (clobber (scratch:SI))]
8429   "TARGET_SH1"
8430   "*
8432   return \"\\
8433 mov.l\\t1f,r4\\n\\
8434 \\tmova\\t2f,r0\\n\\
8435 \\tmov.l\\t2f,r1\\n\\
8436 \\tadd\\tr0,r1\\n\\
8437 \\tjsr\\t@r1\\n\\
8438 \\tadd\\tr12,r4\\n\\
8439 \\tbra\\t3f\\n\\
8440 \\tnop\\n\\
8441 \\t.align\\t2\\n\\
8442 1:\\t.long\\t%a1@TLSLDM\\n\\
8443 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8444 3:\";
8446   [(set_attr "type" "tls_load")
8447    (set_attr "length" "26")])
8449 (define_expand "sym2DTPOFF"
8450   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8451   ""
8452   "")
8454 (define_expand "symDTPOFF2reg"
8455   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8456   ""
8457   "
8459   rtx dtpoffsym, insn;
8460   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8462   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8463   PUT_MODE (dtpoffsym, Pmode);
8464   emit_move_insn (t, dtpoffsym);
8465   insn = emit_move_insn (operands[0],
8466                          gen_rtx_PLUS (Pmode, t, operands[2]));
8467   DONE;
8470 (define_expand "sym2GOTTPOFF"
8471   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8472   ""
8473   "")
8475 (define_insn "tls_initial_exec"
8476   [(set (match_operand:SI 0 "register_operand" "=&r")
8477         (unspec:SI [(match_operand:SI 1 "" "")]
8478                     UNSPEC_TLSIE))
8479    (use (reg:SI GBR_REG))
8480    (use (reg:SI PIC_REG))
8481    (clobber (reg:SI R0_REG))]
8482   ""
8483   "*
8485   return \"\\
8486 mov.l\\t1f,r0\\n\\
8487 \\tstc\\tgbr,%0\\n\\
8488 \\tmov.l\\t@(r0,r12),r0\\n\\
8489 \\tbra\\t2f\\n\\
8490 \\tadd\\tr0,%0\\n\\
8491 \\t.align\\t2\\n\\
8492 1:\\t.long\\t%a1\\n\\
8493 2:\";
8495   [(set_attr "type" "tls_load")
8496    (set_attr "length" "16")])
8498 (define_expand "sym2TPOFF"
8499   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8500   ""
8501   "")
8503 (define_expand "symTPOFF2reg"
8504   [(match_operand 0 "" "") (match_operand 1 "" "")]
8505   ""
8506   "
8508   rtx tpoffsym, insn;
8510   tpoffsym = gen_sym2TPOFF (operands[1]);
8511   PUT_MODE (tpoffsym, Pmode);
8512   insn = emit_move_insn (operands[0], tpoffsym);
8513   DONE;
8516 (define_insn "load_gbr"
8517   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8518    (use (reg:SI GBR_REG))]
8519   ""
8520   "stc  gbr,%0"
8521   [(set_attr "type" "tls_load")])
8523 ;; case instruction for switch statements.
8525 ;; Operand 0 is index
8526 ;; operand 1 is the minimum bound
8527 ;; operand 2 is the maximum bound - minimum bound + 1
8528 ;; operand 3 is CODE_LABEL for the table;
8529 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8531 (define_expand "casesi"
8532   [(match_operand:SI 0 "arith_reg_operand" "")
8533    (match_operand:SI 1 "arith_reg_operand" "")
8534    (match_operand:SI 2 "arith_reg_operand" "")
8535    (match_operand 3 "" "") (match_operand 4 "" "")]
8536   ""
8537   "
8539   rtx reg = gen_reg_rtx (SImode);
8540   rtx reg2 = gen_reg_rtx (SImode);
8541   if (TARGET_SHMEDIA)
8542     {
8543       rtx reg = gen_reg_rtx (DImode);
8544       rtx reg2 = gen_reg_rtx (DImode);
8545       rtx reg3 = gen_reg_rtx (Pmode);
8546       rtx reg4 = gen_reg_rtx (Pmode);
8547       rtx reg5 = gen_reg_rtx (Pmode);
8548       rtx load;
8550       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8551       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8552       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8554       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8555       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8556       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8557       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8558       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8559                                                (Pmode, operands[3])));
8560       /* Messy: can we subreg to clean this up? */
8561       if (Pmode == DImode)
8562         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8563       else
8564         load = gen_casesi_load_media (reg4,
8565                                       gen_rtx_SUBREG (DImode, reg3, 0),
8566                                       reg2, operands[3]);
8567       PUT_MODE (SET_SRC (load), Pmode);
8568       emit_insn (load);
8569       /* ??? The following add could be eliminated if we used ptrel.  */
8570       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8571       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8572       emit_barrier ();
8573       DONE;
8574     }
8575   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8576   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8577   /* If optimizing, casesi_worker depends on the mode of the instruction
8578      before label it 'uses' - operands[3].  */
8579   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8580                            reg));
8581   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8582   if (TARGET_SH2)
8583     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8584   else
8585     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8586   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8587      operands[3], but to lab.  We will fix this up in
8588      machine_dependent_reorg.  */
8589   emit_barrier ();
8590   DONE;
8593 (define_expand "casesi_0"
8594   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8595    (set (match_dup 4) (minus:SI (match_dup 4)
8596                                 (match_operand:SI 1 "arith_operand" "")))
8597    (set (reg:SI T_REG)
8598         (gtu:SI (match_dup 4)
8599                 (match_operand:SI 2 "arith_reg_operand" "")))
8600    (set (pc)
8601         (if_then_else (ne (reg:SI T_REG)
8602                           (const_int 0))
8603                       (label_ref (match_operand 3 "" ""))
8604                       (pc)))]
8605   "TARGET_SH1"
8606   "")
8608 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8609 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8610 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8612 (define_insn "casesi_worker_0"
8613   [(set (match_operand:SI 0 "register_operand" "=r,r")
8614         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8615                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8616    (clobber (match_scratch:SI 3 "=X,1"))
8617    (clobber (match_scratch:SI 4 "=&z,z"))]
8618   "TARGET_SH1"
8619   "#")
8621 (define_split
8622   [(set (match_operand:SI 0 "register_operand" "")
8623         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8624                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8625    (clobber (match_scratch:SI 3 ""))
8626    (clobber (match_scratch:SI 4 ""))]
8627   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8628   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8629    (parallel [(set (match_dup 0)
8630               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8631                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8632               (clobber (match_dup 3))])
8633    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8634   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8636 (define_split
8637   [(set (match_operand:SI 0 "register_operand" "")
8638         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8639                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8640    (clobber (match_scratch:SI 3 ""))
8641    (clobber (match_scratch:SI 4 ""))]
8642   "TARGET_SH2 && reload_completed"
8643   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8644    (parallel [(set (match_dup 0)
8645               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8646                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8647               (clobber (match_dup 3))])]
8648   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8650 (define_insn "casesi_worker_1"
8651   [(set (match_operand:SI 0 "register_operand" "=r,r")
8652         (unspec:SI [(reg:SI R0_REG)
8653                     (match_operand:SI 1 "register_operand" "0,r")
8654                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8655    (clobber (match_scratch:SI 3 "=X,1"))]
8656   "TARGET_SH1"
8657   "*
8659   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8661   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8663   switch (GET_MODE (diff_vec))
8664     {
8665     case SImode:
8666       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8667     case HImode:
8668       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8669     case QImode:
8670       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8671         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8672       return \"mov.b    @(r0,%1),%0\";
8673     default:
8674       gcc_unreachable ();
8675     }
8677   [(set_attr "length" "4")])
8679 (define_insn "casesi_worker_2"
8680   [(set (match_operand:SI 0 "register_operand" "=r,r")
8681         (unspec:SI [(reg:SI R0_REG)
8682                     (match_operand:SI 1 "register_operand" "0,r")
8683                     (label_ref (match_operand 2 "" ""))
8684                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8685    (clobber (match_operand:SI 4 "" "=X,1"))]
8686   "TARGET_SH2 && reload_completed && flag_pic"
8687   "*
8689   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8690   const char *load;
8692   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8694   switch (GET_MODE (diff_vec))
8695     {
8696     case SImode:
8697       output_asm_insn (\"shll2    %1\", operands);
8698       load = \"mov.l    @(r0,%1),%0\"; break;
8699     case HImode:
8700       output_asm_insn (\"add    %1,%1\", operands);
8701       load = \"mov.w    @(r0,%1),%0\"; break;
8702     case QImode:
8703       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8704         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8705       else
8706         load = \"mov.b  @(r0,%1),%0\";
8707       break;
8708     default:
8709       gcc_unreachable ();
8710     }
8711   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8712   return load;
8714   [(set_attr "length" "8")])
8716 (define_insn "casesi_shift_media"
8717   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8718         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8719                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8720                     UNSPEC_CASESI)))]
8721   "TARGET_SHMEDIA"
8722   "*
8724   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8726   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8728   switch (GET_MODE (diff_vec))
8729     {
8730     case SImode:
8731       return \"shlli    %1, 2, %0\";
8732     case HImode:
8733       return \"shlli    %1, 1, %0\";
8734     case QImode:
8735       if (rtx_equal_p (operands[0], operands[1]))
8736         return \"\";
8737       return \"add      %1, r63, %0\";
8738     default:
8739       gcc_unreachable ();
8740     }
8742   [(set_attr "type" "arith_media")])
8744 (define_insn "casesi_load_media"
8745   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8746         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8747                          (match_operand:DI 2 "arith_reg_operand" "r")
8748                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8749   "TARGET_SHMEDIA"
8750   "*
8752   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8754   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8756   switch (GET_MODE (diff_vec))
8757     {
8758     case SImode:
8759       return \"ldx.l    %1, %2, %0\";
8760     case HImode:
8761 #if 0
8762       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8763         return \"ldx.uw %1, %2, %0\";
8764 #endif
8765       return \"ldx.w    %1, %2, %0\";
8766     case QImode:
8767       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8768         return \"ldx.ub %1, %2, %0\";
8769       return \"ldx.b    %1, %2, %0\";
8770     default:
8771       gcc_unreachable ();
8772     }
8774   [(set_attr "type" "load_media")])
8776 (define_expand "return"
8777   [(return)]
8778   "reload_completed && ! sh_need_epilogue ()"
8779   "
8781   if (TARGET_SHMEDIA)
8782     {
8783       emit_jump_insn (gen_return_media ());
8784       DONE;
8785     }
8787   if (TARGET_SHCOMPACT
8788       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8789     {
8790       emit_jump_insn (gen_shcompact_return_tramp ());
8791       DONE;
8792     }
8795 (define_insn "*return_i"
8796   [(return)]
8797   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8798                     && (current_function_args_info.call_cookie
8799                         & CALL_COOKIE_RET_TRAMP (1)))
8800    && reload_completed"
8801   "%@   %#"
8802   [(set_attr "type" "return")
8803    (set_attr "needs_delay_slot" "yes")])
8805 (define_expand "shcompact_return_tramp"
8806   [(return)]
8807   "TARGET_SHCOMPACT
8808    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8809   "
8811   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8813   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8814   emit_jump_insn (gen_shcompact_return_tramp_i ());
8815   DONE;
8818 (define_insn "shcompact_return_tramp_i"
8819   [(parallel [(return) (use (reg:SI R0_REG))])]
8820   "TARGET_SHCOMPACT
8821    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8822   "jmp  @r0%#"
8823   [(set_attr "type" "jump_ind")
8824    (set_attr "needs_delay_slot" "yes")])
8826 (define_insn "return_media_i"
8827   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8828   "TARGET_SHMEDIA && reload_completed"
8829   "blink        %0, r63"
8830   [(set_attr "type" "jump_media")])
8832 (define_insn "return_media_rte"
8833   [(return)]
8834   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8835   "rte"
8836   [(set_attr "type" "jump_media")])
8838 (define_expand "return_media"
8839   [(return)]
8840   "TARGET_SHMEDIA && reload_completed"
8841   "
8843   int tr_regno = sh_media_register_for_return ();
8844   rtx tr;
8846   if (current_function_interrupt)
8847     {
8848       emit_jump_insn (gen_return_media_rte ());
8849       DONE;
8850     }
8851   if (tr_regno < 0)
8852     {
8853       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8855       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8856       tr_regno = TR0_REG;
8857       tr = gen_rtx_REG (Pmode, tr_regno);
8858       emit_move_insn (tr, r18);
8859     }
8860   else
8861     tr = gen_rtx_REG (Pmode, tr_regno);
8863   emit_jump_insn (gen_return_media_i (tr));
8864   DONE;
8867 (define_insn "shcompact_preserve_incoming_args"
8868   [(set (match_operand:SI 0 "register_operand" "+r")
8869         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8870   "TARGET_SHCOMPACT"
8871   ""
8872   [(set_attr "length" "0")])
8874 (define_insn "shcompact_incoming_args"
8875   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8876    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8877    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8878    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8879    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8880    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8881    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8882    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8883    (set (mem:BLK (reg:SI MACL_REG))
8884         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8885    (use (reg:SI R0_REG))
8886    (clobber (reg:SI R0_REG))
8887    (clobber (reg:SI MACL_REG))
8888    (clobber (reg:SI MACH_REG))
8889    (clobber (reg:SI PR_REG))]
8890   "TARGET_SHCOMPACT"
8891   "jsr  @r0%#"
8892   [(set_attr "needs_delay_slot" "yes")])
8894 (define_insn "shmedia_save_restore_regs_compact"
8895   [(set (reg:SI SP_REG)
8896         (plus:SI (reg:SI SP_REG)
8897                  (match_operand:SI 0 "immediate_operand" "i")))
8898    (use (reg:SI R0_REG))
8899    (clobber (reg:SI PR_REG))]
8900   "TARGET_SHCOMPACT
8901    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8902        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8903   "jsr @r0%#"
8904   [(set_attr "needs_delay_slot" "yes")])
8906 (define_expand "prologue"
8907   [(const_int 0)]
8908   ""
8909   "sh_expand_prologue (); DONE;")
8911 (define_expand "epilogue"
8912   [(return)]
8913   ""
8914   "
8916   sh_expand_epilogue (0);
8917   emit_jump_insn (gen_return ());
8918   DONE;
8921 (define_expand "eh_return"
8922   [(use (match_operand 0 "register_operand" ""))]
8923   ""
8925   rtx ra = operands[0];
8927   if (TARGET_SHMEDIA64)
8928     emit_insn (gen_eh_set_ra_di (ra));
8929   else
8930     emit_insn (gen_eh_set_ra_si (ra));
8932   DONE;
8935 ;; Clobber the return address on the stack.  We can't expand this
8936 ;; until we know where it will be put in the stack frame.
8938 (define_insn "eh_set_ra_si"
8939   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8940    (clobber (match_scratch:SI 1 "=&r"))]
8941   "! TARGET_SHMEDIA64"
8942   "#")
8944 (define_insn "eh_set_ra_di"
8945   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8946    (clobber (match_scratch:DI 1 "=&r"))]
8947   "TARGET_SHMEDIA64"
8948   "#")
8950 (define_split
8951   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8952    (clobber (match_scratch 1 ""))]
8953   "reload_completed"
8954   [(const_int 0)]
8955   "
8957   sh_set_return_address (operands[0], operands[1]);
8958   DONE;
8961 (define_insn "blockage"
8962   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8963   ""
8964   ""
8965   [(set_attr "length" "0")])
8967 ;; ------------------------------------------------------------------------
8968 ;; Scc instructions
8969 ;; ------------------------------------------------------------------------
8971 (define_insn "movt"
8972   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
8973         (eq:SI (reg:SI T_REG) (const_int 1)))]
8974   "TARGET_SH1"
8975   "movt %0"
8976   [(set_attr "type" "arith")])
8978 (define_expand "seq"
8979   [(set (match_operand:SI 0 "arith_reg_dest" "")
8980         (match_dup 1))]
8981   ""
8982   "
8984   if (TARGET_SHMEDIA)
8985     {
8986       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
8987       if (sh_compare_op1 != const0_rtx)
8988         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
8989                                     ? GET_MODE (sh_compare_op0)
8990                                     : GET_MODE (sh_compare_op1),
8991                                     sh_compare_op1);
8992       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
8993         {
8994           if (GET_MODE (operands[0]) != SImode)
8995             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
8997           switch (GET_MODE (sh_compare_op0))
8998             {
8999             case SImode:
9000               emit_insn (gen_cmpsieqsi_media (operands[0],
9001                                               sh_compare_op0, sh_compare_op1));
9002               break;
9004             case DImode:
9005               emit_insn (gen_cmpsieqdi_media (operands[0],
9006                                               sh_compare_op0, sh_compare_op1));
9007               break;
9009             case SFmode:
9010               if (! TARGET_SHMEDIA_FPU)
9011                 FAIL;
9012               emit_insn (gen_cmpsieqsf_media (operands[0],
9013                                               sh_compare_op0, sh_compare_op1));
9014               break;
9016             case DFmode:
9017               if (! TARGET_SHMEDIA_FPU)
9018                 FAIL;
9019               emit_insn (gen_cmpsieqdf_media (operands[0],
9020                                               sh_compare_op0, sh_compare_op1));
9021               break;
9023             default:
9024               FAIL;
9025             }
9026           DONE;
9027         }
9029       if (GET_MODE (operands[0]) != DImode)
9030         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9032       switch (GET_MODE (sh_compare_op0))
9033         {
9034         case SImode:
9035           emit_insn (gen_cmpeqsi_media (operands[0],
9036                                         sh_compare_op0, sh_compare_op1));
9037           break;
9039         case DImode:
9040           emit_insn (gen_cmpeqdi_media (operands[0],
9041                                         sh_compare_op0, sh_compare_op1));
9042           break;
9044         case SFmode:
9045           if (! TARGET_SHMEDIA_FPU)
9046             FAIL;
9047           emit_insn (gen_cmpeqsf_media (operands[0],
9048                                         sh_compare_op0, sh_compare_op1));
9049           break;
9051         case DFmode:
9052           if (! TARGET_SHMEDIA_FPU)
9053             FAIL;
9054           emit_insn (gen_cmpeqdf_media (operands[0],
9055                                         sh_compare_op0, sh_compare_op1));
9056           break;
9058         default:
9059           FAIL;
9060         }
9061       DONE;
9062     }
9063   if (sh_expand_t_scc (EQ, operands[0]))
9064     DONE;
9065   if (! currently_expanding_to_rtl)
9066     FAIL;
9067   operands[1] = prepare_scc_operands (EQ);
9070 (define_expand "slt"
9071   [(set (match_operand:SI 0 "arith_reg_operand" "")
9072         (match_dup 1))]
9073   ""
9074   "
9076   if (TARGET_SHMEDIA)
9077     {
9078       if (GET_MODE (operands[0]) != DImode)
9079         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9080       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9081       if (sh_compare_op1 != const0_rtx)
9082         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9083                                     ? GET_MODE (sh_compare_op0)
9084                                     : GET_MODE (sh_compare_op1),
9085                                     sh_compare_op1);
9087       switch (GET_MODE (sh_compare_op0))
9088         {
9089         case SImode:
9090           emit_insn (gen_cmpgtsi_media (operands[0],
9091                                         sh_compare_op1, sh_compare_op0));
9092           break;
9094         case DImode:
9095           emit_insn (gen_cmpgtdi_media (operands[0],
9096                                         sh_compare_op1, sh_compare_op0));
9097           break;
9099         case SFmode:
9100           if (! TARGET_SHMEDIA_FPU)
9101             FAIL;
9102           emit_insn (gen_cmpgtsf_media (operands[0],
9103                                         sh_compare_op1, sh_compare_op0));
9104           break;
9106         case DFmode:
9107           if (! TARGET_SHMEDIA_FPU)
9108             FAIL;
9109           emit_insn (gen_cmpgtdf_media (operands[0],
9110                                         sh_compare_op1, sh_compare_op0));
9111           break;
9113         default:
9114           FAIL;
9115         }
9116       DONE;
9117     }
9118   if (! currently_expanding_to_rtl)
9119     FAIL;
9120   operands[1] = prepare_scc_operands (LT);
9123 (define_expand "sle"
9124   [(match_operand:SI 0 "arith_reg_operand" "")]
9125   ""
9126   "
9128   rtx tmp = sh_compare_op0;
9130   if (TARGET_SHMEDIA)
9131     {
9132       if (GET_MODE (operands[0]) != DImode)
9133         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9134       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9135       if (sh_compare_op1 != const0_rtx)
9136         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9137                                     ? GET_MODE (sh_compare_op0)
9138                                     : GET_MODE (sh_compare_op1),
9139                                     sh_compare_op1);
9141       switch (GET_MODE (sh_compare_op0))
9142         {
9143         case SImode:
9144           {
9145             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9147             emit_insn (gen_cmpgtsi_media (tmp,
9148                                           sh_compare_op0, sh_compare_op1));
9149             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9150             break;
9151           }
9153         case DImode:
9154           {
9155             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9157             emit_insn (gen_cmpgtdi_media (tmp,
9158                                           sh_compare_op0, sh_compare_op1));
9159             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9160             break;
9161           }
9163         case SFmode:
9164           if (! TARGET_SHMEDIA_FPU)
9165             FAIL;
9166           emit_insn (gen_cmpgesf_media (operands[0],
9167                                         sh_compare_op1, sh_compare_op0));
9168           break;
9170         case DFmode:
9171           if (! TARGET_SHMEDIA_FPU)
9172             FAIL;
9173           emit_insn (gen_cmpgedf_media (operands[0],
9174                                         sh_compare_op1, sh_compare_op0));
9175           break;
9177         default:
9178           FAIL;
9179         }
9180       DONE;
9181     }
9183   sh_compare_op0 = sh_compare_op1;
9184   sh_compare_op1 = tmp;
9185   emit_insn (gen_sge (operands[0]));
9186   DONE;
9189 (define_expand "sgt"
9190   [(set (match_operand:SI 0 "arith_reg_operand" "")
9191         (match_dup 1))]
9192   ""
9193   "
9195   if (TARGET_SHMEDIA)
9196     {
9197       if (GET_MODE (operands[0]) != DImode)
9198         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9199       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9200       if (sh_compare_op1 != const0_rtx)
9201         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9202                                     ? GET_MODE (sh_compare_op0)
9203                                     : GET_MODE (sh_compare_op1),
9204                                     sh_compare_op1);
9206       switch (GET_MODE (sh_compare_op0))
9207         {
9208         case SImode:
9209           emit_insn (gen_cmpgtsi_media (operands[0],
9210                                         sh_compare_op0, sh_compare_op1));
9211           break;
9213         case DImode:
9214           emit_insn (gen_cmpgtdi_media (operands[0],
9215                                         sh_compare_op0, sh_compare_op1));
9216           break;
9218         case SFmode:
9219           if (! TARGET_SHMEDIA_FPU)
9220             FAIL;
9221           emit_insn (gen_cmpgtsf_media (operands[0],
9222                                         sh_compare_op0, sh_compare_op1));
9223           break;
9225         case DFmode:
9226           if (! TARGET_SHMEDIA_FPU)
9227             FAIL;
9228           emit_insn (gen_cmpgtdf_media (operands[0],
9229                                         sh_compare_op0, sh_compare_op1));
9230           break;
9232         default:
9233           FAIL;
9234         }
9235       DONE;
9236     }
9237   if (! currently_expanding_to_rtl)
9238     FAIL;
9239   operands[1] = prepare_scc_operands (GT);
9242 (define_expand "sge"
9243   [(set (match_operand:SI 0 "arith_reg_operand" "")
9244         (match_dup 1))]
9245   ""
9246   "
9248   if (TARGET_SHMEDIA)
9249     {
9250       enum machine_mode mode = GET_MODE (sh_compare_op0);
9252       if ((mode) == VOIDmode)
9253         mode = GET_MODE (sh_compare_op1);
9254       if (GET_MODE (operands[0]) != DImode)
9255         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9256       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9257       if (sh_compare_op1 != const0_rtx)
9258         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9260       switch (mode)
9261         {
9262         case SImode:
9263           {
9264             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9266             emit_insn (gen_cmpgtsi_media (tmp,
9267                                           sh_compare_op1, sh_compare_op0));
9268             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9269             break;
9270           }
9272         case DImode:
9273           {
9274             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9276             emit_insn (gen_cmpgtdi_media (tmp,
9277                                           sh_compare_op1, sh_compare_op0));
9278             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9279             break;
9280           }
9282         case SFmode:
9283           if (! TARGET_SHMEDIA_FPU)
9284             FAIL;
9285           emit_insn (gen_cmpgesf_media (operands[0],
9286                                         sh_compare_op0, sh_compare_op1));
9287           break;
9289         case DFmode:
9290           if (! TARGET_SHMEDIA_FPU)
9291             FAIL;
9292           emit_insn (gen_cmpgedf_media (operands[0],
9293                                         sh_compare_op0, sh_compare_op1));
9294           break;
9296         default:
9297           FAIL;
9298         }
9299       DONE;
9300     }
9302   if (! currently_expanding_to_rtl)
9303     FAIL;
9304   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9305     {
9306       if (TARGET_IEEE)
9307         {
9308           rtx lab = gen_label_rtx ();
9309           prepare_scc_operands (EQ);
9310           emit_jump_insn (gen_branch_true (lab));
9311           prepare_scc_operands (GT);
9312           emit_label (lab);
9313           emit_insn (gen_movt (operands[0]));
9314         }
9315       else
9316         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9317       DONE;
9318     }
9319   operands[1] = prepare_scc_operands (GE);
9322 (define_expand "sgtu"
9323   [(set (match_operand:SI 0 "arith_reg_operand" "")
9324         (match_dup 1))]
9325   ""
9326   "
9328   if (TARGET_SHMEDIA)
9329     {
9330       if (GET_MODE (operands[0]) != DImode)
9331         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9332       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9333       if (sh_compare_op1 != const0_rtx)
9334         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9335                                     ? GET_MODE (sh_compare_op0)
9336                                     : GET_MODE (sh_compare_op1),
9337                                     sh_compare_op1);
9339       emit_insn (gen_cmpgtudi_media (operands[0],
9340                                      sh_compare_op0, sh_compare_op1));
9341       DONE;
9342     }
9343   if (! currently_expanding_to_rtl)
9344     FAIL;
9345   operands[1] = prepare_scc_operands (GTU);
9348 (define_expand "sltu"
9349   [(set (match_operand:SI 0 "arith_reg_operand" "")
9350         (match_dup 1))]
9351   ""
9352   "
9354   if (TARGET_SHMEDIA)
9355     {
9356       if (GET_MODE (operands[0]) != DImode)
9357         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9358       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9359       if (sh_compare_op1 != const0_rtx)
9360         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9361                                     ? GET_MODE (sh_compare_op0)
9362                                     : GET_MODE (sh_compare_op1),
9363                                     sh_compare_op1);
9365       emit_insn (gen_cmpgtudi_media (operands[0],
9366                                      sh_compare_op1, sh_compare_op0));
9367       DONE;
9368     }
9369   if (! currently_expanding_to_rtl)
9370     FAIL;
9371   operands[1] = prepare_scc_operands (LTU);
9374 (define_expand "sleu"
9375   [(set (match_operand:SI 0 "arith_reg_operand" "")
9376         (match_dup 1))]
9377   ""
9378   "
9380   if (TARGET_SHMEDIA)
9381     {
9382       rtx tmp;
9384       if (GET_MODE (operands[0]) != DImode)
9385         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9386       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9387       if (sh_compare_op1 != const0_rtx)
9388         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9389                                     ? GET_MODE (sh_compare_op0)
9390                                     : GET_MODE (sh_compare_op1),
9391                                     sh_compare_op1);
9393       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9395       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9396       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9398       DONE;
9399     }
9400   if (! currently_expanding_to_rtl)
9401     FAIL;
9402   operands[1] = prepare_scc_operands (LEU);
9405 (define_expand "sgeu"
9406   [(set (match_operand:SI 0 "arith_reg_operand" "")
9407         (match_dup 1))]
9408   ""
9409   "
9411   if (TARGET_SHMEDIA)
9412     {
9413       rtx tmp;
9415       if (GET_MODE (operands[0]) != DImode)
9416         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9417       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9418       if (sh_compare_op1 != const0_rtx)
9419         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9420                                     ? GET_MODE (sh_compare_op0)
9421                                     : GET_MODE (sh_compare_op1),
9422                                     sh_compare_op1);
9424       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9426       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9427       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9429       DONE;
9430     }
9432   if (! currently_expanding_to_rtl)
9433     FAIL;
9434   operands[1] = prepare_scc_operands (GEU);
9437 ;; sne moves the complement of the T reg to DEST like this:
9438 ;;      cmp/eq ...
9439 ;;      mov    #-1,temp
9440 ;;      negc   temp,dest
9441 ;;   This is better than xoring compare result with 1 because it does
9442 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9443 ;;   loop.
9445 (define_expand "sne"
9446   [(set (match_dup 2) (const_int -1))
9447    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9448                    (neg:SI (plus:SI (match_dup 1)
9449                                     (match_dup 2))))
9450               (set (reg:SI T_REG)
9451                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9452                           (const_int 0)))])]
9453   ""
9454   "
9456   if (TARGET_SHMEDIA)
9457     {
9458       rtx tmp;
9460       if (GET_MODE (operands[0]) != DImode)
9461         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9463       if (! TARGET_SHMEDIA_FPU
9464           && GET_MODE (sh_compare_op0) != DImode
9465           && GET_MODE (sh_compare_op0) != SImode)
9466         FAIL;
9468       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9469       if (sh_compare_op1 != const0_rtx)
9470         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9471                                     ? GET_MODE (sh_compare_op0)
9472                                     : GET_MODE (sh_compare_op1),
9473                                     sh_compare_op1);
9475       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9477       emit_insn (gen_seq (tmp));
9478       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9480       DONE;
9481     }
9483   if (sh_expand_t_scc (NE, operands[0]))
9484     DONE;
9485   if (! currently_expanding_to_rtl)
9486     FAIL;
9487   operands[1] = prepare_scc_operands (EQ);
9488   operands[2] = gen_reg_rtx (SImode);
9491 (define_expand "sunordered"
9492   [(set (match_operand:DI 0 "arith_reg_operand" "")
9493         (unordered:DI (match_dup 1) (match_dup 2)))]
9494   "TARGET_SHMEDIA_FPU"
9495   "
9497   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9498   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9501 ;; Use the same trick for FP sle / sge
9503 ;; Apart from the constant use and the T setting, this is like movt,
9504 ;; except that it uses the logically negated value of T, i.e.
9505 ;; operand[0] := T ? 0 : 1.
9506 (define_expand "movnegt"
9507   [(set (match_dup 2) (const_int -1))
9508    (parallel [(set (match_operand 0 "" "")
9509                    (neg:SI (plus:SI (match_dup 1)
9510                                     (match_dup 2))))
9511               (set (reg:SI T_REG)
9512                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9513                           (const_int 0)))])]
9514   "TARGET_SH1"
9515   "operands[2] = gen_reg_rtx (SImode);")
9517 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9518 ;; This prevents a regression that occurred when we switched from xor to
9519 ;; mov/neg for sne.
9521 (define_split
9522   [(set (match_operand:SI 0 "arith_reg_dest" "")
9523         (plus:SI (reg:SI T_REG)
9524                  (const_int -1)))]
9525   "TARGET_SH1"
9526   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9527    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9528   "")
9530 ;; -------------------------------------------------------------------------
9531 ;; Instructions to cope with inline literal tables
9532 ;; -------------------------------------------------------------------------
9534 ; 2 byte integer in line
9536 (define_insn "consttable_2"
9537  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9538                     (match_operand 1 "" "")]
9539                    UNSPECV_CONST2)]
9540  ""
9541  "*
9543   if (operands[1] != const0_rtx)
9544     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9545   return \"\";
9547  [(set_attr "length" "2")
9548  (set_attr "in_delay_slot" "no")])
9550 ; 4 byte integer in line
9552 (define_insn "consttable_4"
9553  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9554                     (match_operand 1 "" "")]
9555                    UNSPECV_CONST4)]
9556  ""
9557  "*
9559   if (operands[1] != const0_rtx)
9560     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9561   return \"\";
9563  [(set_attr "length" "4")
9564   (set_attr "in_delay_slot" "no")])
9566 ; 8 byte integer in line
9568 (define_insn "consttable_8"
9569  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9570                     (match_operand 1 "" "")]
9571                    UNSPECV_CONST8)]
9572  ""
9573  "*
9575   if (operands[1] != const0_rtx)
9576     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9577   return \"\";
9579  [(set_attr "length" "8")
9580   (set_attr "in_delay_slot" "no")])
9582 ; 4 byte floating point
9584 (define_insn "consttable_sf"
9585  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9586                     (match_operand 1 "" "")]
9587                    UNSPECV_CONST4)]
9588  ""
9589  "*
9591   if (operands[1] != const0_rtx)
9592     {
9593       REAL_VALUE_TYPE d;
9594       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9595       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9596     }
9597   return \"\";
9599  [(set_attr "length" "4")
9600   (set_attr "in_delay_slot" "no")])
9602 ; 8 byte floating point
9604 (define_insn "consttable_df"
9605  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9606                     (match_operand 1 "" "")]
9607                    UNSPECV_CONST8)]
9608  ""
9609  "*
9611   if (operands[1] != const0_rtx)
9612     {
9613       REAL_VALUE_TYPE d;
9614       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9615       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9616     }
9617   return \"\";
9619  [(set_attr "length" "8")
9620   (set_attr "in_delay_slot" "no")])
9622 ;; Alignment is needed for some constant tables; it may also be added for
9623 ;; Instructions at the start of loops, or after unconditional branches.
9624 ;; ??? We would get more accurate lengths if we did instruction
9625 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9626 ;; here is too conservative.
9628 ; align to a two byte boundary
9630 (define_expand "align_2"
9631  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9632  ""
9633  "")
9635 ; align to a four byte boundary
9636 ;; align_4 and align_log are instructions for the starts of loops, or
9637 ;; after unconditional branches, which may take up extra room.
9639 (define_expand "align_4"
9640  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9641  ""
9642  "")
9644 ; align to a cache line boundary
9646 (define_insn "align_log"
9647  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9648  ""
9649  ""
9650  [(set_attr "length" "0")
9651   (set_attr "in_delay_slot" "no")])
9653 ; emitted at the end of the literal table, used to emit the
9654 ; 32bit branch labels if needed.
9656 (define_insn "consttable_end"
9657   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9658   ""
9659   "* return output_jump_label_table ();"
9660   [(set_attr "in_delay_slot" "no")])
9662 ; emitted at the end of the window in the literal table.
9664 (define_insn "consttable_window_end"
9665   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9666   ""
9667   ""
9668   [(set_attr "length" "0")
9669    (set_attr "in_delay_slot" "no")])
9671 ;; -------------------------------------------------------------------------
9672 ;; Misc
9673 ;; -------------------------------------------------------------------------
9675 ;; String/block move insn.
9677 (define_expand "movmemsi"
9678   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9679                    (mem:BLK (match_operand:BLK 1 "" "")))
9680               (use (match_operand:SI 2 "nonmemory_operand" ""))
9681               (use (match_operand:SI 3 "immediate_operand" ""))
9682               (clobber (reg:SI PR_REG))
9683               (clobber (reg:SI R4_REG))
9684               (clobber (reg:SI R5_REG))
9685               (clobber (reg:SI R0_REG))])]
9686   "TARGET_SH1 && ! TARGET_SH5"
9687   "
9689   if(expand_block_move (operands))
9690      DONE;
9691   else FAIL;
9694 (define_insn "block_move_real"
9695   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9696                    (mem:BLK (reg:SI R5_REG)))
9697               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9698               (clobber (reg:SI PR_REG))
9699               (clobber (reg:SI R0_REG))])]
9700   "TARGET_SH1 && ! TARGET_HARD_SH4"
9701   "jsr  @%0%#"
9702   [(set_attr "type" "sfunc")
9703    (set_attr "needs_delay_slot" "yes")])
9705 (define_insn "block_lump_real"
9706   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9707                    (mem:BLK (reg:SI R5_REG)))
9708               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9709               (use (reg:SI R6_REG))
9710               (clobber (reg:SI PR_REG))
9711               (clobber (reg:SI T_REG))
9712               (clobber (reg:SI R4_REG))
9713               (clobber (reg:SI R5_REG))
9714               (clobber (reg:SI R6_REG))
9715               (clobber (reg:SI R0_REG))])]
9716   "TARGET_SH1 && ! TARGET_HARD_SH4"
9717   "jsr  @%0%#"
9718   [(set_attr "type" "sfunc")
9719    (set_attr "needs_delay_slot" "yes")])
9721 (define_insn "block_move_real_i4"
9722   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9723                    (mem:BLK (reg:SI R5_REG)))
9724               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9725               (clobber (reg:SI PR_REG))
9726               (clobber (reg:SI R0_REG))
9727               (clobber (reg:SI R1_REG))
9728               (clobber (reg:SI R2_REG))])]
9729   "TARGET_HARD_SH4"
9730   "jsr  @%0%#"
9731   [(set_attr "type" "sfunc")
9732    (set_attr "needs_delay_slot" "yes")])
9734 (define_insn "block_lump_real_i4"
9735   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9736                    (mem:BLK (reg:SI R5_REG)))
9737               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9738               (use (reg:SI R6_REG))
9739               (clobber (reg:SI PR_REG))
9740               (clobber (reg:SI T_REG))
9741               (clobber (reg:SI R4_REG))
9742               (clobber (reg:SI R5_REG))
9743               (clobber (reg:SI R6_REG))
9744               (clobber (reg:SI R0_REG))
9745               (clobber (reg:SI R1_REG))
9746               (clobber (reg:SI R2_REG))
9747               (clobber (reg:SI R3_REG))])]
9748   "TARGET_HARD_SH4"
9749   "jsr  @%0%#"
9750   [(set_attr "type" "sfunc")
9751    (set_attr "needs_delay_slot" "yes")])
9753 ;; -------------------------------------------------------------------------
9754 ;; Floating point instructions.
9755 ;; -------------------------------------------------------------------------
9757 ;; ??? All patterns should have a type attribute.
9759 (define_expand "fpu_switch0"
9760   [(set (match_operand:SI 0 "" "") (match_dup 2))
9761    (set (match_dup 1) (mem:PSI (match_dup 0)))]
9762   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9763   "
9765   operands[1] = get_fpscr_rtx ();
9766   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9767   if (flag_pic)
9768     operands[2] = legitimize_pic_address (operands[2], SImode,
9769                                           no_new_pseudos ? operands[0] : 0);
9772 (define_expand "fpu_switch1"
9773   [(set (match_operand:SI 0 "" "") (match_dup 2))
9774    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
9775    (set (match_dup 1) (mem:PSI (match_dup 3)))]
9776   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9777   "
9779   operands[1] = get_fpscr_rtx ();
9780   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9781   if (flag_pic)
9782     operands[2] = legitimize_pic_address (operands[2], SImode,
9783                                           no_new_pseudos ? operands[0] : 0);
9784   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9787 (define_expand "movpsi"
9788   [(set (match_operand:PSI 0 "register_operand" "")
9789         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9790   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9791   "")
9793 ;; The c / m alternative is a fake to guide reload to load directly into
9794 ;; fpscr, since reload doesn't know how to use post-increment.
9795 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9796 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9797 ;; predicate after reload.
9798 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9799 ;; like a mac -> gpr move.
9800 (define_insn "fpu_switch"
9801   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9802         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9803   "TARGET_SH2E
9804    && (! reload_completed
9805        || true_regnum (operands[0]) != FPSCR_REG
9806        || GET_CODE (operands[1]) != MEM
9807        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9808   "@
9809         ! precision stays the same
9810         lds.l   %1,fpscr
9811         mov.l   %1,%0
9812         #
9813         lds     %1,fpscr
9814         mov     %1,%0
9815         mov.l   %1,%0
9816         sts     fpscr,%0
9817         sts.l   fpscr,%0"
9818   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9819    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9821 (define_split
9822   [(set (reg:PSI FPSCR_REG)
9823         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9824   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9825   [(set (match_dup 0) (match_dup 0))]
9826   "
9828   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
9829                                         gen_rtx_MEM (PSImode,
9830                                                  gen_rtx_POST_INC (Pmode,
9831                                                           operands[0]))));
9832   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9835 (define_split
9836   [(set (reg:PSI FPSCR_REG)
9837         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9838   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9839   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
9840   "
9842   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
9843                                         gen_rtx_MEM (PSImode,
9844                                                  gen_rtx_POST_INC (Pmode,
9845                                                           operands[0]))));
9846   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9849 ;; ??? This uses the fp unit, but has no type indicating that.
9850 ;; If we did that, this would either give a bogus latency or introduce
9851 ;; a bogus FIFO constraint.
9852 ;; Since this insn is currently only used for prologues/epilogues,
9853 ;; it is probably best to claim no function unit, which matches the
9854 ;; current setting.
9855 (define_insn "toggle_sz"
9856   [(set (reg:PSI FPSCR_REG)
9857         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9858   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9859   "fschg"
9860   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9862 ;; There's no way we can use it today, since optimize mode switching
9863 ;; doesn't enable us to know from which mode we're switching to the
9864 ;; mode it requests, to tell whether we can use a relative mode switch
9865 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9866 ;; memory).
9867 (define_insn "toggle_pr"
9868   [(set (reg:PSI FPSCR_REG)
9869         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9870   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9871   "fpchg"
9872   [(set_attr "type" "fp")])
9874 (define_expand "addsf3"
9875   [(set (match_operand:SF 0 "arith_reg_operand" "")
9876         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9877                  (match_operand:SF 2 "arith_reg_operand" "")))]
9878   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9879   "
9881   if (TARGET_SH2E)
9882     {
9883       expand_sf_binop (&gen_addsf3_i, operands);
9884       DONE;
9885     }
9888 (define_insn "*addsf3_media"
9889   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9890         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9891                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9892   "TARGET_SHMEDIA_FPU"
9893   "fadd.s       %1, %2, %0"
9894   [(set_attr "type" "fparith_media")])
9896 (define_insn_and_split "unary_sf_op"
9897   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9898         (vec_select:V2SF
9899          (vec_concat:V2SF
9900           (vec_select:SF
9901            (match_dup 0)
9902            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9903           (match_operator:SF 2 "unary_float_operator"
9904             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9905                             (parallel [(match_operand 4
9906                                         "const_int_operand" "n")]))]))
9907          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9908   "TARGET_SHMEDIA_FPU"
9909   "#"
9910   "TARGET_SHMEDIA_FPU && reload_completed"
9911   [(set (match_dup 5) (match_dup 6))]
9912   "
9914   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9915   rtx op1 = gen_rtx_REG (SFmode,
9916                          (true_regnum (operands[1])
9917                           + (INTVAL (operands[4]) ^ endian)));
9919   operands[7] = gen_rtx_REG (SFmode,
9920                              (true_regnum (operands[0])
9921                               + (INTVAL (operands[3]) ^ endian)));
9922   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9924   [(set_attr "type" "fparith_media")])
9926 (define_insn_and_split "binary_sf_op"
9927   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9928         (vec_select:V2SF
9929          (vec_concat:V2SF
9930           (vec_select:SF
9931            (match_dup 0)
9932            (parallel [(match_operand 7 "const_int_operand" "n")]))
9933           (match_operator:SF 3 "binary_float_operator"
9934             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9935                             (parallel [(match_operand 5
9936                                         "const_int_operand" "n")]))
9937              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9938                             (parallel [(match_operand 6
9939                                         "const_int_operand" "n")]))]))
9940          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9941   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9942   "#"
9943   "&& reload_completed"
9944   [(set (match_dup 8) (match_dup 9))]
9945   "
9947   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9948   rtx op1 = gen_rtx_REG (SFmode,
9949                          (true_regnum (operands[1])
9950                           + (INTVAL (operands[5]) ^ endian)));
9951   rtx op2 = gen_rtx_REG (SFmode,
9952                          (true_regnum (operands[2])
9953                           + (INTVAL (operands[6]) ^ endian)));
9955   operands[8] = gen_rtx_REG (SFmode,
9956                              (true_regnum (operands[0])
9957                               + (INTVAL (operands[4]) ^ endian)));
9958   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9960   [(set_attr "type" "fparith_media")])
9962 (define_insn "addsf3_i"
9963   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9964         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9965                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9966    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9967   "TARGET_SH2E"
9968   "fadd %2,%0"
9969   [(set_attr "type" "fp")
9970    (set_attr "fp_mode" "single")])
9972 (define_expand "subsf3"
9973   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9974         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9975                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9976   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9977   "
9979   if (TARGET_SH2E)
9980     {
9981       expand_sf_binop (&gen_subsf3_i, operands);
9982       DONE;
9983     }
9986 (define_insn "*subsf3_media"
9987   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9988         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9989                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9990   "TARGET_SHMEDIA_FPU"
9991   "fsub.s       %1, %2, %0"
9992   [(set_attr "type" "fparith_media")])
9994 (define_insn "subsf3_i"
9995   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9996         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9997                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9998    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9999   "TARGET_SH2E"
10000   "fsub %2,%0"
10001   [(set_attr "type" "fp")
10002    (set_attr "fp_mode" "single")])
10004 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10005 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
10006 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
10007 ;; SH3E, we use a separate insn for SH3E mulsf3.
10009 (define_expand "mulsf3"
10010   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10011         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10012                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10013   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10014   "
10016   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10017     expand_sf_binop (&gen_mulsf3_i4, operands);
10018   else if (TARGET_SH2E)
10019     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10020   if (! TARGET_SHMEDIA)
10021     DONE;
10024 (define_insn "*mulsf3_media"
10025   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10026         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10027                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10028   "TARGET_SHMEDIA_FPU"
10029   "fmul.s       %1, %2, %0"
10030   [(set_attr "type" "fparith_media")])
10032 (define_insn "mulsf3_i4"
10033   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10034         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10035                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10036    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10037   "TARGET_SH2E"
10038   "fmul %2,%0"
10039   [(set_attr "type" "fp")
10040    (set_attr "fp_mode" "single")])
10042 (define_insn "mulsf3_ie"
10043   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10044         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10045                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10046   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10047   "fmul %2,%0"
10048   [(set_attr "type" "fp")])
10050 (define_insn "mac_media"
10051   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10052         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10053                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10054                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10055   "TARGET_SHMEDIA_FPU"
10056   "fmac.s %1, %2, %0"
10057   [(set_attr "type" "fparith_media")])
10059 (define_insn "*macsf3"
10060   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10061         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10062                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10063                  (match_operand:SF 3 "arith_reg_operand" "0")))
10064    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10065   "TARGET_SH2E && ! TARGET_SH4"
10066   "fmac fr0,%2,%0"
10067   [(set_attr "type" "fp")
10068    (set_attr "fp_mode" "single")])
10070 (define_expand "divsf3"
10071   [(set (match_operand:SF 0 "arith_reg_operand" "")
10072         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10073                 (match_operand:SF 2 "arith_reg_operand" "")))]
10074   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10075   "
10077   if (TARGET_SH2E)
10078     {
10079       expand_sf_binop (&gen_divsf3_i, operands);
10080       DONE;
10081     }
10084 (define_insn "*divsf3_media"
10085   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10086         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10087                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10088   "TARGET_SHMEDIA_FPU"
10089   "fdiv.s       %1, %2, %0"
10090   [(set_attr "type" "fdiv_media")])
10092 (define_insn "divsf3_i"
10093   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10094         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10095                  (match_operand:SF 2 "arith_reg_operand" "f")))
10096    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10097   "TARGET_SH2E"
10098   "fdiv %2,%0"
10099   [(set_attr "type" "fdiv")
10100    (set_attr "fp_mode" "single")])
10102 (define_insn "floatdisf2"
10103   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10104         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10105   "TARGET_SHMEDIA_FPU"
10106   "float.qs %1, %0"
10107   [(set_attr "type" "fpconv_media")])
10109 (define_expand "floatsisf2"
10110   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10111         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10112   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10113   "
10115   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10116     {
10117       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10118       DONE;
10119     }
10122 (define_insn "*floatsisf2_media"
10123   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10124         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10125   "TARGET_SHMEDIA_FPU"
10126   "float.ls     %1, %0"
10127   [(set_attr "type" "fpconv_media")])
10129 (define_insn "floatsisf2_i4"
10130   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10131         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10132    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10133   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10134   "float        %1,%0"
10135   [(set_attr "type" "fp")
10136    (set_attr "fp_mode" "single")])
10138 (define_insn "*floatsisf2_ie"
10139   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10140         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10141   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10142   "float        %1,%0"
10143   [(set_attr "type" "fp")])
10145 (define_insn "fix_truncsfdi2"
10146   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10147         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10148   "TARGET_SHMEDIA_FPU"
10149   "ftrc.sq %1, %0"
10150   [(set_attr "type" "fpconv_media")])
10152 (define_expand "fix_truncsfsi2"
10153   [(set (match_operand:SI 0 "fpul_operand" "=y")
10154         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10155   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10156   "
10158   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10159     {
10160       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10161       DONE;
10162     }
10165 (define_insn "*fix_truncsfsi2_media"
10166   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10167         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10168   "TARGET_SHMEDIA_FPU"
10169   "ftrc.sl      %1, %0"
10170   [(set_attr "type" "fpconv_media")])
10172 (define_insn "fix_truncsfsi2_i4"
10173   [(set (match_operand:SI 0 "fpul_operand" "=y")
10174         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10175    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10176   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10177   "ftrc %1,%0"
10178   [(set_attr "type" "ftrc_s")
10179    (set_attr "fp_mode" "single")])
10181 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10182 ;; fix_truncsfsi2_i4.
10183 ;; (define_insn "fix_truncsfsi2_i4_2"
10184 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10185 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10186 ;;   (use (reg:PSI FPSCR_REG))
10187 ;;   (clobber (reg:SI FPUL_REG))]
10188 ;;  "TARGET_SH4"
10189 ;;  "#"
10190 ;;  [(set_attr "length" "4")
10191 ;;   (set_attr "fp_mode" "single")])
10193 ;;(define_split
10194 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10195 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10196 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10197 ;;   (clobber (reg:SI FPUL_REG))]
10198 ;;  "TARGET_SH4"
10199 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10200 ;;            (use (match_dup 2))])
10201 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10203 (define_insn "*fixsfsi"
10204   [(set (match_operand:SI 0 "fpul_operand" "=y")
10205         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10206   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10207   "ftrc %1,%0"
10208   [(set_attr "type" "fp")])
10210 (define_insn "cmpgtsf_t"
10211   [(set (reg:SI T_REG)
10212         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10213                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10214   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10215   "fcmp/gt      %1,%0"
10216   [(set_attr "type" "fp")
10217    (set_attr "fp_mode" "single")])
10219 (define_insn "cmpeqsf_t"
10220   [(set (reg:SI T_REG)
10221         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10222                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10223   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10224   "fcmp/eq      %1,%0"
10225   [(set_attr "type" "fp")
10226    (set_attr "fp_mode" "single")])
10228 (define_insn "ieee_ccmpeqsf_t"
10229   [(set (reg:SI T_REG)
10230         (ior:SI (reg:SI T_REG)
10231                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10232                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10233   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10234   "* return output_ieee_ccmpeq (insn, operands);"
10235   [(set_attr "length" "4")])
10238 (define_insn "cmpgtsf_t_i4"
10239   [(set (reg:SI T_REG)
10240         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10241                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10242    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10243   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10244   "fcmp/gt      %1,%0"
10245   [(set_attr "type" "fp")
10246    (set_attr "fp_mode" "single")])
10248 (define_insn "cmpeqsf_t_i4"
10249   [(set (reg:SI T_REG)
10250         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10251                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10252    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10253   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10254   "fcmp/eq      %1,%0"
10255   [(set_attr "type" "fp")
10256    (set_attr "fp_mode" "single")])
10258 (define_insn "*ieee_ccmpeqsf_t_4"
10259   [(set (reg:SI T_REG)
10260         (ior:SI (reg:SI T_REG)
10261                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10262                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10263    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10264   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10265   "* return output_ieee_ccmpeq (insn, operands);"
10266   [(set_attr "length" "4")
10267    (set_attr "fp_mode" "single")])
10269 (define_insn "cmpeqsf_media"
10270   [(set (match_operand:DI 0 "register_operand" "=r")
10271         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10272                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10273   "TARGET_SHMEDIA_FPU"
10274   "fcmpeq.s     %1, %2, %0"
10275   [(set_attr "type" "fcmp_media")])
10277 (define_insn "cmpsieqsf_media"
10278   [(set (match_operand:SI 0 "register_operand" "=r")
10279         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10280                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10281   "TARGET_SHMEDIA_FPU"
10282   "fcmpeq.s     %1, %2, %0"
10283   [(set_attr "type" "fcmp_media")])
10285 (define_insn "cmpgtsf_media"
10286   [(set (match_operand:DI 0 "register_operand" "=r")
10287         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10288                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10289   "TARGET_SHMEDIA_FPU"
10290   "fcmpgt.s     %1, %2, %0"
10291   [(set_attr "type" "fcmp_media")])
10293 (define_insn "cmpgesf_media"
10294   [(set (match_operand:DI 0 "register_operand" "=r")
10295         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10296                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10297   "TARGET_SHMEDIA_FPU"
10298   "fcmpge.s     %1, %2, %0"
10299   [(set_attr "type" "fcmp_media")])
10301 (define_insn "cmpunsf_media"
10302   [(set (match_operand:DI 0 "register_operand" "=r")
10303         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10304                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10305   "TARGET_SHMEDIA_FPU"
10306   "fcmpun.s     %1, %2, %0"
10307   [(set_attr "type" "fcmp_media")])
10309 (define_expand "cmpsf"
10310   [(set (reg:SI T_REG)
10311         (compare (match_operand:SF 0 "arith_operand" "")
10312                  (match_operand:SF 1 "arith_operand" "")))]
10313   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10314   "
10316   sh_compare_op0 = operands[0];
10317   sh_compare_op1 = operands[1];
10318   DONE;
10321 (define_expand "negsf2"
10322   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10323         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10324   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10325   "
10327   if (TARGET_SH2E)
10328     {
10329       expand_sf_unop (&gen_negsf2_i, operands);
10330       DONE;
10331     }
10334 (define_insn "*negsf2_media"
10335   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10336         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10337   "TARGET_SHMEDIA_FPU"
10338   "fneg.s       %1, %0"
10339   [(set_attr "type" "fmove_media")])
10341 (define_insn "negsf2_i"
10342   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10343         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10344    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10345   "TARGET_SH2E"
10346   "fneg %0"
10347   [(set_attr "type" "fmove")
10348    (set_attr "fp_mode" "single")])
10350 (define_expand "sqrtsf2"
10351   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10352         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10353   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10354   "
10356   if (TARGET_SH3E)
10357     {
10358       expand_sf_unop (&gen_sqrtsf2_i, operands);
10359       DONE;
10360     }
10363 (define_insn "*sqrtsf2_media"
10364   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10365         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10366   "TARGET_SHMEDIA_FPU"
10367   "fsqrt.s      %1, %0"
10368   [(set_attr "type" "fdiv_media")])
10370 (define_insn "sqrtsf2_i"
10371   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10372         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10373    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10374   "TARGET_SH3E"
10375   "fsqrt        %0"
10376   [(set_attr "type" "fdiv")
10377    (set_attr "fp_mode" "single")])
10379 (define_insn "rsqrtsf2"
10380   [(set (match_operand:SF 0 "register_operand" "=f")
10381         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10382                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10383    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10384   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10385    && operands[1] == CONST1_RTX (SFmode)"
10386   "fsrra        %0"
10387   [(set_attr "type" "fsrra")
10388    (set_attr "fp_mode" "single")])
10390 (define_insn "fsca"
10391   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10392         (vec_concat:V2SF
10393          (unspec:SF [(mult:SF
10394                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10395                       (match_operand:SF 2 "immediate_operand" "i"))
10396                     ] UNSPEC_FSINA)
10397          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10398                     ] UNSPEC_FCOSA)))
10399    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10400   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10401    && operands[2] == sh_fsca_int2sf ()"
10402   "fsca fpul,%d0"
10403   [(set_attr "type" "fsca")
10404    (set_attr "fp_mode" "single")])
10406 (define_expand "sinsf2"
10407   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10408         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10409                    UNSPEC_FSINA))]
10410   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10411   "
10413   rtx scaled = gen_reg_rtx (SFmode);
10414   rtx truncated = gen_reg_rtx (SImode);
10415   rtx fsca = gen_reg_rtx (V2SFmode);
10416   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10418   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10419   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10420   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10421                           get_fpscr_rtx ()));
10422   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10423   DONE;
10426 (define_expand "cossf2"
10427   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10428         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10429                    UNSPEC_FCOSA))]
10430   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10431   "
10433   rtx scaled = gen_reg_rtx (SFmode);
10434   rtx truncated = gen_reg_rtx (SImode);
10435   rtx fsca = gen_reg_rtx (V2SFmode);
10436   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10438   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10439   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10440   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10441                           get_fpscr_rtx ()));
10442   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10443   DONE;
10446 (define_expand "sindf2"
10447   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10448         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10449                    UNSPEC_FSINA))]
10450   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10451   "
10453   rtx scaled = gen_reg_rtx (DFmode);
10454   rtx truncated = gen_reg_rtx (SImode);
10455   rtx fsca = gen_reg_rtx (V2SFmode);
10456   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10457   rtx sfresult = gen_reg_rtx (SFmode);
10459   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10460   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10461   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10462                           get_fpscr_rtx ()));
10463   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10464   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10465   DONE;
10468 (define_expand "cosdf2"
10469   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10470         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10471                    UNSPEC_FCOSA))]
10472   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10473   "
10475   rtx scaled = gen_reg_rtx (DFmode);
10476   rtx truncated = gen_reg_rtx (SImode);
10477   rtx fsca = gen_reg_rtx (V2SFmode);
10478   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10479   rtx sfresult = gen_reg_rtx (SFmode);
10481   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10482   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10483   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10484                           get_fpscr_rtx ()));
10485   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10486   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10487   DONE;
10490 (define_expand "abssf2"
10491   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10492         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10493   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10494   "
10496   if (TARGET_SH2E)
10497     {
10498       expand_sf_unop (&gen_abssf2_i, operands);
10499       DONE;
10500     }
10503 (define_insn "*abssf2_media"
10504   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10505         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10506   "TARGET_SHMEDIA_FPU"
10507   "fabs.s       %1, %0"
10508   [(set_attr "type" "fmove_media")])
10510 (define_insn "abssf2_i"
10511   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10512         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10513    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10514   "TARGET_SH2E"
10515   "fabs %0"
10516   [(set_attr "type" "fmove")
10517    (set_attr "fp_mode" "single")])
10519 (define_expand "adddf3"
10520   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10521         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10522                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10523   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10524   "
10526   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10527     {
10528       expand_df_binop (&gen_adddf3_i, operands);
10529       DONE;
10530     }
10533 (define_insn "*adddf3_media"
10534   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10535         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10536                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10537   "TARGET_SHMEDIA_FPU"
10538   "fadd.d       %1, %2, %0"
10539   [(set_attr "type" "dfparith_media")])
10541 (define_insn "adddf3_i"
10542   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10543         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10544                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10545    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10546   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10547   "fadd %2,%0"
10548   [(set_attr "type" "dfp_arith")
10549    (set_attr "fp_mode" "double")])
10551 (define_expand "subdf3"
10552   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10553         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10554                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10555   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10556   "
10558   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10559     {
10560       expand_df_binop (&gen_subdf3_i, operands);
10561       DONE;
10562     }
10565 (define_insn "*subdf3_media"
10566   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10567         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10568                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10569   "TARGET_SHMEDIA_FPU"
10570   "fsub.d       %1, %2, %0"
10571   [(set_attr "type" "dfparith_media")])
10573 (define_insn "subdf3_i"
10574   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10575         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10576                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10577    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10578   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10579   "fsub %2,%0"
10580   [(set_attr "type" "dfp_arith")
10581    (set_attr "fp_mode" "double")])
10583 (define_expand "muldf3"
10584   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10585         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10586                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10587   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10588   "
10590   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10591     {
10592       expand_df_binop (&gen_muldf3_i, operands);
10593       DONE;
10594     }
10597 (define_insn "*muldf3_media"
10598   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10599         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10600                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10601   "TARGET_SHMEDIA_FPU"
10602   "fmul.d       %1, %2, %0"
10603   [(set_attr "type" "dfmul_media")])
10605 (define_insn "muldf3_i"
10606   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10607         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10608                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10609    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10610   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10611   "fmul %2,%0"
10612   [(set_attr "type" "dfp_arith")
10613    (set_attr "fp_mode" "double")])
10615 (define_expand "divdf3"
10616   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10617         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10618                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10619   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10620   "
10622   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10623     {
10624       expand_df_binop (&gen_divdf3_i, operands);
10625       DONE;
10626     }
10629 (define_insn "*divdf3_media"
10630   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10631         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10632                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10633   "TARGET_SHMEDIA_FPU"
10634   "fdiv.d       %1, %2, %0"
10635   [(set_attr "type" "dfdiv_media")])
10637 (define_insn "divdf3_i"
10638   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10639         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10640                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10641    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10642   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10643   "fdiv %2,%0"
10644   [(set_attr "type" "dfdiv")
10645    (set_attr "fp_mode" "double")])
10647 (define_insn "floatdidf2"
10648   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10649         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10650   "TARGET_SHMEDIA_FPU"
10651   "float.qd     %1, %0"
10652   [(set_attr "type" "dfpconv_media")])
10654 (define_expand "floatsidf2"
10655   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10656         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10657   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10658   "
10660   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10661     {
10662       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10663                                       get_fpscr_rtx ()));
10664       DONE;
10665     }
10668 (define_insn "*floatsidf2_media"
10669   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10670         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10671   "TARGET_SHMEDIA_FPU"
10672   "float.ld     %1, %0"
10673   [(set_attr "type" "dfpconv_media")])
10675 (define_insn "floatsidf2_i"
10676   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10677         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10678    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10679   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10680   "float        %1,%0"
10681   [(set_attr "type" "dfp_conv")
10682    (set_attr "fp_mode" "double")])
10684 (define_insn "fix_truncdfdi2"
10685   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10686         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10687   "TARGET_SHMEDIA_FPU"
10688   "ftrc.dq      %1, %0"
10689   [(set_attr "type" "dfpconv_media")])
10691 (define_expand "fix_truncdfsi2"
10692   [(set (match_operand:SI 0 "fpul_operand" "")
10693         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10694   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10695   "
10697   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10698     {
10699       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10700                                           get_fpscr_rtx ()));
10701       DONE;
10702     }
10705 (define_insn "*fix_truncdfsi2_media"
10706   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10707         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10708   "TARGET_SHMEDIA_FPU"
10709   "ftrc.dl      %1, %0"
10710   [(set_attr "type" "dfpconv_media")])
10712 (define_insn "fix_truncdfsi2_i"
10713   [(set (match_operand:SI 0 "fpul_operand" "=y")
10714         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10715    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10716   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10717   "ftrc %1,%0"
10718   [(set_attr "type" "dfp_conv")
10719    (set_attr "dfp_comp" "no")
10720    (set_attr "fp_mode" "double")])
10722 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10723 ;; fix_truncdfsi2_i.
10724 ;; (define_insn "fix_truncdfsi2_i4"
10725 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10726 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10727 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10728 ;;    (clobber (reg:SI FPUL_REG))]
10729 ;;   "TARGET_SH4"
10730 ;;   "#"
10731 ;;   [(set_attr "length" "4")
10732 ;;    (set_attr "fp_mode" "double")])
10734 ;; (define_split
10735 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10736 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10737 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10738 ;;    (clobber (reg:SI FPUL_REG))]
10739 ;;   "TARGET_SH4"
10740 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10741 ;;            (use (match_dup 2))])
10742 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10744 (define_insn "cmpgtdf_t"
10745   [(set (reg:SI T_REG)
10746         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10747                (match_operand:DF 1 "arith_reg_operand" "f")))
10748    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10749   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10750   "fcmp/gt      %1,%0"
10751   [(set_attr "type" "dfp_cmp")
10752    (set_attr "fp_mode" "double")])
10754 (define_insn "cmpeqdf_t"
10755   [(set (reg:SI T_REG)
10756         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10757                (match_operand:DF 1 "arith_reg_operand" "f")))
10758    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10759   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10760   "fcmp/eq      %1,%0"
10761   [(set_attr "type" "dfp_cmp")
10762    (set_attr "fp_mode" "double")])
10764 (define_insn "*ieee_ccmpeqdf_t"
10765   [(set (reg:SI T_REG)
10766         (ior:SI (reg:SI T_REG)
10767                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10768                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10769    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10770   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10771   "* return output_ieee_ccmpeq (insn, operands);"
10772   [(set_attr "length" "4")
10773    (set_attr "fp_mode" "double")])
10775 (define_insn "cmpeqdf_media"
10776   [(set (match_operand:DI 0 "register_operand" "=r")
10777         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10778                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10779   "TARGET_SHMEDIA_FPU"
10780   "fcmpeq.d     %1,%2,%0"
10781   [(set_attr "type" "fcmp_media")])
10783 (define_insn "cmpsieqdf_media"
10784   [(set (match_operand:SI 0 "register_operand" "=r")
10785         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10786                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10787   "TARGET_SHMEDIA_FPU"
10788   "fcmpeq.d     %1,%2,%0"
10789   [(set_attr "type" "fcmp_media")])
10791 (define_insn "cmpgtdf_media"
10792   [(set (match_operand:DI 0 "register_operand" "=r")
10793         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10794                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10795   "TARGET_SHMEDIA_FPU"
10796   "fcmpgt.d     %1,%2,%0"
10797   [(set_attr "type" "fcmp_media")])
10799 (define_insn "cmpgedf_media"
10800   [(set (match_operand:DI 0 "register_operand" "=r")
10801         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10802                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10803   "TARGET_SHMEDIA_FPU"
10804   "fcmpge.d     %1,%2,%0"
10805   [(set_attr "type" "fcmp_media")])
10807 (define_insn "cmpundf_media"
10808   [(set (match_operand:DI 0 "register_operand" "=r")
10809         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10810                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10811   "TARGET_SHMEDIA_FPU"
10812   "fcmpun.d     %1,%2,%0"
10813   [(set_attr "type" "fcmp_media")])
10815 (define_expand "cmpdf"
10816   [(set (reg:SI T_REG)
10817         (compare (match_operand:DF 0 "arith_operand" "")
10818                  (match_operand:DF 1 "arith_operand" "")))]
10819   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10820   "
10822   sh_compare_op0 = operands[0];
10823   sh_compare_op1 = operands[1];
10824   DONE;
10827 (define_expand "negdf2"
10828   [(set (match_operand:DF 0 "arith_reg_operand" "")
10829         (neg: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_negdf2_i, operands);
10836       DONE;
10837     }
10840 (define_insn "*negdf2_media"
10841   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10842         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10843   "TARGET_SHMEDIA_FPU"
10844   "fneg.d       %1, %0"
10845   [(set_attr "type" "fmove_media")])
10847 (define_insn "negdf2_i"
10848   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10849         (neg: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   "fneg %0"
10853   [(set_attr "type" "fmove")
10854    (set_attr "fp_mode" "double")])
10856 (define_expand "sqrtdf2"
10857   [(set (match_operand:DF 0 "arith_reg_operand" "")
10858         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10859   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10860   "
10862   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10863     {
10864       expand_df_unop (&gen_sqrtdf2_i, operands);
10865       DONE;
10866     }
10869 (define_insn "*sqrtdf2_media"
10870   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10871         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10872   "TARGET_SHMEDIA_FPU"
10873   "fsqrt.d      %1, %0"
10874   [(set_attr "type" "dfdiv_media")])
10876 (define_insn "sqrtdf2_i"
10877   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10878         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10879    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10880   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10881   "fsqrt        %0"
10882   [(set_attr "type" "dfdiv")
10883    (set_attr "fp_mode" "double")])
10885 (define_expand "absdf2"
10886   [(set (match_operand:DF 0 "arith_reg_operand" "")
10887         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10888   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10889   "
10891   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10892     {
10893       expand_df_unop (&gen_absdf2_i, operands);
10894       DONE;
10895     }
10898 (define_insn "*absdf2_media"
10899   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10900         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10901   "TARGET_SHMEDIA_FPU"
10902   "fabs.d       %1, %0"
10903   [(set_attr "type" "fmove_media")])
10905 (define_insn "absdf2_i"
10906   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10907         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10908    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10909   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10910   "fabs %0"
10911   [(set_attr "type" "fmove")
10912    (set_attr "fp_mode" "double")])
10914 (define_expand "extendsfdf2"
10915   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10916         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10917   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10918   "
10920   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10921     {
10922       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10923                                         get_fpscr_rtx ()));
10924       DONE;
10925     }
10928 (define_insn "*extendsfdf2_media"
10929   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10930         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10931   "TARGET_SHMEDIA_FPU"
10932   "fcnv.sd      %1, %0"
10933   [(set_attr "type" "dfpconv_media")])
10935 (define_insn "extendsfdf2_i4"
10936   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10937         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10938    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10939   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10940   "fcnvsd  %1,%0"
10941   [(set_attr "type" "fp")
10942    (set_attr "fp_mode" "double")])
10944 (define_expand "truncdfsf2"
10945   [(set (match_operand:SF 0 "fpul_operand" "")
10946         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10947   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10948   "
10950   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10951     {
10952       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10953                                        get_fpscr_rtx ()));
10954       DONE;
10955     }
10958 (define_insn "*truncdfsf2_media"
10959   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10960         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10961   "TARGET_SHMEDIA_FPU"
10962   "fcnv.ds      %1, %0"
10963   [(set_attr "type" "dfpconv_media")])
10965 (define_insn "truncdfsf2_i4"
10966   [(set (match_operand:SF 0 "fpul_operand" "=y")
10967         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10968    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10969   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10970   "fcnvds  %1,%0"
10971   [(set_attr "type" "fp")
10972    (set_attr "fp_mode" "double")])
10974 ;; Bit field extract patterns.  These give better code for packed bitfields,
10975 ;; because they allow auto-increment addresses to be generated.
10977 (define_expand "insv"
10978   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10979                          (match_operand:SI 1 "immediate_operand" "")
10980                          (match_operand:SI 2 "immediate_operand" ""))
10981         (match_operand:SI 3 "general_operand" ""))]
10982   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10983   "
10985   rtx addr_target, orig_address, shift_reg, qi_val;
10986   HOST_WIDE_INT bitsize, size, v = 0;
10987   rtx x = operands[3];
10989   /* ??? expmed doesn't care for non-register predicates.  */
10990   if (! memory_operand (operands[0], VOIDmode)
10991       || ! immediate_operand (operands[1], VOIDmode)
10992       || ! immediate_operand (operands[2], VOIDmode)
10993       || ! general_operand (x, VOIDmode))
10994     FAIL;
10995   /* If this isn't a 16 / 24 / 32 bit field, or if
10996      it doesn't start on a byte boundary, then fail.  */
10997   bitsize = INTVAL (operands[1]);
10998   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
10999       || (INTVAL (operands[2]) % 8) != 0)
11000     FAIL;
11002   size = bitsize / 8;
11003   orig_address = XEXP (operands[0], 0);
11004   shift_reg = gen_reg_rtx (SImode);
11005   if (GET_CODE (x) == CONST_INT)
11006     {
11007       v = INTVAL (x);
11008       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11009     }
11010   else
11011     {
11012       emit_insn (gen_movsi (shift_reg, operands[3]));
11013       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11014     }
11015   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11017   operands[0] = replace_equiv_address (operands[0], addr_target);
11018   emit_insn (gen_movqi (operands[0], qi_val));
11020   while (size -= 1)
11021     {
11022       if (GET_CODE (x) == CONST_INT)
11023         qi_val
11024           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11025       else
11026         {
11027           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11028           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11029         }
11030       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11031       emit_insn (gen_movqi (operands[0], qi_val));
11032     }
11034   DONE;
11037 (define_insn "movua"
11038   [(set (match_operand:SI 0 "register_operand" "=z")
11039         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11040                          (const_int 32) (const_int 0)))]
11041   "TARGET_SH4A_ARCH"
11042   "movua.l      %1,%0"
11043   [(set_attr "type" "movua")])
11045 ;; We shouldn't need this, but cse replaces increments with references
11046 ;; to other regs before flow has a chance to create post_inc
11047 ;; addressing modes, and only postreload's cse_move2add brings the
11048 ;; increments back to a usable form.
11049 (define_peephole2
11050   [(set (match_operand:SI 0 "register_operand" "")
11051         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11052                          (const_int 32) (const_int 0)))
11053    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11054   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11055   [(set (match_operand:SI 0 "register_operand" "")
11056         (sign_extract:SI (mem:SI (post_inc:SI
11057                                   (match_operand:SI 1 "register_operand" "")))
11058                          (const_int 32) (const_int 0)))]
11059   "")
11061 (define_expand "extv"
11062   [(set (match_operand:SI 0 "register_operand" "")
11063         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11064                          (match_operand 2 "const_int_operand" "")
11065                          (match_operand 3 "const_int_operand" "")))]
11066   "TARGET_SH4A_ARCH"
11068   if (TARGET_SH4A_ARCH
11069       && INTVAL (operands[2]) == 32
11070       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11071       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11072     {
11073       emit_insn (gen_movua (operands[0],
11074                             adjust_address (operands[1], SImode, 0)));
11075       DONE;
11076     }
11078   FAIL;
11081 (define_expand "extzv"
11082   [(set (match_operand:SI 0 "register_operand" "")
11083         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11084                          (match_operand 2 "const_int_operand" "")
11085                          (match_operand 3 "const_int_operand" "")))]
11086   "TARGET_SH4A_ARCH"
11088   if (TARGET_SH4A_ARCH
11089       && INTVAL (operands[2]) == 32
11090       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11091       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11092     {
11093       emit_insn (gen_movua (operands[0],
11094                             adjust_address (operands[1], SImode, 0)));
11095       DONE;
11096     }
11098   FAIL;
11102 ;; -------------------------------------------------------------------------
11103 ;; Peepholes
11104 ;; -------------------------------------------------------------------------
11106 ;; This matches cases where a stack pointer increment at the start of the
11107 ;; epilogue combines with a stack slot read loading the return value.
11109 (define_peephole
11110   [(set (match_operand:SI 0 "arith_reg_operand" "")
11111         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11112    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11113   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11114   "mov.l        @%1+,%0")
11116 ;; See the comment on the dt combiner pattern above.
11118 (define_peephole
11119   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11120         (plus:SI (match_dup 0)
11121                  (const_int -1)))
11122    (set (reg:SI T_REG)
11123         (eq:SI (match_dup 0)
11124                (const_int 0)))]
11125   "TARGET_SH2"
11126   "dt   %0")
11128 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11129 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11130 ;; reload when the constant is too large for a reg+offset address.
11132 ;; ??? We would get much better code if this was done in reload.  This would
11133 ;; require modifying find_reloads_address to recognize that if the constant
11134 ;; is out-of-range for an immediate add, then we get better code by reloading
11135 ;; the constant into a register than by reloading the sum into a register,
11136 ;; since the former is one instruction shorter if the address does not need
11137 ;; to be offsettable.  Unfortunately this does not work, because there is
11138 ;; only one register, r0, that can be used as an index register.  This register
11139 ;; is also the function return value register.  So, if we try to force reload
11140 ;; to use double-reg addresses, then we end up with some instructions that
11141 ;; need to use r0 twice.  The only way to fix this is to change the calling
11142 ;; convention so that r0 is not used to return values.
11144 (define_peephole
11145   [(set (match_operand:SI 0 "register_operand" "=r")
11146         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11147    (set (mem:SI (match_dup 0))
11148         (match_operand:SI 2 "general_movsrc_operand" ""))]
11149   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11150   "mov.l        %2,@(%0,%1)")
11152 (define_peephole
11153   [(set (match_operand:SI 0 "register_operand" "=r")
11154         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11155    (set (match_operand:SI 2 "general_movdst_operand" "")
11156         (mem:SI (match_dup 0)))]
11157   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11158   "mov.l        @(%0,%1),%2")
11160 (define_peephole
11161   [(set (match_operand:SI 0 "register_operand" "=r")
11162         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11163    (set (mem:HI (match_dup 0))
11164         (match_operand:HI 2 "general_movsrc_operand" ""))]
11165   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11166   "mov.w        %2,@(%0,%1)")
11168 (define_peephole
11169   [(set (match_operand:SI 0 "register_operand" "=r")
11170         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11171    (set (match_operand:HI 2 "general_movdst_operand" "")
11172         (mem:HI (match_dup 0)))]
11173   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11174   "mov.w        @(%0,%1),%2")
11176 (define_peephole
11177   [(set (match_operand:SI 0 "register_operand" "=r")
11178         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11179    (set (mem:QI (match_dup 0))
11180         (match_operand:QI 2 "general_movsrc_operand" ""))]
11181   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11182   "mov.b        %2,@(%0,%1)")
11184 (define_peephole
11185   [(set (match_operand:SI 0 "register_operand" "=r")
11186         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11187    (set (match_operand:QI 2 "general_movdst_operand" "")
11188         (mem:QI (match_dup 0)))]
11189   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11190   "mov.b        @(%0,%1),%2")
11192 (define_peephole
11193   [(set (match_operand:SI 0 "register_operand" "=r")
11194         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11195    (set (mem:SF (match_dup 0))
11196         (match_operand:SF 2 "general_movsrc_operand" ""))]
11197   "TARGET_SH1 && REGNO (operands[0]) == 0
11198    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11199        || (GET_CODE (operands[2]) == SUBREG
11200            && REGNO (SUBREG_REG (operands[2])) < 16))
11201    && reg_unused_after (operands[0], insn)"
11202   "mov.l        %2,@(%0,%1)")
11204 (define_peephole
11205   [(set (match_operand:SI 0 "register_operand" "=r")
11206         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11207    (set (match_operand:SF 2 "general_movdst_operand" "")
11209         (mem:SF (match_dup 0)))]
11210   "TARGET_SH1 && REGNO (operands[0]) == 0
11211    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11212        || (GET_CODE (operands[2]) == SUBREG
11213            && REGNO (SUBREG_REG (operands[2])) < 16))
11214    && reg_unused_after (operands[0], insn)"
11215   "mov.l        @(%0,%1),%2")
11217 (define_peephole
11218   [(set (match_operand:SI 0 "register_operand" "=r")
11219         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11220    (set (mem:SF (match_dup 0))
11221         (match_operand:SF 2 "general_movsrc_operand" ""))]
11222   "TARGET_SH2E && REGNO (operands[0]) == 0
11223    && ((GET_CODE (operands[2]) == REG
11224         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11225        || (GET_CODE (operands[2]) == SUBREG
11226            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11227    && reg_unused_after (operands[0], insn)"
11228   "fmov{.s|}    %2,@(%0,%1)")
11230 (define_peephole
11231   [(set (match_operand:SI 0 "register_operand" "=r")
11232         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11233    (set (match_operand:SF 2 "general_movdst_operand" "")
11235         (mem:SF (match_dup 0)))]
11236   "TARGET_SH2E && REGNO (operands[0]) == 0
11237    && ((GET_CODE (operands[2]) == REG
11238         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11239        || (GET_CODE (operands[2]) == SUBREG
11240            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11241    && reg_unused_after (operands[0], insn)"
11242   "fmov{.s|}    @(%0,%1),%2")
11244 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11245 (define_insn "sp_switch_1"
11246   [(const_int 1)]
11247   "TARGET_SH1"
11248   "*
11250   rtx xoperands[1];
11252   xoperands[0] = sp_switch;
11253   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
11254   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
11255   return \"mov r0,r15\";
11257   [(set_attr "length" "10")])
11259 ;; Switch back to the original stack for interrupt functions with the
11260 ;; sp_switch attribute.  */
11261 (define_insn "sp_switch_2"
11262   [(const_int 2)]
11263   "TARGET_SH1"
11264   "mov.l @r15+,r15\;mov.l @r15+,r0"
11265   [(set_attr "length" "4")])
11267 ;; Integer vector moves
11269 (define_expand "movv8qi"
11270   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11271         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11272   "TARGET_SHMEDIA"
11273   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11275 (define_insn "movv8qi_i"
11276   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11277         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11278   "TARGET_SHMEDIA
11279    && (register_operand (operands[0], V8QImode)
11280        || sh_register_operand (operands[1], V8QImode))"
11281   "@
11282         add     %1, r63, %0
11283         movi    %1, %0
11284         #
11285         ld%M1.q %m1, %0
11286         st%M0.q %m0, %N1"
11287   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11288    (set_attr "length" "4,4,16,4,4")])
11290 (define_split
11291   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11292         (subreg:V8QI (const_int 0) 0))]
11293   "TARGET_SHMEDIA"
11294   [(set (match_dup 0)
11295         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11296                             (const_int 0) (const_int 0) (const_int 0)
11297                             (const_int 0) (const_int 0)]))])
11299 (define_split
11300   [(set (match_operand 0 "arith_reg_dest" "")
11301         (match_operand 1 "sh_rep_vec" ""))]
11302   "TARGET_SHMEDIA && reload_completed
11303    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11304    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11305    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11306    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11307        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11308    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11309        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11310   [(set (match_dup 0) (match_dup 1))
11311    (match_dup 2)]
11312   "
11314   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11315   rtx elt1 = XVECEXP (operands[1], 0, 1);
11317   if (unit_size > 2)
11318     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11319   else
11320     {
11321       if (unit_size < 2)
11322         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11323       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11324     }
11325   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11326   operands[1] = XVECEXP (operands[1], 0, 0);
11327   if (unit_size < 2)
11328     {
11329       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11330         operands[1]
11331           = GEN_INT (TARGET_LITTLE_ENDIAN
11332                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11333                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11334       else
11335         {
11336           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11337           operands[1]
11338             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11339         }
11340     }
11343 (define_split
11344   [(set (match_operand 0 "arith_reg_dest" "")
11345         (match_operand 1 "sh_const_vec" ""))]
11346   "TARGET_SHMEDIA && reload_completed
11347    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11348    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11349   [(set (match_dup 0) (match_dup 1))]
11350   "
11352   rtx v = operands[1];
11353   enum machine_mode new_mode
11354     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11356   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11357   operands[1]
11358     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11361 (define_expand "movv2hi"
11362   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11363         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11364   "TARGET_SHMEDIA"
11365   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11367 (define_insn "movv2hi_i"
11368   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11369         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11370   "TARGET_SHMEDIA
11371    && (register_operand (operands[0], V2HImode)
11372        || sh_register_operand (operands[1], V2HImode))"
11373   "@
11374         add.l   %1, r63, %0
11375         movi    %1, %0
11376         #
11377         ld%M1.l %m1, %0
11378         st%M0.l %m0, %N1"
11379   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11380    (set_attr "length" "4,4,16,4,4")
11381    (set (attr "highpart")
11382         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11383                (const_string "user")]
11384               (const_string "ignore")))])
11386 (define_expand "movv4hi"
11387   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11388         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11389   "TARGET_SHMEDIA"
11390   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11392 (define_insn "movv4hi_i"
11393   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11394         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11395   "TARGET_SHMEDIA
11396    && (register_operand (operands[0], V4HImode)
11397        || sh_register_operand (operands[1], V4HImode))"
11398   "@
11399         add     %1, r63, %0
11400         movi    %1, %0
11401         #
11402         ld%M1.q %m1, %0
11403         st%M0.q %m0, %N1"
11404   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11405    (set_attr "length" "4,4,16,4,4")
11406    (set_attr "highpart" "depend")])
11408 (define_expand "movv2si"
11409   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11410         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11411   "TARGET_SHMEDIA"
11412   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11414 (define_insn "movv2si_i"
11415   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11416         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11417   "TARGET_SHMEDIA
11418    && (register_operand (operands[0], V2SImode)
11419        || sh_register_operand (operands[1], V2SImode))"
11420   "@
11421         add     %1, r63, %0
11422         #
11423         #
11424         ld%M1.q %m1, %0
11425         st%M0.q %m0, %N1"
11426   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11427    (set_attr "length" "4,4,16,4,4")
11428    (set_attr "highpart" "depend")])
11430 ;; Multimedia Intrinsics
11432 (define_insn "absv2si2"
11433   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11434         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11435   "TARGET_SHMEDIA"
11436   "mabs.l       %1, %0"
11437   [(set_attr "type" "mcmp_media")
11438    (set_attr "highpart" "depend")])
11440 (define_insn "absv4hi2"
11441   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11442         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11443   "TARGET_SHMEDIA"
11444   "mabs.w       %1, %0"
11445   [(set_attr "type" "mcmp_media")
11446    (set_attr "highpart" "depend")])
11448 (define_insn "addv2si3"
11449   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11450         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11451                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11452   "TARGET_SHMEDIA"
11453   "madd.l       %1, %2, %0"
11454   [(set_attr "type" "arith_media")
11455    (set_attr "highpart" "depend")])
11457 (define_insn "addv4hi3"
11458   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11459         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11460                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11461   "TARGET_SHMEDIA"
11462   "madd.w       %1, %2, %0"
11463   [(set_attr "type" "arith_media")
11464    (set_attr "highpart" "depend")])
11466 (define_insn_and_split "addv2hi3"
11467   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11468         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11469                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11470   "TARGET_SHMEDIA"
11471   "#"
11472   "TARGET_SHMEDIA"
11473   [(const_int 0)]
11474   "
11476   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11477   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11478   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11479   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11480   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11482   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11483   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11484   DONE;
11486   [(set_attr "highpart" "must_split")])
11488 (define_insn "ssaddv2si3"
11489   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11490         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11491                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11492   "TARGET_SHMEDIA"
11493   "madds.l      %1, %2, %0"
11494   [(set_attr "type" "mcmp_media")
11495    (set_attr "highpart" "depend")])
11497 (define_insn "usaddv8qi3"
11498   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11499         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11500                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11501   "TARGET_SHMEDIA"
11502   "madds.ub     %1, %2, %0"
11503   [(set_attr "type" "mcmp_media")
11504    (set_attr "highpart" "depend")])
11506 (define_insn "ssaddv4hi3"
11507   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11508         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11509                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11510   "TARGET_SHMEDIA"
11511   "madds.w      %1, %2, %0"
11512   [(set_attr "type" "mcmp_media")
11513    (set_attr "highpart" "depend")])
11515 (define_insn "negcmpeqv8qi"
11516   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11517         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11518                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11519   "TARGET_SHMEDIA"
11520   "mcmpeq.b     %N1, %N2, %0"
11521   [(set_attr "type" "mcmp_media")
11522    (set_attr "highpart" "depend")])
11524 (define_insn "negcmpeqv2si"
11525   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11526         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11527                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11528   "TARGET_SHMEDIA"
11529   "mcmpeq.l     %N1, %N2, %0"
11530   [(set_attr "type" "mcmp_media")
11531    (set_attr "highpart" "depend")])
11533 (define_insn "negcmpeqv4hi"
11534   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11535         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11536                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11537   "TARGET_SHMEDIA"
11538   "mcmpeq.w     %N1, %N2, %0"
11539   [(set_attr "type" "mcmp_media")
11540    (set_attr "highpart" "depend")])
11542 (define_insn "negcmpgtuv8qi"
11543   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11544         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11545                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11546   "TARGET_SHMEDIA"
11547   "mcmpgt.ub    %N1, %N2, %0"
11548   [(set_attr "type" "mcmp_media")
11549    (set_attr "highpart" "depend")])
11551 (define_insn "negcmpgtv2si"
11552   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11553         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11554                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11555   "TARGET_SHMEDIA"
11556   "mcmpgt.l     %N1, %N2, %0"
11557   [(set_attr "type" "mcmp_media")
11558    (set_attr "highpart" "depend")])
11560 (define_insn "negcmpgtv4hi"
11561   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11562         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11563                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11564   "TARGET_SHMEDIA"
11565   "mcmpgt.w     %N1, %N2, %0"
11566   [(set_attr "type" "mcmp_media")
11567    (set_attr "highpart" "depend")])
11569 (define_insn "mcmv"
11570   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11571         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11572                         (match_operand:DI 2 "arith_reg_operand" "r"))
11573                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11574                         (not:DI (match_dup 2)))))]
11575   "TARGET_SHMEDIA"
11576   "mcmv %N1, %2, %0"
11577   [(set_attr "type" "arith_media")
11578    (set_attr "highpart" "depend")])
11580 (define_insn "mcnvs_lw"
11581   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11582         (vec_concat:V4HI
11583          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11584          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11585   "TARGET_SHMEDIA"
11586   "mcnvs.lw     %N1, %N2, %0"
11587   [(set_attr "type" "mcmp_media")])
11589 (define_insn "mcnvs_wb"
11590   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11591         (vec_concat:V8QI
11592          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11593          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11594   "TARGET_SHMEDIA"
11595   "mcnvs.wb     %N1, %N2, %0"
11596   [(set_attr "type" "mcmp_media")])
11598 (define_insn "mcnvs_wub"
11599   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11600         (vec_concat:V8QI
11601          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11602          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11603   "TARGET_SHMEDIA"
11604   "mcnvs.wub    %N1, %N2, %0"
11605   [(set_attr "type" "mcmp_media")])
11607 (define_insn "mextr_rl"
11608   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11609         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11610                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11611                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11612                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11613   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11614   "*
11616   static char templ[21];
11618   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11619            (int) INTVAL (operands[3]) >> 3);
11620   return templ;
11622   [(set_attr "type" "arith_media")])
11624 (define_insn "*mextr_lr"
11625   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11626         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11627                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11628                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11629                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11630   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11631   "*
11633   static char templ[21];
11635   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11636            (int) INTVAL (operands[4]) >> 3);
11637   return templ;
11639   [(set_attr "type" "arith_media")])
11641 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11642 ; vector then varies depending on endianness.
11643 (define_expand "mextr1"
11644   [(match_operand:DI 0 "arith_reg_dest" "")
11645    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11646    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11647   "TARGET_SHMEDIA"
11648   "
11650   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11651                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11652   DONE;
11655 (define_expand "mextr2"
11656   [(match_operand:DI 0 "arith_reg_dest" "")
11657    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11658    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11659   "TARGET_SHMEDIA"
11660   "
11662   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11663                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11664   DONE;
11667 (define_expand "mextr3"
11668   [(match_operand:DI 0 "arith_reg_dest" "")
11669    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11670    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11671   "TARGET_SHMEDIA"
11672   "
11674   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11675                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11676   DONE;
11679 (define_expand "mextr4"
11680   [(match_operand:DI 0 "arith_reg_dest" "")
11681    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11682    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11683   "TARGET_SHMEDIA"
11684   "
11686   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11687                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11688   DONE;
11691 (define_expand "mextr5"
11692   [(match_operand:DI 0 "arith_reg_dest" "")
11693    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11694    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11695   "TARGET_SHMEDIA"
11696   "
11698   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11699                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11700   DONE;
11703 (define_expand "mextr6"
11704   [(match_operand:DI 0 "arith_reg_dest" "")
11705    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11706    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11707   "TARGET_SHMEDIA"
11708   "
11710   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11711                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11712   DONE;
11715 (define_expand "mextr7"
11716   [(match_operand:DI 0 "arith_reg_dest" "")
11717    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11718    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11719   "TARGET_SHMEDIA"
11720   "
11722   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11723                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11724   DONE;
11727 (define_expand "mmacfx_wl"
11728   [(match_operand:V2SI 0 "arith_reg_dest" "")
11729    (match_operand:V2HI 1 "extend_reg_operand" "")
11730    (match_operand:V2HI 2 "extend_reg_operand" "")
11731    (match_operand:V2SI 3 "arith_reg_operand" "")]
11732   "TARGET_SHMEDIA"
11733   "
11735   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11736                               operands[1], operands[2]));
11737   DONE;
11740 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11741 ;; is depend
11742 (define_insn "mmacfx_wl_i"
11743   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11744         (ss_plus:V2SI
11745          (match_operand:V2SI 1 "arith_reg_operand" "0")
11746          (ss_truncate:V2SI
11747           (ashift:V2DI
11748            (sign_extend:V2DI
11749             (mult:V2SI
11750              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11751              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11752            (const_int 1)))))]
11753   "TARGET_SHMEDIA"
11754   "mmacfx.wl    %2, %3, %0"
11755   [(set_attr "type" "mac_media")
11756    (set_attr "highpart" "depend")])
11758 (define_expand "mmacnfx_wl"
11759   [(match_operand:V2SI 0 "arith_reg_dest" "")
11760    (match_operand:V2HI 1 "extend_reg_operand" "")
11761    (match_operand:V2HI 2 "extend_reg_operand" "")
11762    (match_operand:V2SI 3 "arith_reg_operand" "")]
11763   "TARGET_SHMEDIA"
11764   "
11766   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11767                                operands[1], operands[2]));
11768   DONE;
11771 (define_insn "mmacnfx_wl_i"
11772   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11773         (ss_minus:V2SI
11774          (match_operand:V2SI 1 "arith_reg_operand" "0")
11775          (ss_truncate:V2SI
11776           (ashift:V2DI
11777            (sign_extend:V2DI
11778             (mult:V2SI
11779              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11780              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11781            (const_int 1)))))]
11782   "TARGET_SHMEDIA"
11783   "mmacnfx.wl   %2, %3, %0"
11784   [(set_attr "type" "mac_media")
11785    (set_attr "highpart" "depend")])
11787 (define_insn "mulv2si3"
11788   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11789         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11790                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11791   "TARGET_SHMEDIA"
11792   "mmul.l       %1, %2, %0"
11793   [(set_attr "type" "d2mpy_media")
11794    (set_attr "highpart" "depend")])
11796 (define_insn "mulv4hi3"
11797   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11798         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11799                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11800   "TARGET_SHMEDIA"
11801   "mmul.w       %1, %2, %0"
11802   [(set_attr "type" "dmpy_media")
11803    (set_attr "highpart" "depend")])
11805 (define_insn "mmulfx_l"
11806   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11807         (ss_truncate:V2SI
11808          (ashiftrt:V2DI
11809           (mult:V2DI
11810            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11811            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11812           (const_int 31))))]
11813   "TARGET_SHMEDIA"
11814   "mmulfx.l     %1, %2, %0"
11815   [(set_attr "type" "d2mpy_media")
11816    (set_attr "highpart" "depend")])
11818 (define_insn "mmulfx_w"
11819   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11820         (ss_truncate:V4HI
11821          (ashiftrt:V4SI
11822           (mult:V4SI
11823            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11824            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11825           (const_int 15))))]
11826   "TARGET_SHMEDIA"
11827   "mmulfx.w     %1, %2, %0"
11828   [(set_attr "type" "dmpy_media")
11829    (set_attr "highpart" "depend")])
11831 (define_insn "mmulfxrp_w"
11832   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11833         (ss_truncate:V4HI
11834          (ashiftrt:V4SI
11835           (plus:V4SI
11836            (mult:V4SI
11837             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11838             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11839            (const_int 16384))
11840           (const_int 15))))]
11841   "TARGET_SHMEDIA"
11842   "mmulfxrp.w   %1, %2, %0"
11843   [(set_attr "type" "dmpy_media")
11844    (set_attr "highpart" "depend")])
11847 (define_expand "mmulhi_wl"
11848   [(match_operand:V2SI 0 "arith_reg_dest" "")
11849    (match_operand:V4HI 1 "arith_reg_operand" "")
11850    (match_operand:V4HI 2 "arith_reg_operand" "")]
11851   "TARGET_SHMEDIA"
11852   "
11854   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11855              (operands[0], operands[1], operands[2]));
11856   DONE;
11859 (define_expand "mmullo_wl"
11860   [(match_operand:V2SI 0 "arith_reg_dest" "")
11861    (match_operand:V4HI 1 "arith_reg_operand" "")
11862    (match_operand:V4HI 2 "arith_reg_operand" "")]
11863   "TARGET_SHMEDIA"
11864   "
11866   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11867              (operands[0], operands[1], operands[2]));
11868   DONE;
11871 (define_insn "mmul23_wl"
11872   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11873         (vec_select:V2SI
11874          (mult:V4SI
11875           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11876           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11877          (parallel [(const_int 2) (const_int 3)])))]
11878   "TARGET_SHMEDIA"
11879   "* return (TARGET_LITTLE_ENDIAN
11880              ? \"mmulhi.wl      %1, %2, %0\"
11881              : \"mmullo.wl      %1, %2, %0\");"
11882   [(set_attr "type" "dmpy_media")
11883    (set (attr "highpart")
11884         (cond [(eq_attr "endian" "big") (const_string "ignore")]
11885          (const_string "user")))])
11887 (define_insn "mmul01_wl"
11888   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11889         (vec_select:V2SI
11890          (mult:V4SI
11891           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11892           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11893          (parallel [(const_int 0) (const_int 1)])))]
11894   "TARGET_SHMEDIA"
11895   "* return (TARGET_LITTLE_ENDIAN
11896              ? \"mmullo.wl      %1, %2, %0\"
11897              : \"mmulhi.wl      %1, %2, %0\");"
11898   [(set_attr "type" "dmpy_media")
11899    (set (attr "highpart")
11900         (cond [(eq_attr "endian" "little") (const_string "ignore")]
11901          (const_string "user")))])
11904 (define_expand "mmulsum_wq"
11905   [(match_operand:DI 0 "arith_reg_dest" "")
11906    (match_operand:V4HI 1 "arith_reg_operand" "")
11907    (match_operand:V4HI 2 "arith_reg_operand" "")
11908    (match_operand:DI 3 "arith_reg_operand" "")]
11909   "TARGET_SHMEDIA"
11910   "
11912   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11913                                operands[1], operands[2]));
11914   DONE;
11917 (define_insn "mmulsum_wq_i"
11918   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11919         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11920          (plus:DI
11921           (plus:DI
11922            (vec_select:DI
11923             (mult:V4DI
11924              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11925              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11926             (parallel [(const_int 0)]))
11927            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11928                                      (sign_extend:V4DI (match_dup 3)))
11929                           (parallel [(const_int 1)])))
11930           (plus:DI
11931            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11932                                      (sign_extend:V4DI (match_dup 3)))
11933                           (parallel [(const_int 2)]))
11934            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11935                                      (sign_extend:V4DI (match_dup 3)))
11936                           (parallel [(const_int 3)]))))))]
11937   "TARGET_SHMEDIA"
11938   "mmulsum.wq   %2, %3, %0"
11939   [(set_attr "type" "mac_media")])
11941 (define_expand "mperm_w"
11942   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11943    (match_operand:V4HI 1 "arith_reg_operand" "r")
11944    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11945   "TARGET_SHMEDIA"
11946   "
11948   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11949              (operands[0], operands[1], operands[2]));
11950   DONE;
11953 ; This use of vec_select isn't exactly correct according to rtl.texi
11954 ; (because not constant), but it seems a straightforward extension.
11955 (define_insn "mperm_w_little"
11956   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11957         (vec_select:V4HI
11958          (match_operand:V4HI 1 "arith_reg_operand" "r")
11959          (parallel
11960           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11961                             (const_int 2) (const_int 0))
11962            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11963            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11964            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11965   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11966   "mperm.w      %1, %N2, %0"
11967   [(set_attr "type" "arith_media")])
11969 (define_insn "mperm_w_big"
11970   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11971         (vec_select:V4HI
11972          (match_operand:V4HI 1 "arith_reg_operand" "r")
11973          (parallel
11974           [(zero_extract:QI (not:QI (match_operand:QI 2
11975                                      "extend_reg_or_0_operand" "rZ"))
11976                             (const_int 2) (const_int 0))
11977            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11978            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11979            (zero_extract:QI (not:QI (match_dup 2))
11980                             (const_int 2) (const_int 6))])))]
11981   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11982   "mperm.w      %1, %N2, %0"
11983   [(set_attr "type" "arith_media")])
11985 (define_insn "mperm_w0"
11986   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11987         (vec_duplicate:V4HI (truncate:HI (match_operand 1
11988                                           "trunc_hi_operand" "r"))))]
11989   "TARGET_SHMEDIA"
11990   "mperm.w      %1, r63, %0"
11991   [(set_attr "type" "arith_media")
11992    (set_attr "highpart" "ignore")])
11994 (define_expand "msad_ubq"
11995   [(match_operand:DI 0 "arith_reg_dest" "")
11996    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
11997    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
11998    (match_operand:DI 3 "arith_reg_operand" "")]
11999   "TARGET_SHMEDIA"
12000   "
12002   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12003                              operands[1], operands[2]));
12004   DONE;
12007 (define_insn "msad_ubq_i"
12008   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12009         (plus:DI
12010          (plus:DI
12011           (plus:DI
12012            (plus:DI
12013             (match_operand:DI 1 "arith_reg_operand" "0")
12014             (abs:DI (vec_select:DI
12015                      (minus:V8DI
12016                       (zero_extend:V8DI
12017                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12018                       (zero_extend:V8DI
12019                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12020                      (parallel [(const_int 0)]))))
12021            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12022                                               (zero_extend:V8DI (match_dup 3)))
12023                                   (parallel [(const_int 1)]))))
12024           (plus:DI
12025            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12026                                               (zero_extend:V8DI (match_dup 3)))
12027                                   (parallel [(const_int 2)])))
12028            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12029                                               (zero_extend:V8DI (match_dup 3)))
12030                                   (parallel [(const_int 3)])))))
12031          (plus:DI
12032           (plus:DI
12033            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12034                                               (zero_extend:V8DI (match_dup 3)))
12035                                   (parallel [(const_int 4)])))
12036            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12037                                               (zero_extend:V8DI (match_dup 3)))
12038                                   (parallel [(const_int 5)]))))
12039           (plus:DI
12040            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12041                                               (zero_extend:V8DI (match_dup 3)))
12042                                   (parallel [(const_int 6)])))
12043            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12044                                               (zero_extend:V8DI (match_dup 3)))
12045                                   (parallel [(const_int 7)])))))))]
12046   "TARGET_SHMEDIA"
12047   "msad.ubq     %N2, %N3, %0"
12048   [(set_attr "type" "mac_media")])
12050 (define_insn "mshalds_l"
12051   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12052         (ss_truncate:V2SI
12053          (ashift:V2DI
12054           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12055           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12056                   (const_int 31)))))]
12057   "TARGET_SHMEDIA"
12058   "mshalds.l    %1, %2, %0"
12059   [(set_attr "type" "mcmp_media")
12060    (set_attr "highpart" "depend")])
12062 (define_insn "mshalds_w"
12063   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12064         (ss_truncate:V4HI
12065          (ashift:V4SI
12066           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12067           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12068                   (const_int 15)))))]
12069   "TARGET_SHMEDIA"
12070   "mshalds.w    %1, %2, %0"
12071   [(set_attr "type" "mcmp_media")
12072    (set_attr "highpart" "depend")])
12074 (define_insn "ashrv2si3"
12075   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12076         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12077                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12078   "TARGET_SHMEDIA"
12079   "mshard.l     %1, %2, %0"
12080   [(set_attr "type" "arith_media")
12081    (set_attr "highpart" "depend")])
12083 (define_insn "ashrv4hi3"
12084   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12085         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12086                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12087   "TARGET_SHMEDIA"
12088   "mshard.w     %1, %2, %0"
12089   [(set_attr "type" "arith_media")
12090    (set_attr "highpart" "depend")])
12092 (define_insn "mshards_q"
12093   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12094         (ss_truncate:HI
12095          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12096                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12097   "TARGET_SHMEDIA"
12098   "mshards.q    %1, %N2, %0"
12099   [(set_attr "type" "mcmp_media")])
12101 (define_expand "mshfhi_b"
12102   [(match_operand:V8QI 0 "arith_reg_dest" "")
12103    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12104    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12105   "TARGET_SHMEDIA"
12106   "
12108   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12109              (operands[0], operands[1], operands[2]));
12110   DONE;
12113 (define_expand "mshflo_b"
12114   [(match_operand:V8QI 0 "arith_reg_dest" "")
12115    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12116    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12117   "TARGET_SHMEDIA"
12118   "
12120   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12121              (operands[0], operands[1], operands[2]));
12122   DONE;
12125 (define_insn "mshf4_b"
12126   [(set
12127     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12128     (vec_select:V8QI
12129      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12130                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12131      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12132                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12133   "TARGET_SHMEDIA"
12134   "* return (TARGET_LITTLE_ENDIAN
12135              ? \"mshfhi.b       %N1, %N2, %0\"
12136              : \"mshflo.b       %N1, %N2, %0\");"
12137   [(set_attr "type" "arith_media")
12138    (set (attr "highpart")
12139         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12140          (const_string "user")))])
12142 (define_insn "mshf0_b"
12143   [(set
12144     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12145     (vec_select:V8QI
12146      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12147                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12148      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12149                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12150   "TARGET_SHMEDIA"
12151   "* return (TARGET_LITTLE_ENDIAN
12152              ? \"mshflo.b       %N1, %N2, %0\"
12153              : \"mshfhi.b       %N1, %N2, %0\");"
12154   [(set_attr "type" "arith_media")
12155    (set (attr "highpart")
12156         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12157          (const_string "user")))])
12159 (define_expand "mshfhi_l"
12160   [(match_operand:V2SI 0 "arith_reg_dest" "")
12161    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12162    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12163   "TARGET_SHMEDIA"
12164   "
12166   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12167              (operands[0], operands[1], operands[2]));
12168   DONE;
12171 (define_expand "mshflo_l"
12172   [(match_operand:V2SI 0 "arith_reg_dest" "")
12173    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12174    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12175   "TARGET_SHMEDIA"
12176   "
12178   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12179              (operands[0], operands[1], operands[2]));
12180   DONE;
12183 (define_insn "mshf4_l"
12184   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12185         (vec_select:V2SI
12186          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12187                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12188          (parallel [(const_int 1) (const_int 3)])))]
12189   "TARGET_SHMEDIA"
12190   "* return (TARGET_LITTLE_ENDIAN
12191              ? \"mshfhi.l       %N1, %N2, %0\"
12192              : \"mshflo.l       %N1, %N2, %0\");"
12193   [(set_attr "type" "arith_media")
12194    (set (attr "highpart")
12195         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12196          (const_string "user")))])
12198 (define_insn "mshf0_l"
12199   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12200         (vec_select:V2SI
12201          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12202                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12203          (parallel [(const_int 0) (const_int 2)])))]
12204   "TARGET_SHMEDIA"
12205   "* return (TARGET_LITTLE_ENDIAN
12206              ? \"mshflo.l       %N1, %N2, %0\"
12207              : \"mshfhi.l       %N1, %N2, %0\");"
12208   [(set_attr "type" "arith_media")
12209    (set (attr "highpart")
12210         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12211          (const_string "user")))])
12213 (define_expand "mshfhi_w"
12214   [(match_operand:V4HI 0 "arith_reg_dest" "")
12215    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12216    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12217   "TARGET_SHMEDIA"
12218   "
12220   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12221              (operands[0], operands[1], operands[2]));
12222   DONE;
12225 (define_expand "mshflo_w"
12226   [(match_operand:V4HI 0 "arith_reg_dest" "")
12227    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12228    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12229   "TARGET_SHMEDIA"
12230   "
12232   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12233              (operands[0], operands[1], operands[2]));
12234   DONE;
12237 (define_insn "mshf4_w"
12238   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12239         (vec_select:V4HI
12240          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12241                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12242          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12243   "TARGET_SHMEDIA"
12244   "* return (TARGET_LITTLE_ENDIAN
12245              ? \"mshfhi.w       %N1, %N2, %0\"
12246              : \"mshflo.w       %N1, %N2, %0\");"
12247   [(set_attr "type" "arith_media")
12248    (set (attr "highpart")
12249         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12250          (const_string "user")))])
12252 (define_insn "mshf0_w"
12253   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12254         (vec_select:V4HI
12255          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12256                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12257          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12258   "TARGET_SHMEDIA"
12259   "* return (TARGET_LITTLE_ENDIAN
12260              ? \"mshflo.w       %N1, %N2, %0\"
12261              : \"mshfhi.w       %N1, %N2, %0\");"
12262   [(set_attr "type" "arith_media")
12263    (set (attr "highpart")
12264         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12265          (const_string "user")))])
12267 (define_insn "mshflo_w_x"
12268   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12269         (vec_select:V4HI
12270          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12271                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12272          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12273   "TARGET_SHMEDIA"
12274   "mshflo.w     %N1, %N2, %0"
12275   [(set_attr "type" "arith_media")
12276    (set_attr "highpart" "ignore")])
12278 /* These are useful to expand ANDs and as combiner patterns.  */
12279 (define_insn_and_split "mshfhi_l_di"
12280   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12281         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12282                              (const_int 32))
12283                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12284                         (const_int -4294967296))))]
12285   "TARGET_SHMEDIA"
12286   "@
12287         mshfhi.l        %N1, %N2, %0
12288         #"
12289   "TARGET_SHMEDIA && reload_completed
12290    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12291   [(set (match_dup 3) (match_dup 4))
12292    (set (match_dup 5) (match_dup 6))]
12293   "
12295   operands[3] = gen_lowpart (SImode, operands[0]);
12296   operands[4] = gen_highpart (SImode, operands[1]);
12297   operands[5] = gen_highpart (SImode, operands[0]);
12298   operands[6] = gen_highpart (SImode, operands[2]);
12300   [(set_attr "type" "arith_media")])
12302 (define_insn "*mshfhi_l_di_rev"
12303   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12304         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12305                         (const_int -4294967296))
12306                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12307                              (const_int 32))))]
12308   "TARGET_SHMEDIA"
12309   "mshfhi.l     %N2, %N1, %0"
12310   [(set_attr "type" "arith_media")])
12312 (define_split
12313   [(set (match_operand:DI 0 "arith_reg_dest" "")
12314         (ior:DI (zero_extend:DI (match_operand:SI 1
12315                                               "extend_reg_or_0_operand" ""))
12316                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12317                         (const_int -4294967296))))
12318    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12319   "TARGET_SHMEDIA"
12320   [(const_int 0)]
12321   "
12323   emit_insn (gen_ashldi3_media (operands[3],
12324                                 simplify_gen_subreg (DImode, operands[1],
12325                                                      SImode, 0),
12326                                 GEN_INT (32)));
12327   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12328   DONE;
12331 (define_insn "mshflo_l_di"
12332   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12333         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12334                         (const_int 4294967295))
12335                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12336                            (const_int 32))))]
12338   "TARGET_SHMEDIA"
12339   "mshflo.l     %N1, %N2, %0"
12340   [(set_attr "type" "arith_media")
12341    (set_attr "highpart" "ignore")])
12343 (define_insn "*mshflo_l_di_rev"
12344   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12345         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12346                            (const_int 32))
12347                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12348                         (const_int 4294967295))))]
12350   "TARGET_SHMEDIA"
12351   "mshflo.l     %N2, %N1, %0"
12352   [(set_attr "type" "arith_media")
12353    (set_attr "highpart" "ignore")])
12355 ;; Combiner pattern for trampoline initialization.
12356 (define_insn_and_split "*double_shori"
12357   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12358         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12359                            (const_int 32))
12360                 (match_operand:DI 2 "const_int_operand" "n")))]
12361   "TARGET_SHMEDIA
12362    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
12363   "#"
12364   "rtx_equal_p (operands[0], operands[1])"
12365   [(const_int 0)]
12366   "
12368   HOST_WIDE_INT v = INTVAL (operands[2]);
12370   emit_insn (gen_shori_media (operands[0], operands[0],
12371              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
12372   emit_insn (gen_shori_media (operands[0], operands[0],
12373                               gen_int_mode (v, HImode)));
12374   DONE;
12376   [(set_attr "highpart" "ignore")])
12379 (define_insn "*mshflo_l_di_x"
12380   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12381         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12382                                  "rZ"))
12383                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12384                            (const_int 32))))]
12386   "TARGET_SHMEDIA"
12387   "mshflo.l     %N1, %N2, %0"
12388   [(set_attr "type" "arith_media")
12389    (set_attr "highpart" "ignore")])
12391 (define_insn_and_split "concat_v2sf"
12392   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12393 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12394         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12395                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12397   "TARGET_SHMEDIA"
12398   "@
12399         mshflo.l        %N1, %N2, %0
12400         #
12401         #"
12402   "TARGET_SHMEDIA && reload_completed
12403    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12404   [(set (match_dup 3) (match_dup 1))
12405    (set (match_dup 4) (match_dup 2))]
12406   "
12408   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12409   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12411   [(set_attr "type" "arith_media")
12412    (set_attr "highpart" "ignore")])
12414 (define_insn "*mshflo_l_di_x_rev"
12415   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12416         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12417                            (const_int 32))
12418                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12420   "TARGET_SHMEDIA"
12421   "mshflo.l     %N2, %N1, %0"
12422   [(set_attr "type" "arith_media")
12423    (set_attr "highpart" "ignore")])
12425 (define_insn "ashlv2si3"
12426   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12427         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12428                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12429   "TARGET_SHMEDIA"
12430   "mshlld.l     %1, %2, %0"
12431   [(set_attr "type" "arith_media")
12432    (set_attr "highpart" "depend")])
12434 (define_split
12435   [(set (match_operand 0 "any_register_operand" "")
12436         (match_operator 3 "shift_operator"
12437           [(match_operand 1 "any_register_operand" "")
12438            (match_operand 2 "shift_count_reg_operand" "")]))]
12439   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12440   [(set (match_dup 0) (match_dup 3))]
12441   "
12443   rtx count = operands[2];
12444   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12446   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12447          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12448          || GET_CODE (count) == TRUNCATE)
12449     count = XEXP (count, 0);
12450   inner_mode = GET_MODE (count);
12451   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12452                                subreg_lowpart_offset (outer_mode, inner_mode));
12453   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12454                                 operands[1], count);
12457 (define_insn "ashlv4hi3"
12458   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12459         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12460                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12461   "TARGET_SHMEDIA"
12462   "mshlld.w     %1, %2, %0"
12463   [(set_attr "type" "arith_media")
12464    (set_attr "highpart" "depend")])
12466 (define_insn "lshrv2si3"
12467   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12468         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12469                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12470   "TARGET_SHMEDIA"
12471   "mshlrd.l     %1, %2, %0"
12472   [(set_attr "type" "arith_media")
12473    (set_attr "highpart" "depend")])
12475 (define_insn "lshrv4hi3"
12476   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12477         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12478                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12479   "TARGET_SHMEDIA"
12480   "mshlrd.w     %1, %2, %0"
12481   [(set_attr "type" "arith_media")
12482    (set_attr "highpart" "depend")])
12484 (define_insn "subv2si3"
12485   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12486         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12487                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12488   "TARGET_SHMEDIA"
12489   "msub.l       %N1, %2, %0"
12490   [(set_attr "type" "arith_media")
12491    (set_attr "highpart" "depend")])
12493 (define_insn "subv4hi3"
12494   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12495         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12496                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12497   "TARGET_SHMEDIA"
12498   "msub.w       %N1, %2, %0"
12499   [(set_attr "type" "arith_media")
12500    (set_attr "highpart" "depend")])
12502 (define_insn_and_split "subv2hi3"
12503   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12504         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12505                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12506   "TARGET_SHMEDIA"
12507   "#"
12508   "TARGET_SHMEDIA"
12509   [(const_int 0)]
12510   "
12512   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12513   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12514   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12515   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12516   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12518   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12519   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12520   DONE;
12522   [(set_attr "highpart" "must_split")])
12524 (define_insn "sssubv2si3"
12525   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12526         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12527                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12528   "TARGET_SHMEDIA"
12529   "msubs.l      %N1, %2, %0"
12530   [(set_attr "type" "mcmp_media")
12531    (set_attr "highpart" "depend")])
12533 (define_insn "ussubv8qi3"
12534   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12535         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12536                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12537   "TARGET_SHMEDIA"
12538   "msubs.ub     %N1, %2, %0"
12539   [(set_attr "type" "mcmp_media")
12540    (set_attr "highpart" "depend")])
12542 (define_insn "sssubv4hi3"
12543   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12544         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12545                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12546   "TARGET_SHMEDIA"
12547   "msubs.w      %N1, %2, %0"
12548   [(set_attr "type" "mcmp_media")
12549    (set_attr "highpart" "depend")])
12551 ;; Floating Point Intrinsics
12553 (define_insn "fcosa_s"
12554   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12555         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12556                    UNSPEC_FCOSA))]
12557   "TARGET_SHMEDIA"
12558   "fcosa.s      %1, %0"
12559   [(set_attr "type" "atrans_media")])
12561 (define_insn "fsina_s"
12562   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12563         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12564                    UNSPEC_FSINA))]
12565   "TARGET_SHMEDIA"
12566   "fsina.s      %1, %0"
12567   [(set_attr "type" "atrans_media")])
12569 (define_insn "fipr"
12570   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12571         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12572                                                     "fp_arith_reg_operand" "f")
12573                                                    (match_operand:V4SF 2
12574                                                     "fp_arith_reg_operand" "f"))
12575                                          (parallel [(const_int 0)]))
12576                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12577                                          (parallel [(const_int 1)])))
12578                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12579                                          (parallel [(const_int 2)]))
12580                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12581                                          (parallel [(const_int 3)])))))]
12582   "TARGET_SHMEDIA"
12583   "fipr.s       %1, %2, %0"
12584   [(set_attr "type" "fparith_media")])
12586 (define_insn "fsrra_s"
12587   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12588         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12589                    UNSPEC_FSRRA))]
12590   "TARGET_SHMEDIA"
12591   "fsrra.s      %1, %0"
12592   [(set_attr "type" "atrans_media")])
12594 (define_insn "ftrv"
12595   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12596         (plus:V4SF
12597          (plus:V4SF
12598           (mult:V4SF
12599            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12600                             (parallel [(const_int 0) (const_int 5)
12601                                        (const_int 10) (const_int 15)]))
12602            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12603           (mult:V4SF
12604            (vec_select:V4SF (match_dup 1)
12605                             (parallel [(const_int 4) (const_int 9)
12606                                        (const_int 14) (const_int 3)]))
12607            (vec_select:V4SF (match_dup 2)
12608                             (parallel [(const_int 1) (const_int 2)
12609                                        (const_int 3) (const_int 0)]))))
12610          (plus:V4SF
12611           (mult:V4SF
12612            (vec_select:V4SF (match_dup 1)
12613                             (parallel [(const_int 8) (const_int 13)
12614                                        (const_int 2) (const_int 7)]))
12615            (vec_select:V4SF (match_dup 2)
12616                             (parallel [(const_int 2) (const_int 3)
12617                                        (const_int 0) (const_int 1)])))
12618           (mult:V4SF
12619            (vec_select:V4SF (match_dup 1)
12620                             (parallel [(const_int 12) (const_int 1)
12621                                        (const_int 6) (const_int 11)]))
12622            (vec_select:V4SF (match_dup 2)
12623                             (parallel [(const_int 3) (const_int 0)
12624                                        (const_int 1) (const_int 2)]))))))]
12625   "TARGET_SHMEDIA"
12626   "ftrv.s %1, %2, %0"
12627   [(set_attr "type" "fparith_media")])
12629 (define_insn "ldhi_l"
12630   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12631         (zero_extract:SI
12632          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12633                                   (const_int 3))
12634                           (const_int -3)))
12635          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12636          (const_int 0)))]
12637   "TARGET_SHMEDIA32"
12638   "ldhi.l       %U1, %0"
12639   [(set_attr "type" "load_media")])
12641 (define_insn "ldhi_q"
12642   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12643         (zero_extract:DI
12644          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12645                                   (const_int 7))
12646                           (const_int -7)))
12647          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12648          (const_int 0)))]
12649   "TARGET_SHMEDIA32"
12650   "ldhi.q       %U1, %0"
12651   [(set_attr "type" "load_media")])
12653 (define_insn_and_split "*ldhi_q_comb0"
12654   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12655         (zero_extract:DI
12656          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12657                                             "register_operand" "r")
12658                                            (match_operand:SI 2
12659                                             "ua_offset" "I06"))
12660                                   (const_int 7))
12661                           (const_int -7)))
12662          (plus:SI (and:SI (match_dup 1) (const_int 7))
12663                   (const_int 1))
12664          (const_int 0)))]
12665   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12666   "#"
12667   ""
12668   [(pc)]
12669   "emit_insn (gen_ldhi_q (operands[0],
12670                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12671    DONE;")
12674 (define_insn_and_split "*ldhi_q_comb1"
12675   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12676         (zero_extract:DI
12677          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12678                                             "register_operand" "r")
12679                                            (match_operand:SI 2
12680                                             "ua_offset" "I06"))
12681                                   (const_int 7))
12682                           (const_int -7)))
12683          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12684                                                    "ua_offset" "I06"))
12685                           (const_int 7))
12686                   (const_int 1))
12687          (const_int 0)))]
12688   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12689    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12690   "#"
12691   ""
12692   [(pc)]
12693   "emit_insn (gen_ldhi_q (operands[0],
12694                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12695    DONE;")
12698 (define_insn "ldlo_l"
12699   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12700         (zero_extract:SI
12701          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12702                          (const_int -4)))
12703          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12704          (and:SI (match_dup 1) (const_int 3))))]
12705   "TARGET_SHMEDIA32"
12706   "ldlo.l       %U1, %0"
12707   [(set_attr "type" "load_media")])
12709 (define_insn "ldlo_q"
12710   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12711         (zero_extract:DI
12712          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12713                          (const_int -8)))
12714          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12715          (and:SI (match_dup 1) (const_int 7))))]
12716   "TARGET_SHMEDIA32"
12717   "ldlo.q       %U1, %0"
12718   [(set_attr "type" "load_media")])
12720 (define_insn_and_split "*ldlo_q_comb0"
12721   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12722         (zero_extract:DI
12723          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12724                                   (match_operand:SI 2 "ua_offset" "I06"))
12725                          (const_int -8)))
12726          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12727          (and:SI (match_dup 1) (const_int 7))))]
12728   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12729   "#"
12730   ""
12731   [(pc)]
12732   "emit_insn (gen_ldlo_q (operands[0],
12733                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12734    DONE;")
12736 (define_insn_and_split "*ldlo_q_comb1"
12737   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12738         (zero_extract:DI
12739          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12740                                   (match_operand:SI 2 "ua_offset" "I06"))
12741                          (const_int -8)))
12742          (minus:SI (const_int 8)
12743                    (and:SI (plus:SI (match_dup 1)
12744                                     (match_operand:SI 3 "ua_offset" "I06"))
12745                            (const_int 7)))
12746          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12747   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12748    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12749   "#"
12750   ""
12751   [(pc)]
12752   "emit_insn (gen_ldlo_q (operands[0],
12753                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12754    DONE;")
12756 (define_insn "sthi_l"
12757   [(set (zero_extract:SI
12758          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12759                                   (const_int 3))
12760                           (const_int -3)))
12761          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12762          (const_int 0))
12763         (match_operand:SI 1 "arith_reg_operand" "r"))]
12764   "TARGET_SHMEDIA32"
12765   "sthi.l       %U0, %1"
12766   [(set_attr "type" "ustore_media")])
12768 ;; All unaligned stores are considered to be 'narrow' because they typically
12769 ;; operate on less that a quadword, and when they operate on a full quadword,
12770 ;; the vanilla store high / store low sequence will cause a stall if not
12771 ;; scheduled apart.
12772 (define_insn "sthi_q"
12773   [(set (zero_extract:DI
12774          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12775                                   (const_int 7))
12776                           (const_int -7)))
12777          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12778          (const_int 0))
12779         (match_operand:DI 1 "arith_reg_operand" "r"))]
12780   "TARGET_SHMEDIA32"
12781   "sthi.q       %U0, %1"
12782   [(set_attr "type" "ustore_media")])
12784 (define_insn_and_split "*sthi_q_comb0"
12785   [(set (zero_extract:DI
12786          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12787                                             "register_operand" "r")
12788                                            (match_operand:SI 1 "ua_offset"
12789                                             "I06"))
12790                                   (const_int 7))
12791                           (const_int -7)))
12792          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12793          (const_int 0))
12794         (match_operand:DI 2 "arith_reg_operand" "r"))]
12795   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12796   "#"
12797   ""
12798   [(pc)]
12799   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12800                           operands[2]));
12801    DONE;")
12803 (define_insn_and_split "*sthi_q_comb1"
12804   [(set (zero_extract:DI
12805          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12806                                             "register_operand" "r")
12807                                            (match_operand:SI 1 "ua_offset"
12808                                             "I06"))
12809                                   (const_int 7))
12810                           (const_int -7)))
12811          (plus:SI (and:SI (plus:SI (match_dup 0)
12812                                    (match_operand:SI 2 "ua_offset" "I06"))
12813                           (const_int 7))
12814                   (const_int 1))
12815          (const_int 0))
12816         (match_operand:DI 3 "arith_reg_operand" "r"))]
12817   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12818    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12819   "#"
12820   ""
12821   [(pc)]
12822   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12823                           operands[3]));
12824    DONE;")
12826 ;; This is highpart user because the address is used as full 64 bit.
12827 (define_insn "stlo_l"
12828   [(set (zero_extract:SI
12829          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12830                          (const_int -4)))
12831          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12832          (and:SI (match_dup 0) (const_int 3)))
12833         (match_operand:SI 1 "arith_reg_operand" "r"))]
12834   "TARGET_SHMEDIA32"
12835   "stlo.l       %U0, %1"
12836   [(set_attr "type" "ustore_media")])
12838 (define_insn "stlo_q"
12839   [(set (zero_extract:DI
12840          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12841                          (const_int -8)))
12842          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12843          (and:SI (match_dup 0) (const_int 7)))
12844         (match_operand:DI 1 "arith_reg_operand" "r"))]
12845   "TARGET_SHMEDIA32"
12846   "stlo.q       %U0, %1"
12847   [(set_attr "type" "ustore_media")])
12849 (define_insn_and_split "*stlo_q_comb0"
12850   [(set (zero_extract:DI
12851          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12852                                   (match_operand:SI 1 "ua_offset" "I06"))
12853                          (const_int -8)))
12854          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12855          (and:SI (match_dup 0) (const_int 7)))
12856         (match_operand:DI 2 "arith_reg_operand" "r"))]
12857   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12858   "#"
12859   ""
12860   [(pc)]
12861   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12862                           operands[2]));
12863    DONE;")
12865 (define_insn_and_split "*stlo_q_comb1"
12866   [(set (zero_extract:DI
12867          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12868                                   (match_operand:SI 1 "ua_offset" "I06"))
12869                          (const_int -8)))
12870          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12871                                                   (match_operand:SI 2
12872                                                    "ua_offset" "I06"))
12873                                          (const_int 7)))
12874          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12875         (match_operand:DI 3 "arith_reg_operand" "r"))]
12876   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12877   "#"
12878   ""
12879   [(pc)]
12880   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12881                           operands[3]));
12882    DONE;")
12884 (define_insn "ldhi_l64"
12885   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12886         (zero_extract:SI
12887          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12888                                   (const_int 3))
12889                           (const_int -3)))
12890          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12891          (const_int 0)))]
12892   "TARGET_SHMEDIA64"
12893   "ldhi.l       %U1, %0"
12894   [(set_attr "type" "load_media")])
12896 (define_insn "ldhi_q64"
12897   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12898         (zero_extract:DI
12899          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12900                                   (const_int 7))
12901                           (const_int -7)))
12902          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12903          (const_int 0)))]
12904   "TARGET_SHMEDIA64"
12905   "ldhi.q       %U1, %0"
12906   [(set_attr "type" "load_media")])
12908 (define_insn "ldlo_l64"
12909   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12910         (zero_extract:SI
12911          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12912                          (const_int -4)))
12913          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12914          (and:DI (match_dup 1) (const_int 3))))]
12915   "TARGET_SHMEDIA64"
12916   "ldlo.l       %U1, %0"
12917   [(set_attr "type" "load_media")])
12919 (define_insn "ldlo_q64"
12920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12921         (zero_extract:DI
12922          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12923                          (const_int -8)))
12924          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12925          (and:DI (match_dup 1) (const_int 7))))]
12926   "TARGET_SHMEDIA64"
12927   "ldlo.q       %U1, %0"
12928   [(set_attr "type" "load_media")])
12930 (define_insn "sthi_l64"
12931   [(set (zero_extract:SI
12932          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12933                                   (const_int 3))
12934                           (const_int -3)))
12935          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12936          (const_int 0))
12937         (match_operand:SI 1 "arith_reg_operand" "r"))]
12938   "TARGET_SHMEDIA64"
12939   "sthi.l       %U0, %1"
12940   [(set_attr "type" "ustore_media")])
12942 (define_insn "sthi_q64"
12943   [(set (zero_extract:DI
12944          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12945                                   (const_int 7))
12946                           (const_int -7)))
12947          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12948          (const_int 0))
12949         (match_operand:DI 1 "arith_reg_operand" "r"))]
12950   "TARGET_SHMEDIA64"
12951   "sthi.q       %U0, %1"
12952   [(set_attr "type" "ustore_media")])
12954 (define_insn "stlo_l64"
12955   [(set (zero_extract:SI
12956          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12957                          (const_int -4)))
12958          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12959          (and:DI (match_dup 0) (const_int 3)))
12960         (match_operand:SI 1 "arith_reg_operand" "r"))]
12961   "TARGET_SHMEDIA64"
12962   "stlo.l       %U0, %1"
12963   [(set_attr "type" "ustore_media")])
12965 (define_insn "stlo_q64"
12966   [(set (zero_extract:DI
12967          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12968                          (const_int -8)))
12969          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12970          (and:DI (match_dup 0) (const_int 7)))
12971         (match_operand:DI 1 "arith_reg_operand" "r"))]
12972   "TARGET_SHMEDIA64"
12973   "stlo.q       %U0, %1"
12974   [(set_attr "type" "ustore_media")])
12976 (define_insn "nsb"
12977   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12978         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12979                    UNSPEC_NSB))]
12980   "TARGET_SHMEDIA"
12981   "nsb  %1, %0"
12982   [(set_attr "type" "arith_media")])
12984 (define_insn "nsbsi"
12985   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12986         (zero_extend:SI
12987          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12988                     UNSPEC_NSB)))]
12989   "TARGET_SHMEDIA"
12990   "nsb  %1, %0"
12991   [(set_attr "type" "arith_media")])
12993 (define_insn "nsbdi"
12994   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12995         (zero_extend:DI
12996          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12997                     UNSPEC_NSB)))]
12998   "TARGET_SHMEDIA"
12999   "nsb  %1, %0"
13000   [(set_attr "type" "arith_media")])
13002 (define_expand "ffsdi2"
13003   [(set (match_operand:DI 0 "arith_reg_dest" "")
13004         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13005   "TARGET_SHMEDIA"
13006   "
13008   rtx scratch = gen_reg_rtx (DImode);
13009   rtx last;
13011   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13012   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13013   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13014   emit_insn (gen_nsbdi (scratch, scratch));
13015   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13016   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13017   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13018   REG_NOTES (last)
13019     = gen_rtx_EXPR_LIST (REG_EQUAL,
13020                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13021   DONE;
13024 (define_expand "ffssi2"
13025   [(set (match_operand:SI 0 "arith_reg_dest" "")
13026         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13027   "TARGET_SHMEDIA"
13028   "
13030   rtx scratch = gen_reg_rtx (SImode);
13031   rtx discratch = gen_reg_rtx (DImode);
13032   rtx last;
13034   emit_insn (gen_adddi3 (discratch,
13035                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13036                          constm1_rtx));
13037   emit_insn (gen_andcdi3 (discratch,
13038                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13039                           discratch));
13040   emit_insn (gen_nsbsi (scratch, discratch));
13041   last = emit_insn (gen_subsi3 (operands[0],
13042                                 force_reg (SImode, GEN_INT (63)), scratch));
13043   REG_NOTES (last)
13044     = gen_rtx_EXPR_LIST (REG_EQUAL,
13045                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13046   DONE;
13049 (define_insn "byterev"
13050   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13051         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13052                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13053                                     (const_int 4) (const_int 3) (const_int 2)
13054                                     (const_int 1) (const_int 0)])))]
13055   "TARGET_SHMEDIA"
13056   "byterev      %1, %0"
13057   [(set_attr "type" "arith_media")])
13059 (define_insn "*prefetch_media"
13060   [(prefetch (match_operand:QI 0 "address_operand" "p")
13061              (match_operand:SI 1 "const_int_operand" "n")
13062              (match_operand:SI 2 "const_int_operand" "n"))]
13063   "TARGET_SHMEDIA"
13064   "*
13066   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13067   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13068   return \"\";
13070   [(set_attr "type" "other")])
13072 (define_insn "*prefetch_i4"
13073   [(prefetch (match_operand:SI 0 "register_operand" "r")
13074              (match_operand:SI 1 "const_int_operand" "n")
13075              (match_operand:SI 2 "const_int_operand" "n"))]
13076   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13077   "*
13079   return \"pref @%0\";
13081   [(set_attr "type" "other")])
13083 (define_expand "prefetch"
13084   [(prefetch (match_operand 0 "address_operand" "p")
13085              (match_operand:SI 1 "const_int_operand" "n")
13086              (match_operand:SI 2 "const_int_operand" "n"))]
13087   "TARGET_HARD_SH4 || TARGET_SH5"
13088   "
13090   if (GET_MODE (operands[0]) != Pmode
13091       || GET_CODE (operands[1]) != CONST_INT
13092       || GET_CODE (operands[2]) != CONST_INT)
13093     FAIL;
13094   if (! TARGET_SHMEDIA)
13095     operands[0] = force_reg (Pmode, operands[0]);
13098 (define_insn "alloco_i"
13099   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13100         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13101   "TARGET_SHMEDIA32"
13102   "*
13104   rtx xops[2];
13106   if (GET_CODE (operands[0]) == PLUS)
13107     {
13108       xops[0] = XEXP (operands[0], 0);
13109       xops[1] = XEXP (operands[0], 1);
13110     }
13111   else
13112     {
13113       xops[0] = operands[0];
13114       xops[1] = const0_rtx;
13115     }
13116   output_asm_insn (\"alloco   %0, %1\", xops);
13117   return \"\";
13119   [(set_attr "type" "other")])
13121 (define_split
13122   [(set (match_operand 0 "any_register_operand" "")
13123         (match_operand 1 "" ""))]
13124   "TARGET_SHMEDIA && reload_completed"
13125   [(set (match_dup 0) (match_dup 1))]
13126   "
13128   int n_changes = 0;
13130   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13131   if (!n_changes)
13132     FAIL;