2005-08-31 J"orn Rennecke <joern.rennecke@st.com>
[official-gcc.git] / gcc / config / sh / sh.md
blob0c93a4d3976d6680dd76ecc201459a99156bfab2
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)
153   (UNSPEC_SP_SET        40)
154   (UNSPEC_SP_TEST       41)
156   ;; These are used with unspec_volatile.
157   (UNSPECV_BLOCKAGE     0)
158   (UNSPECV_ALIGN        1)
159   (UNSPECV_CONST2       2)
160   (UNSPECV_CONST4       4)
161   (UNSPECV_CONST8       6)
162   (UNSPECV_WINDOW_END   10)
163   (UNSPECV_CONST_END    11)
166 ;; -------------------------------------------------------------------------
167 ;; Attributes
168 ;; -------------------------------------------------------------------------
170 ;; Target CPU.
172 (define_attr "cpu"
173  "sh1,sh2,sh2e,sh2a,sh3,sh3e,sh4,sh4a,sh5"
174   (const (symbol_ref "sh_cpu_attr")))
176 (define_attr "endian" "big,little"
177  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
178                       (const_string "little") (const_string "big"))))
180 ;; Indicate if the default fpu mode is single precision.
181 (define_attr "fpu_single" "yes,no"
182   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
183                          (const_string "yes") (const_string "no"))))
185 (define_attr "fmovd" "yes,no"
186   (const (if_then_else (symbol_ref "TARGET_FMOVD")
187                        (const_string "yes") (const_string "no"))))
188 ;; pipeline model
189 (define_attr "pipe_model" "sh1,sh4,sh5media"
190   (const
191    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
192           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
193          (const_string "sh1"))))
195 ;; cbranch      conditional branch instructions
196 ;; jump         unconditional jumps
197 ;; arith        ordinary arithmetic
198 ;; arith3       a compound insn that behaves similarly to a sequence of
199 ;;              three insns of type arith
200 ;; arith3b      like above, but might end with a redirected branch
201 ;; load         from memory
202 ;; load_si      Likewise, SImode variant for general register.
203 ;; fload        Likewise, but load to fp register.
204 ;; store        to memory
205 ;; move         general purpose register to register
206 ;; mt_group     other sh4 mt instructions
207 ;; fmove        register to register, floating point
208 ;; smpy         word precision integer multiply
209 ;; dmpy         longword or doublelongword precision integer multiply
210 ;; return       rts
211 ;; pload        load of pr reg, which can't be put into delay slot of rts
212 ;; prset        copy register to pr reg, ditto
213 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
214 ;; prget        copy pr to register, ditto
215 ;; pcload       pc relative load of constant value
216 ;; pcfload      Likewise, but load to fp register.
217 ;; pcload_si    Likewise, SImode variant for general register.
218 ;; rte          return from exception
219 ;; sfunc        special function call with known used registers
220 ;; call         function call
221 ;; fp           floating point
222 ;; fdiv         floating point divide (or square root)
223 ;; gp_fpul      move from general purpose register to fpul
224 ;; fpul_gp      move from fpul to general purpose register
225 ;; mac_gp       move from mac[lh] to general purpose register
226 ;; dfp_arith, dfp_cmp,dfp_conv
227 ;; ftrc_s       fix_truncsfsi2_i4
228 ;; dfdiv        double precision floating point divide (or square root)
229 ;; cwb          ic_invalidate_line_i
230 ;; movua        SH4a unaligned load
231 ;; fsrra        square root reciprocal approximate
232 ;; fsca         sine and cosine approximate
233 ;; tls_load     load TLS related address
234 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
235 ;; cbranch_media SHmedia conditional branch instructions
236 ;; cmp_media    SHmedia compare instructions
237 ;; dfdiv_media  SHmedia double precision divide and square root
238 ;; dfmul_media  SHmedia double precision multiply instruction
239 ;; dfparith_media SHmedia double precision floating point arithmetic
240 ;; dfpconv_media SHmedia double precision floating point conversions
241 ;; dmpy_media   SHmedia longword multiply
242 ;; fcmp_media   SHmedia floating point compare instructions
243 ;; fdiv_media   SHmedia single precision divide and square root
244 ;; fload_media  SHmedia floating point register load instructions
245 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
246 ;; fparith_media SHmedia single precision floating point arithmetic
247 ;; fpconv_media SHmedia single precision floating point conversions
248 ;; fstore_media SHmedia floating point register store instructions
249 ;; gettr_media  SHmedia gettr instruction
250 ;; invalidate_line_media SHmedia invalidate_line sequence
251 ;; jump_media   SHmedia unconditional branch instructions
252 ;; load_media   SHmedia general register load instructions
253 ;; pt_media     SHmedia pt instruction (expanded by assembler)
254 ;; ptabs_media  SHmedia ptabs instruction
255 ;; store_media  SHmedia general register store instructions
256 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
257 ;; mac_media    SHmedia mac-style fixed point operations
258 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
259 ;; atrans_media SHmedia approximate transcendental functions
260 ;; ustore_media SHmedia unaligned stores
261 ;; nil          no-op move, will be deleted.
263 (define_attr "type"
264  "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"
265   (const_string "other"))
267 ;; We define a new attribute namely "insn_class".We use
268 ;; this for the DFA based pipeline description.
270 ;; mt_group      SH4 "mt" group instructions.
272 ;; ex_group      SH4 "ex" group instructions.
274 ;; ls_group      SH4 "ls" group instructions.
277 (define_attr "insn_class"
278   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
279   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
280          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
281          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
282          (eq_attr "type" "cbranch,jump") (const_string "br_group")
283          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
284            (const_string "fe_group")
285          (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")]
286         (const_string "none")))
287 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
288 ;; so these do not belong in an insn group, although they are modeled
289 ;; with their own define_insn_reservations.
291 ;; Indicate what precision must be selected in fpscr for this insn, if any.
293 (define_attr "fp_mode" "single,double,none" (const_string "none"))
295 ;; Indicate if the fpu mode is set by this instruction
296 ;; "unknown" must have the value as "none" in fp_mode, and means
297 ;; that the instruction/abi has left the processor in an unknown
298 ;; state.
299 ;; "none" means that nothing has changed and no mode is set.
300 ;; This attribute is only used for the Renesas ABI.
301 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
303 ; If a conditional branch destination is within -252..258 bytes away
304 ; from the instruction it can be 2 bytes long.  Something in the
305 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
306 ; branches are initially assumed to be 16 bytes long.
307 ; In machine_dependent_reorg, we split all branches that are longer than
308 ; 2 bytes.
310 ;; The maximum range used for SImode constant pool entries is 1018.  A final
311 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
312 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
313 ;; instruction around the pool table, 2 bytes of alignment before the table,
314 ;; and 30 bytes of alignment after the table.  That gives a maximum total
315 ;; pool size of 1058 bytes.
316 ;; Worst case code/pool content size ratio is 1:2 (using asms).
317 ;; Thus, in the worst case, there is one instruction in front of a maximum
318 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
319 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
320 ;; If we have a forward branch, the initial table will be put after the
321 ;; unconditional branch.
323 ;; ??? We could do much better by keeping track of the actual pcloads within
324 ;; the branch range and in the pcload range in front of the branch range.
326 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
327 ;; inside an le.
328 (define_attr "short_cbranch_p" "no,yes"
329   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
330          (const_string "no")
331          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
332          (const_string "yes")
333          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
334          (const_string "no")
335          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
336          (const_string "yes")
337          ] (const_string "no")))
339 (define_attr "med_branch_p" "no,yes"
340   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
341               (const_int 1988))
342          (const_string "yes")
343          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
344          (const_string "no")
345          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
346               (const_int 8186))
347          (const_string "yes")
348          ] (const_string "no")))
350 (define_attr "med_cbranch_p" "no,yes"
351   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
352               (const_int 1986))
353          (const_string "yes")
354          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
355          (const_string "no")
356          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
357                (const_int 8184))
358          (const_string "yes")
359          ] (const_string "no")))
361 (define_attr "braf_branch_p" "no,yes"
362   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
363          (const_string "no")
364          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
365               (const_int 20660))
366          (const_string "yes")
367          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
368          (const_string "no")
369          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
370               (const_int 65530))
371          (const_string "yes")
372          ] (const_string "no")))
374 (define_attr "braf_cbranch_p" "no,yes"
375   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
376          (const_string "no")
377          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
378               (const_int 20658))
379          (const_string "yes")
380          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
381          (const_string "no")
382          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
383               (const_int 65528))
384          (const_string "yes")
385          ] (const_string "no")))
387 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
388 ; For wider ranges, we need a combination of a code and a data part.
389 ; If we can get a scratch register for a long range jump, the code
390 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
391 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
392 ; long; otherwise, it must be 6 bytes long.
394 ; All other instructions are two bytes long by default.
396 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
397 ;; but getattrtab doesn't understand this.
398 (define_attr "length" ""
399   (cond [(eq_attr "type" "cbranch")
400          (cond [(eq_attr "short_cbranch_p" "yes")
401                 (const_int 2)
402                 (eq_attr "med_cbranch_p" "yes")
403                 (const_int 6)
404                 (eq_attr "braf_cbranch_p" "yes")
405                 (const_int 12)
406 ;; ??? using pc is not computed transitively.
407                 (ne (match_dup 0) (match_dup 0))
408                 (const_int 14)
409                 (ne (symbol_ref ("flag_pic")) (const_int 0))
410                 (const_int 24)
411                 ] (const_int 16))
412          (eq_attr "type" "jump")
413          (cond [(eq_attr "med_branch_p" "yes")
414                 (const_int 2)
415                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
416                          (symbol_ref "INSN"))
417                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
418                          (symbol_ref "code_for_indirect_jump_scratch")))
419                 (cond [(eq_attr "braf_branch_p" "yes")
420                        (const_int 6)
421                        (eq (symbol_ref "flag_pic") (const_int 0))
422                        (const_int 10)
423                        (ne (symbol_ref "TARGET_SH2") (const_int 0))
424                        (const_int 10)] (const_int 18))
425                 (eq_attr "braf_branch_p" "yes")
426                 (const_int 10)
427 ;; ??? using pc is not computed transitively.
428                 (ne (match_dup 0) (match_dup 0))
429                 (const_int 12)
430                 (ne (symbol_ref ("flag_pic")) (const_int 0))
431                 (const_int 22)
432                 ] (const_int 14))
433          (eq_attr "type" "pt_media")
434          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
435                        (const_int 20) (const_int 12))
436          (and (eq_attr "type" "jump_media")
437               (ne (symbol_ref "TARGET_SH5_CUT2_WORKAROUND") (const_int 0)))
438          (const_int 8)
439          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
440                          (const_int 4)
441                          (const_int 2))))
443 ;; DFA descriptions for the pipelines
445 (include "sh1.md")
446 (include "shmedia.md")
447 (include "sh4.md")
449 (include "predicates.md")
451 ;; Definitions for filling delay slots
453 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
455 ;; ??? This should be (nil) instead of (const_int 0)
456 (define_attr "hit_stack" "yes,no"
457         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
458                    (const_int 0))
459                (const_string "no")]
460               (const_string "yes")))
462 (define_attr "interrupt_function" "no,yes"
463   (const (symbol_ref "current_function_interrupt")))
465 (define_attr "in_delay_slot" "yes,no"
466   (cond [(eq_attr "type" "cbranch") (const_string "no")
467          (eq_attr "type" "pcload,pcload_si") (const_string "no")
468          (eq_attr "needs_delay_slot" "yes") (const_string "no")
469          (eq_attr "length" "2") (const_string "yes")
470          ] (const_string "no")))
472 (define_attr "cond_delay_slot" "yes,no"
473   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
474          ] (const_string "no")))
476 (define_attr "is_sfunc" ""
477   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
479 (define_attr "is_mac_media" ""
480   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
482 (define_attr "branch_zero" "yes,no"
483   (cond [(eq_attr "type" "!cbranch") (const_string "no")
484          (ne (symbol_ref "(next_active_insn (insn)\
485                            == (prev_active_insn\
486                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
487                           && get_attr_length (next_active_insn (insn)) == 2")
488              (const_int 0))
489          (const_string "yes")]
490         (const_string "no")))
492 ;; SH4 Double-precision computation with double-precision result -
493 ;; the two halves are ready at different times.
494 (define_attr "dfp_comp" "yes,no"
495   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
496         (const_string "no")))
498 ;; Insns for which the latency of a preceding fp insn is decreased by one.
499 (define_attr "late_fp_use" "yes,no" (const_string "no"))
500 ;; And feeding insns for which this relevant.
501 (define_attr "any_fp_comp" "yes,no"
502   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
503          (const_string "yes")]
504         (const_string "no")))
506 (define_attr "any_int_load" "yes,no"
507   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
508          (const_string "yes")]
509         (const_string "no")))
511 (define_attr "highpart" "user, ignore, extend, depend, must_split"
512   (const_string "user"))
514 (define_delay
515   (eq_attr "needs_delay_slot" "yes")
516   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
518 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
519 ;; and thus we can't put a pop instruction in its delay slot.
520 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
521 ;; instruction can go in the delay slot.
523 ;; Since a normal return (rts) implicitly uses the PR register,
524 ;; we can't allow PR register loads in an rts delay slot.
526 (define_delay
527   (eq_attr "type" "return")
528   [(and (eq_attr "in_delay_slot" "yes")
529         (ior (and (eq_attr "interrupt_function" "no")
530                   (eq_attr "type" "!pload,prset"))
531              (and (eq_attr "interrupt_function" "yes")
532                   (ior
533                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
534                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
536 ;; Since a call implicitly uses the PR register, we can't allow
537 ;; a PR register store in a jsr delay slot.
539 (define_delay
540   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
541   [(and (eq_attr "in_delay_slot" "yes")
542         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
544 ;; Say that we have annulled true branches, since this gives smaller and
545 ;; faster code when branches are predicted as not taken.
547 ;; ??? The non-annulled condition should really be "in_delay_slot",
548 ;; but insns that can be filled in non-annulled get priority over insns
549 ;; that can only be filled in anulled.
551 (define_delay
552   (and (eq_attr "type" "cbranch")
553        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
554   ;; SH2e has a hardware bug that pretty much prohibits the use of
555   ;; annuled delay slots.
556   [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
557                                           (not (eq_attr "cpu" "sh2e"))) (nil)])
559 ;; -------------------------------------------------------------------------
560 ;; SImode signed integer comparisons
561 ;; -------------------------------------------------------------------------
563 (define_insn ""
564   [(set (reg:SI T_REG)
565         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
566                        (match_operand:SI 1 "arith_operand" "K08,r"))
567                (const_int 0)))]
568   "TARGET_SH1"
569   "tst  %1,%0"
570   [(set_attr "type" "mt_group")])
572 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
573 ;; That would still allow reload to create cmpi instructions, but would
574 ;; perhaps allow forcing the constant into a register when that is better.
575 ;; Probably should use r0 for mem/imm compares, but force constant into a
576 ;; register for pseudo/imm compares.
578 (define_insn "cmpeqsi_t"
579   [(set (reg:SI T_REG)
580         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
581                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
582   "TARGET_SH1"
583   "@
584         tst     %0,%0
585         cmp/eq  %1,%0
586         cmp/eq  %1,%0"
587    [(set_attr "type" "mt_group")])
589 (define_insn "cmpgtsi_t"
590   [(set (reg:SI T_REG)
591         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
592                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
593   "TARGET_SH1"
594   "@
595         cmp/gt  %1,%0
596         cmp/pl  %0"
597    [(set_attr "type" "mt_group")])
599 (define_insn "cmpgesi_t"
600   [(set (reg:SI T_REG)
601         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
602                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
603   "TARGET_SH1"
604   "@
605         cmp/ge  %1,%0
606         cmp/pz  %0"
607    [(set_attr "type" "mt_group")])
609 ;; -------------------------------------------------------------------------
610 ;; SImode unsigned integer comparisons
611 ;; -------------------------------------------------------------------------
613 (define_insn "cmpgeusi_t"
614   [(set (reg:SI T_REG)
615         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
616                 (match_operand:SI 1 "arith_reg_operand" "r")))]
617   "TARGET_SH1"
618   "cmp/hs       %1,%0"
619    [(set_attr "type" "mt_group")])
621 (define_insn "cmpgtusi_t"
622   [(set (reg:SI T_REG)
623         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
624                 (match_operand:SI 1 "arith_reg_operand" "r")))]
625   "TARGET_SH1"
626   "cmp/hi       %1,%0"
627    [(set_attr "type" "mt_group")])
629 ;; We save the compare operands in the cmpxx patterns and use them when
630 ;; we generate the branch.
632 (define_expand "cmpsi"
633   [(set (reg:SI T_REG)
634         (compare (match_operand:SI 0 "cmpsi_operand" "")
635                  (match_operand:SI 1 "arith_operand" "")))]
636   "TARGET_SH1 || TARGET_SHMEDIA"
637   "
639   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
640       && GET_CODE (operands[1]) != CONST_INT)
641     operands[0] = copy_to_mode_reg (SImode, operands[0]);
642   sh_compare_op0 = operands[0];
643   sh_compare_op1 = operands[1];
644   DONE;
647 ;; -------------------------------------------------------------------------
648 ;; DImode signed integer comparisons
649 ;; -------------------------------------------------------------------------
651 ;; ??? Could get better scheduling by splitting the initial test from the
652 ;; rest of the insn after reload.  However, the gain would hardly justify
653 ;; the sh.md size increase necessary to do that.
655 (define_insn ""
656   [(set (reg:SI T_REG)
657         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
658                        (match_operand:DI 1 "arith_operand" "r"))
659                (const_int 0)))]
660   "TARGET_SH1"
661   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
662                                  insn, operands);"
663   [(set_attr "length" "6")
664    (set_attr "type" "arith3b")])
666 (define_insn "cmpeqdi_t"
667   [(set (reg:SI T_REG)
668         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
669                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
670   "TARGET_SH1"
671   "@
672         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
673         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
674   [(set_attr "length" "6")
675    (set_attr "type" "arith3b")])
677 (define_split
678   [(set (reg:SI T_REG)
679         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
680                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
681 ;; If we applied this split when not optimizing, it would only be
682 ;; applied during the machine-dependent reorg, when no new basic blocks
683 ;; may be created.
684   "TARGET_SH1 && reload_completed && optimize"
685   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
686    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
687                            (label_ref (match_dup 6))
688                            (pc)))
689    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
690    (match_dup 6)]
691   "
693   operands[2]
694     = gen_rtx_REG (SImode,
695                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
696   operands[3]
697     = (operands[1] == const0_rtx
698        ? const0_rtx
699        : gen_rtx_REG (SImode,
700                       true_regnum (operands[1])
701                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
702   operands[4] = gen_lowpart (SImode, operands[0]);
703   operands[5] = gen_lowpart (SImode, operands[1]);
704   operands[6] = gen_label_rtx ();
707 (define_insn "cmpgtdi_t"
708   [(set (reg:SI T_REG)
709         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
710                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
711   "TARGET_SH2"
712   "@
713         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
714         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
715   [(set_attr "length" "8")
716    (set_attr "type" "arith3")])
718 (define_insn "cmpgedi_t"
719   [(set (reg:SI T_REG)
720         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
721                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
722   "TARGET_SH2"
723   "@
724         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
725         cmp/pz\\t%S0"
726   [(set_attr "length" "8,2")
727    (set_attr "type" "arith3,mt_group")])
729 ;; -------------------------------------------------------------------------
730 ;; DImode unsigned integer comparisons
731 ;; -------------------------------------------------------------------------
733 (define_insn "cmpgeudi_t"
734   [(set (reg:SI T_REG)
735         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
736                 (match_operand:DI 1 "arith_reg_operand" "r")))]
737   "TARGET_SH2"
738   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
739   [(set_attr "length" "8")
740    (set_attr "type" "arith3")])
742 (define_insn "cmpgtudi_t"
743   [(set (reg:SI T_REG)
744         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
745                 (match_operand:DI 1 "arith_reg_operand" "r")))]
746   "TARGET_SH2"
747   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
748   [(set_attr "length" "8")
749    (set_attr "type" "arith3")])
751 (define_insn "cmpeqsi_media"
752   [(set (match_operand:DI 0 "register_operand" "=r")
753         (eq:DI (match_operand:SI 1 "logical_operand" "%r")
754                (match_operand:SI 2 "cmp_operand" "Nr")))]
755   "TARGET_SHMEDIA"
756   "cmpeq        %1, %N2, %0"
757   [(set_attr "type" "cmp_media")])
759 (define_insn "cmpeqdi_media"
760   [(set (match_operand:DI 0 "register_operand" "=r")
761         (eq:DI (match_operand:DI 1 "register_operand" "%r")
762                (match_operand:DI 2 "cmp_operand" "Nr")))]
763   "TARGET_SHMEDIA"
764   "cmpeq        %1, %N2, %0"
765   [(set_attr "type" "cmp_media")])
767 (define_insn "cmpgtsi_media"
768   [(set (match_operand:DI 0 "register_operand" "=r")
769         (gt:DI (match_operand:SI 1 "cmp_operand" "Nr")
770                (match_operand:SI 2 "cmp_operand" "rN")))]
771   "TARGET_SHMEDIA"
772   "cmpgt        %N1, %N2, %0"
773   [(set_attr "type" "cmp_media")])
775 (define_insn "cmpgtdi_media"
776   [(set (match_operand:DI 0 "register_operand" "=r")
777         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
778                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
779   "TARGET_SHMEDIA"
780   "cmpgt        %N1, %N2, %0"
781   [(set_attr "type" "cmp_media")])
783 (define_insn "cmpgtusi_media"
784   [(set (match_operand:DI 0 "register_operand" "=r")
785         (gtu:DI (match_operand:SI 1 "cmp_operand" "Nr")
786                 (match_operand:SI 2 "cmp_operand" "rN")))]
787   "TARGET_SHMEDIA"
788   "cmpgtu       %N1, %N2, %0"
789   [(set_attr "type" "cmp_media")])
791 (define_insn "cmpgtudi_media"
792   [(set (match_operand:DI 0 "register_operand" "=r")
793         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
794                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
795   "TARGET_SHMEDIA"
796   "cmpgtu       %N1, %N2, %0"
797   [(set_attr "type" "cmp_media")])
799 (define_insn "cmpsieqsi_media"
800   [(set (match_operand:SI 0 "register_operand" "=r")
801         (eq:SI (match_operand:SI 1 "logical_operand" "%r")
802                (match_operand:SI 2 "cmp_operand" "Nr")))]
803   "TARGET_SHMEDIA"
804   "cmpeq        %1, %N2, %0"
805   [(set_attr "type" "cmp_media")])
807 (define_insn "cmpsieqdi_media"
808   [(set (match_operand:SI 0 "register_operand" "=r")
809         (eq:SI (match_operand:DI 1 "register_operand" "%r")
810                (match_operand:DI 2 "cmp_operand" "Nr")))]
811   "TARGET_SHMEDIA"
812   "cmpeq        %1, %N2, %0"
813   [(set_attr "type" "cmp_media")])
815 (define_insn "cmpsigtsi_media"
816   [(set (match_operand:SI 0 "register_operand" "=r")
817         (gt:SI (match_operand:SI 1 "cmp_operand" "Nr")
818                (match_operand:SI 2 "cmp_operand" "rN")))]
819   "TARGET_SHMEDIA"
820   "cmpgt        %N1, %N2, %0"
821   [(set_attr "type" "cmp_media")])
823 (define_insn "cmpsigtdi_media"
824   [(set (match_operand:SI 0 "register_operand" "=r")
825         (gt:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
826                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
827   "TARGET_SHMEDIA"
828   "cmpgt        %N1, %N2, %0"
829   [(set_attr "type" "cmp_media")])
831 (define_insn "cmpsigtusi_media"
832   [(set (match_operand:SI 0 "register_operand" "=r")
833         (gtu:SI (match_operand:SI 1 "cmp_operand" "Nr")
834                 (match_operand:SI 2 "cmp_operand" "rN")))]
835   "TARGET_SHMEDIA"
836   "cmpgtu       %N1, %N2, %0"
837   [(set_attr "type" "cmp_media")])
839 (define_insn "cmpsigtudi_media"
840   [(set (match_operand:SI 0 "register_operand" "=r")
841         (gtu:SI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
842                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
843   "TARGET_SHMEDIA"
844   "cmpgtu       %N1, %N2, %0"
845   [(set_attr "type" "cmp_media")])
847 ; These two patterns are for combine.
848 (define_insn "*cmpne0si_media"
849   [(set (match_operand:DI 0 "register_operand" "=r")
850         (ne:DI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
851   "TARGET_SHMEDIA"
852   "cmpgtu       %1,r63,%0"
853   [(set_attr "type" "cmp_media")])
855 (define_insn "*cmpne0sisi_media"
856   [(set (match_operand:SI 0 "register_operand" "=r")
857         (ne:SI (match_operand:SI 1 "arith_reg_operand" "r") (const_int 0)))]
858   "TARGET_SHMEDIA"
859   "cmpgtu       %1,r63,%0"
860   [(set_attr "type" "cmp_media")])
862 ;; We save the compare operands in the cmpxx patterns and use them when
863 ;; we generate the branch.
865 (define_expand "cmpdi"
866   [(set (reg:SI T_REG)
867         (compare (match_operand:DI 0 "arith_operand" "")
868                  (match_operand:DI 1 "arith_operand" "")))]
869   "TARGET_SH2 || TARGET_SHMEDIA"
870   "
872   sh_compare_op0 = operands[0];
873   sh_compare_op1 = operands[1];
874   DONE;
876 ;; -------------------------------------------------------------------------
877 ;; Conditional move instructions
878 ;; -------------------------------------------------------------------------
880 ;; The insn names may seem reversed, but note that cmveq performs the move
881 ;; if op1 == 0, and cmvne does it if op1 != 0.
883 (define_insn "movdicc_false"
884   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
885         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
886                              (const_int 0))
887          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
888          (match_operand:DI 3 "arith_reg_operand" "0")))]
889   "TARGET_SHMEDIA"
890   "cmveq        %1, %N2, %0"
891   [(set_attr "type" "arith_media")])
893 (define_insn "movdicc_true"
894   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
895         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
896                              (const_int 0))
897          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
898          (match_operand:DI 3 "arith_reg_operand" "0")))]
899   "TARGET_SHMEDIA"
900   "cmvne        %1, %N2, %0"
901   [(set_attr "type" "arith_media")])
903 (define_peephole2
904   [(set (match_operand:DI 0 "arith_reg_dest" "")
905         (if_then_else:DI (match_operator 3 "equality_comparison_operator"
906                            [(match_operand:DI 1 "arith_reg_operand" "")
907                             (const_int 0)])
908          (match_operand:DI 2 "arith_reg_dest" "")
909          (match_dup 0)))
910    (set (match_dup 2) (match_dup 0))]
911   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
912   [(set (match_dup 2)
913         (if_then_else:DI (match_dup 3) (match_dup 0) (match_dup 2)))]
914   "
916   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
917                                 VOIDmode, operands[1], CONST0_RTX (DImode));
920 (define_peephole2
921   [(set (match_operand:DI 0 "general_movdst_operand" "")
922         (match_operand:DI 1 "arith_reg_or_0_operand" ""))
923    (set (match_operand:DI 2 "arith_reg_dest" "")
924         (if_then_else:DI (match_operator 4 "equality_comparison_operator"
925                            [(match_operand:DI 3 "arith_reg_operand" "")
926                             (const_int 0)])
927          (match_dup 0)
928          (match_dup 2)))]
929   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
930   [(set (match_dup 2)
931         (if_then_else:DI (match_dup 4) (match_dup 1) (match_dup 2)))]
932   "")
934 (define_expand "movdicc"
935   [(set (match_operand:DI 0 "register_operand" "")
936         (if_then_else:DI (match_operand 1 "comparison_operator" "")
937                          (match_operand:DI 2 "register_operand" "")
938                          (match_operand:DI 3 "register_operand" "")))]
939   "TARGET_SHMEDIA"
940   "
942   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
943       && GET_MODE (sh_compare_op0) == DImode
944       && sh_compare_op1 == const0_rtx)
945     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
946                                   sh_compare_op0, sh_compare_op1);
947   else
948     {
949       rtx tmp;
951       if (no_new_pseudos)
952         FAIL;
954       tmp = gen_reg_rtx (DImode);
956       switch (GET_CODE (operands[1]))
957         {
958         case EQ:
959           emit_insn (gen_seq (tmp));
960           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
961           break;
963         case NE:
964           emit_insn (gen_seq (tmp));
965           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
966           break;
968         case GT:
969           emit_insn (gen_sgt (tmp));
970           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
971           break;
973         case LT:
974           emit_insn (gen_slt (tmp));
975           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
976           break;
978         case GE:
979           emit_insn (gen_slt (tmp));
980           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
981           break;
983         case LE:
984           emit_insn (gen_sgt (tmp));
985           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
986           break;
988         case GTU:
989           emit_insn (gen_sgtu (tmp));
990           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
991           break;
993         case LTU:
994           emit_insn (gen_sltu (tmp));
995           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
996           break;
998         case GEU:
999           emit_insn (gen_sltu (tmp));
1000           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1001           break;
1003         case LEU:
1004           emit_insn (gen_sgtu (tmp));
1005           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1006           break;
1008         case UNORDERED:
1009           emit_insn (gen_sunordered (tmp));
1010           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1011           break;
1013         case ORDERED:
1014           emit_insn (gen_sunordered (tmp));
1015           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1016           break;
1018         case UNEQ:
1019         case UNGE:
1020         case UNGT:
1021         case UNLE:
1022         case UNLT:
1023         case LTGT:
1024           FAIL;
1026         default:
1027           gcc_unreachable ();
1028         }
1029     }
1032 ;; Add SImode variants for cmveq / cmvne to compensate for not promoting
1033 ;; SImode to DImode.
1034 (define_insn "movsicc_false"
1035   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1036         (if_then_else:SI (eq (match_operand:SI 1 "arith_reg_operand" "r")
1037                           (const_int 0))
1038          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1039          (match_operand:SI 3 "arith_reg_operand" "0")))]
1040   "TARGET_SHMEDIA"
1041   "cmveq        %1, %N2, %0"
1042   [(set_attr "type" "arith_media")])
1044 (define_insn "movsicc_true"
1045   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1046         (if_then_else:SI (ne (match_operand:SI 1 "arith_reg_operand" "r")
1047                           (const_int 0))
1048          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1049          (match_operand:SI 3 "arith_reg_operand" "0")))]
1050   "TARGET_SHMEDIA"
1051   "cmvne        %1, %N2, %0"
1052   [(set_attr "type" "arith_media")])
1054 (define_peephole2
1055   [(set (match_operand:SI 0 "arith_reg_dest" "")
1056         (if_then_else:SI (match_operator 3 "equality_comparison_operator"
1057                            [(match_operand:SI 1 "arith_reg_operand" "")
1058                             (const_int 0)])
1059          (match_operand:SI 2 "arith_reg_dest" "")
1060          (match_dup 0)))
1061    (set (match_dup 2) (match_dup 0))]
1062   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])"
1063   [(set (match_dup 2)
1064         (if_then_else:SI (match_dup 3) (match_dup 0) (match_dup 2)))]
1065   "
1067   operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[3])),
1068                                 VOIDmode, operands[1], CONST0_RTX (SImode));
1071 (define_peephole2
1072   [(set (match_operand:SI 0 "general_movdst_operand" "")
1073         (match_operand:SI 1 "arith_reg_or_0_operand" ""))
1074    (set (match_operand:SI 2 "arith_reg_dest" "")
1075         (if_then_else:SI (match_operator 4 "equality_comparison_operator"
1076                            [(match_operand:SI 3 "arith_reg_operand" "")
1077                             (const_int 0)])
1078          (match_dup 0)
1079          (match_dup 2)))]
1080   "TARGET_SHMEDIA && peep2_reg_dead_p (2, operands[0])
1081    && (GET_CODE (operands[1]) != REG || GENERAL_REGISTER_P (REGNO (operands[1])))"
1082   [(set (match_dup 2)
1083         (if_then_else:SI (match_dup 4) (match_dup 1) (match_dup 2)))]
1084   "
1086   replace_rtx (operands[4], operands[0], operands[1]);
1089 (define_peephole2
1090   [(set (match_operand 0 "any_register_operand" "")
1091         (match_operand 1 "any_register_operand" ""))
1092    (set (match_operand 2 "any_register_operand" "") (match_operand 3 "" ""))
1093    (set (match_operand 4 "" "") (match_operand 5 "" ""))]
1094   "(HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[2]))
1095     <= HARD_REGNO_NREGS (REGNO (operands[0]), GET_MODE (operands[0])))
1096    && peep2_reg_dead_p (3, operands[0]) && peep2_reg_dead_p (3, operands[2])
1097    && ! reg_overlap_mentioned_p (operands[0], operands[3])
1098    && ! reg_overlap_mentioned_p (operands[2], operands[0])
1099    && ! reg_overlap_mentioned_p (operands[0], operands[1])
1100    && (REGNO_REG_CLASS (REGNO (operands[0]))
1101        == REGNO_REG_CLASS (REGNO (operands[2])))
1102    && (REGNO_REG_CLASS (REGNO (operands[1]))
1103        == REGNO_REG_CLASS (REGNO (operands[0])))"
1104   [(set (match_dup 0) (match_dup 3))
1105    (set (match_dup 4) (match_dup 5))]
1106   "
1108   rtx set1, set2;
1109   rtx replacements[4];
1111   /* We want to replace occurrences of operands[0] with operands[1] and
1112      operands[2] with operands[0] in operands[4]/operands[5].
1113      Doing just two replace_rtx calls naively would result in the second
1114      replacement undoing all that the first did if operands[1] and operands[2]
1115      are identical, so we must do this simultaneously.  */
1116   replacements[0] = operands[0];
1117   replacements[1] = operands[1];
1118   replacements[2] = operands[2];
1119   replacements[3] = operands[0];
1120   if (!replace_n_hard_rtx (operands[5], replacements, 2, 0)
1121       || !replace_n_hard_rtx (operands[4], replacements, 2, 0)
1122       || !replace_n_hard_rtx (operands[2], replacements, 2, 0))
1123     FAIL;
1125   operands[5] = replace_n_hard_rtx (operands[5], replacements, 2, 1);
1126   replace_n_hard_rtx (operands[4], replacements, 2, 1);
1127   operands[2] = replace_n_hard_rtx (operands[2], replacements, 2, 1);
1128   /* The operands array is aliased to recog_data.operand, which gets
1129      clobbered by extract_insn, so finish with it now.  */
1130   set1 = gen_rtx_SET (VOIDmode, operands[2], operands[3]);
1131   set2 = gen_rtx_SET (VOIDmode, operands[4], operands[5]);
1132   /* ??? The last insn might be a jump insn, but the generic peephole2 code
1133      always uses emit_insn.  */
1134   /* Check that we don't violate matching constraints or earlyclobbers.  */
1135   extract_insn (emit_insn (set1));
1136   if (! constrain_operands (1))
1137     goto failure;
1138   extract_insn (emit (set2));
1139   if (! constrain_operands (1))
1140     {
1141       rtx tmp;
1142     failure:
1143       tmp = replacements[0];
1144       replacements[0] = replacements[1];
1145       replacements[1] = tmp;
1146       tmp = replacements[2];
1147       replacements[2] = replacements[3];
1148       replacements[3] = tmp;
1149       replace_n_hard_rtx (SET_DEST (set1), replacements, 2, 1);
1150       replace_n_hard_rtx (SET_DEST (set2), replacements, 2, 1);
1151       replace_n_hard_rtx (SET_SRC (set2), replacements, 2, 1);
1152       FAIL;
1153     }
1154   DONE;
1157 ;; The register allocator is rather clumsy in handling multi-way conditional
1158 ;; moves, so allow the combiner to make them, and we split them up after
1159 ;; reload.  */
1160 (define_insn_and_split "*movsicc_umin"
1161   [(set (match_operand:SI 0 "arith_reg_dest" "=&r")
1162         (umin:SI (if_then_else:SI
1163                    (eq (match_operand:SI 1 "arith_reg_operand" "r")
1164                        (const_int 0))
1165                    (match_operand:SI 2 "arith_reg_or_0_operand" "rN")
1166                    (match_operand:SI 3 "register_operand" "0"))
1167                  (match_operand:SI 4 "arith_reg_or_0_operand" "r")))
1168    (clobber (match_scratch:SI 5 "=&r"))]
1169   "TARGET_SHMEDIA && no_new_pseudos"
1170   "#"
1171   "TARGET_SHMEDIA && reload_completed"
1172   [(pc)]
1173   "
1175   emit_insn (gen_movsicc_false (operands[0], operands[1], operands[2],
1176                                 operands[3]));
1177   emit_insn (gen_cmpsigtusi_media (operands[5], operands[4], operands[0]));
1178   emit_insn (gen_movsicc_false (operands[0], operands[5], operands[4],
1179                                 operands[0]));
1180   DONE;
1183 (define_expand "movsicc"
1184   [(set (match_operand:SI 0 "register_operand" "")
1185         (if_then_else:SI (match_operand 1 "comparison_operator" "")
1186                          (match_operand:SI 2 "register_operand" "")
1187                          (match_operand:SI 3 "register_operand" "")))]
1188   "TARGET_SHMEDIA"
1189   "
1191   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
1192       && GET_MODE (sh_compare_op0) == SImode
1193       && sh_compare_op1 == const0_rtx)
1194     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
1195                                   sh_compare_op0, sh_compare_op1);
1196   else
1197     {
1198       rtx tmp;
1200       if (no_new_pseudos)
1201         FAIL;
1203       tmp = gen_reg_rtx (SImode);
1205       switch (GET_CODE (operands[1]))
1206         {
1207         case EQ:
1208           emit_insn (gen_seq (tmp));
1209           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1210           break;
1212         case NE:
1213           emit_insn (gen_seq (tmp));
1214           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1215           break;
1217         case GT:
1218           emit_insn (gen_sgt (tmp));
1219           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1220           break;
1222         case LT:
1223           emit_insn (gen_slt (tmp));
1224           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1225           break;
1227         case GE:
1228           emit_insn (gen_slt (tmp));
1229           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1230           break;
1232         case LE:
1233           emit_insn (gen_sgt (tmp));
1234           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1235           break;
1237         case GTU:
1238           emit_insn (gen_sgtu (tmp));
1239           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1240           break;
1242         case LTU:
1243           emit_insn (gen_sltu (tmp));
1244           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1245           break;
1247         case GEU:
1248           emit_insn (gen_sltu (tmp));
1249           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1250           break;
1252         case LEU:
1253           emit_insn (gen_sgtu (tmp));
1254           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1255           break;
1257         case UNORDERED:
1258           emit_insn (gen_sunordered (tmp));
1259           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
1260           break;
1262         case ORDERED:
1263           emit_insn (gen_sunordered (tmp));
1264           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
1265           break;
1267         case UNEQ:
1268         case UNGE:
1269         case UNGT:
1270         case UNLE:
1271         case UNLT:
1272         case LTGT:
1273           FAIL;
1275         default:
1276           abort ();
1277         }
1278     }
1281 (define_expand "movqicc"
1282   [(set (match_operand:QI 0 "register_operand" "")
1283         (if_then_else:QI (match_operand 1 "comparison_operator" "")
1284                          (match_operand:QI 2 "register_operand" "")
1285                          (match_operand:QI 3 "register_operand" "")))]
1286   "TARGET_SHMEDIA"
1287   "
1289   operands[0] = simplify_gen_subreg (SImode, operands[0], QImode, 0);
1290   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
1291   operands[3] = simplify_gen_subreg (SImode, operands[3], QImode, 0);
1292   emit (gen_movsicc (operands[0], operands[1], operands[2], operands[3]));
1293   DONE;
1296 ;; -------------------------------------------------------------------------
1297 ;; Addition instructions
1298 ;; -------------------------------------------------------------------------
1300 (define_expand "adddi3"
1301   [(set (match_operand:DI 0 "arith_reg_operand" "")
1302         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1303                  (match_operand:DI 2 "arith_operand" "")))]
1304   ""
1305   "
1307   if (TARGET_SH1)
1308     {
1309       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1310         FAIL;
1311       operands[2] = force_reg (DImode, operands[2]);
1312       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1313       DONE;
1314     }
1317 (define_insn "*adddi3_media"
1318   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1319         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1320                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1321   "TARGET_SHMEDIA"
1322   "@
1323         add     %1, %2, %0
1324         addi    %1, %2, %0"
1325   [(set_attr "type" "arith_media")])
1327 (define_insn "*adddisi3_media"
1328   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r,r") 0)
1329         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1330                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1331   "TARGET_SHMEDIA"
1332   "@
1333         add.l   %1, %2, %0
1334         addi.l  %1, %2, %0"
1335   [(set_attr "type" "arith_media")
1336    (set_attr "highpart" "ignore")])
1338 (define_insn "adddi3z_media"
1339   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1340         (zero_extend:DI
1341          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1342                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1343   "TARGET_SHMEDIA"
1344   "addz.l       %1, %N2, %0"
1345   [(set_attr "type" "arith_media")
1346    (set_attr "highpart" "ignore")])
1348 (define_insn "adddi3_compact"
1349   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1350         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1351                  (match_operand:DI 2 "arith_reg_operand" "r")))
1352    (clobber (reg:SI T_REG))]
1353   "TARGET_SH1"
1354   "#"
1355   [(set_attr "length" "6")])
1357 (define_split
1358   [(set (match_operand:DI 0 "arith_reg_dest" "")
1359         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1360                  (match_operand:DI 2 "arith_reg_operand" "")))
1361    (clobber (reg:SI T_REG))]
1362   "TARGET_SH1 && reload_completed"
1363   [(const_int 0)]
1364   "
1366   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1367   high0 = gen_rtx_REG (SImode,
1368                        true_regnum (operands[0])
1369                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1370   high2 = gen_rtx_REG (SImode,
1371                        true_regnum (operands[2])
1372                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1373   emit_insn (gen_clrt ());
1374   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1375   emit_insn (gen_addc1 (high0, high0, high2));
1376   DONE;
1379 (define_insn "addc"
1380   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1381         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1382                           (match_operand:SI 2 "arith_reg_operand" "r"))
1383                  (reg:SI T_REG)))
1384    (set (reg:SI T_REG)
1385         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1386   "TARGET_SH1"
1387   "addc %2,%0"
1388   [(set_attr "type" "arith")])
1390 (define_insn "addc1"
1391   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1392         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1393                           (match_operand:SI 2 "arith_reg_operand" "r"))
1394                  (reg:SI T_REG)))
1395    (clobber (reg:SI T_REG))]
1396   "TARGET_SH1"
1397   "addc %2,%0"
1398   [(set_attr "type" "arith")])
1400 (define_expand "addsi3"
1401   [(set (match_operand:SI 0 "arith_reg_operand" "")
1402         (plus:SI (match_operand:SI 1 "arith_operand" "")
1403                  (match_operand:SI 2 "arith_operand" "")))]
1404   ""
1405   "
1407   if (TARGET_SHMEDIA)
1408     operands[1] = force_reg (SImode, operands[1]);
1411 (define_insn "addsi3_media"
1412   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
1413         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1414                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1415   "TARGET_SHMEDIA"
1416   "@
1417         add.l   %1, %2, %0
1418         addi.l  %1, %2, %0"
1419   [(set_attr "type" "arith_media")
1420    (set_attr "highpart" "ignore")])
1422 (define_insn "addsidi3_media"
1423   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
1424         (sign_extend:DI (plus:SI (match_operand:SI 1 "extend_reg_operand"
1425                                   "%r,r")
1426                                  (match_operand:SI 2 "arith_operand"
1427                                   "r,I10"))))]
1428   "TARGET_SHMEDIA"
1429   "@
1430         add.l   %1, %2, %0
1431         addi.l  %1, %2, %0"
1432   [(set_attr "type" "arith_media")
1433    (set_attr "highpart" "ignore")])
1435 (define_insn "*addsi3_compact"
1436   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1437         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1438                  (match_operand:SI 2 "arith_operand" "rI08")))]
1439   "TARGET_SH1"
1440   "add  %2,%0"
1441   [(set_attr "type" "arith")])
1443 ;; -------------------------------------------------------------------------
1444 ;; Subtraction instructions
1445 ;; -------------------------------------------------------------------------
1447 (define_expand "subdi3"
1448   [(set (match_operand:DI 0 "arith_reg_operand" "")
1449         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1450                   (match_operand:DI 2 "arith_reg_operand" "")))]
1451   ""
1452   "
1454   if (TARGET_SH1)
1455     {
1456       operands[1] = force_reg (DImode, operands[1]);
1457       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1458       DONE;
1459     }
1462 (define_insn "*subdi3_media"
1463   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
1464         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1465                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1466   "TARGET_SHMEDIA"
1467   "sub  %N1, %2, %0"
1468   [(set_attr "type" "arith_media")])
1469   
1470 (define_insn "subdisi3_media"
1471   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
1472         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1473                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1474   "TARGET_SHMEDIA"
1475   "sub.l        %N1, %2, %0"
1476   [(set_attr "type" "arith_media")
1477    (set_attr "highpart" "ignore")])
1479 (define_insn "subdi3_compact"
1480   [(set (match_operand:DI 0 "arith_reg_dest" "=&r")
1481         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1482                  (match_operand:DI 2 "arith_reg_operand" "r")))
1483    (clobber (reg:SI T_REG))]
1484   "TARGET_SH1"
1485   "#"
1486   [(set_attr "length" "6")])
1488 (define_split
1489   [(set (match_operand:DI 0 "arith_reg_dest" "")
1490         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1491                   (match_operand:DI 2 "arith_reg_operand" "")))
1492    (clobber (reg:SI T_REG))]
1493   "TARGET_SH1 && reload_completed"
1494   [(const_int 0)]
1495   "
1497   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1498   high0 = gen_rtx_REG (SImode,
1499                        true_regnum (operands[0])
1500                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1501   high2 = gen_rtx_REG (SImode,
1502                        true_regnum (operands[2])
1503                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1504   emit_insn (gen_clrt ());
1505   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1506   emit_insn (gen_subc1 (high0, high0, high2));
1507   DONE;
1510 (define_insn "subc"
1511   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1512         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1513                             (match_operand:SI 2 "arith_reg_operand" "r"))
1514                   (reg:SI T_REG)))
1515    (set (reg:SI T_REG)
1516         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1517                           (reg:SI T_REG))
1518                 (match_dup 1)))]
1519   "TARGET_SH1"
1520   "subc %2,%0"
1521   [(set_attr "type" "arith")])
1523 (define_insn "subc1"
1524   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1525         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1526                             (match_operand:SI 2 "arith_reg_operand" "r"))
1527                   (reg:SI T_REG)))
1528    (clobber (reg:SI T_REG))]
1529   "TARGET_SH1"
1530   "subc %2,%0"
1531   [(set_attr "type" "arith")])
1533 ;; life_analysis thinks rn is live before subc rn,rn, so make a special
1534 ;; pattern for this case.  This helps multimedia applications that compute
1535 ;; the sum of absolute differences.
1536 (define_insn "mov_neg_si_t"
1537   [(set (match_operand:SI 0 "arith_reg_dest" "=r") (neg:SI (reg:SI T_REG)))]
1538   "TARGET_SH1"
1539   "subc %0,%0"
1540   [(set_attr "type" "arith")])
1542 (define_insn "*subsi3_internal"
1543   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1544         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1545                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1546   "TARGET_SH1"
1547   "sub  %2,%0"
1548   [(set_attr "type" "arith")])
1550 (define_insn_and_split "*subsi3_media"
1551   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1552         (minus:SI (match_operand:SI 1 "minuend_operand" "rN")
1553                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1554   "TARGET_SHMEDIA
1555    && (operands[1] != constm1_rtx
1556        || (GET_CODE (operands[2]) != TRUNCATE
1557            && GET_CODE (operands[2]) != SUBREG))"
1558   "sub.l        %N1, %2, %0"
1559   "operands[1] == constm1_rtx"
1560   [(set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))]
1561   ""
1562   [(set_attr "type" "arith_media")
1563    (set_attr "highpart" "ignore")])
1565 (define_split
1566   [(set (match_operand:SI 0 "arith_reg_dest" "")
1567         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1568                                                        "general_extend_operand"
1569                                                        "") 0)) 0)))]
1570   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
1571   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1572    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1573   "")
1575 (define_split
1576   [(set (match_operand:SI 0 "arith_reg_dest" "")
1577         (zero_extend:SI (subreg:QI (not:SI (subreg:SI (match_operand:QI 1
1578                                                        "general_extend_operand"
1579                                                        "") 0)) 3)))]
1580   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
1581   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
1582    (set (match_dup 0) (xor:SI (match_dup 0) (const_int 255)))]
1583   "")
1584 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1585 ;; will sometimes save one instruction.  Otherwise we might get
1586 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1587 ;; are the same.
1589 (define_expand "subsi3"
1590   [(set (match_operand:SI 0 "arith_reg_operand" "")
1591         (minus:SI (match_operand:SI 1 "arith_operand" "")
1592                   (match_operand:SI 2 "arith_reg_operand" "")))]
1593   ""
1594   "
1596   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1597     {
1598       emit_insn (gen_negsi2 (operands[0], operands[2]));
1599       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1600       DONE;
1601     }
1602   if (TARGET_SHMEDIA)
1603     {
1604       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1605         FAIL;
1606       if (operands[1] != const0_rtx && GET_CODE (operands[1]) != SUBREG)
1607         operands[1] = force_reg (SImode, operands[1]);
1608     }
1611 ;; -------------------------------------------------------------------------
1612 ;; Division instructions
1613 ;; -------------------------------------------------------------------------
1615 ;; We take advantage of the library routines which don't clobber as many
1616 ;; registers as a normal function call would.
1618 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1619 ;; also has an effect on the register that holds the address of the sfunc.
1620 ;; To make this work, we have an extra dummy insn that shows the use
1621 ;; of this register for reorg.
1623 (define_insn "use_sfunc_addr"
1624   [(set (reg:SI PR_REG)
1625         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1626   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1627   ""
1628   [(set_attr "length" "0")])
1630 (define_insn "udivsi3_sh2a"
1631   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1632         (udiv:SI (match_operand:SI 1 "arith_reg_operand" "0")
1633                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1634   "TARGET_SH2A"
1635   "divu %2,%1"
1636   [(set_attr "type" "arith")
1637    (set_attr "in_delay_slot" "no")])
1639 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1640 ;; hard register 0.  If we used hard register 0, then the next instruction
1641 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1642 ;; gets allocated to a stack slot that needs its address reloaded, then
1643 ;; there is nothing to prevent reload from using r0 to reload the address.
1644 ;; This reload would clobber the value in r0 we are trying to store.
1645 ;; If we let reload allocate r0, then this problem can never happen.
1647 (define_insn "udivsi3_i1"
1648   [(set (match_operand:SI 0 "register_operand" "=z")
1649         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1650    (clobber (reg:SI T_REG))
1651    (clobber (reg:SI PR_REG))
1652    (clobber (reg:SI R4_REG))
1653    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1654   "TARGET_SH1 && ! TARGET_SH4"
1655   "jsr  @%1%#"
1656   [(set_attr "type" "sfunc")
1657    (set_attr "needs_delay_slot" "yes")])
1659 ; Since shmedia-nofpu code could be linked against shcompact code, and
1660 ; the udivsi3 libcall has the same name, we must consider all registers
1661 ; clobbered that are in the union of the registers clobbered by the
1662 ; shmedia and the shcompact implementation.  Note, if the shcompact
1663 ; implementation actually used shcompact code, we'd need to clobber
1664 ; also r23 and fr23.
1665 (define_insn "udivsi3_i1_media"
1666   [(set (match_operand:SI 0 "register_operand" "=z")
1667         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1668    (clobber (reg:SI T_MEDIA_REG))
1669    (clobber (reg:SI PR_MEDIA_REG))
1670    (clobber (reg:SI R20_REG))
1671    (clobber (reg:SI R21_REG))
1672    (clobber (reg:SI R22_REG))
1673    (clobber (reg:DI TR0_REG))
1674    (clobber (reg:DI TR1_REG))
1675    (clobber (reg:DI TR2_REG))
1676    (use (match_operand 1 "target_operand" "b"))]
1677   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1678   "blink        %1, r18"
1679   [(set_attr "type" "sfunc")
1680    (set_attr "needs_delay_slot" "yes")])
1682 (define_expand "udivsi3_i4_media"
1683   [(set (match_dup 3)
1684         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1685    (set (match_dup 4)
1686         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1687    (set (match_dup 5) (float:DF (match_dup 3)))
1688    (set (match_dup 6) (float:DF (match_dup 4)))
1689    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1690    (set (match_dup 8) (fix:DI (match_dup 7)))
1691    (set (match_operand:SI 0 "register_operand" "")
1692         (truncate:SI (match_dup 8)))]
1693   "TARGET_SHMEDIA_FPU"
1694   "
1696   operands[3] = gen_reg_rtx (DImode);
1697   operands[4] = gen_reg_rtx (DImode);
1698   operands[5] = gen_reg_rtx (DFmode);
1699   operands[6] = gen_reg_rtx (DFmode);
1700   operands[7] = gen_reg_rtx (DFmode);
1701   operands[8] = gen_reg_rtx (DImode);
1704 (define_insn "udivsi3_i4"
1705   [(set (match_operand:SI 0 "register_operand" "=y")
1706         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1707    (clobber (reg:SI T_REG))
1708    (clobber (reg:SI PR_REG))
1709    (clobber (reg:DF DR0_REG))
1710    (clobber (reg:DF DR2_REG))
1711    (clobber (reg:DF DR4_REG))
1712    (clobber (reg:SI R0_REG))
1713    (clobber (reg:SI R1_REG))
1714    (clobber (reg:SI R4_REG))
1715    (clobber (reg:SI R5_REG))
1716    (use (reg:PSI FPSCR_REG))
1717    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1718   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1719   "jsr  @%1%#"
1720   [(set_attr "type" "sfunc")
1721    (set_attr "fp_mode" "double")
1722    (set_attr "needs_delay_slot" "yes")])
1724 (define_insn "udivsi3_i4_single"
1725   [(set (match_operand:SI 0 "register_operand" "=y")
1726         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1727    (clobber (reg:SI T_REG))
1728    (clobber (reg:SI PR_REG))
1729    (clobber (reg:DF DR0_REG))
1730    (clobber (reg:DF DR2_REG))
1731    (clobber (reg:DF DR4_REG))
1732    (clobber (reg:SI R0_REG))
1733    (clobber (reg:SI R1_REG))
1734    (clobber (reg:SI R4_REG))
1735    (clobber (reg:SI R5_REG))
1736    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1737   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1738   "jsr  @%1%#"
1739   [(set_attr "type" "sfunc")
1740    (set_attr "needs_delay_slot" "yes")])
1742 (define_expand "udivsi3"
1743   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1744    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1745    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1746    (parallel [(set (match_operand:SI 0 "register_operand" "")
1747                    (udiv:SI (reg:SI R4_REG)
1748                             (reg:SI R5_REG)))
1749               (clobber (reg:SI T_REG))
1750               (clobber (reg:SI PR_REG))
1751               (clobber (reg:SI R4_REG))
1752               (use (match_dup 3))])]
1753   ""
1754   "
1756   rtx first, last;
1758   operands[3] = gen_reg_rtx (Pmode);
1759   /* Emit the move of the address to a pseudo outside of the libcall.  */
1760   if (TARGET_HARD_SH4 && TARGET_SH2E)
1761     {
1762       function_symbol (operands[3], \"__udivsi3_i4\", SFUNC_STATIC);
1763       if (TARGET_FPU_SINGLE)
1764         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1765       else
1766         last = gen_udivsi3_i4 (operands[0], operands[3]);
1767     }
1768   else if (TARGET_SHMEDIA_FPU)
1769     {
1770       operands[1] = force_reg (SImode, operands[1]);
1771       operands[2] = force_reg (SImode, operands[2]);
1772       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1773       DONE;
1774     }
1775   else if (TARGET_SH2A)
1776     {
1777       operands[1] = force_reg (SImode, operands[1]);
1778       operands[2] = force_reg (SImode, operands[2]);
1779       emit_insn (gen_udivsi3_sh2a (operands[0], operands[1], operands[2]));
1780       DONE;
1781     }
1782   else if (TARGET_SH5)
1783     {
1784       function_symbol (operands[3],
1785                        TARGET_FPU_ANY ? \"__udivsi3_i4\" : \"__udivsi3\",
1786                        SFUNC_STATIC);
1788       if (TARGET_SHMEDIA)
1789         last = gen_udivsi3_i1_media (operands[0], operands[3]);
1790       else if (TARGET_FPU_ANY)
1791         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1792       else
1793         last = gen_udivsi3_i1 (operands[0], operands[3]);
1794     }
1795   else
1796     {
1797       function_symbol (operands[3], \"__udivsi3\", SFUNC_STATIC);
1798       last = gen_udivsi3_i1 (operands[0], operands[3]);
1799     }
1800   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1801   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1802   last = emit_insn (last);
1803   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1804      invariant code motion can move it.  */
1805   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1806   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1807   DONE;
1810 (define_insn "divsi3_sh2a"
1811   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
1812         (div:SI (match_operand:SI 1 "arith_reg_operand" "0")
1813                 (match_operand:SI 2 "arith_reg_operand" "z")))]
1814   "TARGET_SH2A"
1815   "divs %2,%1"
1816   [(set_attr "type" "arith")
1817    (set_attr "in_delay_slot" "no")])
1819 (define_insn "divsi3_i1"
1820   [(set (match_operand:SI 0 "register_operand" "=z")
1821         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1822    (clobber (reg:SI T_REG))
1823    (clobber (reg:SI PR_REG))
1824    (clobber (reg:SI R1_REG))
1825    (clobber (reg:SI R2_REG))
1826    (clobber (reg:SI R3_REG))
1827    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1828   "TARGET_SH1 && ! TARGET_SH4"
1829   "jsr  @%1%#"
1830   [(set_attr "type" "sfunc")
1831    (set_attr "needs_delay_slot" "yes")])
1833 (define_insn "divsi3_i1_media"
1834   [(set (match_operand:SI 0 "register_operand" "=z")
1835         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1836    (clobber (reg:SI T_MEDIA_REG))
1837    (clobber (reg:SI PR_MEDIA_REG))
1838    (clobber (reg:SI R1_REG))
1839    (clobber (reg:SI R20_REG))
1840    (clobber (reg:SI R21_REG))
1841    (clobber (reg:SI TR0_REG))
1842    (use (match_operand 1 "target_operand" "b"))]
1843   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1844   "blink        %1, r18"
1845   [(set_attr "type" "sfunc")])
1847 (define_insn "divsi3_media_2"
1848   [(set (match_operand:SI 0 "register_operand" "=z")
1849         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1850    (clobber (reg:SI T_MEDIA_REG))
1851    (clobber (reg:SI PR_MEDIA_REG))
1852    (clobber (reg:SI R1_REG))
1853    (clobber (reg:SI R21_REG))
1854    (clobber (reg:SI TR0_REG))
1855    (use (reg:SI R20_REG))
1856    (use (match_operand 1 "target_operand" "b"))]
1857   "TARGET_SHMEDIA && (! TARGET_SHMEDIA_FPU || ! TARGET_DIVIDE_FP)"
1858   "blink        %1, r18"
1859   [(set_attr "type" "sfunc")])
1861 ;; This pattern acts as a placeholder for -mdiv=inv:call to carry
1862 ;; hard reg clobbers and data dependencies that we need when we want
1863 ;; to rematerialize the division into a call.
1864 (define_insn_and_split "divsi_inv_call"
1865   [(set (match_operand:SI 0 "register_operand" "=r")
1866         (div:SI (match_operand:SI 1 "register_operand" "r")
1867                 (match_operand:SI 2 "register_operand" "r")))
1868    (clobber (reg:SI R4_REG))
1869    (clobber (reg:SI R5_REG))
1870    (clobber (reg:SI T_MEDIA_REG))
1871    (clobber (reg:SI PR_MEDIA_REG))
1872    (clobber (reg:SI R1_REG))
1873    (clobber (reg:SI R21_REG))
1874    (clobber (reg:SI TR0_REG))
1875    (clobber (reg:SI R20_REG))
1876    (use (match_operand:SI 3 "register_operand" "r"))]
1877   "TARGET_SHMEDIA"
1878   "#"
1879   "&& (high_life_started || reload_completed)"
1880   [(set (match_dup 0) (match_dup 3))]
1881   ""
1882   [(set_attr "highpart" "must_split")])
1884 ;; This is the combiner pattern for -mdiv=inv:call .
1885 (define_insn_and_split "*divsi_inv_call_combine"
1886   [(set (match_operand:SI 0 "register_operand" "=z")
1887         (div:SI (match_operand:SI 1 "register_operand" "r")
1888                 (match_operand:SI 2 "register_operand" "r")))
1889    (clobber (reg:SI R4_REG))
1890    (clobber (reg:SI R5_REG))
1891    (clobber (reg:SI T_MEDIA_REG))
1892    (clobber (reg:SI PR_MEDIA_REG))
1893    (clobber (reg:SI R1_REG))
1894    (clobber (reg:SI R21_REG))
1895    (clobber (reg:SI TR0_REG))
1896    (clobber (reg:SI R20_REG))
1897    (use (unspec:SI [(match_dup 1)
1898                     (match_operand:SI 3 "" "")
1899                     (unspec:SI [(match_operand:SI 4 "" "")
1900                                 (match_dup 3)
1901                                 (match_operand:DI 5 "" "")]
1902                      UNSPEC_DIV_INV_M2)
1903                     (match_operand:DI 6 "" "")
1904                     (const_int 0)
1905                     (const_int 0)]
1906          UNSPEC_DIV_INV_M3))]
1907   "TARGET_SHMEDIA"
1908   "#"
1909   "&& (high_life_started || reload_completed)"
1910   [(pc)]
1911   "
1913   const char *name = sh_divsi3_libfunc;
1914   enum sh_function_kind kind = SFUNC_GOT;
1915   rtx sym;
1917   emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
1918   emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
1919   while (TARGET_DIVIDE_INV_CALL2)
1920     {
1921       rtx x = operands[3];
1923       if (GET_CODE (x) != UNSPEC || XINT (x, 1) != UNSPEC_DIV_INV_M1)
1924         break;
1925       x = XVECEXP (x, 0, 0);
1926       name = \"__sdivsi3_2\";
1927       kind = SFUNC_STATIC;
1928       emit_move_insn (gen_rtx_REG (DImode, R20_REG), x);
1929       break;
1930     }
1931   sym = function_symbol (NULL, name, kind);
1932   emit_insn (gen_divsi3_media_2 (operands[0], sym));
1933   DONE;
1935   [(set_attr "highpart" "must_split")])
1937 (define_expand "divsi3_i4_media"
1938   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1939    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1940    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1941    (set (match_operand:SI 0 "register_operand" "=r")
1942         (fix:SI (match_dup 5)))]
1943   "TARGET_SHMEDIA_FPU"
1944   "
1946   operands[3] = gen_reg_rtx (DFmode);
1947   operands[4] = gen_reg_rtx (DFmode);
1948   operands[5] = gen_reg_rtx (DFmode);
1951 (define_insn "divsi3_i4"
1952   [(set (match_operand:SI 0 "register_operand" "=y")
1953         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1954    (clobber (reg:SI PR_REG))
1955    (clobber (reg:DF DR0_REG))
1956    (clobber (reg:DF DR2_REG))
1957    (use (reg:PSI FPSCR_REG))
1958    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1959   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1960   "jsr  @%1%#"
1961   [(set_attr "type" "sfunc")
1962    (set_attr "fp_mode" "double")
1963    (set_attr "needs_delay_slot" "yes")])
1965 (define_insn "divsi3_i4_single"
1966   [(set (match_operand:SI 0 "register_operand" "=y")
1967         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1968    (clobber (reg:SI PR_REG))
1969    (clobber (reg:DF DR0_REG))
1970    (clobber (reg:DF DR2_REG))
1971    (clobber (reg:SI R2_REG))
1972    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1973   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1974   "jsr  @%1%#"
1975   [(set_attr "type" "sfunc")
1976    (set_attr "needs_delay_slot" "yes")])
1978 (define_expand "divsi3"
1979   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1980    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1981    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1982    (parallel [(set (match_operand:SI 0 "register_operand" "")
1983                    (div:SI (reg:SI R4_REG)
1984                            (reg:SI R5_REG)))
1985               (clobber (reg:SI T_REG))
1986               (clobber (reg:SI PR_REG))
1987               (clobber (reg:SI R1_REG))
1988               (clobber (reg:SI R2_REG))
1989               (clobber (reg:SI R3_REG))
1990               (use (match_dup 3))])]
1991   ""
1992   "
1994   rtx first, last;
1996   operands[3] = gen_reg_rtx (Pmode);
1997   /* Emit the move of the address to a pseudo outside of the libcall.  */
1998   if (TARGET_HARD_SH4 && TARGET_SH2E)
1999     {
2000       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2001       if (TARGET_FPU_SINGLE)
2002         last = gen_divsi3_i4_single (operands[0], operands[3]);
2003       else
2004         last = gen_divsi3_i4 (operands[0], operands[3]);
2005     }
2006   else if (TARGET_SH2A)
2007     {
2008       operands[1] = force_reg (SImode, operands[1]);
2009       operands[2] = force_reg (SImode, operands[2]);
2010       emit_insn (gen_divsi3_sh2a (operands[0], operands[1], operands[2]));
2011       DONE;
2012     }
2013   else if (TARGET_DIVIDE_INV)
2014     {
2015       rtx dividend = operands[1];
2016       rtx divisor = operands[2];
2017       rtx tab_base;
2018       rtx nsb_res = gen_reg_rtx (DImode);
2019       rtx norm64 = gen_reg_rtx (DImode);
2020       rtx tab_ix = gen_reg_rtx (DImode);
2021       rtx norm32 = gen_reg_rtx (SImode);
2022       rtx i92 = force_reg (DImode, GEN_INT (92));
2023       rtx scratch0a = gen_reg_rtx (DImode);
2024       rtx scratch0b = gen_reg_rtx (DImode);
2025       rtx inv0 = gen_reg_rtx (SImode);
2026       rtx scratch1a = gen_reg_rtx (DImode);
2027       rtx scratch1b = gen_reg_rtx (DImode);
2028       rtx shift = gen_reg_rtx (DImode);
2029       rtx i2p27, i43;
2030       rtx inv1 = gen_reg_rtx (SImode);
2031       rtx scratch2a = gen_reg_rtx (DImode);
2032       rtx scratch2b = gen_reg_rtx (SImode);
2033       rtx inv2 = gen_reg_rtx (SImode);
2034       rtx scratch3a = gen_reg_rtx (DImode);
2035       rtx scratch3b = gen_reg_rtx (DImode);
2036       rtx scratch3c = gen_reg_rtx (DImode);
2037       rtx scratch3d = gen_reg_rtx (SImode);
2038       rtx scratch3e = gen_reg_rtx (DImode);
2039       rtx result = gen_reg_rtx (SImode);
2041       if (! arith_reg_or_0_operand (dividend, SImode))
2042         dividend = force_reg (SImode, dividend);
2043       if (! arith_reg_operand (divisor, SImode))
2044         divisor = force_reg (SImode, divisor);
2045       if (flag_pic && Pmode != DImode)
2046         {
2047           tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2048           tab_base = gen_datalabel_ref (tab_base);
2049           tab_base = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, tab_base));
2050         }
2051       else
2052         {
2053           tab_base = gen_rtx_SYMBOL_REF (DImode, \"__div_table\");
2054           tab_base = gen_datalabel_ref (tab_base);
2055           tab_base = force_reg (DImode, tab_base);
2056         }
2057       if (TARGET_DIVIDE_INV20U)
2058         i2p27 = force_reg (DImode, GEN_INT (-2 << 27));
2059       else
2060         i2p27 = GEN_INT (0);
2061       if (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)
2062         i43 = force_reg (DImode, GEN_INT (43));
2063       else
2064         i43 = GEN_INT (0);
2065       emit_insn (gen_nsbdi (nsb_res,
2066                             simplify_gen_subreg (DImode, divisor, SImode, 0)));
2067       emit_insn (gen_ashldi3_media (norm64,
2068                                     gen_rtx_SUBREG (DImode, divisor, 0),
2069                                     nsb_res));
2070       emit_insn (gen_ashrdi3_media (tab_ix, norm64, GEN_INT (58)));
2071       emit_insn (gen_ashrdisi3_media_high (norm32, norm64, GEN_INT (32)));
2072       emit_insn (gen_divsi_inv_m1 (inv1, tab_base, tab_ix, norm32,
2073                                    inv0, scratch0a, scratch0b,
2074                                    scratch1a, scratch1b));
2075       emit_insn (gen_subdi3 (shift, i92, nsb_res));
2076       emit_insn (gen_divsi_inv_m2 (inv2, norm32, inv1, i92,
2077                                    scratch2a));
2078       emit_insn (gen_divsi_inv_m3 (result, dividend, inv1, inv2, shift,
2079                                    i2p27, i43,
2080                                    scratch3a, scratch3b, scratch3c,
2081                                    scratch2a, scratch2b, scratch3d, scratch3e));
2082       if (TARGET_DIVIDE_INV_CALL || TARGET_DIVIDE_INV_CALL2)
2083         emit_insn (gen_divsi_inv_call (operands[0], dividend, divisor, result));
2084       else if (TARGET_DIVIDE_INV_FP)
2085         emit_insn (gen_divsi_inv_fp (operands[0], dividend, divisor, result,
2086                                      gen_reg_rtx (SImode), gen_reg_rtx (SImode),
2087                                      gen_reg_rtx (DFmode), gen_reg_rtx (DFmode),
2088                                      gen_reg_rtx (DFmode)));
2089       else
2090         emit_move_insn (operands[0], result);
2091       DONE;
2092     }
2093   else if (TARGET_SHMEDIA_FPU && TARGET_DIVIDE_FP)
2094     {
2095       operands[1] = force_reg (SImode, operands[1]);
2096       operands[2] = force_reg (SImode, operands[2]);
2097       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
2098       DONE;
2099     }
2100   else if (TARGET_SH5)
2101     {
2102       if (TARGET_DIVIDE_CALL2)
2103         {
2104           rtx tab_base = gen_rtx_SYMBOL_REF (Pmode, \"__div_table\");
2105           tab_base = gen_datalabel_ref (tab_base);
2106           emit_move_insn (gen_rtx_REG (Pmode, R20_REG), tab_base);
2107         }
2108       if (TARGET_FPU_ANY && TARGET_SH1)
2109         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_STATIC);
2110       else if (TARGET_DIVIDE_CALL2)
2111         function_symbol (operands[3], \"__sdivsi3_2\", SFUNC_STATIC);
2112       else
2113         function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2115       if (TARGET_SHMEDIA)
2116         last = ((TARGET_DIVIDE_CALL2 ? gen_divsi3_media_2 : gen_divsi3_i1_media)
2117                 (operands[0], operands[3]));
2118       else if (TARGET_FPU_ANY)
2119         last = gen_divsi3_i4_single (operands[0], operands[3]);
2120       else
2121         last = gen_divsi3_i1 (operands[0], operands[3]);
2122     }
2123   else
2124     {
2125       function_symbol (operands[3], sh_divsi3_libfunc, SFUNC_GOT);
2126       last = gen_divsi3_i1 (operands[0], operands[3]);
2127     }
2128   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
2129   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
2130   last = emit_insn (last);
2131   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2132      invariant code motion can move it.  */
2133   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2134   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2135   DONE;
2138 ;; operands: inv0, tab_base, tab_ix, norm32
2139 ;; scratch equiv in sdivsi3_2: r19, r21
2140 (define_expand "divsi_inv_m0"
2141   [(set (match_operand:SI 0 "register_operand" "=r")
2142         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2143                     (match_operand:DI 2 "register_operand" "r")
2144                     (match_operand:SI 3 "register_operand" "r")]
2145          UNSPEC_DIV_INV_M0))
2146    (clobber (match_operand:DI 4 "register_operand" "=r"))
2147    (clobber (match_operand:DI 5 "register_operand" "=r"))]
2148   "TARGET_SHMEDIA"
2149   "
2152 tab_base: r20
2153 tab_ix: r21
2154 norm32: r25
2155  ldx.ub r20, r21, r19 // u0.8
2156  shlli r21, 1, r21
2157  muls.l r25, r19, r19 // s2.38
2158  ldx.w r20, r21, r21  // s2.14
2159  shari r19, 24, r19   // truncate to s2.14
2160  sub r21, r19, r19    // some 11 bit inverse in s1.14
2163   rtx inv0 = operands[0];
2164   rtx tab_base = operands[1];
2165   rtx tab_ix = operands[2];
2166   rtx norm32 = operands[3];
2167   rtx scratch0 = operands[4];
2168   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2169   rtx scratch1 = operands[5];
2170   rtx mem;
2172   mem = gen_rtx_MEM (QImode, gen_rtx_PLUS (DImode, tab_base, tab_ix));
2173   emit_insn (gen_zero_extendqidi2 (scratch0, mem));
2174   emit_insn (gen_ashldi3_media (scratch1, tab_ix, GEN_INT (1)));
2175   emit_insn (gen_mulsidi3_media (scratch0, norm32, scratch0_si));
2176   mem = gen_rtx_MEM (HImode, gen_rtx_PLUS (DImode, tab_base, scratch1));
2177   emit_insn (gen_extendhidi2 (scratch1, mem));
2178   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (24)));
2179   emit_insn (gen_subdisi3_media (inv0, scratch1, scratch0));
2180   DONE;
2183 ;; operands: inv1, tab_base, tab_ix, norm32
2184 (define_insn_and_split "divsi_inv_m1"
2185   [(set (match_operand:SI 0 "register_operand" "=r")
2186         (unspec:SI [(match_operand:DI 1 "register_operand" "r")
2187                     (match_operand:DI 2 "register_operand" "r")
2188                     (match_operand:SI 3 "register_operand" "r")]
2189          UNSPEC_DIV_INV_M1))
2190    (clobber (match_operand:SI 4 "register_operand" "=r"))
2191    (clobber (match_operand:DI 5 "register_operand" "=r"))
2192    (clobber (match_operand:DI 6 "register_operand" "=r"))
2193    (clobber (match_operand:DI 7 "register_operand" "=r"))
2194    (clobber (match_operand:DI 8 "register_operand" "=r"))]
2195   "TARGET_SHMEDIA"
2196   "#"
2197   "&& no_new_pseudos"
2198   [(pc)]
2199   "
2201 /* inv0: r19
2202  muls.l r19, r19, r18 // u0.28
2203  muls.l r25, r18, r18 // s2.58
2204  shlli r19, 45, r0    // multiply by two and convert to s2.58
2205  sub r0, r18, r18
2206  shari r18, 28, r18   // some 18 bit inverse in s1.30
2209   rtx inv1 = operands[0];
2210   rtx tab_base = operands[1];
2211   rtx tab_ix = operands[2];
2212   rtx norm32 = operands[3];
2213   rtx inv0 = operands[4];
2214   rtx inv0_di = simplify_gen_subreg (DImode, inv0, SImode, 0);
2215   rtx scratch0a = operands[5];
2216   rtx scratch0b = operands[6];
2217   rtx scratch0 = operands[7];
2218   rtx scratch1 = operands[8];
2219   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2221   emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32,
2222                                scratch0a, scratch0b));
2223   emit_insn (gen_mulsidi3_media (scratch1, inv0, inv0));
2224   emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2225   emit_insn (gen_ashldi3_media (scratch0, inv0_di, GEN_INT (45)));
2226   emit_insn (gen_subdi3 (scratch1, scratch0, scratch1));
2227   emit_insn (gen_ashrdisi3_media_opaque (inv1, scratch1, GEN_INT (28)));
2228   DONE;
2231 ;; operands: inv2, norm32, inv1, i92
2232 (define_insn_and_split "divsi_inv_m2"
2233   [(set (match_operand:SI 0 "register_operand" "=r")
2234         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
2235                     (match_operand:SI 2 "register_operand" "r")
2236                     (match_operand:DI 3 "register_operand" "r")]
2237          UNSPEC_DIV_INV_M2))
2238    (clobber (match_operand:DI 4 "register_operand" "=r"))]
2239   "TARGET_SHMEDIA"
2240   "#"
2241   "&& no_new_pseudos"
2242   [(pc)]
2243   "
2246  muls.l r18, r25, r0  // s2.60
2247  shari r0, 16, r0     // s-16.44
2248   sub
2249  muls.l r0, r18, r19  // s-16.74
2250  shari r19, 30, r19   // s-16.44
2252   rtx inv2 = operands[0];
2253   rtx norm32 = operands[1];
2254   rtx inv1 = operands[2];
2255   rtx i92 = operands[3];
2256   rtx scratch0 = operands[4];
2257   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2259   emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32));
2260   emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16)));
2261   emit_insn (gen_subdi3 (scratch0, i92, scratch0));
2262   emit_insn (gen_mulsidi3_media (scratch0, scratch0_si, inv1));
2263   emit_insn (gen_ashrdisi3_media_opaque (inv2, scratch0, GEN_INT (30)));
2264   DONE;
2267 (define_insn_and_split "divsi_inv_m3"
2268   [(set (match_operand:SI 0 "register_operand" "=r")
2269         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2270                     (match_operand:SI 2 "register_operand" "r")
2271                     (match_operand:SI 3 "register_operand" "r")
2272                     (match_operand:DI 4 "register_operand" "r")
2273                     (match_operand:DI 5 "arith_reg_or_0_operand" "rN")
2274                     (match_operand:DI 6 "arith_reg_or_0_operand" "rN")]
2275          UNSPEC_DIV_INV_M3))
2276    (clobber (match_operand:DI 7 "register_operand" "=r"))
2277    (clobber (match_operand:DI 8 "register_operand" "=r"))
2278    (clobber (match_operand:DI 9 "register_operand" "=r"))
2279    (clobber (match_operand:DI 10 "register_operand" "=r"))
2280    (clobber (match_operand:SI 11 "register_operand" "=r"))
2281    (clobber (match_operand:SI 12 "register_operand" "=r"))
2282    (clobber (match_operand:DI 13 "register_operand" "=r"))]
2283   "TARGET_SHMEDIA"
2284   "#"
2285   "&& no_new_pseudos"
2286   [(pc)]
2287   "
2290   r0: result  r1: shift  r4: dividend  r18: inv1  r19: inv2
2291   r0: scratch0  r19: scratch1 r21: scratch2
2293   muls.l r18, r4, r25 // s32.30
2294  muls.l r19, r4, r19  // s15.30
2295  shari r25, 63, r21
2296   shari r19, 14, r19  // s18.-14
2297  sub r25, r19, r0
2298  shard r0, r1, r0
2299  sub r0, r21, r0
2302   rtx result = operands[0];
2303   rtx dividend = operands[1];
2304   rtx inv1 = operands[2];
2305   rtx inv2 = operands[3];
2306   rtx shift = operands[4];
2307   rtx scratch0 = operands[7];
2308   rtx scratch1 = operands[8];
2309   rtx scratch2 = operands[9];
2311   emit_insn (gen_mulsidi3_media (scratch0, inv1, dividend));
2312   emit_insn (gen_mulsidi3_media (scratch1, inv2, dividend));
2313   emit_insn (gen_ashrdi3_media (scratch2, scratch0, GEN_INT (63)));
2314   emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (14)));
2315   emit_insn (gen_adddi3 (scratch0, scratch0, scratch1));
2316   emit_insn (gen_ashrdi3_media (scratch0, scratch0, shift));
2317   emit_insn (gen_subdisi3_media (result, scratch0, scratch2));
2318   DONE;
2321 ;; operands: quotient, dividend, inv1, inv2, shift, i2p27, i43
2322 ;; inv1: tab_base, tab_ix, norm32
2323 ;; inv2: norm32, inv1, i92
2324 (define_insn_and_split "divsi_inv_m1_3"
2325   [(set (match_operand:SI 0 "register_operand" "=r")
2326         (unspec:SI [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
2327                     (unspec:SI [(match_operand:DI 2 "register_operand" "r")
2328                                 (match_operand:DI 3 "register_operand" "r")
2329                                 (match_operand:SI 4 "register_operand" "r")]
2330                      UNSPEC_DIV_INV_M1)
2331                     (unspec:SI [(match_dup 4)
2332                                 (unspec:SI [(match_dup 2)
2333                                             (match_dup 3)
2334                                             (match_dup 4)] UNSPEC_DIV_INV_M1)
2335                                 (match_operand:SI 5 "" "")]
2336                      UNSPEC_DIV_INV_M2)
2337                     (match_operand:DI 6 "register_operand" "r")
2338                     (match_operand:DI 7 "arith_reg_or_0_operand" "rN")
2339                     (match_operand:DI 8 "arith_reg_or_0_operand" "rN")]
2340          UNSPEC_DIV_INV_M3))
2341    (clobber (match_operand:DI 9 "register_operand" "=r"))
2342    (clobber (match_operand:DI 10 "register_operand" "=r"))
2343    (clobber (match_operand:DI 11 "register_operand" "=r"))
2344    (clobber (match_operand:DI 12 "register_operand" "=r"))
2345    (clobber (match_operand:SI 13 "register_operand" "=r"))
2346    (clobber (match_operand:SI 14 "register_operand" "=r"))
2347    (clobber (match_operand:DI 15 "register_operand" "=r"))]
2348   "TARGET_SHMEDIA
2349    && (TARGET_DIVIDE_INV_MINLAT
2350        || TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2351   "#"
2352   "&& no_new_pseudos"
2353   [(pc)]
2354   "
2356   rtx result = operands[0];
2357   rtx dividend = operands[1];
2358   rtx tab_base = operands[2];
2359   rtx tab_ix = operands[3];
2360   rtx norm32 = operands[4];
2361   /* rtx i92 = operands[5]; */
2362   rtx shift = operands[6];
2363   rtx i2p27 = operands[7];
2364   rtx i43 = operands[8];
2365   rtx scratch0 = operands[9];
2366   rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF);
2367   rtx scratch1 = operands[10];
2368   rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF);
2369   rtx scratch2 = operands[11];
2370   rtx scratch3 = operands[12];
2371   rtx scratch4 = operands[13];
2372   rtx scratch4_di = simplify_gen_subreg (DImode, scratch4, SImode, 0);
2373   rtx scratch5 = operands[14];
2374   rtx scratch5_di = simplify_gen_subreg (DImode, scratch5, SImode, 0);
2375   rtx scratch6 = operands[15];
2377   emit_insn (gen_divsi_inv_m0 (scratch4, tab_base, tab_ix, norm32,
2378                                scratch0, scratch1));
2379   /* inv0 == scratch4 */
2380   if (! TARGET_DIVIDE_INV20U)
2381     {
2382       emit_insn (gen_mulsidi3_media (scratch0, scratch4, scratch4));
2383       i2p27 = scratch0;
2384       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch0_si));
2385     }
2386   else
2387     {
2388       emit_insn (gen_mulsidi3_media (scratch1, scratch4, scratch4));
2389       emit_insn (gen_mulsidi3_media (scratch1, norm32, scratch1_si));
2390     }
2391   emit_insn (gen_ashldi3_media (scratch2, scratch4_di, GEN_INT (45)));
2392   emit_insn (gen_subdi3 (scratch1, scratch2, scratch1));
2393   emit_insn (gen_ashrdisi3_media_opaque (scratch4, scratch1, GEN_INT (28)));
2394   /* inv1 == scratch4 */
2396   if (TARGET_DIVIDE_INV_MINLAT)
2397     {
2398       emit_insn (gen_mulsidi3_media (scratch1, scratch4, norm32));
2399       emit_insn (gen_mulsidi3_media (scratch2, dividend, scratch4));
2400       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (16)));
2401       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch4));
2402       emit_insn (gen_ashrdi3_media (scratch3, scratch2, GEN_INT (63)));
2403       emit_insn (gen_ashrsi3_media (scratch5, dividend, GEN_INT (14)));
2404       emit_insn (gen_ashrdi3_media (scratch1, scratch1, GEN_INT (30)));
2405       emit_insn (gen_mulsidi3_media (scratch1, scratch1_si, scratch5));
2406       emit_insn (gen_xordi3 (scratch0, scratch3, i2p27));
2407       emit_insn (gen_adddi3 (scratch2, scratch2, scratch0));
2408       emit_insn (gen_subdi3 (scratch2, scratch2, scratch1));
2409     }
2410   else
2411     {
2412       rtx label = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
2413       /* Use separate scratch regs for nsb and sign to allow scheduling.  */
2414       emit_insn (gen_nsbdi (scratch6,
2415                             simplify_gen_subreg (DImode, dividend, SImode, 0)));
2416       emit_insn (gen_xorsi3 (scratch5, dividend, norm32));
2417       emit_insn (gen_ashrdi3_media (scratch3, scratch5_di, GEN_INT (63)));
2418       emit_insn (gen_divsi_inv20 (scratch2,
2419                                   norm32, scratch4, dividend,
2420                                   scratch6, scratch3, i43,
2421                                   /* scratch0 may be shared with i2p27.  */
2422                                   scratch0, scratch1, scratch5,
2423                                   label, label, i2p27));
2424     }
2425   emit_insn (gen_ashrdi3_media (scratch2, scratch2, shift));
2426   emit_insn (gen_subdisi3_media (result, scratch2, scratch3));
2427   DONE;
2430 (define_insn "divsi_inv20"
2431   [(set (match_operand:DI 0 "register_operand" "=&r")
2432         (unspec:DI [(match_operand:SI 1 "register_operand" "r")
2433                     (match_operand:SI 2 "register_operand" "r")
2434                     (match_operand:SI 3 "register_operand" "r")
2435                     (match_operand:DI 4 "register_operand" "r")
2436                     (match_operand:DI 5 "register_operand" "r")
2437                     (match_operand:DI 6 "register_operand" "r")
2438                     (match_operand:DI 12 "register_operand" "r")
2439                     (match_operand 10 "target_operand" "b")
2440                     (match_operand 11 "immediate_operand" "i")]
2441          UNSPEC_DIV_INV20))
2442    (clobber (match_operand:DI 7 "register_operand" "=&r"))
2443    (clobber (match_operand:DI 8 "register_operand" "=&r"))
2444    (clobber (match_operand:SI 9 "register_operand" "=r"))]
2445   "TARGET_SHMEDIA
2446    && (TARGET_DIVIDE_INV20U || TARGET_DIVIDE_INV20L)"
2447   "*
2449 /* operands: %0 div_result, %1 norm32, %2 inv1, %3 dividend,
2450              %4 dividend_nsb, %5 result_sign, %6 i43, %12 i2p27,
2451              %7 round_scratch, %8 scratch0 (di), %9 scratch1 (si)
2452              %10 label (tr), %11 label (imm)
2454  muls.l inv1, norm32, scratch0  // s2.60
2455   muls.l inv1, dividend, result // s32.30
2456   xor i2p27, result_sign, round_scratch
2457  bge/u dividend_nsb, i43, tr.. (label)
2458  shari scratch0, 16, scratch0   // s-16.44
2459  muls.l sratch0_si, inv1, scratch0 // s-16.74
2460   sub result, round_scratch, result
2461   shari dividend, 14, scratch1   // s19.-14
2462  shari scratch0, 30, scratch0   // s-16.44
2463  muls.l scratch0, scratch1, round_scratch // s15.30
2464 label:
2465  sub result, round_scratch, result */
2467   int likely = TARGET_DIVIDE_INV20L;
2469   if (! likely) output_asm_insn (\"muls.l\t%2, %1 , %8\", operands);
2470   output_asm_insn (\"muls.l\t%2, %3, %0\;xor\t%12, %5, %7\", operands);
2471   output_asm_insn (likely
2472                    ? \"bge/l\t%4, %6, %10\;muls.l\t%2, %1 , %8\"
2473                    : \"bge/u\t%4, %6, %10\", operands);
2474   output_asm_insn (\"shari\t%8, 16, %8\;muls.l\t%8, %2, %8\", operands);
2475   if (! likely) output_asm_insn (\"sub\t%0, %7, %0\", operands);
2476   output_asm_insn (\"shari\t%3, 14, %9\;shari\t%8, 30, %8\", operands);
2477   return (likely
2478           ? \"muls.l\t%8, %9, %8\;sub\t%0, %8, %0\n%11:\tadd\t%0, %7, %0\"
2479           : \"muls.l\t%8, %9, %7\n%11:\tsub\t%0, %7, %0\");
2482 (define_insn_and_split "divsi_inv_fp"
2483   [(set (match_operand:SI 0 "general_movdst_operand" "=rf")
2484         (div:SI (match_operand:SI 1 "general_movsrc_operand" "rf")
2485                 (match_operand:SI 2 "register_operand" "rf")))
2486    (use (match_operand:SI 3 "general_movsrc_operand" "r"))
2487    (clobber (match_operand:SI 4 "register_operand" "=r"))
2488    (clobber (match_operand:SI 5 "register_operand" "=r"))
2489    (clobber (match_operand:DF 6 "register_operand" "=r"))
2490    (clobber (match_operand:DF 7 "register_operand" "=r"))
2491    (clobber (match_operand:DF 8 "register_operand" "=r"))]
2492   "TARGET_SHMEDIA_FPU"
2493   "#"
2494   "&& (high_life_started || reload_completed)"
2495   [(set (match_dup 0) (match_dup 3))]
2496   ""
2497   [(set_attr "highpart" "must_split")])
2499 ;; If a matching group of divide-by-inverse instructions is in the same
2500 ;; basic block after gcse & loop optimizations, we want to transform them
2501 ;; to a straight division using floating point for TARGET_DIVIDE_INV_FP.
2502 (define_insn_and_split "*divsi_inv_fp_combine"
2503   [(set (match_operand:SI 0 "register_operand" "=f")
2504         (div:SI (match_operand:SI 1 "register_operand" "f")
2505                 (match_operand:SI 2 "register_operand" "f")))
2506    (use (unspec:SI [(match_dup 1)
2507                     (match_operand:SI 3 "" "")
2508                     (unspec:SI [(match_operand:SI 4 "" "")
2509                                 (match_dup 3)
2510                                 (match_operand:DI 5 "" "")] UNSPEC_DIV_INV_M2)
2511                     (match_operand:DI 6 "" "")
2512                     (const_int 0)
2513                     (const_int 0)] UNSPEC_DIV_INV_M3))
2514    (clobber (match_operand:SI 7 "fp_arith_reg_operand" ""))
2515    (clobber (match_operand:SI 8 "fp_arith_reg_operand" ""))
2516    (clobber (match_operand:DF 9 "fp_arith_reg_operand" ""))
2517    (clobber (match_operand:DF 10 "fp_arith_reg_operand" ""))
2518    (clobber (match_operand:DF 11 "fp_arith_reg_operand" ""))]
2519   "TARGET_SHMEDIA_FPU && TARGET_DIVIDE_INV_FP && no_new_pseudos"
2520   "#"
2521   "&& 1"
2522   [(set (match_dup 9) (float:DF (match_dup 1)))
2523    (set (match_dup 10) (float:DF (match_dup 2)))
2524    (set (match_dup 11) (div:DF (match_dup 9) (match_dup 10)))
2525    (set (match_dup 8)
2526         (fix:SI (match_dup 11)))
2527    (set (match_dup 0) (match_dup 8))]
2528   "
2530   if (! fp_arith_reg_operand (operands[1], SImode))
2531     {
2532       emit_move_insn (operands[7], operands[1]);
2533       operands[1] = operands[7];
2534     }
2535   if (! fp_arith_reg_operand (operands[2], SImode))
2536     {
2537       emit_move_insn (operands[8], operands[2]);
2538       operands[2] = operands[8];
2539     }
2541   [(set_attr "highpart" "must_split")])
2543 ;; -------------------------------------------------------------------------
2544 ;; Multiplication instructions
2545 ;; -------------------------------------------------------------------------
2547 (define_insn "umulhisi3_i"
2548   [(set (reg:SI MACL_REG)
2549         (mult:SI (zero_extend:SI
2550                   (match_operand:HI 0 "arith_reg_operand" "r"))
2551                  (zero_extend:SI
2552                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2553   "TARGET_SH1"
2554   "mulu.w       %1,%0"
2555   [(set_attr "type" "smpy")])
2557 (define_insn "mulhisi3_i"
2558   [(set (reg:SI MACL_REG)
2559         (mult:SI (sign_extend:SI
2560                   (match_operand:HI 0 "arith_reg_operand" "r"))
2561                  (sign_extend:SI
2562                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
2563   "TARGET_SH1"
2564   "muls.w       %1,%0"
2565   [(set_attr "type" "smpy")])
2567 (define_expand "mulhisi3"
2568   [(set (reg:SI MACL_REG)
2569         (mult:SI (sign_extend:SI
2570                   (match_operand:HI 1 "arith_reg_operand" ""))
2571                  (sign_extend:SI
2572                   (match_operand:HI 2 "arith_reg_operand" ""))))
2573    (set (match_operand:SI 0 "arith_reg_operand" "")
2574         (reg:SI MACL_REG))]
2575   "TARGET_SH1"
2576   "
2578   rtx first, last;
2580   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
2581   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2582   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2583      invariant code motion can move it.  */
2584   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2585   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2586   /* expand_binop can't find a suitable code in umul_widen_optab to
2587      make a REG_EQUAL note from, so make one here.
2588      See also smulsi3_highpart.
2589      ??? Alternatively, we could put this at the calling site of expand_binop,
2590      i.e. expand_expr.  */
2591   REG_NOTES (last)
2592     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2593                          REG_NOTES (last));
2594   DONE;
2597 (define_expand "umulhisi3"
2598   [(set (reg:SI MACL_REG)
2599         (mult:SI (zero_extend:SI
2600                   (match_operand:HI 1 "arith_reg_operand" ""))
2601                  (zero_extend:SI
2602                   (match_operand:HI 2 "arith_reg_operand" ""))))
2603    (set (match_operand:SI 0 "arith_reg_operand" "")
2604         (reg:SI MACL_REG))]
2605   "TARGET_SH1"
2606   "
2608   rtx first, last;
2610   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
2611   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
2612   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2613      invariant code motion can move it.  */
2614   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2615   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2616   /* expand_binop can't find a suitable code in umul_widen_optab to
2617      make a REG_EQUAL note from, so make one here.
2618      See also smulsi3_highpart.
2619      ??? Alternatively, we could put this at the calling site of expand_binop,
2620      i.e. expand_expr.  */
2621   REG_NOTES (last)
2622     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2623                          REG_NOTES (last));
2624   DONE;
2627 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
2628 ;; a call to a routine which clobbers known registers.
2630 (define_insn ""
2631   [(set (match_operand:SI 1 "register_operand" "=z")
2632         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
2633    (clobber (reg:SI MACL_REG))
2634    (clobber (reg:SI T_REG))
2635    (clobber (reg:SI PR_REG))
2636    (clobber (reg:SI R3_REG))
2637    (clobber (reg:SI R2_REG))
2638    (clobber (reg:SI R1_REG))
2639    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
2640   "TARGET_SH1"
2641   "jsr  @%0%#"
2642   [(set_attr "type" "sfunc")
2643    (set_attr "needs_delay_slot" "yes")])
2645 (define_expand "mulsi3_call"
2646   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
2647    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
2648    (parallel[(set (match_operand:SI 0 "register_operand" "")
2649                   (mult:SI (reg:SI R4_REG)
2650                            (reg:SI R5_REG)))
2651              (clobber (reg:SI MACL_REG))
2652              (clobber (reg:SI T_REG))
2653              (clobber (reg:SI PR_REG))
2654              (clobber (reg:SI R3_REG))
2655              (clobber (reg:SI R2_REG))
2656              (clobber (reg:SI R1_REG))
2657              (use (match_operand:SI 3 "register_operand" ""))])]
2658   "TARGET_SH1"
2659   "")
2661 (define_insn "mul_r"
2662   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
2663         (mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
2664                  (match_operand:SI 2 "arith_reg_operand" "z")))]
2665   "TARGET_SH2A"
2666   "mulr %2,%0"
2667   [(set_attr "type" "dmpy")])
2669 (define_insn "mul_l"
2670   [(set (reg:SI MACL_REG)
2671         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
2672                  (match_operand:SI 1 "arith_reg_operand" "r")))]
2673   "TARGET_SH2"
2674   "mul.l        %1,%0"
2675   [(set_attr "type" "dmpy")])
2677 (define_expand "mulsi3"
2678   [(set (reg:SI MACL_REG)
2679         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
2680                   (match_operand:SI 2 "arith_reg_operand" "")))
2681    (set (match_operand:SI 0 "arith_reg_operand" "")
2682         (reg:SI MACL_REG))]
2683   "TARGET_SH1"
2684   "
2686   rtx first, last;
2688   if (!TARGET_SH2)
2689     {
2690       /* The address must be set outside the libcall,
2691          since it goes into a pseudo.  */
2692       rtx sym = function_symbol (NULL, \"__mulsi3\", SFUNC_STATIC);
2693       rtx addr = force_reg (SImode, sym);
2694       rtx insns = gen_mulsi3_call (operands[0], operands[1],
2695                                    operands[2], addr);
2696       first = insns;
2697       last = emit_insn (insns);
2698     }
2699   else
2700     {
2701       rtx macl = gen_rtx_REG (SImode, MACL_REG);
2703       first = emit_insn (gen_mul_l (operands[1], operands[2]));
2704       /* consec_sets_giv can only recognize the first insn that sets a
2705          giv as the giv insn.  So we must tag this also with a REG_EQUAL
2706          note.  */
2707       last = emit_insn (gen_movsi_i ((operands[0]), macl));
2708     }
2709   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2710      invariant code motion can move it.  */
2711   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2712   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2713   DONE;
2716 (define_insn "mulsidi3_i"
2717   [(set (reg:SI MACH_REG)
2718         (truncate:SI
2719          (lshiftrt:DI
2720           (mult:DI
2721            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2722            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2723           (const_int 32))))
2724    (set (reg:SI MACL_REG)
2725         (mult:SI (match_dup 0)
2726                  (match_dup 1)))]
2727   "TARGET_SH2"
2728   "dmuls.l      %1,%0"
2729   [(set_attr "type" "dmpy")])
2731 (define_expand "mulsidi3"
2732   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2733         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2734                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2735   "TARGET_SH2 || TARGET_SHMEDIA"
2736   "
2738   if (TARGET_SH2)
2739     {
2740        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
2741                                         operands[2]));
2742        DONE;
2743     }
2746 (define_insn "mulsidi3_media"
2747   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2748         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2749                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2750   "TARGET_SHMEDIA"
2751   "muls.l       %1, %2, %0"
2752   [(set_attr "type" "dmpy_media")
2753    (set_attr "highpart" "ignore")])
2755 (define_insn "mulsidi3_compact"
2756   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2757         (mult:DI
2758          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2759          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2760    (clobber (reg:SI MACH_REG))
2761    (clobber (reg:SI MACL_REG))]
2762   "TARGET_SH2"
2763   "#")
2765 (define_split
2766   [(set (match_operand:DI 0 "arith_reg_dest" "")
2767         (mult:DI
2768          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2769          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2770    (clobber (reg:SI MACH_REG))
2771    (clobber (reg:SI MACL_REG))]
2772   "TARGET_SH2"
2773   [(const_int 0)]
2774   "
2776   rtx low_dst = gen_lowpart (SImode, operands[0]);
2777   rtx high_dst = gen_highpart (SImode, operands[0]);
2779   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
2781   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2782   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2783   /* We need something to tag the possible REG_EQUAL notes on to.  */
2784   emit_move_insn (operands[0], operands[0]);
2785   DONE;
2788 (define_insn "umulsidi3_i"
2789   [(set (reg:SI MACH_REG)
2790         (truncate:SI
2791          (lshiftrt:DI
2792           (mult:DI
2793            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2794            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2795           (const_int 32))))
2796    (set (reg:SI MACL_REG)
2797         (mult:SI (match_dup 0)
2798                  (match_dup 1)))]
2799   "TARGET_SH2"
2800   "dmulu.l      %1,%0"
2801   [(set_attr "type" "dmpy")])
2803 (define_expand "umulsidi3"
2804   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2805         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2806                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2807   "TARGET_SH2 || TARGET_SHMEDIA"
2808   "
2810   if (TARGET_SH2)
2811     {
2812        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
2813                                          operands[2]));
2814        DONE;
2815     }
2818 (define_insn "umulsidi3_media"
2819   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2820         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
2821                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
2822   "TARGET_SHMEDIA"
2823   "mulu.l       %1, %2, %0"
2824   [(set_attr "type" "dmpy_media")
2825    (set_attr "highpart" "ignore")])
2827 (define_insn "umulsidi3_compact"
2828   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2829         (mult:DI
2830          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
2831          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
2832    (clobber (reg:SI MACH_REG))
2833    (clobber (reg:SI MACL_REG))]
2834   "TARGET_SH2"
2835   "#")
2837 (define_split
2838   [(set (match_operand:DI 0 "arith_reg_dest" "")
2839         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2840                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
2841    (clobber (reg:SI MACH_REG))
2842    (clobber (reg:SI MACL_REG))]
2843   "TARGET_SH2"
2844   [(const_int 0)]
2845   "
2847   rtx low_dst = gen_lowpart (SImode, operands[0]);
2848   rtx high_dst = gen_highpart (SImode, operands[0]);
2850   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
2852   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
2853   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
2854   /* We need something to tag the possible REG_EQUAL notes on to.  */
2855   emit_move_insn (operands[0], operands[0]);
2856   DONE;
2859 (define_insn "smulsi3_highpart_i"
2860   [(set (reg:SI MACH_REG)
2861         (truncate:SI
2862          (lshiftrt:DI
2863           (mult:DI
2864            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2865            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2866           (const_int 32))))
2867    (clobber (reg:SI MACL_REG))]
2868   "TARGET_SH2"
2869   "dmuls.l      %1,%0"
2870   [(set_attr "type" "dmpy")])
2872 (define_expand "smulsi3_highpart"
2873   [(parallel
2874     [(set (reg:SI MACH_REG)
2875           (truncate:SI
2876            (lshiftrt:DI
2877             (mult:DI
2878              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2879              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2880             (const_int 32))))
2881     (clobber (reg:SI MACL_REG))])
2882    (set (match_operand:SI 0 "arith_reg_operand" "")
2883         (reg:SI MACH_REG))]
2884   "TARGET_SH2"
2885   "
2887   rtx first, last;
2889   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
2890   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2891   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2892      invariant code motion can move it.  */
2893   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2894   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2895   /* expand_binop can't find a suitable code in mul_highpart_optab to
2896      make a REG_EQUAL note from, so make one here.
2897      See also {,u}mulhisi.
2898      ??? Alternatively, we could put this at the calling site of expand_binop,
2899      i.e. expand_mult_highpart.  */
2900   REG_NOTES (last)
2901     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
2902                          REG_NOTES (last));
2903   DONE;
2906 (define_insn "umulsi3_highpart_i"
2907   [(set (reg:SI MACH_REG)
2908         (truncate:SI
2909          (lshiftrt:DI
2910           (mult:DI
2911            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
2912            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
2913           (const_int 32))))
2914    (clobber (reg:SI MACL_REG))]
2915   "TARGET_SH2"
2916   "dmulu.l      %1,%0"
2917   [(set_attr "type" "dmpy")])
2919 (define_expand "umulsi3_highpart"
2920   [(parallel
2921     [(set (reg:SI MACH_REG)
2922           (truncate:SI
2923            (lshiftrt:DI
2924             (mult:DI
2925              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
2926              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
2927             (const_int 32))))
2928     (clobber (reg:SI MACL_REG))])
2929    (set (match_operand:SI 0 "arith_reg_operand" "")
2930         (reg:SI MACH_REG))]
2931   "TARGET_SH2"
2932   "
2934   rtx first, last;
2936   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
2937   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
2938   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
2939      invariant code motion can move it.  */
2940   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
2941   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2942   DONE;
2945 (define_insn_and_split "muldi3"
2946   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2947         (mult:DI (match_operand:DI 1 "arith_reg_operand" "r")
2948                  (match_operand:DI 2 "arith_reg_operand" "r")))
2949    (clobber (match_scratch:DI 3 "=&r"))
2950    (clobber (match_scratch:DI 4 "=r"))]
2951   "TARGET_SHMEDIA"
2952   "#"
2953   "reload_completed"
2954   [(const_int 0)]
2955   "
2957   rtx op3_v2si, op2_v2si;
2959   op3_v2si = operands[3];
2960   if (GET_CODE (op3_v2si) == SIGN_EXTEND)
2961     {
2962       op3_v2si = XEXP (op3_v2si, 0);
2963       op3_v2si = simplify_gen_subreg (DImode, op3_v2si, GET_MODE (op3_v2si), 0);
2964     }
2965   op3_v2si = simplify_gen_subreg (V2SImode, op3_v2si, DImode, 0);
2966   op2_v2si = operands[2];
2967   if (GET_CODE (op2_v2si) == SIGN_EXTEND)
2968     {
2969       op2_v2si = XEXP (op2_v2si, 0);
2970       op2_v2si = simplify_gen_subreg (DImode, op2_v2si, GET_MODE (op2_v2si), 0);
2971     }
2972   op2_v2si = simplify_gen_subreg (V2SImode, op2_v2si, DImode, 0);
2973   emit_insn (gen_rotldi3 (operands[3], operands[1], GEN_INT (32)));
2974   emit_insn (gen_mulv2si3 (op3_v2si, op3_v2si, op2_v2si));
2975   emit_insn (gen_umulsidi3_media (operands[4],
2976                                  sh_gen_truncate (SImode, operands[1], 0),
2977                                  sh_gen_truncate (SImode, operands[2], 0)));
2978   emit_insn (gen_anddi3 (operands[0], operands[3], GEN_INT (0xffffffff00000000LL)));
2979   emit_insn (gen_ashldi3_media (operands[3], operands[3], GEN_INT (32)));
2980   emit_insn (gen_adddi3 (operands[0], operands[3], operands[0]));
2981   emit_insn (gen_adddi3 (operands[0], operands[4], operands[0]));
2982   DONE;
2986 ;; -------------------------------------------------------------------------
2987 ;; Logical operations
2988 ;; -------------------------------------------------------------------------
2990 (define_insn "*andsi3_compact"
2991   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
2992         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2993                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2994   "TARGET_SH1"
2995   "and  %2,%0"
2996   [(set_attr "type" "arith")])
2998 (define_insn "*andsi3_media"
2999   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3000         (and:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3001                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3002   "TARGET_SHMEDIA"
3003   "@
3004         and     %1, %2, %0
3005         andi    %1, %2, %0"
3006   [(set_attr "type" "arith_media")])
3008 ;; If the constant is 255, then emit an extu.b instruction instead of an
3009 ;; and, since that will give better code.
3011 (define_expand "andsi3"
3012   [(set (match_operand:SI 0 "arith_reg_operand" "")
3013         (and:SI (match_operand:SI 1 "logical_reg_operand" "")
3014                 (match_operand:SI 2 "logical_operand" "")))]
3015   ""
3016   "
3018   if (TARGET_SH1
3019       && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
3020     {
3021       emit_insn (gen_zero_extendqisi2 (operands[0],
3022                                        gen_lowpart (QImode, operands[1])));
3023       DONE;
3024     }
3027 (define_insn_and_split "anddi3"
3028   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r,r")
3029         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
3030                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
3031   "TARGET_SHMEDIA"
3032   "@
3033         and     %1, %2, %0
3034         andi    %1, %2, %0
3035         #"
3036   "reload_completed
3037    && ! logical_operand (operands[2], DImode)"
3038   [(const_int 0)]
3039   "
3041   if ((unsigned)INTVAL (operands[2]) == (unsigned) 0xffffffff)
3042     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
3043   else
3044     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
3045   DONE;
3047   [(set_attr "type" "arith_media")])
3049 (define_insn "andcsi3"
3050   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3051         (and:SI (match_operand:SI 1 "arith_reg_operand" "r")
3052                 (not:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3053   "TARGET_SHMEDIA"
3054   "andc %1,%2,%0"
3055   [(set_attr "type" "arith_media")])
3057 (define_insn "andcdi3"
3058   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3059         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
3060                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
3061   "TARGET_SHMEDIA"
3062   "andc %1,%2,%0"
3063   [(set_attr "type" "arith_media")])
3065 (define_expand "iorsi3"
3066   [(set (match_operand:SI 0 "arith_reg_operand" "")
3067         (ior:SI (match_operand:SI 1 "logical_reg_operand" "")
3068                 (match_operand:SI 2 "logical_operand" "")))]
3069   ""
3070   "")
3072 (define_insn "*iorsi3_compact"
3073   [(set (match_operand:SI 0 "arith_reg_dest" "=r,z")
3074         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3075                 (match_operand:SI 2 "logical_operand" "r,K08")))]
3076   "TARGET_SH1"
3077   "or   %2,%0"
3078   [(set_attr "type" "arith")])
3080 (define_insn "*iorsi3_media"
3081   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3082         (ior:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3083                 (match_operand:SI 2 "logical_operand" "r,I10")))]
3084   "TARGET_SHMEDIA"
3085   "@
3086         or      %1, %2, %0
3087         ori     %1, %2, %0"
3088   [(set_attr "type" "arith_media")])
3090 (define_insn "iordi3"
3091   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3092         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3093                 (match_operand:DI 2 "logical_operand" "r,I10")))]
3094   "TARGET_SHMEDIA"
3095   "@
3096         or      %1, %2, %0
3097         ori     %1, %2, %0"
3098   [(set_attr "type" "arith_media")])
3100 (define_insn_and_split "*logical_sidi3"
3101   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3102         (sign_extend:DI (match_operator:SI 3 "logical_operator"
3103                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3104                            (match_operand:SI 2 "logical_operand" "r,I10")])))]
3105   "TARGET_SHMEDIA"
3106   "#"
3107   "&& reload_completed"
3108   [(set (match_dup 0) (match_dup 3))]
3109   "
3111   operands[3]
3112     = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
3113                       simplify_gen_subreg (DImode, operands[1], SImode, 0),
3114                       simplify_gen_subreg (DImode, operands[2], SImode, 0));
3117 (define_insn_and_split "*logical_sidisi3"
3118   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3119         (truncate:SI (sign_extend:DI
3120                         (match_operator:SI 3 "logical_operator"
3121                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3122                            (match_operand:SI 2 "logical_operand" "r,I10")]))))]
3123   "TARGET_SHMEDIA"
3124   "#"
3125   "&& 1"
3126   [(set (match_dup 0) (match_dup 3))])
3128 (define_insn_and_split "*logical_sidi3_2"
3129   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3130         (sign_extend:DI (truncate:SI (sign_extend:DI
3131                         (match_operator:SI 3 "logical_operator"
3132                           [(match_operand:SI 1 "arith_reg_operand" "%r,r")
3133                            (match_operand:SI 2 "logical_operand" "r,I10")])))))]
3134   "TARGET_SHMEDIA"
3135   "#"
3136   "&& 1"
3137   [(set (match_dup 0) (sign_extend:DI (match_dup 3)))])
3139 (define_expand "xorsi3"
3140   [(set (match_operand:SI 0 "arith_reg_operand" "")
3141         (xor:SI (match_operand:SI 1 "logical_reg_operand" "")
3142                 (match_operand:SI 2 "xor_operand" "")))]
3143   ""
3144   "")
3146 (define_insn "*xorsi3_compact"
3147   [(set (match_operand:SI 0 "arith_reg_dest" "=z,r")
3148         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
3149                 (match_operand:SI 2 "logical_operand" "K08,r")))]
3150   "TARGET_SH1"
3151   "xor  %2,%0"
3152   [(set_attr "type" "arith")])
3154 (define_insn "*xorsi3_media"
3155   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3156         (xor:SI (match_operand:SI 1 "logical_reg_operand" "%r,r")
3157                 (match_operand:SI 2 "xor_operand" "r,I06")))]
3158   "TARGET_SHMEDIA"
3159   "@
3160         xor     %1, %2, %0
3161         xori    %1, %2, %0"
3162   [(set_attr "type" "arith_media")])
3164 (define_insn "xordi3"
3165   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3166         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
3167                 (match_operand:DI 2 "xor_operand" "r,I06")))]
3168   "TARGET_SHMEDIA"
3169   "@
3170         xor     %1, %2, %0
3171         xori    %1, %2, %0"
3172   [(set_attr "type" "arith_media")])
3174 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
3175 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
3176 (define_split
3177   [(set (match_operand:DI 0 "arith_reg_dest" "")
3178         (sign_extend:DI (match_operator 4 "binary_logical_operator"
3179                           [(match_operand 1 "any_register_operand" "")
3180                            (match_operand 2 "any_register_operand" "")])))]
3181   "TARGET_SHMEDIA"
3182   [(set (match_dup 5) (match_dup 4))
3183    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
3186   enum machine_mode inmode = GET_MODE (operands[1]);
3187   int offset = 0;
3189   if (GET_CODE (operands[0]) == SUBREG)
3190     {
3191       offset = SUBREG_BYTE (operands[0]);
3192       operands[0] = SUBREG_REG (operands[0]);
3193     }
3194   gcc_assert (GET_CODE (operands[0]) == REG);
3195   if (! TARGET_LITTLE_ENDIAN)
3196     offset += 8 - GET_MODE_SIZE (inmode);
3197   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
3200 ;; -------------------------------------------------------------------------
3201 ;; Shifts and rotates
3202 ;; -------------------------------------------------------------------------
3204 (define_expand "rotldi3"
3205   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3206         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3207                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3208   "TARGET_SHMEDIA"
3209   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3211 (define_insn "rotldi3_mextr"
3212   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3213         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
3214                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
3215   "TARGET_SHMEDIA"
3216   "*
3218   static char templ[16];
3220   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
3221            8 - (int) (INTVAL (operands[2]) >> 3));
3222   return templ;
3224   [(set_attr "type" "arith_media")])
3226 (define_expand "rotrdi3"
3227   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3228         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3229                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3230   "TARGET_SHMEDIA"
3231   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
3233 (define_insn "rotrdi3_mextr"
3234   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3235         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
3236                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
3237   "TARGET_SHMEDIA"
3238   "*
3240   static char templ[16];
3242   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
3243   return templ;
3245   [(set_attr "type" "arith_media")])
3247 (define_split
3248   [(set (match_operand:DI 0 "arith_reg_dest" "")
3249         (ior:DI (zero_extend:DI (mem:QI (match_operand 1
3250                                          "ua_address_operand" "")))
3251                 (ashift:DI (match_operand:DI 2 "arith_reg_operand" "")
3252                            (const_int 8))))
3253    (clobber (match_operand:DI 3 "register_operand" ""))]
3254   "TARGET_SHMEDIA"
3255   [(match_dup 4) (match_dup 5)]
3256   "
3258   operands[4] = ((TARGET_LITTLE_ENDIAN ? gen_ldhi_q : gen_ldlo_q)
3259                  (operands[3], operands[1]));
3260   operands[5] = gen_mextr_rl (operands[0], operands[3], operands[2],
3261                               GEN_INT (56), GEN_INT (8));
3264 (define_insn "rotlsi3_1"
3265   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3266         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3267                    (const_int 1)))
3268    (set (reg:SI T_REG)
3269         (lshiftrt:SI (match_dup 1) (const_int 31)))]
3270   "TARGET_SH1"
3271   "rotl %0"
3272   [(set_attr "type" "arith")])
3274 (define_insn "rotlsi3_31"
3275   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3276         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
3277                    (const_int 31)))
3278    (clobber (reg:SI T_REG))]
3279   "TARGET_SH1"
3280   "rotr %0"
3281   [(set_attr "type" "arith")])
3283 (define_insn "rotlsi3_16"
3284   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3285         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
3286                    (const_int 16)))]
3287   "TARGET_SH1"
3288   "swap.w       %1,%0"
3289   [(set_attr "type" "arith")])
3291 (define_expand "rotlsi3"
3292   [(set (match_operand:SI 0 "arith_reg_dest" "")
3293         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
3294                    (match_operand:SI 2 "immediate_operand" "")))]
3295   "TARGET_SH1"
3296   "
3298   static const char rot_tab[] = {
3299     000, 000, 000, 000, 000, 000, 010, 001,
3300     001, 001, 011, 013, 003, 003, 003, 003,
3301     003, 003, 003, 003, 003, 013, 012, 002,
3302     002, 002, 010, 000, 000, 000, 000, 000,
3303   };
3305   int count, choice;
3307   if (GET_CODE (operands[2]) != CONST_INT)
3308     FAIL;
3309   count = INTVAL (operands[2]);
3310   choice = rot_tab[count];
3311   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
3312     FAIL;
3313   choice &= 7;
3314   switch (choice)
3315     {
3316     case 0:
3317       emit_move_insn (operands[0], operands[1]);
3318       count -= (count & 16) * 2;
3319       break;
3320     case 3:
3321      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
3322      count -= 16;
3323      break;
3324     case 1:
3325     case 2:
3326       {
3327         rtx parts[2];
3328         parts[0] = gen_reg_rtx (SImode);
3329         parts[1] = gen_reg_rtx (SImode);
3330         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
3331         emit_move_insn (parts[choice-1], operands[1]);
3332         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
3333         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
3334         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
3335         count = (count & ~16) - 8;
3336       }
3337     }
3339   for (; count > 0; count--)
3340     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
3341   for (; count < 0; count++)
3342     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
3344   DONE;
3347 (define_insn "*rotlhi3_8"
3348   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3349         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
3350                    (const_int 8)))]
3351   "TARGET_SH1"
3352   "swap.b       %1,%0"
3353   [(set_attr "type" "arith")])
3355 (define_expand "rotlhi3"
3356   [(set (match_operand:HI 0 "arith_reg_operand" "")
3357         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
3358                    (match_operand:HI 2 "immediate_operand" "")))]
3359   "TARGET_SH1"
3360   "
3362   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
3363     FAIL;
3367 ;; shift left
3369 (define_insn "ashlsi3_sh2a"
3370   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3371         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3372                    (match_operand:SI 2 "arith_reg_operand" "r")))]
3373   "TARGET_SH2A"
3374   "shad %2,%0"
3375   [(set_attr "type" "arith")
3376    (set_attr "length" "4")])
3378 ;; This pattern is used by init_expmed for computing the costs of shift
3379 ;; insns.
3381 (define_insn_and_split "ashlsi3_std"
3382   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r,r,r")
3383         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
3384                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
3385    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
3386   "TARGET_SH3
3387    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
3388        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
3389   "@
3390    shld %2,%0
3391    add  %0,%0
3392    shll%O2      %0
3393    #"
3394   "TARGET_SH3
3395    && reload_completed
3396    && GET_CODE (operands[2]) == CONST_INT
3397    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3398   [(set (match_dup 3) (match_dup 2))
3399    (parallel
3400     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
3401      (clobber (match_dup 4))])]
3402   "operands[4] = gen_rtx_SCRATCH (SImode);"
3403   [(set_attr "length" "*,*,*,4")
3404    (set_attr "type" "dyn_shift,arith,arith,arith")])
3406 (define_insn "ashlhi3_k"
3407   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
3408         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
3409                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
3410   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
3411   "@
3412         add     %0,%0
3413         shll%O2 %0"
3414   [(set_attr "type" "arith")])
3416 (define_insn "ashlsi3_n"
3417   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3418         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
3419                    (match_operand:SI 2 "const_int_operand" "n")))
3420    (clobber (reg:SI T_REG))]
3421   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3422   "#"
3423   [(set (attr "length")
3424         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3425                (const_string "2")
3426                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3427                (const_string "4")
3428                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3429                (const_string "6")]
3430               (const_string "8")))
3431    (set_attr "type" "arith")])
3433 (define_split
3434   [(set (match_operand:SI 0 "arith_reg_dest" "")
3435         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3436                    (match_operand:SI 2 "const_int_operand" "")))
3437    (clobber (reg:SI T_REG))]
3438   "TARGET_SH1 && reload_completed"
3439   [(use (reg:SI R0_REG))]
3440   "
3442   gen_shifty_op (ASHIFT, operands);
3443   DONE;
3446 (define_insn "ashlsi3_media"
3447   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3448         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3449                    (match_operand:SI 2 "shift_count_operand" "r,n")))]
3450   "TARGET_SHMEDIA"
3451   "@
3452         shlld.l %1, %2, %0
3453         shlli.l %1, %2, %0"
3454   [(set_attr "type" "arith_media")
3455    (set_attr "highpart" "ignore")])
3457 (define_expand "ashlsi3"
3458   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3459                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
3460                               (match_operand:SI 2 "nonmemory_operand" "")))
3461               (clobber (reg:SI T_REG))])]
3462   ""
3463   "
3465   if (TARGET_SHMEDIA)
3466     {
3467       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
3468       DONE;
3469     }
3470   if (GET_CODE (operands[2]) == CONST_INT
3471       && sh_dynamicalize_shift_p (operands[2]))
3472     operands[2] = force_reg (SImode, operands[2]);
3473   if (TARGET_SH3)
3474     {
3475       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
3476       DONE;
3477     }
3478   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3479     FAIL;
3482 (define_insn "*ashlhi3_n"
3483   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
3484         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
3485                    (match_operand:HI 2 "const_int_operand" "n")))
3486    (clobber (reg:SI T_REG))]
3487   "TARGET_SH1"
3488   "#"
3489   [(set (attr "length")
3490         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3491                (const_string "2")
3492                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3493                (const_string "4")]
3494               (const_string "6")))
3495    (set_attr "type" "arith")])
3497 (define_expand "ashlhi3"
3498   [(parallel [(set (match_operand:HI 0 "arith_reg_operand" "")
3499                    (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3500                               (match_operand:SI 2 "nonmemory_operand" "")))
3501               (clobber (reg:SI T_REG))])]
3502   "TARGET_SH1"
3503   "
3505   if (GET_CODE (operands[2]) != CONST_INT)
3506     FAIL;
3507   /* It may be possible to call gen_ashlhi3 directly with more generic
3508      operands.  Make sure operands[1] is a HImode register here.  */
3509   if (!arith_reg_operand (operands[1], HImode))
3510     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3513 (define_split
3514   [(set (match_operand:HI 0 "arith_reg_dest" "")
3515         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
3516                    (match_operand:HI 2 "const_int_operand" "")))
3517    (clobber (reg:SI T_REG))]
3518   "TARGET_SH1 && reload_completed"
3519   [(use (reg:SI R0_REG))]
3520   "
3522   gen_shifty_hi_op (ASHIFT, operands);
3523   DONE;
3527 ; arithmetic shift right
3530 (define_insn "ashrsi3_sh2a"
3531   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3532         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3533                    (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3534   "TARGET_SH2A"
3535   "shad %2,%0"
3536   [(set_attr "type" "dyn_shift")
3537    (set_attr "length" "4")])
3539 (define_insn "ashrsi3_k"
3540   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3541         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3542                      (match_operand:SI 2 "const_int_operand" "M")))
3543    (clobber (reg:SI T_REG))]
3544   "TARGET_SH1 && INTVAL (operands[2]) == 1"
3545   "shar %0"
3546   [(set_attr "type" "arith")])
3548 ;; We can't do HImode right shifts correctly unless we start out with an
3549 ;; explicit zero / sign extension; doing that would result in worse overall
3550 ;; code, so just let the machine independent code widen the mode.
3551 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
3554 ;; ??? This should be a define expand.
3556 (define_insn "ashrsi2_16"
3557   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3558         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
3559                      (const_int 16)))]
3560   "TARGET_SH1"
3561   "#"
3562   [(set_attr "length" "4")])
3564 (define_split
3565   [(set (match_operand:SI 0 "arith_reg_dest" "")
3566         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3567                      (const_int 16)))]
3568   "TARGET_SH1"
3569   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
3570    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
3571   "operands[2] = gen_lowpart (HImode, operands[0]);")
3573 ;; ??? This should be a define expand.
3575 (define_insn "ashrsi2_31"
3576   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3577         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3578                      (const_int 31)))
3579    (clobber (reg:SI T_REG))]
3580   "TARGET_SH1"
3581   "#"
3582   [(set_attr "length" "4")])
3584 (define_split
3585   [(set (match_operand:SI 0 "arith_reg_dest" "")
3586         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3587                      (const_int 31)))
3588    (clobber (reg:SI T_REG))]
3589   "TARGET_SH1"
3590   [(const_int 0)]
3591   "
3593   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
3594   emit_insn (gen_mov_neg_si_t (operands[0]));
3595   DONE;
3598 (define_peephole2
3599   [(set (match_operand:SI 0 "arith_reg_dest" "") (const_int 0))
3600    (set (reg:SI T_REG)
3601         (gt:SI (match_dup 0) (match_operand:SI 1 "arith_reg_operand" "")))]
3602   "TARGET_SH1
3603    && peep2_reg_dead_p (2, operands[0])
3604    && peep2_reg_dead_p (2, operands[1])"
3605   [(const_int 0)]
3606   "
3608   emit_insn (gen_ashlsi_c (operands[1], operands[1]));
3609   DONE;
3612 (define_insn "ashlsi_c"
3613   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3614         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
3615    (set (reg:SI T_REG)
3616         (lt:SI (match_dup 1) (const_int 0)))]
3617   "TARGET_SH1"
3618   "shll %0"
3619   [(set_attr "type" "arith")])
3621 (define_insn "*ashlsi_c_void"
3622   [(set (reg:SI T_REG)
3623         (lt:SI (match_operand:SI 0 "arith_reg_operand" "r") (const_int 0)))
3624    (clobber (match_scratch:SI 1 "=0"))]
3625   "TARGET_SH1 && cse_not_expected"
3626   "shll %0"
3627   [(set_attr "type" "arith")])
3629 (define_insn "ashrsi3_d"
3630   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3631         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3632                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3633   "TARGET_SH3"
3634   "shad %2,%0"
3635   [(set_attr "type" "dyn_shift")])
3637 (define_insn "ashrsi3_n"
3638   [(set (reg:SI R4_REG)
3639         (ashiftrt:SI (reg:SI R4_REG)
3640                      (match_operand:SI 0 "const_int_operand" "i")))
3641    (clobber (reg:SI T_REG))
3642    (clobber (reg:SI PR_REG))
3643    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
3644   "TARGET_SH1"
3645   "jsr  @%1%#"
3646   [(set_attr "type" "sfunc")
3647    (set_attr "needs_delay_slot" "yes")])
3649 (define_insn "ashrsi3_media"
3650   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3651         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3652                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3653   "TARGET_SHMEDIA"
3654   "@
3655         shard.l %1, %2, %0
3656         shari.l %1, %2, %0"
3657   [(set_attr "type" "arith_media")
3658    (set_attr "highpart" "ignore")])
3660 (define_expand "ashrsi3"
3661   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
3662                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3663                                 (match_operand:SI 2 "nonmemory_operand" "")))
3664               (clobber (reg:SI T_REG))])]
3665   ""
3666   "
3668   if (TARGET_SHMEDIA)
3669     {
3670       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
3671       DONE;
3672     }
3673   if (expand_ashiftrt (operands))
3674     DONE;
3675   else
3676     FAIL;
3679 ;; logical shift right
3681 (define_insn "lshrsi3_sh2a"
3682   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3683         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3684                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3685   "TARGET_SH2A"
3686   "shld %2,%0"
3687   [(set_attr "type" "dyn_shift")
3688    (set_attr "length" "4")])
3690 (define_insn "lshrsi3_d"
3691   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3692         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3693                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
3694   "TARGET_SH3"
3695   "shld %2,%0"
3696   [(set_attr "type" "dyn_shift")])
3698 ;;  Only the single bit shift clobbers the T bit.
3700 (define_insn "lshrsi3_m"
3701   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3702         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3703                      (match_operand:SI 2 "const_int_operand" "M")))
3704    (clobber (reg:SI T_REG))]
3705   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
3706   "shlr %0"
3707   [(set_attr "type" "arith")])
3709 (define_insn "lshrsi3_k"
3710   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3711         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3712                      (match_operand:SI 2 "const_int_operand" "P27")))]
3713   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
3714    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
3715   "shlr%O2      %0"
3716   [(set_attr "type" "arith")])
3718 (define_insn "lshrsi3_n"
3719   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3720         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
3721                      (match_operand:SI 2 "const_int_operand" "n")))
3722    (clobber (reg:SI T_REG))]
3723   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
3724   "#"
3725   [(set (attr "length")
3726         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
3727                (const_string "2")
3728                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
3729                (const_string "4")
3730                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
3731                (const_string "6")]
3732               (const_string "8")))
3733    (set_attr "type" "arith")])
3735 (define_split
3736   [(set (match_operand:SI 0 "arith_reg_dest" "")
3737         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3738                      (match_operand:SI 2 "const_int_operand" "")))
3739    (clobber (reg:SI T_REG))]
3740   "TARGET_SH1 && reload_completed"
3741   [(use (reg:SI R0_REG))]
3742   "
3744   gen_shifty_op (LSHIFTRT, operands);
3745   DONE;
3748 (define_insn "lshrsi3_media"
3749   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
3750         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
3751                      (match_operand:SI 2 "shift_count_operand" "r,n")))]
3752   "TARGET_SHMEDIA"
3753   "@
3754         shlrd.l %1, %2, %0
3755         shlri.l %1, %2, %0"
3756   [(set_attr "type" "arith_media")
3757    (set_attr "highpart" "ignore")])
3759 (define_expand "lshrsi3"
3760   [(parallel [(set (match_operand:SI 0 "arith_reg_dest" "")
3761                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
3762                                 (match_operand:SI 2 "nonmemory_operand" "")))
3763               (clobber (reg:SI T_REG))])]
3764   ""
3765   "
3767   if (TARGET_SHMEDIA)
3768     {
3769       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
3770       DONE;
3771     }
3772   if (GET_CODE (operands[2]) == CONST_INT
3773       && sh_dynamicalize_shift_p (operands[2]))
3774     operands[2] = force_reg (SImode, operands[2]);
3775   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
3776     {
3777       rtx count = copy_to_mode_reg (SImode, operands[2]);
3778       emit_insn (gen_negsi2 (count, count));
3779       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
3780       DONE;
3781     }
3782   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
3783     FAIL;
3786 ;; ??? This should be a define expand.
3788 (define_insn "ashldi3_k"
3789   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3790         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
3791                    (const_int 1)))
3792    (clobber (reg:SI T_REG))]
3793   "TARGET_SH1"
3794   "shll %R0\;rotcl      %S0"
3795   [(set_attr "length" "4")
3796    (set_attr "type" "arith")])
3798 (define_insn "ashldi3_media"
3799   [(set (match_operand:DI 0 "arith_reg_dest" "=r,r")
3800         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3801                    (match_operand:DI 2 "shift_count_operand" "r,n")))]
3802   "TARGET_SHMEDIA"
3803   "@
3804         shlld   %1, %2, %0
3805         shlli   %1, %2, %0"
3806   [(set_attr "type" "arith_media")])
3808 (define_insn "*ashldisi3_media"
3809   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3810         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
3811                    (match_operand:DI 2 "const_int_operand" "n")))]
3812   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3813   "shlli.l      %1, %2, %0"
3814   [(set_attr "type" "arith_media")
3815    (set_attr "highpart" "ignore")])
3817 (define_expand "ashldi3"
3818   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3819                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
3820                               (match_operand:DI 2 "immediate_operand" "")))
3821               (clobber (reg:SI T_REG))])]
3822   ""
3823   "
3825   if (TARGET_SHMEDIA)
3826     {
3827       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
3828       DONE;
3829     }
3830   if (GET_CODE (operands[2]) != CONST_INT
3831       || INTVAL (operands[2]) != 1)
3832     FAIL;
3835 ;; ??? This should be a define expand.
3837 (define_insn "lshrdi3_k"
3838   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3839         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3840                      (const_int 1)))
3841    (clobber (reg:SI T_REG))]
3842   "TARGET_SH1"
3843   "shlr %S0\;rotcr      %R0"
3844   [(set_attr "length" "4")
3845    (set_attr "type" "arith")])
3847 (define_insn "lshrdi3_media"
3848   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3849         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3850                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3851   "TARGET_SHMEDIA
3852    && (arith_reg_dest (operands[0], DImode)
3853        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 32))"
3854   "@
3855         shlrd   %1, %2, %0
3856         shlri   %1, %2, %0"
3857   [(set_attr "type" "arith_media")])
3859 (define_insn "*lshrdisi3_media"
3860   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3861         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3862                      (match_operand:DI 2 "const_int_operand" "n")))]
3863   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3864   "shlri.l      %1, %2, %0"
3865   [(set_attr "type" "arith_media")
3866    (set_attr "highpart" "ignore")])
3868 (define_expand "lshrdi3"
3869   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3870                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3871                                (match_operand:DI 2 "immediate_operand" "")))
3872              (clobber (reg:SI T_REG))])]
3873   ""
3874   "
3876   if (TARGET_SHMEDIA)
3877     {
3878       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
3879       DONE;
3880     }
3881   if (GET_CODE (operands[2]) != CONST_INT
3882       || INTVAL (operands[2]) != 1)
3883     FAIL;
3886 ;; ??? This should be a define expand.
3888 (define_insn "ashrdi3_k"
3889   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
3890         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
3891                      (const_int 1)))
3892    (clobber (reg:SI T_REG))]
3893   "TARGET_SH1"
3894   "shar %S0\;rotcr      %R0"
3895   [(set_attr "length" "4")
3896    (set_attr "type" "arith")])
3898 (define_insn "ashrdi3_media"
3899   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
3900         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
3901                      (match_operand:DI 2 "shift_count_operand" "r,n")))]
3902   "TARGET_SHMEDIA
3903    && (arith_reg_dest (operands[0], DImode)
3904        || (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32))"
3905   "@
3906         shard   %1, %2, %0
3907         shari   %1, %2, %0"
3908   [(set_attr "type" "arith_media")])
3910 (define_insn "*ashrdisi3_media"
3911   [(set (subreg:DI (match_operand:SI 0 "arith_reg_operand" "=r") 0)
3912         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3913                      (match_operand:DI 2 "const_int_operand" "n")))]
3914   "TARGET_SHMEDIA && INTVAL (operands[2]) < 32"
3915   "shari.l      %1, %2, %0"
3916   [(set_attr "type" "arith_media")
3917    (set_attr "highpart" "ignore")])
3919 (define_insn "ashrdisi3_media_high"
3920   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3921         (truncate:SI
3922            (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
3923                         (match_operand:DI 2 "const_int_operand" "n"))))]
3924   "TARGET_SHMEDIA && INTVAL (operands[2]) >= 32"
3925   "shari        %1, %2, %0"
3926   [(set_attr "type" "arith_media")])
3928 (define_insn "ashrdisi3_media_opaque"
3929   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
3930         (unspec:SI [(match_operand:DI 1 "arith_reg_operand" "r")
3931                     (match_operand:DI 2 "const_int_operand" "n")]
3932          UNSPEC_ASHIFTRT))]
3933   "TARGET_SHMEDIA"
3934   "shari        %1, %2, %0"
3935   [(set_attr "type" "arith_media")])
3937 (define_expand "ashrdi3"
3938   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
3939                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
3940                                 (match_operand:DI 2 "immediate_operand" "")))
3941               (clobber (reg:SI T_REG))])]
3942   ""
3943   "
3945   if (TARGET_SHMEDIA)
3946     {
3947       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
3948       DONE;
3949     }
3950   if (GET_CODE (operands[2]) != CONST_INT
3951       || INTVAL (operands[2]) != 1)
3952     FAIL;
3955 ;; combined left/right shift
3957 (define_split
3958   [(set (match_operand:SI 0 "register_operand" "")
3959         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3960                            (match_operand:SI 2 "const_int_operand" ""))
3961                 (match_operand:SI 3 "const_int_operand" "")))]
3962   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3963   [(use (reg:SI R0_REG))]
3964   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3965    DONE;")
3967 (define_split
3968   [(set (match_operand:SI 0 "register_operand" "")
3969         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
3970                            (match_operand:SI 2 "const_int_operand" ""))
3971                 (match_operand:SI 3 "const_int_operand" "")))
3972    (clobber (reg:SI T_REG))]
3973   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
3974   [(use (reg:SI R0_REG))]
3975   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
3976    DONE;")
3978 (define_insn ""
3979   [(set (match_operand:SI 0 "register_operand" "=r")
3980         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
3981                            (match_operand:SI 2 "const_int_operand" "n"))
3982                 (match_operand:SI 3 "const_int_operand" "n")))
3983    (clobber (reg:SI T_REG))]
3984   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
3985  "#"
3986   [(set (attr "length")
3987         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
3988                (const_string "4")
3989                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
3990                (const_string "6")
3991                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
3992                (const_string "8")
3993                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
3994                (const_string "10")
3995                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
3996                (const_string "12")
3997                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
3998                (const_string "14")
3999                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
4000                (const_string "16")]
4001               (const_string "18")))
4002    (set_attr "type" "arith")])
4004 (define_insn ""
4005   [(set (match_operand:SI 0 "register_operand" "=z")
4006         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
4007                            (match_operand:SI 2 "const_int_operand" "n"))
4008                 (match_operand:SI 3 "const_int_operand" "n")))
4009    (clobber (reg:SI T_REG))]
4010   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
4011  "#"
4012   [(set (attr "length")
4013         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
4014                (const_string "4")
4015                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
4016                (const_string "6")
4017                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
4018                (const_string "8")]
4019               (const_string "10")))
4020    (set_attr "type" "arith")])
4022 ;; shift left / and combination with a scratch register: The combine pass
4023 ;; does not accept the individual instructions, even though they are
4024 ;; cheap.  But it needs a precise description so that it is usable after
4025 ;; reload.
4026 (define_insn "and_shl_scratch"
4027   [(set (match_operand:SI 0 "register_operand" "=r,&r")
4028         (lshiftrt:SI
4029          (ashift:SI
4030           (and:SI
4031            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
4032                         (match_operand:SI 2 "const_int_operand" "N,n"))
4033            (match_operand:SI 3 "" "0,r"))
4034           (match_operand:SI 4 "const_int_operand" "n,n"))
4035          (match_operand:SI 5 "const_int_operand" "n,n")))
4036    (clobber (reg:SI T_REG))]
4037   "TARGET_SH1"
4038   "#"
4039   [(set (attr "length")
4040         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
4041                (const_string "4")
4042                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
4043                (const_string "6")
4044                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
4045                (const_string "8")
4046                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
4047                (const_string "10")]
4048               (const_string "12")))
4049    (set_attr "type" "arith")])
4051 (define_split
4052   [(set (match_operand:SI 0 "register_operand" "")
4053         (lshiftrt:SI
4054          (ashift:SI
4055           (and:SI
4056            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
4057                         (match_operand:SI 2 "const_int_operand" ""))
4058            (match_operand:SI 3 "register_operand" ""))
4059           (match_operand:SI 4 "const_int_operand" ""))
4060          (match_operand:SI 5 "const_int_operand" "")))
4061    (clobber (reg:SI T_REG))]
4062   "TARGET_SH1"
4063   [(use (reg:SI R0_REG))]
4064   "
4066   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
4068   if (INTVAL (operands[2]))
4069     {
4070       gen_shifty_op (LSHIFTRT, operands);
4071     }
4072   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
4073   operands[2] = operands[4];
4074   gen_shifty_op (ASHIFT, operands);
4075   if (INTVAL (operands[5]))
4076     {
4077       operands[2] = operands[5];
4078       gen_shifty_op (LSHIFTRT, operands);
4079     }
4080   DONE;
4083 ;; signed left/right shift combination.
4084 (define_split
4085   [(set (match_operand:SI 0 "register_operand" "")
4086         (sign_extract:SI
4087          (ashift:SI (match_operand:SI 1 "register_operand" "")
4088                     (match_operand:SI 2 "const_int_operand" ""))
4089          (match_operand:SI 3 "const_int_operand" "")
4090          (const_int 0)))
4091    (clobber (reg:SI T_REG))]
4092   "TARGET_SH1"
4093   [(use (reg:SI R0_REG))]
4094   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
4095    DONE;")
4097 (define_insn "shl_sext_ext"
4098   [(set (match_operand:SI 0 "register_operand" "=r")
4099         (sign_extract:SI
4100          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4101                     (match_operand:SI 2 "const_int_operand" "n"))
4102          (match_operand:SI 3 "const_int_operand" "n")
4103          (const_int 0)))
4104    (clobber (reg:SI T_REG))]
4105   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
4106   "#"
4107   [(set (attr "length")
4108         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
4109                (const_string "2")
4110                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
4111                (const_string "4")
4112                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4113                (const_string "6")
4114                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4115                (const_string "8")
4116                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4117                (const_string "10")
4118                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4119                (const_string "12")
4120                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
4121                (const_string "14")
4122                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
4123                (const_string "16")]
4124               (const_string "18")))
4125     (set_attr "type" "arith")])
4127 (define_insn "shl_sext_sub"
4128   [(set (match_operand:SI 0 "register_operand" "=z")
4129         (sign_extract:SI
4130          (ashift:SI (match_operand:SI 1 "register_operand" "0")
4131                     (match_operand:SI 2 "const_int_operand" "n"))
4132          (match_operand:SI 3 "const_int_operand" "n")
4133          (const_int 0)))
4134    (clobber (reg:SI T_REG))]
4135   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
4136   "#"
4137   [(set (attr "length")
4138         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
4139                (const_string "6")
4140                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
4141                (const_string "8")
4142                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
4143                (const_string "10")
4144                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
4145                (const_string "12")]
4146               (const_string "14")))
4147     (set_attr "type" "arith")])
4149 ;; These patterns are found in expansions of DImode shifts by 16, and
4150 ;; allow the xtrct instruction to be generated from C source.
4152 (define_insn "xtrct_left"
4153   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4154         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
4155                            (const_int 16))
4156                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
4157                              (const_int 16))))]
4158   "TARGET_SH1"
4159   "xtrct        %1,%0"
4160   [(set_attr "type" "arith")])
4162 (define_insn "xtrct_right"
4163   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4164         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
4165                              (const_int 16))
4166                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
4167                            (const_int 16))))]
4168   "TARGET_SH1"
4169   "xtrct        %2,%0"
4170   [(set_attr "type" "arith")])
4172 ;; -------------------------------------------------------------------------
4173 ;; Unary arithmetic
4174 ;; -------------------------------------------------------------------------
4176 (define_insn "negc"
4177   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4178         (neg:SI (plus:SI (reg:SI T_REG)
4179                          (match_operand:SI 1 "arith_reg_operand" "r"))))
4180    (set (reg:SI T_REG)
4181         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
4182                (const_int 0)))]
4183   "TARGET_SH1"
4184   "negc %1,%0"
4185   [(set_attr "type" "arith")])
4187 (define_insn "*negdi_media"
4188   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4189         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
4190   "TARGET_SHMEDIA"
4191   "sub  r63, %1, %0"
4192   [(set_attr "type" "arith_media")])
4194 (define_expand "negdi2"
4195   [(set (match_operand:DI 0 "arith_reg_operand" "")
4196         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
4197   ""
4198   "
4200   if (TARGET_SH1)
4201     {
4202       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
4203       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
4205       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
4206       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
4208       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
4209       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
4211       emit_insn (gen_clrt ());
4212       emit_insn (gen_negc (low_dst, low_src));
4213       emit_insn (gen_negc (high_dst, high_src));
4214       DONE;
4215     }
4218 (define_insn "negsi2"
4219   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4220         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4221   "TARGET_SH1"
4222   "neg  %1,%0"
4223   [(set_attr "type" "arith")])
4225 (define_insn "one_cmplsi2"
4226   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4227         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
4228   "TARGET_SH1"
4229   "not  %1,%0"
4230   [(set_attr "type" "arith")])
4232 (define_expand "one_cmpldi2"
4233   [(set (match_operand:DI 0 "arith_reg_dest" "")
4234         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
4235                 (const_int -1)))]
4236   "TARGET_SHMEDIA" "")
4238 /* The SH4 202 can do zero-offset branches without pipeline stalls.
4239    This can be used as some kind of conditional execution, which is useful
4240    for abs.  */
4241 (define_split
4242   [(set (match_operand:SI 0 "arith_reg_dest" "")
4243         (plus:SI (xor:SI (neg:SI (reg:SI T_REG))
4244                          (match_operand:SI 1 "arith_reg_operand" ""))
4245                  (reg:SI T_REG)))]
4246   "TARGET_HARD_SH4"
4247   [(const_int 0)]
4248   "emit_insn (gen_movsi_i (operands[0], operands[1]));
4249    emit_insn (gen_cneg (operands[0], operands[0], operands[0]));
4250    DONE;")
4252 (define_insn "cneg"
4253   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4254         (if_then_else:SI (eq:SI (reg:SI T_REG) (const_int 0))
4255                       (match_operand:SI 1 "arith_reg_operand" "0")
4256                       (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
4257   "TARGET_HARD_SH4"
4258   "bf 0f\;neg %2,%0\\n0:"
4259   [(set_attr "type" "arith") ;; poor approximation
4260    (set_attr "length" "4")])
4263 ;; -------------------------------------------------------------------------
4264 ;; Zero extension instructions
4265 ;; -------------------------------------------------------------------------
4267 (define_insn "zero_extendsidi2"
4268   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
4269         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
4270   "TARGET_SHMEDIA"
4271   "addz.l       %1, r63, %0"
4272   [(set_attr "type" "arith_media")
4273    (set_attr "highpart" "extend")])
4275 (define_insn "zero_extendhidi2"
4276   [(set (match_operand:DI 0 "register_operand" "=r,r")
4277         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4278   "TARGET_SHMEDIA"
4279   "@
4280         #
4281         ld%M1.uw        %m1, %0"
4282   [(set_attr "type" "*,load_media")
4283    (set (attr "highpart")
4284         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4285                (const_string "user")]
4286               (const_string "ignore")))])
4288 (define_split
4289   [(set (match_operand:DI 0 "register_operand" "")
4290         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4291   "TARGET_SHMEDIA && reload_completed"
4292   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4293    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
4294   "
4296   if (GET_CODE (operands[1]) == TRUNCATE)
4297     operands[1] = XEXP (operands[1], 0);
4300 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
4301 ;; reload the entire truncate expression.
4302 (define_insn_and_split "*loaddi_trunc"
4303   [(set (match_operand 0 "any_register_operand" "=r")
4304         (truncate (match_operand:DI 1 "memory_operand" "m")))]
4305   "TARGET_SHMEDIA && reload_completed"
4306   "#"
4307   "TARGET_SHMEDIA && reload_completed"
4308   [(set (match_dup 0) (match_dup 1))]
4309   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
4311 (define_insn "zero_extendqidi2"
4312   [(set (match_operand:DI 0 "register_operand" "=r,r")
4313         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4314   "TARGET_SHMEDIA"
4315   "@
4316         andi    %1, 255, %0
4317         ld%M1.ub        %m1, %0"
4318   [(set_attr "type" "arith_media,load_media")
4319    (set (attr "highpart")
4320         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4321                (const_string "user")]
4322               (const_string "ignore")))])
4324 (define_expand "zero_extendhisi2"
4325   [(set (match_operand:SI 0 "arith_reg_operand" "")
4326         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
4327   ""
4328   "
4330   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
4331     operands[1] = copy_to_mode_reg (HImode, operands[1]);
4334 (define_insn "*zero_extendhisi2_compact"
4335   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4336         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
4337   "TARGET_SH1"
4338   "extu.w       %1,%0"
4339   [(set_attr "type" "arith")])
4341 (define_insn "*zero_extendhisi2_media"
4342   [(set (match_operand:SI 0 "register_operand" "=r,r")
4343         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4344   "TARGET_SHMEDIA"
4345   "@
4346         #
4347         ld%M1.uw        %m1, %0"
4348   [(set_attr "type" "arith_media,load_media")
4349    (set (attr "highpart")
4350         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4351                (const_string "user")]
4352               (const_string "ignore")))])
4354 (define_split
4355   [(set (match_operand:SI 0 "register_operand" "")
4356         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4357   "TARGET_SHMEDIA && reload_completed"
4358   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4359    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
4360   "
4362   rtx op1 = operands[1];
4364   if (GET_CODE (op1) == TRUNCATE)
4365     op1 = XEXP (op1, 0);
4366   operands[2]
4367     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4368                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4371 (define_expand "zero_extendqisi2"
4372   [(set (match_operand:SI 0 "arith_reg_operand" "")
4373         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
4374   ""
4375   "
4377   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
4378     operands[1] = copy_to_mode_reg (QImode, operands[1]);
4381 (define_insn "*zero_extendqisi2_compact"
4382   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
4383         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
4384   "TARGET_SH1"
4385   "extu.b       %1,%0"
4386   [(set_attr "type" "arith")])
4388 (define_insn "*zero_extendqisi2_media"
4389   [(set (match_operand:SI 0 "register_operand" "=r,r")
4390         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4391   "TARGET_SHMEDIA"
4392   "@
4393         andi    %1, 255, %0
4394         ld%M1.ub        %m1, %0"
4395   [(set_attr "type" "arith_media,load_media")
4396    (set (attr "highpart")
4397         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4398                (const_string "user")]
4399               (const_string "ignore")))])
4401 (define_insn "zero_extendqihi2"
4402   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
4403         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
4404   "TARGET_SH1"
4405   "extu.b       %1,%0"
4406   [(set_attr "type" "arith")])
4408 ;; -------------------------------------------------------------------------
4409 ;; Sign extension instructions
4410 ;; -------------------------------------------------------------------------
4412 ;; ??? This should be a define expand.
4413 ;; ??? Or perhaps it should be dropped?
4415 ;; convert_move generates good code for SH[1-4].
4416 (define_insn "extendsidi2"
4417   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
4418         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,?f")))]
4419   "TARGET_SHMEDIA"
4420   "@
4421         add.l   %1, r63, %0
4422         ld%M1.l %m1, %0
4423         fmov.sl %1, %0"
4424   [(set_attr "type" "arith_media,load_media,fpconv_media")
4425    (set (attr "highpart")
4426         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4427                (const_string "user")]
4428               (const_string "extend")))])
4430 (define_insn "extendhidi2"
4431   [(set (match_operand:DI 0 "register_operand" "=r,r")
4432         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4433   "TARGET_SHMEDIA"
4434   "@
4435         #
4436         ld%M1.w %m1, %0"
4437   [(set_attr "type" "*,load_media")
4438    (set (attr "highpart")
4439         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4440                (const_string "user")]
4441               (const_string "ignore")))])
4443 (define_split
4444   [(set (match_operand:DI 0 "register_operand" "")
4445         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
4446   "TARGET_SHMEDIA && reload_completed"
4447   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
4448    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
4449   "
4451   if (GET_CODE (operands[1]) == TRUNCATE)
4452     operands[1] = XEXP (operands[1], 0);
4455 (define_insn "extendqidi2"
4456   [(set (match_operand:DI 0 "register_operand" "=r,r")
4457         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4458   "TARGET_SHMEDIA"
4459   "@
4460         #
4461         ld%M1.b %m1, %0"
4462   [(set_attr "type" "*,load_media")
4463    (set (attr "highpart")
4464         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4465                (const_string "user")]
4466               (const_string "ignore")))])
4468 (define_split
4469   [(set (match_operand:DI 0 "register_operand" "")
4470         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
4471   "TARGET_SHMEDIA && reload_completed"
4472   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
4473    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
4474   "
4476   if (GET_CODE (operands[1]) == TRUNCATE)
4477     operands[1] = XEXP (operands[1], 0);
4480 (define_expand "extendhisi2"
4481   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4482         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4483   ""
4484   "")
4486 (define_insn "*extendhisi2_compact"
4487   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4488         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
4489   "TARGET_SH1"
4490   "@
4491         exts.w  %1,%0
4492         mov.w   %1,%0"
4493   [(set_attr "type" "arith,load")])
4495 (define_insn "*extendhisi2_media"
4496   [(set (match_operand:SI 0 "register_operand" "=r,r")
4497         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
4498   "TARGET_SHMEDIA"
4499   "@
4500         #
4501         ld%M1.w %m1, %0"
4502   [(set_attr "type" "arith_media,load_media")
4503    (set (attr "highpart")
4504         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4505                (const_string "user")]
4506               (const_string "ignore")))])
4508 (define_split
4509   [(set (match_operand:SI 0 "register_operand" "")
4510         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
4511   "TARGET_SHMEDIA && reload_completed"
4512   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16)))
4513    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
4514   "
4516   rtx op1 = operands[1];
4517   if (GET_CODE (op1) == TRUNCATE)
4518     op1 = XEXP (op1, 0);
4519   operands[2]
4520     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4521                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4524 (define_expand "extendqisi2"
4525   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4526         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4527   ""
4528   "")
4530 (define_insn "*extendqisi2_compact"
4531   [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
4532         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4533   "TARGET_SH1"
4534   "@
4535         exts.b  %1,%0
4536         mov.b   %1,%0"
4537   [(set_attr "type" "arith,load")])
4539 (define_insn "*extendqisi2_media"
4540   [(set (match_operand:SI 0 "register_operand" "=r,r")
4541         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
4542   "TARGET_SHMEDIA"
4543   "@
4544         #
4545         ld%M1.b %m1, %0"
4546   [(set_attr "type" "arith_media,load_media")
4547    (set (attr "highpart")
4548         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4549                (const_string "user")]
4550               (const_string "ignore")))])
4552 (define_split
4553   [(set (match_operand:SI 0 "register_operand" "")
4554         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
4555   "TARGET_SHMEDIA && reload_completed"
4556   [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24)))
4557    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
4558    "
4560   rtx op1 = operands[1];
4561   if (GET_CODE (op1) == TRUNCATE)
4562     op1 = XEXP (op1, 0);
4563   operands[2]
4564     = simplify_gen_subreg (SImode, op1, GET_MODE (op1),
4565                            subreg_lowpart_offset (SImode, GET_MODE (op1)));
4568 (define_insn "extendqihi2"
4569   [(set (match_operand:HI 0 "arith_reg_dest" "=r,r")
4570         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
4571   "TARGET_SH1"
4572   "@
4573         exts.b  %1,%0
4574         mov.b   %1,%0"
4575   [(set_attr "type" "arith,load")])
4577 /* It would seem useful to combine the truncXi patterns into the movXi
4578    patterns, but unary operators are ignored when matching constraints,
4579    so we need separate patterns.  */
4580 (define_insn "truncdisi2"
4581   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
4582         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
4583   "TARGET_SHMEDIA"
4584   "@
4585         add.l   %1, r63, %0
4586         st%M0.l %m0, %1
4587         fst%M0.s        %m0, %T1
4588         fmov.ls %1, %0
4589         fmov.sl %T1, %0
4590         fmov.s  %T1, %0"
4591   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")
4592    (set (attr "highpart")
4593         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4594                (const_string "user")]
4595               (const_string "extend")))])
4597 (define_insn "truncdihi2"
4598   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
4599         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
4600   "TARGET_SHMEDIA"
4601   "@
4602         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
4603         st%M0.w %m0, %1"
4604   [(set_attr "type"   "arith_media,store_media")
4605    (set_attr "length" "8,4")
4606    (set (attr "highpart")
4607         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4608                (const_string "user")]
4609               (const_string "extend")))])
4611 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
4612 ; Because we use zero extension, we can't provide signed QImode compares
4613 ; using a simple compare or conditional banch insn.
4614 (define_insn "truncdiqi2"
4615   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
4616         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
4617   "TARGET_SHMEDIA"
4618   "@
4619         andi    %1, 255, %0
4620         st%M0.b %m0, %1"
4621   [(set_attr "type"   "arith_media,store")
4622    (set (attr "highpart")
4623         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4624                (const_string "user")]
4625               (const_string "extend")))])
4626 ;; -------------------------------------------------------------------------
4627 ;; Move instructions
4628 ;; -------------------------------------------------------------------------
4630 ;; define push and pop so it is easy for sh.c
4631 ;; We can't use push and pop on SHcompact because the stack must always
4632 ;; be 8-byte aligned.
4634 (define_expand "push"
4635   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
4636         (match_operand:SI 0 "register_operand" "r,l,x"))]
4637   "TARGET_SH1 && ! TARGET_SH5"
4638   "")
4640 (define_expand "pop"
4641   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
4642         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
4643   "TARGET_SH1 && ! TARGET_SH5"
4644   "")
4646 (define_expand "push_e"
4647   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
4648                    (match_operand:SF 0 "" ""))
4649               (use (reg:PSI FPSCR_REG))
4650               (clobber (scratch:SI))])]
4651   "TARGET_SH1 && ! TARGET_SH5"
4652   "")
4654 (define_insn "push_fpul"
4655   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
4656   "TARGET_SH2E && ! TARGET_SH5"
4657   "sts.l        fpul,@-r15"
4658   [(set_attr "type" "store")
4659    (set_attr "late_fp_use" "yes")
4660    (set_attr "hit_stack" "yes")])
4662 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
4663 ;; so use that.
4664 (define_expand "push_4"
4665   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
4666                    (match_operand:DF 0 "" ""))
4667               (use (reg:PSI FPSCR_REG))
4668               (clobber (scratch:SI))])]
4669   "TARGET_SH1 && ! TARGET_SH5"
4670   "")
4672 (define_expand "pop_e"
4673   [(parallel [(set (match_operand:SF 0 "" "")
4674               (mem:SF (post_inc:SI (reg:SI SP_REG))))
4675               (use (reg:PSI FPSCR_REG))
4676               (clobber (scratch:SI))])]
4677   "TARGET_SH1 && ! TARGET_SH5"
4678   "")
4680 (define_insn "pop_fpul"
4681   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
4682   "TARGET_SH2E && ! TARGET_SH5"
4683   "lds.l        @r15+,fpul"
4684   [(set_attr "type" "load")
4685    (set_attr "hit_stack" "yes")])
4687 (define_expand "pop_4"
4688   [(parallel [(set (match_operand:DF 0 "" "")
4689                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
4690               (use (reg:PSI FPSCR_REG))
4691               (clobber (scratch:SI))])]
4692   "TARGET_SH1 && ! TARGET_SH5"
4693   "")
4695 (define_expand "push_fpscr"
4696   [(const_int 0)]
4697   "TARGET_SH2E"
4698   "
4700   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
4701                                                  gen_rtx_PRE_DEC (Pmode,
4702                                                           stack_pointer_rtx)),
4703                                         get_fpscr_rtx ()));
4704   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4705   DONE;
4708 (define_expand "pop_fpscr"
4709   [(const_int 0)]
4710   "TARGET_SH2E"
4711   "
4713   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
4714                                         gen_rtx_MEM (PSImode,
4715                                                  gen_rtx_POST_INC (Pmode,
4716                                                           stack_pointer_rtx))));
4717   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4718   DONE;
4721 ;; These two patterns can happen as the result of optimization, when
4722 ;; comparisons get simplified to a move of zero or 1 into the T reg.
4723 ;; They don't disappear completely, because the T reg is a fixed hard reg.
4725 (define_insn "clrt"
4726   [(set (reg:SI T_REG) (const_int 0))]
4727   "TARGET_SH1"
4728   "clrt")
4730 (define_insn "sett"
4731   [(set (reg:SI T_REG) (const_int 1))]
4732   "TARGET_SH1"
4733   "sett")
4735 ;; t/r must come after r/r, lest reload will try to reload stuff like
4736 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
4737 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
4738 (define_insn "movsi_i"
4739   [(set (match_operand:SI 0 "general_movdst_operand"
4740             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
4741         (match_operand:SI 1 "general_movsrc_operand"
4742          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
4743   "TARGET_SH1
4744    && ! TARGET_SH2E
4745    && ! TARGET_SH2A
4746    && (register_operand (operands[0], SImode)
4747        || register_operand (operands[1], SImode))"
4748   "@
4749         mov.l   %1,%0
4750         mov     %1,%0
4751         cmp/pl  %1
4752         mov.l   %1,%0
4753         sts     %1,%0
4754         sts     %1,%0
4755         movt    %0
4756         mov.l   %1,%0
4757         sts.l   %1,%0
4758         sts.l   %1,%0
4759         lds     %1,%0
4760         lds     %1,%0
4761         lds.l   %1,%0
4762         lds.l   %1,%0
4763         fake    %1,%0"
4764   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
4765    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
4767 ;; t/r must come after r/r, lest reload will try to reload stuff like
4768 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
4769 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
4770 ;; will require a reload.
4771 ;; ??? We can't include f/f because we need the proper FPSCR setting when
4772 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
4773 (define_insn "movsi_ie"
4774   [(set (match_operand:SI 0 "general_movdst_operand"
4775             "=r,r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
4776         (match_operand:SI 1 "general_movsrc_operand"
4777          "Q,rI08,I20,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
4778   "(TARGET_SH2E || TARGET_SH2A)
4779    && (register_operand (operands[0], SImode)
4780        || register_operand (operands[1], SImode))"
4781   "@
4782         mov.l   %1,%0
4783         mov     %1,%0
4784         movi20  %1,%0
4785         cmp/pl  %1
4786         mov.l   %1,%0
4787         sts     %1,%0
4788         sts     %1,%0
4789         movt    %0
4790         mov.l   %1,%0
4791         sts.l   %1,%0
4792         sts.l   %1,%0
4793         lds     %1,%0
4794         lds     %1,%0
4795         lds.l   %1,%0
4796         lds.l   %1,%0
4797         lds.l   %1,%0
4798         sts.l   %1,%0
4799         fake    %1,%0
4800         lds     %1,%0
4801         sts     %1,%0
4802         fsts    fpul,%0
4803         flds    %1,fpul
4804         fmov    %1,%0
4805         ! move optimized away"
4806   [(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")
4807    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
4808    (set_attr "length" "*,*,4,*,4,*,*,*,4,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
4810 (define_insn "movsi_i_lowpart"
4811   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
4812         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
4813    "TARGET_SH1
4814     && (register_operand (operands[0], SImode)
4815         || register_operand (operands[1], SImode))"
4816   "@
4817         mov.l   %1,%0
4818         mov     %1,%0
4819         mov.l   %1,%0
4820         sts     %1,%0
4821         sts     %1,%0
4822         movt    %0
4823         mov.l   %1,%0
4824         fake    %1,%0"
4825   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
4827 (define_insn_and_split "load_ra"
4828   [(set (match_operand:SI 0 "general_movdst_operand" "")
4829         (unspec:SI [(match_operand:SI 1 "register_operand" "")] UNSPEC_RA))]
4830   "TARGET_SH1"
4831   "#"
4832   "&& ! currently_expanding_to_rtl"
4833   [(set (match_dup 0) (match_dup 1))]
4834   "
4836   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
4837     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
4840 ;; The '?'s in the following constraints may not reflect the time taken
4841 ;; to perform the move. They are there to discourage the use of floating-
4842 ;; point registers for storing integer values.
4843 (define_insn "*movsi_media"
4844   [(set (match_operand:SI 0 "general_movdst_operand"
4845                 "=r,r,r,r,m,f?,m,f?,r,f?,*b,r,b")
4846         (match_operand:SI 1 "general_movsrc_operand"
4847          "r,I16C16,nCpg,m,rZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
4848   "TARGET_SHMEDIA_FPU
4849    && (register_operand (operands[0], SImode)
4850        || sh_register_operand (operands[1], SImode)
4851        || GET_CODE (operands[1]) == TRUNCATE)"
4852   "@
4853         add.l   %1, r63, %0
4854         movi    %1, %0
4855         #
4856         ld%M1.l %m1, %0
4857         st%M0.l %m0, %N1
4858         fld%M1.s        %m1, %0
4859         fst%M0.s        %m0, %1
4860         fmov.ls %N1, %0
4861         fmov.sl %1, %0
4862         fmov.s  %1, %0
4863         ptabs   %1, %0
4864         gettr   %1, %0
4865         pt      %1, %0"
4866   [(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")
4867    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")
4868    (set (attr "highpart")
4869         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4870                (const_string "user")]
4871               (const_string "ignore")))])
4873 (define_insn "*movsi_media_nofpu"
4874   [(set (match_operand:SI 0 "general_movdst_operand"
4875                 "=r,r,r,r,m,*b,r,*b")
4876         (match_operand:SI 1 "general_movsrc_operand"
4877          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
4878   "TARGET_SHMEDIA
4879    && (register_operand (operands[0], SImode)
4880        || sh_register_operand (operands[1], SImode)
4881        || GET_CODE (operands[1]) == TRUNCATE)"
4882   "@
4883         add.l   %1, r63, %0
4884         movi    %1, %0
4885         #
4886         ld%M1.l %m1, %0
4887         st%M0.l %m0, %N1
4888         ptabs   %1, %0
4889         gettr   %1, %0
4890         pt      %1, %0"
4891   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
4892    (set_attr "length" "4,4,8,4,4,4,4,12")
4893    (set (attr "highpart")
4894         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
4895                (const_string "user")]
4896               (const_string "ignore")))])
4898 (define_expand "movsi_const"
4899   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4900         (const:SI (sign_extend:SI
4901                    (truncate:HI
4902                     (ashiftrt:SI
4903                      (match_operand:DI 1 "immediate_operand" "s")
4904                      (const_int 16))))))
4905    (set (match_dup 0)
4906         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
4907                 (zero_extend:SI
4908                  (truncate:HI
4909                   (const:SI
4910                    (sign_extend:SI
4911                     (truncate:HI (match_dup 1))))))))]
4912   "TARGET_SHMEDIA && reload_completed
4913    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4914   "
4916   if (GET_CODE (operands[1]) == LABEL_REF
4917       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
4918     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
4919   else if (GOTOFF_P (operands[1]))
4920     {
4921       rtx unspec = XEXP (operands[1], 0);
4923       if (! UNSPEC_GOTOFF_P (unspec))
4924         {
4925           unspec = XEXP (unspec, 0);
4926           if (! UNSPEC_GOTOFF_P (unspec))
4927             abort ();
4928         }
4929       if (GET_CODE (XVECEXP (unspec , 0, 0)) == LABEL_REF
4930           && (GET_CODE (XEXP (XVECEXP (unspec, 0, 0), 0)) == CODE_LABEL))
4931         LABEL_NUSES (XEXP (XVECEXP (unspec, 0, 0), 0)) += 2;
4932     }
4935 (define_expand "movsi_const_16bit"
4936   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
4937         (const:SI (sign_extend:SI
4938                    (truncate:HI
4939                     (match_operand:DI 1 "immediate_operand" "s")))))]
4940   "TARGET_SHMEDIA && flag_pic && reload_completed
4941    && GET_CODE (operands[1]) == SYMBOL_REF"
4942   "")
4944 (define_split
4945   [(set (match_operand:SI 0 "arith_reg_dest" "")
4946         (match_operand:SI 1 "immediate_operand" ""))]
4947   "TARGET_SHMEDIA && reload_completed
4948    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
4949   [(const_int 0)]
4950   "
4952   rtx insn = emit_insn (gen_movsi_const (operands[0], operands[1]));
4954   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
4955                                         REG_NOTES (insn));
4957   DONE;
4960 (define_split
4961   [(set (match_operand:SI 0 "register_operand" "")
4962         (match_operand:SI 1 "immediate_operand" ""))]
4963   "TARGET_SHMEDIA && reload_completed
4964    && ((GET_CODE (operands[1]) == CONST_INT
4965         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
4966        || GET_CODE (operands[1]) == CONST_DOUBLE)"
4967   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
4969 (define_expand "movsi"
4970   [(set (match_operand:SI 0 "general_movdst_operand" "")
4971         (match_operand:SI 1 "general_movsrc_operand" ""))]
4972   ""
4973   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
4975 (define_expand "ic_invalidate_line"
4976   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
4977                                 (match_dup 1)] UNSPEC_ICACHE)
4978               (clobber (scratch:SI))])]
4979   "TARGET_HARD_SH4 || TARGET_SH5"
4980   "
4982   if (TARGET_SHMEDIA)
4983     {
4984       emit_insn (gen_ic_invalidate_line_media (operands[0]));
4985       DONE;
4986     }
4987   else if (TARGET_SHCOMPACT)
4988     {
4989       operands[1] = function_symbol (NULL, \"__ic_invalidate\", SFUNC_STATIC);
4990       operands[1] = force_reg (Pmode, operands[1]);
4991       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
4992       DONE;
4993     }
4994   else if (TARGET_SH4A_ARCH)
4995     {
4996       emit_insn (gen_ic_invalidate_line_sh4a (operands[0]));
4997       DONE;
4998     }
4999   operands[0] = force_reg (Pmode, operands[0]);
5000   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
5001                                                                Pmode)));
5004 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
5005 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
5006 ;; the requirement *1*00 for associative address writes.  The alignment of
5007 ;; %0 implies that its least significant bit is cleared,
5008 ;; thus we clear the V bit of a matching entry if there is one.
5009 (define_insn "ic_invalidate_line_i"
5010   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
5011                      (match_operand:SI 1 "register_operand" "r")]
5012                      UNSPEC_ICACHE)
5013    (clobber (match_scratch:SI 2 "=&r"))]
5014   "TARGET_HARD_SH4"
5015   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
5016   [(set_attr "length" "8")
5017    (set_attr "type" "cwb")])
5019 (define_insn "ic_invalidate_line_sh4a"
5020   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
5021                     UNSPEC_ICACHE)]
5022   "TARGET_SH4A_ARCH"
5023   "ocbwb\\t@%0\;synco\;icbi\\t@%0"
5024   [(set_attr "length" "16")
5025    (set_attr "type" "cwb")])
5027 ;; ??? could make arg 0 an offsettable memory operand to allow to save
5028 ;; an add in the code that calculates the address.
5029 (define_insn "ic_invalidate_line_media"
5030   [(unspec_volatile [(match_operand 0 "any_register_operand" "r")]
5031                     UNSPEC_ICACHE)]
5032   "TARGET_SHMEDIA"
5033   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
5034   [(set_attr "length" "16")
5035    (set_attr "type" "invalidate_line_media")])
5037 (define_insn "ic_invalidate_line_compact"
5038   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5039                      (match_operand:SI 1 "register_operand" "r")]
5040                     UNSPEC_ICACHE)
5041    (clobber (reg:SI PR_REG))]
5042   "TARGET_SHCOMPACT"
5043   "jsr @%1%#"
5044   [(set_attr "type" "sfunc")
5045    (set_attr "needs_delay_slot" "yes")])
5047 (define_expand "initialize_trampoline"
5048   [(match_operand:SI 0 "" "")
5049    (match_operand:SI 1 "" "")
5050    (match_operand:SI 2 "" "")]
5051   "TARGET_SHCOMPACT"
5052   "
5054   rtx sfun, tramp;
5056   tramp = force_reg (Pmode, operands[0]);
5057   sfun = force_reg (Pmode, function_symbol (NULL, \"__init_trampoline\",
5058                                             SFUNC_STATIC));
5059   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
5060   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
5062   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
5063   DONE;
5066 (define_insn "initialize_trampoline_compact"
5067   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
5068                      (match_operand:SI 1 "register_operand" "r")
5069                      (reg:SI R2_REG) (reg:SI R3_REG)]
5070                     UNSPEC_INIT_TRAMP)
5072    (clobber (reg:SI PR_REG))]
5073   "TARGET_SHCOMPACT"
5074   "jsr @%1%#"
5075   [(set_attr "type" "sfunc")
5076    (set_attr "needs_delay_slot" "yes")])
5078 (define_insn "movqi_i"
5079   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
5080         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
5081   "TARGET_SH1
5082    && (arith_reg_operand (operands[0], QImode)
5083        || arith_reg_operand (operands[1], QImode))"
5084   "@
5085         mov     %1,%0
5086         mov.b   %1,%0
5087         mov.b   %1,%0
5088         movt    %0
5089         sts     %1,%0
5090         lds     %1,%0"
5091  [(set_attr "type" "move,load,store,move,move,move")])
5093 (define_insn "*movqi_media"
5094   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
5095         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
5096   "TARGET_SHMEDIA
5097    && (arith_reg_operand (operands[0], QImode)
5098        || extend_reg_or_0_operand (operands[1], QImode))"
5099   "@
5100         add.l   %1, r63, %0
5101         movi    %1, %0
5102         ld%M1.ub        %m1, %0
5103         st%M0.b %m0, %N1"
5104   [(set_attr "type" "arith_media,arith_media,load_media,store_media")
5105    (set (attr "highpart")
5106         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5107                (const_string "user")]
5108               (const_string "ignore")))])
5110 (define_expand "movqi"
5111   [(set (match_operand:QI 0 "general_operand" "")
5112         (match_operand:QI 1 "general_operand"  ""))]
5113   ""
5114   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
5116 (define_expand "reload_inqi"
5117   [(set (match_operand:SI 2 "" "=&r")
5118         (match_operand:QI 1 "inqhi_operand" ""))
5119    (set (match_operand:QI 0 "arith_reg_operand" "=r")
5120         (truncate:QI (match_dup 3)))]
5121   "TARGET_SHMEDIA"
5122   "
5124   rtx inner = XEXP (operands[1], 0);
5125   int regno = REGNO (inner);
5127   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5128   operands[1] = gen_rtx_REG (SImode, regno);
5129   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5132 /* When storing r0, we have to avoid reg+reg addressing.  */
5133 (define_insn "movhi_i"
5134   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
5135         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
5136   "TARGET_SH1
5137    && (arith_reg_operand (operands[0], HImode)
5138        || arith_reg_operand (operands[1], HImode))
5139    && (GET_CODE (operands[0]) != MEM
5140        || GET_CODE (XEXP (operands[0], 0)) != PLUS
5141        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
5142        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
5143   "@
5144         mov.w   %1,%0
5145         mov     %1,%0
5146         mov.w   %1,%0
5147         movt    %0
5148         mov.w   %1,%0
5149         sts     %1,%0
5150         lds     %1,%0
5151         fake    %1,%0"
5152   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
5154 (define_insn "*movhi_media"
5155   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
5156         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
5157   "TARGET_SHMEDIA
5158    && (arith_reg_operand (operands[0], HImode)
5159        || arith_reg_or_0_operand (operands[1], HImode))"
5160   "@
5161         add.l   %1, r63, %0
5162         movi    %1, %0
5163         #
5164         ld%M1.w %m1, %0
5165         st%M0.w %m0, %N1"
5166   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")
5167    (set (attr "highpart")
5168         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
5169                (const_string "user")]
5170               (const_string "ignore")))])
5172 (define_split
5173   [(set (match_operand:HI 0 "register_operand" "")
5174         (match_operand:HI 1 "immediate_operand" ""))]
5175   "TARGET_SHMEDIA && reload_completed
5176    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5177   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
5179 (define_expand "movhi"
5180   [(set (match_operand:HI 0 "general_movdst_operand" "")
5181         (match_operand:HI 1 "general_movsrc_operand"  ""))]
5182   ""
5183   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
5185 (define_expand "reload_inhi"
5186   [(set (match_operand:SI 2 "" "=&r")
5187         (match_operand:HI 1 "inqhi_operand" ""))
5188    (set (match_operand:HI 0 "arith_reg_operand" "=r")
5189         (truncate:HI (match_dup 3)))]
5190   "TARGET_SHMEDIA"
5191   "
5193   rtx inner = XEXP (operands[1], 0);
5194   int regno = REGNO (inner);
5196   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
5197   operands[1] = gen_rtx_REG (SImode, regno);
5198   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
5201 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
5202 ;; compiled with -m2 -ml -O3 -funroll-loops
5203 (define_insn "*movdi_i"
5204   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
5205         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
5206   "TARGET_SH1
5207    && (arith_reg_operand (operands[0], DImode)
5208        || arith_reg_operand (operands[1], DImode))"
5209   "* return output_movedouble (insn, operands, DImode);"
5210   [(set_attr "length" "4")
5211    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
5213 ;; If the output is a register and the input is memory or a register, we have
5214 ;; to be careful and see which word needs to be loaded first.
5216 (define_split
5217   [(set (match_operand:DI 0 "general_movdst_operand" "")
5218         (match_operand:DI 1 "general_movsrc_operand" ""))]
5219   "TARGET_SH1 && reload_completed"
5220   [(set (match_dup 2) (match_dup 3))
5221    (set (match_dup 4) (match_dup 5))]
5222   "
5224   int regno;
5226   if ((GET_CODE (operands[0]) == MEM
5227        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
5228       || (GET_CODE (operands[1]) == MEM
5229           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
5230     FAIL;
5232   switch (GET_CODE (operands[0]))
5233     {
5234     case REG:
5235       regno = REGNO (operands[0]);
5236       break;
5237     case SUBREG:
5238       regno = subreg_regno (operands[0]);
5239       break;
5240     case MEM:
5241       regno = -1;
5242       break;
5243     default:
5244       gcc_unreachable ();
5245     }
5247   if (regno == -1
5248       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
5249     {
5250       operands[2] = operand_subword (operands[0], 0, 0, DImode);
5251       operands[3] = operand_subword (operands[1], 0, 0, DImode);
5252       operands[4] = operand_subword (operands[0], 1, 0, DImode);
5253       operands[5] = operand_subword (operands[1], 1, 0, DImode);
5254     }
5255   else
5256     {
5257       operands[2] = operand_subword (operands[0], 1, 0, DImode);
5258       operands[3] = operand_subword (operands[1], 1, 0, DImode);
5259       operands[4] = operand_subword (operands[0], 0, 0, DImode);
5260       operands[5] = operand_subword (operands[1], 0, 0, DImode);
5261     }
5263   if (operands[2] == 0 || operands[3] == 0
5264       || operands[4] == 0 || operands[5] == 0)
5265     FAIL;
5268 ;; The '?'s in the following constraints may not reflect the time taken
5269 ;; to perform the move. They are there to discourage the use of floating-
5270 ;; point registers for storing integer values.
5271 (define_insn "*movdi_media"
5272   [(set (match_operand:DI 0 "general_movdst_operand"
5273                  "=r,r,r,rl,m,f?,m,f?,r,f?,*b,r,*b")
5274         (match_operand:DI 1 "general_movsrc_operand"
5275          "r,I16C16,nCpgF,m,rlZ,m,f?,rZ,f?,f?,r,*b,Csy"))]
5276   "TARGET_SHMEDIA_FPU
5277    && (register_operand (operands[0], DImode)
5278        || sh_register_operand (operands[1], DImode))"
5279   "@
5280         add     %1, r63, %0
5281         movi    %1, %0
5282         #
5283         ld%M1.q %m1, %0
5284         st%M0.q %m0, %N1
5285         fld%M1.d        %m1, %0
5286         fst%M0.d        %m0, %1
5287         fmov.qd %N1, %0
5288         fmov.dq %1, %0
5289         fmov.d  %1, %0
5290         ptabs   %1, %0
5291         gettr   %1, %0
5292         pt      %1, %0"
5293   [(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")
5294    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
5296 (define_insn "*movdi_media_nofpu"
5297   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,*b");
5298         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
5299   "TARGET_SHMEDIA
5300    && (register_operand (operands[0], DImode)
5301        || sh_register_operand (operands[1], DImode))"
5302   "@
5303         add     %1, r63, %0
5304         movi    %1, %0
5305         #
5306         ld%M1.q %m1, %0
5307         st%M0.q %m0, %N1
5308         ptabs   %1, %0
5309         gettr   %1, %0
5310         pt      %1, %0"
5311   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
5312    (set_attr "length" "4,4,16,4,4,4,4,*")])
5314 (define_insn "*movdi_media_I16"
5315   [(set (match_operand:DI 0 "ext_dest_operand" "=r")
5316         (match_operand:DI 1 "const_int_operand" "I16"))]
5317   "TARGET_SHMEDIA && reload_completed"
5318   "movi %1, %0"
5319   [(set_attr "type" "arith_media")
5320    (set_attr "length" "4")])
5322 (define_split
5323   [(set (match_operand:DI 0 "arith_reg_dest" "")
5324         (match_operand:DI 1 "immediate_operand" ""))]
5325   "TARGET_SHMEDIA && reload_completed
5326    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5327   [(set (match_dup 0) (match_dup 1))]
5328   "
5330   rtx insn;
5332   if (TARGET_SHMEDIA64)
5333     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
5334   else
5335     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
5337   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5338                                         REG_NOTES (insn));
5340   DONE;
5343 (define_expand "movdi_const"
5344   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5345         (const:DI (sign_extend:DI
5346                    (truncate:HI
5347                     (ashiftrt:DI
5348                      (match_operand:DI 1 "immediate_operand" "s")
5349                      (const_int 48))))))
5350    (set (match_dup 0)
5351         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5352                 (zero_extend:DI
5353                  (truncate:HI
5354                   (const:DI
5355                    (sign_extend:DI
5356                     (truncate:HI
5357                      (ashiftrt:SI
5358                       (match_dup 1)
5359                       (const_int 32)))))))))
5360    (set (match_dup 0)
5361         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5362                 (zero_extend:DI
5363                  (truncate:HI
5364                   (const:DI
5365                    (sign_extend:DI
5366                     (truncate:HI
5367                      (ashiftrt:SI
5368                       (match_dup 1)
5369                       (const_int 16)))))))))
5370    (set (match_dup 0)
5371         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5372                 (zero_extend:DI
5373                  (truncate:HI
5374                   (const:DI
5375                    (sign_extend:DI
5376                     (truncate:HI
5377                      (match_dup 1))))))))]
5378   "TARGET_SHMEDIA64 && reload_completed
5379    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5380   "
5382   sh_mark_label (operands[1], 4);
5385 (define_expand "movdi_const_32bit"
5386   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5387         (const:DI (sign_extend:DI
5388                    (truncate:HI
5389                     (ashiftrt:DI
5390                      (match_operand:DI 1 "immediate_operand" "s")
5391                      (const_int 16))))))
5392    (set (match_dup 0)
5393         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5394                 (zero_extend:DI
5395                  (truncate:HI
5396                   (const:DI
5397                    (sign_extend:DI
5398                     (truncate:HI
5399                      (match_dup 1))))))))]
5400   "TARGET_SHMEDIA32 && reload_completed
5401    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
5402   "
5404   sh_mark_label (operands[1], 2);
5407 (define_expand "movdi_const_16bit"
5408   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
5409         (const:DI (sign_extend:DI
5410                    (truncate:HI
5411                     (match_operand:DI 1 "immediate_operand" "s")))))]
5412   "TARGET_SHMEDIA && flag_pic && reload_completed
5413    && GET_CODE (operands[1]) == SYMBOL_REF"
5414   "")
5416 (define_split
5417   [(set (match_operand:DI 0 "ext_dest_operand" "")
5418         (match_operand:DI 1 "immediate_operand" ""))]
5419   "TARGET_SHMEDIA && reload_completed
5420    && GET_CODE (operands[1]) == CONST_INT
5421    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
5422   [(set (match_dup 0) (match_dup 2))
5423    (match_dup 1)]
5424   "
5426   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
5427   unsigned HOST_WIDE_INT low = val;
5428   unsigned HOST_WIDE_INT high = val;
5429   unsigned HOST_WIDE_INT sign;
5430   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
5432   /* Sign-extend the 16 least-significant bits.  */
5433   low &= 0xffff;
5434   low ^= 0x8000;
5435   low -= 0x8000;
5437   /* Arithmetic shift right the word by 16 bits.  */
5438   high >>= 16;
5439   if (GET_CODE (operands[0]) == SUBREG
5440       && GET_MODE (SUBREG_REG (operands[0])) == SImode)
5441     {
5442       high &= 0xffff;
5443       high ^= 0x8000;
5444       high -= 0x8000;
5445     }
5446   else
5447     {
5448       sign = 1;
5449       sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5450       high ^= sign;
5451       high -= sign;
5452     }
5453   do
5454     {
5455       /* If we can't generate the constant with a two-insn movi / shori
5456          sequence, try some other strategies.  */
5457       if (! CONST_OK_FOR_I16 (high))
5458         {
5459           /* Try constant load / left shift.  We know VAL != 0.  */
5460           val2 = val ^ (val-1);
5461           if (val2 > 0x1ffff)
5462             {
5463               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
5465               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
5466                   || (! CONST_OK_FOR_I16 (high >> 16)
5467                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
5468                 {
5469                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
5470                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
5471                                                    GEN_INT (trailing_zeroes));
5472                   break;
5473                 }
5474             }
5475           /* Try constant load / right shift.  */
5476           val2 = (val >> 15) + 1;
5477           if (val2 == (val2 & -val2))
5478             {
5479               int shift = 49 - exact_log2 (val2);
5481               val2 = trunc_int_for_mode (val << shift, DImode);
5482               if (CONST_OK_FOR_I16 (val2))
5483                 {
5484                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
5485                                                    GEN_INT (shift));
5486                   break;
5487                 }
5488             }
5489           /* Try mperm.w .  */
5490           val2 = val & 0xffff;
5491           if ((val >> 16 & 0xffff) == val2
5492               && (val >> 32 & 0xffff) == val2
5493               && (val >> 48 & 0xffff) == val2)
5494             {
5495               val2 = (HOST_WIDE_INT) val >> 48;
5496               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
5497               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
5498               break;
5499             }
5500           /* Try movi / mshflo.l  */
5501           val2 = (HOST_WIDE_INT) val >> 32;
5502           if (val2 == ((unsigned HOST_WIDE_INT)
5503                         trunc_int_for_mode (val, SImode)))
5504             {
5505               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5506                                              operands[0]);
5507               break;
5508             }
5509           /* Try movi / mshflo.l w/ r63.  */
5510           val2 = val + ((HOST_WIDE_INT) -1 << 32);
5511           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
5512             {
5513               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
5514                                              const0_rtx);
5515               break;
5516             }
5517         }
5518       val2 = high;
5519       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
5520     }
5521   while (0);
5522   operands[2] = GEN_INT (val2);
5525 (define_split
5526   [(set (match_operand:DI 0 "ext_dest_operand" "")
5527         (match_operand:DI 1 "immediate_operand" ""))]
5528   "TARGET_SHMEDIA && reload_completed
5529    && GET_CODE (operands[1]) == CONST_DOUBLE"
5530   [(set (match_dup 0) (match_dup 2))
5531   (set (match_dup 0)
5532        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
5533                (zero_extend:DI (truncate:HI (match_dup 1)))))]
5534   "
5536   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
5537   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
5538   unsigned HOST_WIDE_INT val = low;
5539   unsigned HOST_WIDE_INT sign;
5541   /* Sign-extend the 16 least-significant bits.  */
5542   val &= 0xffff;
5543   val ^= 0x8000;
5544   val -= 0x8000;
5545   operands[1] = GEN_INT (val);
5547   /* Arithmetic shift right the double-word by 16 bits.  */
5548   low >>= 16;
5549   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
5550   high >>= 16;
5551   sign = 1;
5552   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
5553   high ^= sign;
5554   high -= sign;
5556   /* This will only be true if high is a sign-extension of low, i.e.,
5557      it must be either 0 or (unsigned)-1, and be zero iff the
5558      most-significant bit of low is set.  */
5559   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
5560     operands[2] = GEN_INT (low);
5561   else
5562     operands[2] = immed_double_const (low, high, DImode);
5565 (define_insn "shori_media"
5566   [(set (match_operand:DI 0 "ext_dest_operand" "=r,r")
5567         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
5568                            (const_int 16))
5569                 (zero_extend:DI
5570                  (truncate:HI
5571                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
5572   "TARGET_SHMEDIA && (reload_completed || arith_reg_dest (operands[0], DImode))"
5573   "@
5574         shori   %u2, %0
5575         #"
5576   [(set_attr "type" "arith_media,*")])
5578 (define_insn "*shori_media_si"
5579   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
5580         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
5581                            (const_int 16))
5582                 (zero_extend:SI
5583                  (truncate:HI
5584                   (match_operand:SI 2 "immediate_operand" "I16C16")))))]
5585   "TARGET_SHMEDIA"
5586   "shori        %u2, %0")
5588 (define_expand "movdi"
5589   [(set (match_operand:DI 0 "general_movdst_operand" "")
5590         (match_operand:DI 1 "general_movsrc_operand" ""))]
5591   ""
5592   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
5594 (define_insn "movdf_media"
5595   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
5596         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
5597   "TARGET_SHMEDIA_FPU
5598    && (register_operand (operands[0], DFmode)
5599        || sh_register_operand (operands[1], DFmode))"
5600   "@
5601         fmov.d  %1, %0
5602         fmov.qd %N1, %0
5603         fmov.dq %1, %0
5604         add     %1, r63, %0
5605         #
5606         fld%M1.d        %m1, %0
5607         fst%M0.d        %m0, %1
5608         ld%M1.q %m1, %0
5609         st%M0.q %m0, %N1"
5610   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
5612 (define_insn "movdf_media_nofpu"
5613   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5614         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
5615   "TARGET_SHMEDIA
5616    && (register_operand (operands[0], DFmode)
5617        || sh_register_operand (operands[1], DFmode))"
5618   "@
5619         add     %1, r63, %0
5620         #
5621         ld%M1.q %m1, %0
5622         st%M0.q %m0, %N1"
5623   [(set_attr "type" "arith_media,*,load_media,store_media")])
5625 (define_split
5626   [(set (match_operand:DF 0 "arith_reg_dest" "")
5627         (match_operand:DF 1 "immediate_operand" ""))]
5628   "TARGET_SHMEDIA && reload_completed"
5629   [(set (match_dup 3) (match_dup 2))]
5630   "
5632   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
5633   long values[2];
5634   REAL_VALUE_TYPE value;
5636   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
5637   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
5639   if (HOST_BITS_PER_WIDE_INT >= 64)
5640     operands[2] = immed_double_const ((unsigned long) values[endian]
5641                                       | ((HOST_WIDE_INT) values[1 - endian]
5642                                          << 32), 0, DImode);
5643   else
5644     {
5645       gcc_assert (HOST_BITS_PER_WIDE_INT == 32);
5646       operands[2] = immed_double_const (values[endian], values[1 - endian],
5647                                         DImode);
5648     }
5650   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
5653 ;; ??? This should be a define expand.
5655 (define_insn "movdf_k"
5656   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
5657         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
5658   "TARGET_SH1
5659    && (! (TARGET_SH4 || TARGET_SH2A_DOUBLE) || reload_completed
5660        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
5661        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
5662        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
5663    && (arith_reg_operand (operands[0], DFmode)
5664        || arith_reg_operand (operands[1], DFmode))"
5665   "* return output_movedouble (insn, operands, DFmode);"
5666   [(set_attr "length" "4")
5667    (set_attr "type" "move,pcload,load,store")])
5669 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
5670 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
5671 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
5672 ;; the d/m/c/X alternative, which is split later into single-precision
5673 ;; instructions.  And when not optimizing, no splits are done before fixing
5674 ;; up pcloads, so we need usable length information for that.
5675 (define_insn "movdf_i4"
5676   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
5677         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
5678    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
5679    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
5680   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5681    && (arith_reg_operand (operands[0], DFmode)
5682        || arith_reg_operand (operands[1], DFmode))"
5683   "@
5684         fmov    %1,%0
5685         #
5686         #
5687         fmov.d  %1,%0
5688         fmov.d  %1,%0
5689         #
5690         #
5691         #
5692         #
5693         #"
5694   [(set_attr_alternative "length"
5695      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
5696       (const_int 4)
5697       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5698       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5699       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
5700       (const_int 4)
5701       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
5702       ;; We can't use 4-byte push/pop on SHcompact, so we have to
5703       ;; increment or decrement r15 explicitly.
5704       (if_then_else
5705        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5706        (const_int 10) (const_int 8))
5707       (if_then_else
5708        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
5709        (const_int 10) (const_int 8))])
5710    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
5711    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
5712    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
5713                                            (const_string "double")
5714                                            (const_string "none")))])
5716 ;; Moving DFmode between fp/general registers through memory
5717 ;; (the top of the stack) is faster than moving through fpul even for
5718 ;; little endian.  Because the type of an instruction is important for its
5719 ;; scheduling,  it is beneficial to split these operations, rather than
5720 ;; emitting them in one single chunk, even if this will expose a stack
5721 ;; use that will prevent scheduling of other stack accesses beyond this
5722 ;; instruction.
5723 (define_split
5724   [(set (match_operand:DF 0 "register_operand" "")
5725         (match_operand:DF 1 "register_operand" ""))
5726    (use (match_operand:PSI 2 "fpscr_operand" ""))
5727    (clobber (match_scratch:SI 3 "=X"))]
5728   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed
5729    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
5730   [(const_int 0)]
5731   "
5733   rtx insn, tos;
5735   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
5736     {
5737       emit_move_insn (stack_pointer_rtx,
5738                       plus_constant (stack_pointer_rtx, -8));
5739       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
5740     }
5741   else
5742     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
5743   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
5744   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
5745     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5746   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5747     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
5748   else
5749     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
5750   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
5751   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
5752     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
5753   else
5754     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
5755   DONE;
5758 ;; local-alloc sometimes allocates scratch registers even when not required,
5759 ;; so we must be prepared to handle these.
5761 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
5762 (define_split
5763   [(set (match_operand:DF 0 "general_movdst_operand" "")
5764         (match_operand:DF 1 "general_movsrc_operand"  ""))
5765    (use (match_operand:PSI 2 "fpscr_operand" ""))
5766    (clobber (match_scratch:SI 3 ""))]
5767   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)
5768    && reload_completed
5769    && true_regnum (operands[0]) < 16
5770    && true_regnum (operands[1]) < 16"
5771   [(set (match_dup 0) (match_dup 1))]
5772   "
5774   /* If this was a reg <-> mem operation with base + index reg addressing,
5775      we have to handle this in a special way.  */
5776   rtx mem = operands[0];
5777   int store_p = 1;
5778   if (! memory_operand (mem, DFmode))
5779     {
5780       mem = operands[1];
5781       store_p = 0;
5782     }
5783   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
5784     mem = SUBREG_REG (mem);
5785   if (GET_CODE (mem) == MEM)
5786     {
5787       rtx addr = XEXP (mem, 0);
5788       if (GET_CODE (addr) == PLUS
5789           && GET_CODE (XEXP (addr, 0)) == REG
5790           && GET_CODE (XEXP (addr, 1)) == REG)
5791         {
5792           int offset;
5793           rtx reg0 = gen_rtx_REG (Pmode, 0);
5794           rtx regop = operands[store_p], word0 ,word1;
5796           if (GET_CODE (regop) == SUBREG)
5797             alter_subreg (&regop);
5798           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
5799             offset = 2;
5800           else
5801             offset = 4;
5802           mem = copy_rtx (mem);
5803           PUT_MODE (mem, SImode);
5804           word0 = gen_rtx_SUBREG (SImode, regop, 0);
5805           alter_subreg (&word0);
5806           word1 = gen_rtx_SUBREG (SImode, regop, 4);
5807           alter_subreg (&word1);
5808           if (store_p || ! refers_to_regno_p (REGNO (word0),
5809                                               REGNO (word0) + 1, addr, 0))
5810             {
5811               emit_insn (store_p
5812                          ? gen_movsi_ie (mem, word0)
5813                          : gen_movsi_ie (word0, mem));
5814               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5815               mem = copy_rtx (mem);
5816               emit_insn (store_p
5817                          ? gen_movsi_ie (mem, word1)
5818                          : gen_movsi_ie (word1, mem));
5819               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5820             }
5821           else
5822             {
5823               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
5824               emit_insn (gen_movsi_ie (word1, mem));
5825               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
5826               mem = copy_rtx (mem);
5827               emit_insn (gen_movsi_ie (word0, mem));
5828             }
5829           DONE;
5830         }
5831     }
5834 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
5835 (define_split
5836   [(set (match_operand:DF 0 "register_operand" "")
5837         (match_operand:DF 1 "memory_operand"  ""))
5838    (use (match_operand:PSI 2 "fpscr_operand" ""))
5839    (clobber (reg:SI R0_REG))]
5840   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed"
5841   [(parallel [(set (match_dup 0) (match_dup 1))
5842               (use (match_dup 2))
5843               (clobber (scratch:SI))])]
5844   "")
5846 (define_expand "reload_indf"
5847   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
5848                    (match_operand:DF 1 "immediate_operand" "FQ"))
5849               (use (reg:PSI FPSCR_REG))
5850               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5851   "TARGET_SH1"
5852   "")
5854 (define_expand "reload_outdf"
5855   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
5856                    (match_operand:DF 1 "register_operand" "af,r"))
5857               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
5858   "TARGET_SH1"
5859   "")
5861 ;; Simplify no-op moves.
5862 (define_split
5863   [(set (match_operand:SF 0 "register_operand" "")
5864         (match_operand:SF 1 "register_operand" ""))
5865    (use (match_operand:PSI 2 "fpscr_operand" ""))
5866    (clobber (match_scratch:SI 3 ""))]
5867   "TARGET_SH2E && reload_completed
5868    && true_regnum (operands[0]) == true_regnum (operands[1])"
5869   [(set (match_dup 0) (match_dup 0))]
5870   "")
5872 ;; fmovd substitute post-reload splits
5873 (define_split
5874   [(set (match_operand:DF 0 "register_operand" "")
5875         (match_operand:DF 1 "register_operand" ""))
5876    (use (match_operand:PSI 2 "fpscr_operand" ""))
5877    (clobber (match_scratch:SI 3 ""))]
5878   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
5879    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5880    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5881   [(const_int 0)]
5882   "
5884   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
5885   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
5886                            gen_rtx_REG (SFmode, src), operands[2]));
5887   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
5888                            gen_rtx_REG (SFmode, src + 1), operands[2]));
5889   DONE;
5892 (define_split
5893   [(set (match_operand:DF 0 "register_operand" "")
5894         (mem:DF (match_operand:SI 1 "register_operand" "")))
5895    (use (match_operand:PSI 2 "fpscr_operand" ""))
5896    (clobber (match_scratch:SI 3 ""))]
5897   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5898    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
5899    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
5900   [(const_int 0)]
5901   "
5903   int regno = true_regnum (operands[0]);
5904   rtx insn;
5905   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
5907   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5908                                            regno + !! TARGET_LITTLE_ENDIAN),
5909                                   mem2, operands[2]));
5910   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
5911   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
5912                                            regno + ! TARGET_LITTLE_ENDIAN),
5913                                   gen_rtx_MEM (SFmode, operands[1]),
5914                                   operands[2]));
5915   DONE;
5918 (define_split
5919   [(set (match_operand:DF 0 "register_operand" "")
5920         (match_operand:DF 1 "memory_operand" ""))
5921    (use (match_operand:PSI 2 "fpscr_operand" ""))
5922    (clobber (match_scratch:SI 3 ""))]
5923   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5924    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
5925   [(const_int 0)]
5926   "
5928   int regno = true_regnum (operands[0]);
5929   rtx addr, insn, adjust = NULL_RTX;
5930   rtx mem2 = copy_rtx (operands[1]);
5931   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
5932   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
5934   PUT_MODE (mem2, SFmode);
5935   operands[1] = copy_rtx (mem2);
5936   addr = XEXP (mem2, 0);
5937   if (GET_CODE (addr) != POST_INC)
5938     {
5939       /* If we have to modify the stack pointer, the value that we have
5940          read with post-increment might be modified by an interrupt,
5941          so write it back.  */
5942       if (REGNO (addr) == STACK_POINTER_REGNUM)
5943         adjust = gen_push_e (reg0);
5944       else
5945         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
5946       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
5947     }
5948   addr = XEXP (addr, 0);
5949   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
5950   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5951   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
5952   if (adjust)
5953     emit_insn (adjust);
5954   else
5955     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5956   DONE;
5959 (define_split
5960   [(set (match_operand:DF 0 "memory_operand" "")
5961         (match_operand:DF 1 "register_operand" ""))
5962    (use (match_operand:PSI 2 "fpscr_operand" ""))
5963    (clobber (match_scratch:SI 3 ""))]
5964   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed
5965    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
5966   [(const_int 0)]
5967   "
5969   int regno = true_regnum (operands[1]);
5970   rtx insn, addr, adjust = NULL_RTX;
5972   operands[0] = copy_rtx (operands[0]);
5973   PUT_MODE (operands[0], SFmode);
5974   insn = emit_insn (gen_movsf_ie (operands[0],
5975                                   gen_rtx_REG (SFmode,
5976                                            regno + ! TARGET_LITTLE_ENDIAN),
5977                                   operands[2]));
5978   operands[0] = copy_rtx (operands[0]);
5979   addr = XEXP (operands[0], 0);
5980   if (GET_CODE (addr) != PRE_DEC)
5981     {
5982       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
5983       emit_insn_before (adjust, insn);
5984       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
5985     }
5986   addr = XEXP (addr, 0);
5987   if (! adjust)
5988     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5989   insn = emit_insn (gen_movsf_ie (operands[0],
5990                                   gen_rtx_REG (SFmode,
5991                                            regno + !! TARGET_LITTLE_ENDIAN),
5992                                   operands[2]));
5993   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
5994   DONE;
5997 ;; If the output is a register and the input is memory or a register, we have
5998 ;; to be careful and see which word needs to be loaded first.
6000 (define_split
6001   [(set (match_operand:DF 0 "general_movdst_operand" "")
6002         (match_operand:DF 1 "general_movsrc_operand" ""))]
6003   "TARGET_SH1 && reload_completed"
6004   [(set (match_dup 2) (match_dup 3))
6005    (set (match_dup 4) (match_dup 5))]
6006   "
6008   int regno;
6010   if ((GET_CODE (operands[0]) == MEM
6011        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
6012       || (GET_CODE (operands[1]) == MEM
6013           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
6014     FAIL;
6016   switch (GET_CODE (operands[0]))
6017     {
6018     case REG:
6019       regno = REGNO (operands[0]);
6020       break;
6021     case SUBREG:
6022       regno = subreg_regno (operands[0]);
6023       break;
6024     case MEM:
6025       regno = -1;
6026       break;
6027     default:
6028       gcc_unreachable ();
6029     }
6031   if (regno == -1
6032       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
6033     {
6034       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
6035       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
6036       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
6037       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
6038     }
6039   else
6040     {
6041       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
6042       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
6043       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
6044       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
6045     }
6047   if (operands[2] == 0 || operands[3] == 0
6048       || operands[4] == 0 || operands[5] == 0)
6049     FAIL;
6052 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
6053 ;; used only once, let combine add in the index again.
6055 (define_split
6056   [(set (match_operand:SI 0 "register_operand" "")
6057         (match_operand:SI 1 "" ""))
6058    (clobber (match_operand 2 "register_operand" ""))]
6059   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6060    && ALLOW_INDEXED_ADDRESS"
6061   [(use (reg:SI R0_REG))]
6062   "
6064   rtx addr, reg, const_int;
6066   if (GET_CODE (operands[1]) != MEM)
6067     FAIL;
6068   addr = XEXP (operands[1], 0);
6069   if (GET_CODE (addr) != PLUS)
6070     FAIL;
6071   reg = XEXP (addr, 0);
6072   const_int = XEXP (addr, 1);
6073   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6074          && GET_CODE (const_int) == CONST_INT))
6075     FAIL;
6076   emit_move_insn (operands[2], const_int);
6077   emit_move_insn (operands[0],
6078                   change_address (operands[1], VOIDmode,
6079                                   gen_rtx_PLUS (SImode, reg, operands[2])));
6080   DONE;
6083 (define_split
6084   [(set (match_operand:SI 1 "" "")
6085         (match_operand:SI 0 "register_operand" ""))
6086    (clobber (match_operand 2 "register_operand" ""))]
6087   "TARGET_SH1 && ! reload_in_progress && ! reload_completed
6088    && ALLOW_INDEXED_ADDRESS"
6089   [(use (reg:SI R0_REG))]
6090   "
6092   rtx addr, reg, const_int;
6094   if (GET_CODE (operands[1]) != MEM)
6095     FAIL;
6096   addr = XEXP (operands[1], 0);
6097   if (GET_CODE (addr) != PLUS)
6098     FAIL;
6099   reg = XEXP (addr, 0);
6100   const_int = XEXP (addr, 1);
6101   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
6102          && GET_CODE (const_int) == CONST_INT))
6103     FAIL;
6104   emit_move_insn (operands[2], const_int);
6105   emit_move_insn (change_address (operands[1], VOIDmode,
6106                                   gen_rtx_PLUS (SImode, reg, operands[2])),
6107                   operands[0]);
6108   DONE;
6111 (define_expand "movdf"
6112   [(set (match_operand:DF 0 "general_movdst_operand" "")
6113         (match_operand:DF 1 "general_movsrc_operand" ""))]
6114   ""
6115   "
6117   if (prepare_move_operands (operands, DFmode)) DONE;
6118   if (TARGET_SHMEDIA)
6119     {
6120       if (TARGET_SHMEDIA_FPU)
6121         emit_insn (gen_movdf_media (operands[0], operands[1]));
6122       else
6123         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
6124       DONE;
6125     }
6126   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
6127     {
6128       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
6129       DONE;
6130     }
6133 ;;This is incompatible with the way gcc uses subregs.
6134 ;;(define_insn "movv2sf_i"
6135 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
6136 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
6137 ;;  "TARGET_SHMEDIA_FPU
6138 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
6139 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
6140 ;;  "@
6141 ;;      #
6142 ;;      fld%M1.p        %m1, %0
6143 ;;      fst%M0.p        %m0, %1"
6144 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
6146 (define_insn_and_split "movv2sf_i"
6147   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
6148         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
6149   "TARGET_SHMEDIA_FPU"
6150   "#"
6151   "TARGET_SHMEDIA_FPU && reload_completed"
6152   [(set (match_dup 0) (match_dup 1))]
6153   "
6155   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
6156   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
6159 (define_expand "movv2sf"
6160   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
6161         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
6162   "TARGET_SHMEDIA_FPU"
6163   "
6165   if (prepare_move_operands (operands, V2SFmode))
6166     DONE;
6169 (define_expand "addv2sf3"
6170   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6171    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6172    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6173   "TARGET_SHMEDIA_FPU"
6174   "
6176   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
6177   DONE;
6180 (define_expand "subv2sf3"
6181   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6182    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6183    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6184   "TARGET_SHMEDIA_FPU"
6185   "
6187   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
6188   DONE;
6191 (define_expand "mulv2sf3"
6192   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6193    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6194    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6195   "TARGET_SHMEDIA_FPU"
6196   "
6198   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
6199   DONE;
6202 (define_expand "divv2sf3"
6203   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
6204    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
6205    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
6206   "TARGET_SHMEDIA_FPU"
6207   "
6209   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
6210   DONE;
6213 (define_insn_and_split "*movv4sf_i"
6214   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
6215         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
6216   "TARGET_SHMEDIA_FPU"
6217   "#"
6218   "&& reload_completed"
6219   [(const_int 0)]
6220   "
6222   int i;
6224   for (i = 0; i < 4/2; i++)
6225     {
6226       rtx x, y;
6228       if (GET_CODE (operands[0]) == MEM)
6229         x = gen_rtx_MEM (V2SFmode,
6230                          plus_constant (XEXP (operands[0], 0),
6231                                         i * GET_MODE_SIZE (V2SFmode)));
6232       else
6233         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
6235       if (GET_CODE (operands[1]) == MEM)
6236         y = gen_rtx_MEM (V2SFmode,
6237                          plus_constant (XEXP (operands[1], 0),
6238                                         i * GET_MODE_SIZE (V2SFmode)));
6239       else
6240         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
6242       emit_insn (gen_movv2sf_i (x, y));
6243     }
6245   DONE;
6247   [(set_attr "length" "8")])
6249 (define_expand "movv4sf"
6250   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
6251         (match_operand:V4SF 1 "general_operand" ""))]
6252   "TARGET_SHMEDIA_FPU"
6253   "
6255   if (prepare_move_operands (operands, V4SFmode))
6256     DONE;
6259 (define_insn_and_split "*movv16sf_i"
6260   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6261         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6262   "TARGET_SHMEDIA_FPU"
6263   "#"
6264   "&& reload_completed"
6265   [(const_int 0)]
6266   "
6268   int i;
6270   for (i = 0; i < 16/2; i++)
6271     {
6272       rtx x,y;
6274       if (GET_CODE (operands[0]) == MEM)
6275         x = gen_rtx_MEM (V2SFmode,
6276                          plus_constant (XEXP (operands[0], 0),
6277                                         i * GET_MODE_SIZE (V2SFmode)));
6278       else
6279         {
6280           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
6281           alter_subreg (&x);
6282         }
6284       if (GET_CODE (operands[1]) == MEM)
6285         y = gen_rtx_MEM (V2SFmode,
6286                          plus_constant (XEXP (operands[1], 0),
6287                                         i * GET_MODE_SIZE (V2SFmode)));
6288       else
6289         {
6290           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
6291           alter_subreg (&y);
6292         }
6294       emit_insn (gen_movv2sf_i (x, y));
6295     }
6297   DONE;
6299   [(set_attr "length" "32")])
6301 (define_expand "movv16sf"
6302   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
6303         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
6304   "TARGET_SHMEDIA_FPU"
6305   "
6307   if (prepare_move_operands (operands, V16SFmode))
6308     DONE;
6311 (define_insn "movsf_media"
6312   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
6313         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
6314   "TARGET_SHMEDIA_FPU
6315    && (register_operand (operands[0], SFmode)
6316        || sh_register_operand (operands[1], SFmode))"
6317   "@
6318         fmov.s  %1, %0
6319         fmov.ls %N1, %0
6320         fmov.sl %1, %0
6321         add.l   %1, r63, %0
6322         #
6323         fld%M1.s        %m1, %0
6324         fst%M0.s        %m0, %1
6325         ld%M1.l %m1, %0
6326         st%M0.l %m0, %N1"
6327   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")
6328    (set (attr "highpart")
6329         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6330                (const_string "user")]
6331               (const_string "ignore")))])
6333 (define_insn "movsf_media_nofpu"
6334   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
6335         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
6336   "TARGET_SHMEDIA
6337    && (register_operand (operands[0], SFmode)
6338        || sh_register_operand (operands[1], SFmode))"
6339   "@
6340         add.l   %1, r63, %0
6341         #
6342         ld%M1.l %m1, %0
6343         st%M0.l %m0, %N1"
6344   [(set_attr "type" "arith_media,*,load_media,store_media")
6345    (set (attr "highpart")
6346         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
6347                (const_string "user")]
6348               (const_string "ignore")))])
6350 (define_split
6351   [(set (match_operand:SF 0 "arith_reg_dest" "")
6352         (match_operand:SF 1 "immediate_operand" ""))]
6353   "TARGET_SHMEDIA && reload_completed
6354    && ! FP_REGISTER_P (true_regnum (operands[0]))"
6355   [(set (match_dup 3) (match_dup 2))]
6356   "
6358   long values;
6359   REAL_VALUE_TYPE value;
6361   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
6362   REAL_VALUE_TO_TARGET_SINGLE (value, values);
6363   operands[2] = GEN_INT (values);
6365   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
6368 (define_insn "movsf_i"
6369   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
6370         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
6371   "TARGET_SH1
6372    && (! TARGET_SH2E
6373        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
6374        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
6375        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
6376    && (arith_reg_operand (operands[0], SFmode)
6377        || arith_reg_operand (operands[1], SFmode))"
6378   "@
6379         mov     %1,%0
6380         mov     #0,%0
6381         mov.l   %1,%0
6382         mov.l   %1,%0
6383         mov.l   %1,%0
6384         lds     %1,%0
6385         sts     %1,%0"
6386   [(set_attr "type" "move,move,pcload,load,store,move,move")])
6388 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
6389 ;; update_flow_info would not know where to put REG_EQUAL notes
6390 ;; when the destination changes mode.
6391 (define_insn "movsf_ie"
6392   [(set (match_operand:SF 0 "general_movdst_operand"
6393          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
6394         (match_operand:SF 1 "general_movsrc_operand"
6395           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
6396    (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"))
6397    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
6399   "TARGET_SH2E
6400    && (arith_reg_operand (operands[0], SFmode)
6401        || arith_reg_operand (operands[1], SFmode)
6402        || arith_reg_operand (operands[3], SImode)
6403        || (fpul_operand (operands[0], SFmode)
6404            && memory_operand (operands[1], SFmode)
6405            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
6406        || (fpul_operand (operands[1], SFmode)
6407            && memory_operand (operands[0], SFmode)
6408            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
6409   "@
6410         fmov    %1,%0
6411         mov     %1,%0
6412         fldi0   %0
6413         fldi1   %0
6414         #
6415         fmov.s  %1,%0
6416         fmov.s  %1,%0
6417         mov.l   %1,%0
6418         mov.l   %1,%0
6419         mov.l   %1,%0
6420         fsts    fpul,%0
6421         flds    %1,fpul
6422         lds.l   %1,%0
6423         #
6424         sts     %1,%0
6425         lds     %1,%0
6426         sts.l   %1,%0
6427         lds.l   %1,%0
6428         ! move optimized away"
6429   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
6430    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
6431    (set_attr "length" "*,*,*,*,4,4,4,*,*,*,2,2,2,4,2,2,2,2,0")
6432    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
6433                                            (const_string "single")
6434                                            (const_string "none")))])
6436 (define_split
6437   [(set (match_operand:SF 0 "register_operand" "")
6438         (match_operand:SF 1 "register_operand" ""))
6439    (use (match_operand:PSI 2 "fpscr_operand" ""))
6440    (clobber (reg:SI FPUL_REG))]
6441   "TARGET_SH1"
6442   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
6443               (use (match_dup 2))
6444               (clobber (scratch:SI))])
6445    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
6446               (use (match_dup 2))
6447               (clobber (scratch:SI))])]
6448   "")
6450 (define_expand "movsf"
6451   [(set (match_operand:SF 0 "general_movdst_operand" "")
6452         (match_operand:SF 1 "general_movsrc_operand" ""))]
6453   ""
6454   "
6456   if (prepare_move_operands (operands, SFmode))
6457     DONE;
6458   if (TARGET_SHMEDIA)
6459     {
6460       if (TARGET_SHMEDIA_FPU)
6461         emit_insn (gen_movsf_media (operands[0], operands[1]));
6462       else
6463         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
6464       DONE;
6465     }
6466   if (TARGET_SH2E)
6467     {
6468       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
6469       DONE;
6470     }
6473 (define_insn "mov_nop"
6474   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
6475   "TARGET_SH2E"
6476   ""
6477   [(set_attr "length" "0")
6478    (set_attr "type" "nil")])
6480 (define_expand "reload_insf"
6481   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
6482                    (match_operand:SF 1 "immediate_operand" "FQ"))
6483               (use (reg:PSI FPSCR_REG))
6484               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6485   "TARGET_SH1"
6486   "")
6488 (define_expand "reload_insi"
6489   [(parallel [(set (match_operand:SI 0 "fpul_operand" "=y")
6490                    (match_operand:SI 1 "immediate_operand" "i"))
6491               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
6492   "TARGET_SH1"
6493   "")
6495 (define_expand "ptabs"
6496   [(set (match_operand 0 "" "=b") (match_operand 1 "" "r"))]
6497   "TARGET_SHMEDIA"
6498   "
6500   if (!TARGET_PT_FIXED)
6501     {
6502       rtx eq = operands[1];
6504       /* ??? For canonical RTL we really should remove any CONST from EQ
6505          before wrapping it in the AND, and finally wrap the EQ into a
6506          const if is constant.  However, for reload we must expose the
6507          input register or symbolic constant, and we can't have
6508          different insn structures outside of the operands for different
6509          alternatives of the same pattern.  */
6510       eq = gen_rtx_EQ (SImode, gen_rtx_AND (Pmode, eq, GEN_INT (3)),
6511                        GEN_INT (3));
6512       operands[1]
6513         = (gen_rtx_IF_THEN_ELSE
6514             (PDImode,
6515              eq,
6516              gen_rtx_MEM (PDImode, operands[1]),
6517              gen_rtx_fmt_e (TARGET_SHMEDIA32 ? SIGN_EXTEND : TRUNCATE,
6518                             PDImode, operands[1])));
6519     }
6522 ;; expanded by ptabs expander.
6523 (define_insn "*extendsipdi_media"
6524   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6525         (if_then_else:PDI (eq (and:SI (match_operand:SI 1 "target_operand"
6526                                                           "r,Csy")
6527                                       (const_int 3))
6528                               (const_int 3))
6529                           (mem:PDI (match_dup 1))
6530                           (sign_extend:PDI (match_dup 1))))]
6531   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6532   "@
6533         ptabs   %1, %0
6534         pt      %1, %0"
6535   [(set_attr "type"   "ptabs_media,pt_media")
6536    (set_attr "length" "4,*")])
6538 (define_insn "*truncdipdi_media"
6539   [(set (match_operand:PDI 0 "target_reg_operand" "=b,b");
6540         (if_then_else:PDI (eq (and:DI (match_operand:DI 1 "target_operand"
6541                                                           "r,Csy")
6542                                       (const_int 3))
6543                               (const_int 3))
6544                           (mem:PDI (match_dup 1))
6545                           (truncate:PDI (match_dup 1))))]
6546   "TARGET_SHMEDIA && !TARGET_PT_FIXED"
6547   "@
6548         ptabs   %1, %0
6549         pt      %1, %0"
6550   [(set_attr "type"   "ptabs_media,pt_media")
6551    (set_attr "length" "4,*")])
6553 (define_insn "*movsi_y"
6554   [(set (match_operand:SI 0 "register_operand" "=y,y")
6555         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
6556    (clobber (match_scratch:SI 2 "=&z,r"))]
6557   "TARGET_SH2E
6558    && (reload_in_progress || reload_completed)"
6559   "#"
6560   [(set_attr "length" "4")
6561    (set_attr "type" "pcload,move")])
6563 (define_split
6564   [(set (match_operand:SI 0 "register_operand" "")
6565         (match_operand:SI 1 "immediate_operand" ""))
6566    (clobber (match_operand:SI 2 "register_operand" ""))]
6567   "TARGET_SH1"
6568   [(set (match_dup 2) (match_dup 1))
6569    (set (match_dup 0) (match_dup 2))]
6570   "")
6572 (define_split
6573   [(set (match_operand:SI 0 "register_operand" "")
6574         (match_operand:SI 1 "memory_operand" ""))
6575    (clobber (reg:SI R0_REG))]
6576   "TARGET_SH1"
6577   [(set (match_dup 0) (match_dup 1))]
6578   "")
6580 ;; ------------------------------------------------------------------------
6581 ;; Define the real conditional branch instructions.
6582 ;; ------------------------------------------------------------------------
6584 (define_insn "branch_true"
6585   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
6586                            (label_ref (match_operand 0 "" ""))
6587                            (pc)))]
6588   "TARGET_SH1"
6589   "* return output_branch (1, insn, operands);"
6590   [(set_attr "type" "cbranch")])
6592 (define_insn "branch_false"
6593   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
6594                            (label_ref (match_operand 0 "" ""))
6595                            (pc)))]
6596   "TARGET_SH1"
6597   "* return output_branch (0, insn, operands);"
6598   [(set_attr "type" "cbranch")])
6600 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
6601 ;; which destination is too far away.
6602 ;; The const_int_operand is distinct for each branch target; it avoids
6603 ;; unwanted matches with redundant_insn.
6604 (define_insn "block_branch_redirect"
6605   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
6606   "TARGET_SH1"
6607   ""
6608   [(set_attr "length" "0")])
6610 ;; This one has the additional purpose to record a possible scratch register
6611 ;; for the following branch.
6612 ;; ??? Unfortunately, just setting the scratch register is not good enough,
6613 ;; because the insn then might be deemed dead and deleted.  And we can't
6614 ;; make the use in the jump insn explicit because that would disable
6615 ;; delay slot scheduling from the target.
6616 (define_insn "indirect_jump_scratch"
6617   [(set (match_operand:SI 0 "register_operand" "=r")
6618         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
6619    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
6620   "TARGET_SH1"
6621   ""
6622   [(set_attr "length" "0")])
6624 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
6625 ;; being pulled into the delay slot of a condbranch that has been made to
6626 ;; jump around the unconditional jump because it was out of range.
6627 (define_insn "stuff_delay_slot"
6628   [(set (pc)
6629         (unspec [(match_operand:SI 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
6630    (set (reg:SI T_REG) (match_operand:SI 1 "const_int_operand" ""))]
6631   "TARGET_SH1"
6632   ""
6633   [(set_attr "length" "0")
6634    (set_attr "cond_delay_slot" "yes")])
6636 ;; Conditional branch insns
6638 (define_expand "beq_media"
6639   [(set (pc)
6640         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
6641                           (match_operand:DI 2 "arith_operand" "r,I06"))
6642                       (match_operand 0 "" "")
6643                       (pc)))]
6644   "TARGET_SHMEDIA"
6645   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6647 (define_insn "*beq_media_i"
6648   [(set (pc)
6649         (if_then_else (match_operator 3 "equality_comparison_operator"
6650                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
6651                          (match_operand:DI 2 "arith_operand" "r,I06")])
6652                       (match_operand 0 "target_operand" "b,b")
6653                       (pc)))]
6654   "TARGET_SHMEDIA"
6655   "@
6656         b%o3%'  %1, %2, %0%>
6657         b%o3i%' %1, %2, %0%>"
6658   [(set_attr "type" "cbranch_media")])
6660 (define_insn "*beq_media_i32"
6661   [(set (pc)
6662         (if_then_else (match_operator 3 "equality_comparison_operator"
6663                         [(match_operand:SI 1 "arith_reg_operand" "r,r")
6664                          (match_operand:SI 2 "arith_operand" "r,I06")])
6665                       (match_operand 0 "target_operand" "b,b")
6666                       (pc)))]
6667   "TARGET_SHMEDIA"
6668   "@
6669         b%o3%'  %1, %2, %0%>
6670         b%o3i%' %1, %2, %0%>"
6671   [(set_attr "type" "cbranch_media")])
6673 (define_expand "bne_media"
6674   [(set (pc)
6675         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
6676                           (match_operand:DI 2 "arith_operand" "r,I06"))
6677                       (match_operand 0 "" "")
6678                       (pc)))]
6679   "TARGET_SHMEDIA"
6680   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6682 (define_expand "bgt_media"
6683   [(set (pc)
6684         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "")
6685                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6686                       (match_operand 0 "" "")
6687                       (pc)))]
6688   "TARGET_SHMEDIA"
6689   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6691 (define_expand "bge_media"
6692   [(set (pc)
6693         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "")
6694                           (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6695                       (match_operand 0 "" "")
6696                       (pc)))]
6697   "TARGET_SHMEDIA"
6698   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6700 (define_expand "bgtu_media"
6701   [(set (pc)
6702         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6703                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6704                       (match_operand 0 "" "")
6705                       (pc)))]
6706   "TARGET_SHMEDIA"
6707   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6709 (define_expand "bgeu_media"
6710   [(set (pc)
6711         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "")
6712                            (match_operand:DI 2 "arith_reg_or_0_operand" ""))
6713                       (match_operand 0 "" "")
6714                       (pc)))]
6715   "TARGET_SHMEDIA"
6716   "operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);")
6718 (define_insn "*bgt_media_i"
6719   [(set (pc)
6720         (if_then_else (match_operator 3 "greater_comparison_operator"
6721                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6722                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6723                       (match_operand 0 "target_operand" "b")
6724                       (pc)))]
6725   "TARGET_SHMEDIA"
6726   "b%o3%'       %N1, %N2, %0%>"
6727   [(set_attr "type" "cbranch_media")])
6729 (define_insn "*bgt_media_i32"
6730   [(set (pc)
6731         (if_then_else (match_operator 3 "greater_comparison_operator"
6732                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6733                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6734                       (match_operand 0 "target_operand" "b")
6735                       (pc)))]
6736   "TARGET_SHMEDIA"
6737   "b%o3%'       %N1, %N2, %0%>"
6738   [(set_attr "type" "cbranch_media")])
6740 ;; These are only needed to make invert_jump() happy - otherwise, jump
6741 ;; optimization will be silently disabled.
6742 (define_insn "*blt_media_i"
6743   [(set (pc)
6744         (if_then_else (match_operator 3 "less_comparison_operator"
6745                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
6746                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
6747                       (match_operand 0 "target_operand" "b")
6748                       (pc)))]
6749   "TARGET_SHMEDIA"
6750   "b%o3%'       %N2, %N1, %0%>"
6751   [(set_attr "type" "cbranch_media")])
6753 (define_insn "*blt_media_i32"
6754   [(set (pc)
6755         (if_then_else (match_operator 3 "less_comparison_operator"
6756                         [(match_operand:SI 1 "arith_reg_or_0_operand" "rN")
6757                          (match_operand:SI 2 "arith_reg_or_0_operand" "rN")])
6758                       (match_operand 0 "target_operand" "b")
6759                       (pc)))]
6760   "TARGET_SHMEDIA"
6761   "b%o3%'       %N2, %N1, %0%>"
6762   [(set_attr "type" "cbranch_media")])
6764 (define_expand "beq"
6765   [(set (pc)
6766         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6767                       (label_ref (match_operand 0 "" ""))
6768                       (pc)))]
6769   ""
6770   "
6772   if (TARGET_SHMEDIA)
6773     {
6774       enum machine_mode mode = GET_MODE (sh_compare_op0);
6776       if (mode != DImode && mode != SImode)
6777         {
6778           rtx tmp = gen_reg_rtx (DImode);
6780           emit_insn (gen_seq (tmp));
6781           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6782           DONE;
6783         }
6785       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6786       if (CONSTANT_P (sh_compare_op1)
6787           && (GET_CODE (sh_compare_op1) != CONST_INT
6788               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6789         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6790       emit_jump_insn (gen_beq_media (operands[0],
6791                                      sh_compare_op0, sh_compare_op1));
6792       DONE;
6793     }
6795   from_compare (operands, EQ);
6798 (define_expand "bne"
6799   [(set (pc)
6800         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6801                       (label_ref (match_operand 0 "" ""))
6802                       (pc)))]
6803   ""
6804   "
6806   if (TARGET_SHMEDIA)
6807     {
6808       enum machine_mode mode = GET_MODE (sh_compare_op0);
6810       if (mode != DImode && mode != SImode)
6811         {
6812           rtx tmp = gen_reg_rtx (DImode);
6814           emit_insn (gen_seq (tmp));
6815           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
6816           DONE;
6817         }
6819       sh_compare_op0 = force_reg (mode, sh_compare_op0);
6820       if (CONSTANT_P (sh_compare_op1)
6821           && (GET_CODE (sh_compare_op1) != CONST_INT
6822               || ! CONST_OK_FOR_I06 (INTVAL (sh_compare_op1))))
6823         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6824       emit_jump_insn (gen_bne_media (operands[0],
6825                                      sh_compare_op0, sh_compare_op1));
6826       DONE;
6827     }
6829   from_compare (operands, EQ);
6832 (define_expand "bgt"
6833   [(set (pc)
6834         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6835                       (label_ref (match_operand 0 "" ""))
6836                       (pc)))]
6837   ""
6838   "
6840   if (TARGET_SHMEDIA)
6841     {
6842       enum machine_mode mode = GET_MODE (sh_compare_op0);
6844       if (mode != DImode && mode != SImode)
6845         {
6846           rtx tmp = gen_reg_rtx (DImode);
6848           emit_insn (gen_sgt (tmp));
6849           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6850           DONE;
6851         }
6853       if (sh_compare_op0 != const0_rtx)
6854         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6855       if (sh_compare_op1 != const0_rtx)
6856         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6857       emit_jump_insn (gen_bgt_media (operands[0],
6858                                      sh_compare_op0, sh_compare_op1));
6859       DONE;
6860     }
6862   from_compare (operands, GT);
6865 (define_expand "blt"
6866   [(set (pc)
6867         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6868                       (label_ref (match_operand 0 "" ""))
6869                       (pc)))]
6870   ""
6871   "
6873   if (TARGET_SHMEDIA)
6874     {
6875       enum machine_mode mode = GET_MODE (sh_compare_op0);
6877       if (mode != DImode && mode != SImode)
6878         {
6879           rtx tmp = gen_reg_rtx (DImode);
6881           emit_insn (gen_slt (tmp));
6882           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6883           DONE;
6884         }
6886       if (sh_compare_op0 != const0_rtx)
6887         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6888       if (sh_compare_op1 != const0_rtx)
6889         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6890       emit_jump_insn (gen_bgt_media (operands[0],
6891                                      sh_compare_op1, sh_compare_op0));
6892       DONE;
6893     }
6895   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6896     {
6897       rtx tmp = sh_compare_op0;
6898       sh_compare_op0 = sh_compare_op1;
6899       sh_compare_op1 = tmp;
6900       emit_insn (gen_bgt (operands[0]));
6901       DONE;
6902     }
6903   from_compare (operands, GE);
6906 (define_expand "ble"
6907   [(set (pc)
6908         (if_then_else (eq (reg:SI T_REG) (const_int 0))
6909                       (label_ref (match_operand 0 "" ""))
6910                       (pc)))]
6911   ""
6912   "
6914   if (TARGET_SHMEDIA)
6915     {
6916       enum machine_mode mode = GET_MODE (sh_compare_op0);
6918       if (mode != DImode && mode != SImode)
6919         {
6920           rtx tmp = gen_reg_rtx (DImode);
6922           emit_insn (gen_sle (tmp));
6923           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6924           DONE;
6925         }
6927       if (sh_compare_op0 != const0_rtx)
6928         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6929       if (sh_compare_op1 != const0_rtx)
6930         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6931       emit_jump_insn (gen_bge_media (operands[0],
6932                                      sh_compare_op1, sh_compare_op0));
6933       DONE;
6934     }
6936   if (TARGET_SH2E
6937       && TARGET_IEEE
6938       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6939     {
6940       rtx tmp = sh_compare_op0;
6941       sh_compare_op0 = sh_compare_op1;
6942       sh_compare_op1 = tmp;
6943       emit_insn (gen_bge (operands[0]));
6944       DONE;
6945     }
6946   from_compare (operands, GT);
6949 (define_expand "bge"
6950   [(set (pc)
6951         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6952                       (label_ref (match_operand 0 "" ""))
6953                       (pc)))]
6954   ""
6955   "
6957   if (TARGET_SHMEDIA)
6958     {
6959       enum machine_mode mode = GET_MODE (sh_compare_op0);
6961       if (mode != DImode && mode != SImode)
6962         {
6963           rtx tmp = gen_reg_rtx (DImode);
6965           emit_insn (gen_sge (tmp));
6966           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
6967           DONE;
6968         }
6970       if (sh_compare_op0 != const0_rtx)
6971         sh_compare_op0 = force_reg (mode, sh_compare_op0);
6972       if (sh_compare_op1 != const0_rtx)
6973         sh_compare_op1 = force_reg (mode, sh_compare_op1);
6974       emit_jump_insn (gen_bge_media (operands[0],
6975                                      sh_compare_op0, sh_compare_op1));
6976       DONE;
6977     }
6979   if (TARGET_SH2E
6980       && ! TARGET_IEEE
6981       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
6982     {
6983       rtx tmp = sh_compare_op0;
6984       sh_compare_op0 = sh_compare_op1;
6985       sh_compare_op1 = tmp;
6986       emit_insn (gen_ble (operands[0]));
6987       DONE;
6988     }
6989   from_compare (operands, GE);
6992 (define_expand "bgtu"
6993   [(set (pc)
6994         (if_then_else (ne (reg:SI T_REG) (const_int 0))
6995                       (label_ref (match_operand 0 "" ""))
6996                       (pc)))]
6997   ""
6998   "
7000   if (TARGET_SHMEDIA)
7001     {
7002       enum machine_mode mode = GET_MODE (sh_compare_op0);
7004       if (sh_compare_op0 != const0_rtx)
7005         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7006       if (sh_compare_op1 != const0_rtx)
7007         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7008       emit_jump_insn (gen_bgtu_media (operands[0],
7009                                       sh_compare_op0, sh_compare_op1));
7010       DONE;
7011     }
7013   from_compare (operands, GTU);
7016 (define_expand "bltu"
7017   [(set (pc)
7018         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7019                       (label_ref (match_operand 0 "" ""))
7020                       (pc)))]
7021   ""
7022   "
7024   if (TARGET_SHMEDIA)
7025     {
7026       enum machine_mode mode = GET_MODE (sh_compare_op0);
7028       if (sh_compare_op0 != const0_rtx)
7029         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7030       if (sh_compare_op1 != const0_rtx)
7031         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7032       emit_jump_insn (gen_bgtu_media (operands[0],
7033                                       sh_compare_op1, sh_compare_op0));
7034       DONE;
7035     }
7037   from_compare (operands, GEU);
7040 (define_expand "bgeu"
7041   [(set (pc)
7042         (if_then_else (ne (reg:SI T_REG) (const_int 0))
7043                       (label_ref (match_operand 0 "" ""))
7044                       (pc)))]
7045   ""
7046   "
7048   if (TARGET_SHMEDIA)
7049     {
7050       enum machine_mode mode = GET_MODE (sh_compare_op0);
7052       if (sh_compare_op0 != const0_rtx)
7053         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7054       if (sh_compare_op1 != const0_rtx)
7055         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7056       emit_jump_insn (gen_bgeu_media (operands[0],
7057                                       sh_compare_op0, sh_compare_op1));
7058       DONE;
7059     }
7061   from_compare (operands, GEU);
7064 (define_expand "bleu"
7065   [(set (pc)
7066         (if_then_else (eq (reg:SI T_REG) (const_int 0))
7067                       (label_ref (match_operand 0 "" ""))
7068                       (pc)))]
7069   ""
7070   "
7072   if (TARGET_SHMEDIA)
7073     {
7074       enum machine_mode mode = GET_MODE (sh_compare_op0);
7076       if (sh_compare_op0 != const0_rtx)
7077         sh_compare_op0 = force_reg (mode, sh_compare_op0);
7078       if (sh_compare_op1 != const0_rtx)
7079         sh_compare_op1 = force_reg (mode, sh_compare_op1);
7080       emit_jump_insn (gen_bgeu_media (operands[0],
7081                                       sh_compare_op1, sh_compare_op0));
7082       DONE;
7083     }
7085   from_compare (operands, GTU);
7088 (define_expand "bunordered"
7089   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
7090    (set (pc)
7091         (if_then_else (ne (match_dup 1) (const_int 0))
7092                       (match_operand 0 "" "")
7093                       (pc)))]
7094   "TARGET_SHMEDIA"
7095   "
7097   operands[0] = gen_rtx_LABEL_REF (Pmode, operands[0]);
7098   operands[1] = gen_reg_rtx (DImode);
7099   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7100   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7103 ;; combiner splitter for test-and-branch on single bit in register.  This
7104 ;; is endian dependent because the non-paradoxical subreg looks different
7105 ;; on big endian.
7106 (define_split
7107   [(set (pc)
7108         (if_then_else
7109           (match_operator 3 "equality_comparison_operator"
7110             [(subreg:SI (zero_extract:DI (subreg:DI (match_operand:SI 1
7111                                                       "extend_reg_operand" "")
7112                                                     0)
7113                                          (const_int 1)
7114                                          (match_operand 2
7115                                           "const_int_operand" "")) 0)
7116              (const_int 0)])
7117           (match_operand 0 "target_operand" "")
7118           (pc)))
7119    (clobber (match_operand:SI 4 "arith_reg_dest" ""))]
7120   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
7121   [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 5)))
7122    (set (pc) (if_then_else (match_dup 6) (match_dup 0) (pc)))]
7124   "
7126   operands[5] = GEN_INT (31 - INTVAL (operands[2]));
7127   operands[6] = (GET_CODE (operands[3]) == EQ
7128                  ? gen_rtx_GE (VOIDmode, operands[4], const0_rtx)
7129                  : gen_rtx_GT (VOIDmode, const0_rtx, operands[4]));
7132 ;; ------------------------------------------------------------------------
7133 ;; Jump and linkage insns
7134 ;; ------------------------------------------------------------------------
7136 (define_insn "jump_compact"
7137   [(set (pc)
7138         (label_ref (match_operand 0 "" "")))]
7139   "TARGET_SH1"
7140   "*
7142   /* The length is 16 if the delay slot is unfilled.  */
7143   if (get_attr_length(insn) > 4)
7144     return output_far_jump(insn, operands[0]);
7145   else
7146     return   \"bra      %l0%#\";
7148   [(set_attr "type" "jump")
7149    (set_attr "needs_delay_slot" "yes")])
7151 ;; ??? It would be much saner to explicitly use the scratch register
7152 ;; in the jump insn, and have indirect_jump_scratch only set it,
7153 ;; but fill_simple_delay_slots would refuse to do delay slot filling
7154 ;; from the target then, as it uses simplejump_p.
7155 ;;(define_insn "jump_compact_far"
7156 ;;  [(set (pc)
7157 ;;      (label_ref (match_operand 0 "" "")))
7158 ;;   (use (match_operand 1 "register_operand" "r")]
7159 ;;  "TARGET_SH1"
7160 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
7161 ;;  [(set_attr "type" "jump")
7162 ;;   (set_attr "needs_delay_slot" "yes")])
7164 (define_insn "jump_media"
7165   [(set (pc)
7166         (match_operand 0 "target_operand" "b"))]
7167   "TARGET_SHMEDIA"
7168   "blink        %0, r63%>"
7169   [(set_attr "type" "jump_media")])
7171 (define_expand "jump"
7172   [(set (pc)
7173         (label_ref (match_operand 0 "" "")))]
7174   ""
7175   "
7177   if (TARGET_SH1)
7178     emit_jump_insn (gen_jump_compact (operands[0]));
7179   else if (TARGET_SHMEDIA)
7180     {
7181       if (reload_in_progress || reload_completed)
7182         FAIL;
7183       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (Pmode,
7184                                                          operands[0])));
7185     }
7186   DONE;
7189 (define_insn "force_mode_for_call"
7190   [(use (reg:PSI FPSCR_REG))]
7191   "TARGET_SHCOMPACT"
7192   ""
7193   [(set_attr "length" "0")
7194    (set (attr "fp_mode")
7195         (if_then_else (eq_attr "fpu_single" "yes")
7196                       (const_string "single") (const_string "double")))])
7198 (define_insn "calli"
7199   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7200          (match_operand 1 "" ""))
7201    (use (reg:PSI FPSCR_REG))
7202    (clobber (reg:SI PR_REG))]
7203   "TARGET_SH1"
7204   "jsr  @%0%#"
7205   [(set_attr "type" "call")
7206    (set (attr "fp_mode")
7207         (if_then_else (eq_attr "fpu_single" "yes")
7208                       (const_string "single") (const_string "double")))
7209    (set_attr "needs_delay_slot" "yes")
7210    (set_attr "fp_set" "unknown")])
7212 ;; This is a pc-rel call, using bsrf, for use with PIC.
7214 (define_insn "calli_pcrel"
7215   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7216          (match_operand 1 "" ""))
7217    (use (reg:PSI FPSCR_REG))
7218    (use (reg:SI PIC_REG))
7219    (use (match_operand 2 "" ""))
7220    (clobber (reg:SI PR_REG))]
7221   "TARGET_SH2"
7222   "bsrf %0\\n%O2:%#"
7223   [(set_attr "type" "call")
7224    (set (attr "fp_mode")
7225         (if_then_else (eq_attr "fpu_single" "yes")
7226                       (const_string "single") (const_string "double")))
7227    (set_attr "needs_delay_slot" "yes")
7228    (set_attr "fp_set" "unknown")])
7230 (define_insn_and_split "call_pcrel"
7231   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7232          (match_operand 1 "" ""))
7233    (use (reg:PSI FPSCR_REG))
7234    (use (reg:SI PIC_REG))
7235    (clobber (reg:SI PR_REG))
7236    (clobber (match_scratch:SI 2 "=r"))]
7237   "TARGET_SH2"
7238   "#"
7239   "reload_completed"
7240   [(const_int 0)]
7241   "
7243   rtx lab = PATTERN (gen_call_site ());
7245   if (SYMBOL_REF_LOCAL_P (operands[0]))
7246     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7247   else
7248     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
7249   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
7250   DONE;
7252   [(set_attr "type" "call")
7253    (set (attr "fp_mode")
7254         (if_then_else (eq_attr "fpu_single" "yes")
7255                       (const_string "single") (const_string "double")))
7256    (set_attr "needs_delay_slot" "yes")
7257    (set_attr "fp_set" "unknown")])
7259 (define_insn "call_compact"
7260   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7261          (match_operand 1 "" ""))
7262    (match_operand 2 "immediate_operand" "n")
7263    (use (reg:SI R0_REG))
7264    (use (reg:SI R1_REG))
7265    (use (reg:PSI FPSCR_REG))
7266    (clobber (reg:SI PR_REG))]
7267   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7268   "jsr  @%0%#"
7269   [(set_attr "type" "call")
7270    (set (attr "fp_mode")
7271         (if_then_else (eq_attr "fpu_single" "yes")
7272                       (const_string "single") (const_string "double")))
7273    (set_attr "needs_delay_slot" "yes")])
7275 (define_insn "call_compact_rettramp"
7276   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7277          (match_operand 1 "" ""))
7278    (match_operand 2 "immediate_operand" "n")
7279    (use (reg:SI R0_REG))
7280    (use (reg:SI R1_REG))
7281    (use (reg:PSI FPSCR_REG))
7282    (clobber (reg:SI R10_REG))
7283    (clobber (reg:SI PR_REG))]
7284   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7285   "jsr  @%0%#"
7286   [(set_attr "type" "call")
7287    (set (attr "fp_mode")
7288         (if_then_else (eq_attr "fpu_single" "yes")
7289                       (const_string "single") (const_string "double")))
7290    (set_attr "needs_delay_slot" "yes")])
7292 (define_insn "call_media"
7293   [(call (mem:DI (match_operand 0 "target_reg_operand" "b"))
7294          (match_operand 1 "" ""))
7295    (clobber (reg:DI PR_MEDIA_REG))]
7296   "TARGET_SHMEDIA"
7297   "blink        %0, r18"
7298   [(set_attr "type" "jump_media")])
7300 (define_insn "call_valuei"
7301   [(set (match_operand 0 "" "=rf")
7302         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7303               (match_operand 2 "" "")))
7304    (use (reg:PSI FPSCR_REG))
7305    (clobber (reg:SI PR_REG))]
7306   "TARGET_SH1"
7307   "jsr  @%1%#"
7308   [(set_attr "type" "call")
7309    (set (attr "fp_mode")
7310         (if_then_else (eq_attr "fpu_single" "yes")
7311                       (const_string "single") (const_string "double")))
7312    (set_attr "needs_delay_slot" "yes")
7313    (set_attr "fp_set" "unknown")])
7315 (define_insn "call_valuei_pcrel"
7316   [(set (match_operand 0 "" "=rf")
7317         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7318               (match_operand 2 "" "")))
7319    (use (reg:PSI FPSCR_REG))
7320    (use (reg:SI PIC_REG))
7321    (use (match_operand 3 "" ""))
7322    (clobber (reg:SI PR_REG))]
7323   "TARGET_SH2"
7324   "bsrf %1\\n%O3:%#"
7325   [(set_attr "type" "call")
7326    (set (attr "fp_mode")
7327         (if_then_else (eq_attr "fpu_single" "yes")
7328                       (const_string "single") (const_string "double")))
7329    (set_attr "needs_delay_slot" "yes")
7330    (set_attr "fp_set" "unknown")])
7332 (define_insn_and_split "call_value_pcrel"
7333   [(set (match_operand 0 "" "=rf")
7334         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
7335               (match_operand 2 "" "")))
7336    (use (reg:PSI FPSCR_REG))
7337    (use (reg:SI PIC_REG))
7338    (clobber (reg:SI PR_REG))
7339    (clobber (match_scratch:SI 3 "=r"))]
7340   "TARGET_SH2"
7341   "#"
7342   "reload_completed"
7343   [(const_int 0)]
7344   "
7346   rtx lab = PATTERN (gen_call_site ());
7348   if (SYMBOL_REF_LOCAL_P (operands[1]))
7349     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
7350   else
7351     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
7352   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
7353                                          operands[2], lab));
7354   DONE;
7356   [(set_attr "type" "call")
7357    (set (attr "fp_mode")
7358         (if_then_else (eq_attr "fpu_single" "yes")
7359                       (const_string "single") (const_string "double")))
7360    (set_attr "needs_delay_slot" "yes")
7361    (set_attr "fp_set" "unknown")])
7363 (define_insn "call_value_compact"
7364   [(set (match_operand 0 "" "=rf")
7365         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7366               (match_operand 2 "" "")))
7367    (match_operand 3 "immediate_operand" "n")
7368    (use (reg:SI R0_REG))
7369    (use (reg:SI R1_REG))
7370    (use (reg:PSI FPSCR_REG))
7371    (clobber (reg:SI PR_REG))]
7372   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7373   "jsr  @%1%#"
7374   [(set_attr "type" "call")
7375    (set (attr "fp_mode")
7376         (if_then_else (eq_attr "fpu_single" "yes")
7377                       (const_string "single") (const_string "double")))
7378    (set_attr "needs_delay_slot" "yes")])
7380 (define_insn "call_value_compact_rettramp"
7381   [(set (match_operand 0 "" "=rf")
7382         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7383               (match_operand 2 "" "")))
7384    (match_operand 3 "immediate_operand" "n")
7385    (use (reg:SI R0_REG))
7386    (use (reg:SI R1_REG))
7387    (use (reg:PSI FPSCR_REG))
7388    (clobber (reg:SI R10_REG))
7389    (clobber (reg:SI PR_REG))]
7390   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7391   "jsr  @%1%#"
7392   [(set_attr "type" "call")
7393    (set (attr "fp_mode")
7394         (if_then_else (eq_attr "fpu_single" "yes")
7395                       (const_string "single") (const_string "double")))
7396    (set_attr "needs_delay_slot" "yes")])
7398 (define_insn "call_value_media"
7399   [(set (match_operand 0 "" "=rf")
7400         (call (mem:DI (match_operand 1 "target_reg_operand" "b"))
7401               (match_operand 2 "" "")))
7402    (clobber (reg:DI PR_MEDIA_REG))]
7403   "TARGET_SHMEDIA"
7404   "blink        %1, r18"
7405   [(set_attr "type" "jump_media")])
7407 (define_expand "call"
7408   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7409                             (match_operand 1 "" ""))
7410               (match_operand 2 "" "")
7411               (use (reg:PSI FPSCR_REG))
7412               (clobber (reg:SI PR_REG))])]
7413   ""
7414   "
7416   if (TARGET_SHMEDIA)
7417     {
7418       operands[0] = shmedia_prepare_call_address (operands[0], 0);
7419       emit_call_insn (gen_call_media (operands[0], operands[1]));
7420       DONE;
7421     }
7422   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
7423     {
7424       rtx cookie_rtx = operands[2];
7425       long cookie = INTVAL (cookie_rtx);
7426       rtx func = XEXP (operands[0], 0);
7427       rtx r0, r1;
7429       if (flag_pic)
7430         {
7431           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7432             {
7433               rtx reg = gen_reg_rtx (Pmode);
7435               emit_insn (gen_symGOTPLT2reg (reg, func));
7436               func = reg;
7437             }
7438           else
7439             func = legitimize_pic_address (func, Pmode, 0);
7440         }
7442       r0 = gen_rtx_REG (SImode, R0_REG);
7443       r1 = gen_rtx_REG (SImode, R1_REG);
7445       /* Since such a call function may use all call-clobbered
7446          registers, we force a mode switch earlier, so that we don't
7447          run out of registers when adjusting fpscr for the call.  */
7448       emit_insn (gen_force_mode_for_call ());
7450       operands[0]
7451         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7452                            SFUNC_GOT);
7453       operands[0] = force_reg (SImode, operands[0]);
7455       emit_move_insn (r0, func);
7456       emit_move_insn (r1, cookie_rtx);
7458       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7459         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
7460                                                    operands[2]));
7461       else
7462         emit_call_insn (gen_call_compact (operands[0], operands[1],
7463                                           operands[2]));
7465       DONE;
7466     }
7467   else if (TARGET_SHCOMPACT && flag_pic
7468            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7469            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7470     {
7471       rtx reg = gen_reg_rtx (Pmode);
7473       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
7474       XEXP (operands[0], 0) = reg;
7475     }
7476   if (flag_pic && TARGET_SH2
7477       && GET_CODE (operands[0]) == MEM
7478       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
7479     {
7480       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
7481       DONE;
7482     }
7483   else
7484   {
7485     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7486     operands[1] = operands[2];
7487   }
7489   emit_call_insn (gen_calli (operands[0], operands[1]));
7490   DONE;
7493 (define_insn "call_pop_compact"
7494   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7495          (match_operand 1 "" ""))
7496    (match_operand 2 "immediate_operand" "n")
7497    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7498                                  (match_operand 3 "immediate_operand" "n")))
7499    (use (reg:SI R0_REG))
7500    (use (reg:SI R1_REG))
7501    (use (reg:PSI FPSCR_REG))
7502    (clobber (reg:SI PR_REG))]
7503   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7504   "jsr  @%0%#"
7505   [(set_attr "type" "call")
7506    (set (attr "fp_mode")
7507         (if_then_else (eq_attr "fpu_single" "yes")
7508                       (const_string "single") (const_string "double")))
7509    (set_attr "needs_delay_slot" "yes")])
7511 (define_insn "call_pop_compact_rettramp"
7512   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
7513          (match_operand 1 "" ""))
7514    (match_operand 2 "immediate_operand" "n")
7515    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7516                                  (match_operand 3 "immediate_operand" "n")))
7517    (use (reg:SI R0_REG))
7518    (use (reg:SI R1_REG))
7519    (use (reg:PSI FPSCR_REG))
7520    (clobber (reg:SI R10_REG))
7521    (clobber (reg:SI PR_REG))]
7522   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
7523   "jsr  @%0%#"
7524   [(set_attr "type" "call")
7525    (set (attr "fp_mode")
7526         (if_then_else (eq_attr "fpu_single" "yes")
7527                       (const_string "single") (const_string "double")))
7528    (set_attr "needs_delay_slot" "yes")])
7530 (define_expand "call_pop"
7531   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7532                     (match_operand 1 "" ""))
7533              (match_operand 2 "" "")
7534              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7535                                            (match_operand 3 "" "")))])]
7536   "TARGET_SHCOMPACT"
7537   "
7539   rtx cookie_rtx;
7540   long cookie;
7541   rtx func;
7542   rtx r0, r1;
7544   gcc_assert (operands[2] && INTVAL (operands[2]));
7545   cookie_rtx = operands[2];
7546   cookie = INTVAL (cookie_rtx);
7547   func = XEXP (operands[0], 0);
7549   if (flag_pic)
7550     {
7551       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7552         {
7553           rtx reg = gen_reg_rtx (Pmode);
7554           emit_insn (gen_symGOTPLT2reg (reg, func));
7555           func = reg;
7556         }
7557       else
7558         func = legitimize_pic_address (func, Pmode, 0);
7559     }
7561   r0 = gen_rtx_REG (SImode, R0_REG);
7562   r1 = gen_rtx_REG (SImode, R1_REG);
7564   /* Since such a call function may use all call-clobbered
7565      registers, we force a mode switch earlier, so that we don't
7566      run out of registers when adjusting fpscr for the call.  */
7567   emit_insn (gen_force_mode_for_call ());
7569   operands[0] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7570                                  SFUNC_GOT);
7571   operands[0] = force_reg (SImode, operands[0]);
7573   emit_move_insn (r0, func);
7574   emit_move_insn (r1, cookie_rtx);
7576   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7577     emit_call_insn (gen_call_pop_compact_rettramp
7578                      (operands[0], operands[1], operands[2], operands[3]));
7579   else
7580     emit_call_insn (gen_call_pop_compact
7581                      (operands[0], operands[1], operands[2], operands[3]));
7583   DONE;
7586 (define_expand "call_value"
7587   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7588                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7589                                  (match_operand 2 "" "")))
7590               (match_operand 3 "" "")
7591               (use (reg:PSI FPSCR_REG))
7592               (clobber (reg:SI PR_REG))])]
7593   ""
7594   "
7596   if (TARGET_SHMEDIA)
7597     {
7598       operands[1] = shmedia_prepare_call_address (operands[1], 0);
7599       emit_call_insn (gen_call_value_media (operands[0], operands[1],
7600                                             operands[2]));
7601       DONE;
7602     }
7603   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
7604     {
7605       rtx cookie_rtx = operands[3];
7606       long cookie = INTVAL (cookie_rtx);
7607       rtx func = XEXP (operands[1], 0);
7608       rtx r0, r1;
7610       if (flag_pic)
7611         {
7612           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7613             {
7614               rtx reg = gen_reg_rtx (Pmode);
7616               emit_insn (gen_symGOTPLT2reg (reg, func));
7617               func = reg;
7618             }
7619           else
7620             func = legitimize_pic_address (func, Pmode, 0);
7621         }
7623       r0 = gen_rtx_REG (SImode, R0_REG);
7624       r1 = gen_rtx_REG (SImode, R1_REG);
7626       /* Since such a call function may use all call-clobbered
7627          registers, we force a mode switch earlier, so that we don't
7628          run out of registers when adjusting fpscr for the call.  */
7629       emit_insn (gen_force_mode_for_call ());
7631       operands[1]
7632         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7633                            SFUNC_GOT);
7634       operands[1] = force_reg (SImode, operands[1]);
7636       emit_move_insn (r0, func);
7637       emit_move_insn (r1, cookie_rtx);
7639       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7640         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
7641                                                          operands[1],
7642                                                          operands[2],
7643                                                          operands[3]));
7644       else
7645         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
7646                                                 operands[2], operands[3]));
7648       DONE;
7649     }
7650   else if (TARGET_SHCOMPACT && flag_pic
7651            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
7652            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
7653     {
7654       rtx reg = gen_reg_rtx (Pmode);
7656       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
7657       XEXP (operands[1], 0) = reg;
7658     }
7659   if (flag_pic && TARGET_SH2
7660       && GET_CODE (operands[1]) == MEM
7661       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
7662     {
7663       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
7664                                             operands[2]));
7665       DONE;
7666     }
7667   else
7668     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
7670   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
7671   DONE;
7674 (define_insn "sibcalli"
7675   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
7676          (match_operand 1 "" ""))
7677    (use (reg:PSI FPSCR_REG))
7678    (return)]
7679   "TARGET_SH1"
7680   "jmp  @%0%#"
7681   [(set_attr "needs_delay_slot" "yes")
7682    (set (attr "fp_mode")
7683         (if_then_else (eq_attr "fpu_single" "yes")
7684                       (const_string "single") (const_string "double")))
7685    (set_attr "type" "jump_ind")])
7687 (define_insn "sibcalli_pcrel"
7688   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
7689          (match_operand 1 "" ""))
7690    (use (match_operand 2 "" ""))
7691    (use (reg:PSI FPSCR_REG))
7692    (return)]
7693   "TARGET_SH2"
7694   "braf %0\\n%O2:%#"
7695   [(set_attr "needs_delay_slot" "yes")
7696    (set (attr "fp_mode")
7697         (if_then_else (eq_attr "fpu_single" "yes")
7698                       (const_string "single") (const_string "double")))
7699    (set_attr "type" "jump_ind")])
7701 ;; This uses an unspec to describe that the symbol_ref is very close.
7702 (define_insn "sibcalli_thunk"
7703   [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")]
7704                              UNSPEC_THUNK))
7705          (match_operand 1 "" ""))
7706    (use (reg:PSI FPSCR_REG))
7707    (return)]
7708   "TARGET_SH1"
7709   "bra  %O0"
7710   [(set_attr "needs_delay_slot" "yes")
7711    (set (attr "fp_mode")
7712         (if_then_else (eq_attr "fpu_single" "yes")
7713                       (const_string "single") (const_string "double")))
7714    (set_attr "type" "jump")
7715    (set_attr "length" "2")])
7717 (define_insn_and_split "sibcall_pcrel"
7718   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
7719          (match_operand 1 "" ""))
7720    (use (reg:PSI FPSCR_REG))
7721    (clobber (match_scratch:SI 2 "=k"))
7722    (return)]
7723   "TARGET_SH2"
7724   "#"
7725   "reload_completed"
7726   [(const_int 0)]
7727   "
7729   rtx lab = PATTERN (gen_call_site ());
7730   rtx call_insn;
7732   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
7733   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
7734                                                   lab));
7735   SIBLING_CALL_P (call_insn) = 1;
7736   DONE;
7738   [(set_attr "needs_delay_slot" "yes")
7739    (set (attr "fp_mode")
7740         (if_then_else (eq_attr "fpu_single" "yes")
7741                       (const_string "single") (const_string "double")))
7742    (set_attr "type" "jump_ind")])
7744 (define_insn "sibcall_compact"
7745   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
7746          (match_operand 1 "" ""))
7747    (return)
7748    (use (match_operand:SI 2 "register_operand" "z,x"))
7749    (use (reg:SI R1_REG))
7750    (use (reg:PSI FPSCR_REG))
7751    ;; We want to make sure the `x' above will only match MACH_REG
7752    ;; because sibcall_epilogue may clobber MACL_REG.
7753    (clobber (reg:SI MACL_REG))]
7754   "TARGET_SHCOMPACT"
7755   "@
7756         jmp     @%0%#
7757         jmp     @%0\\n  sts     %2, r0"
7758   [(set_attr "needs_delay_slot" "yes,no")
7759    (set_attr "length" "2,4")
7760    (set (attr "fp_mode") (const_string "single"))
7761    (set_attr "type" "jump_ind")])
7763 (define_insn "sibcall_media"
7764   [(call (mem:DI (match_operand 0 "target_reg_operand" "k"))
7765          (match_operand 1 "" ""))
7766    (use (reg:SI PR_MEDIA_REG))
7767    (return)]
7768   "TARGET_SHMEDIA"
7769   "blink        %0, r63"
7770   [(set_attr "type" "jump_media")])
7772 (define_expand "sibcall"
7773   [(parallel
7774     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
7775            (match_operand 1 "" ""))
7776      (match_operand 2 "" "")
7777      (use (reg:PSI FPSCR_REG))
7778      (return)])]
7779   ""
7780   "
7782   if (TARGET_SHMEDIA)
7783     {
7784       operands[0] = shmedia_prepare_call_address (operands[0], 1);
7785       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
7786       DONE;
7787     }
7788   else if (TARGET_SHCOMPACT && operands[2]
7789            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
7790     {
7791       rtx cookie_rtx = operands[2];
7792       long cookie = INTVAL (cookie_rtx);
7793       rtx func = XEXP (operands[0], 0);
7794       rtx mach, r1;
7796       if (flag_pic)
7797         {
7798           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7799             {
7800               rtx reg = gen_reg_rtx (Pmode);
7802               emit_insn (gen_symGOT2reg (reg, func));
7803               func = reg;
7804             }
7805           else
7806             func = legitimize_pic_address (func, Pmode, 0);
7807         }
7809       /* FIXME: if we could tell whether all argument registers are
7810          already taken, we could decide whether to force the use of
7811          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
7812          simple way to tell.  We could use the CALL_COOKIE, but we
7813          can't currently tell a register used for regular argument
7814          passing from one that is unused.  If we leave it up to reload
7815          to decide which register to use, it seems to always choose
7816          R0_REG, which leaves no available registers in SIBCALL_REGS
7817          to hold the address of the trampoline.  */
7818       mach = gen_rtx_REG (SImode, MACH_REG);
7819       r1 = gen_rtx_REG (SImode, R1_REG);
7821       /* Since such a call function may use all call-clobbered
7822          registers, we force a mode switch earlier, so that we don't
7823          run out of registers when adjusting fpscr for the call.  */
7824       emit_insn (gen_force_mode_for_call ());
7826       operands[0]
7827         = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7828                            SFUNC_GOT);
7829       operands[0] = force_reg (SImode, operands[0]);
7831       /* We don't need a return trampoline, since the callee will
7832          return directly to the upper caller.  */
7833       if (cookie & CALL_COOKIE_RET_TRAMP (1))
7834         {
7835           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
7836           cookie_rtx = GEN_INT (cookie);
7837         }
7839       emit_move_insn (mach, func);
7840       emit_move_insn (r1, cookie_rtx);
7842       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
7843       DONE;
7844     }
7845   else if (TARGET_SHCOMPACT && flag_pic
7846            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7847            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7848     {
7849       rtx reg = gen_reg_rtx (Pmode);
7851       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
7852       XEXP (operands[0], 0) = reg;
7853     }
7854   if (flag_pic && TARGET_SH2
7855       && GET_CODE (operands[0]) == MEM
7856       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
7857       /* The PLT needs the PIC register, but the epilogue would have
7858          to restore it, so we can only use PC-relative PIC calls for
7859          static functions.  */
7860       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
7861     {
7862       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
7863       DONE;
7864     }
7865   else
7866     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
7868   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
7869   DONE;
7872 (define_expand "sibcall_value"
7873   [(set (match_operand 0 "" "")
7874         (call (match_operand 1 "" "")
7875               (match_operand 2 "" "")))
7876    (match_operand 3 "" "")]
7877   ""
7878   "
7880   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
7881   DONE;
7884 (define_insn "call_value_pop_compact"
7885   [(set (match_operand 0 "" "=rf")
7886         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7887               (match_operand 2 "" "")))
7888    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7889                                  (match_operand 4 "immediate_operand" "n")))
7890    (match_operand 3 "immediate_operand" "n")
7891    (use (reg:SI R0_REG))
7892    (use (reg:SI R1_REG))
7893    (use (reg:PSI FPSCR_REG))
7894    (clobber (reg:SI PR_REG))]
7895   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7896   "jsr  @%1%#"
7897   [(set_attr "type" "call")
7898    (set (attr "fp_mode")
7899         (if_then_else (eq_attr "fpu_single" "yes")
7900                       (const_string "single") (const_string "double")))
7901    (set_attr "needs_delay_slot" "yes")])
7903 (define_insn "call_value_pop_compact_rettramp"
7904   [(set (match_operand 0 "" "=rf")
7905         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
7906               (match_operand 2 "" "")))
7907    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7908                                  (match_operand 4 "immediate_operand" "n")))
7909    (match_operand 3 "immediate_operand" "n")
7910    (use (reg:SI R0_REG))
7911    (use (reg:SI R1_REG))
7912    (use (reg:PSI FPSCR_REG))
7913    (clobber (reg:SI R10_REG))
7914    (clobber (reg:SI PR_REG))]
7915   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
7916   "jsr  @%1%#"
7917   [(set_attr "type" "call")
7918    (set (attr "fp_mode")
7919         (if_then_else (eq_attr "fpu_single" "yes")
7920                       (const_string "single") (const_string "double")))
7921    (set_attr "needs_delay_slot" "yes")])
7923 (define_expand "call_value_pop"
7924   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
7925                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
7926                                  (match_operand 2 "" "")))
7927               (match_operand 3 "" "")
7928               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
7929                                             (match_operand 4 "" "")))])]
7930   "TARGET_SHCOMPACT"
7931   "
7933   rtx cookie_rtx;
7934   long cookie;
7935   rtx func;
7936   rtx r0, r1;
7938   gcc_assert (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]));
7939   cookie_rtx = operands[3];
7940   cookie = INTVAL (cookie_rtx);
7941   func = XEXP (operands[1], 0);
7943   if (flag_pic)
7944     {
7945       if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
7946         {
7947           rtx reg = gen_reg_rtx (Pmode);
7949           emit_insn (gen_symGOTPLT2reg (reg, func));
7950           func = reg;
7951         }
7952       else
7953         func = legitimize_pic_address (func, Pmode, 0);
7954     }
7956   r0 = gen_rtx_REG (SImode, R0_REG);
7957   r1 = gen_rtx_REG (SImode, R1_REG);
7959   /* Since such a call function may use all call-clobbered
7960      registers, we force a mode switch earlier, so that we don't
7961      run out of registers when adjusting fpscr for the call.  */
7962   emit_insn (gen_force_mode_for_call ());
7964   operands[1] = function_symbol (NULL, \"__GCC_shcompact_call_trampoline\",
7965                                  SFUNC_GOT);
7966   operands[1] = force_reg (SImode, operands[1]);
7968   emit_move_insn (r0, func);
7969   emit_move_insn (r1, cookie_rtx);
7971   if (cookie & CALL_COOKIE_RET_TRAMP (1))
7972     emit_call_insn (gen_call_value_pop_compact_rettramp
7973                         (operands[0], operands[1], operands[2],
7974                          operands[3], operands[4]));
7975   else
7976     emit_call_insn (gen_call_value_pop_compact
7977                         (operands[0], operands[1], operands[2],
7978                          operands[3], operands[4]));
7980   DONE;
7983 (define_expand "sibcall_epilogue"
7984   [(return)]
7985   ""
7986   "
7988   sh_expand_epilogue (1);
7989   if (TARGET_SHCOMPACT)
7990     {
7991       rtx insn, set;
7993       /* If epilogue clobbers r0, preserve it in macl.  */
7994       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7995         if ((set = single_set (insn))
7996             && GET_CODE (SET_DEST (set)) == REG
7997             && REGNO (SET_DEST (set)) == R0_REG)
7998           {
7999             rtx r0 = gen_rtx_REG (SImode, R0_REG);
8000             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
8001             rtx i;
8003             /* We can't tell at this point whether the sibcall is a
8004                sibcall_compact and, if it is, whether it uses r0 or
8005                mach as operand 2, so let the instructions that
8006                preserve r0 be optimized away if r0 turns out to be
8007                dead.  */
8008             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
8009             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8010                                                REG_NOTES (i));
8011             i = emit_move_insn (r0, tmp);
8012             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
8013                                                REG_NOTES (i));
8014             break;
8015           }
8016     }
8017   DONE;
8020 (define_insn "indirect_jump_compact"
8021   [(set (pc)
8022         (match_operand:SI 0 "arith_reg_operand" "r"))]
8023   "TARGET_SH1"
8024   "jmp  @%0%#"
8025   [(set_attr "needs_delay_slot" "yes")
8026    (set_attr "type" "jump_ind")])
8028 (define_expand "indirect_jump"
8029   [(set (pc)
8030         (match_operand 0 "register_operand" ""))]
8031   ""
8032   "
8034   if (GET_MODE (operands[0]) != Pmode)
8035     operands[0] = gen_rtx_SUBREG (Pmode, operands[0], 0);
8038 ;; The use of operand 1 / 2 helps us distinguish case table jumps
8039 ;; which can be present in structured code from indirect jumps which can not
8040 ;; be present in structured code.  This allows -fprofile-arcs to work.
8042 ;; For SH1 processors.
8043 (define_insn "casesi_jump_1"
8044   [(set (pc)
8045         (match_operand:SI 0 "register_operand" "r"))
8046    (use (label_ref (match_operand 1 "" "")))]
8047   "TARGET_SH1"
8048   "jmp  @%0%#"
8049   [(set_attr "needs_delay_slot" "yes")
8050    (set_attr "type" "jump_ind")])
8052 ;; For all later processors.
8053 (define_insn "casesi_jump_2"
8054   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
8055                       (label_ref (match_operand 1 "" ""))))
8056    (use (label_ref (match_operand 2 "" "")))]
8057   "TARGET_SH2
8058    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
8059   "braf %0%#"
8060   [(set_attr "needs_delay_slot" "yes")
8061    (set_attr "type" "jump_ind")])
8063 (define_insn "casesi_jump_media"
8064   [(set (pc) (match_operand 0 "target_reg_operand" "b"))
8065    (use (label_ref (match_operand 1 "" "")))]
8066   "TARGET_SHMEDIA"
8067   "blink        %0, r63"
8068   [(set_attr "type" "jump_media")])
8070 ;; Call subroutine returning any type.
8071 ;; ??? This probably doesn't work.
8073 (define_expand "untyped_call"
8074   [(parallel [(call (match_operand 0 "" "")
8075                     (const_int 0))
8076               (match_operand 1 "" "")
8077               (match_operand 2 "" "")])]
8078   "(TARGET_SH2E || TARGET_SH2A) || TARGET_SHMEDIA"
8079   "
8081   int i;
8083   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
8085   for (i = 0; i < XVECLEN (operands[2], 0); i++)
8086     {
8087       rtx set = XVECEXP (operands[2], 0, i);
8088       emit_move_insn (SET_DEST (set), SET_SRC (set));
8089     }
8091   /* The optimizer does not know that the call sets the function value
8092      registers we stored in the result block.  We avoid problems by
8093      claiming that all hard registers are used and clobbered at this
8094      point.  */
8095   emit_insn (gen_blockage ());
8097   DONE;
8100 ;; ------------------------------------------------------------------------
8101 ;; Misc insns
8102 ;; ------------------------------------------------------------------------
8104 (define_insn "dect"
8105   [(set (reg:SI T_REG)
8106         (eq:SI (match_operand:SI 0 "arith_reg_dest" "+r") (const_int 1)))
8107    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
8108   "TARGET_SH2"
8109   "dt   %0"
8110   [(set_attr "type" "arith")])
8112 (define_insn "nop"
8113   [(const_int 0)]
8114   ""
8115   "nop")
8117 ;; Load address of a label. This is only generated by the casesi expand,
8118 ;; and by machine_dependent_reorg (fixing up fp moves).
8119 ;; This must use unspec, because this only works for labels that are
8120 ;; within range,
8122 (define_insn "mova"
8123   [(set (reg:SI R0_REG)
8124         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
8125   "TARGET_SH1"
8126   "mova %O0,r0"
8127   [(set_attr "in_delay_slot" "no")
8128    (set_attr "type" "arith")])
8130 ;; machine_dependent_reorg will make this a `mova'.
8131 (define_insn "mova_const"
8132   [(set (reg:SI R0_REG)
8133         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
8134   "TARGET_SH1"
8135   "#"
8136   [(set_attr "in_delay_slot" "no")
8137    (set_attr "type" "arith")])
8139 (define_expand "GOTaddr2picreg"
8140   [(set (reg:SI R0_REG)
8141         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
8142                    UNSPEC_MOVA))
8143    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
8144    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8145   "" "
8147   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
8148   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
8150   if (TARGET_SHMEDIA)
8151     {
8152       rtx tr = gen_rtx_REG (Pmode, TR0_REG);
8153       rtx pic = operands[0];
8154       rtx lab = PATTERN (gen_call_site ());
8155       rtx insn, equiv;
8157       equiv = operands[1];
8158       operands[1] = gen_rtx_MINUS (Pmode,
8159                                    operands[1],
8160                                    gen_rtx_CONST
8161                                    (Pmode,
8162                                     gen_rtx_MINUS (Pmode,
8163                                                    gen_rtx_CONST (Pmode,
8164                                                                   lab),
8165                                                    pc_rtx)));
8166       operands[1] = gen_sym2PIC (operands[1]);
8167       PUT_MODE (operands[1], Pmode);
8169       if (Pmode == SImode)
8170         {
8171           emit_insn (gen_movsi_const (pic, operands[1]));
8172           emit_insn (gen_ptrel_si (tr, pic, lab));
8173         }
8174       else
8175         {
8176           emit_insn (gen_movdi_const (pic, operands[1]));
8177           emit_insn (gen_ptrel_di (tr, pic, lab));
8178         }
8180       insn = emit_move_insn (operands[0], tr);
8182       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
8183                                             REG_NOTES (insn));
8185       DONE;
8186     }
8190 (define_insn "*ptb"
8191   [(set (match_operand 0 "target_reg_operand" "=b")
8192         (const (unspec [(match_operand 1 "" "Csy")]
8193                              UNSPEC_DATALABEL)))]
8194   "TARGET_SHMEDIA && flag_pic
8195    && EXTRA_CONSTRAINT_Csy (operands[1])"
8196   "ptb/u        datalabel %1, %0"
8197   [(set_attr "type" "ptabs_media")
8198    (set_attr "length" "*")])
8200 (define_insn "ptrel_si"
8201   [(set (match_operand:SI 0 "target_reg_operand" "=b")
8202         (plus:SI (match_operand:SI 1 "register_operand" "r")
8203               (pc)))
8204    (match_operand:SI 2 "" "")]
8205   "TARGET_SHMEDIA"
8206   "%O2: ptrel/u %1, %0"
8207   [(set_attr "type" "ptabs_media")])
8209 (define_insn "ptrel_di"
8210   [(set (match_operand:DI 0 "target_reg_operand" "=b")
8211         (plus:DI (match_operand:DI 1 "register_operand" "r")
8212               (pc)))
8213    (match_operand:DI 2 "" "")]
8214   "TARGET_SHMEDIA"
8215   "%O2: ptrel/u %1, %0"
8216   [(set_attr "type" "ptabs_media")])
8218 (define_expand "builtin_setjmp_receiver"
8219   [(match_operand 0 "" "")]
8220   "flag_pic"
8221   "
8223   emit_insn (gen_GOTaddr2picreg ());
8224   DONE;
8227 (define_expand "call_site"
8228   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
8229   "TARGET_SH1"
8230   "
8232   static HOST_WIDE_INT i = 0;
8233   operands[0] = GEN_INT (i);
8234   i++;
8237 (define_expand "sym_label2reg"
8238   [(set (match_operand:SI 0 "" "")
8239         (const:SI (minus:SI
8240                    (const:SI
8241                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
8242                    (const:SI
8243                     (plus:SI
8244                      (match_operand:SI 2 "" "")
8245                      (const_int 2))))))]
8246   "TARGET_SH1" "")
8248 (define_expand "symGOT_load"
8249   [(set (match_dup 2) (match_operand 1 "" ""))
8250    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
8251    (set (match_operand 0 "" "") (mem (match_dup 3)))]
8252   ""
8253   "
8255   rtx insn;
8257   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8258   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
8260   if (TARGET_SHMEDIA)
8261     {
8262       rtx reg = operands[2];
8264       if (Pmode == DImode)
8265         {      
8266           if (flag_pic > 1)
8267             emit_insn (gen_movdi_const_32bit (reg, operands[1]));
8268           else
8269             emit_insn (gen_movdi_const_16bit (reg, operands[1]));
8270         }
8271       else
8272         {
8273           if (flag_pic > 1)
8274             emit_insn (gen_movsi_const (reg, operands[1]));
8275           else
8276             emit_insn (gen_movsi_const_16bit (reg, operands[1]));
8277         }
8278     }
8279   else
8280     emit_move_insn (operands[2], operands[1]);
8282   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
8283                                              operands[2],
8284                                              gen_rtx_REG (Pmode, PIC_REG)));
8286   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
8288   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
8289                                                                   0), 0, 0),
8290                                         REG_NOTES (insn));
8292   DONE;
8295 (define_expand "sym2GOT"
8296   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
8297   ""
8298   "")
8300 (define_expand "symGOT2reg"
8301   [(match_operand 0 "" "") (match_operand 1 "" "")]
8302   ""
8303   "
8305   rtx gotsym, insn;
8307   gotsym = gen_sym2GOT (operands[1]);
8308   PUT_MODE (gotsym, Pmode);
8309   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
8311   MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1;
8313   DONE;
8316 (define_expand "sym2GOTPLT"
8317   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
8318   ""
8319   "")
8321 (define_expand "symGOTPLT2reg"
8322   [(match_operand 0 "" "") (match_operand 1 "" "")]
8323   ""
8324   "
8326   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
8327   DONE;
8330 (define_expand "sym2GOTOFF"
8331   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
8332   ""
8333   "")
8335 (define_expand "symGOTOFF2reg"
8336   [(match_operand 0 "" "") (match_operand 1 "" "")]
8337   ""
8338   "
8340   rtx gotoffsym, insn;
8341   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8343   gotoffsym = gen_sym2GOTOFF (operands[1]);
8344   PUT_MODE (gotoffsym, Pmode);
8345   emit_move_insn (t, gotoffsym);
8346   insn = emit_move_insn (operands[0],
8347                          gen_rtx_PLUS (Pmode, t,
8348                                        gen_rtx_REG (Pmode, PIC_REG)));
8350   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
8351                                         REG_NOTES (insn));
8353   DONE;
8356 (define_expand "symPLT_label2reg"
8357   [(set (match_operand:SI 0 "" "")
8358         (const:SI (minus:SI
8359                    (const:SI
8360                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
8361                    (const:SI
8362                     (minus:SI
8363                      (const:SI (plus:SI
8364                                 (match_operand:SI 2 "" "")
8365                                 (const_int 2)))
8366                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
8367    ;; Even though the PIC register is not really used by the call
8368    ;; sequence in which this is expanded, the PLT code assumes the PIC
8369    ;; register is set, so we must not skip its initialization.  Since
8370    ;; we only use this expand as part of calling sequences, and never
8371    ;; to take the address of a function, this is the best point to
8372    ;; insert the (use).  Using the PLT to take the address of a
8373    ;; function would be wrong, not only because the PLT entry could
8374    ;; then be called from a function that doesn't initialize the PIC
8375    ;; register to the proper GOT, but also because pointers to the
8376    ;; same function might not compare equal, should they be set by
8377    ;; different shared libraries.
8378    (use (reg:SI PIC_REG))]
8379   "TARGET_SH1"
8380   "")
8382 (define_expand "sym2PIC"
8383   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
8384   ""
8385   "")
8387 ;; TLS code generation.
8388 ;; ??? this should be a define_insn_and_split
8389 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
8390 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
8391 ;; for details.
8393 (define_insn "tls_global_dynamic"
8394   [(set (match_operand:SI 0 "register_operand" "=&z")
8395         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8396                                   UNSPEC_TLSGD))
8397               (const_int 0)))
8398    (use (reg:PSI FPSCR_REG))
8399    (use (reg:SI PIC_REG))
8400    (clobber (reg:SI PR_REG))
8401    (clobber (scratch:SI))]
8402   "TARGET_SH1"
8403   "*
8405   return \"\\
8406 mov.l\\t1f,r4\\n\\
8407 \\tmova\\t2f,r0\\n\\
8408 \\tmov.l\\t2f,r1\\n\\
8409 \\tadd\\tr0,r1\\n\\
8410 \\tjsr\\t@r1\\n\\
8411 \\tadd\\tr12,r4\\n\\
8412 \\tbra\\t3f\\n\\
8413 \\tnop\\n\\
8414 \\t.align\\t2\\n\\
8415 1:\\t.long\\t%a1@TLSGD\\n\\
8416 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8417 3:\";
8419   [(set_attr "type" "tls_load")
8420    (set_attr "length" "26")])
8422 (define_insn "tls_local_dynamic"
8423   [(set (match_operand:SI 0 "register_operand" "=&z")
8424         (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")]
8425                                   UNSPEC_TLSLDM))
8426               (const_int 0)))
8427    (use (reg:PSI FPSCR_REG))
8428    (use (reg:SI PIC_REG))
8429    (clobber (reg:SI PR_REG))
8430    (clobber (scratch:SI))]
8431   "TARGET_SH1"
8432   "*
8434   return \"\\
8435 mov.l\\t1f,r4\\n\\
8436 \\tmova\\t2f,r0\\n\\
8437 \\tmov.l\\t2f,r1\\n\\
8438 \\tadd\\tr0,r1\\n\\
8439 \\tjsr\\t@r1\\n\\
8440 \\tadd\\tr12,r4\\n\\
8441 \\tbra\\t3f\\n\\
8442 \\tnop\\n\\
8443 \\t.align\\t2\\n\\
8444 1:\\t.long\\t%a1@TLSLDM\\n\\
8445 2:\\t.long\\t__tls_get_addr@PLT\\n\\
8446 3:\";
8448   [(set_attr "type" "tls_load")
8449    (set_attr "length" "26")])
8451 (define_expand "sym2DTPOFF"
8452   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
8453   ""
8454   "")
8456 (define_expand "symDTPOFF2reg"
8457   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
8458   ""
8459   "
8461   rtx dtpoffsym, insn;
8462   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
8464   dtpoffsym = gen_sym2DTPOFF (operands[1]);
8465   PUT_MODE (dtpoffsym, Pmode);
8466   emit_move_insn (t, dtpoffsym);
8467   insn = emit_move_insn (operands[0],
8468                          gen_rtx_PLUS (Pmode, t, operands[2]));
8469   DONE;
8472 (define_expand "sym2GOTTPOFF"
8473   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
8474   ""
8475   "")
8477 (define_insn "tls_initial_exec"
8478   [(set (match_operand:SI 0 "register_operand" "=&r")
8479         (unspec:SI [(match_operand:SI 1 "" "")]
8480                     UNSPEC_TLSIE))
8481    (use (reg:SI GBR_REG))
8482    (use (reg:SI PIC_REG))
8483    (clobber (reg:SI R0_REG))]
8484   ""
8485   "*
8487   return \"\\
8488 mov.l\\t1f,r0\\n\\
8489 \\tstc\\tgbr,%0\\n\\
8490 \\tmov.l\\t@(r0,r12),r0\\n\\
8491 \\tbra\\t2f\\n\\
8492 \\tadd\\tr0,%0\\n\\
8493 \\t.align\\t2\\n\\
8494 1:\\t.long\\t%a1\\n\\
8495 2:\";
8497   [(set_attr "type" "tls_load")
8498    (set_attr "length" "16")])
8500 (define_expand "sym2TPOFF"
8501   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
8502   ""
8503   "")
8505 (define_expand "symTPOFF2reg"
8506   [(match_operand 0 "" "") (match_operand 1 "" "")]
8507   ""
8508   "
8510   rtx tpoffsym, insn;
8512   tpoffsym = gen_sym2TPOFF (operands[1]);
8513   PUT_MODE (tpoffsym, Pmode);
8514   insn = emit_move_insn (operands[0], tpoffsym);
8515   DONE;
8518 (define_insn "load_gbr"
8519   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
8520    (use (reg:SI GBR_REG))]
8521   ""
8522   "stc  gbr,%0"
8523   [(set_attr "type" "tls_load")])
8525 ;; case instruction for switch statements.
8527 ;; Operand 0 is index
8528 ;; operand 1 is the minimum bound
8529 ;; operand 2 is the maximum bound - minimum bound + 1
8530 ;; operand 3 is CODE_LABEL for the table;
8531 ;; operand 4 is the CODE_LABEL to go to if index out of range.
8533 (define_expand "casesi"
8534   [(match_operand:SI 0 "arith_reg_operand" "")
8535    (match_operand:SI 1 "arith_reg_operand" "")
8536    (match_operand:SI 2 "arith_reg_operand" "")
8537    (match_operand 3 "" "") (match_operand 4 "" "")]
8538   ""
8539   "
8541   rtx reg = gen_reg_rtx (SImode);
8542   rtx reg2 = gen_reg_rtx (SImode);
8543   if (TARGET_SHMEDIA)
8544     {
8545       rtx reg = gen_reg_rtx (DImode);
8546       rtx reg2 = gen_reg_rtx (DImode);
8547       rtx reg3 = gen_reg_rtx (Pmode);
8548       rtx reg4 = gen_reg_rtx (Pmode);
8549       rtx reg5 = gen_reg_rtx (Pmode);
8550       rtx load;
8552       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
8553       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
8554       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
8556       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
8557       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
8558       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
8559       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
8560       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
8561                                                (Pmode, operands[3])));
8562       /* Messy: can we subreg to clean this up? */
8563       if (Pmode == DImode)
8564         load = gen_casesi_load_media (reg4, reg3, reg2, operands[3]);
8565       else
8566         load = gen_casesi_load_media (reg4,
8567                                       gen_rtx_SUBREG (DImode, reg3, 0),
8568                                       reg2, operands[3]);
8569       PUT_MODE (SET_SRC (load), Pmode);
8570       emit_insn (load);
8571       /* ??? The following add could be eliminated if we used ptrel.  */
8572       emit_move_insn (reg5, gen_rtx_PLUS (Pmode, reg3, reg4));
8573       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
8574       emit_barrier ();
8575       DONE;
8576     }
8577   operands[1] = copy_to_mode_reg (SImode, operands[1]);
8578   operands[2] = copy_to_mode_reg (SImode, operands[2]);
8579   /* If optimizing, casesi_worker depends on the mode of the instruction
8580      before label it 'uses' - operands[3].  */
8581   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
8582                            reg));
8583   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
8584   if (TARGET_SH2)
8585     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
8586   else
8587     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
8588   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
8589      operands[3], but to lab.  We will fix this up in
8590      machine_dependent_reorg.  */
8591   emit_barrier ();
8592   DONE;
8595 (define_expand "casesi_0"
8596   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
8597    (set (match_dup 4) (minus:SI (match_dup 4)
8598                                 (match_operand:SI 1 "arith_operand" "")))
8599    (set (reg:SI T_REG)
8600         (gtu:SI (match_dup 4)
8601                 (match_operand:SI 2 "arith_reg_operand" "")))
8602    (set (pc)
8603         (if_then_else (ne (reg:SI T_REG)
8604                           (const_int 0))
8605                       (label_ref (match_operand 3 "" ""))
8606                       (pc)))]
8607   "TARGET_SH1"
8608   "")
8610 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
8611 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
8612 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
8614 (define_insn "casesi_worker_0"
8615   [(set (match_operand:SI 0 "register_operand" "=r,r")
8616         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
8617                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8618    (clobber (match_scratch:SI 3 "=X,1"))
8619    (clobber (match_scratch:SI 4 "=&z,z"))]
8620   "TARGET_SH1"
8621   "#")
8623 (define_split
8624   [(set (match_operand:SI 0 "register_operand" "")
8625         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8626                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8627    (clobber (match_scratch:SI 3 ""))
8628    (clobber (match_scratch:SI 4 ""))]
8629   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
8630   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8631    (parallel [(set (match_dup 0)
8632               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8633                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8634               (clobber (match_dup 3))])
8635    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
8636   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8638 (define_split
8639   [(set (match_operand:SI 0 "register_operand" "")
8640         (unspec:SI [(match_operand:SI 1 "register_operand" "")
8641                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8642    (clobber (match_scratch:SI 3 ""))
8643    (clobber (match_scratch:SI 4 ""))]
8644   "TARGET_SH2 && reload_completed"
8645   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
8646    (parallel [(set (match_dup 0)
8647               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
8648                           (label_ref (match_dup 2))] UNSPEC_CASESI))
8649               (clobber (match_dup 3))])]
8650   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
8652 (define_insn "casesi_worker_1"
8653   [(set (match_operand:SI 0 "register_operand" "=r,r")
8654         (unspec:SI [(reg:SI R0_REG)
8655                     (match_operand:SI 1 "register_operand" "0,r")
8656                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
8657    (clobber (match_scratch:SI 3 "=X,1"))]
8658   "TARGET_SH1"
8659   "*
8661   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8663   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8665   switch (GET_MODE (diff_vec))
8666     {
8667     case SImode:
8668       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
8669     case HImode:
8670       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
8671     case QImode:
8672       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8673         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8674       return \"mov.b    @(r0,%1),%0\";
8675     default:
8676       gcc_unreachable ();
8677     }
8679   [(set_attr "length" "4")])
8681 (define_insn "casesi_worker_2"
8682   [(set (match_operand:SI 0 "register_operand" "=r,r")
8683         (unspec:SI [(reg:SI R0_REG)
8684                     (match_operand:SI 1 "register_operand" "0,r")
8685                     (label_ref (match_operand 2 "" ""))
8686                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
8687    (clobber (match_operand:SI 4 "" "=X,1"))]
8688   "TARGET_SH2 && reload_completed && flag_pic"
8689   "*
8691   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8692   const char *load;
8694   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8696   switch (GET_MODE (diff_vec))
8697     {
8698     case SImode:
8699       output_asm_insn (\"shll2    %1\", operands);
8700       load = \"mov.l    @(r0,%1),%0\"; break;
8701     case HImode:
8702       output_asm_insn (\"add    %1,%1\", operands);
8703       load = \"mov.w    @(r0,%1),%0\"; break;
8704     case QImode:
8705       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8706         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
8707       else
8708         load = \"mov.b  @(r0,%1),%0\";
8709       break;
8710     default:
8711       gcc_unreachable ();
8712     }
8713   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
8714   return load;
8716   [(set_attr "length" "8")])
8718 (define_insn "casesi_shift_media"
8719   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
8720         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
8721                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
8722                     UNSPEC_CASESI)))]
8723   "TARGET_SHMEDIA"
8724   "*
8726   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
8728   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8730   switch (GET_MODE (diff_vec))
8731     {
8732     case SImode:
8733       return \"shlli    %1, 2, %0\";
8734     case HImode:
8735       return \"shlli    %1, 1, %0\";
8736     case QImode:
8737       if (rtx_equal_p (operands[0], operands[1]))
8738         return \"\";
8739       return \"add      %1, r63, %0\";
8740     default:
8741       gcc_unreachable ();
8742     }
8744   [(set_attr "type" "arith_media")])
8746 (define_insn "casesi_load_media"
8747   [(set (match_operand 0 "any_arith_reg_dest" "=r")
8748         (mem (unspec [(match_operand:DI 1 "arith_reg_operand" "r")
8749                          (match_operand:DI 2 "arith_reg_operand" "r")
8750                          (label_ref:DI (match_operand 3 "" ""))] UNSPEC_CASESI)))]
8751   "TARGET_SHMEDIA"
8752   "*
8754   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
8756   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
8758   switch (GET_MODE (diff_vec))
8759     {
8760     case SImode:
8761       return \"ldx.l    %1, %2, %0\";
8762     case HImode:
8763 #if 0
8764       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8765         return \"ldx.uw %1, %2, %0\";
8766 #endif
8767       return \"ldx.w    %1, %2, %0\";
8768     case QImode:
8769       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
8770         return \"ldx.ub %1, %2, %0\";
8771       return \"ldx.b    %1, %2, %0\";
8772     default:
8773       gcc_unreachable ();
8774     }
8776   [(set_attr "type" "load_media")])
8778 (define_expand "return"
8779   [(return)]
8780   "reload_completed && ! sh_need_epilogue ()"
8781   "
8783   if (TARGET_SHMEDIA)
8784     {
8785       emit_jump_insn (gen_return_media ());
8786       DONE;
8787     }
8789   if (TARGET_SHCOMPACT
8790       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
8791     {
8792       emit_jump_insn (gen_shcompact_return_tramp ());
8793       DONE;
8794     }
8797 (define_insn "*return_i"
8798   [(return)]
8799   "TARGET_SH1 && ! (TARGET_SHCOMPACT
8800                     && (current_function_args_info.call_cookie
8801                         & CALL_COOKIE_RET_TRAMP (1)))
8802    && reload_completed"
8803   "%@   %#"
8804   [(set_attr "type" "return")
8805    (set_attr "needs_delay_slot" "yes")])
8807 (define_expand "shcompact_return_tramp"
8808   [(return)]
8809   "TARGET_SHCOMPACT
8810    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8811   "
8813   rtx reg = gen_rtx_REG (Pmode, R0_REG);
8815   function_symbol (reg, \"__GCC_shcompact_return_trampoline\", SFUNC_STATIC);
8816   emit_jump_insn (gen_shcompact_return_tramp_i ());
8817   DONE;
8820 (define_insn "shcompact_return_tramp_i"
8821   [(parallel [(return) (use (reg:SI R0_REG))])]
8822   "TARGET_SHCOMPACT
8823    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
8824   "jmp  @r0%#"
8825   [(set_attr "type" "jump_ind")
8826    (set_attr "needs_delay_slot" "yes")])
8828 (define_insn "return_media_i"
8829   [(parallel [(return) (use (match_operand 0 "target_reg_operand" "k"))])]
8830   "TARGET_SHMEDIA && reload_completed"
8831   "blink        %0, r63"
8832   [(set_attr "type" "jump_media")])
8834 (define_insn "return_media_rte"
8835   [(return)]
8836   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
8837   "rte"
8838   [(set_attr "type" "jump_media")])
8840 (define_expand "return_media"
8841   [(return)]
8842   "TARGET_SHMEDIA && reload_completed"
8843   "
8845   int tr_regno = sh_media_register_for_return ();
8846   rtx tr;
8848   if (current_function_interrupt)
8849     {
8850       emit_jump_insn (gen_return_media_rte ());
8851       DONE;
8852     }
8853   if (tr_regno < 0)
8854     {
8855       rtx r18 = gen_rtx_REG (Pmode, PR_MEDIA_REG);
8857       gcc_assert (call_really_used_regs[TR0_REG] && !fixed_regs[TR0_REG]);
8858       tr_regno = TR0_REG;
8859       tr = gen_rtx_REG (Pmode, tr_regno);
8860       emit_move_insn (tr, r18);
8861     }
8862   else
8863     tr = gen_rtx_REG (Pmode, tr_regno);
8865   emit_jump_insn (gen_return_media_i (tr));
8866   DONE;
8869 (define_insn "shcompact_preserve_incoming_args"
8870   [(set (match_operand:SI 0 "register_operand" "+r")
8871         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
8872   "TARGET_SHCOMPACT"
8873   ""
8874   [(set_attr "length" "0")])
8876 (define_insn "shcompact_incoming_args"
8877   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
8878    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
8879    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
8880    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
8881    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
8882    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
8883    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
8884    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
8885    (set (mem:BLK (reg:SI MACL_REG))
8886         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
8887    (use (reg:SI R0_REG))
8888    (clobber (reg:SI R0_REG))
8889    (clobber (reg:SI MACL_REG))
8890    (clobber (reg:SI MACH_REG))
8891    (clobber (reg:SI PR_REG))]
8892   "TARGET_SHCOMPACT"
8893   "jsr  @r0%#"
8894   [(set_attr "needs_delay_slot" "yes")])
8896 (define_insn "shmedia_save_restore_regs_compact"
8897   [(set (reg:SI SP_REG)
8898         (plus:SI (reg:SI SP_REG)
8899                  (match_operand:SI 0 "immediate_operand" "i")))
8900    (use (reg:SI R0_REG))
8901    (clobber (reg:SI PR_REG))]
8902   "TARGET_SHCOMPACT
8903    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
8904        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
8905   "jsr @r0%#"
8906   [(set_attr "needs_delay_slot" "yes")])
8908 (define_expand "prologue"
8909   [(const_int 0)]
8910   ""
8911   "sh_expand_prologue (); DONE;")
8913 (define_expand "epilogue"
8914   [(return)]
8915   ""
8916   "
8918   sh_expand_epilogue (0);
8919   emit_jump_insn (gen_return ());
8920   DONE;
8923 (define_expand "eh_return"
8924   [(use (match_operand 0 "register_operand" ""))]
8925   ""
8927   rtx ra = operands[0];
8929   if (TARGET_SHMEDIA64)
8930     emit_insn (gen_eh_set_ra_di (ra));
8931   else
8932     emit_insn (gen_eh_set_ra_si (ra));
8934   DONE;
8937 ;; Clobber the return address on the stack.  We can't expand this
8938 ;; until we know where it will be put in the stack frame.
8940 (define_insn "eh_set_ra_si"
8941   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8942    (clobber (match_scratch:SI 1 "=&r"))]
8943   "! TARGET_SHMEDIA64"
8944   "#")
8946 (define_insn "eh_set_ra_di"
8947   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
8948    (clobber (match_scratch:DI 1 "=&r"))]
8949   "TARGET_SHMEDIA64"
8950   "#")
8952 (define_split
8953   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
8954    (clobber (match_scratch 1 ""))]
8955   "reload_completed"
8956   [(const_int 0)]
8957   "
8959   sh_set_return_address (operands[0], operands[1]);
8960   DONE;
8963 (define_insn "blockage"
8964   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
8965   ""
8966   ""
8967   [(set_attr "length" "0")])
8969 ;; ------------------------------------------------------------------------
8970 ;; Scc instructions
8971 ;; ------------------------------------------------------------------------
8973 (define_insn "movt"
8974   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
8975         (eq:SI (reg:SI T_REG) (const_int 1)))]
8976   "TARGET_SH1"
8977   "movt %0"
8978   [(set_attr "type" "arith")])
8980 (define_expand "seq"
8981   [(set (match_operand:SI 0 "arith_reg_dest" "")
8982         (match_dup 1))]
8983   ""
8984   "
8986   if (TARGET_SHMEDIA)
8987     {
8988       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
8989       if (sh_compare_op1 != const0_rtx)
8990         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
8991                                     ? GET_MODE (sh_compare_op0)
8992                                     : GET_MODE (sh_compare_op1),
8993                                     sh_compare_op1);
8994       if (GET_MODE_SIZE (GET_MODE (operands[0])) <= 4)
8995         {
8996           if (GET_MODE (operands[0]) != SImode)
8997             operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0);
8999           switch (GET_MODE (sh_compare_op0))
9000             {
9001             case SImode:
9002               emit_insn (gen_cmpsieqsi_media (operands[0],
9003                                               sh_compare_op0, sh_compare_op1));
9004               break;
9006             case DImode:
9007               emit_insn (gen_cmpsieqdi_media (operands[0],
9008                                               sh_compare_op0, sh_compare_op1));
9009               break;
9011             case SFmode:
9012               if (! TARGET_SHMEDIA_FPU)
9013                 FAIL;
9014               emit_insn (gen_cmpsieqsf_media (operands[0],
9015                                               sh_compare_op0, sh_compare_op1));
9016               break;
9018             case DFmode:
9019               if (! TARGET_SHMEDIA_FPU)
9020                 FAIL;
9021               emit_insn (gen_cmpsieqdf_media (operands[0],
9022                                               sh_compare_op0, sh_compare_op1));
9023               break;
9025             default:
9026               FAIL;
9027             }
9028           DONE;
9029         }
9031       if (GET_MODE (operands[0]) != DImode)
9032         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9034       switch (GET_MODE (sh_compare_op0))
9035         {
9036         case SImode:
9037           emit_insn (gen_cmpeqsi_media (operands[0],
9038                                         sh_compare_op0, sh_compare_op1));
9039           break;
9041         case DImode:
9042           emit_insn (gen_cmpeqdi_media (operands[0],
9043                                         sh_compare_op0, sh_compare_op1));
9044           break;
9046         case SFmode:
9047           if (! TARGET_SHMEDIA_FPU)
9048             FAIL;
9049           emit_insn (gen_cmpeqsf_media (operands[0],
9050                                         sh_compare_op0, sh_compare_op1));
9051           break;
9053         case DFmode:
9054           if (! TARGET_SHMEDIA_FPU)
9055             FAIL;
9056           emit_insn (gen_cmpeqdf_media (operands[0],
9057                                         sh_compare_op0, sh_compare_op1));
9058           break;
9060         default:
9061           FAIL;
9062         }
9063       DONE;
9064     }
9065   if (sh_expand_t_scc (EQ, operands[0]))
9066     DONE;
9067   if (! currently_expanding_to_rtl)
9068     FAIL;
9069   operands[1] = prepare_scc_operands (EQ);
9072 (define_expand "slt"
9073   [(set (match_operand:SI 0 "arith_reg_operand" "")
9074         (match_dup 1))]
9075   ""
9076   "
9078   if (TARGET_SHMEDIA)
9079     {
9080       if (GET_MODE (operands[0]) != DImode)
9081         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9082       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9083       if (sh_compare_op1 != const0_rtx)
9084         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9085                                     ? GET_MODE (sh_compare_op0)
9086                                     : GET_MODE (sh_compare_op1),
9087                                     sh_compare_op1);
9089       switch (GET_MODE (sh_compare_op0))
9090         {
9091         case SImode:
9092           emit_insn (gen_cmpgtsi_media (operands[0],
9093                                         sh_compare_op1, sh_compare_op0));
9094           break;
9096         case DImode:
9097           emit_insn (gen_cmpgtdi_media (operands[0],
9098                                         sh_compare_op1, sh_compare_op0));
9099           break;
9101         case SFmode:
9102           if (! TARGET_SHMEDIA_FPU)
9103             FAIL;
9104           emit_insn (gen_cmpgtsf_media (operands[0],
9105                                         sh_compare_op1, sh_compare_op0));
9106           break;
9108         case DFmode:
9109           if (! TARGET_SHMEDIA_FPU)
9110             FAIL;
9111           emit_insn (gen_cmpgtdf_media (operands[0],
9112                                         sh_compare_op1, sh_compare_op0));
9113           break;
9115         default:
9116           FAIL;
9117         }
9118       DONE;
9119     }
9120   if (! currently_expanding_to_rtl)
9121     FAIL;
9122   operands[1] = prepare_scc_operands (LT);
9125 (define_expand "sle"
9126   [(match_operand:SI 0 "arith_reg_operand" "")]
9127   ""
9128   "
9130   rtx tmp = sh_compare_op0;
9132   if (TARGET_SHMEDIA)
9133     {
9134       if (GET_MODE (operands[0]) != DImode)
9135         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9136       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9137       if (sh_compare_op1 != const0_rtx)
9138         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9139                                     ? GET_MODE (sh_compare_op0)
9140                                     : GET_MODE (sh_compare_op1),
9141                                     sh_compare_op1);
9143       switch (GET_MODE (sh_compare_op0))
9144         {
9145         case SImode:
9146           {
9147             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9149             emit_insn (gen_cmpgtsi_media (tmp,
9150                                           sh_compare_op0, sh_compare_op1));
9151             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9152             break;
9153           }
9155         case DImode:
9156           {
9157             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9159             emit_insn (gen_cmpgtdi_media (tmp,
9160                                           sh_compare_op0, sh_compare_op1));
9161             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9162             break;
9163           }
9165         case SFmode:
9166           if (! TARGET_SHMEDIA_FPU)
9167             FAIL;
9168           emit_insn (gen_cmpgesf_media (operands[0],
9169                                         sh_compare_op1, sh_compare_op0));
9170           break;
9172         case DFmode:
9173           if (! TARGET_SHMEDIA_FPU)
9174             FAIL;
9175           emit_insn (gen_cmpgedf_media (operands[0],
9176                                         sh_compare_op1, sh_compare_op0));
9177           break;
9179         default:
9180           FAIL;
9181         }
9182       DONE;
9183     }
9185   sh_compare_op0 = sh_compare_op1;
9186   sh_compare_op1 = tmp;
9187   emit_insn (gen_sge (operands[0]));
9188   DONE;
9191 (define_expand "sgt"
9192   [(set (match_operand:SI 0 "arith_reg_operand" "")
9193         (match_dup 1))]
9194   ""
9195   "
9197   if (TARGET_SHMEDIA)
9198     {
9199       if (GET_MODE (operands[0]) != DImode)
9200         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9201       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9202       if (sh_compare_op1 != const0_rtx)
9203         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9204                                     ? GET_MODE (sh_compare_op0)
9205                                     : GET_MODE (sh_compare_op1),
9206                                     sh_compare_op1);
9208       switch (GET_MODE (sh_compare_op0))
9209         {
9210         case SImode:
9211           emit_insn (gen_cmpgtsi_media (operands[0],
9212                                         sh_compare_op0, sh_compare_op1));
9213           break;
9215         case DImode:
9216           emit_insn (gen_cmpgtdi_media (operands[0],
9217                                         sh_compare_op0, sh_compare_op1));
9218           break;
9220         case SFmode:
9221           if (! TARGET_SHMEDIA_FPU)
9222             FAIL;
9223           emit_insn (gen_cmpgtsf_media (operands[0],
9224                                         sh_compare_op0, sh_compare_op1));
9225           break;
9227         case DFmode:
9228           if (! TARGET_SHMEDIA_FPU)
9229             FAIL;
9230           emit_insn (gen_cmpgtdf_media (operands[0],
9231                                         sh_compare_op0, sh_compare_op1));
9232           break;
9234         default:
9235           FAIL;
9236         }
9237       DONE;
9238     }
9239   if (! currently_expanding_to_rtl)
9240     FAIL;
9241   operands[1] = prepare_scc_operands (GT);
9244 (define_expand "sge"
9245   [(set (match_operand:SI 0 "arith_reg_operand" "")
9246         (match_dup 1))]
9247   ""
9248   "
9250   if (TARGET_SHMEDIA)
9251     {
9252       enum machine_mode mode = GET_MODE (sh_compare_op0);
9254       if ((mode) == VOIDmode)
9255         mode = GET_MODE (sh_compare_op1);
9256       if (GET_MODE (operands[0]) != DImode)
9257         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9258       sh_compare_op0 = force_reg (mode, sh_compare_op0);
9259       if (sh_compare_op1 != const0_rtx)
9260         sh_compare_op1 = force_reg (mode, sh_compare_op1);
9262       switch (mode)
9263         {
9264         case SImode:
9265           {
9266             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9268             emit_insn (gen_cmpgtsi_media (tmp,
9269                                           sh_compare_op1, sh_compare_op0));
9270             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9271             break;
9272           }
9274         case DImode:
9275           {
9276             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9278             emit_insn (gen_cmpgtdi_media (tmp,
9279                                           sh_compare_op1, sh_compare_op0));
9280             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9281             break;
9282           }
9284         case SFmode:
9285           if (! TARGET_SHMEDIA_FPU)
9286             FAIL;
9287           emit_insn (gen_cmpgesf_media (operands[0],
9288                                         sh_compare_op0, sh_compare_op1));
9289           break;
9291         case DFmode:
9292           if (! TARGET_SHMEDIA_FPU)
9293             FAIL;
9294           emit_insn (gen_cmpgedf_media (operands[0],
9295                                         sh_compare_op0, sh_compare_op1));
9296           break;
9298         default:
9299           FAIL;
9300         }
9301       DONE;
9302     }
9304   if (! currently_expanding_to_rtl)
9305     FAIL;
9306   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
9307     {
9308       if (TARGET_IEEE)
9309         {
9310           rtx lab = gen_label_rtx ();
9311           prepare_scc_operands (EQ);
9312           emit_jump_insn (gen_branch_true (lab));
9313           prepare_scc_operands (GT);
9314           emit_label (lab);
9315           emit_insn (gen_movt (operands[0]));
9316         }
9317       else
9318         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
9319       DONE;
9320     }
9321   operands[1] = prepare_scc_operands (GE);
9324 (define_expand "sgtu"
9325   [(set (match_operand:SI 0 "arith_reg_operand" "")
9326         (match_dup 1))]
9327   ""
9328   "
9330   if (TARGET_SHMEDIA)
9331     {
9332       if (GET_MODE (operands[0]) != DImode)
9333         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9334       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9335       if (sh_compare_op1 != const0_rtx)
9336         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9337                                     ? GET_MODE (sh_compare_op0)
9338                                     : GET_MODE (sh_compare_op1),
9339                                     sh_compare_op1);
9341       emit_insn (gen_cmpgtudi_media (operands[0],
9342                                      sh_compare_op0, sh_compare_op1));
9343       DONE;
9344     }
9345   if (! currently_expanding_to_rtl)
9346     FAIL;
9347   operands[1] = prepare_scc_operands (GTU);
9350 (define_expand "sltu"
9351   [(set (match_operand:SI 0 "arith_reg_operand" "")
9352         (match_dup 1))]
9353   ""
9354   "
9356   if (TARGET_SHMEDIA)
9357     {
9358       if (GET_MODE (operands[0]) != DImode)
9359         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9360       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9361       if (sh_compare_op1 != const0_rtx)
9362         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9363                                     ? GET_MODE (sh_compare_op0)
9364                                     : GET_MODE (sh_compare_op1),
9365                                     sh_compare_op1);
9367       emit_insn (gen_cmpgtudi_media (operands[0],
9368                                      sh_compare_op1, sh_compare_op0));
9369       DONE;
9370     }
9371   if (! currently_expanding_to_rtl)
9372     FAIL;
9373   operands[1] = prepare_scc_operands (LTU);
9376 (define_expand "sleu"
9377   [(set (match_operand:SI 0 "arith_reg_operand" "")
9378         (match_dup 1))]
9379   ""
9380   "
9382   if (TARGET_SHMEDIA)
9383     {
9384       rtx tmp;
9386       if (GET_MODE (operands[0]) != DImode)
9387         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9388       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9389       if (sh_compare_op1 != const0_rtx)
9390         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9391                                     ? GET_MODE (sh_compare_op0)
9392                                     : GET_MODE (sh_compare_op1),
9393                                     sh_compare_op1);
9395       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9397       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
9398       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9400       DONE;
9401     }
9402   if (! currently_expanding_to_rtl)
9403     FAIL;
9404   operands[1] = prepare_scc_operands (LEU);
9407 (define_expand "sgeu"
9408   [(set (match_operand:SI 0 "arith_reg_operand" "")
9409         (match_dup 1))]
9410   ""
9411   "
9413   if (TARGET_SHMEDIA)
9414     {
9415       rtx tmp;
9417       if (GET_MODE (operands[0]) != DImode)
9418         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9419       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9420       if (sh_compare_op1 != const0_rtx)
9421         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9422                                     ? GET_MODE (sh_compare_op0)
9423                                     : GET_MODE (sh_compare_op1),
9424                                     sh_compare_op1);
9426       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9428       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
9429       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9431       DONE;
9432     }
9434   if (! currently_expanding_to_rtl)
9435     FAIL;
9436   operands[1] = prepare_scc_operands (GEU);
9439 ;; sne moves the complement of the T reg to DEST like this:
9440 ;;      cmp/eq ...
9441 ;;      mov    #-1,temp
9442 ;;      negc   temp,dest
9443 ;;   This is better than xoring compare result with 1 because it does
9444 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
9445 ;;   loop.
9447 (define_expand "sne"
9448   [(set (match_dup 2) (const_int -1))
9449    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
9450                    (neg:SI (plus:SI (match_dup 1)
9451                                     (match_dup 2))))
9452               (set (reg:SI T_REG)
9453                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
9454                           (const_int 0)))])]
9455   ""
9456   "
9458   if (TARGET_SHMEDIA)
9459     {
9460       rtx tmp;
9462       if (GET_MODE (operands[0]) != DImode)
9463         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
9465       if (! TARGET_SHMEDIA_FPU
9466           && GET_MODE (sh_compare_op0) != DImode
9467           && GET_MODE (sh_compare_op0) != SImode)
9468         FAIL;
9470       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9471       if (sh_compare_op1 != const0_rtx)
9472         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
9473                                     ? GET_MODE (sh_compare_op0)
9474                                     : GET_MODE (sh_compare_op1),
9475                                     sh_compare_op1);
9477       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
9479       emit_insn (gen_seq (tmp));
9480       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
9482       DONE;
9483     }
9485   if (sh_expand_t_scc (NE, operands[0]))
9486     DONE;
9487   if (! currently_expanding_to_rtl)
9488     FAIL;
9489   operands[1] = prepare_scc_operands (EQ);
9490   operands[2] = gen_reg_rtx (SImode);
9493 (define_expand "sunordered"
9494   [(set (match_operand:DI 0 "arith_reg_operand" "")
9495         (unordered:DI (match_dup 1) (match_dup 2)))]
9496   "TARGET_SHMEDIA_FPU"
9497   "
9499   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
9500   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
9503 ;; Use the same trick for FP sle / sge
9505 ;; Apart from the constant use and the T setting, this is like movt,
9506 ;; except that it uses the logically negated value of T, i.e.
9507 ;; operand[0] := T ? 0 : 1.
9508 (define_expand "movnegt"
9509   [(set (match_dup 2) (const_int -1))
9510    (parallel [(set (match_operand 0 "" "")
9511                    (neg:SI (plus:SI (match_dup 1)
9512                                     (match_dup 2))))
9513               (set (reg:SI T_REG)
9514                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
9515                           (const_int 0)))])]
9516   "TARGET_SH1"
9517   "operands[2] = gen_reg_rtx (SImode);")
9519 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
9520 ;; This prevents a regression that occurred when we switched from xor to
9521 ;; mov/neg for sne.
9523 (define_split
9524   [(set (match_operand:SI 0 "arith_reg_dest" "")
9525         (plus:SI (reg:SI T_REG)
9526                  (const_int -1)))]
9527   "TARGET_SH1"
9528   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
9529    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
9530   "")
9532 ;; -------------------------------------------------------------------------
9533 ;; Instructions to cope with inline literal tables
9534 ;; -------------------------------------------------------------------------
9536 ; 2 byte integer in line
9538 (define_insn "consttable_2"
9539  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9540                     (match_operand 1 "" "")]
9541                    UNSPECV_CONST2)]
9542  ""
9543  "*
9545   if (operands[1] != const0_rtx)
9546     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
9547   return \"\";
9549  [(set_attr "length" "2")
9550  (set_attr "in_delay_slot" "no")])
9552 ; 4 byte integer in line
9554 (define_insn "consttable_4"
9555  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9556                     (match_operand 1 "" "")]
9557                    UNSPECV_CONST4)]
9558  ""
9559  "*
9561   if (operands[1] != const0_rtx)
9562     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
9563   return \"\";
9565  [(set_attr "length" "4")
9566   (set_attr "in_delay_slot" "no")])
9568 ; 8 byte integer in line
9570 (define_insn "consttable_8"
9571  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
9572                     (match_operand 1 "" "")]
9573                    UNSPECV_CONST8)]
9574  ""
9575  "*
9577   if (operands[1] != const0_rtx)
9578     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
9579   return \"\";
9581  [(set_attr "length" "8")
9582   (set_attr "in_delay_slot" "no")])
9584 ; 4 byte floating point
9586 (define_insn "consttable_sf"
9587  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
9588                     (match_operand 1 "" "")]
9589                    UNSPECV_CONST4)]
9590  ""
9591  "*
9593   if (operands[1] != const0_rtx)
9594     {
9595       REAL_VALUE_TYPE d;
9596       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9597       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
9598     }
9599   return \"\";
9601  [(set_attr "length" "4")
9602   (set_attr "in_delay_slot" "no")])
9604 ; 8 byte floating point
9606 (define_insn "consttable_df"
9607  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
9608                     (match_operand 1 "" "")]
9609                    UNSPECV_CONST8)]
9610  ""
9611  "*
9613   if (operands[1] != const0_rtx)
9614     {
9615       REAL_VALUE_TYPE d;
9616       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
9617       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
9618     }
9619   return \"\";
9621  [(set_attr "length" "8")
9622   (set_attr "in_delay_slot" "no")])
9624 ;; Alignment is needed for some constant tables; it may also be added for
9625 ;; Instructions at the start of loops, or after unconditional branches.
9626 ;; ??? We would get more accurate lengths if we did instruction
9627 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
9628 ;; here is too conservative.
9630 ; align to a two byte boundary
9632 (define_expand "align_2"
9633  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
9634  ""
9635  "")
9637 ; align to a four byte boundary
9638 ;; align_4 and align_log are instructions for the starts of loops, or
9639 ;; after unconditional branches, which may take up extra room.
9641 (define_expand "align_4"
9642  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
9643  ""
9644  "")
9646 ; align to a cache line boundary
9648 (define_insn "align_log"
9649  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
9650  ""
9651  ""
9652  [(set_attr "length" "0")
9653   (set_attr "in_delay_slot" "no")])
9655 ; emitted at the end of the literal table, used to emit the
9656 ; 32bit branch labels if needed.
9658 (define_insn "consttable_end"
9659   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
9660   ""
9661   "* return output_jump_label_table ();"
9662   [(set_attr "in_delay_slot" "no")])
9664 ; emitted at the end of the window in the literal table.
9666 (define_insn "consttable_window_end"
9667   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
9668   ""
9669   ""
9670   [(set_attr "length" "0")
9671    (set_attr "in_delay_slot" "no")])
9673 ;; -------------------------------------------------------------------------
9674 ;; Misc
9675 ;; -------------------------------------------------------------------------
9677 ;; String/block move insn.
9679 (define_expand "movmemsi"
9680   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
9681                    (mem:BLK (match_operand:BLK 1 "" "")))
9682               (use (match_operand:SI 2 "nonmemory_operand" ""))
9683               (use (match_operand:SI 3 "immediate_operand" ""))
9684               (clobber (reg:SI PR_REG))
9685               (clobber (reg:SI R4_REG))
9686               (clobber (reg:SI R5_REG))
9687               (clobber (reg:SI R0_REG))])]
9688   "TARGET_SH1 && ! TARGET_SH5"
9689   "
9691   if(expand_block_move (operands))
9692      DONE;
9693   else FAIL;
9696 (define_insn "block_move_real"
9697   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9698                    (mem:BLK (reg:SI R5_REG)))
9699               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9700               (clobber (reg:SI PR_REG))
9701               (clobber (reg:SI R0_REG))])]
9702   "TARGET_SH1 && ! TARGET_HARD_SH4"
9703   "jsr  @%0%#"
9704   [(set_attr "type" "sfunc")
9705    (set_attr "needs_delay_slot" "yes")])
9707 (define_insn "block_lump_real"
9708   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9709                    (mem:BLK (reg:SI R5_REG)))
9710               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9711               (use (reg:SI R6_REG))
9712               (clobber (reg:SI PR_REG))
9713               (clobber (reg:SI T_REG))
9714               (clobber (reg:SI R4_REG))
9715               (clobber (reg:SI R5_REG))
9716               (clobber (reg:SI R6_REG))
9717               (clobber (reg:SI R0_REG))])]
9718   "TARGET_SH1 && ! TARGET_HARD_SH4"
9719   "jsr  @%0%#"
9720   [(set_attr "type" "sfunc")
9721    (set_attr "needs_delay_slot" "yes")])
9723 (define_insn "block_move_real_i4"
9724   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9725                    (mem:BLK (reg:SI R5_REG)))
9726               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9727               (clobber (reg:SI PR_REG))
9728               (clobber (reg:SI R0_REG))
9729               (clobber (reg:SI R1_REG))
9730               (clobber (reg:SI R2_REG))])]
9731   "TARGET_HARD_SH4"
9732   "jsr  @%0%#"
9733   [(set_attr "type" "sfunc")
9734    (set_attr "needs_delay_slot" "yes")])
9736 (define_insn "block_lump_real_i4"
9737   [(parallel [(set (mem:BLK (reg:SI R4_REG))
9738                    (mem:BLK (reg:SI R5_REG)))
9739               (use (match_operand:SI 0 "arith_reg_operand" "r"))
9740               (use (reg:SI R6_REG))
9741               (clobber (reg:SI PR_REG))
9742               (clobber (reg:SI T_REG))
9743               (clobber (reg:SI R4_REG))
9744               (clobber (reg:SI R5_REG))
9745               (clobber (reg:SI R6_REG))
9746               (clobber (reg:SI R0_REG))
9747               (clobber (reg:SI R1_REG))
9748               (clobber (reg:SI R2_REG))
9749               (clobber (reg:SI R3_REG))])]
9750   "TARGET_HARD_SH4"
9751   "jsr  @%0%#"
9752   [(set_attr "type" "sfunc")
9753    (set_attr "needs_delay_slot" "yes")])
9755 ;; -------------------------------------------------------------------------
9756 ;; Floating point instructions.
9757 ;; -------------------------------------------------------------------------
9759 ;; ??? All patterns should have a type attribute.
9761 (define_expand "fpu_switch0"
9762   [(set (match_operand:SI 0 "" "") (match_dup 2))
9763    (set (match_dup 1) (mem:PSI (match_dup 0)))]
9764   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9765   "
9767   operands[1] = get_fpscr_rtx ();
9768   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9769   if (flag_pic)
9770     operands[2] = legitimize_pic_address (operands[2], SImode,
9771                                           no_new_pseudos ? operands[0] : 0);
9774 (define_expand "fpu_switch1"
9775   [(set (match_operand:SI 0 "" "") (match_dup 2))
9776    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
9777    (set (match_dup 1) (mem:PSI (match_dup 3)))]
9778   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9779   "
9781   operands[1] = get_fpscr_rtx ();
9782   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
9783   if (flag_pic)
9784     operands[2] = legitimize_pic_address (operands[2], SImode,
9785                                           no_new_pseudos ? operands[0] : 0);
9786   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
9789 (define_expand "movpsi"
9790   [(set (match_operand:PSI 0 "register_operand" "")
9791         (match_operand:PSI 1 "general_movsrc_operand" ""))]
9792   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9793   "")
9795 ;; The c / m alternative is a fake to guide reload to load directly into
9796 ;; fpscr, since reload doesn't know how to use post-increment.
9797 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
9798 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
9799 ;; predicate after reload.
9800 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
9801 ;; like a mac -> gpr move.
9802 (define_insn "fpu_switch"
9803   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
9804         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
9805   "TARGET_SH2E
9806    && (! reload_completed
9807        || true_regnum (operands[0]) != FPSCR_REG
9808        || GET_CODE (operands[1]) != MEM
9809        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
9810   "@
9811         ! precision stays the same
9812         lds.l   %1,fpscr
9813         mov.l   %1,%0
9814         #
9815         lds     %1,fpscr
9816         mov     %1,%0
9817         mov.l   %1,%0
9818         sts     fpscr,%0
9819         sts.l   fpscr,%0"
9820   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
9821    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
9823 (define_split
9824   [(set (reg:PSI FPSCR_REG)
9825         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9826   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
9827   [(set (match_dup 0) (match_dup 0))]
9828   "
9830   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
9831                                         gen_rtx_MEM (PSImode,
9832                                                  gen_rtx_POST_INC (Pmode,
9833                                                           operands[0]))));
9834   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9837 (define_split
9838   [(set (reg:PSI FPSCR_REG)
9839         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
9840   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9841   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
9842   "
9844   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
9845                                         gen_rtx_MEM (PSImode,
9846                                                  gen_rtx_POST_INC (Pmode,
9847                                                           operands[0]))));
9848   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
9851 ;; ??? This uses the fp unit, but has no type indicating that.
9852 ;; If we did that, this would either give a bogus latency or introduce
9853 ;; a bogus FIFO constraint.
9854 ;; Since this insn is currently only used for prologues/epilogues,
9855 ;; it is probably best to claim no function unit, which matches the
9856 ;; current setting.
9857 (define_insn "toggle_sz"
9858   [(set (reg:PSI FPSCR_REG)
9859         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
9860   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
9861   "fschg"
9862   [(set_attr "type" "fp") (set_attr "fp_set" "unknown")])
9864 ;; There's no way we can use it today, since optimize mode switching
9865 ;; doesn't enable us to know from which mode we're switching to the
9866 ;; mode it requests, to tell whether we can use a relative mode switch
9867 ;; (like toggle_pr) or an absolute switch (like loading fpscr from
9868 ;; memory).
9869 (define_insn "toggle_pr"
9870   [(set (reg:PSI FPSCR_REG)
9871         (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))]
9872   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE"
9873   "fpchg"
9874   [(set_attr "type" "fp")])
9876 (define_expand "addsf3"
9877   [(set (match_operand:SF 0 "arith_reg_operand" "")
9878         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
9879                  (match_operand:SF 2 "arith_reg_operand" "")))]
9880   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9881   "
9883   if (TARGET_SH2E)
9884     {
9885       expand_sf_binop (&gen_addsf3_i, operands);
9886       DONE;
9887     }
9890 (define_insn "*addsf3_media"
9891   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9892         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
9893                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9894   "TARGET_SHMEDIA_FPU"
9895   "fadd.s       %1, %2, %0"
9896   [(set_attr "type" "fparith_media")])
9898 (define_insn_and_split "unary_sf_op"
9899   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9900         (vec_select:V2SF
9901          (vec_concat:V2SF
9902           (vec_select:SF
9903            (match_dup 0)
9904            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
9905           (match_operator:SF 2 "unary_float_operator"
9906             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9907                             (parallel [(match_operand 4
9908                                         "const_int_operand" "n")]))]))
9909          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
9910   "TARGET_SHMEDIA_FPU"
9911   "#"
9912   "TARGET_SHMEDIA_FPU && reload_completed"
9913   [(set (match_dup 5) (match_dup 6))]
9914   "
9916   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9917   rtx op1 = gen_rtx_REG (SFmode,
9918                          (true_regnum (operands[1])
9919                           + (INTVAL (operands[4]) ^ endian)));
9921   operands[7] = gen_rtx_REG (SFmode,
9922                              (true_regnum (operands[0])
9923                               + (INTVAL (operands[3]) ^ endian)));
9924   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
9926   [(set_attr "type" "fparith_media")])
9928 (define_insn_and_split "binary_sf_op"
9929   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
9930         (vec_select:V2SF
9931          (vec_concat:V2SF
9932           (vec_select:SF
9933            (match_dup 0)
9934            (parallel [(match_operand 7 "const_int_operand" "n")]))
9935           (match_operator:SF 3 "binary_float_operator"
9936             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
9937                             (parallel [(match_operand 5
9938                                         "const_int_operand" "n")]))
9939              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
9940                             (parallel [(match_operand 6
9941                                         "const_int_operand" "n")]))]))
9942          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
9943   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
9944   "#"
9945   "&& reload_completed"
9946   [(set (match_dup 8) (match_dup 9))]
9947   "
9949   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
9950   rtx op1 = gen_rtx_REG (SFmode,
9951                          (true_regnum (operands[1])
9952                           + (INTVAL (operands[5]) ^ endian)));
9953   rtx op2 = gen_rtx_REG (SFmode,
9954                          (true_regnum (operands[2])
9955                           + (INTVAL (operands[6]) ^ endian)));
9957   operands[8] = gen_rtx_REG (SFmode,
9958                              (true_regnum (operands[0])
9959                               + (INTVAL (operands[4]) ^ endian)));
9960   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
9962   [(set_attr "type" "fparith_media")])
9964 (define_insn "addsf3_i"
9965   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9966         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
9967                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
9968    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
9969   "TARGET_SH2E"
9970   "fadd %2,%0"
9971   [(set_attr "type" "fp")
9972    (set_attr "fp_mode" "single")])
9974 (define_expand "subsf3"
9975   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
9976         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
9977                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
9978   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
9979   "
9981   if (TARGET_SH2E)
9982     {
9983       expand_sf_binop (&gen_subsf3_i, operands);
9984       DONE;
9985     }
9988 (define_insn "*subsf3_media"
9989   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9990         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
9991                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
9992   "TARGET_SHMEDIA_FPU"
9993   "fsub.s       %1, %2, %0"
9994   [(set_attr "type" "fparith_media")])
9996 (define_insn "subsf3_i"
9997   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9998         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
9999                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10000    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10001   "TARGET_SH2E"
10002   "fsub %2,%0"
10003   [(set_attr "type" "fp")
10004    (set_attr "fp_mode" "single")])
10006 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
10007 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
10008 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
10009 ;; SH3E, we use a separate insn for SH3E mulsf3.
10011 (define_expand "mulsf3"
10012   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10013         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
10014                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
10015   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10016   "
10018   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10019     expand_sf_binop (&gen_mulsf3_i4, operands);
10020   else if (TARGET_SH2E)
10021     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
10022   if (! TARGET_SHMEDIA)
10023     DONE;
10026 (define_insn "*mulsf3_media"
10027   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10028         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10029                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10030   "TARGET_SHMEDIA_FPU"
10031   "fmul.s       %1, %2, %0"
10032   [(set_attr "type" "fparith_media")])
10034 (define_insn "mulsf3_i4"
10035   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10036         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10037                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
10038    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10039   "TARGET_SH2E"
10040   "fmul %2,%0"
10041   [(set_attr "type" "fp")
10042    (set_attr "fp_mode" "single")])
10044 (define_insn "mulsf3_ie"
10045   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10046         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
10047                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10048   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10049   "fmul %2,%0"
10050   [(set_attr "type" "fp")])
10052 (define_insn "mac_media"
10053   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10054         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
10055                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10056                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
10057   "TARGET_SHMEDIA_FPU"
10058   "fmac.s %1, %2, %0"
10059   [(set_attr "type" "fparith_media")])
10061 (define_insn "*macsf3"
10062   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10063         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
10064                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
10065                  (match_operand:SF 3 "arith_reg_operand" "0")))
10066    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
10067   "TARGET_SH2E && ! TARGET_SH4"
10068   "fmac fr0,%2,%0"
10069   [(set_attr "type" "fp")
10070    (set_attr "fp_mode" "single")])
10072 (define_expand "divsf3"
10073   [(set (match_operand:SF 0 "arith_reg_operand" "")
10074         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
10075                 (match_operand:SF 2 "arith_reg_operand" "")))]
10076   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10077   "
10079   if (TARGET_SH2E)
10080     {
10081       expand_sf_binop (&gen_divsf3_i, operands);
10082       DONE;
10083     }
10086 (define_insn "*divsf3_media"
10087   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10088         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
10089                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10090   "TARGET_SHMEDIA_FPU"
10091   "fdiv.s       %1, %2, %0"
10092   [(set_attr "type" "fdiv_media")])
10094 (define_insn "divsf3_i"
10095   [(set (match_operand:SF 0 "arith_reg_dest" "=f")
10096         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
10097                  (match_operand:SF 2 "arith_reg_operand" "f")))
10098    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10099   "TARGET_SH2E"
10100   "fdiv %2,%0"
10101   [(set_attr "type" "fdiv")
10102    (set_attr "fp_mode" "single")])
10104 (define_insn "floatdisf2"
10105   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10106         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10107   "TARGET_SHMEDIA_FPU"
10108   "float.qs %1, %0"
10109   [(set_attr "type" "fpconv_media")])
10111 (define_expand "floatsisf2"
10112   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10113         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
10114   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10115   "
10117   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10118     {
10119       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10120       DONE;
10121     }
10124 (define_insn "*floatsisf2_media"
10125   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10126         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10127   "TARGET_SHMEDIA_FPU"
10128   "float.ls     %1, %0"
10129   [(set_attr "type" "fpconv_media")])
10131 (define_insn "floatsisf2_i4"
10132   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10133         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
10134    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10135   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10136   "float        %1,%0"
10137   [(set_attr "type" "fp")
10138    (set_attr "fp_mode" "single")])
10140 (define_insn "*floatsisf2_ie"
10141   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10142         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
10143   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10144   "float        %1,%0"
10145   [(set_attr "type" "fp")])
10147 (define_insn "fix_truncsfdi2"
10148   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10149         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10150   "TARGET_SHMEDIA_FPU"
10151   "ftrc.sq %1, %0"
10152   [(set_attr "type" "fpconv_media")])
10154 (define_expand "fix_truncsfsi2"
10155   [(set (match_operand:SI 0 "fpul_operand" "=y")
10156         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10157   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10158   "
10160   if (TARGET_SH4 || TARGET_SH2A_SINGLE)
10161     {
10162       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
10163       DONE;
10164     }
10167 (define_insn "*fix_truncsfsi2_media"
10168   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10169         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10170   "TARGET_SHMEDIA_FPU"
10171   "ftrc.sl      %1, %0"
10172   [(set_attr "type" "fpconv_media")])
10174 (define_insn "fix_truncsfsi2_i4"
10175   [(set (match_operand:SI 0 "fpul_operand" "=y")
10176         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10177    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10178   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10179   "ftrc %1,%0"
10180   [(set_attr "type" "ftrc_s")
10181    (set_attr "fp_mode" "single")])
10183 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
10184 ;; fix_truncsfsi2_i4.
10185 ;; (define_insn "fix_truncsfsi2_i4_2"
10186 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10187 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10188 ;;   (use (reg:PSI FPSCR_REG))
10189 ;;   (clobber (reg:SI FPUL_REG))]
10190 ;;  "TARGET_SH4"
10191 ;;  "#"
10192 ;;  [(set_attr "length" "4")
10193 ;;   (set_attr "fp_mode" "single")])
10195 ;;(define_split
10196 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10197 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
10198 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
10199 ;;   (clobber (reg:SI FPUL_REG))]
10200 ;;  "TARGET_SH4"
10201 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10202 ;;            (use (match_dup 2))])
10203 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
10205 (define_insn "*fixsfsi"
10206   [(set (match_operand:SI 0 "fpul_operand" "=y")
10207         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10208   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10209   "ftrc %1,%0"
10210   [(set_attr "type" "fp")])
10212 (define_insn "cmpgtsf_t"
10213   [(set (reg:SI T_REG)
10214         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10215                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10216   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10217   "fcmp/gt      %1,%0"
10218   [(set_attr "type" "fp")
10219    (set_attr "fp_mode" "single")])
10221 (define_insn "cmpeqsf_t"
10222   [(set (reg:SI T_REG)
10223         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10224                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10225   "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10226   "fcmp/eq      %1,%0"
10227   [(set_attr "type" "fp")
10228    (set_attr "fp_mode" "single")])
10230 (define_insn "ieee_ccmpeqsf_t"
10231   [(set (reg:SI T_REG)
10232         (ior:SI (reg:SI T_REG)
10233                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10234                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
10235   "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10236   "* return output_ieee_ccmpeq (insn, operands);"
10237   [(set_attr "length" "4")])
10240 (define_insn "cmpgtsf_t_i4"
10241   [(set (reg:SI T_REG)
10242         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10243                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10244    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10245   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10246   "fcmp/gt      %1,%0"
10247   [(set_attr "type" "fp")
10248    (set_attr "fp_mode" "single")])
10250 (define_insn "cmpeqsf_t_i4"
10251   [(set (reg:SI T_REG)
10252         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10253                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
10254    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10255   "(TARGET_SH4 || TARGET_SH2A_SINGLE)"
10256   "fcmp/eq      %1,%0"
10257   [(set_attr "type" "fp")
10258    (set_attr "fp_mode" "single")])
10260 (define_insn "*ieee_ccmpeqsf_t_4"
10261   [(set (reg:SI T_REG)
10262         (ior:SI (reg:SI T_REG)
10263                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
10264                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
10265    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10266   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)"
10267   "* return output_ieee_ccmpeq (insn, operands);"
10268   [(set_attr "length" "4")
10269    (set_attr "fp_mode" "single")])
10271 (define_insn "cmpeqsf_media"
10272   [(set (match_operand:DI 0 "register_operand" "=r")
10273         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10274                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10275   "TARGET_SHMEDIA_FPU"
10276   "fcmpeq.s     %1, %2, %0"
10277   [(set_attr "type" "fcmp_media")])
10279 (define_insn "cmpsieqsf_media"
10280   [(set (match_operand:SI 0 "register_operand" "=r")
10281         (eq:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10282                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10283   "TARGET_SHMEDIA_FPU"
10284   "fcmpeq.s     %1, %2, %0"
10285   [(set_attr "type" "fcmp_media")])
10287 (define_insn "cmpgtsf_media"
10288   [(set (match_operand:DI 0 "register_operand" "=r")
10289         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10290                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10291   "TARGET_SHMEDIA_FPU"
10292   "fcmpgt.s     %1, %2, %0"
10293   [(set_attr "type" "fcmp_media")])
10295 (define_insn "cmpgesf_media"
10296   [(set (match_operand:DI 0 "register_operand" "=r")
10297         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10298                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10299   "TARGET_SHMEDIA_FPU"
10300   "fcmpge.s     %1, %2, %0"
10301   [(set_attr "type" "fcmp_media")])
10303 (define_insn "cmpunsf_media"
10304   [(set (match_operand:DI 0 "register_operand" "=r")
10305         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
10306                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
10307   "TARGET_SHMEDIA_FPU"
10308   "fcmpun.s     %1, %2, %0"
10309   [(set_attr "type" "fcmp_media")])
10311 (define_expand "cmpsf"
10312   [(set (reg:SI T_REG)
10313         (compare (match_operand:SF 0 "arith_operand" "")
10314                  (match_operand:SF 1 "arith_operand" "")))]
10315   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10316   "
10318   sh_compare_op0 = operands[0];
10319   sh_compare_op1 = operands[1];
10320   DONE;
10323 (define_expand "negsf2"
10324   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10325         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10326   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10327   "
10329   if (TARGET_SH2E)
10330     {
10331       expand_sf_unop (&gen_negsf2_i, operands);
10332       DONE;
10333     }
10336 (define_insn "*negsf2_media"
10337   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10338         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10339   "TARGET_SHMEDIA_FPU"
10340   "fneg.s       %1, %0"
10341   [(set_attr "type" "fmove_media")])
10343 (define_insn "negsf2_i"
10344   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10345         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10346    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10347   "TARGET_SH2E"
10348   "fneg %0"
10349   [(set_attr "type" "fmove")
10350    (set_attr "fp_mode" "single")])
10352 (define_expand "sqrtsf2"
10353   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10354         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10355   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
10356   "
10358   if (TARGET_SH3E)
10359     {
10360       expand_sf_unop (&gen_sqrtsf2_i, operands);
10361       DONE;
10362     }
10365 (define_insn "*sqrtsf2_media"
10366   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10367         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10368   "TARGET_SHMEDIA_FPU"
10369   "fsqrt.s      %1, %0"
10370   [(set_attr "type" "fdiv_media")])
10372 (define_insn "sqrtsf2_i"
10373   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10374         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10375    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10376   "TARGET_SH3E"
10377   "fsqrt        %0"
10378   [(set_attr "type" "fdiv")
10379    (set_attr "fp_mode" "single")])
10381 (define_insn "rsqrtsf2"
10382   [(set (match_operand:SF 0 "register_operand" "=f")
10383         (div:SF (match_operand:SF 1 "immediate_operand" "i")
10384                 (sqrt:SF (match_operand:SF 2 "register_operand" "0"))))
10385    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10386   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10387    && operands[1] == CONST1_RTX (SFmode)"
10388   "fsrra        %0"
10389   [(set_attr "type" "fsrra")
10390    (set_attr "fp_mode" "single")])
10392 (define_insn "fsca"
10393   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
10394         (vec_concat:V2SF
10395          (unspec:SF [(mult:SF
10396                       (float:SF (match_operand:SI 1 "fpul_operand" "y"))
10397                       (match_operand:SF 2 "immediate_operand" "i"))
10398                     ] UNSPEC_FSINA)
10399          (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
10400                     ] UNSPEC_FCOSA)))
10401    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10402   "TARGET_SH4A_FP && flag_unsafe_math_optimizations
10403    && operands[2] == sh_fsca_int2sf ()"
10404   "fsca fpul,%d0"
10405   [(set_attr "type" "fsca")
10406    (set_attr "fp_mode" "single")])
10408 (define_expand "sinsf2"
10409   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10410         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10411                    UNSPEC_FSINA))]
10412   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10413   "
10415   rtx scaled = gen_reg_rtx (SFmode);
10416   rtx truncated = gen_reg_rtx (SImode);
10417   rtx fsca = gen_reg_rtx (V2SFmode);
10418   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10420   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10421   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10422   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10423                           get_fpscr_rtx ()));
10424   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 0));
10425   DONE;
10428 (define_expand "cossf2"
10429   [(set (match_operand:SF 0 "nonimmediate_operand" "")
10430         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "")]
10431                    UNSPEC_FCOSA))]
10432   "TARGET_SH4A_FP && flag_unsafe_math_optimizations"
10433   "
10435   rtx scaled = gen_reg_rtx (SFmode);
10436   rtx truncated = gen_reg_rtx (SImode);
10437   rtx fsca = gen_reg_rtx (V2SFmode);
10438   rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ());
10440   emit_sf_insn (gen_mulsf3 (scaled, operands[1], scale_reg));
10441   emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled));
10442   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10443                           get_fpscr_rtx ()));
10444   emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4));
10445   DONE;
10448 (define_expand "sindf2"
10449   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10450         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10451                    UNSPEC_FSINA))]
10452   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10453   "
10455   rtx scaled = gen_reg_rtx (DFmode);
10456   rtx truncated = gen_reg_rtx (SImode);
10457   rtx fsca = gen_reg_rtx (V2SFmode);
10458   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10459   rtx sfresult = gen_reg_rtx (SFmode);
10461   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10462   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10463   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10464                           get_fpscr_rtx ()));
10465   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 0));
10466   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10467   DONE;
10470 (define_expand "cosdf2"
10471   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10472         (unspec:DF [(match_operand:DF 1 "fp_arith_reg_operand" "")]
10473                    UNSPEC_FCOSA))]
10474   "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE && flag_unsafe_math_optimizations"
10475   "
10477   rtx scaled = gen_reg_rtx (DFmode);
10478   rtx truncated = gen_reg_rtx (SImode);
10479   rtx fsca = gen_reg_rtx (V2SFmode);
10480   rtx scale_reg = force_reg (DFmode, sh_fsca_df2int ());
10481   rtx sfresult = gen_reg_rtx (SFmode);
10483   emit_df_insn (gen_muldf3 (scaled, operands[1], scale_reg));
10484   emit_df_insn (gen_fix_truncdfsi2 (truncated, scaled));
10485   emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (),
10486                           get_fpscr_rtx ()));
10487   emit_move_insn (sfresult, gen_rtx_SUBREG (SFmode, fsca, 4));
10488   emit_df_insn (gen_extendsfdf2 (operands[0], sfresult));
10489   DONE;
10492 (define_expand "abssf2"
10493   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
10494         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
10495   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
10496   "
10498   if (TARGET_SH2E)
10499     {
10500       expand_sf_unop (&gen_abssf2_i, operands);
10501       DONE;
10502     }
10505 (define_insn "*abssf2_media"
10506   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10507         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10508   "TARGET_SHMEDIA_FPU"
10509   "fabs.s       %1, %0"
10510   [(set_attr "type" "fmove_media")])
10512 (define_insn "abssf2_i"
10513   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10514         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
10515    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10516   "TARGET_SH2E"
10517   "fabs %0"
10518   [(set_attr "type" "fmove")
10519    (set_attr "fp_mode" "single")])
10521 (define_expand "adddf3"
10522   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10523         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10524                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10525   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10526   "
10528   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10529     {
10530       expand_df_binop (&gen_adddf3_i, operands);
10531       DONE;
10532     }
10535 (define_insn "*adddf3_media"
10536   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10537         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10538                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10539   "TARGET_SHMEDIA_FPU"
10540   "fadd.d       %1, %2, %0"
10541   [(set_attr "type" "dfparith_media")])
10543 (define_insn "adddf3_i"
10544   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10545         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10546                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10547    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10548   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10549   "fadd %2,%0"
10550   [(set_attr "type" "dfp_arith")
10551    (set_attr "fp_mode" "double")])
10553 (define_expand "subdf3"
10554   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10555         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10556                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10557   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10558   "
10560   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10561     {
10562       expand_df_binop (&gen_subdf3_i, operands);
10563       DONE;
10564     }
10567 (define_insn "*subdf3_media"
10568   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10569         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10570                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10571   "TARGET_SHMEDIA_FPU"
10572   "fsub.d       %1, %2, %0"
10573   [(set_attr "type" "dfparith_media")])
10575 (define_insn "subdf3_i"
10576   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10577         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10578                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10579    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10580   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10581   "fsub %2,%0"
10582   [(set_attr "type" "dfp_arith")
10583    (set_attr "fp_mode" "double")])
10585 (define_expand "muldf3"
10586   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10587         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10588                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10589   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10590   "
10592   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10593     {
10594       expand_df_binop (&gen_muldf3_i, operands);
10595       DONE;
10596     }
10599 (define_insn "*muldf3_media"
10600   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10601         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
10602                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10603   "TARGET_SHMEDIA_FPU"
10604   "fmul.d       %1, %2, %0"
10605   [(set_attr "type" "dfmul_media")])
10607 (define_insn "muldf3_i"
10608   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10609         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
10610                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10611    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10612   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10613   "fmul %2,%0"
10614   [(set_attr "type" "dfp_arith")
10615    (set_attr "fp_mode" "double")])
10617 (define_expand "divdf3"
10618   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10619         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
10620                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
10621   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10622   "
10624   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10625     {
10626       expand_df_binop (&gen_divdf3_i, operands);
10627       DONE;
10628     }
10631 (define_insn "*divdf3_media"
10632   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10633         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
10634                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10635   "TARGET_SHMEDIA_FPU"
10636   "fdiv.d       %1, %2, %0"
10637   [(set_attr "type" "dfdiv_media")])
10639 (define_insn "divdf3_i"
10640   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10641         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
10642                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
10643    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
10644   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10645   "fdiv %2,%0"
10646   [(set_attr "type" "dfdiv")
10647    (set_attr "fp_mode" "double")])
10649 (define_insn "floatdidf2"
10650   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10651         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
10652   "TARGET_SHMEDIA_FPU"
10653   "float.qd     %1, %0"
10654   [(set_attr "type" "dfpconv_media")])
10656 (define_expand "floatsidf2"
10657   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10658         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
10659   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10660   "
10662   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10663     {
10664       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
10665                                       get_fpscr_rtx ()));
10666       DONE;
10667     }
10670 (define_insn "*floatsidf2_media"
10671   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10672         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
10673   "TARGET_SHMEDIA_FPU"
10674   "float.ld     %1, %0"
10675   [(set_attr "type" "dfpconv_media")])
10677 (define_insn "floatsidf2_i"
10678   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10679         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
10680    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10681   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10682   "float        %1,%0"
10683   [(set_attr "type" "dfp_conv")
10684    (set_attr "fp_mode" "double")])
10686 (define_insn "fix_truncdfdi2"
10687   [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f")
10688         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10689   "TARGET_SHMEDIA_FPU"
10690   "ftrc.dq      %1, %0"
10691   [(set_attr "type" "dfpconv_media")])
10693 (define_expand "fix_truncdfsi2"
10694   [(set (match_operand:SI 0 "fpul_operand" "")
10695         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10696   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10697   "
10699   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10700     {
10701       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
10702                                           get_fpscr_rtx ()));
10703       DONE;
10704     }
10707 (define_insn "*fix_truncdfsi2_media"
10708   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
10709         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10710   "TARGET_SHMEDIA_FPU"
10711   "ftrc.dl      %1, %0"
10712   [(set_attr "type" "dfpconv_media")])
10714 (define_insn "fix_truncdfsi2_i"
10715   [(set (match_operand:SI 0 "fpul_operand" "=y")
10716         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10717    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10718   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10719   "ftrc %1,%0"
10720   [(set_attr "type" "dfp_conv")
10721    (set_attr "dfp_comp" "no")
10722    (set_attr "fp_mode" "double")])
10724 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
10725 ;; fix_truncdfsi2_i.
10726 ;; (define_insn "fix_truncdfsi2_i4"
10727 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10728 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10729 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10730 ;;    (clobber (reg:SI FPUL_REG))]
10731 ;;   "TARGET_SH4"
10732 ;;   "#"
10733 ;;   [(set_attr "length" "4")
10734 ;;    (set_attr "fp_mode" "double")])
10736 ;; (define_split
10737 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
10738 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
10739 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
10740 ;;    (clobber (reg:SI FPUL_REG))]
10741 ;;   "TARGET_SH4"
10742 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
10743 ;;            (use (match_dup 2))])
10744 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
10746 (define_insn "cmpgtdf_t"
10747   [(set (reg:SI T_REG)
10748         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
10749                (match_operand:DF 1 "arith_reg_operand" "f")))
10750    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10751   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10752   "fcmp/gt      %1,%0"
10753   [(set_attr "type" "dfp_cmp")
10754    (set_attr "fp_mode" "double")])
10756 (define_insn "cmpeqdf_t"
10757   [(set (reg:SI T_REG)
10758         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10759                (match_operand:DF 1 "arith_reg_operand" "f")))
10760    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10761   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10762   "fcmp/eq      %1,%0"
10763   [(set_attr "type" "dfp_cmp")
10764    (set_attr "fp_mode" "double")])
10766 (define_insn "*ieee_ccmpeqdf_t"
10767   [(set (reg:SI T_REG)
10768         (ior:SI (reg:SI T_REG)
10769                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
10770                        (match_operand:DF 1 "arith_reg_operand" "f"))))
10771    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10772   "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10773   "* return output_ieee_ccmpeq (insn, operands);"
10774   [(set_attr "length" "4")
10775    (set_attr "fp_mode" "double")])
10777 (define_insn "cmpeqdf_media"
10778   [(set (match_operand:DI 0 "register_operand" "=r")
10779         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10780                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10781   "TARGET_SHMEDIA_FPU"
10782   "fcmpeq.d     %1,%2,%0"
10783   [(set_attr "type" "fcmp_media")])
10785 (define_insn "cmpsieqdf_media"
10786   [(set (match_operand:SI 0 "register_operand" "=r")
10787         (eq:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10788                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10789   "TARGET_SHMEDIA_FPU"
10790   "fcmpeq.d     %1,%2,%0"
10791   [(set_attr "type" "fcmp_media")])
10793 (define_insn "cmpgtdf_media"
10794   [(set (match_operand:DI 0 "register_operand" "=r")
10795         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10796                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10797   "TARGET_SHMEDIA_FPU"
10798   "fcmpgt.d     %1,%2,%0"
10799   [(set_attr "type" "fcmp_media")])
10801 (define_insn "cmpgedf_media"
10802   [(set (match_operand:DI 0 "register_operand" "=r")
10803         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10804                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10805   "TARGET_SHMEDIA_FPU"
10806   "fcmpge.d     %1,%2,%0"
10807   [(set_attr "type" "fcmp_media")])
10809 (define_insn "cmpundf_media"
10810   [(set (match_operand:DI 0 "register_operand" "=r")
10811         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
10812                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
10813   "TARGET_SHMEDIA_FPU"
10814   "fcmpun.d     %1,%2,%0"
10815   [(set_attr "type" "fcmp_media")])
10817 (define_expand "cmpdf"
10818   [(set (reg:SI T_REG)
10819         (compare (match_operand:DF 0 "arith_operand" "")
10820                  (match_operand:DF 1 "arith_operand" "")))]
10821   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10822   "
10824   sh_compare_op0 = operands[0];
10825   sh_compare_op1 = operands[1];
10826   DONE;
10829 (define_expand "negdf2"
10830   [(set (match_operand:DF 0 "arith_reg_operand" "")
10831         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10832   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10833   "
10835   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10836     {
10837       expand_df_unop (&gen_negdf2_i, operands);
10838       DONE;
10839     }
10842 (define_insn "*negdf2_media"
10843   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10844         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10845   "TARGET_SHMEDIA_FPU"
10846   "fneg.d       %1, %0"
10847   [(set_attr "type" "fmove_media")])
10849 (define_insn "negdf2_i"
10850   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10851         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10852    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10853   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10854   "fneg %0"
10855   [(set_attr "type" "fmove")
10856    (set_attr "fp_mode" "double")])
10858 (define_expand "sqrtdf2"
10859   [(set (match_operand:DF 0 "arith_reg_operand" "")
10860         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10861   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10862   "
10864   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10865     {
10866       expand_df_unop (&gen_sqrtdf2_i, operands);
10867       DONE;
10868     }
10871 (define_insn "*sqrtdf2_media"
10872   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10873         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10874   "TARGET_SHMEDIA_FPU"
10875   "fsqrt.d      %1, %0"
10876   [(set_attr "type" "dfdiv_media")])
10878 (define_insn "sqrtdf2_i"
10879   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10880         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10881    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10882   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10883   "fsqrt        %0"
10884   [(set_attr "type" "dfdiv")
10885    (set_attr "fp_mode" "double")])
10887 (define_expand "absdf2"
10888   [(set (match_operand:DF 0 "arith_reg_operand" "")
10889         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
10890   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10891   "
10893   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10894     {
10895       expand_df_unop (&gen_absdf2_i, operands);
10896       DONE;
10897     }
10900 (define_insn "*absdf2_media"
10901   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10902         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10903   "TARGET_SHMEDIA_FPU"
10904   "fabs.d       %1, %0"
10905   [(set_attr "type" "fmove_media")])
10907 (define_insn "absdf2_i"
10908   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10909         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")))
10910    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10911   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10912   "fabs %0"
10913   [(set_attr "type" "fmove")
10914    (set_attr "fp_mode" "double")])
10916 (define_expand "extendsfdf2"
10917   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
10918         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
10919   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10920   "
10922   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10923     {
10924       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
10925                                         get_fpscr_rtx ()));
10926       DONE;
10927     }
10930 (define_insn "*extendsfdf2_media"
10931   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10932         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
10933   "TARGET_SHMEDIA_FPU"
10934   "fcnv.sd      %1, %0"
10935   [(set_attr "type" "dfpconv_media")])
10937 (define_insn "extendsfdf2_i4"
10938   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
10939         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
10940    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10941   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10942   "fcnvsd  %1,%0"
10943   [(set_attr "type" "fp")
10944    (set_attr "fp_mode" "double")])
10946 (define_expand "truncdfsf2"
10947   [(set (match_operand:SF 0 "fpul_operand" "")
10948         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
10949   "(TARGET_SH4 || TARGET_SH2A_DOUBLE) || TARGET_SHMEDIA_FPU"
10950   "
10952   if (TARGET_SH4 || TARGET_SH2A_DOUBLE)
10953     {
10954       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
10955                                        get_fpscr_rtx ()));
10956       DONE;
10957     }
10960 (define_insn "*truncdfsf2_media"
10961   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10962         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
10963   "TARGET_SHMEDIA_FPU"
10964   "fcnv.ds      %1, %0"
10965   [(set_attr "type" "dfpconv_media")])
10967 (define_insn "truncdfsf2_i4"
10968   [(set (match_operand:SF 0 "fpul_operand" "=y")
10969         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
10970    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
10971   "(TARGET_SH4 || TARGET_SH2A_DOUBLE)"
10972   "fcnvds  %1,%0"
10973   [(set_attr "type" "fp")
10974    (set_attr "fp_mode" "double")])
10976 ;; Bit field extract patterns.  These give better code for packed bitfields,
10977 ;; because they allow auto-increment addresses to be generated.
10979 (define_expand "insv"
10980   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
10981                          (match_operand:SI 1 "immediate_operand" "")
10982                          (match_operand:SI 2 "immediate_operand" ""))
10983         (match_operand:SI 3 "general_operand" ""))]
10984   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
10985   "
10987   rtx addr_target, orig_address, shift_reg, qi_val;
10988   HOST_WIDE_INT bitsize, size, v = 0;
10989   rtx x = operands[3];
10991   /* ??? expmed doesn't care for non-register predicates.  */
10992   if (! memory_operand (operands[0], VOIDmode)
10993       || ! immediate_operand (operands[1], VOIDmode)
10994       || ! immediate_operand (operands[2], VOIDmode)
10995       || ! general_operand (x, VOIDmode))
10996     FAIL;
10997   /* If this isn't a 16 / 24 / 32 bit field, or if
10998      it doesn't start on a byte boundary, then fail.  */
10999   bitsize = INTVAL (operands[1]);
11000   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
11001       || (INTVAL (operands[2]) % 8) != 0)
11002     FAIL;
11004   size = bitsize / 8;
11005   orig_address = XEXP (operands[0], 0);
11006   shift_reg = gen_reg_rtx (SImode);
11007   if (GET_CODE (x) == CONST_INT)
11008     {
11009       v = INTVAL (x);
11010       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
11011     }
11012   else
11013     {
11014       emit_insn (gen_movsi (shift_reg, operands[3]));
11015       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11016     }
11017   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
11019   operands[0] = replace_equiv_address (operands[0], addr_target);
11020   emit_insn (gen_movqi (operands[0], qi_val));
11022   while (size -= 1)
11023     {
11024       if (GET_CODE (x) == CONST_INT)
11025         qi_val
11026           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
11027       else
11028         {
11029           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
11030           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
11031         }
11032       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
11033       emit_insn (gen_movqi (operands[0], qi_val));
11034     }
11036   DONE;
11039 (define_insn "movua"
11040   [(set (match_operand:SI 0 "register_operand" "=z")
11041         (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>")
11042                          (const_int 32) (const_int 0)))]
11043   "TARGET_SH4A_ARCH"
11044   "movua.l      %1,%0"
11045   [(set_attr "type" "movua")])
11047 ;; We shouldn't need this, but cse replaces increments with references
11048 ;; to other regs before flow has a chance to create post_inc
11049 ;; addressing modes, and only postreload's cse_move2add brings the
11050 ;; increments back to a usable form.
11051 (define_peephole2
11052   [(set (match_operand:SI 0 "register_operand" "")
11053         (sign_extract:SI (mem:SI (match_operand:SI 1 "register_operand" ""))
11054                          (const_int 32) (const_int 0)))
11055    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11056   "TARGET_SH4A_ARCH && REGNO (operands[0]) != REGNO (operands[1])"
11057   [(set (match_operand:SI 0 "register_operand" "")
11058         (sign_extract:SI (mem:SI (post_inc:SI
11059                                   (match_operand:SI 1 "register_operand" "")))
11060                          (const_int 32) (const_int 0)))]
11061   "")
11063 (define_expand "extv"
11064   [(set (match_operand:SI 0 "register_operand" "")
11065         (sign_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11066                          (match_operand 2 "const_int_operand" "")
11067                          (match_operand 3 "const_int_operand" "")))]
11068   "TARGET_SH4A_ARCH"
11070   if (TARGET_SH4A_ARCH
11071       && INTVAL (operands[2]) == 32
11072       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11073       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11074     {
11075       emit_insn (gen_movua (operands[0],
11076                             adjust_address (operands[1], SImode, 0)));
11077       DONE;
11078     }
11080   FAIL;
11083 (define_expand "extzv"
11084   [(set (match_operand:SI 0 "register_operand" "")
11085         (zero_extract:SI (match_operand:QI 1 "unaligned_load_operand" "")
11086                          (match_operand 2 "const_int_operand" "")
11087                          (match_operand 3 "const_int_operand" "")))]
11088   "TARGET_SH4A_ARCH"
11090   if (TARGET_SH4A_ARCH
11091       && INTVAL (operands[2]) == 32
11092       && INTVAL (operands[3]) == -24 * (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
11093       && GET_CODE (operands[1]) == MEM && MEM_ALIGN (operands[1]) < 32)
11094     {
11095       emit_insn (gen_movua (operands[0],
11096                             adjust_address (operands[1], SImode, 0)));
11097       DONE;
11098     }
11100   FAIL;
11104 ;; -------------------------------------------------------------------------
11105 ;; Peepholes
11106 ;; -------------------------------------------------------------------------
11108 ;; This matches cases where a stack pointer increment at the start of the
11109 ;; epilogue combines with a stack slot read loading the return value.
11111 (define_peephole
11112   [(set (match_operand:SI 0 "arith_reg_operand" "")
11113         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
11114    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
11115   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
11116   "mov.l        @%1+,%0")
11118 ;; See the comment on the dt combiner pattern above.
11120 (define_peephole
11121   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
11122         (plus:SI (match_dup 0)
11123                  (const_int -1)))
11124    (set (reg:SI T_REG)
11125         (eq:SI (match_dup 0)
11126                (const_int 0)))]
11127   "TARGET_SH2"
11128   "dt   %0")
11130 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
11131 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
11132 ;; reload when the constant is too large for a reg+offset address.
11134 ;; ??? We would get much better code if this was done in reload.  This would
11135 ;; require modifying find_reloads_address to recognize that if the constant
11136 ;; is out-of-range for an immediate add, then we get better code by reloading
11137 ;; the constant into a register than by reloading the sum into a register,
11138 ;; since the former is one instruction shorter if the address does not need
11139 ;; to be offsettable.  Unfortunately this does not work, because there is
11140 ;; only one register, r0, that can be used as an index register.  This register
11141 ;; is also the function return value register.  So, if we try to force reload
11142 ;; to use double-reg addresses, then we end up with some instructions that
11143 ;; need to use r0 twice.  The only way to fix this is to change the calling
11144 ;; convention so that r0 is not used to return values.
11146 (define_peephole
11147   [(set (match_operand:SI 0 "register_operand" "=r")
11148         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11149    (set (mem:SI (match_dup 0))
11150         (match_operand:SI 2 "general_movsrc_operand" ""))]
11151   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11152   "mov.l        %2,@(%0,%1)")
11154 (define_peephole
11155   [(set (match_operand:SI 0 "register_operand" "=r")
11156         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11157    (set (match_operand:SI 2 "general_movdst_operand" "")
11158         (mem:SI (match_dup 0)))]
11159   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11160   "mov.l        @(%0,%1),%2")
11162 (define_peephole
11163   [(set (match_operand:SI 0 "register_operand" "=r")
11164         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11165    (set (mem:HI (match_dup 0))
11166         (match_operand:HI 2 "general_movsrc_operand" ""))]
11167   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11168   "mov.w        %2,@(%0,%1)")
11170 (define_peephole
11171   [(set (match_operand:SI 0 "register_operand" "=r")
11172         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11173    (set (match_operand:HI 2 "general_movdst_operand" "")
11174         (mem:HI (match_dup 0)))]
11175   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11176   "mov.w        @(%0,%1),%2")
11178 (define_peephole
11179   [(set (match_operand:SI 0 "register_operand" "=r")
11180         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11181    (set (mem:QI (match_dup 0))
11182         (match_operand:QI 2 "general_movsrc_operand" ""))]
11183   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11184   "mov.b        %2,@(%0,%1)")
11186 (define_peephole
11187   [(set (match_operand:SI 0 "register_operand" "=r")
11188         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11189    (set (match_operand:QI 2 "general_movdst_operand" "")
11190         (mem:QI (match_dup 0)))]
11191   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
11192   "mov.b        @(%0,%1),%2")
11194 (define_peephole
11195   [(set (match_operand:SI 0 "register_operand" "=r")
11196         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11197    (set (mem:SF (match_dup 0))
11198         (match_operand:SF 2 "general_movsrc_operand" ""))]
11199   "TARGET_SH1 && REGNO (operands[0]) == 0
11200    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11201        || (GET_CODE (operands[2]) == SUBREG
11202            && REGNO (SUBREG_REG (operands[2])) < 16))
11203    && reg_unused_after (operands[0], insn)"
11204   "mov.l        %2,@(%0,%1)")
11206 (define_peephole
11207   [(set (match_operand:SI 0 "register_operand" "=r")
11208         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11209    (set (match_operand:SF 2 "general_movdst_operand" "")
11211         (mem:SF (match_dup 0)))]
11212   "TARGET_SH1 && REGNO (operands[0]) == 0
11213    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
11214        || (GET_CODE (operands[2]) == SUBREG
11215            && REGNO (SUBREG_REG (operands[2])) < 16))
11216    && reg_unused_after (operands[0], insn)"
11217   "mov.l        @(%0,%1),%2")
11219 (define_peephole
11220   [(set (match_operand:SI 0 "register_operand" "=r")
11221         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11222    (set (mem:SF (match_dup 0))
11223         (match_operand:SF 2 "general_movsrc_operand" ""))]
11224   "TARGET_SH2E && REGNO (operands[0]) == 0
11225    && ((GET_CODE (operands[2]) == REG
11226         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11227        || (GET_CODE (operands[2]) == SUBREG
11228            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11229    && reg_unused_after (operands[0], insn)"
11230   "fmov{.s|}    %2,@(%0,%1)")
11232 (define_peephole
11233   [(set (match_operand:SI 0 "register_operand" "=r")
11234         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
11235    (set (match_operand:SF 2 "general_movdst_operand" "")
11237         (mem:SF (match_dup 0)))]
11238   "TARGET_SH2E && REGNO (operands[0]) == 0
11239    && ((GET_CODE (operands[2]) == REG
11240         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
11241        || (GET_CODE (operands[2]) == SUBREG
11242            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
11243    && reg_unused_after (operands[0], insn)"
11244   "fmov{.s|}    @(%0,%1),%2")
11246 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
11247 (define_insn "sp_switch_1"
11248   [(const_int 1)]
11249   "TARGET_SH1"
11250   "*
11252   rtx xoperands[1];
11254   xoperands[0] = sp_switch;
11255   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
11256   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
11257   return \"mov r0,r15\";
11259   [(set_attr "length" "10")])
11261 ;; Switch back to the original stack for interrupt functions with the
11262 ;; sp_switch attribute.  */
11263 (define_insn "sp_switch_2"
11264   [(const_int 2)]
11265   "TARGET_SH1"
11266   "mov.l @r15+,r15\;mov.l @r15+,r0"
11267   [(set_attr "length" "4")])
11269 ;; Integer vector moves
11271 (define_expand "movv8qi"
11272   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
11273         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
11274   "TARGET_SHMEDIA"
11275   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
11277 (define_insn "movv8qi_i"
11278   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
11279         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11280   "TARGET_SHMEDIA
11281    && (register_operand (operands[0], V8QImode)
11282        || sh_register_operand (operands[1], V8QImode))"
11283   "@
11284         add     %1, r63, %0
11285         movi    %1, %0
11286         #
11287         ld%M1.q %m1, %0
11288         st%M0.q %m0, %N1"
11289   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11290    (set_attr "length" "4,4,16,4,4")])
11292 (define_split
11293   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
11294         (subreg:V8QI (const_int 0) 0))]
11295   "TARGET_SHMEDIA"
11296   [(set (match_dup 0)
11297         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
11298                             (const_int 0) (const_int 0) (const_int 0)
11299                             (const_int 0) (const_int 0)]))])
11301 (define_split
11302   [(set (match_operand 0 "arith_reg_dest" "")
11303         (match_operand 1 "sh_rep_vec" ""))]
11304   "TARGET_SHMEDIA && reload_completed
11305    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11306    && sh_vector_mode_supported_p (GET_MODE (operands[0]))
11307    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
11308    && (XVECEXP (operands[1], 0, 0) != const0_rtx
11309        || XVECEXP (operands[1], 0, 1) != const0_rtx)
11310    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
11311        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
11312   [(set (match_dup 0) (match_dup 1))
11313    (match_dup 2)]
11314   "
11316   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
11317   rtx elt1 = XVECEXP (operands[1], 0, 1);
11319   if (unit_size > 2)
11320     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
11321   else
11322     {
11323       if (unit_size < 2)
11324         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
11325       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
11326     }
11327   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
11328   operands[1] = XVECEXP (operands[1], 0, 0);
11329   if (unit_size < 2)
11330     {
11331       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
11332         operands[1]
11333           = GEN_INT (TARGET_LITTLE_ENDIAN
11334                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
11335                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
11336       else
11337         {
11338           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
11339           operands[1]
11340             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
11341         }
11342     }
11345 (define_split
11346   [(set (match_operand 0 "arith_reg_dest" "")
11347         (match_operand 1 "sh_const_vec" ""))]
11348   "TARGET_SHMEDIA && reload_completed
11349    && GET_MODE (operands[0]) == GET_MODE (operands[1])
11350    && sh_vector_mode_supported_p (GET_MODE (operands[0]))"
11351   [(set (match_dup 0) (match_dup 1))]
11352   "
11354   rtx v = operands[1];
11355   enum machine_mode new_mode
11356     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
11358   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
11359   operands[1]
11360     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
11363 (define_expand "movv2hi"
11364   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
11365         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
11366   "TARGET_SHMEDIA"
11367   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
11369 (define_insn "movv2hi_i"
11370   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11371         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11372   "TARGET_SHMEDIA
11373    && (register_operand (operands[0], V2HImode)
11374        || sh_register_operand (operands[1], V2HImode))"
11375   "@
11376         add.l   %1, r63, %0
11377         movi    %1, %0
11378         #
11379         ld%M1.l %m1, %0
11380         st%M0.l %m0, %N1"
11381   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11382    (set_attr "length" "4,4,16,4,4")
11383    (set (attr "highpart")
11384         (cond [(ne (symbol_ref "sh_contains_memref_p (insn)") (const_int 0))
11385                (const_string "user")]
11386               (const_string "ignore")))])
11388 (define_expand "movv4hi"
11389   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
11390         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
11391   "TARGET_SHMEDIA"
11392   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
11394 (define_insn "movv4hi_i"
11395   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
11396         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11397   "TARGET_SHMEDIA
11398    && (register_operand (operands[0], V4HImode)
11399        || sh_register_operand (operands[1], V4HImode))"
11400   "@
11401         add     %1, r63, %0
11402         movi    %1, %0
11403         #
11404         ld%M1.q %m1, %0
11405         st%M0.q %m0, %N1"
11406   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11407    (set_attr "length" "4,4,16,4,4")
11408    (set_attr "highpart" "depend")])
11410 (define_expand "movv2si"
11411   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
11412         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
11413   "TARGET_SHMEDIA"
11414   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
11416 (define_insn "movv2si_i"
11417   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
11418         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
11419   "TARGET_SHMEDIA
11420    && (register_operand (operands[0], V2SImode)
11421        || sh_register_operand (operands[1], V2SImode))"
11422   "@
11423         add     %1, r63, %0
11424         #
11425         #
11426         ld%M1.q %m1, %0
11427         st%M0.q %m0, %N1"
11428   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
11429    (set_attr "length" "4,4,16,4,4")
11430    (set_attr "highpart" "depend")])
11432 ;; Multimedia Intrinsics
11434 (define_insn "absv2si2"
11435   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11436         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
11437   "TARGET_SHMEDIA"
11438   "mabs.l       %1, %0"
11439   [(set_attr "type" "mcmp_media")
11440    (set_attr "highpart" "depend")])
11442 (define_insn "absv4hi2"
11443   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11444         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
11445   "TARGET_SHMEDIA"
11446   "mabs.w       %1, %0"
11447   [(set_attr "type" "mcmp_media")
11448    (set_attr "highpart" "depend")])
11450 (define_insn "addv2si3"
11451   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11452         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11453                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11454   "TARGET_SHMEDIA"
11455   "madd.l       %1, %2, %0"
11456   [(set_attr "type" "arith_media")
11457    (set_attr "highpart" "depend")])
11459 (define_insn "addv4hi3"
11460   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11461         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11462                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11463   "TARGET_SHMEDIA"
11464   "madd.w       %1, %2, %0"
11465   [(set_attr "type" "arith_media")
11466    (set_attr "highpart" "depend")])
11468 (define_insn_and_split "addv2hi3"
11469   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
11470         (plus:V2HI (match_operand:V2HI 1 "extend_reg_operand" "%r")
11471                    (match_operand:V2HI 2 "extend_reg_operand" "r")))]
11472   "TARGET_SHMEDIA"
11473   "#"
11474   "TARGET_SHMEDIA"
11475   [(const_int 0)]
11476   "
11478   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
11479   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
11480   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
11481   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
11482   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
11484   emit_insn (gen_addv4hi3 (v4hi_dst, src0, src1));
11485   emit_insn (gen_truncdisi2 (si_dst, di_dst));
11486   DONE;
11488   [(set_attr "highpart" "must_split")])
11490 (define_insn "ssaddv2si3"
11491   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11492         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
11493                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11494   "TARGET_SHMEDIA"
11495   "madds.l      %1, %2, %0"
11496   [(set_attr "type" "mcmp_media")
11497    (set_attr "highpart" "depend")])
11499 (define_insn "usaddv8qi3"
11500   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11501         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
11502                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
11503   "TARGET_SHMEDIA"
11504   "madds.ub     %1, %2, %0"
11505   [(set_attr "type" "mcmp_media")
11506    (set_attr "highpart" "depend")])
11508 (define_insn "ssaddv4hi3"
11509   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11510         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
11511                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11512   "TARGET_SHMEDIA"
11513   "madds.w      %1, %2, %0"
11514   [(set_attr "type" "mcmp_media")
11515    (set_attr "highpart" "depend")])
11517 (define_insn "negcmpeqv8qi"
11518   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11519         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11520                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11521   "TARGET_SHMEDIA"
11522   "mcmpeq.b     %N1, %N2, %0"
11523   [(set_attr "type" "mcmp_media")
11524    (set_attr "highpart" "depend")])
11526 (define_insn "negcmpeqv2si"
11527   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11528         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11529                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11530   "TARGET_SHMEDIA"
11531   "mcmpeq.l     %N1, %N2, %0"
11532   [(set_attr "type" "mcmp_media")
11533    (set_attr "highpart" "depend")])
11535 (define_insn "negcmpeqv4hi"
11536   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11537         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11538                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11539   "TARGET_SHMEDIA"
11540   "mcmpeq.w     %N1, %N2, %0"
11541   [(set_attr "type" "mcmp_media")
11542    (set_attr "highpart" "depend")])
11544 (define_insn "negcmpgtuv8qi"
11545   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11546         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
11547                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
11548   "TARGET_SHMEDIA"
11549   "mcmpgt.ub    %N1, %N2, %0"
11550   [(set_attr "type" "mcmp_media")
11551    (set_attr "highpart" "depend")])
11553 (define_insn "negcmpgtv2si"
11554   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11555         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
11556                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11557   "TARGET_SHMEDIA"
11558   "mcmpgt.l     %N1, %N2, %0"
11559   [(set_attr "type" "mcmp_media")
11560    (set_attr "highpart" "depend")])
11562 (define_insn "negcmpgtv4hi"
11563   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11564         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
11565                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11566   "TARGET_SHMEDIA"
11567   "mcmpgt.w     %N1, %N2, %0"
11568   [(set_attr "type" "mcmp_media")
11569    (set_attr "highpart" "depend")])
11571 (define_insn "mcmv"
11572   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11573         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11574                         (match_operand:DI 2 "arith_reg_operand" "r"))
11575                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
11576                         (not:DI (match_dup 2)))))]
11577   "TARGET_SHMEDIA"
11578   "mcmv %N1, %2, %0"
11579   [(set_attr "type" "arith_media")
11580    (set_attr "highpart" "depend")])
11582 (define_insn "mcnvs_lw"
11583   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11584         (vec_concat:V4HI
11585          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
11586          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
11587   "TARGET_SHMEDIA"
11588   "mcnvs.lw     %N1, %N2, %0"
11589   [(set_attr "type" "mcmp_media")])
11591 (define_insn "mcnvs_wb"
11592   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11593         (vec_concat:V8QI
11594          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11595          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11596   "TARGET_SHMEDIA"
11597   "mcnvs.wb     %N1, %N2, %0"
11598   [(set_attr "type" "mcmp_media")])
11600 (define_insn "mcnvs_wub"
11601   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
11602         (vec_concat:V8QI
11603          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
11604          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
11605   "TARGET_SHMEDIA"
11606   "mcnvs.wub    %N1, %N2, %0"
11607   [(set_attr "type" "mcmp_media")])
11609 (define_insn "mextr_rl"
11610   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11611         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11612                              (match_operand:HI 3 "mextr_bit_offset" "i"))
11613                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11614                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11615   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11616   "*
11618   static char templ[21];
11620   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
11621            (int) INTVAL (operands[3]) >> 3);
11622   return templ;
11624   [(set_attr "type" "arith_media")])
11626 (define_insn "*mextr_lr"
11627   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11628         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11629                            (match_operand:HI 3 "mextr_bit_offset" "i"))
11630                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
11631                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
11632   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
11633   "*
11635   static char templ[21];
11637   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
11638            (int) INTVAL (operands[4]) >> 3);
11639   return templ;
11641   [(set_attr "type" "arith_media")])
11643 ; mextrN can be modelled with vec_select / vec_concat, but the selection
11644 ; vector then varies depending on endianness.
11645 (define_expand "mextr1"
11646   [(match_operand:DI 0 "arith_reg_dest" "")
11647    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11648    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11649   "TARGET_SHMEDIA"
11650   "
11652   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11653                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
11654   DONE;
11657 (define_expand "mextr2"
11658   [(match_operand:DI 0 "arith_reg_dest" "")
11659    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11660    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11661   "TARGET_SHMEDIA"
11662   "
11664   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11665                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
11666   DONE;
11669 (define_expand "mextr3"
11670   [(match_operand:DI 0 "arith_reg_dest" "")
11671    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11672    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11673   "TARGET_SHMEDIA"
11674   "
11676   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11677                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
11678   DONE;
11681 (define_expand "mextr4"
11682   [(match_operand:DI 0 "arith_reg_dest" "")
11683    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11684    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11685   "TARGET_SHMEDIA"
11686   "
11688   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11689                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
11690   DONE;
11693 (define_expand "mextr5"
11694   [(match_operand:DI 0 "arith_reg_dest" "")
11695    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11696    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11697   "TARGET_SHMEDIA"
11698   "
11700   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11701                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
11702   DONE;
11705 (define_expand "mextr6"
11706   [(match_operand:DI 0 "arith_reg_dest" "")
11707    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11708    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11709   "TARGET_SHMEDIA"
11710   "
11712   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11713                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
11714   DONE;
11717 (define_expand "mextr7"
11718   [(match_operand:DI 0 "arith_reg_dest" "")
11719    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
11720    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
11721   "TARGET_SHMEDIA"
11722   "
11724   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
11725                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
11726   DONE;
11729 (define_expand "mmacfx_wl"
11730   [(match_operand:V2SI 0 "arith_reg_dest" "")
11731    (match_operand:V2HI 1 "extend_reg_operand" "")
11732    (match_operand:V2HI 2 "extend_reg_operand" "")
11733    (match_operand:V2SI 3 "arith_reg_operand" "")]
11734   "TARGET_SHMEDIA"
11735   "
11737   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
11738                               operands[1], operands[2]));
11739   DONE;
11742 ;; This could be highpart ignore if it only had inputs 2 or 3, but input 1
11743 ;; is depend
11744 (define_insn "mmacfx_wl_i"
11745   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11746         (ss_plus:V2SI
11747          (match_operand:V2SI 1 "arith_reg_operand" "0")
11748          (ss_truncate:V2SI
11749           (ashift:V2DI
11750            (sign_extend:V2DI
11751             (mult:V2SI
11752              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11753              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11754            (const_int 1)))))]
11755   "TARGET_SHMEDIA"
11756   "mmacfx.wl    %2, %3, %0"
11757   [(set_attr "type" "mac_media")
11758    (set_attr "highpart" "depend")])
11760 (define_expand "mmacnfx_wl"
11761   [(match_operand:V2SI 0 "arith_reg_dest" "")
11762    (match_operand:V2HI 1 "extend_reg_operand" "")
11763    (match_operand:V2HI 2 "extend_reg_operand" "")
11764    (match_operand:V2SI 3 "arith_reg_operand" "")]
11765   "TARGET_SHMEDIA"
11766   "
11768   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
11769                                operands[1], operands[2]));
11770   DONE;
11773 (define_insn "mmacnfx_wl_i"
11774   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11775         (ss_minus:V2SI
11776          (match_operand:V2SI 1 "arith_reg_operand" "0")
11777          (ss_truncate:V2SI
11778           (ashift:V2DI
11779            (sign_extend:V2DI
11780             (mult:V2SI
11781              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
11782              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
11783            (const_int 1)))))]
11784   "TARGET_SHMEDIA"
11785   "mmacnfx.wl   %2, %3, %0"
11786   [(set_attr "type" "mac_media")
11787    (set_attr "highpart" "depend")])
11789 (define_insn "mulv2si3"
11790   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11791         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
11792                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
11793   "TARGET_SHMEDIA"
11794   "mmul.l       %1, %2, %0"
11795   [(set_attr "type" "d2mpy_media")
11796    (set_attr "highpart" "depend")])
11798 (define_insn "mulv4hi3"
11799   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11800         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
11801                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
11802   "TARGET_SHMEDIA"
11803   "mmul.w       %1, %2, %0"
11804   [(set_attr "type" "dmpy_media")
11805    (set_attr "highpart" "depend")])
11807 (define_insn "mmulfx_l"
11808   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11809         (ss_truncate:V2SI
11810          (ashiftrt:V2DI
11811           (mult:V2DI
11812            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
11813            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
11814           (const_int 31))))]
11815   "TARGET_SHMEDIA"
11816   "mmulfx.l     %1, %2, %0"
11817   [(set_attr "type" "d2mpy_media")
11818    (set_attr "highpart" "depend")])
11820 (define_insn "mmulfx_w"
11821   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11822         (ss_truncate:V4HI
11823          (ashiftrt:V4SI
11824           (mult:V4SI
11825            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11826            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11827           (const_int 15))))]
11828   "TARGET_SHMEDIA"
11829   "mmulfx.w     %1, %2, %0"
11830   [(set_attr "type" "dmpy_media")
11831    (set_attr "highpart" "depend")])
11833 (define_insn "mmulfxrp_w"
11834   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11835         (ss_truncate:V4HI
11836          (ashiftrt:V4SI
11837           (plus:V4SI
11838            (mult:V4SI
11839             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11840             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11841            (const_int 16384))
11842           (const_int 15))))]
11843   "TARGET_SHMEDIA"
11844   "mmulfxrp.w   %1, %2, %0"
11845   [(set_attr "type" "dmpy_media")
11846    (set_attr "highpart" "depend")])
11849 (define_expand "mmulhi_wl"
11850   [(match_operand:V2SI 0 "arith_reg_dest" "")
11851    (match_operand:V4HI 1 "arith_reg_operand" "")
11852    (match_operand:V4HI 2 "arith_reg_operand" "")]
11853   "TARGET_SHMEDIA"
11854   "
11856   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
11857              (operands[0], operands[1], operands[2]));
11858   DONE;
11861 (define_expand "mmullo_wl"
11862   [(match_operand:V2SI 0 "arith_reg_dest" "")
11863    (match_operand:V4HI 1 "arith_reg_operand" "")
11864    (match_operand:V4HI 2 "arith_reg_operand" "")]
11865   "TARGET_SHMEDIA"
11866   "
11868   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
11869              (operands[0], operands[1], operands[2]));
11870   DONE;
11873 (define_insn "mmul23_wl"
11874   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11875         (vec_select:V2SI
11876          (mult:V4SI
11877           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11878           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11879          (parallel [(const_int 2) (const_int 3)])))]
11880   "TARGET_SHMEDIA"
11881   "* return (TARGET_LITTLE_ENDIAN
11882              ? \"mmulhi.wl      %1, %2, %0\"
11883              : \"mmullo.wl      %1, %2, %0\");"
11884   [(set_attr "type" "dmpy_media")
11885    (set (attr "highpart")
11886         (cond [(eq_attr "endian" "big") (const_string "ignore")]
11887          (const_string "user")))])
11889 (define_insn "mmul01_wl"
11890   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
11891         (vec_select:V2SI
11892          (mult:V4SI
11893           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
11894           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
11895          (parallel [(const_int 0) (const_int 1)])))]
11896   "TARGET_SHMEDIA"
11897   "* return (TARGET_LITTLE_ENDIAN
11898              ? \"mmullo.wl      %1, %2, %0\"
11899              : \"mmulhi.wl      %1, %2, %0\");"
11900   [(set_attr "type" "dmpy_media")
11901    (set (attr "highpart")
11902         (cond [(eq_attr "endian" "little") (const_string "ignore")]
11903          (const_string "user")))])
11906 (define_expand "mmulsum_wq"
11907   [(match_operand:DI 0 "arith_reg_dest" "")
11908    (match_operand:V4HI 1 "arith_reg_operand" "")
11909    (match_operand:V4HI 2 "arith_reg_operand" "")
11910    (match_operand:DI 3 "arith_reg_operand" "")]
11911   "TARGET_SHMEDIA"
11912   "
11914   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
11915                                operands[1], operands[2]));
11916   DONE;
11919 (define_insn "mmulsum_wq_i"
11920   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
11921         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
11922          (plus:DI
11923           (plus:DI
11924            (vec_select:DI
11925             (mult:V4DI
11926              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
11927              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
11928             (parallel [(const_int 0)]))
11929            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11930                                      (sign_extend:V4DI (match_dup 3)))
11931                           (parallel [(const_int 1)])))
11932           (plus:DI
11933            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11934                                      (sign_extend:V4DI (match_dup 3)))
11935                           (parallel [(const_int 2)]))
11936            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
11937                                      (sign_extend:V4DI (match_dup 3)))
11938                           (parallel [(const_int 3)]))))))]
11939   "TARGET_SHMEDIA"
11940   "mmulsum.wq   %2, %3, %0"
11941   [(set_attr "type" "mac_media")])
11943 (define_expand "mperm_w"
11944   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
11945    (match_operand:V4HI 1 "arith_reg_operand" "r")
11946    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
11947   "TARGET_SHMEDIA"
11948   "
11950   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
11951              (operands[0], operands[1], operands[2]));
11952   DONE;
11955 ; This use of vec_select isn't exactly correct according to rtl.texi
11956 ; (because not constant), but it seems a straightforward extension.
11957 (define_insn "mperm_w_little"
11958   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11959         (vec_select:V4HI
11960          (match_operand:V4HI 1 "arith_reg_operand" "r")
11961          (parallel
11962           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
11963                             (const_int 2) (const_int 0))
11964            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
11965            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
11966            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
11967   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
11968   "mperm.w      %1, %N2, %0"
11969   [(set_attr "type" "arith_media")])
11971 (define_insn "mperm_w_big"
11972   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11973         (vec_select:V4HI
11974          (match_operand:V4HI 1 "arith_reg_operand" "r")
11975          (parallel
11976           [(zero_extract:QI (not:QI (match_operand:QI 2
11977                                      "extend_reg_or_0_operand" "rZ"))
11978                             (const_int 2) (const_int 0))
11979            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
11980            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
11981            (zero_extract:QI (not:QI (match_dup 2))
11982                             (const_int 2) (const_int 6))])))]
11983   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
11984   "mperm.w      %1, %N2, %0"
11985   [(set_attr "type" "arith_media")])
11987 (define_insn "mperm_w0"
11988   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
11989         (vec_duplicate:V4HI (truncate:HI (match_operand 1
11990                                           "trunc_hi_operand" "r"))))]
11991   "TARGET_SHMEDIA"
11992   "mperm.w      %1, r63, %0"
11993   [(set_attr "type" "arith_media")
11994    (set_attr "highpart" "ignore")])
11996 (define_expand "msad_ubq"
11997   [(match_operand:DI 0 "arith_reg_dest" "")
11998    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
11999    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
12000    (match_operand:DI 3 "arith_reg_operand" "")]
12001   "TARGET_SHMEDIA"
12002   "
12004   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
12005                              operands[1], operands[2]));
12006   DONE;
12009 (define_insn "msad_ubq_i"
12010   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12011         (plus:DI
12012          (plus:DI
12013           (plus:DI
12014            (plus:DI
12015             (match_operand:DI 1 "arith_reg_operand" "0")
12016             (abs:DI (vec_select:DI
12017                      (minus:V8DI
12018                       (zero_extend:V8DI
12019                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12020                       (zero_extend:V8DI
12021                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
12022                      (parallel [(const_int 0)]))))
12023            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12024                                               (zero_extend:V8DI (match_dup 3)))
12025                                   (parallel [(const_int 1)]))))
12026           (plus:DI
12027            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12028                                               (zero_extend:V8DI (match_dup 3)))
12029                                   (parallel [(const_int 2)])))
12030            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12031                                               (zero_extend:V8DI (match_dup 3)))
12032                                   (parallel [(const_int 3)])))))
12033          (plus:DI
12034           (plus:DI
12035            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12036                                               (zero_extend:V8DI (match_dup 3)))
12037                                   (parallel [(const_int 4)])))
12038            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12039                                               (zero_extend:V8DI (match_dup 3)))
12040                                   (parallel [(const_int 5)]))))
12041           (plus:DI
12042            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12043                                               (zero_extend:V8DI (match_dup 3)))
12044                                   (parallel [(const_int 6)])))
12045            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
12046                                               (zero_extend:V8DI (match_dup 3)))
12047                                   (parallel [(const_int 7)])))))))]
12048   "TARGET_SHMEDIA"
12049   "msad.ubq     %N2, %N3, %0"
12050   [(set_attr "type" "mac_media")])
12052 (define_insn "mshalds_l"
12053   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12054         (ss_truncate:V2SI
12055          (ashift:V2DI
12056           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
12057           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12058                   (const_int 31)))))]
12059   "TARGET_SHMEDIA"
12060   "mshalds.l    %1, %2, %0"
12061   [(set_attr "type" "mcmp_media")
12062    (set_attr "highpart" "depend")])
12064 (define_insn "mshalds_w"
12065   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12066         (ss_truncate:V4HI
12067          (ashift:V4SI
12068           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
12069           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
12070                   (const_int 15)))))]
12071   "TARGET_SHMEDIA"
12072   "mshalds.w    %1, %2, %0"
12073   [(set_attr "type" "mcmp_media")
12074    (set_attr "highpart" "depend")])
12076 (define_insn "ashrv2si3"
12077   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12078         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12079                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12080   "TARGET_SHMEDIA"
12081   "mshard.l     %1, %2, %0"
12082   [(set_attr "type" "arith_media")
12083    (set_attr "highpart" "depend")])
12085 (define_insn "ashrv4hi3"
12086   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12087         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12088                        (match_operand:DI 2 "arith_reg_operand" "r")))]
12089   "TARGET_SHMEDIA"
12090   "mshard.w     %1, %2, %0"
12091   [(set_attr "type" "arith_media")
12092    (set_attr "highpart" "depend")])
12094 (define_insn "mshards_q"
12095   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
12096         (ss_truncate:HI
12097          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
12098                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
12099   "TARGET_SHMEDIA"
12100   "mshards.q    %1, %N2, %0"
12101   [(set_attr "type" "mcmp_media")])
12103 (define_expand "mshfhi_b"
12104   [(match_operand:V8QI 0 "arith_reg_dest" "")
12105    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12106    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12107   "TARGET_SHMEDIA"
12108   "
12110   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
12111              (operands[0], operands[1], operands[2]));
12112   DONE;
12115 (define_expand "mshflo_b"
12116   [(match_operand:V8QI 0 "arith_reg_dest" "")
12117    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12118    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
12119   "TARGET_SHMEDIA"
12120   "
12122   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
12123              (operands[0], operands[1], operands[2]));
12124   DONE;
12127 (define_insn "mshf4_b"
12128   [(set
12129     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12130     (vec_select:V8QI
12131      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12132                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12133      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
12134                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
12135   "TARGET_SHMEDIA"
12136   "* return (TARGET_LITTLE_ENDIAN
12137              ? \"mshfhi.b       %N1, %N2, %0\"
12138              : \"mshflo.b       %N1, %N2, %0\");"
12139   [(set_attr "type" "arith_media")
12140    (set (attr "highpart")
12141         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12142          (const_string "user")))])
12144 (define_insn "mshf0_b"
12145   [(set
12146     (match_operand:V8QI 0 "arith_reg_dest" "=r")
12147     (vec_select:V8QI
12148      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12149                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
12150      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
12151                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
12152   "TARGET_SHMEDIA"
12153   "* return (TARGET_LITTLE_ENDIAN
12154              ? \"mshflo.b       %N1, %N2, %0\"
12155              : \"mshfhi.b       %N1, %N2, %0\");"
12156   [(set_attr "type" "arith_media")
12157    (set (attr "highpart")
12158         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12159          (const_string "user")))])
12161 (define_expand "mshfhi_l"
12162   [(match_operand:V2SI 0 "arith_reg_dest" "")
12163    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12164    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12165   "TARGET_SHMEDIA"
12166   "
12168   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
12169              (operands[0], operands[1], operands[2]));
12170   DONE;
12173 (define_expand "mshflo_l"
12174   [(match_operand:V2SI 0 "arith_reg_dest" "")
12175    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12176    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
12177   "TARGET_SHMEDIA"
12178   "
12180   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
12181              (operands[0], operands[1], operands[2]));
12182   DONE;
12185 (define_insn "mshf4_l"
12186   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12187         (vec_select:V2SI
12188          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12189                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12190          (parallel [(const_int 1) (const_int 3)])))]
12191   "TARGET_SHMEDIA"
12192   "* return (TARGET_LITTLE_ENDIAN
12193              ? \"mshfhi.l       %N1, %N2, %0\"
12194              : \"mshflo.l       %N1, %N2, %0\");"
12195   [(set_attr "type" "arith_media")
12196    (set (attr "highpart")
12197         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12198          (const_string "user")))])
12200 (define_insn "mshf0_l"
12201   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12202         (vec_select:V2SI
12203          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12204                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
12205          (parallel [(const_int 0) (const_int 2)])))]
12206   "TARGET_SHMEDIA"
12207   "* return (TARGET_LITTLE_ENDIAN
12208              ? \"mshflo.l       %N1, %N2, %0\"
12209              : \"mshfhi.l       %N1, %N2, %0\");"
12210   [(set_attr "type" "arith_media")
12211    (set (attr "highpart")
12212         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12213          (const_string "user")))])
12215 (define_expand "mshfhi_w"
12216   [(match_operand:V4HI 0 "arith_reg_dest" "")
12217    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12218    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12219   "TARGET_SHMEDIA"
12220   "
12222   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
12223              (operands[0], operands[1], operands[2]));
12224   DONE;
12227 (define_expand "mshflo_w"
12228   [(match_operand:V4HI 0 "arith_reg_dest" "")
12229    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12230    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
12231   "TARGET_SHMEDIA"
12232   "
12234   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
12235              (operands[0], operands[1], operands[2]));
12236   DONE;
12239 (define_insn "mshf4_w"
12240   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12241         (vec_select:V4HI
12242          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12243                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12244          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
12245   "TARGET_SHMEDIA"
12246   "* return (TARGET_LITTLE_ENDIAN
12247              ? \"mshfhi.w       %N1, %N2, %0\"
12248              : \"mshflo.w       %N1, %N2, %0\");"
12249   [(set_attr "type" "arith_media")
12250    (set (attr "highpart")
12251         (cond [(eq_attr "endian" "big") (const_string "ignore")]
12252          (const_string "user")))])
12254 (define_insn "mshf0_w"
12255   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12256         (vec_select:V4HI
12257          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12258                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
12259          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
12260   "TARGET_SHMEDIA"
12261   "* return (TARGET_LITTLE_ENDIAN
12262              ? \"mshflo.w       %N1, %N2, %0\"
12263              : \"mshfhi.w       %N1, %N2, %0\");"
12264   [(set_attr "type" "arith_media")
12265    (set (attr "highpart")
12266         (cond [(eq_attr "endian" "little") (const_string "ignore")]
12267          (const_string "user")))])
12269 (define_insn "mshflo_w_x"
12270   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12271         (vec_select:V4HI
12272          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
12273                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
12274          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
12275   "TARGET_SHMEDIA"
12276   "mshflo.w     %N1, %N2, %0"
12277   [(set_attr "type" "arith_media")
12278    (set_attr "highpart" "ignore")])
12280 /* These are useful to expand ANDs and as combiner patterns.  */
12281 (define_insn_and_split "mshfhi_l_di"
12282   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
12283         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
12284                              (const_int 32))
12285                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
12286                         (const_int -4294967296))))]
12287   "TARGET_SHMEDIA"
12288   "@
12289         mshfhi.l        %N1, %N2, %0
12290         #"
12291   "TARGET_SHMEDIA && reload_completed
12292    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12293   [(set (match_dup 3) (match_dup 4))
12294    (set (match_dup 5) (match_dup 6))]
12295   "
12297   operands[3] = gen_lowpart (SImode, operands[0]);
12298   operands[4] = gen_highpart (SImode, operands[1]);
12299   operands[5] = gen_highpart (SImode, operands[0]);
12300   operands[6] = gen_highpart (SImode, operands[2]);
12302   [(set_attr "type" "arith_media")])
12304 (define_insn "*mshfhi_l_di_rev"
12305   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12306         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12307                         (const_int -4294967296))
12308                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12309                              (const_int 32))))]
12310   "TARGET_SHMEDIA"
12311   "mshfhi.l     %N2, %N1, %0"
12312   [(set_attr "type" "arith_media")])
12314 (define_split
12315   [(set (match_operand:DI 0 "arith_reg_dest" "")
12316         (ior:DI (zero_extend:DI (match_operand:SI 1
12317                                               "extend_reg_or_0_operand" ""))
12318                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
12319                         (const_int -4294967296))))
12320    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
12321   "TARGET_SHMEDIA"
12322   [(const_int 0)]
12323   "
12325   emit_insn (gen_ashldi3_media (operands[3],
12326                                 simplify_gen_subreg (DImode, operands[1],
12327                                                      SImode, 0),
12328                                 GEN_INT (32)));
12329   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
12330   DONE;
12333 (define_insn "mshflo_l_di"
12334   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12335         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12336                         (const_int 4294967295))
12337                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12338                            (const_int 32))))]
12340   "TARGET_SHMEDIA"
12341   "mshflo.l     %N1, %N2, %0"
12342   [(set_attr "type" "arith_media")
12343    (set_attr "highpart" "ignore")])
12345 (define_insn "*mshflo_l_di_rev"
12346   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12347         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12348                            (const_int 32))
12349                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12350                         (const_int 4294967295))))]
12352   "TARGET_SHMEDIA"
12353   "mshflo.l     %N2, %N1, %0"
12354   [(set_attr "type" "arith_media")
12355    (set_attr "highpart" "ignore")])
12357 ;; Combiner pattern for trampoline initialization.
12358 (define_insn_and_split "*double_shori"
12359   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12360         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
12361                            (const_int 32))
12362                 (match_operand:DI 2 "const_int_operand" "n")))]
12363   "TARGET_SHMEDIA
12364    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
12365   "#"
12366   "rtx_equal_p (operands[0], operands[1])"
12367   [(const_int 0)]
12368   "
12370   HOST_WIDE_INT v = INTVAL (operands[2]);
12372   emit_insn (gen_shori_media (operands[0], operands[0],
12373              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
12374   emit_insn (gen_shori_media (operands[0], operands[0],
12375                               gen_int_mode (v, HImode)));
12376   DONE;
12378   [(set_attr "highpart" "ignore")])
12381 (define_insn "*mshflo_l_di_x"
12382   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12383         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
12384                                  "rZ"))
12385                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
12386                            (const_int 32))))]
12388   "TARGET_SHMEDIA"
12389   "mshflo.l     %N1, %N2, %0"
12390   [(set_attr "type" "arith_media")
12391    (set_attr "highpart" "ignore")])
12393 (define_insn_and_split "concat_v2sf"
12394   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
12395 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
12396         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
12397                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
12399   "TARGET_SHMEDIA"
12400   "@
12401         mshflo.l        %N1, %N2, %0
12402         #
12403         #"
12404   "TARGET_SHMEDIA && reload_completed
12405    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
12406   [(set (match_dup 3) (match_dup 1))
12407    (set (match_dup 4) (match_dup 2))]
12408   "
12410   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
12411   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
12413   [(set_attr "type" "arith_media")
12414    (set_attr "highpart" "ignore")])
12416 (define_insn "*mshflo_l_di_x_rev"
12417   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12418         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
12419                            (const_int 32))
12420                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
12422   "TARGET_SHMEDIA"
12423   "mshflo.l     %N2, %N1, %0"
12424   [(set_attr "type" "arith_media")
12425    (set_attr "highpart" "ignore")])
12427 (define_insn "ashlv2si3"
12428   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12429         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12430                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12431   "TARGET_SHMEDIA"
12432   "mshlld.l     %1, %2, %0"
12433   [(set_attr "type" "arith_media")
12434    (set_attr "highpart" "depend")])
12436 (define_split
12437   [(set (match_operand 0 "any_register_operand" "")
12438         (match_operator 3 "shift_operator"
12439           [(match_operand 1 "any_register_operand" "")
12440            (match_operand 2 "shift_count_reg_operand" "")]))]
12441   "TARGET_SHMEDIA && ! register_operand (operands[2], VOIDmode)"
12442   [(set (match_dup 0) (match_dup 3))]
12443   "
12445   rtx count = operands[2];
12446   enum machine_mode outer_mode = GET_MODE (operands[2]), inner_mode;
12448   while (GET_CODE (count) == ZERO_EXTEND || GET_CODE (count) == SIGN_EXTEND
12449          || (GET_CODE (count) == SUBREG && SUBREG_BYTE (count) == 0)
12450          || GET_CODE (count) == TRUNCATE)
12451     count = XEXP (count, 0);
12452   inner_mode = GET_MODE (count);
12453   count = simplify_gen_subreg (outer_mode, count, inner_mode,
12454                                subreg_lowpart_offset (outer_mode, inner_mode));
12455   operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
12456                                 operands[1], count);
12459 (define_insn "ashlv4hi3"
12460   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12461         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12462                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12463   "TARGET_SHMEDIA"
12464   "mshlld.w     %1, %2, %0"
12465   [(set_attr "type" "arith_media")
12466    (set_attr "highpart" "depend")])
12468 (define_insn "lshrv2si3"
12469   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12470         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
12471                      (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12472   "TARGET_SHMEDIA"
12473   "mshlrd.l     %1, %2, %0"
12474   [(set_attr "type" "arith_media")
12475    (set_attr "highpart" "depend")])
12477 (define_insn "lshrv4hi3"
12478   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12479         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
12480                        (match_operand:DI 2 "shift_count_reg_operand" "r")))]
12481   "TARGET_SHMEDIA"
12482   "mshlrd.w     %1, %2, %0"
12483   [(set_attr "type" "arith_media")
12484    (set_attr "highpart" "depend")])
12486 (define_insn "subv2si3"
12487   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12488         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12489                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12490   "TARGET_SHMEDIA"
12491   "msub.l       %N1, %2, %0"
12492   [(set_attr "type" "arith_media")
12493    (set_attr "highpart" "depend")])
12495 (define_insn "subv4hi3"
12496   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12497         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12498                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12499   "TARGET_SHMEDIA"
12500   "msub.w       %N1, %2, %0"
12501   [(set_attr "type" "arith_media")
12502    (set_attr "highpart" "depend")])
12504 (define_insn_and_split "subv2hi3"
12505   [(set (match_operand:V2HI 0 "arith_reg_dest" "=r")
12506         (minus:V2HI (match_operand:V2HI 1 "arith_reg_or_0_operand" "rZ")
12507                    (match_operand:V2HI 2 "arith_reg_operand" "r")))]
12508   "TARGET_SHMEDIA"
12509   "#"
12510   "TARGET_SHMEDIA"
12511   [(const_int 0)]
12512   "
12514   rtx src0 = simplify_gen_subreg (V4HImode, operands[1], V2HImode, 0);
12515   rtx src1 = simplify_gen_subreg (V4HImode, operands[2], V2HImode, 0);
12516   rtx v4hi_dst = simplify_gen_subreg (V4HImode, operands[0], V2HImode, 0);
12517   rtx di_dst = simplify_gen_subreg (DImode, operands[0], V2HImode, 0);
12518   rtx si_dst = simplify_gen_subreg (SImode, operands[0], V2HImode, 0);
12520   emit_insn (gen_subv4hi3 (v4hi_dst, src0, src1));
12521   emit_insn (gen_truncdisi2 (si_dst, di_dst));
12522   DONE;
12524   [(set_attr "highpart" "must_split")])
12526 (define_insn "sssubv2si3"
12527   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
12528         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
12529                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
12530   "TARGET_SHMEDIA"
12531   "msubs.l      %N1, %2, %0"
12532   [(set_attr "type" "mcmp_media")
12533    (set_attr "highpart" "depend")])
12535 (define_insn "ussubv8qi3"
12536   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
12537         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
12538                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
12539   "TARGET_SHMEDIA"
12540   "msubs.ub     %N1, %2, %0"
12541   [(set_attr "type" "mcmp_media")
12542    (set_attr "highpart" "depend")])
12544 (define_insn "sssubv4hi3"
12545   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
12546         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
12547                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
12548   "TARGET_SHMEDIA"
12549   "msubs.w      %N1, %2, %0"
12550   [(set_attr "type" "mcmp_media")
12551    (set_attr "highpart" "depend")])
12553 ;; Floating Point Intrinsics
12555 (define_insn "fcosa_s"
12556   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12557         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12558                    UNSPEC_FCOSA))]
12559   "TARGET_SHMEDIA"
12560   "fcosa.s      %1, %0"
12561   [(set_attr "type" "atrans_media")])
12563 (define_insn "fsina_s"
12564   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12565         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
12566                    UNSPEC_FSINA))]
12567   "TARGET_SHMEDIA"
12568   "fsina.s      %1, %0"
12569   [(set_attr "type" "atrans_media")])
12571 (define_insn "fipr"
12572   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12573         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
12574                                                     "fp_arith_reg_operand" "f")
12575                                                    (match_operand:V4SF 2
12576                                                     "fp_arith_reg_operand" "f"))
12577                                          (parallel [(const_int 0)]))
12578                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12579                                          (parallel [(const_int 1)])))
12580                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12581                                          (parallel [(const_int 2)]))
12582                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
12583                                          (parallel [(const_int 3)])))))]
12584   "TARGET_SHMEDIA"
12585   "fipr.s       %1, %2, %0"
12586   [(set_attr "type" "fparith_media")])
12588 (define_insn "fsrra_s"
12589   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
12590         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
12591                    UNSPEC_FSRRA))]
12592   "TARGET_SHMEDIA"
12593   "fsrra.s      %1, %0"
12594   [(set_attr "type" "atrans_media")])
12596 (define_insn "ftrv"
12597   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
12598         (plus:V4SF
12599          (plus:V4SF
12600           (mult:V4SF
12601            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
12602                             (parallel [(const_int 0) (const_int 5)
12603                                        (const_int 10) (const_int 15)]))
12604            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
12605           (mult:V4SF
12606            (vec_select:V4SF (match_dup 1)
12607                             (parallel [(const_int 4) (const_int 9)
12608                                        (const_int 14) (const_int 3)]))
12609            (vec_select:V4SF (match_dup 2)
12610                             (parallel [(const_int 1) (const_int 2)
12611                                        (const_int 3) (const_int 0)]))))
12612          (plus:V4SF
12613           (mult:V4SF
12614            (vec_select:V4SF (match_dup 1)
12615                             (parallel [(const_int 8) (const_int 13)
12616                                        (const_int 2) (const_int 7)]))
12617            (vec_select:V4SF (match_dup 2)
12618                             (parallel [(const_int 2) (const_int 3)
12619                                        (const_int 0) (const_int 1)])))
12620           (mult:V4SF
12621            (vec_select:V4SF (match_dup 1)
12622                             (parallel [(const_int 12) (const_int 1)
12623                                        (const_int 6) (const_int 11)]))
12624            (vec_select:V4SF (match_dup 2)
12625                             (parallel [(const_int 3) (const_int 0)
12626                                        (const_int 1) (const_int 2)]))))))]
12627   "TARGET_SHMEDIA"
12628   "ftrv.s %1, %2, %0"
12629   [(set_attr "type" "fparith_media")])
12631 (define_insn "ldhi_l"
12632   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12633         (zero_extract:SI
12634          (mem:SI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12635                                   (const_int 3))
12636                           (const_int -3)))
12637          (plus:SI (and:SI (match_dup 1) (const_int 3)) (const_int 1))
12638          (const_int 0)))]
12639   "TARGET_SHMEDIA32"
12640   "ldhi.l       %U1, %0"
12641   [(set_attr "type" "load_media")])
12643 (define_insn "ldhi_q"
12644   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12645         (zero_extract:DI
12646          (mem:DI (plus:SI (ior:SI (match_operand:QI 1 "ua_address_operand" "p")
12647                                   (const_int 7))
12648                           (const_int -7)))
12649          (plus:SI (and:SI (match_dup 1) (const_int 7)) (const_int 1))
12650          (const_int 0)))]
12651   "TARGET_SHMEDIA32"
12652   "ldhi.q       %U1, %0"
12653   [(set_attr "type" "load_media")])
12655 (define_insn_and_split "*ldhi_q_comb0"
12656   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12657         (zero_extract:DI
12658          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12659                                             "register_operand" "r")
12660                                            (match_operand:SI 2
12661                                             "ua_offset" "I06"))
12662                                   (const_int 7))
12663                           (const_int -7)))
12664          (plus:SI (and:SI (match_dup 1) (const_int 7))
12665                   (const_int 1))
12666          (const_int 0)))]
12667   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12668   "#"
12669   ""
12670   [(pc)]
12671   "emit_insn (gen_ldhi_q (operands[0],
12672                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12673    DONE;")
12676 (define_insn_and_split "*ldhi_q_comb1"
12677   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12678         (zero_extract:DI
12679          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 1
12680                                             "register_operand" "r")
12681                                            (match_operand:SI 2
12682                                             "ua_offset" "I06"))
12683                                   (const_int 7))
12684                           (const_int -7)))
12685          (plus:SI (and:SI (plus:SI (match_dup 1)  (match_operand:SI 3
12686                                                    "ua_offset" "I06"))
12687                           (const_int 7))
12688                   (const_int 1))
12689          (const_int 0)))]
12690   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12691    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12692   "#"
12693   ""
12694   [(pc)]
12695   "emit_insn (gen_ldhi_q (operands[0],
12696                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12697    DONE;")
12700 (define_insn "ldlo_l"
12701   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12702         (zero_extract:SI
12703          (mem:SI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12704                          (const_int -4)))
12705          (minus:SI (const_int 4) (and:SI (match_dup 1) (const_int 3)))
12706          (and:SI (match_dup 1) (const_int 3))))]
12707   "TARGET_SHMEDIA32"
12708   "ldlo.l       %U1, %0"
12709   [(set_attr "type" "load_media")])
12711 (define_insn "ldlo_q"
12712   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12713         (zero_extract:DI
12714          (mem:DI (and:SI (match_operand:QI 1 "ua_address_operand" "p")
12715                          (const_int -8)))
12716          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12717          (and:SI (match_dup 1) (const_int 7))))]
12718   "TARGET_SHMEDIA32"
12719   "ldlo.q       %U1, %0"
12720   [(set_attr "type" "load_media")])
12722 (define_insn_and_split "*ldlo_q_comb0"
12723   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12724         (zero_extract:DI
12725          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12726                                   (match_operand:SI 2 "ua_offset" "I06"))
12727                          (const_int -8)))
12728          (minus:SI (const_int 8) (and:SI (match_dup 1) (const_int 7)))
12729          (and:SI (match_dup 1) (const_int 7))))]
12730   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & 7) == 0"
12731   "#"
12732   ""
12733   [(pc)]
12734   "emit_insn (gen_ldlo_q (operands[0],
12735                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12736    DONE;")
12738 (define_insn_and_split "*ldlo_q_comb1"
12739   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12740         (zero_extract:DI
12741          (mem:DI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
12742                                   (match_operand:SI 2 "ua_offset" "I06"))
12743                          (const_int -8)))
12744          (minus:SI (const_int 8)
12745                    (and:SI (plus:SI (match_dup 1)
12746                                     (match_operand:SI 3 "ua_offset" "I06"))
12747                            (const_int 7)))
12748          (and:SI (plus:SI (match_dup 1) (match_dup 3)) (const_int 7))))]
12749   "TARGET_SHMEDIA32 && (INTVAL (operands[2]) & -8)
12750    && (INTVAL (operands[2]) & 7) == INTVAL (operands[3])"
12751   "#"
12752   ""
12753   [(pc)]
12754   "emit_insn (gen_ldlo_q (operands[0],
12755                           gen_rtx_PLUS (SImode, operands[1], operands[2])));
12756    DONE;")
12758 (define_insn "sthi_l"
12759   [(set (zero_extract:SI
12760          (mem:SI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12761                                   (const_int 3))
12762                           (const_int -3)))
12763          (plus:SI (and:SI (match_dup 0) (const_int 3)) (const_int 1))
12764          (const_int 0))
12765         (match_operand:SI 1 "arith_reg_operand" "r"))]
12766   "TARGET_SHMEDIA32"
12767   "sthi.l       %U0, %1"
12768   [(set_attr "type" "ustore_media")])
12770 ;; All unaligned stores are considered to be 'narrow' because they typically
12771 ;; operate on less that a quadword, and when they operate on a full quadword,
12772 ;; the vanilla store high / store low sequence will cause a stall if not
12773 ;; scheduled apart.
12774 (define_insn "sthi_q"
12775   [(set (zero_extract:DI
12776          (mem:DI (plus:SI (ior:SI (match_operand:QI 0 "ua_address_operand" "p")
12777                                   (const_int 7))
12778                           (const_int -7)))
12779          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12780          (const_int 0))
12781         (match_operand:DI 1 "arith_reg_operand" "r"))]
12782   "TARGET_SHMEDIA32"
12783   "sthi.q       %U0, %1"
12784   [(set_attr "type" "ustore_media")])
12786 (define_insn_and_split "*sthi_q_comb0"
12787   [(set (zero_extract:DI
12788          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12789                                             "register_operand" "r")
12790                                            (match_operand:SI 1 "ua_offset"
12791                                             "I06"))
12792                                   (const_int 7))
12793                           (const_int -7)))
12794          (plus:SI (and:SI (match_dup 0) (const_int 7)) (const_int 1))
12795          (const_int 0))
12796         (match_operand:DI 2 "arith_reg_operand" "r"))]
12797   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12798   "#"
12799   ""
12800   [(pc)]
12801   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12802                           operands[2]));
12803    DONE;")
12805 (define_insn_and_split "*sthi_q_comb1"
12806   [(set (zero_extract:DI
12807          (mem:DI (plus:SI (ior:SI (plus:SI (match_operand:SI 0
12808                                             "register_operand" "r")
12809                                            (match_operand:SI 1 "ua_offset"
12810                                             "I06"))
12811                                   (const_int 7))
12812                           (const_int -7)))
12813          (plus:SI (and:SI (plus:SI (match_dup 0)
12814                                    (match_operand:SI 2 "ua_offset" "I06"))
12815                           (const_int 7))
12816                   (const_int 1))
12817          (const_int 0))
12818         (match_operand:DI 3 "arith_reg_operand" "r"))]
12819   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & -8)
12820    && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12821   "#"
12822   ""
12823   [(pc)]
12824   "emit_insn (gen_sthi_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12825                           operands[3]));
12826    DONE;")
12828 ;; This is highpart user because the address is used as full 64 bit.
12829 (define_insn "stlo_l"
12830   [(set (zero_extract:SI
12831          (mem:SI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12832                          (const_int -4)))
12833          (minus:SI (const_int 4) (and:SI (match_dup 0) (const_int 3)))
12834          (and:SI (match_dup 0) (const_int 3)))
12835         (match_operand:SI 1 "arith_reg_operand" "r"))]
12836   "TARGET_SHMEDIA32"
12837   "stlo.l       %U0, %1"
12838   [(set_attr "type" "ustore_media")])
12840 (define_insn "stlo_q"
12841   [(set (zero_extract:DI
12842          (mem:DI (and:SI (match_operand:QI 0 "ua_address_operand" "p")
12843                          (const_int -8)))
12844          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12845          (and:SI (match_dup 0) (const_int 7)))
12846         (match_operand:DI 1 "arith_reg_operand" "r"))]
12847   "TARGET_SHMEDIA32"
12848   "stlo.q       %U0, %1"
12849   [(set_attr "type" "ustore_media")])
12851 (define_insn_and_split "*stlo_q_comb0"
12852   [(set (zero_extract:DI
12853          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12854                                   (match_operand:SI 1 "ua_offset" "I06"))
12855                          (const_int -8)))
12856          (minus:SI (const_int 8) (and:SI (match_dup 0) (const_int 7)))
12857          (and:SI (match_dup 0) (const_int 7)))
12858         (match_operand:DI 2 "arith_reg_operand" "r"))]
12859   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == 0"
12860   "#"
12861   ""
12862   [(pc)]
12863   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12864                           operands[2]));
12865    DONE;")
12867 (define_insn_and_split "*stlo_q_comb1"
12868   [(set (zero_extract:DI
12869          (mem:DI (and:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
12870                                   (match_operand:SI 1 "ua_offset" "I06"))
12871                          (const_int -8)))
12872          (minus:SI (const_int 8) (and:SI (plus:SI (match_dup 0)
12873                                                   (match_operand:SI 2
12874                                                    "ua_offset" "I06"))
12875                                          (const_int 7)))
12876          (and:SI (plus:SI (match_dup 0) (match_dup 2)) (const_int 7)))
12877         (match_operand:DI 3 "arith_reg_operand" "r"))]
12878   "TARGET_SHMEDIA32 && (INTVAL (operands[1]) & 7) == INTVAL (operands[2])"
12879   "#"
12880   ""
12881   [(pc)]
12882   "emit_insn (gen_stlo_q (gen_rtx_PLUS (SImode, operands[0], operands[1]),
12883                           operands[3]));
12884    DONE;")
12886 (define_insn "ldhi_l64"
12887   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12888         (zero_extract:SI
12889          (mem:SI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12890                                   (const_int 3))
12891                           (const_int -3)))
12892          (plus:DI (and:DI (match_dup 1) (const_int 3)) (const_int 1))
12893          (const_int 0)))]
12894   "TARGET_SHMEDIA64"
12895   "ldhi.l       %U1, %0"
12896   [(set_attr "type" "load_media")])
12898 (define_insn "ldhi_q64"
12899   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12900         (zero_extract:DI
12901          (mem:DI (plus:DI (ior:DI (match_operand:QI 1 "ua_address_operand" "p")
12902                                   (const_int 7))
12903                           (const_int -7)))
12904          (plus:DI (and:DI (match_dup 1) (const_int 7)) (const_int 1))
12905          (const_int 0)))]
12906   "TARGET_SHMEDIA64"
12907   "ldhi.q       %U1, %0"
12908   [(set_attr "type" "load_media")])
12910 (define_insn "ldlo_l64"
12911   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12912         (zero_extract:SI
12913          (mem:SI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12914                          (const_int -4)))
12915          (minus:DI (const_int 4) (and:DI (match_dup 1) (const_int 3)))
12916          (and:DI (match_dup 1) (const_int 3))))]
12917   "TARGET_SHMEDIA64"
12918   "ldlo.l       %U1, %0"
12919   [(set_attr "type" "load_media")])
12921 (define_insn "ldlo_q64"
12922   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12923         (zero_extract:DI
12924          (mem:DI (and:DI (match_operand:QI 1 "ua_address_operand" "p")
12925                          (const_int -8)))
12926          (minus:DI (const_int 8) (and:DI (match_dup 1) (const_int 7)))
12927          (and:DI (match_dup 1) (const_int 7))))]
12928   "TARGET_SHMEDIA64"
12929   "ldlo.q       %U1, %0"
12930   [(set_attr "type" "load_media")])
12932 (define_insn "sthi_l64"
12933   [(set (zero_extract:SI
12934          (mem:SI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12935                                   (const_int 3))
12936                           (const_int -3)))
12937          (plus:DI (and:DI (match_dup 0) (const_int 3)) (const_int 1))
12938          (const_int 0))
12939         (match_operand:SI 1 "arith_reg_operand" "r"))]
12940   "TARGET_SHMEDIA64"
12941   "sthi.l       %U0, %1"
12942   [(set_attr "type" "ustore_media")])
12944 (define_insn "sthi_q64"
12945   [(set (zero_extract:DI
12946          (mem:DI (plus:DI (ior:DI (match_operand:QI 0 "ua_address_operand" "p")
12947                                   (const_int 7))
12948                           (const_int -7)))
12949          (plus:DI (and:DI (match_dup 0) (const_int 7)) (const_int 1))
12950          (const_int 0))
12951         (match_operand:DI 1 "arith_reg_operand" "r"))]
12952   "TARGET_SHMEDIA64"
12953   "sthi.q       %U0, %1"
12954   [(set_attr "type" "ustore_media")])
12956 (define_insn "stlo_l64"
12957   [(set (zero_extract:SI
12958          (mem:SI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12959                          (const_int -4)))
12960          (minus:DI (const_int 4) (and:DI (match_dup 0) (const_int 3)))
12961          (and:DI (match_dup 0) (const_int 3)))
12962         (match_operand:SI 1 "arith_reg_operand" "r"))]
12963   "TARGET_SHMEDIA64"
12964   "stlo.l       %U0, %1"
12965   [(set_attr "type" "ustore_media")])
12967 (define_insn "stlo_q64"
12968   [(set (zero_extract:DI
12969          (mem:DI (and:DI (match_operand:QI 0 "ua_address_operand" "p")
12970                          (const_int -8)))
12971          (minus:DI (const_int 8) (and:DI (match_dup 0) (const_int 7)))
12972          (and:DI (match_dup 0) (const_int 7)))
12973         (match_operand:DI 1 "arith_reg_operand" "r"))]
12974   "TARGET_SHMEDIA64"
12975   "stlo.q       %U0, %1"
12976   [(set_attr "type" "ustore_media")])
12978 (define_insn "nsb"
12979   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
12980         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12981                    UNSPEC_NSB))]
12982   "TARGET_SHMEDIA"
12983   "nsb  %1, %0"
12984   [(set_attr "type" "arith_media")])
12986 (define_insn "nsbsi"
12987   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
12988         (zero_extend:SI
12989          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12990                     UNSPEC_NSB)))]
12991   "TARGET_SHMEDIA"
12992   "nsb  %1, %0"
12993   [(set_attr "type" "arith_media")])
12995 (define_insn "nsbdi"
12996   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
12997         (zero_extend:DI
12998          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
12999                     UNSPEC_NSB)))]
13000   "TARGET_SHMEDIA"
13001   "nsb  %1, %0"
13002   [(set_attr "type" "arith_media")])
13004 (define_expand "ffsdi2"
13005   [(set (match_operand:DI 0 "arith_reg_dest" "")
13006         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
13007   "TARGET_SHMEDIA"
13008   "
13010   rtx scratch = gen_reg_rtx (DImode);
13011   rtx last;
13013   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
13014   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
13015   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
13016   emit_insn (gen_nsbdi (scratch, scratch));
13017   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
13018   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
13019   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
13020   REG_NOTES (last)
13021     = gen_rtx_EXPR_LIST (REG_EQUAL,
13022                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
13023   DONE;
13026 (define_expand "ffssi2"
13027   [(set (match_operand:SI 0 "arith_reg_dest" "")
13028         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
13029   "TARGET_SHMEDIA"
13030   "
13032   rtx scratch = gen_reg_rtx (SImode);
13033   rtx discratch = gen_reg_rtx (DImode);
13034   rtx last;
13036   emit_insn (gen_adddi3 (discratch,
13037                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
13038                          constm1_rtx));
13039   emit_insn (gen_andcdi3 (discratch,
13040                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
13041                           discratch));
13042   emit_insn (gen_nsbsi (scratch, discratch));
13043   last = emit_insn (gen_subsi3 (operands[0],
13044                                 force_reg (SImode, GEN_INT (63)), scratch));
13045   REG_NOTES (last)
13046     = gen_rtx_EXPR_LIST (REG_EQUAL,
13047                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
13048   DONE;
13051 (define_insn "byterev"
13052   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
13053         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
13054                          (parallel [(const_int 7) (const_int 6) (const_int 5)
13055                                     (const_int 4) (const_int 3) (const_int 2)
13056                                     (const_int 1) (const_int 0)])))]
13057   "TARGET_SHMEDIA"
13058   "byterev      %1, %0"
13059   [(set_attr "type" "arith_media")])
13061 (define_insn "*prefetch_media"
13062   [(prefetch (match_operand:QI 0 "address_operand" "p")
13063              (match_operand:SI 1 "const_int_operand" "n")
13064              (match_operand:SI 2 "const_int_operand" "n"))]
13065   "TARGET_SHMEDIA"
13066   "*
13068   operands[0] = gen_rtx_MEM (QImode, operands[0]);
13069   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
13070   return \"\";
13072   [(set_attr "type" "other")])
13074 (define_insn "*prefetch_i4"
13075   [(prefetch (match_operand:SI 0 "register_operand" "r")
13076              (match_operand:SI 1 "const_int_operand" "n")
13077              (match_operand:SI 2 "const_int_operand" "n"))]
13078   "TARGET_HARD_SH4 || TARGET_SHCOMPACT"
13079   "*
13081   return \"pref @%0\";
13083   [(set_attr "type" "other")])
13085 (define_expand "prefetch"
13086   [(prefetch (match_operand 0 "address_operand" "p")
13087              (match_operand:SI 1 "const_int_operand" "n")
13088              (match_operand:SI 2 "const_int_operand" "n"))]
13089   "TARGET_HARD_SH4 || TARGET_SH5"
13090   "
13092   if (GET_MODE (operands[0]) != Pmode
13093       || GET_CODE (operands[1]) != CONST_INT
13094       || GET_CODE (operands[2]) != CONST_INT)
13095     FAIL;
13096   if (! TARGET_SHMEDIA)
13097     operands[0] = force_reg (Pmode, operands[0]);
13100 (define_insn "alloco_i"
13101   [(set (mem:BLK (match_operand:QI 0 "cache_address_operand" "p"))
13102         (unspec:BLK [(const_int 0)] UNSPEC_ALLOCO))]
13103   "TARGET_SHMEDIA32"
13104   "*
13106   rtx xops[2];
13108   if (GET_CODE (operands[0]) == PLUS)
13109     {
13110       xops[0] = XEXP (operands[0], 0);
13111       xops[1] = XEXP (operands[0], 1);
13112     }
13113   else
13114     {
13115       xops[0] = operands[0];
13116       xops[1] = const0_rtx;
13117     }
13118   output_asm_insn (\"alloco   %0, %1\", xops);
13119   return \"\";
13121   [(set_attr "type" "other")])
13123 (define_split
13124   [(set (match_operand 0 "any_register_operand" "")
13125         (match_operand 1 "" ""))]
13126   "TARGET_SHMEDIA && reload_completed"
13127   [(set (match_dup 0) (match_dup 1))]
13128   "
13130   int n_changes = 0;
13132   for_each_rtx (&operands[1], shmedia_cleanup_truncate, &n_changes);
13133   if (!n_changes)
13134     FAIL;
13137 ; Stack Protector Patterns
13139 (define_expand "stack_protect_set"
13140   [(set (match_operand 0 "memory_operand" "")
13141         (match_operand 1 "memory_operand" ""))]
13142   ""
13144   if (TARGET_SHMEDIA)
13145     {
13146       if (TARGET_SHMEDIA64)
13147         emit_insn (gen_stack_protect_set_di_media (operands[0], operands[1]));
13148       else
13149         emit_insn (gen_stack_protect_set_si_media (operands[0], operands[1]));
13150     }
13151   else
13152     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
13154   DONE;
13157 (define_insn "stack_protect_set_si"
13158   [(set (match_operand:SI 0 "memory_operand" "=m")
13159         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13160    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13161   "!TARGET_SHMEDIA"
13162   "mov.l\t%1, %2\;mov.l\t%2, %0\;mov\t#0, %2"
13163   [(set_attr "type" "other")
13164    (set_attr "length" "6")])
13166 (define_insn "stack_protect_set_si_media"
13167   [(set (match_operand:SI 0 "memory_operand" "=m")
13168         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13169    (set (match_scratch:SI 2 "=&r") (const_int 0))]
13170   "TARGET_SHMEDIA"
13171   "ld%M1.l\t%m1, %2\;st%M0.l\t%m0, %2\;movi\t0, %2"
13172   [(set_attr "type" "other")
13173    (set_attr "length" "12")])
13175 (define_insn "stack_protect_set_di_media"
13176   [(set (match_operand:DI 0 "memory_operand" "=m")
13177         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
13178    (set (match_scratch:DI 2 "=&r") (const_int 0))]
13179   "TARGET_SHMEDIA64"
13180   "ld%M1.q\t%m1, %2\;st%M0.q\t%m0, %2\;movi\t0, %2"
13181   [(set_attr "type" "other")
13182    (set_attr "length" "12")])
13184 (define_expand "stack_protect_test"
13185   [(match_operand 0 "memory_operand" "")
13186    (match_operand 1 "memory_operand" "")
13187    (match_operand 2 "" "")]
13188   ""
13190   if (TARGET_SHMEDIA)
13191     {
13192       rtx tmp = gen_reg_rtx (GET_MODE (operands[0]));
13194       if (TARGET_SHMEDIA64)
13195         emit_insn (gen_stack_protect_test_di_media (tmp, operands[0],
13196                                                     operands[1]));
13197       else
13198         emit_insn (gen_stack_protect_test_si_media (tmp, operands[0],
13199                                                     operands[1]));
13201       emit_jump_insn (gen_bne_media (operands[2], tmp, const0_rtx));
13202     }
13203   else
13204     {
13205       emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
13206       emit_jump_insn (gen_branch_true (operands[2]));
13207     }
13209   DONE;
13212 (define_insn "stack_protect_test_si"
13213   [(set (reg:SI T_REG)
13214         (unspec:SI [(match_operand:SI 0 "memory_operand" "m")
13215                     (match_operand:SI 1 "memory_operand" "m")]
13216                    UNSPEC_SP_TEST))
13217   (set (match_scratch:SI 2 "=&r") (const_int 0))
13218   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13219   "!TARGET_SHMEDIA"
13220   "mov.l\t%0, %2\;mov.l\t%1, %3\;cmp/eq\t%2, %3\;mov\t#0, %2\;mov\t#0, %3"
13221   [(set_attr "type" "other")
13222    (set_attr "length" "10")])
13224 (define_insn "stack_protect_test_si_media"
13225   [(set (match_operand:SI 0 "register_operand" "=&r")
13226         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
13227                     (match_operand:SI 2 "memory_operand" "m")]
13228                    UNSPEC_SP_TEST))
13229   (set (match_scratch:SI 3 "=&r") (const_int 0))]
13230   "TARGET_SHMEDIA"
13231   "ld%M1.l\t%m1, %0\;ld%M2.l\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13232   [(set_attr "type" "other")
13233    (set_attr "length" "16")])
13235 (define_insn "stack_protect_test_di_media"
13236   [(set (match_operand:DI 0 "register_operand" "=&r")
13237         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
13238                     (match_operand:DI 2 "memory_operand" "m")]
13239                    UNSPEC_SP_TEST))
13240   (set (match_scratch:DI 3 "=&r") (const_int 0))]
13241   "TARGET_SHMEDIA64"
13242   "ld%M1.q\t%m1, %0\;ld%M2.q\t%m2, %3\;cmpeq\t%0, %3, %0\;movi\t0, %3"
13243   [(set_attr "type" "other")
13244    (set_attr "length" "16")])