Add x prefix to v850e case for handling --with-cpu=v850e.
[official-gcc.git] / gcc / config / sh / sh.md
blobf0408efd2aaf2739c27171c1a0f2526a6e88fa04
1 ;;- Machine description for Hitachi / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 ;;  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 GNU CC.
9 ;; GNU CC 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 ;; GNU CC 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 GNU CC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, 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)
139   ;; These are used with unspec_volatile.
140   (UNSPECV_BLOCKAGE     0)
141   (UNSPECV_ALIGN        1)
142   (UNSPECV_CONST2       2)
143   (UNSPECV_CONST4       4)
144   (UNSPECV_CONST8       6)
145   (UNSPECV_WINDOW_END   10)
146   (UNSPECV_CONST_END    11)
147 ])  
149 ;; -------------------------------------------------------------------------
150 ;; Attributes
151 ;; -------------------------------------------------------------------------
153 ;; Target CPU.
155 (define_attr "cpu"
156  "sh1,sh2,sh3,sh3e,sh4,sh5"
157   (const (symbol_ref "sh_cpu_attr")))
159 (define_attr "endian" "big,little"
160  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
161                       (const_string "little") (const_string "big"))))
163 ;; Indicate if the default fpu mode is single precision.
164 (define_attr "fpu_single" "yes,no"
165   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
166                          (const_string "yes") (const_string "no"))))
168 (define_attr "fmovd" "yes,no"
169   (const (if_then_else (symbol_ref "TARGET_FMOVD")
170                        (const_string "yes") (const_string "no"))))
171 ;; pipeline model
172 (define_attr "pipe_model" "sh1,sh4,sh5media"
173   (const
174    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
175           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
176          (const_string "sh1"))))
178 ;; cbranch      conditional branch instructions
179 ;; jump         unconditional jumps
180 ;; arith        ordinary arithmetic
181 ;; arith3       a compound insn that behaves similarly to a sequence of
182 ;;              three insns of type arith
183 ;; arith3b      like above, but might end with a redirected branch
184 ;; load         from memory
185 ;; load_si      Likewise, SImode variant for general register.
186 ;; fload        Likewise, but load to fp register.
187 ;; store        to memory
188 ;; move         general purpose register to register
189 ;; mt_group     other sh4 mt instructions
190 ;; fmove        register to register, floating point
191 ;; smpy         word precision integer multiply
192 ;; dmpy         longword or doublelongword precision integer multiply
193 ;; return       rts
194 ;; pload        load of pr reg, which can't be put into delay slot of rts
195 ;; prset        copy register to pr reg, ditto
196 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
197 ;; prget        copy pr to register, ditto
198 ;; pcload       pc relative load of constant value
199 ;; pcfload      Likewise, but load to fp register.
200 ;; pcload_si    Likewise, SImode variant for general register.
201 ;; rte          return from exception
202 ;; sfunc        special function call with known used registers
203 ;; call         function call
204 ;; fp           floating point
205 ;; fdiv         floating point divide (or square root)
206 ;; gp_fpul      move from general purpose register to fpul
207 ;; fpul_gp      move from fpul to general purpose register
208 ;; mac_gp       move from mac[lh] to general purpose register
209 ;; dfp_arith, dfp_cmp,dfp_conv
210 ;; ftrc_s       fix_truncsfsi2_i4
211 ;; dfdiv        double precision floating point divide (or square root)
212 ;; cwb          ic_invalidate_line_i
213 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
214 ;; cbranch_media SHmedia conditional branch instructions
215 ;; cmp_media    SHmedia compare instructions
216 ;; dfdiv_media  SHmedia double precision divide and square root
217 ;; dfmul_media  SHmedia double precision multiply instruction
218 ;; dfparith_media SHmedia double precision floating point arithmetic
219 ;; dfpconv_media SHmedia double precision floating point conversions
220 ;; dmpy_media   SHmedia longword multiply
221 ;; fcmp_media   SHmedia floating point compare instructions
222 ;; fdiv_media   SHmedia single precision divide and square root
223 ;; fload_media  SHmedia floating point register load instructions
224 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
225 ;; fparith_media SHmedia single precision floating point arithmetic
226 ;; fpconv_media SHmedia single precision floating point conversions
227 ;; fstore_media SHmedia floating point register store instructions
228 ;; gettr_media  SHmedia gettr instruction
229 ;; invalidate_line_media SHmedia invaldiate_line sequence
230 ;; jump_media   SHmedia unconditional branch instructions
231 ;; load_media   SHmedia general register load instructions
232 ;; pt_media     SHmedia pt instruction (expanded by assembler)
233 ;; ptabs_media  SHmedia ptabs instruction
234 ;; store_media  SHmedia general register store instructions
235 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
236 ;; mac_media    SHmedia mac-style fixed point operations
237 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
238 ;; atrans       SHmedia approximate transcendential functions
239 ;; ustore_media SHmedia unaligned stores
240 ;; nil          no-op move, will be deleted.
242 (define_attr "type"
243  "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,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"
244   (const_string "other"))
246 ;; We define a new attribute namely "insn_class".We use
247 ;; this for the DFA based pipeline description.
249 ;; mt_group      SH4 "mt" group instructions.
251 ;; ex_group      SH4 "ex" group instructions.
253 ;; ls_group      SH4 "ls" group instructions.
256 (define_attr "insn_class"
257   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
258   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
259          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
260          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
261          (eq_attr "type" "cbranch,jump") (const_string "br_group")
262          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
263            (const_string "fe_group")
264          (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")]
265         (const_string "none")))
266 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
267 ;; so these do not belong in an insn group, although they are modeled
268 ;; with their own define_insn_reservations.
270 ;; Indicate what precision must be selected in fpscr for this insn, if any.
272 (define_attr "fp_mode" "single,double,none" (const_string "none"))
274 ; If a conditional branch destination is within -252..258 bytes away
275 ; from the instruction it can be 2 bytes long.  Something in the
276 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
277 ; branches are initially assumed to be 16 bytes long.
278 ; In machine_dependent_reorg, we split all branches that are longer than
279 ; 2 bytes.
281 ;; The maximum range used for SImode constant pool entries is 1018.  A final
282 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
283 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
284 ;; instruction around the pool table, 2 bytes of alignment before the table,
285 ;; and 30 bytes of alignment after the table.  That gives a maximum total
286 ;; pool size of 1058 bytes.
287 ;; Worst case code/pool content size ratio is 1:2 (using asms).
288 ;; Thus, in the worst case, there is one instruction in front of a maximum
289 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
290 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
291 ;; If we have a forward branch, the initial table will be put after the
292 ;; unconditional branch.
294 ;; ??? We could do much better by keeping track of the actual pcloads within
295 ;; the branch range and in the pcload range in front of the branch range.
297 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
298 ;; inside an le.
299 (define_attr "short_cbranch_p" "no,yes"
300   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
301          (const_string "no")
302          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
303          (const_string "yes")
304          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
305          (const_string "no")
306          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
307          (const_string "yes")
308          ] (const_string "no")))
310 (define_attr "med_branch_p" "no,yes"
311   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
312               (const_int 1988))
313          (const_string "yes")
314          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
315          (const_string "no")
316          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
317               (const_int 8186))
318          (const_string "yes")
319          ] (const_string "no")))
321 (define_attr "med_cbranch_p" "no,yes"
322   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
323               (const_int 1986))
324          (const_string "yes")
325          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
326          (const_string "no")
327          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
328                (const_int 8184))
329          (const_string "yes")
330          ] (const_string "no")))
332 (define_attr "braf_branch_p" "no,yes"
333   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
334          (const_string "no")
335          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
336               (const_int 20660))
337          (const_string "yes")
338          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
339          (const_string "no")
340          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
341               (const_int 65530))
342          (const_string "yes")
343          ] (const_string "no")))
345 (define_attr "braf_cbranch_p" "no,yes"
346   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
347          (const_string "no")
348          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
349               (const_int 20658))
350          (const_string "yes")
351          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
352          (const_string "no")
353          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
354               (const_int 65528))
355          (const_string "yes")
356          ] (const_string "no")))
358 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
359 ; For wider ranges, we need a combination of a code and a data part.
360 ; If we can get a scratch register for a long range jump, the code
361 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
362 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
363 ; long; otherwise, it must be 6 bytes long.
365 ; All other instructions are two bytes long by default.
367 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
368 ;; but getattrtab doesn't understand this.
369 (define_attr "length" ""
370   (cond [(eq_attr "type" "cbranch")
371          (cond [(eq_attr "short_cbranch_p" "yes")
372                 (const_int 2)
373                 (eq_attr "med_cbranch_p" "yes")
374                 (const_int 6)
375                 (eq_attr "braf_cbranch_p" "yes")
376                 (const_int 12)
377 ;; ??? using pc is not computed transitively.
378                 (ne (match_dup 0) (match_dup 0))
379                 (const_int 14)
380                 (ne (symbol_ref ("flag_pic")) (const_int 0))
381                 (const_int 24)
382                 ] (const_int 16))
383          (eq_attr "type" "jump")
384          (cond [(eq_attr "med_branch_p" "yes")
385                 (const_int 2)
386                 (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
387                          (symbol_ref "INSN"))
388                      (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
389                          (symbol_ref "code_for_indirect_jump_scratch")))
390                 (if_then_else (eq_attr "braf_branch_p" "yes")
391                               (const_int 6)
392                               (const_int 10))
393                 (eq_attr "braf_branch_p" "yes")
394                 (const_int 10)
395 ;; ??? using pc is not computed transitively.
396                 (ne (match_dup 0) (match_dup 0))
397                 (const_int 12)
398                 (ne (symbol_ref ("flag_pic")) (const_int 0))
399                 (const_int 22)
400                 ] (const_int 14))
401          (eq_attr "type" "pt_media")
402          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
403                        (const_int 20) (const_int 12))
404          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
405                          (const_int 4)
406                          (const_int 2))))
408 ;; (define_function_unit {name} {num-units} {n-users} {test}
409 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
411 ;; Load and store instructions save a cycle if they are aligned on a
412 ;; four byte boundary.  Using a function unit for stores encourages
413 ;; gcc to separate load and store instructions by one instruction,
414 ;; which makes it more likely that the linker will be able to word
415 ;; align them when relaxing.
417 ;; Loads have a latency of two.
418 ;; However, call insns can have a delay slot, so that we want one more
419 ;; insn to be scheduled between the load of the function address and the call.
420 ;; This is equivalent to a latency of three.
421 ;; We cannot use a conflict list for this, because we need to distinguish
422 ;; between the actual call address and the function arguments.
423 ;; ADJUST_COST can only properly handle reductions of the cost, so we
424 ;; use a latency of three here.
425 ;; We only do this for SImode loads of general registers, to make the work
426 ;; for ADJUST_COST easier.
427 (define_function_unit "memory" 1 0
428   (and (eq_attr "pipe_model" "sh1")
429        (eq_attr "type" "load_si,pcload_si"))
430   3 2)
431 (define_function_unit "memory" 1 0
432   (and (eq_attr "pipe_model" "sh1")
433        (eq_attr "type" "load,pcload,pload,store,pstore"))
434   2 2)
436 (define_function_unit "int"    1 0
437   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
439 (define_function_unit "int"    1 0
440   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
442 (define_function_unit "int"    1 0
443   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
445 ;; ??? These are approximations.
446 (define_function_unit "mpy"    1 0
447   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
448 (define_function_unit "mpy"    1 0
449   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
451 (define_function_unit "fp"     1 0
452   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
453 (define_function_unit "fp"     1 0
454   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
457 ;; SH-5 SHmedia scheduling
458 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
459 ;; single-issue machine.  It has four pipelines, the branch unit (br),
460 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
461 ;; the floating point unit (fpu).
462 ;; Here model the instructions with a latency greater than one cycle.
464 ;; Every instruction on SH-5 occupies the issue resource for at least one
465 ;; cycle.
466 (define_function_unit "sh5issue" 1 0
467   (and (eq_attr "pipe_model" "sh5media")
468        (eq_attr "type" "!pt_media,ptabs_media,invalidate_line_media,dmpy_media,load_media,fload_media,fcmp_media,fmove_media,fparith_media,dfparith_media,fpconv_media,dfpconv_media,dfmul_media,store_media,fstore_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media")) 1 1)
470 ;; Specify the various types of instruction which have latency > 1
471 (define_function_unit "sh5issue" 1 0
472   (and (eq_attr "pipe_model" "sh5media")
473        (eq_attr "type" "mcmp_media")) 2 1)
475 (define_function_unit "sh5issue" 1 0
476   (and (eq_attr "pipe_model" "sh5media")
477        (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
478 ;; but see sh_adjust_cost for mac_media exception.
480 (define_function_unit "sh5issue" 1 0
481   (and (eq_attr "pipe_model" "sh5media")
482        (eq_attr "type" "fload_media,fmove_media")) 4 1)
484 (define_function_unit "sh5issue" 1 0
485   (and (eq_attr "pipe_model" "sh5media")
486        (eq_attr "type" "d2mpy_media")) 4 2)
488 (define_function_unit "sh5issue" 1 0
489   (and (eq_attr "pipe_model" "sh5media")
490        (eq_attr "type" "pt_media,ptabs_media")) 5 1)
492 (define_function_unit "sh5issue" 1 0
493   (and (eq_attr "pipe_model" "sh5media")
494        (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
496 (define_function_unit "sh5issue" 1 0
497   (and (eq_attr "pipe_model" "sh5media")
498        (eq_attr "type" "invalidate_line_media")) 7 7)
500 (define_function_unit "sh5issue" 1 0
501   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
503 (define_function_unit "sh5issue" 1 0
504   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
506 ;; Floating-point divide and square-root occupy an additional resource,
507 ;; which is not internally pipelined.  However, other instructions
508 ;; can continue to issue.
509 (define_function_unit "sh5fds" 1 0
510   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media"))  19 19)
512 (define_function_unit "sh5fds" 1 0
513   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
515 ; Definitions for filling branch delay slots.
517 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
519 ;; ??? This should be (nil) instead of (const_int 0)
520 (define_attr "hit_stack" "yes,no"
521         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
522                    (const_int 0))
523                (const_string "no")]
524               (const_string "yes")))
526 (define_attr "interrupt_function" "no,yes"
527   (const (symbol_ref "current_function_interrupt")))
529 (define_attr "in_delay_slot" "yes,no"
530   (cond [(eq_attr "type" "cbranch") (const_string "no")
531          (eq_attr "type" "pcload,pcload_si") (const_string "no")
532          (eq_attr "needs_delay_slot" "yes") (const_string "no")
533          (eq_attr "length" "2") (const_string "yes")
534          ] (const_string "no")))
536 (define_attr "cond_delay_slot" "yes,no"
537   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
538          ] (const_string "no")))
540 (define_attr "is_sfunc" ""
541   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
543 (define_attr "is_mac_media" ""
544   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
546 (define_attr "branch_zero" "yes,no"
547   (cond [(eq_attr "type" "!cbranch") (const_string "no")
548          (ne (symbol_ref "(next_active_insn (insn)\
549                            == (prev_active_insn\
550                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
551                           && get_attr_length (next_active_insn (insn)) == 2")
552              (const_int 0))
553          (const_string "yes")]
554         (const_string "no")))
556 ;; SH4 Double-precision computation with double-precision result -
557 ;; the two halves are ready at different times.
558 (define_attr "dfp_comp" "yes,no"
559   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
560         (const_string "no")))
562 ;; Insns for which the latency of a preceding fp insn is decreased by one.
563 (define_attr "late_fp_use" "yes,no" (const_string "no"))
564 ;; And feeding insns for which this relevant.
565 (define_attr "any_fp_comp" "yes,no"
566   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
567          (const_string "yes")]
568         (const_string "no")))
570 (define_attr "any_int_load" "yes,no"
571   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
572          (const_string "yes")]
573         (const_string "no")))
575 (define_delay
576   (eq_attr "needs_delay_slot" "yes")
577   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
579 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
580 ;; and thus we can't put a pop instruction in its delay slot.
581 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
582 ;; instruction can go in the delay slot.
584 ;; Since a normal return (rts) implicitly uses the PR register,
585 ;; we can't allow PR register loads in an rts delay slot.
587 (define_delay
588   (eq_attr "type" "return")
589   [(and (eq_attr "in_delay_slot" "yes")
590         (ior (and (eq_attr "interrupt_function" "no")
591                   (eq_attr "type" "!pload,prset"))
592              (and (eq_attr "interrupt_function" "yes")
593                   (ior
594                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
595                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
597 ;; Since a call implicitly uses the PR register, we can't allow
598 ;; a PR register store in a jsr delay slot.
600 (define_delay
601   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
602   [(and (eq_attr "in_delay_slot" "yes")
603         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
605 ;; Say that we have annulled true branches, since this gives smaller and
606 ;; faster code when branches are predicted as not taken.
608 (define_delay
609   (and (eq_attr "type" "cbranch")
610        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
611   [(eq_attr "in_delay_slot" "yes") (eq_attr "cond_delay_slot" "yes") (nil)])
613 ;; -------------------------------------------------------------------------
614 ;; SImode signed integer comparisons
615 ;; -------------------------------------------------------------------------
617 (define_insn ""
618   [(set (reg:SI T_REG)
619         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
620                        (match_operand:SI 1 "arith_operand" "L,r"))
621                (const_int 0)))]
622   "TARGET_SH1"
623   "tst  %1,%0"
624   [(set_attr "type" "mt_group")])
626 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
627 ;; That would still allow reload to create cmpi instructions, but would
628 ;; perhaps allow forcing the constant into a register when that is better.
629 ;; Probably should use r0 for mem/imm compares, but force constant into a
630 ;; register for pseudo/imm compares.
632 (define_insn "cmpeqsi_t"
633   [(set (reg:SI T_REG)
634         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
635                (match_operand:SI 1 "arith_operand" "N,rI,r")))]
636   "TARGET_SH1"
637   "@
638         tst     %0,%0
639         cmp/eq  %1,%0
640         cmp/eq  %1,%0"
641    [(set_attr "type" "mt_group")])
643 (define_insn "cmpgtsi_t"
644   [(set (reg:SI T_REG)
645         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
646                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
647   "TARGET_SH1"
648   "@
649         cmp/gt  %1,%0
650         cmp/pl  %0"
651    [(set_attr "type" "mt_group")])
653 (define_insn "cmpgesi_t"
654   [(set (reg:SI T_REG)
655         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
656                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
657   "TARGET_SH1"
658   "@
659         cmp/ge  %1,%0
660         cmp/pz  %0"
661    [(set_attr "type" "mt_group")])
663 ;; -------------------------------------------------------------------------
664 ;; SImode unsigned integer comparisons
665 ;; -------------------------------------------------------------------------
667 (define_insn "cmpgeusi_t"
668   [(set (reg:SI T_REG)
669         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
670                 (match_operand:SI 1 "arith_reg_operand" "r")))]
671   "TARGET_SH1"
672   "cmp/hs       %1,%0"
673    [(set_attr "type" "mt_group")])
675 (define_insn "cmpgtusi_t"
676   [(set (reg:SI T_REG)
677         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
678                 (match_operand:SI 1 "arith_reg_operand" "r")))]
679   "TARGET_SH1"
680   "cmp/hi       %1,%0"
681    [(set_attr "type" "mt_group")])
683 ;; We save the compare operands in the cmpxx patterns and use them when
684 ;; we generate the branch.
686 (define_expand "cmpsi"
687   [(set (reg:SI T_REG)
688         (compare (match_operand:SI 0 "arith_operand" "")
689                  (match_operand:SI 1 "arith_operand" "")))]
690   "TARGET_SH1"
691   "
693   sh_compare_op0 = operands[0];
694   sh_compare_op1 = operands[1];
695   DONE;
698 ;; -------------------------------------------------------------------------
699 ;; DImode signed integer comparisons
700 ;; -------------------------------------------------------------------------
702 ;; ??? Could get better scheduling by splitting the initial test from the
703 ;; rest of the insn after reload.  However, the gain would hardly justify
704 ;; the sh.md size increase necessary to do that.
706 (define_insn ""
707   [(set (reg:SI T_REG)
708         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
709                        (match_operand:DI 1 "arith_operand" "r"))
710                (const_int 0)))]
711   "TARGET_SH1"
712   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
713                                  insn, operands);"
714   [(set_attr "length" "6")
715    (set_attr "type" "arith3b")])
717 (define_insn "cmpeqdi_t"
718   [(set (reg:SI T_REG)
719         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
720                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
721   "TARGET_SH1"
722   "@
723         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
724         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
725   [(set_attr "length" "6")
726    (set_attr "type" "arith3b")])
728 (define_split
729   [(set (reg:SI T_REG)
730         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
731                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
732 ;; If we applied this split when not optimizing, it would only be
733 ;; applied during the machine-dependent reorg, when no new basic blocks
734 ;; may be created.
735   "TARGET_SH1 && reload_completed && optimize"
736   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
737    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
738                            (label_ref (match_dup 6))
739                            (pc)))
740    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
741    (match_dup 6)]
742   "
744   operands[2]
745     = gen_rtx_REG (SImode,
746                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
747   operands[3]
748     = (operands[1] == const0_rtx
749        ? const0_rtx
750        : gen_rtx_REG (SImode,
751                       true_regnum (operands[1])
752                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
753   operands[4] = gen_lowpart (SImode, operands[0]);
754   operands[5] = gen_lowpart (SImode, operands[1]);
755   operands[6] = gen_label_rtx ();
758 (define_insn "cmpgtdi_t"
759   [(set (reg:SI T_REG)
760         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
761                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
762   "TARGET_SH2"
763   "@
764         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
765         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
766   [(set_attr "length" "8")
767    (set_attr "type" "arith3")])
769 (define_insn "cmpgedi_t"
770   [(set (reg:SI T_REG)
771         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
772                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
773   "TARGET_SH2"
774   "@
775         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
776         cmp/pz\\t%S0"
777   [(set_attr "length" "8,2")
778    (set_attr "type" "arith3,mt_group")])
780 ;; -------------------------------------------------------------------------
781 ;; DImode unsigned integer comparisons
782 ;; -------------------------------------------------------------------------
784 (define_insn "cmpgeudi_t"
785   [(set (reg:SI T_REG)
786         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
787                 (match_operand:DI 1 "arith_reg_operand" "r")))]
788   "TARGET_SH2"
789   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
790   [(set_attr "length" "8")
791    (set_attr "type" "arith3")])
793 (define_insn "cmpgtudi_t"
794   [(set (reg:SI T_REG)
795         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
796                 (match_operand:DI 1 "arith_reg_operand" "r")))]
797   "TARGET_SH2"
798   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
799   [(set_attr "length" "8")
800    (set_attr "type" "arith3")])
802 (define_insn "cmpeqdi_media"
803   [(set (match_operand:DI 0 "register_operand" "=r")
804         (eq:DI (match_operand:DI 1 "register_operand" "%r")
805                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
806   "TARGET_SHMEDIA"
807   "cmpeq        %1, %N2, %0"
808   [(set_attr "type" "cmp_media")])
810 (define_insn "cmpgtdi_media"
811   [(set (match_operand:DI 0 "register_operand" "=r")
812         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
813                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
814   "TARGET_SHMEDIA"
815   "cmpgt        %N1, %N2, %0"
816   [(set_attr "type" "cmp_media")])
818 (define_insn "cmpgtudi_media"
819   [(set (match_operand:DI 0 "register_operand" "=r")
820         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
821                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
822   "TARGET_SHMEDIA"
823   "cmpgtu       %N1, %N2, %0"
824   [(set_attr "type" "cmp_media")])
826 ;; We save the compare operands in the cmpxx patterns and use them when
827 ;; we generate the branch.
829 (define_expand "cmpdi"
830   [(set (reg:SI T_REG)
831         (compare (match_operand:DI 0 "arith_operand" "")
832                  (match_operand:DI 1 "arith_operand" "")))]
833   "TARGET_SH2 || TARGET_SHMEDIA"
834   "
836   sh_compare_op0 = operands[0];
837   sh_compare_op1 = operands[1];
838   DONE;
840 ;; -------------------------------------------------------------------------
841 ;; Conditional move instructions
842 ;; -------------------------------------------------------------------------
844 ;; The insn names may seem reversed, but note that cmveq performs the move
845 ;; if op1 == 0, and cmvne does it if op1 != 0.
847 (define_insn "movdicc_false"
848   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
849         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
850                              (const_int 0))
851          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
852          (match_operand:DI 3 "arith_reg_operand" "0")))]
853   "TARGET_SHMEDIA"
854   "cmveq        %1, %N2, %0"
855   [(set_attr "type" "arith_media")])
857 (define_insn "movdicc_true"
858   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
859         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
860                              (const_int 0))
861          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
862          (match_operand:DI 3 "arith_reg_operand" "0")))]
863   "TARGET_SHMEDIA"
864   "cmvne        %1, %N2, %0"
865   [(set_attr "type" "arith_media")])
867 (define_expand "movdicc"
868   [(set (match_operand:DI 0 "register_operand" "")
869         (if_then_else:DI (match_operand 1 "comparison_operator" "")
870                          (match_operand:DI 2 "register_operand" "")
871                          (match_operand:DI 3 "register_operand" "")))]
872   "TARGET_SHMEDIA"
873   "
875   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
876       && GET_MODE (sh_compare_op0) == DImode
877       && sh_compare_op1 == const0_rtx)
878     operands[1] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
879                            sh_compare_op0, sh_compare_op1);
880   else
881     {
882       rtx tmp;
884       if (no_new_pseudos)
885         FAIL;
887       tmp = gen_reg_rtx (DImode);
889       switch (GET_CODE (operands[1]))
890         {
891         case EQ:
892           emit_insn (gen_seq (tmp));
893           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
894           break;
896         case NE:
897           emit_insn (gen_seq (tmp));
898           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
899           break;
901         case GT:
902           emit_insn (gen_sgt (tmp));
903           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
904           break;
906         case LT:
907           emit_insn (gen_slt (tmp));
908           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
909           break;
911         case GE:
912           emit_insn (gen_slt (tmp));
913           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
914           break;
916         case LE:
917           emit_insn (gen_sgt (tmp));
918           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
919           break;
921         case GTU:
922           emit_insn (gen_sgtu (tmp));
923           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
924           break;
926         case LTU:
927           emit_insn (gen_sltu (tmp));
928           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
929           break;
931         case GEU:
932           emit_insn (gen_sltu (tmp));
933           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
934           break;
936         case LEU:
937           emit_insn (gen_sgtu (tmp));
938           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
939           break;
941         case UNORDERED:
942           emit_insn (gen_sunordered (tmp));
943           operands[1] = gen_rtx (NE, VOIDmode, tmp, const0_rtx);
944           break;
946         case ORDERED:
947           emit_insn (gen_sunordered (tmp));
948           operands[1] = gen_rtx (EQ, VOIDmode, tmp, const0_rtx);
949           break;
951         case UNEQ:
952         case UNGE:
953         case UNGT:
954         case UNLE:
955         case UNLT:
956         case LTGT:
957           FAIL;
959         default:
960           abort ();
961         }
962     }
965 ;; -------------------------------------------------------------------------
966 ;; Addition instructions
967 ;; -------------------------------------------------------------------------
969 (define_expand "adddi3"
970   [(set (match_operand:DI 0 "arith_reg_operand" "")
971         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
972                  (match_operand:DI 2 "arith_operand" "")))]
973   ""
974   "
976   if (TARGET_SH1)
977     {
978       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
979         FAIL;
980       operands[2] = force_reg (DImode, operands[2]);
981       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
982       DONE;
983     }
986 (define_insn "*adddi3_media"
987   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
988         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
989                  (match_operand:DI 2 "arith_operand" "r,P")))]
990   "TARGET_SHMEDIA"
991   "@
992         add     %1, %2, %0
993         addi    %1, %2, %0"
994   [(set_attr "type" "arith_media")])
996 (define_insn "adddi3z_media"
997   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
998         (zero_extend:DI
999          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1000                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1001   "TARGET_SHMEDIA"
1002   "addz.l       %1, %N2, %0"
1003   [(set_attr "type" "arith_media")])
1005 (define_insn "adddi3_compact"
1006   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1007         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1008                  (match_operand:DI 2 "arith_reg_operand" "r")))
1009    (clobber (reg:SI T_REG))]
1010   "TARGET_SH1"
1011   "#"
1012   [(set_attr "length" "6")])
1014 (define_split
1015   [(set (match_operand:DI 0 "arith_reg_operand" "")
1016         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1017                  (match_operand:DI 2 "arith_reg_operand" "")))
1018    (clobber (reg:SI T_REG))]
1019   "TARGET_SH1 && reload_completed"
1020   [(const_int 0)]
1021   "
1023   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1024   high0 = gen_rtx_REG (SImode,
1025                        true_regnum (operands[0])
1026                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1027   high2 = gen_rtx_REG (SImode,
1028                        true_regnum (operands[2])
1029                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1030   emit_insn (gen_clrt ());
1031   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1032   emit_insn (gen_addc1 (high0, high0, high2));
1033   DONE;
1036 (define_insn "addc"
1037   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1038         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1039                           (match_operand:SI 2 "arith_reg_operand" "r"))
1040                  (reg:SI T_REG)))
1041    (set (reg:SI T_REG)
1042         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1043   "TARGET_SH1"
1044   "addc %2,%0"
1045   [(set_attr "type" "arith")])
1047 (define_insn "addc1"
1048   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1049         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1050                           (match_operand:SI 2 "arith_reg_operand" "r"))
1051                  (reg:SI T_REG)))
1052    (clobber (reg:SI T_REG))]
1053   "TARGET_SH1"
1054   "addc %2,%0"
1055   [(set_attr "type" "arith")])
1057 (define_expand "addsi3"
1058   [(set (match_operand:SI 0 "arith_reg_operand" "")
1059         (plus:SI (match_operand:SI 1 "arith_operand" "")
1060                  (match_operand:SI 2 "arith_operand" "")))]
1061   ""
1062   "
1064   if (TARGET_SHMEDIA)
1065     operands[1] = force_reg (SImode, operands[1]);
1068 (define_insn "addsi3_media"
1069   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1070         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1071                  (match_operand:SI 2 "arith_operand" "r,P")))]
1072   "TARGET_SHMEDIA"
1073   "@
1074         add.l   %1, %2, %0
1075         addi.l  %1, %2, %0"
1076   [(set_attr "type" "arith_media")])
1078 (define_insn "*addsi3_compact"
1079   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1080         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1081                  (match_operand:SI 2 "arith_operand" "rI")))]
1082   "TARGET_SH1"
1083   "add  %2,%0"
1084   [(set_attr "type" "arith")])
1086 ;; -------------------------------------------------------------------------
1087 ;; Subtraction instructions
1088 ;; -------------------------------------------------------------------------
1090 (define_expand "subdi3"
1091   [(set (match_operand:DI 0 "arith_reg_operand" "")
1092         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1093                   (match_operand:DI 2 "arith_reg_operand" "")))]
1094   ""
1095   "
1097   if (TARGET_SH1)
1098     {
1099       operands[1] = force_reg (DImode, operands[1]);
1100       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1101       DONE;
1102     }
1105 (define_insn "*subdi3_media"
1106   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1107         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1108                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1109   "TARGET_SHMEDIA"
1110   "sub  %N1, %2, %0"
1111   [(set_attr "type" "arith_media")])
1113 (define_insn "subdi3_compact"
1114   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1115         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1116                  (match_operand:DI 2 "arith_reg_operand" "r")))
1117    (clobber (reg:SI T_REG))]
1118   "TARGET_SH1"
1119   "#"
1120   [(set_attr "length" "6")])
1122 (define_split
1123   [(set (match_operand:DI 0 "arith_reg_operand" "")
1124         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1125                   (match_operand:DI 2 "arith_reg_operand" "")))
1126    (clobber (reg:SI T_REG))]
1127   "TARGET_SH1 && reload_completed"
1128   [(const_int 0)]
1129   "
1131   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1132   high0 = gen_rtx_REG (SImode,
1133                        true_regnum (operands[0])
1134                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1135   high2 = gen_rtx_REG (SImode,
1136                        true_regnum (operands[2])
1137                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1138   emit_insn (gen_clrt ());
1139   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1140   emit_insn (gen_subc1 (high0, high0, high2));
1141   DONE;
1144 (define_insn "subc"
1145   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1146         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1147                             (match_operand:SI 2 "arith_reg_operand" "r"))
1148                   (reg:SI T_REG)))
1149    (set (reg:SI T_REG)
1150         (gtu:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1151   "TARGET_SH1"
1152   "subc %2,%0"
1153   [(set_attr "type" "arith")])
1155 (define_insn "subc1"
1156   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1157         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1158                             (match_operand:SI 2 "arith_reg_operand" "r"))
1159                   (reg:SI T_REG)))
1160    (clobber (reg:SI T_REG))]
1161   "TARGET_SH1"
1162   "subc %2,%0"
1163   [(set_attr "type" "arith")])
1165 (define_insn "*subsi3_internal"
1166   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1167         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1168                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1169   "TARGET_SH1"
1170   "sub  %2,%0"
1171   [(set_attr "type" "arith")])
1173 (define_insn "*subsi3_media"
1174   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1175         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1176                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1177   "TARGET_SHMEDIA"
1178   "sub.l        %N1, %2, %0"
1179   [(set_attr "type" "arith_media")])
1181 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1182 ;; will sometimes save one instruction.  Otherwise we might get
1183 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1184 ;; are the same.
1186 (define_expand "subsi3"
1187   [(set (match_operand:SI 0 "arith_reg_operand" "")
1188         (minus:SI (match_operand:SI 1 "arith_operand" "")
1189                   (match_operand:SI 2 "arith_reg_operand" "")))]
1190   ""
1191   "
1193   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1194     {
1195       emit_insn (gen_negsi2 (operands[0], operands[2]));
1196       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1197       DONE;
1198     }
1199   if (TARGET_SHMEDIA)
1200     {
1201       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1202         FAIL;
1203       if (operands[1] != const0_rtx)
1204         operands[1] = force_reg (SImode, operands[1]);
1205     }
1208 ;; -------------------------------------------------------------------------
1209 ;; Division instructions
1210 ;; -------------------------------------------------------------------------
1212 ;; We take advantage of the library routines which don't clobber as many
1213 ;; registers as a normal function call would.
1215 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1216 ;; also has an effect on the register that holds the address of the sfunc.
1217 ;; To make this work, we have an extra dummy insn that shows the use
1218 ;; of this register for reorg.
1220 (define_insn "use_sfunc_addr"
1221   [(set (reg:SI PR_REG)
1222         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1223   "TARGET_SH1"
1224   ""
1225   [(set_attr "length" "0")])
1227 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1228 ;; hard register 0.  If we used hard register 0, then the next instruction
1229 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1230 ;; gets allocated to a stack slot that needs its address reloaded, then
1231 ;; there is nothing to prevent reload from using r0 to reload the address.
1232 ;; This reload would clobber the value in r0 we are trying to store.
1233 ;; If we let reload allocate r0, then this problem can never happen.
1235 (define_insn "udivsi3_i1"
1236   [(set (match_operand:SI 0 "register_operand" "=z")
1237         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1238    (clobber (reg:SI T_REG))
1239    (clobber (reg:SI PR_REG))
1240    (clobber (reg:SI R4_REG))
1241    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1242   "TARGET_SH1 && ! TARGET_SH4"
1243   "jsr  @%1%#"
1244   [(set_attr "type" "sfunc")
1245    (set_attr "needs_delay_slot" "yes")])
1247 ; Since shmedia-nofpu code could be linked against shcompact code, and
1248 ; the udivsi3 libcall has the same name, we must consider all registers
1249 ; clobbered that are in the union of the registers clobbered by the
1250 ; shmedia and the shcompact implementation.  Note, if the shcompact
1251 ; implemenation actually used shcompact code, we'd need to clobber
1252 ; also r23 and fr23.
1253 (define_insn "udivsi3_i1_media"
1254   [(set (match_operand:SI 0 "register_operand" "=z")
1255         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1256    (clobber (reg:SI T_MEDIA_REG))
1257    (clobber (reg:SI PR_MEDIA_REG))
1258    (clobber (reg:SI R20_REG))
1259    (clobber (reg:SI R21_REG))
1260    (clobber (reg:SI R22_REG))
1261    (clobber (reg:DI TR0_REG))
1262    (clobber (reg:DI TR1_REG))
1263    (clobber (reg:DI TR2_REG))
1264    (use (match_operand:DI 1 "target_operand" "b"))]
1265   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1266   "blink        %1, r18"
1267   [(set_attr "type" "sfunc")
1268    (set_attr "needs_delay_slot" "yes")])
1270 (define_expand "udivsi3_i4_media"
1271   [(set (match_dup 3)
1272         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1273    (set (match_dup 4)
1274         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1275    (set (match_dup 5) (float:DF (match_dup 3)))
1276    (set (match_dup 6) (float:DF (match_dup 4)))
1277    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1278    (set (match_dup 8) (fix:DI (match_dup 7)))
1279    (set (match_operand:SI 0 "register_operand" "")
1280         (truncate:SI (match_dup 8)))]
1281   "TARGET_SHMEDIA_FPU"
1282   "
1284   operands[3] = gen_reg_rtx (DImode);
1285   operands[4] = gen_reg_rtx (DImode);
1286   operands[5] = gen_reg_rtx (DFmode);
1287   operands[6] = gen_reg_rtx (DFmode);
1288   operands[7] = gen_reg_rtx (DFmode);
1289   operands[8] = gen_reg_rtx (DImode);
1292 (define_insn "udivsi3_i4"
1293   [(set (match_operand:SI 0 "register_operand" "=y")
1294         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1295    (clobber (reg:SI T_REG))
1296    (clobber (reg:SI PR_REG))
1297    (clobber (reg:DF DR0_REG))
1298    (clobber (reg:DF DR2_REG))
1299    (clobber (reg:DF DR4_REG))
1300    (clobber (reg:SI R0_REG))
1301    (clobber (reg:SI R1_REG))
1302    (clobber (reg:SI R4_REG))
1303    (clobber (reg:SI R5_REG))
1304    (use (reg:PSI FPSCR_REG))
1305    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1306   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1307   "jsr  @%1%#"
1308   [(set_attr "type" "sfunc")
1309    (set_attr "fp_mode" "double")
1310    (set_attr "needs_delay_slot" "yes")])
1312 (define_insn "udivsi3_i4_single"
1313   [(set (match_operand:SI 0 "register_operand" "=y")
1314         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1315    (clobber (reg:SI T_REG))
1316    (clobber (reg:SI PR_REG))
1317    (clobber (reg:DF DR0_REG))
1318    (clobber (reg:DF DR2_REG))
1319    (clobber (reg:DF DR4_REG))
1320    (clobber (reg:SI R0_REG))
1321    (clobber (reg:SI R1_REG))
1322    (clobber (reg:SI R4_REG))
1323    (clobber (reg:SI R5_REG))
1324    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1325   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1326   "jsr  @%1%#"
1327   [(set_attr "type" "sfunc")
1328    (set_attr "needs_delay_slot" "yes")])
1330 (define_expand "udivsi3"
1331   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1332    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1333    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1334    (parallel [(set (match_operand:SI 0 "register_operand" "")
1335                    (udiv:SI (reg:SI R4_REG)
1336                             (reg:SI R5_REG)))
1337               (clobber (reg:SI T_REG))
1338               (clobber (reg:SI PR_REG))
1339               (clobber (reg:SI R4_REG))
1340               (use (match_dup 3))])]
1341   ""
1342   "
1344   rtx first = 0, last;
1346   operands[3] = gen_reg_rtx (Pmode);
1347   /* Emit the move of the address to a pseudo outside of the libcall.  */
1348   if (TARGET_HARD_SH4 && TARGET_SH3E)
1349     {
1350       emit_move_insn (operands[3],
1351                       gen_rtx_SYMBOL_REF (SImode, \"__udivsi3_i4\"));
1352       if (TARGET_FPU_SINGLE)
1353         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1354       else
1355         last = gen_udivsi3_i4 (operands[0], operands[3]);
1356     }
1357   else if (TARGET_SHMEDIA_FPU)
1358     {
1359       operands[1] = force_reg (SImode, operands[1]);
1360       operands[2] = force_reg (SImode, operands[2]);
1361       last = gen_udivsi3_i4_media (operands[0], operands[1], operands[2]);
1362       first = last;
1363     }
1364   else if (TARGET_SH5)
1365     {
1366       emit_move_insn (operands[3],
1367                       gen_rtx_SYMBOL_REF (Pmode,
1368                                           (TARGET_FPU_ANY
1369                                            ? \"__udivsi3_i4\"
1370                                            : \"__udivsi3\")));
1372       if (TARGET_SHMEDIA)
1373         last = gen_udivsi3_i1_media (operands[0],
1374                                      Pmode == DImode
1375                                      ? operands[3]
1376                                      : gen_rtx_SUBREG (DImode, operands[3],
1377                                                        0));
1378       else if (TARGET_FPU_ANY)
1379         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1380       else
1381         last = gen_udivsi3_i1 (operands[0], operands[3]);
1382     }
1383   else
1384     {
1385       emit_move_insn (operands[3],
1386                       gen_rtx_SYMBOL_REF (SImode, \"__udivsi3\"));
1387       last = gen_udivsi3_i1 (operands[0], operands[3]);
1388     }
1389   if (! first)
1390     {
1391       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1392       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1393     }
1394   last = emit_insn (last);
1395   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1396      invariant code motion can move it.  */
1397   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1398   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1399   DONE;
1402 (define_insn "divsi3_i1"
1403   [(set (match_operand:SI 0 "register_operand" "=z")
1404         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1405    (clobber (reg:SI T_REG))
1406    (clobber (reg:SI PR_REG))
1407    (clobber (reg:SI R1_REG))
1408    (clobber (reg:SI R2_REG))
1409    (clobber (reg:SI R3_REG))
1410    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1411   "TARGET_SH1 && ! TARGET_SH4"
1412   "jsr  @%1%#"
1413   [(set_attr "type" "sfunc")
1414    (set_attr "needs_delay_slot" "yes")])
1416 ; Since shmedia-nofpu code could be linked against shcompact code, and
1417 ; the sdivsi3 libcall has the same name, we must consider all registers
1418 ; clobbered that are in the union of the registers clobbered by the
1419 ; shmedia and the shcompact implementation.  Note, if the shcompact
1420 ; implemenation actually used shcompact code, we'd need to clobber
1421 ; also r22, r23 and fr23.
1422 (define_insn "divsi3_i1_media"
1423   [(set (match_operand:SI 0 "register_operand" "=z")
1424         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1425    (clobber (reg:SI T_MEDIA_REG))
1426    (clobber (reg:SI PR_MEDIA_REG))
1427    (clobber (reg:SI R1_REG))
1428    (clobber (reg:SI R2_REG))
1429    (clobber (reg:SI R3_REG))
1430    (clobber (reg:SI R20_REG))
1431    (clobber (reg:SI R21_REG))
1432    (clobber (reg:DI TR0_REG))
1433    (clobber (reg:DI TR1_REG))
1434    (clobber (reg:DI TR2_REG))
1435    (use (match_operand:DI 1 "target_operand" "b"))]
1436   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1437   "blink        %1, r18"
1438   [(set_attr "type" "sfunc")])
1440 (define_expand "divsi3_i4_media"
1441   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1442    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1443    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1444    (set (match_operand:SI 0 "register_operand" "=r")
1445         (fix:SI (match_dup 5)))]
1446   "TARGET_SHMEDIA_FPU"
1447   "
1449   operands[3] = gen_reg_rtx (DFmode);
1450   operands[4] = gen_reg_rtx (DFmode);
1451   operands[5] = gen_reg_rtx (DFmode);
1454 (define_insn "divsi3_i4"
1455   [(set (match_operand:SI 0 "register_operand" "=y")
1456         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1457    (clobber (reg:SI PR_REG))
1458    (clobber (reg:DF DR0_REG))
1459    (clobber (reg:DF DR2_REG))
1460    (use (reg:PSI FPSCR_REG))
1461    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1462   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1463   "jsr  @%1%#"
1464   [(set_attr "type" "sfunc")
1465    (set_attr "fp_mode" "double")
1466    (set_attr "needs_delay_slot" "yes")])
1468 (define_insn "divsi3_i4_single"
1469   [(set (match_operand:SI 0 "register_operand" "=y")
1470         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1471    (clobber (reg:SI PR_REG))
1472    (clobber (reg:DF DR0_REG))
1473    (clobber (reg:DF DR2_REG))
1474    (clobber (reg:SI R2_REG))
1475    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1476   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1477   "jsr  @%1%#"
1478   [(set_attr "type" "sfunc")
1479    (set_attr "needs_delay_slot" "yes")])
1481 (define_expand "divsi3"
1482   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1483    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1484    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1485    (parallel [(set (match_operand:SI 0 "register_operand" "")
1486                    (div:SI (reg:SI R4_REG)
1487                            (reg:SI R5_REG)))
1488               (clobber (reg:SI T_REG))
1489               (clobber (reg:SI PR_REG))
1490               (clobber (reg:SI R1_REG))
1491               (clobber (reg:SI R2_REG))
1492               (clobber (reg:SI R3_REG))
1493               (use (match_dup 3))])]
1494   ""
1495   "
1497   rtx first = 0, last;
1499   operands[3] = gen_reg_rtx (Pmode);
1500   /* Emit the move of the address to a pseudo outside of the libcall.  */
1501   if (TARGET_HARD_SH4 && TARGET_SH3E)
1502     {
1503       emit_move_insn (operands[3],
1504                       gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3_i4\"));
1505       if (TARGET_FPU_SINGLE)
1506         last = gen_divsi3_i4_single (operands[0], operands[3]);
1507       else
1508         last = gen_divsi3_i4 (operands[0], operands[3]);
1509     }
1510   else if (TARGET_SHMEDIA_FPU)
1511     {
1512       operands[1] = force_reg (SImode, operands[1]);
1513       operands[2] = force_reg (SImode, operands[2]);
1514       last = gen_divsi3_i4_media (operands[0], operands[1], operands[2]);
1515       first = last;
1516     }
1517   else if (TARGET_SH5)
1518     {
1519       emit_move_insn (operands[3],
1520                       gen_rtx_SYMBOL_REF (Pmode,
1521                                           (TARGET_FPU_ANY
1522                                            ? \"__sdivsi3_i4\"
1523                                            : \"__sdivsi3\")));
1525       if (TARGET_SHMEDIA)
1526         last = gen_divsi3_i1_media (operands[0],
1527                                     Pmode == DImode
1528                                     ? operands[3]
1529                                     : gen_rtx_SUBREG (DImode, operands[3],
1530                                                       0));
1531       else if (TARGET_FPU_ANY)
1532         last = gen_divsi3_i4_single (operands[0], operands[3]);
1533       else
1534         last = gen_divsi3_i1 (operands[0], operands[3]);
1535     }
1536   else
1537     {
1538       emit_move_insn (operands[3], gen_rtx_SYMBOL_REF (SImode, \"__sdivsi3\"));
1539       last = gen_divsi3_i1 (operands[0], operands[3]);
1540     }
1541   if (! first)
1542     {
1543       first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1544       emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1545     }
1546   last = emit_insn (last);
1547   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1548      invariant code motion can move it.  */
1549   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1550   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1551   DONE;
1554 ;; -------------------------------------------------------------------------
1555 ;; Multiplication instructions
1556 ;; -------------------------------------------------------------------------
1558 (define_insn "umulhisi3_i"
1559   [(set (reg:SI MACL_REG)
1560         (mult:SI (zero_extend:SI
1561                   (match_operand:HI 0 "arith_reg_operand" "r"))
1562                  (zero_extend:SI
1563                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1564   "TARGET_SH1"
1565   "mulu.w       %1,%0"
1566   [(set_attr "type" "smpy")])
1568 (define_insn "mulhisi3_i"
1569   [(set (reg:SI MACL_REG)
1570         (mult:SI (sign_extend:SI
1571                   (match_operand:HI 0 "arith_reg_operand" "r"))
1572                  (sign_extend:SI
1573                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1574   "TARGET_SH1"
1575   "muls.w       %1,%0"
1576   [(set_attr "type" "smpy")])
1578 (define_expand "mulhisi3"
1579   [(set (reg:SI MACL_REG)
1580         (mult:SI (sign_extend:SI
1581                   (match_operand:HI 1 "arith_reg_operand" ""))
1582                  (sign_extend:SI
1583                   (match_operand:HI 2 "arith_reg_operand" ""))))
1584    (set (match_operand:SI 0 "arith_reg_operand" "")
1585         (reg:SI MACL_REG))]
1586   "TARGET_SH1"
1587   "
1589   rtx first, last;
1591   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1592   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1593   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1594      invariant code motion can move it.  */
1595   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1596   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1597   /* expand_binop can't find a suitable code in umul_widen_optab to
1598      make a REG_EQUAL note from, so make one here.
1599      See also smulsi3_highpart.
1600      ??? Alternatively, we could put this at the calling site of expand_binop,
1601      i.e. expand_expr.  */
1602   REG_NOTES (last)
1603     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1604                          REG_NOTES (last));
1605   DONE;
1608 (define_expand "umulhisi3"
1609   [(set (reg:SI MACL_REG)
1610         (mult:SI (zero_extend:SI
1611                   (match_operand:HI 1 "arith_reg_operand" ""))
1612                  (zero_extend:SI
1613                   (match_operand:HI 2 "arith_reg_operand" ""))))
1614    (set (match_operand:SI 0 "arith_reg_operand" "")
1615         (reg:SI MACL_REG))]
1616   "TARGET_SH1"
1617   "
1619   rtx first, last;
1621   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1622   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1623   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1624      invariant code motion can move it.  */
1625   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1626   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1627   /* expand_binop can't find a suitable code in umul_widen_optab to
1628      make a REG_EQUAL note from, so make one here.
1629      See also smulsi3_highpart.
1630      ??? Alternatively, we could put this at the calling site of expand_binop,
1631      i.e. expand_expr.  */
1632   REG_NOTES (last)
1633     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1634                          REG_NOTES (last));
1635   DONE;
1638 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1639 ;; a call to a routine which clobbers known registers.
1641 (define_insn ""
1642   [(set (match_operand:SI 1 "register_operand" "=z")
1643         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1644    (clobber (reg:SI MACL_REG))
1645    (clobber (reg:SI T_REG))
1646    (clobber (reg:SI PR_REG))
1647    (clobber (reg:SI R3_REG))
1648    (clobber (reg:SI R2_REG))
1649    (clobber (reg:SI R1_REG))
1650    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1651   "TARGET_SH1"
1652   "jsr  @%0%#"
1653   [(set_attr "type" "sfunc")
1654    (set_attr "needs_delay_slot" "yes")])
1656 (define_expand "mulsi3_call"
1657   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1658    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1659    (parallel[(set (match_operand:SI 0 "register_operand" "")
1660                   (mult:SI (reg:SI R4_REG)
1661                            (reg:SI R5_REG)))
1662              (clobber (reg:SI MACL_REG))
1663              (clobber (reg:SI T_REG))
1664              (clobber (reg:SI PR_REG))
1665              (clobber (reg:SI R3_REG))
1666              (clobber (reg:SI R2_REG))
1667              (clobber (reg:SI R1_REG))
1668              (use (match_operand:SI 3 "register_operand" ""))])]
1669   "TARGET_SH1"
1670   "")
1672 (define_insn "mul_l"
1673   [(set (reg:SI MACL_REG)
1674         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1675                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1676   "TARGET_SH2"
1677   "mul.l        %1,%0"
1678   [(set_attr "type" "dmpy")])
1680 (define_expand "mulsi3"
1681   [(set (reg:SI MACL_REG)
1682         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1683                   (match_operand:SI 2 "arith_reg_operand" "")))
1684    (set (match_operand:SI 0 "arith_reg_operand" "")
1685         (reg:SI MACL_REG))]
1686   "TARGET_SH1"
1687   "
1689   rtx first, last;
1691   if (!TARGET_SH2)
1692     {
1693       /* The address must be set outside the libcall,
1694          since it goes into a pseudo.  */
1695       rtx sym = gen_rtx_SYMBOL_REF (SImode, \"__mulsi3\");
1696       rtx addr = force_reg (SImode, sym);
1697       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1698                                    operands[2], addr);
1699       first = insns;
1700       last = emit_insn (insns);
1701     }
1702   else
1703     {
1704       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1706       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1707       /* consec_sets_giv can only recognize the first insn that sets a
1708          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1709          note.  */
1710       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1711     }
1712   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1713      invariant code motion can move it.  */
1714   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1715   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1716   DONE;
1719 (define_insn "mulsidi3_i"
1720   [(set (reg:SI MACH_REG)
1721         (truncate:SI
1722          (lshiftrt:DI
1723           (mult:DI
1724            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1725            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1726           (const_int 32))))
1727    (set (reg:SI MACL_REG)
1728         (mult:SI (match_dup 0)
1729                  (match_dup 1)))]
1730   "TARGET_SH2"
1731   "dmuls.l      %1,%0"
1732   [(set_attr "type" "dmpy")])
1734 (define_expand "mulsidi3"
1735   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1736         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1737                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1738   "TARGET_SH2 || TARGET_SHMEDIA"
1739   "
1741   if (TARGET_SH2)
1742     {
1743        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1744                                         operands[2]));
1745        DONE;
1746     }
1749 (define_insn "mulsidi3_media"
1750   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1751         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1752                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1753   "TARGET_SHMEDIA"
1754   "muls.l       %1, %2, %0"
1755   [(set_attr "type" "dmpy_media")])
1757 (define_insn "mulsidi3_compact"
1758   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1759         (mult:DI
1760          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1761          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1762    (clobber (reg:SI MACH_REG))
1763    (clobber (reg:SI MACL_REG))]
1764   "TARGET_SH2"
1765   "#")
1767 (define_split
1768   [(set (match_operand:DI 0 "arith_reg_operand" "")
1769         (mult:DI
1770          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1771          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1772    (clobber (reg:SI MACH_REG))
1773    (clobber (reg:SI MACL_REG))]
1774   "TARGET_SH2"
1775   [(const_int 0)]
1776   "
1778   rtx low_dst = gen_lowpart (SImode, operands[0]);
1779   rtx high_dst = gen_highpart (SImode, operands[0]);
1781   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1783   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1784   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1785   /* We need something to tag the possible REG_EQUAL notes on to.  */
1786   emit_move_insn (operands[0], operands[0]);
1787   DONE;
1790 (define_insn "umulsidi3_i"
1791   [(set (reg:SI MACH_REG)
1792         (truncate:SI
1793          (lshiftrt:DI
1794           (mult:DI
1795            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1796            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1797           (const_int 32))))
1798    (set (reg:SI MACL_REG)
1799         (mult:SI (match_dup 0)
1800                  (match_dup 1)))]
1801   "TARGET_SH2"
1802   "dmulu.l      %1,%0"
1803   [(set_attr "type" "dmpy")])
1805 (define_expand "umulsidi3"
1806   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1807         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1808                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1809   "TARGET_SH2 || TARGET_SHMEDIA"
1810   "
1812   if (TARGET_SH2)
1813     {
1814        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1815                                          operands[2]));
1816        DONE;
1817     }
1820 (define_insn "umulsidi3_media"
1821   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1822         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1823                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1824   "TARGET_SHMEDIA"
1825   "mulu.l       %1, %2, %0"
1826   [(set_attr "type" "dmpy_media")])
1828 (define_insn "umulsidi3_compact"
1829   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1830         (mult:DI
1831          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1832          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1833    (clobber (reg:SI MACH_REG))
1834    (clobber (reg:SI MACL_REG))]
1835   "TARGET_SH2"
1836   "#")
1838 (define_split
1839   [(set (match_operand:DI 0 "arith_reg_operand" "")
1840         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1841                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1842    (clobber (reg:SI MACH_REG))
1843    (clobber (reg:SI MACL_REG))]
1844   "TARGET_SH2"
1845   [(const_int 0)]
1846   "
1848   rtx low_dst = gen_lowpart (SImode, operands[0]);
1849   rtx high_dst = gen_highpart (SImode, operands[0]);
1851   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1853   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1854   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1855   /* We need something to tag the possible REG_EQUAL notes on to.  */
1856   emit_move_insn (operands[0], operands[0]);
1857   DONE;
1860 (define_insn "smulsi3_highpart_i"
1861   [(set (reg:SI MACH_REG)
1862         (truncate:SI
1863          (lshiftrt:DI
1864           (mult:DI
1865            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1866            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1867           (const_int 32))))
1868    (clobber (reg:SI MACL_REG))]
1869   "TARGET_SH2"
1870   "dmuls.l      %1,%0"
1871   [(set_attr "type" "dmpy")])
1873 (define_expand "smulsi3_highpart"
1874   [(parallel
1875     [(set (reg:SI MACH_REG)
1876           (truncate:SI
1877            (lshiftrt:DI
1878             (mult:DI
1879              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1880              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1881             (const_int 32))))
1882     (clobber (reg:SI MACL_REG))])
1883    (set (match_operand:SI 0 "arith_reg_operand" "")
1884         (reg:SI MACH_REG))]
1885   "TARGET_SH2"
1886   "
1888   rtx first, last;
1890   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1891   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1892   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1893      invariant code motion can move it.  */
1894   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1895   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1896   /* expand_binop can't find a suitable code in mul_highpart_optab to
1897      make a REG_EQUAL note from, so make one here.
1898      See also {,u}mulhisi.
1899      ??? Alternatively, we could put this at the calling site of expand_binop,
1900      i.e. expand_mult_highpart.  */
1901   REG_NOTES (last)
1902     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1903                          REG_NOTES (last));
1904   DONE;
1907 (define_insn "umulsi3_highpart_i"
1908   [(set (reg:SI MACH_REG)
1909         (truncate:SI
1910          (lshiftrt:DI
1911           (mult:DI
1912            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1913            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1914           (const_int 32))))
1915    (clobber (reg:SI MACL_REG))]
1916   "TARGET_SH2"
1917   "dmulu.l      %1,%0"
1918   [(set_attr "type" "dmpy")])
1920 (define_expand "umulsi3_highpart"
1921   [(parallel
1922     [(set (reg:SI MACH_REG)
1923           (truncate:SI
1924            (lshiftrt:DI
1925             (mult:DI
1926              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1927              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1928             (const_int 32))))
1929     (clobber (reg:SI MACL_REG))])
1930    (set (match_operand:SI 0 "arith_reg_operand" "")
1931         (reg:SI MACH_REG))]
1932   "TARGET_SH2"
1933   "
1935   rtx first, last;
1937   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1938   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1939   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1940      invariant code motion can move it.  */
1941   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1942   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1943   DONE;
1946 ;; -------------------------------------------------------------------------
1947 ;; Logical operations
1948 ;; -------------------------------------------------------------------------
1950 (define_insn "*andsi3_compact"
1951   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1952         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1953                 (match_operand:SI 2 "logical_operand" "r,L")))]
1954   "TARGET_SH1"
1955   "and  %2,%0"
1956   [(set_attr "type" "arith")])
1958 ;; If the constant is 255, then emit a extu.b instruction instead of an
1959 ;; and, since that will give better code.
1961 (define_expand "andsi3"
1962   [(set (match_operand:SI 0 "arith_reg_operand" "")
1963         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1964                 (match_operand:SI 2 "logical_operand" "")))]
1965   "TARGET_SH1"
1966   "
1968   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1969     {
1970       emit_insn (gen_zero_extendqisi2 (operands[0],
1971                                        gen_lowpart (QImode, operands[1])));
1972       DONE;
1973     }
1976 (define_insn_and_split "anddi3"
1977   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1978         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1979                 (match_operand:DI 2 "and_operand" "r,P,n")))]
1980   "TARGET_SHMEDIA"
1981   "@
1982         and     %1, %2, %0
1983         andi    %1, %2, %0
1984         #"
1985   "reload_completed
1986    && ! logical_operand (operands[2], DImode)"
1987   [(const_int 0)]
1988   "
1990   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
1991     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
1992   else
1993     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
1994   DONE;
1996   [(set_attr "type" "arith_media")])
1998 (define_insn "andcdi3"
1999   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2000         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2001                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2002   "TARGET_SHMEDIA"
2003   "andc %1,%2,%0"
2004   [(set_attr "type" "arith_media")])
2006 (define_insn "iorsi3"
2007   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2008         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2009                 (match_operand:SI 2 "logical_operand" "r,L")))]
2010   "TARGET_SH1"
2011   "or   %2,%0"
2012   [(set_attr "type" "arith")])
2014 (define_insn "iordi3"
2015   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2016         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2017                 (match_operand:DI 2 "logical_operand" "r,P")))]
2018   "TARGET_SHMEDIA"
2019   "@
2020         or      %1, %2, %0
2021         ori     %1, %2, %0"
2022   [(set_attr "type" "arith_media")])
2024 (define_insn "xorsi3"
2025   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2026         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2027                 (match_operand:SI 2 "logical_operand" "L,r")))]
2028   "TARGET_SH1"
2029   "xor  %2,%0"
2030   [(set_attr "type" "arith")])
2032 (define_insn "xordi3"
2033   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2034         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2035                 (match_operand:DI 2 "shmedia_6bit_operand" "r,O")))]
2036   "TARGET_SHMEDIA"
2037   "@
2038         xor     %1, %2, %0
2039         xori    %1, %2, %0"
2040   [(set_attr "type" "arith_media")])
2042 ;; -------------------------------------------------------------------------
2043 ;; Shifts and rotates
2044 ;; -------------------------------------------------------------------------
2046 (define_expand "rotldi3"
2047   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2048         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2049                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2050   "TARGET_SHMEDIA"
2051   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2053 (define_insn "rotldi3_mextr"
2054   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2055         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2056                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2057   "TARGET_SHMEDIA"
2058   "*
2060   static char templ[16];
2062   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2063            8 - (int) (INTVAL (operands[2]) >> 3));
2064   return templ;
2066   [(set_attr "type" "arith_media")])
2068 (define_expand "rotrdi3"
2069   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2070         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2071                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2072   "TARGET_SHMEDIA"
2073   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2075 (define_insn "rotrdi3_mextr"
2076   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2077         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2078                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2079   "TARGET_SHMEDIA"
2080   "*
2082   static char templ[16];
2084   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2085   return templ;
2087   [(set_attr "type" "arith_media")])
2089 (define_insn "rotlsi3_1"
2090   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2091         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2092                    (const_int 1)))
2093    (set (reg:SI T_REG)
2094         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2095   "TARGET_SH1"
2096   "rotl %0"
2097   [(set_attr "type" "arith")])
2099 (define_insn "rotlsi3_31"
2100   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2101         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2102                    (const_int 31)))
2103    (clobber (reg:SI T_REG))]
2104   "TARGET_SH1"
2105   "rotr %0"
2106   [(set_attr "type" "arith")])
2108 (define_insn "rotlsi3_16"
2109   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2110         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2111                    (const_int 16)))]
2112   "TARGET_SH1"
2113   "swap.w       %1,%0"
2114   [(set_attr "type" "arith")])
2116 (define_expand "rotlsi3"
2117   [(set (match_operand:SI 0 "arith_reg_operand" "")
2118         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2119                    (match_operand:SI 2 "immediate_operand" "")))]
2120   "TARGET_SH1"
2121   "
2123   static const char rot_tab[] = {
2124     000, 000, 000, 000, 000, 000, 010, 001,
2125     001, 001, 011, 013, 003, 003, 003, 003,
2126     003, 003, 003, 003, 003, 013, 012, 002,
2127     002, 002, 010, 000, 000, 000, 000, 000,
2128   };
2130   int count, choice;
2132   if (GET_CODE (operands[2]) != CONST_INT)
2133     FAIL;
2134   count = INTVAL (operands[2]);
2135   choice = rot_tab[count];
2136   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2137     FAIL;
2138   choice &= 7;
2139   switch (choice)
2140     {
2141     case 0:
2142       emit_move_insn (operands[0], operands[1]);
2143       count -= (count & 16) * 2;
2144       break;
2145     case 3:
2146      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2147      count -= 16;
2148      break;
2149     case 1:
2150     case 2:
2151       {
2152         rtx parts[2];
2153         parts[0] = gen_reg_rtx (SImode);
2154         parts[1] = gen_reg_rtx (SImode);
2155         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2156         parts[choice-1] = operands[1];
2157         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2158         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2159         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2160         count = (count & ~16) - 8;
2161       }
2162     }
2164   for (; count > 0; count--)
2165     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2166   for (; count < 0; count++)
2167     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2169   DONE;
2172 (define_insn "*rotlhi3_8"
2173   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2174         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2175                    (const_int 8)))]
2176   "TARGET_SH1"
2177   "swap.b       %1,%0"
2178   [(set_attr "type" "arith")])
2180 (define_expand "rotlhi3"
2181   [(set (match_operand:HI 0 "arith_reg_operand" "")
2182         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2183                    (match_operand:HI 2 "immediate_operand" "")))]
2184   "TARGET_SH1"
2185   "
2187   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2188     FAIL;
2192 ;; shift left
2194 ;; This pattern is used by init_expmed for computing the costs of shift
2195 ;; insns.
2197 (define_insn_and_split "ashlsi3_std"
2198   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2199         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2200                    (match_operand:SI 2 "nonmemory_operand" "r,M,K,?ri")))
2201    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2202   "TARGET_SH3
2203    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2204        && CONST_OK_FOR_K (INTVAL (operands[2])))"
2205   "@
2206    shld %2,%0
2207    add  %0,%0
2208    shll%O2      %0
2209    #"
2210   "TARGET_SH3
2211    && reload_completed
2212    && GET_CODE (operands[2]) == CONST_INT
2213    && ! CONST_OK_FOR_K (INTVAL (operands[2]))"
2214   [(set (match_dup 3) (match_dup 2))
2215    (parallel
2216     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2217      (clobber (match_dup 4))])]
2218   "operands[4] = gen_rtx_SCRATCH (SImode);"
2219   [(set_attr "length" "*,*,*,4")
2220    (set_attr "type" "dyn_shift,arith,arith,arith")])
2222 (define_insn "ashlhi3_k"
2223   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2224         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2225                    (match_operand:HI 2 "const_int_operand" "M,K")))]
2226   "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))"
2227   "@
2228         add     %0,%0
2229         shll%O2 %0"
2230   [(set_attr "type" "arith")])
2232 (define_insn "ashlsi3_n"
2233   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2234         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2235                    (match_operand:SI 2 "const_int_operand" "n")))
2236    (clobber (reg:SI T_REG))]
2237   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2238   "#"
2239   [(set (attr "length")
2240         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2241                (const_string "2")
2242                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2243                (const_string "4")
2244                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2245                (const_string "6")]
2246               (const_string "8")))
2247    (set_attr "type" "arith")])
2249 (define_split
2250   [(set (match_operand:SI 0 "arith_reg_operand" "")
2251         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2252                    (match_operand:SI 2 "const_int_operand" "")))
2253    (clobber (reg:SI T_REG))]
2254   "TARGET_SH1 && reload_completed"
2255   [(use (reg:SI R0_REG))]
2256   "
2258   gen_shifty_op (ASHIFT, operands);
2259   DONE;
2262 (define_insn "ashlsi3_media"
2263   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2264         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2265                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2266   "TARGET_SHMEDIA"
2267   "@
2268         shlld.l %1, %2, %0
2269         shlli.l %1, %2, %0"
2270   [(set_attr "type" "arith_media")])
2272 (define_expand "ashlsi3"
2273   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2274                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2275                               (match_operand:SI 2 "nonmemory_operand" "")))
2276               (clobber (reg:SI T_REG))])]
2277   ""
2278   "
2280   if (TARGET_SHMEDIA)
2281     {
2282       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2283       DONE;
2284     }
2285   if (GET_CODE (operands[2]) == CONST_INT
2286       && sh_dynamicalize_shift_p (operands[2]))
2287     operands[2] = force_reg (SImode, operands[2]);
2288   if (TARGET_SH3)
2289     {
2290       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2291       DONE;
2292     }
2293   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2294     FAIL;
2297 (define_insn "ashlhi3"
2298   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2299         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2300                    (match_operand:HI 2 "const_int_operand" "n")))
2301    (clobber (reg:SI T_REG))]
2302   "TARGET_SH1"
2303   "#"
2304   [(set (attr "length")
2305         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2306                (const_string "2")
2307                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2308                (const_string "4")]
2309               (const_string "6")))
2310    (set_attr "type" "arith")])
2312 (define_split
2313   [(set (match_operand:HI 0 "arith_reg_operand" "")
2314         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2315                    (match_operand:HI 2 "const_int_operand" "")))
2316    (clobber (reg:SI T_REG))]
2317   "TARGET_SH1 && reload_completed"
2318   [(use (reg:SI R0_REG))]
2319   "
2321   gen_shifty_hi_op (ASHIFT, operands);
2322   DONE;
2326 ; arithmetic shift right
2329 (define_insn "ashrsi3_k"
2330   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2331         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2332                      (match_operand:SI 2 "const_int_operand" "M")))
2333    (clobber (reg:SI T_REG))]
2334   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2335   "shar %0"
2336   [(set_attr "type" "arith")])
2338 ;; We can't do HImode right shifts correctly unless we start out with an
2339 ;; explicit zero / sign extension; doing that would result in worse overall
2340 ;; code, so just let the machine independent code widen the mode.
2341 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2344 ;; ??? This should be a define expand.
2346 (define_insn "ashrsi2_16"
2347   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2348         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2349                      (const_int 16)))]
2350   "TARGET_SH1"
2351   "#"
2352   [(set_attr "length" "4")])
2354 (define_split
2355   [(set (match_operand:SI 0 "arith_reg_operand" "")
2356         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2357                      (const_int 16)))]
2358   "TARGET_SH1"
2359   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2360    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2361   "operands[2] = gen_lowpart (HImode, operands[0]);")
2363 ;; ??? This should be a define expand.
2365 (define_insn "ashrsi2_31"
2366   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2367         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2368                      (const_int 31)))
2369    (clobber (reg:SI T_REG))]
2370   "TARGET_SH1"
2371   "#"
2372   [(set_attr "length" "4")])
2374 (define_split
2375   [(set (match_operand:SI 0 "arith_reg_operand" "")
2376         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2377                      (const_int 31)))
2378    (clobber (reg:SI T_REG))]
2379   "TARGET_SH1"
2380   [(const_int 0)]
2381   "
2383   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2384   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2385   DONE;
2388 (define_insn "ashlsi_c"
2389   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2390         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2391    (set (reg:SI T_REG)
2392         (lt:SI (match_dup 1) (const_int 0)))]
2393   "TARGET_SH1"
2394   "shll %0"
2395   [(set_attr "type" "arith")])
2397 (define_insn "ashrsi3_d"
2398   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2399         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2400                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2401   "TARGET_SH3"
2402   "shad %2,%0"
2403   [(set_attr "type" "dyn_shift")])
2405 (define_insn "ashrsi3_n"
2406   [(set (reg:SI R4_REG)
2407         (ashiftrt:SI (reg:SI R4_REG)
2408                      (match_operand:SI 0 "const_int_operand" "i")))
2409    (clobber (reg:SI T_REG))
2410    (clobber (reg:SI PR_REG))
2411    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2412   "TARGET_SH1"
2413   "jsr  @%1%#"
2414   [(set_attr "type" "sfunc")
2415    (set_attr "needs_delay_slot" "yes")])
2417 (define_insn "ashrsi3_media"
2418   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2419         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2420                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2421   "TARGET_SHMEDIA"
2422   "@
2423         shard.l %1, %2, %0
2424         shari.l %1, %2, %0"
2425   [(set_attr "type" "arith_media")])
2427 (define_expand "ashrsi3"
2428   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2429                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2430                                 (match_operand:SI 2 "nonmemory_operand" "")))
2431               (clobber (reg:SI T_REG))])]
2432   ""
2433   "
2435   if (TARGET_SHMEDIA)
2436     {
2437       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2438       DONE;
2439     }
2440   if (expand_ashiftrt (operands))
2441     DONE;
2442   else
2443     FAIL;
2446 ;; logical shift right
2448 (define_insn "lshrsi3_d"
2449   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2450         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2451                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2452   "TARGET_SH3"
2453   "shld %2,%0"
2454   [(set_attr "type" "dyn_shift")])
2456 ;;  Only the single bit shift clobbers the T bit.
2458 (define_insn "lshrsi3_m"
2459   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2460         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2461                      (match_operand:SI 2 "const_int_operand" "M")))
2462    (clobber (reg:SI T_REG))]
2463   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2464   "shlr %0"
2465   [(set_attr "type" "arith")])
2467 (define_insn "lshrsi3_k"
2468   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2469         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2470                      (match_operand:SI 2 "const_int_operand" "K")))]
2471   "TARGET_SH1 && CONST_OK_FOR_K (INTVAL (operands[2]))
2472    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2473   "shlr%O2      %0"
2474   [(set_attr "type" "arith")])
2476 (define_insn "lshrsi3_n"
2477   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2478         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2479                      (match_operand:SI 2 "const_int_operand" "n")))
2480    (clobber (reg:SI T_REG))]
2481   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2482   "#"
2483   [(set (attr "length")
2484         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2485                (const_string "2")
2486                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2487                (const_string "4")
2488                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2489                (const_string "6")]
2490               (const_string "8")))
2491    (set_attr "type" "arith")])
2493 (define_split
2494   [(set (match_operand:SI 0 "arith_reg_operand" "")
2495         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2496                      (match_operand:SI 2 "const_int_operand" "")))
2497    (clobber (reg:SI T_REG))]
2498   "TARGET_SH1 && reload_completed"
2499   [(use (reg:SI R0_REG))]
2500   "
2502   gen_shifty_op (LSHIFTRT, operands);
2503   DONE;
2506 (define_insn "lshrsi3_media"
2507   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2508         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2509                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2510   "TARGET_SHMEDIA"
2511   "@
2512         shlrd.l %1, %2, %0
2513         shlri.l %1, %2, %0"
2514   [(set_attr "type" "arith_media")])
2516 (define_expand "lshrsi3"
2517   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2518                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2519                                 (match_operand:SI 2 "nonmemory_operand" "")))
2520               (clobber (reg:SI T_REG))])]
2521   ""
2522   "
2524   if (TARGET_SHMEDIA)
2525     {
2526       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2527       DONE;
2528     }
2529   if (GET_CODE (operands[2]) == CONST_INT
2530       && sh_dynamicalize_shift_p (operands[2]))
2531     operands[2] = force_reg (SImode, operands[2]);
2532   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2533     {
2534       rtx count = copy_to_mode_reg (SImode, operands[2]);
2535       emit_insn (gen_negsi2 (count, count));
2536       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2537       DONE;
2538     }
2539   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2540     FAIL;
2543 ;; ??? This should be a define expand.
2545 (define_insn "ashldi3_k"
2546   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2547         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2548                    (const_int 1)))
2549    (clobber (reg:SI T_REG))]
2550   "TARGET_SH1"
2551   "shll %R0\;rotcl      %S0"
2552   [(set_attr "length" "4")
2553    (set_attr "type" "arith")])
2555 (define_insn "ashldi3_media"
2556   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2557         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2558                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2559   "TARGET_SHMEDIA"
2560   "@
2561         shlld   %1, %2, %0
2562         shlli   %1, %2, %0"
2563   [(set_attr "type" "arith_media")])
2565 (define_expand "ashldi3"
2566   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2567                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2568                               (match_operand:DI 2 "immediate_operand" "")))
2569               (clobber (reg:SI T_REG))])]
2570   ""
2571   "
2573   if (TARGET_SHMEDIA)
2574     {
2575       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2576       DONE;
2577     }
2578   if (GET_CODE (operands[2]) != CONST_INT
2579       || INTVAL (operands[2]) != 1)
2580     FAIL;
2583 ;; ??? This should be a define expand.
2585 (define_insn "lshrdi3_k"
2586   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2587         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2588                      (const_int 1)))
2589    (clobber (reg:SI T_REG))]
2590   "TARGET_SH1"
2591   "shlr %S0\;rotcr      %R0"
2592   [(set_attr "length" "4")
2593    (set_attr "type" "arith")])
2595 (define_insn "lshrdi3_media"
2596   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2597         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2598                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2599   "TARGET_SHMEDIA"
2600   "@
2601         shlrd   %1, %2, %0
2602         shlri   %1, %2, %0"
2603   [(set_attr "type" "arith_media")])
2605 (define_expand "lshrdi3"
2606   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2607                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2608                                (match_operand:DI 2 "immediate_operand" "")))
2609              (clobber (reg:SI T_REG))])]
2610   ""
2611   "
2613   if (TARGET_SHMEDIA)
2614     {
2615       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2616       DONE;
2617     }
2618   if (GET_CODE (operands[2]) != CONST_INT
2619       || INTVAL (operands[2]) != 1)
2620     FAIL;
2623 ;; ??? This should be a define expand.
2625 (define_insn "ashrdi3_k"
2626   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2627         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2628                      (const_int 1)))
2629    (clobber (reg:SI T_REG))]
2630   "TARGET_SH1"
2631   "shar %S0\;rotcr      %R0"
2632   [(set_attr "length" "4")
2633    (set_attr "type" "arith")])
2635 (define_insn "ashrdi3_media"
2636   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2637         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2638                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2639   "TARGET_SHMEDIA"
2640   "@
2641         shard   %1, %2, %0
2642         shari   %1, %2, %0"
2643   [(set_attr "type" "arith_media")])
2645 (define_expand "ashrdi3"
2646   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2647                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2648                                 (match_operand:DI 2 "immediate_operand" "")))
2649               (clobber (reg:SI T_REG))])]
2650   ""
2651   "
2653   if (TARGET_SHMEDIA)
2654     {
2655       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2656       DONE;
2657     }
2658   if (GET_CODE (operands[2]) != CONST_INT
2659       || INTVAL (operands[2]) != 1)
2660     FAIL;
2663 ;; combined left/right shift
2665 (define_split
2666   [(set (match_operand:SI 0 "register_operand" "")
2667         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2668                            (match_operand:SI 2 "const_int_operand" ""))
2669                 (match_operand:SI 3 "const_int_operand" "")))]
2670   "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2671   [(use (reg:SI R0_REG))]
2672   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2673    DONE;")
2675 (define_split
2676   [(set (match_operand:SI 0 "register_operand" "")
2677         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2678                            (match_operand:SI 2 "const_int_operand" ""))
2679                 (match_operand:SI 3 "const_int_operand" "")))
2680    (clobber (reg:SI T_REG))]
2681   "TARGET_SH1 && (unsigned)INTVAL (operands[2]) < 32"
2682   [(use (reg:SI R0_REG))]
2683   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2684    DONE;")
2686 (define_insn ""
2687   [(set (match_operand:SI 0 "register_operand" "=r")
2688         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2689                            (match_operand:SI 2 "const_int_operand" "n"))
2690                 (match_operand:SI 3 "const_int_operand" "n")))
2691    (clobber (reg:SI T_REG))]
2692   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2693  "#"
2694   [(set (attr "length")
2695         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2696                (const_string "4")
2697                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2698                (const_string "6")
2699                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2700                (const_string "8")
2701                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2702                (const_string "10")
2703                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2704                (const_string "12")
2705                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2706                (const_string "14")
2707                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2708                (const_string "16")]
2709               (const_string "18")))
2710    (set_attr "type" "arith")])
2712 (define_insn ""
2713   [(set (match_operand:SI 0 "register_operand" "=z")
2714         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2715                            (match_operand:SI 2 "const_int_operand" "n"))
2716                 (match_operand:SI 3 "const_int_operand" "n")))
2717    (clobber (reg:SI T_REG))]
2718   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2719  "#"
2720   [(set (attr "length")
2721         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2722                (const_string "4")
2723                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2724                (const_string "6")
2725                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2726                (const_string "8")]
2727               (const_string "10")))
2728    (set_attr "type" "arith")])
2730 ;; shift left / and combination with a scratch register: The combine pass
2731 ;; does not accept the individual instructions, even though they are
2732 ;; cheap.  But it needs a precise description so that it is usable after
2733 ;; reload.
2734 (define_insn "and_shl_scratch"
2735   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2736         (lshiftrt:SI
2737          (ashift:SI
2738           (and:SI
2739            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2740                         (match_operand:SI 2 "const_int_operand" "N,n"))
2741            (match_operand:SI 3 "" "0,r"))
2742           (match_operand:SI 4 "const_int_operand" "n,n"))
2743          (match_operand:SI 5 "const_int_operand" "n,n")))
2744    (clobber (reg:SI T_REG))]
2745   "TARGET_SH1"
2746   "#"
2747   [(set (attr "length")
2748         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2749                (const_string "4")
2750                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2751                (const_string "6")
2752                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2753                (const_string "8")
2754                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2755                (const_string "10")]
2756               (const_string "12")))
2757    (set_attr "type" "arith")])
2759 (define_split
2760   [(set (match_operand:SI 0 "register_operand" "")
2761         (lshiftrt:SI
2762          (ashift:SI
2763           (and:SI
2764            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2765                         (match_operand:SI 2 "const_int_operand" ""))
2766            (match_operand:SI 3 "register_operand" ""))
2767           (match_operand:SI 4 "const_int_operand" ""))
2768          (match_operand:SI 5 "const_int_operand" "")))
2769    (clobber (reg:SI T_REG))]
2770   "TARGET_SH1"
2771   [(use (reg:SI R0_REG))]
2772   "
2774   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2776   if (INTVAL (operands[2]))
2777     {
2778       gen_shifty_op (LSHIFTRT, operands);
2779     }
2780   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2781   operands[2] = operands[4];
2782   gen_shifty_op (ASHIFT, operands);
2783   if (INTVAL (operands[5]))
2784     {
2785       operands[2] = operands[5];
2786       gen_shifty_op (LSHIFTRT, operands);
2787     }
2788   DONE;
2791 ;; signed left/right shift combination.
2792 (define_split
2793   [(set (match_operand:SI 0 "register_operand" "")
2794         (sign_extract:SI
2795          (ashift:SI (match_operand:SI 1 "register_operand" "")
2796                     (match_operand:SI 2 "const_int_operand" ""))
2797          (match_operand:SI 3 "const_int_operand" "")
2798          (const_int 0)))
2799    (clobber (reg:SI T_REG))]
2800   "TARGET_SH1"
2801   [(use (reg:SI R0_REG))]
2802   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2803    DONE;")
2805 (define_insn "shl_sext_ext"
2806   [(set (match_operand:SI 0 "register_operand" "=r")
2807         (sign_extract:SI
2808          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2809                     (match_operand:SI 2 "const_int_operand" "n"))
2810          (match_operand:SI 3 "const_int_operand" "n")
2811          (const_int 0)))
2812    (clobber (reg:SI T_REG))]
2813   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2814   "#"
2815   [(set (attr "length")
2816         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2817                (const_string "2")
2818                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2819                (const_string "4")
2820                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2821                (const_string "6")
2822                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2823                (const_string "8")
2824                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2825                (const_string "10")
2826                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2827                (const_string "12")
2828                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2829                (const_string "14")
2830                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2831                (const_string "16")]
2832               (const_string "18")))
2833     (set_attr "type" "arith")])
2835 (define_insn "shl_sext_sub"
2836   [(set (match_operand:SI 0 "register_operand" "=z")
2837         (sign_extract:SI
2838          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2839                     (match_operand:SI 2 "const_int_operand" "n"))
2840          (match_operand:SI 3 "const_int_operand" "n")
2841          (const_int 0)))
2842    (clobber (reg:SI T_REG))]
2843   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2844   "#"
2845   [(set (attr "length")
2846         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2847                (const_string "6")
2848                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2849                (const_string "8")
2850                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2851                (const_string "10")
2852                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2853                (const_string "12")]
2854               (const_string "14")))
2855     (set_attr "type" "arith")])
2857 ;; These patterns are found in expansions of DImode shifts by 16, and
2858 ;; allow the xtrct instruction to be generated from C source.
2860 (define_insn "xtrct_left"
2861   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2862         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2863                            (const_int 16))
2864                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2865                              (const_int 16))))]
2866   "TARGET_SH1"
2867   "xtrct        %1,%0"
2868   [(set_attr "type" "arith")])
2870 (define_insn "xtrct_right"
2871   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2872         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2873                              (const_int 16))
2874                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2875                            (const_int 16))))]
2876   "TARGET_SH1"
2877   "xtrct        %2,%0"
2878   [(set_attr "type" "arith")])
2880 ;; -------------------------------------------------------------------------
2881 ;; Unary arithmetic
2882 ;; -------------------------------------------------------------------------
2884 (define_insn "negc"
2885   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2886         (neg:SI (plus:SI (reg:SI T_REG)
2887                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2888    (set (reg:SI T_REG)
2889         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2890                (const_int 0)))]
2891   "TARGET_SH1"
2892   "negc %1,%0"
2893   [(set_attr "type" "arith")])
2895 (define_insn "*negdi_media"
2896   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2897         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2898   "TARGET_SHMEDIA"
2899   "sub  r63, %1, %0"
2900   [(set_attr "type" "arith_media")])
2902 (define_expand "negdi2"
2903   [(set (match_operand:DI 0 "arith_reg_operand" "")
2904         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2905   ""
2906   "
2908   if (TARGET_SH1)
2909     {
2910       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2911       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2913       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2914       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2916       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2917       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2919       emit_insn (gen_clrt ());
2920       emit_insn (gen_negc (low_dst, low_src));
2921       emit_insn (gen_negc (high_dst, high_src));
2922       DONE;
2923     }
2926 (define_insn "negsi2"
2927   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2928         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2929   "TARGET_SH1"
2930   "neg  %1,%0"
2931   [(set_attr "type" "arith")])
2933 (define_insn "one_cmplsi2"
2934   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2935         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2936   "TARGET_SH1"
2937   "not  %1,%0"
2938   [(set_attr "type" "arith")])
2940 (define_expand "one_cmpldi2"
2941   [(set (match_operand:DI 0 "arith_reg_operand" "")
2942         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2943                 (const_int -1)))]
2944   "TARGET_SHMEDIA" "")
2946 ;; -------------------------------------------------------------------------
2947 ;; Zero extension instructions
2948 ;; -------------------------------------------------------------------------
2950 (define_insn "zero_extendsidi2"
2951   [(set (match_operand:DI 0 "register_operand" "=r")
2952         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2953   "TARGET_SHMEDIA"
2954   "addz.l       %1, r63, %0"
2955   [(set_attr "type" "arith_media")])
2957 (define_insn "zero_extendhidi2"
2958   [(set (match_operand:DI 0 "register_operand" "=r,r")
2959         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
2960   "TARGET_SHMEDIA"
2961   "@
2962         #
2963         ld%M1.uw        %m1, %0"
2964   [(set_attr "type" "*,load_media")])
2966 (define_split
2967   [(set (match_operand:DI 0 "register_operand" "")
2968         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
2969   "TARGET_SHMEDIA && reload_completed"
2970   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
2971    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
2972   "
2974   if (GET_CODE (operands[1]) == TRUNCATE)
2975     operands[1] = XEXP (operands[1], 0);
2978 ;; ??? when a truncated input to a zero_extrend is reloaded, reload will
2979 ;; reload the entrire truncate expression.
2980 (define_insn_and_split "*loaddi_trunc"
2981   [(set (match_operand 0 "int_gpr_dest" "=r")
2982         (truncate (match_operand:DI 1 "memory_operand" "m")))]
2983   "TARGET_SHMEDIA && reload_completed"
2984   "#"
2985   "TARGET_SHMEDIA && reload_completed"
2986   [(set (match_dup 0) (match_dup 1))]
2987   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
2989 (define_insn "zero_extendqidi2"
2990   [(set (match_operand:DI 0 "register_operand" "=r,r")
2991         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
2992   "TARGET_SHMEDIA"
2993   "@
2994         andi    %1, 255, %0
2995         ld%M1.ub        %m1, %0"
2996   [(set_attr "type" "arith_media,load_media")])
2998 (define_expand "zero_extendhisi2"
2999   [(set (match_operand:SI 0 "arith_reg_operand" "")
3000         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3001   ""
3002   "
3004   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3005     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3008 (define_insn "*zero_extendhisi2_compact"
3009   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3010         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3011   "TARGET_SH1"
3012   "extu.w       %1,%0"
3013   [(set_attr "type" "arith")])
3015 (define_insn "*zero_extendhisi2_media"
3016   [(set (match_operand:SI 0 "register_operand" "=r,r")
3017         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3018   "TARGET_SHMEDIA"
3019   "@
3020         #
3021         ld%M1.uw        %m1, %0"
3022   [(set_attr "type" "arith_media,load_media")])
3024 (define_split
3025   [(set (match_operand:SI 0 "register_operand" "")
3026         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3027   "TARGET_SHMEDIA && reload_completed"
3028   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3029    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3030   "
3032   if (GET_CODE (operands[1]) == TRUNCATE)
3033     operands[1] = XEXP (operands[1], 0);
3036 (define_expand "zero_extendqisi2"
3037   [(set (match_operand:SI 0 "arith_reg_operand" "")
3038         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3039   ""
3040   "
3042   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3043     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3046 (define_insn "*zero_extendqisi2_compact"
3047   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3048         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3049   "TARGET_SH1"
3050   "extu.b       %1,%0"
3051   [(set_attr "type" "arith")])
3053 (define_insn "*zero_extendqisi2_media"
3054   [(set (match_operand:SI 0 "register_operand" "=r,r")
3055         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3056   "TARGET_SHMEDIA"
3057   "@
3058         andi    %1, 255, %0
3059         ld%M1.ub        %m1, %0"
3060   [(set_attr "type" "arith_media,load_media")])
3062 (define_insn "zero_extendqihi2"
3063   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3064         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3065   "TARGET_SH1"
3066   "extu.b       %1,%0"
3067   [(set_attr "type" "arith")])
3069 ;; -------------------------------------------------------------------------
3070 ;; Sign extension instructions
3071 ;; -------------------------------------------------------------------------
3073 ;; ??? This should be a define expand.
3074 ;; ??? Or perhaps it should be dropped?
3076 ;; convert_move generates good code for SH[1-4].
3077 (define_insn "extendsidi2"
3078   [(set (match_operand:DI 0 "register_operand" "=r,r")
3079         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3080   "TARGET_SHMEDIA"
3081   "@
3082         add.l   %1, r63, %0
3083         ld%M1.l %m1, %0"
3084   [(set_attr "type" "arith_media,load_media")])
3086 (define_insn "extendhidi2"
3087   [(set (match_operand:DI 0 "register_operand" "=r,r")
3088         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3089   "TARGET_SHMEDIA"
3090   "@
3091         #
3092         ld%M1.w %m1, %0"
3093   [(set_attr "type" "*,load_media")])
3095 (define_split
3096   [(set (match_operand:DI 0 "register_operand" "")
3097         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3098   "TARGET_SHMEDIA && reload_completed"
3099   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3100    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3101   "
3103   if (GET_CODE (operands[1]) == TRUNCATE)
3104     operands[1] = XEXP (operands[1], 0);
3107 (define_insn "extendqidi2"
3108   [(set (match_operand:DI 0 "register_operand" "=r,r")
3109         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3110   "TARGET_SHMEDIA"
3111   "@
3112         #
3113         ld%M1.b %m1, %0"
3114   [(set_attr "type" "*,load_media")])
3116 (define_split
3117   [(set (match_operand:DI 0 "register_operand" "")
3118         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3119   "TARGET_SHMEDIA && reload_completed"
3120   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3121    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3122   "
3124   if (GET_CODE (operands[1]) == TRUNCATE)
3125     operands[1] = XEXP (operands[1], 0);
3128 (define_expand "extendhisi2"
3129   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3130        (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3131   ""
3132   "")
3134 (define_insn "*extendhisi2_compact"
3135   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3136         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3137   "TARGET_SH1"
3138   "@
3139         exts.w  %1,%0
3140         mov.w   %1,%0"
3141   [(set_attr "type" "arith,load")])
3143 (define_insn "*extendhisi2_media"
3144   [(set (match_operand:SI 0 "register_operand" "=r,r")
3145         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3146   "TARGET_SHMEDIA"
3147   "@
3148         #
3149         ld%M1.w %m1, %0"
3150   [(set_attr "type" "arith_media,load_media")])
3152 (define_split
3153   [(set (match_operand:SI 0 "register_operand" "")
3154         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3155   "TARGET_SHMEDIA && reload_completed"
3156   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3157    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3158   "
3160   if (GET_CODE (operands[1]) == TRUNCATE)
3161     operands[1] = XEXP (operands[1], 0);
3164 (define_expand "extendqisi2"
3165   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3166         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3167   ""
3168   "")
3170 (define_insn "*extendqisi2_compact"
3171   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3172         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3173   "TARGET_SH1"
3174   "@
3175         exts.b  %1,%0
3176         mov.b   %1,%0"
3177   [(set_attr "type" "arith,load")])
3179 (define_insn "*extendqisi2_media"
3180   [(set (match_operand:SI 0 "register_operand" "=r,r")
3181         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3182   "TARGET_SHMEDIA"
3183   "@
3184         #
3185         ld%M1.b %m1, %0"
3186   [(set_attr "type" "arith_media,load_media")])
3188 (define_split
3189   [(set (match_operand:SI 0 "register_operand" "")
3190         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3191   "TARGET_SHMEDIA && reload_completed"
3192   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3193    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3194    "
3196   if (GET_CODE (operands[1]) == TRUNCATE)
3197     operands[1] = XEXP (operands[1], 0);
3200 (define_insn "extendqihi2"
3201   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3202         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3203   "TARGET_SH1"
3204   "@
3205         exts.b  %1,%0
3206         mov.b   %1,%0"
3207   [(set_attr "type" "arith,load")])
3209 /* It would seem useful to combine the truncXi patterns into the movXi
3210    patterns, but unary operators are ignored when matching constraints,
3211    so we need separate patterns.  */
3212 (define_insn "truncdisi2"
3213   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3214         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3215   "TARGET_SHMEDIA"
3216   "@
3217         add.l   %1, r63, %0
3218         st%M0.l %m0, %1
3219         fst%M0.s        %m0, %T1
3220         fmov.ls %1, %0
3221         fmov.sl %T1, %0
3222         fmov.s  %T1, %0"
3223   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3226 (define_insn "truncdihi2"
3227   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3228         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3229   "TARGET_SHMEDIA"
3230   "@
3231         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3232         st%M0.w %m0, %1"
3233   [(set_attr "type"   "arith_media,store_media")
3234    (set_attr "length" "8,4")])
3236 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3237 ; Because we use zero extension, we can't provide signed QImode compares
3238 ; using a simple compare or conditional banch insn.
3239 (define_insn "truncdiqi2"
3240   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3241         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3242   "TARGET_SHMEDIA"
3243   "@
3244         and     %1, 255, %0
3245         st%M0.b %m0, %1"
3246   [(set_attr "type"   "arith_media,store")])
3248 ;; -------------------------------------------------------------------------
3249 ;; Move instructions
3250 ;; -------------------------------------------------------------------------
3252 ;; define push and pop so it is easy for sh.c
3253 ;; We can't use push and pop on SHcompact because the stack must always
3254 ;; be 8-byte aligned.
3256 (define_expand "push"
3257   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3258         (match_operand:SI 0 "register_operand" "r,l,x"))]
3259   "TARGET_SH1 && ! TARGET_SH5"
3260   "")
3262 (define_expand "pop"
3263   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3264         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3265   "TARGET_SH1 && ! TARGET_SH5"
3266   "")
3268 (define_expand "push_e"
3269   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3270                    (match_operand:SF 0 "" ""))
3271               (use (reg:PSI FPSCR_REG))
3272               (clobber (scratch:SI))])]
3273   "TARGET_SH1 && ! TARGET_SH5"
3274   "")
3276 (define_insn "push_fpul"
3277   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3278   "TARGET_SH3E && ! TARGET_SH5"
3279   "sts.l        fpul,@-r15"
3280   [(set_attr "type" "store")
3281    (set_attr "late_fp_use" "yes")
3282    (set_attr "hit_stack" "yes")])
3284 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3285 ;; so use that.
3286 (define_expand "push_4"
3287   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3288                    (match_operand:DF 0 "" ""))
3289               (use (reg:PSI FPSCR_REG))
3290               (clobber (scratch:SI))])]
3291   "TARGET_SH1 && ! TARGET_SH5"
3292   "")
3294 (define_expand "pop_e"
3295   [(parallel [(set (match_operand:SF 0 "" "")
3296               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3297               (use (reg:PSI FPSCR_REG))
3298               (clobber (scratch:SI))])]
3299   "TARGET_SH1 && ! TARGET_SH5"
3300   "")
3302 (define_insn "pop_fpul"
3303   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3304   "TARGET_SH3E && ! TARGET_SH5"
3305   "lds.l        @r15+,fpul"
3306   [(set_attr "type" "load")
3307    (set_attr "hit_stack" "yes")])
3309 (define_expand "pop_4"
3310   [(parallel [(set (match_operand:DF 0 "" "")
3311                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3312               (use (reg:PSI FPSCR_REG))
3313               (clobber (scratch:SI))])]
3314   "TARGET_SH1 && ! TARGET_SH5"
3315   "")
3317 ;; These two patterns can happen as the result of optimization, when
3318 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3319 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3321 (define_insn "clrt"
3322   [(set (reg:SI T_REG) (const_int 0))]
3323   "TARGET_SH1"
3324   "clrt")
3326 (define_insn "sett"
3327   [(set (reg:SI T_REG) (const_int 1))]
3328   "TARGET_SH1"
3329   "sett")
3331 ;; t/r must come after r/r, lest reload will try to reload stuff like
3332 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3333 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3334 (define_insn "movsi_i"
3335   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3336         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3337   "TARGET_SH1
3338    && ! TARGET_SH3E
3339    && (register_operand (operands[0], SImode)
3340        || register_operand (operands[1], SImode))"
3341   "@
3342         mov.l   %1,%0
3343         mov     %1,%0
3344         cmp/pl  %1
3345         mov.l   %1,%0
3346         sts     %1,%0
3347         sts     %1,%0
3348         movt    %0
3349         mov.l   %1,%0
3350         sts.l   %1,%0
3351         sts.l   %1,%0
3352         lds     %1,%0
3353         lds     %1,%0
3354         lds.l   %1,%0
3355         lds.l   %1,%0
3356         fake    %1,%0"
3357   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3358    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3360 ;; t/r must come after r/r, lest reload will try to reload stuff like
3361 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3362 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3363 ;; will require a reload.
3364 (define_insn "movsi_ie"
3365   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,y")
3366         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y"))]
3367   "TARGET_SH3E
3368    && (register_operand (operands[0], SImode)
3369        || register_operand (operands[1], SImode))"
3370   "@
3371         mov.l   %1,%0
3372         mov     %1,%0
3373         cmp/pl  %1
3374         mov.l   %1,%0
3375         sts     %1,%0
3376         sts     %1,%0
3377         movt    %0
3378         mov.l   %1,%0
3379         sts.l   %1,%0
3380         sts.l   %1,%0
3381         lds     %1,%0
3382         lds     %1,%0
3383         lds.l   %1,%0
3384         lds.l   %1,%0
3385         lds.l   %1,%0
3386         sts.l   %1,%0
3387         fake    %1,%0
3388         lds     %1,%0
3389         sts     %1,%0
3390         ! move optimized away"
3391   [(set_attr "type" "pcload_si,move,*,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,load,store,pcload_si,gp_fpul,fpul_gp,nil")
3392    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*")
3393    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3395 (define_insn "movsi_i_lowpart"
3396   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3397         (match_operand:SI 1 "general_movsrc_operand" "Q,rI,mr,x,l,t,r,i"))]
3398    "TARGET_SH1
3399     && (register_operand (operands[0], SImode)
3400         || register_operand (operands[1], SImode))"
3401   "@
3402         mov.l   %1,%0
3403         mov     %1,%0
3404         mov.l   %1,%0
3405         sts     %1,%0
3406         sts     %1,%0
3407         movt    %0
3408         mov.l   %1,%0
3409         fake    %1,%0"
3410   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3412 (define_insn "*movsi_media"
3413   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3414         (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,m,f,rU,f,f,r,*b,T"))]
3415   "TARGET_SHMEDIA_FPU
3416    && (register_operand (operands[0], SImode)
3417        || register_operand (operands[1], SImode))"
3418   "@
3419         add.l   %1, r63, %0
3420         movi    %1, %0
3421         #
3422         ld%M1.l %m1, %0
3423         st%M0.l %m0, %1
3424         fld%M1.s        %m1, %0
3425         fst%M0.s        %m0, %1
3426         fmov.ls %N1, %0
3427         fmov.sl %1, %0
3428         fmov.s  %1, %0
3429         ptabs   %1, %0
3430         gettr   %1, %0
3431         pt      %1, %0"
3432   [(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")
3433    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3435 (define_insn "*movsi_media_nofpu"
3436   [(set (match_operand:SI 0 "general_movdst_operand" "=r,r,r,r,m,*b,r,b")
3437         (match_operand:SI 1 "general_movsrc_operand" "r,JS,ns,m,r,r,*b,T"))]
3438   "TARGET_SHMEDIA
3439    && (register_operand (operands[0], SImode)
3440        || register_operand (operands[1], SImode))"
3441   "@
3442         add.l   %1, r63, %0
3443         movi    %1, %0
3444         #
3445         ld%M1.l %m1, %0
3446         st%M0.l %m0, %1
3447         ptabs   %1, %0
3448         gettr   %1, %0
3449         pt      %1, %0"
3450   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3451    (set_attr "length" "4,4,8,4,4,4,4,12")])
3453 (define_split
3454   [(set (match_operand:SI 0 "arith_reg_operand" "")
3455         (match_operand:SI 1 "immediate_operand" ""))]
3456   "TARGET_SHMEDIA && reload_completed
3457    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3458   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3459   "
3461   operands[2] = shallow_copy_rtx (operands[1]);
3462   PUT_MODE (operands[2], DImode);
3465 (define_split
3466   [(set (match_operand:SI 0 "register_operand" "")
3467         (match_operand:SI 1 "immediate_operand" ""))]
3468   "TARGET_SHMEDIA && reload_completed
3469    && ((GET_CODE (operands[1]) == CONST_INT
3470         && ! CONST_OK_FOR_J (INTVAL (operands[1])))
3471        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3472   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3474 (define_expand "movsi"
3475   [(set (match_operand:SI 0 "general_movdst_operand" "")
3476         (match_operand:SI 1 "general_movsrc_operand" ""))]
3477   ""
3478   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3480 (define_expand "ic_invalidate_line"
3481   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3482                                 (match_dup 1)] UNSPEC_ICACHE)
3483               (clobber (scratch:SI))])]
3484   "TARGET_HARD_SH4 || TARGET_SH5"
3485   "
3487   if (TARGET_SHMEDIA)
3488     {
3489       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3490       DONE;
3491     }
3492   else if (TARGET_SHCOMPACT)
3493     {
3494       operands[1] = gen_rtx_SYMBOL_REF (Pmode, \"__ic_invalidate\");
3495       operands[1] = force_reg (Pmode, operands[1]);
3496       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3497       DONE;
3498     }
3499   operands[0] = force_reg (Pmode, operands[0]);
3500   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3501                                                                Pmode)));
3504 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3505 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3506 ;; the requirement *1*00 for associative address writes.  The alignment of
3507 ;; %0 implies that its least significant bit is cleared,
3508 ;; thus we clear the V bit of a matching entry if there is one.
3509 (define_insn "ic_invalidate_line_i"
3510   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3511                      (match_operand:SI 1 "register_operand" "r")]
3512                      UNSPEC_ICACHE)
3513    (clobber (match_scratch:SI 2 "=&r"))]
3514   "TARGET_HARD_SH4"
3515   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3516   [(set_attr "length" "8")
3517    (set_attr "type" "cwb")])
3519 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3520 ;; an add in the code that calculates the address.
3521 (define_insn "ic_invalidate_line_media"
3522   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3523                     UNSPEC_ICACHE)]
3524   "TARGET_SHMEDIA"
3525   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3526   [(set_attr "length" "16")
3527    (set_attr "type" "invalidate_line_media")])
3529 (define_insn "ic_invalidate_line_compact"
3530   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3531                      (match_operand:SI 1 "register_operand" "r")]
3532                     UNSPEC_ICACHE)
3533    (clobber (reg:SI PR_REG))]
3534   "TARGET_SHCOMPACT"
3535   "jsr @%1%#"
3536   [(set_attr "type" "sfunc")
3537    (set_attr "needs_delay_slot" "yes")])
3539 (define_expand "initialize_trampoline"
3540   [(match_operand:SI 0 "" "")
3541    (match_operand:SI 1 "" "")
3542    (match_operand:SI 2 "" "")]
3543   "TARGET_SHCOMPACT"
3544   "
3546   rtx sfun, tramp;
3548   sfun = force_reg (Pmode, gen_rtx_SYMBOL_REF (Pmode, \"__init_trampoline\"));
3549   tramp = gen_rtx_REG (SImode, R0_REG);
3550   emit_move_insn (tramp, operands[0]);
3551   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3552   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3554   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3555   DONE;
3558 (define_insn "initialize_trampoline_compact"
3559   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3560                      (match_operand:SI 1 "register_operand" "r")
3561                      (reg:SI R2_REG) (reg:SI R3_REG)]
3562                     UNSPEC_INIT_TRAMP)
3564    (clobber (reg:SI PR_REG))]
3565   "TARGET_SHCOMPACT"
3566   "jsr @%1%#"
3567   [(set_attr "type" "sfunc")
3568    (set_attr "needs_delay_slot" "yes")])
3570 (define_insn "movqi_i"
3571   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3572         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3573   "TARGET_SH1
3574    && (arith_reg_operand (operands[0], QImode)
3575        || arith_reg_operand (operands[1], QImode))"
3576   "@
3577         mov     %1,%0
3578         mov.b   %1,%0
3579         mov.b   %1,%0
3580         movt    %0
3581         sts     %1,%0
3582         lds     %1,%0"
3583  [(set_attr "type" "move,load,store,move,move,move")])
3585 (define_insn "*movqi_media"
3586   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3587         (match_operand:QI 1 "general_movsrc_operand" "r,JS,m,r"))]
3588   "TARGET_SHMEDIA
3589    && (arith_reg_operand (operands[0], QImode)
3590        || arith_reg_operand (operands[1], QImode))"
3591   "@
3592         add.l   %1, r63, %0
3593         movi    %1, %0
3594         ld%M1.ub        %m1, %0
3595         st%M0.b %m0, %1"
3596   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3598 (define_expand "movqi"
3599   [(set (match_operand:QI 0 "general_operand" "")
3600         (match_operand:QI 1 "general_operand"  ""))]
3601   ""
3602   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3604 (define_expand "reload_inqi"
3605   [(set (match_operand:SI 2 "" "=&r")
3606         (match_operand:QI 1 "inqhi_operand" ""))
3607    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3608         (truncate:HI (match_dup 3)))]
3609   "TARGET_SHMEDIA"
3610   "
3612   rtx inner = XEXP (operands[1], 0);
3613   int regno = REGNO (inner);
3615   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3616   operands[1] = gen_rtx_REG (SImode, regno);
3617   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3620 (define_insn "movhi_i"
3621   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r")
3622         (match_operand:HI 1 "general_movsrc_operand" "Q,rI,m,t,r,l,r,i"))]
3623   "TARGET_SH1
3624    && (arith_reg_operand (operands[0], HImode)
3625        || arith_reg_operand (operands[1], HImode))"
3626   "@
3627         mov.w   %1,%0
3628         mov     %1,%0
3629         mov.w   %1,%0
3630         movt    %0
3631         mov.w   %1,%0
3632         sts     %1,%0
3633         lds     %1,%0
3634         fake    %1,%0"
3635   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3637 (define_insn "*movhi_media"
3638   [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m")
3639         (match_operand:HI 1 "general_movsrc_operand" "r,JS,n,m,r"))]
3640   "TARGET_SHMEDIA
3641    && (arith_reg_operand (operands[0], HImode)
3642        || arith_reg_operand (operands[1], HImode))"
3643   "@
3644         add.l   %1, r63, %0
3645         movi    %1, %0
3646         #
3647         ld%M1.w %m1, %0
3648         st%M0.w %m0, %1"
3649   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3651 (define_split
3652   [(set (match_operand:HI 0 "register_operand" "")
3653         (match_operand:HI 1 "immediate_operand" ""))]
3654   "TARGET_SHMEDIA && reload_completed
3655    && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3656   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3658 (define_expand "movhi"
3659   [(set (match_operand:HI 0 "general_movdst_operand" "")
3660         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3661   ""
3662   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3664 (define_expand "reload_inhi"
3665   [(set (match_operand:SI 2 "" "=&r")
3666         (match_operand:HI 1 "inqhi_operand" ""))
3667    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3668         (truncate:HI (match_dup 3)))]
3669   "TARGET_SHMEDIA"
3670   "
3672   rtx inner = XEXP (operands[1], 0);
3673   int regno = REGNO (inner);
3675   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3676   operands[1] = gen_rtx_REG (SImode, regno);
3677   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3680 ;; ??? This should be a define expand.
3682 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3683 ;; compiled with -m2 -ml -O3 -funroll-loops
3684 (define_insn ""
3685   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3686         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I,i,x,r"))]
3687   "TARGET_SH1
3688    && (arith_reg_operand (operands[0], DImode)
3689        || arith_reg_operand (operands[1], DImode))"
3690   "* return output_movedouble (insn, operands, DImode);"
3691   [(set_attr "length" "4")
3692    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3694 ;; If the output is a register and the input is memory or a register, we have
3695 ;; to be careful and see which word needs to be loaded first.
3697 (define_split
3698   [(set (match_operand:DI 0 "general_movdst_operand" "")
3699         (match_operand:DI 1 "general_movsrc_operand" ""))]
3700   "TARGET_SH1 && reload_completed"
3701   [(set (match_dup 2) (match_dup 3))
3702    (set (match_dup 4) (match_dup 5))]
3703   "
3705   int regno;
3707   if ((GET_CODE (operands[0]) == MEM
3708        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3709       || (GET_CODE (operands[1]) == MEM
3710           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3711     FAIL;
3713   if (GET_CODE (operands[0]) == REG)
3714     regno = REGNO (operands[0]);
3715   else if (GET_CODE (operands[0]) == SUBREG)
3716     regno = subreg_regno (operands[0]);
3717   else if (GET_CODE (operands[0]) == MEM)
3718     regno = -1;
3719   else
3720     abort ();
3722   if (regno == -1
3723       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3724     {
3725       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3726       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3727       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3728       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3729     }
3730   else
3731     {
3732       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3733       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3734       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3735       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3736     }
3738   if (operands[2] == 0 || operands[3] == 0
3739       || operands[4] == 0 || operands[5] == 0)
3740     FAIL;
3743 (define_insn "*movdi_media"
3744   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3745         (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,m,f,rU,f,f,r,*b,T"))]
3746   "TARGET_SHMEDIA_FPU
3747    && (register_operand (operands[0], DImode)
3748        || register_operand (operands[1], DImode))"
3749   "@
3750         add     %1, r63, %0
3751         movi    %1, %0
3752         #
3753         ld%M1.q %m1, %0
3754         st%M0.q %m0, %1
3755         fld%M1.d        %m1, %0
3756         fst%M0.d        %m0, %1
3757         fmov.qd %N1, %0
3758         fmov.dq %1, %0
3759         fmov.d  %1, %0
3760         ptabs   %1, %0
3761         gettr   %1, %0
3762         pt      %1, %0"
3763   [(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")
3764    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3766 (define_insn "*movdi_media_nofpu"
3767   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3768         (match_operand:DI 1 "general_movsrc_operand" "r,JS,iF,m,rl,r,*b,T"))]
3769   "TARGET_SHMEDIA
3770    && (register_operand (operands[0], DImode)
3771        || register_operand (operands[1], DImode))"
3772   "@
3773         add     %1, r63, %0
3774         movi    %1, %0
3775         #
3776         ld%M1.q %m1, %0
3777         st%M0.q %m0, %1
3778         ptabs   %1, %0
3779         gettr   %1, %0
3780         pt      %1, %0"
3781   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3782    (set_attr "length" "4,4,16,4,4,4,4,*")])
3784 (define_split
3785   [(set (match_operand:DI 0 "arith_reg_operand" "")
3786         (match_operand:DI 1 "immediate_operand" ""))]
3787   "TARGET_SHMEDIA && reload_completed
3788    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3789   [(set (match_dup 0) (match_dup 1))]
3790   "
3792   rtx insn;
3794   if (TARGET_SHMEDIA64)
3795     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3796   else
3797     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3799   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3800                                         REG_NOTES (insn));
3802   DONE;
3805 (define_expand "movdi_const"
3806   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3807         (const:DI (sign_extend:DI
3808                    (truncate:HI
3809                     (ashiftrt:DI
3810                      (match_operand:DI 1 "immediate_operand" "s")
3811                      (const_int 48))))))
3812    (set (match_dup 0)
3813         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3814                 (zero_extend:DI
3815                  (truncate:HI
3816                   (const:DI
3817                    (sign_extend:DI
3818                     (truncate:HI
3819                      (ashiftrt:SI
3820                       (match_dup 1)
3821                       (const_int 32)))))))))
3822    (set (match_dup 0)
3823         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3824                 (zero_extend:DI
3825                  (truncate:HI
3826                   (const:DI
3827                    (sign_extend:DI
3828                     (truncate:HI
3829                      (ashiftrt:SI
3830                       (match_dup 1)
3831                       (const_int 16)))))))))
3832    (set (match_dup 0)
3833         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3834                 (zero_extend:DI
3835                  (truncate:HI
3836                   (const:DI
3837                    (sign_extend:DI
3838                     (truncate:HI
3839                      (match_dup 1))))))))]
3840   "TARGET_SHMEDIA64 && reload_completed
3841    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3842   "
3844   if (GET_CODE (operands[1]) == LABEL_REF
3845       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3846     LABEL_NUSES (XEXP (operands[1], 0)) += 4;
3847   else if (GOTOFF_P (operands[1])
3848            && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3849            && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3850                == CODE_LABEL))
3851     LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 4;
3854 (define_expand "movdi_const_32bit"
3855   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3856         (const:DI (sign_extend:DI
3857                    (truncate:HI
3858                     (ashiftrt:DI
3859                      (match_operand:DI 1 "immediate_operand" "s")
3860                      (const_int 16))))))
3861    (set (match_dup 0)
3862         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3863                 (zero_extend:DI
3864                  (truncate:HI
3865                   (const:DI
3866                    (sign_extend:DI
3867                     (truncate:HI
3868                      (match_dup 1))))))))]
3869   "TARGET_SHMEDIA32 && reload_completed
3870    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3871   "
3873   if (GET_CODE (operands[1]) == LABEL_REF
3874       && GET_CODE (XEXP (operands[1], 0)) == CODE_LABEL)
3875     LABEL_NUSES (XEXP (operands[1], 0)) += 2;
3876   else if (GOTOFF_P (operands[1])
3877            && GET_CODE (XVECEXP (XEXP (operands[1], 0), 0, 0)) == LABEL_REF
3878            && (GET_CODE (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0))
3879                == CODE_LABEL))
3880     LABEL_NUSES (XEXP (XVECEXP (XEXP (operands[1], 0), 0, 0), 0)) += 2;
3883 (define_expand "movdi_const_16bit"
3884   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3885         (const:DI (sign_extend:DI
3886                    (truncate:HI
3887                     (match_operand:DI 1 "immediate_operand" "s")))))]
3888   "TARGET_SHMEDIA && flag_pic && reload_completed
3889    && GET_CODE (operands[1]) == SYMBOL_REF"
3890   "")
3892 (define_split
3893   [(set (match_operand:DI 0 "arith_reg_operand" "")
3894         (match_operand:DI 1 "immediate_operand" ""))]
3895   "TARGET_SHMEDIA && reload_completed
3896    && GET_CODE (operands[1]) == CONST_INT
3897    && ! CONST_OK_FOR_J (INTVAL (operands[1]))"
3898   [(set (match_dup 0) (match_dup 2))
3899    (match_dup 1)]
3900   "
3902   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3903   unsigned HOST_WIDE_INT low = val;
3904   unsigned HOST_WIDE_INT high = val;
3905   unsigned HOST_WIDE_INT sign;
3906   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3908   /* Sign-extend the 16 least-significant bits.  */
3909   low &= 0xffff;
3910   low ^= 0x8000;
3911   low -= 0x8000;
3913   /* Arithmetic shift right the word by 16 bits.  */
3914   high >>= 16;
3915   sign = 1;
3916   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
3917   high ^= sign;
3918   high -= sign;
3919   do
3920     {
3921       /* If we can't generate the constant with a two-insn movi / shori
3922          sequence, try some other strategies.  */
3923       if (! CONST_OK_FOR_J (high))
3924         {
3925           /* Try constant load / left shift.  We know VAL != 0.  */
3926           val2 = val ^ (val-1);
3927           if (val2 > 0x1ffff)
3928             {
3929               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
3931               if (CONST_OK_FOR_J (val >> trailing_zeroes)
3932                   || (! CONST_OK_FOR_J (high >> 16)
3933                       && CONST_OK_FOR_J (val >> (trailing_zeroes + 16))))
3934                 {
3935                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
3936                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
3937                                                    GEN_INT (trailing_zeroes));
3938                   break;
3939                 }
3940             }
3941           /* Try constant load / right shift.  */
3942           val2 = (val >> 15) + 1;
3943           if (val2 == (val2 & -val2))
3944             {
3945               int shift = 49 - exact_log2 (val2);
3947               val2 = trunc_int_for_mode (val << shift, DImode);
3948               if (CONST_OK_FOR_J (val2))
3949                 {
3950                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
3951                                                    GEN_INT (shift));
3952                   break;
3953                 }
3954             }
3955           /* Try mperm.w .  */
3956           val2 = val & 0xffff;
3957           if ((val >> 16 & 0xffff) == val2
3958               && (val >> 32 & 0xffff) == val2
3959               && (val >> 48 & 0xffff) == val2)
3960             {
3961               val2 = (HOST_WIDE_INT) val >> 48;
3962               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
3963               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
3964               break;
3965             }
3966           /* Try movi / mshflo.l  */
3967           val2 = (HOST_WIDE_INT) val >> 32;
3968           if (val2 == trunc_int_for_mode (val, SImode))
3969             {
3970               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3971                                              operands[0]);
3972               break;
3973             }
3974           /* Try movi / mshflo.l w/ r63.  */
3975           val2 = val + ((HOST_WIDE_INT) -1 << 32);
3976           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_J (val2))
3977             {
3978               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
3979                                              GEN_INT (0));
3980               break;
3981             }
3982         }
3983       val2 = high;
3984       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
3985     }
3986   while (0);
3987   operands[2] = GEN_INT (val2);
3990 (define_split
3991   [(set (match_operand:DI 0 "arith_reg_operand" "")
3992         (match_operand:DI 1 "immediate_operand" ""))]
3993   "TARGET_SHMEDIA && reload_completed
3994    && GET_CODE (operands[1]) == CONST_DOUBLE"
3995   [(set (match_dup 0) (match_dup 2))
3996   (set (match_dup 0)
3997        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3998                (zero_extend:DI (truncate:HI (match_dup 1)))))]
3999   "
4001   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4002   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4003   unsigned HOST_WIDE_INT val = low;
4004   unsigned HOST_WIDE_INT sign;
4006   /* Sign-extend the 16 least-significant bits.  */
4007   val &= 0xffff;
4008   val ^= 0x8000;
4009   val -= 0x8000;
4010   operands[1] = GEN_INT (val);
4012   /* Arithmetic shift right the double-word by 16 bits.  */
4013   low >>= 16;
4014   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4015   high >>= 16;
4016   sign = 1;
4017   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4018   high ^= sign;
4019   high -= sign;
4021   /* This will only be true if high is a sign-extension of low, i.e.,
4022      it must be either 0 or (unsigned)-1, and be zero iff the
4023      most-significant bit of low is set.  */
4024   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4025     operands[2] = GEN_INT (low);
4026   else
4027     operands[2] = immed_double_const (low, high, DImode);
4030 (define_insn "shori_media"
4031   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4032         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4033                            (const_int 16))
4034                 (zero_extend:DI
4035                  (truncate:HI
4036                   (match_operand:DI 2 "immediate_operand" "JS,nF")))))]
4037   "TARGET_SHMEDIA"
4038   "@
4039         shori   %u2, %0
4040         #"
4041   [(set_attr "type" "arith_media,*")])
4043 (define_expand "movdi"
4044   [(set (match_operand:DI 0 "general_movdst_operand" "")
4045         (match_operand:DI 1 "general_movsrc_operand" ""))]
4046   ""
4047   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4049 (define_insn "movdf_media"
4050   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4051         (match_operand:DF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4052   "TARGET_SHMEDIA_FPU
4053    && (register_operand (operands[0], DFmode)
4054        || register_operand (operands[1], DFmode))"
4055   "@
4056         fmov.d  %1, %0
4057         fmov.qd %N1, %0
4058         fmov.dq %1, %0
4059         add     %1, r63, %0
4060         #
4061         fld%M1.d        %m1, %0
4062         fst%M0.d        %m0, %1
4063         ld%M1.q %m1, %0
4064         st%M0.q %m0, %1"
4065   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4067 (define_insn "movdf_media_nofpu"
4068   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4069         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,r"))]
4070   "TARGET_SHMEDIA
4071    && (register_operand (operands[0], DFmode)
4072        || register_operand (operands[1], DFmode))"
4073   "@
4074         add     %1, r63, %0
4075         #
4076         ld%M1.q %m1, %0
4077         st%M0.q %m0, %1"
4078   [(set_attr "type" "arith_media,*,load_media,store_media")])
4080 (define_split
4081   [(set (match_operand:DF 0 "arith_reg_operand" "")
4082         (match_operand:DF 1 "immediate_operand" ""))]
4083   "TARGET_SHMEDIA && reload_completed"
4084   [(set (match_dup 3) (match_dup 2))]
4085   "
4087   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4088   long values[2];
4089   REAL_VALUE_TYPE value;
4091   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4092   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4094   if (HOST_BITS_PER_WIDE_INT >= 64)
4095     operands[2] = immed_double_const ((unsigned long) values[endian]
4096                                       | ((HOST_WIDE_INT) values[1 - endian]
4097                                          << 32), 0, DImode);
4098   else if (HOST_BITS_PER_WIDE_INT == 32)
4099     operands[2] = immed_double_const (values[endian], values[1 - endian],
4100                                       DImode);
4101   else
4102     abort ();
4104   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4107 ;; ??? This should be a define expand.
4109 (define_insn "movdf_k"
4110   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4111         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4112   "TARGET_SH1
4113    && (! TARGET_SH4 || reload_completed
4114        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4115        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4116        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4117    && (arith_reg_operand (operands[0], DFmode)
4118        || arith_reg_operand (operands[1], DFmode))"
4119   "* return output_movedouble (insn, operands, DFmode);"
4120   [(set_attr "length" "4")
4121    (set_attr "type" "move,pcload,load,store")])
4123 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4124 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4125 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4126 ;; the d/m/c/X alternative, which is split later into single-precision
4127 ;; instructions.  And when not optimizing, no splits are done before fixing
4128 ;; up pcloads, so we need usable length information for that.
4129 (define_insn "movdf_i4"
4130   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4131         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4132    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4133    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4134   "TARGET_SH4
4135    && (arith_reg_operand (operands[0], DFmode)
4136        || arith_reg_operand (operands[1], DFmode))"
4137   "@
4138         fmov    %1,%0
4139         #
4140         #
4141         fmov.d  %1,%0
4142         fmov.d  %1,%0
4143         #
4144         #
4145         #
4146         #
4147         #"
4148   [(set_attr_alternative "length"
4149      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4150       (const_int 4)
4151       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4152       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4153       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4154       (const_int 4)
4155       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4156       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4157       ;; increment or decrement r15 explicitly.
4158       (if_then_else
4159        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4160        (const_int 10) (const_int 8))
4161       (if_then_else
4162        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4163        (const_int 10) (const_int 8))])
4164    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4165    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4166    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4167                                            (const_string "double")
4168                                            (const_string "none")))])
4170 ;; Moving DFmode between fp/general registers through memory
4171 ;; (the top of the stack) is faster than moving through fpul even for
4172 ;; little endian.  Because the type of an instruction is important for its
4173 ;; scheduling,  it is beneficial to split these operations, rather than
4174 ;; emitting them in one single chunk, even if this will expose a stack
4175 ;; use that will prevent scheduling of other stack accesses beyond this
4176 ;; instruction.
4177 (define_split
4178   [(set (match_operand:DF 0 "register_operand" "")
4179         (match_operand:DF 1 "register_operand" ""))
4180    (use (match_operand:PSI 2 "fpscr_operand" ""))
4181    (clobber (match_scratch:SI 3 "=X"))]
4182   "TARGET_SH4 && reload_completed
4183    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4184   [(const_int 0)]
4185   "
4187   rtx insn, tos;
4189   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4190     {
4191       emit_move_insn (stack_pointer_rtx,
4192                       plus_constant (stack_pointer_rtx, -8));
4193       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4194     }
4195   else
4196     tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4197   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4198   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4199     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4200   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4201     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4202   else
4203     tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4204   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4205   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4206     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4207   else
4208     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4209   DONE;
4212 ;; local-alloc sometimes allocates scratch registers even when not required,
4213 ;; so we must be prepared to handle these.
4215 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4216 (define_split
4217   [(set (match_operand:DF 0 "general_movdst_operand" "")
4218         (match_operand:DF 1 "general_movsrc_operand"  ""))
4219    (use (match_operand:PSI 2 "fpscr_operand" ""))
4220    (clobber (match_scratch:SI 3 ""))]
4221   "TARGET_SH4
4222    && reload_completed
4223    && true_regnum (operands[0]) < 16
4224    && true_regnum (operands[1]) < 16"
4225   [(set (match_dup 0) (match_dup 1))]
4226   "
4228   /* If this was a reg <-> mem operation with base + index reg addressing,
4229      we have to handle this in a special way.  */
4230   rtx mem = operands[0];
4231   int store_p = 1;
4232   if (! memory_operand (mem, DFmode))
4233     {
4234       mem = operands[1];
4235       store_p = 0;
4236     }
4237   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4238     mem = SUBREG_REG (mem);
4239   if (GET_CODE (mem) == MEM)
4240     {
4241       rtx addr = XEXP (mem, 0);
4242       if (GET_CODE (addr) == PLUS
4243           && GET_CODE (XEXP (addr, 0)) == REG
4244           && GET_CODE (XEXP (addr, 1)) == REG)
4245         {
4246           int offset;
4247           rtx reg0 = gen_rtx (REG, Pmode, 0);
4248           rtx regop = operands[store_p], word0 ,word1;
4250           if (GET_CODE (regop) == SUBREG)
4251             alter_subreg (&regop);
4252           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4253             offset = 2;
4254           else
4255             offset = 4;
4256           mem = copy_rtx (mem);
4257           PUT_MODE (mem, SImode);
4258           word0 = gen_rtx (SUBREG, SImode, regop, 0);
4259           alter_subreg (&word0);
4260           word1 = gen_rtx (SUBREG, SImode, regop, 4);
4261           alter_subreg (&word1);
4262           if (store_p || ! refers_to_regno_p (REGNO (word0),
4263                                               REGNO (word0) + 1, addr, 0))
4264             {
4265               emit_insn (store_p
4266                          ? gen_movsi_ie (mem, word0)
4267                          : gen_movsi_ie (word0, mem));
4268               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4269               mem = copy_rtx (mem);
4270               emit_insn (store_p
4271                          ? gen_movsi_ie (mem, word1)
4272                          : gen_movsi_ie (word1, mem));
4273               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4274             }
4275           else
4276             {
4277               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4278               emit_insn (gen_movsi_ie (word1, mem));
4279               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4280               mem = copy_rtx (mem);
4281               emit_insn (gen_movsi_ie (word0, mem));
4282             }
4283           DONE;
4284         }
4285     }
4288 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4289 (define_split
4290   [(set (match_operand:DF 0 "register_operand" "")
4291         (match_operand:DF 1 "memory_operand"  ""))
4292    (use (match_operand:PSI 2 "fpscr_operand" ""))
4293    (clobber (reg:SI R0_REG))]
4294   "TARGET_SH4 && reload_completed"
4295   [(parallel [(set (match_dup 0) (match_dup 1))
4296               (use (match_dup 2))
4297               (clobber (scratch:SI))])]
4298   "")
4300 (define_expand "reload_indf"
4301   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4302                    (match_operand:DF 1 "immediate_operand" "FQ"))
4303               (use (reg:PSI FPSCR_REG))
4304               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4305   "TARGET_SH1"
4306   "")
4308 (define_expand "reload_outdf"
4309   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4310                    (match_operand:DF 1 "register_operand" "af,r"))
4311               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4312   "TARGET_SH1"
4313   "")
4315 ;; Simplify no-op moves.
4316 (define_split
4317   [(set (match_operand:SF 0 "register_operand" "")
4318         (match_operand:SF 1 "register_operand" ""))
4319    (use (match_operand:PSI 2 "fpscr_operand" ""))
4320    (clobber (match_scratch:SI 3 "X"))]
4321   "TARGET_SH3E && reload_completed
4322    && true_regnum (operands[0]) == true_regnum (operands[1])"
4323   [(set (match_dup 0) (match_dup 0))]
4324   "")
4326 ;; fmovd substitute post-reload splits
4327 (define_split
4328   [(set (match_operand:DF 0 "register_operand" "")
4329         (match_operand:DF 1 "register_operand" ""))
4330    (use (match_operand:PSI 2 "fpscr_operand" ""))
4331    (clobber (match_scratch:SI 3 "X"))]
4332   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4333    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4334    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4335   [(const_int 0)]
4336   "
4338   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4339   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4340                            gen_rtx (REG, SFmode, src), operands[2]));
4341   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4342                            gen_rtx (REG, SFmode, src + 1), operands[2]));
4343   DONE;
4346 (define_split
4347   [(set (match_operand:DF 0 "register_operand" "")
4348         (mem:DF (match_operand:SI 1 "register_operand" "")))
4349    (use (match_operand:PSI 2 "fpscr_operand" ""))
4350    (clobber (match_scratch:SI 3 ""))]
4351   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4352    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4353    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4354   [(const_int 0)]
4355   "
4357   int regno = true_regnum (operands[0]);
4358   rtx insn;
4359   rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4361   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4362                                            regno + !! TARGET_LITTLE_ENDIAN),
4363                                   mem2, operands[2]));
4364   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4365   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4366                                            regno + ! TARGET_LITTLE_ENDIAN),
4367                                   gen_rtx (MEM, SFmode, operands[1]),
4368                                   operands[2]));
4369   DONE;
4372 (define_split
4373   [(set (match_operand:DF 0 "register_operand" "")
4374         (match_operand:DF 1 "memory_operand" ""))
4375    (use (match_operand:PSI 2 "fpscr_operand" ""))
4376    (clobber (match_scratch:SI 3 ""))]
4377   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4378    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4379   [(const_int 0)]
4380   "
4382   int regno = true_regnum (operands[0]);
4383   rtx addr, insn, adjust = NULL_RTX;
4384   rtx mem2 = copy_rtx (operands[1]);
4385   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4386   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4388   PUT_MODE (mem2, SFmode);
4389   operands[1] = copy_rtx (mem2);
4390   addr = XEXP (mem2, 0);
4391   if (GET_CODE (addr) != POST_INC)
4392     {
4393       /* If we have to modify the stack pointer, the value that we have
4394          read with post-increment might be modified by an interrupt,
4395          so write it back.  */
4396       if (REGNO (addr) == STACK_POINTER_REGNUM)
4397         adjust = gen_push_e (reg0);
4398       else
4399         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4400       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4401     }
4402   addr = XEXP (addr, 0);
4403   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4404   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4405   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4406   if (adjust)
4407     emit_insn (adjust);
4408   else
4409     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4410   DONE;
4413 (define_split
4414   [(set (match_operand:DF 0 "memory_operand" "")
4415         (match_operand:DF 1 "register_operand" ""))
4416    (use (match_operand:PSI 2 "fpscr_operand" ""))
4417    (clobber (match_scratch:SI 3 ""))]
4418   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4419    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4420   [(const_int 0)]
4421   "
4423   int regno = true_regnum (operands[1]);
4424   rtx insn, addr, adjust = NULL_RTX;
4426   operands[0] = copy_rtx (operands[0]);
4427   PUT_MODE (operands[0], SFmode);
4428   insn = emit_insn (gen_movsf_ie (operands[0],
4429                                   gen_rtx (REG, SFmode,
4430                                            regno + ! TARGET_LITTLE_ENDIAN),
4431                                   operands[2]));
4432   operands[0] = copy_rtx (operands[0]);
4433   addr = XEXP (operands[0], 0);
4434   if (GET_CODE (addr) != PRE_DEC)
4435     {
4436       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4437       emit_insn_before (adjust, insn);
4438       XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4439     }
4440   addr = XEXP (addr, 0);
4441   if (! adjust)
4442     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4443   insn = emit_insn (gen_movsf_ie (operands[0],
4444                                   gen_rtx (REG, SFmode,
4445                                            regno + !! TARGET_LITTLE_ENDIAN),
4446                                   operands[2]));
4447   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4448   DONE;
4451 ;; If the output is a register and the input is memory or a register, we have
4452 ;; to be careful and see which word needs to be loaded first.
4454 (define_split
4455   [(set (match_operand:DF 0 "general_movdst_operand" "")
4456         (match_operand:DF 1 "general_movsrc_operand" ""))]
4457   "TARGET_SH1 && reload_completed"
4458   [(set (match_dup 2) (match_dup 3))
4459    (set (match_dup 4) (match_dup 5))]
4460   "
4462   int regno;
4464   if ((GET_CODE (operands[0]) == MEM
4465        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4466       || (GET_CODE (operands[1]) == MEM
4467           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4468     FAIL;
4470   if (GET_CODE (operands[0]) == REG)
4471     regno = REGNO (operands[0]);
4472   else if (GET_CODE (operands[0]) == SUBREG)
4473     regno = subreg_regno (operands[0]);
4474   else if (GET_CODE (operands[0]) == MEM)
4475     regno = -1;
4476   else
4477     abort ();
4479   if (regno == -1
4480       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4481     {
4482       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4483       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4484       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4485       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4486     }
4487   else
4488     {
4489       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4490       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4491       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4492       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4493     }
4495   if (operands[2] == 0 || operands[3] == 0
4496       || operands[4] == 0 || operands[5] == 0)
4497     FAIL;
4500 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4501 ;; used only once, let combine add in the index again.
4503 (define_split
4504   [(set (match_operand:SI 0 "register_operand" "")
4505         (match_operand:SI 1 "" ""))
4506    (clobber (match_operand 2 "register_operand" ""))]
4507   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4508   [(use (reg:SI R0_REG))]
4509   "
4511   rtx addr, reg, const_int;
4513   if (GET_CODE (operands[1]) != MEM)
4514     FAIL;
4515   addr = XEXP (operands[1], 0);
4516   if (GET_CODE (addr) != PLUS)
4517     FAIL;
4518   reg = XEXP (addr, 0);
4519   const_int = XEXP (addr, 1);
4520   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4521          && GET_CODE (const_int) == CONST_INT))
4522     FAIL;
4523   emit_move_insn (operands[2], const_int);
4524   emit_move_insn (operands[0],
4525                   change_address (operands[1], VOIDmode,
4526                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4527   DONE;
4530 (define_split
4531   [(set (match_operand:SI 1 "" "")
4532         (match_operand:SI 0 "register_operand" ""))
4533    (clobber (match_operand 2 "register_operand" ""))]
4534   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4535   [(use (reg:SI R0_REG))]
4536   "
4538   rtx addr, reg, const_int;
4540   if (GET_CODE (operands[1]) != MEM)
4541     FAIL;
4542   addr = XEXP (operands[1], 0);
4543   if (GET_CODE (addr) != PLUS)
4544     FAIL;
4545   reg = XEXP (addr, 0);
4546   const_int = XEXP (addr, 1);
4547   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4548          && GET_CODE (const_int) == CONST_INT))
4549     FAIL;
4550   emit_move_insn (operands[2], const_int);
4551   emit_move_insn (change_address (operands[1], VOIDmode,
4552                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4553                   operands[0]);
4554   DONE;
4557 (define_expand "movdf"
4558   [(set (match_operand:DF 0 "general_movdst_operand" "")
4559         (match_operand:DF 1 "general_movsrc_operand" ""))]
4560   ""
4561   "
4563   if (prepare_move_operands (operands, DFmode)) DONE;
4564   if (TARGET_SHMEDIA)
4565     {
4566       if (TARGET_SHMEDIA_FPU)
4567         emit_insn (gen_movdf_media (operands[0], operands[1]));
4568       else
4569         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4570       DONE;
4571     }
4572   if (TARGET_SH4)
4573     {
4574       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4575       DONE;
4576     }
4579 ;;This is incompatible with the way gcc uses subregs.
4580 ;;(define_insn "movv2sf_i"
4581 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4582 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4583 ;;  "TARGET_SHMEDIA_FPU
4584 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4585 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4586 ;;  "@
4587 ;;      #
4588 ;;      fld%M1.p        %m1, %0
4589 ;;      fst%M0.p        %m0, %1"
4590 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4592 (define_insn_and_split "movv2sf_i"
4593   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4594         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfU?"))]
4595   "TARGET_SHMEDIA_FPU"
4596   "#"
4597   "TARGET_SHMEDIA_FPU && reload_completed"
4598   [(set (match_dup 0) (match_dup 1))]
4599   "
4601   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4602   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4605 (define_expand "movv2sf"
4606   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4607         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4608   "TARGET_SHMEDIA_FPU"
4609   "
4611   if (prepare_move_operands (operands, V2SFmode))
4612     DONE;
4615 (define_expand "addv2sf3"
4616   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4617    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4618    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4619   "TARGET_SHMEDIA_FPU"
4620   "
4622   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4623   DONE;
4626 (define_expand "subv2sf3"
4627   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4628    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4629    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4630   "TARGET_SHMEDIA_FPU"
4631   "
4633   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4634   DONE;
4637 (define_expand "mulv2sf3"
4638   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4639    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4640    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4641   "TARGET_SHMEDIA_FPU"
4642   "
4644   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4645   DONE;
4648 (define_expand "divv2sf3"
4649   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4650    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4651    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4652   "TARGET_SHMEDIA_FPU"
4653   "
4655   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4656   DONE;
4659 (define_insn_and_split "*movv4sf_i"
4660   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4661         (match_operand:V4SF 1 "general_operand" "fU,m,f"))]
4662   "TARGET_SHMEDIA_FPU"
4663   "#"
4664   "&& reload_completed"
4665   [(const_int 0)]
4666   "
4668   int i;
4670   for (i = 0; i < 4/2; i++)
4671     {
4672       rtx x, y;
4674       if (GET_CODE (operands[0]) == MEM)
4675         x = gen_rtx_MEM (V2SFmode,
4676                          plus_constant (XEXP (operands[0], 0),
4677                                         i * GET_MODE_SIZE (V2SFmode)));
4678       else
4679         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4681       if (GET_CODE (operands[1]) == MEM)
4682         y = gen_rtx_MEM (V2SFmode,
4683                          plus_constant (XEXP (operands[1], 0),
4684                                         i * GET_MODE_SIZE (V2SFmode)));
4685       else
4686         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4688       emit_insn (gen_movv2sf_i (x, y));
4689     }
4691   DONE;
4693   [(set_attr "length" "8")])
4695 (define_expand "movv4sf"
4696   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4697         (match_operand:V4SF 1 "general_operand" ""))]
4698   "TARGET_SHMEDIA_FPU"
4699   "
4701   if (prepare_move_operands (operands, V4SFmode))
4702     DONE;
4705 (define_insn_and_split "*movv16sf_i"
4706   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4707         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4708   "TARGET_SHMEDIA_FPU"
4709   "#"
4710   "&& reload_completed"
4711   [(const_int 0)]
4712   "
4714   int i;
4716   for (i = 0; i < 16/2; i++)
4717     {
4718       rtx x,y;
4720       if (GET_CODE (operands[0]) == MEM)
4721         x = gen_rtx_MEM (V2SFmode,
4722                          plus_constant (XEXP (operands[0], 0),
4723                                         i * GET_MODE_SIZE (V2SFmode)));
4724       else
4725         {
4726           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 2);
4727           alter_subreg (&x);
4728         }
4730       if (GET_CODE (operands[1]) == MEM)
4731         y = gen_rtx_MEM (V2SFmode,
4732                          plus_constant (XEXP (operands[1], 0),
4733                                         i * GET_MODE_SIZE (V2SFmode)));
4734       else
4735         {
4736           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 2);
4737           alter_subreg (&y);
4738         }
4740       emit_insn (gen_movv2sf_i (x, y));
4741     }
4743   DONE;
4745   [(set_attr "length" "32")])
4747 (define_expand "movv16sf"
4748   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4749         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4750   "TARGET_SHMEDIA_FPU"
4751   "
4753   if (prepare_move_operands (operands, V16SFmode))
4754     DONE;
4757 (define_insn "movsf_media"
4758   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4759         (match_operand:SF 1 "general_movsrc_operand" "f,rU,f,r,F,m,f,m,r"))]
4760   "TARGET_SHMEDIA_FPU
4761    && (register_operand (operands[0], SFmode)
4762        || register_operand (operands[1], SFmode))"
4763   "@
4764         fmov.s  %1, %0
4765         fmov.ls %N1, %0
4766         fmov.sl %1, %0
4767         add.l   %1, r63, %0
4768         #
4769         fld%M1.s        %m1, %0
4770         fst%M0.s        %m0, %1
4771         ld%M1.l %m1, %0
4772         st%M0.l %m0, %1"
4773   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4775 (define_insn "movsf_media_nofpu"
4776   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4777         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,r"))]
4778   "TARGET_SHMEDIA
4779    && (register_operand (operands[0], SFmode)
4780        || register_operand (operands[1], SFmode))"
4781   "@
4782         add.l   %1, r63, %0
4783         #
4784         ld%M1.l %m1, %0
4785         st%M0.l %m0, %1"
4786   [(set_attr "type" "arith_media,*,load_media,store_media")])
4788 (define_split
4789   [(set (match_operand:SF 0 "arith_reg_operand" "")
4790         (match_operand:SF 1 "immediate_operand" ""))]
4791   "TARGET_SHMEDIA && reload_completed
4792    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4793   [(set (match_dup 3) (match_dup 2))]
4794   "
4796   long values;
4797   REAL_VALUE_TYPE value;
4799   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4800   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4801   operands[2] = GEN_INT (values);
4803   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4806 (define_insn "movsf_i"
4807   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4808         (match_operand:SF 1 "general_movsrc_operand"  "r,I,FQ,mr,r,r,l"))]
4809   "TARGET_SH1
4810    && (! TARGET_SH3E
4811        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4812        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4813        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4814    && (arith_reg_operand (operands[0], SFmode)
4815        || arith_reg_operand (operands[1], SFmode))"
4816   "@
4817         mov     %1,%0
4818         mov     %1,%0
4819         mov.l   %1,%0
4820         mov.l   %1,%0
4821         mov.l   %1,%0
4822         lds     %1,%0
4823         sts     %1,%0"
4824   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4826 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4827 ;; update_flow_info would not know where to put REG_EQUAL notes
4828 ;; when the destination changes mode.
4829 (define_insn "movsf_ie"
4830   [(set (match_operand:SF 0 "general_movdst_operand"
4831          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4832         (match_operand:SF 1 "general_movsrc_operand"
4833           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4834    (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"))
4835    (clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4837   "TARGET_SH3E
4838    && (arith_reg_operand (operands[0], SFmode)
4839        || arith_reg_operand (operands[1], SFmode)
4840        || arith_reg_operand (operands[3], SImode)
4841        || (fpul_operand (operands[0], SFmode)
4842            && memory_operand (operands[1], SFmode)
4843            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4844        || (fpul_operand (operands[1], SFmode)
4845            && memory_operand (operands[0], SFmode)
4846            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4847   "@
4848         fmov    %1,%0
4849         mov     %1,%0
4850         fldi0   %0
4851         fldi1   %0
4852         #
4853         fmov.s  %1,%0
4854         fmov.s  %1,%0
4855         mov.l   %1,%0
4856         mov.l   %1,%0
4857         mov.l   %1,%0
4858         fsts    fpul,%0
4859         flds    %1,fpul
4860         lds.l   %1,%0
4861         #
4862         sts     %1,%0
4863         lds     %1,%0
4864         sts.l   %1,%0
4865         lds.l   %1,%0
4866         ! move optimized away"
4867   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4868    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4869    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4870    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4871                                            (const_string "single")
4872                                            (const_string "none")))])
4874 (define_split
4875   [(set (match_operand:SF 0 "register_operand" "")
4876         (match_operand:SF 1 "register_operand" ""))
4877    (use (match_operand:PSI 2 "fpscr_operand" ""))
4878    (clobber (reg:SI FPUL_REG))]
4879   "TARGET_SH1"
4880   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4881               (use (match_dup 2))
4882               (clobber (scratch:SI))])
4883    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4884               (use (match_dup 2))
4885               (clobber (scratch:SI))])]
4886   "")
4888 (define_expand "movsf"
4889   [(set (match_operand:SF 0 "general_movdst_operand" "")
4890         (match_operand:SF 1 "general_movsrc_operand" ""))]
4891   ""
4892   "
4894   if (prepare_move_operands (operands, SFmode))
4895     DONE;
4896   if (TARGET_SHMEDIA)
4897     {
4898       if (TARGET_SHMEDIA_FPU)
4899         emit_insn (gen_movsf_media (operands[0], operands[1]));
4900       else
4901         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4902       DONE;
4903     }
4904   if (TARGET_SH3E)
4905     {
4906       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4907       DONE;
4908     }
4911 (define_insn "mov_nop"
4912   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4913   "TARGET_SH3E"
4914   ""
4915   [(set_attr "length" "0")
4916    (set_attr "type" "nil")])
4918 (define_expand "reload_insf"
4919   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
4920                    (match_operand:SF 1 "immediate_operand" "FQ"))
4921               (use (reg:PSI FPSCR_REG))
4922               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4923   "TARGET_SH1"
4924   "")
4926 (define_expand "reload_insi"
4927   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
4928                    (match_operand:SF 1 "immediate_operand" "FQ"))
4929               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4930   "TARGET_SH1"
4931   "")
4933 (define_insn "*movsi_y"
4934   [(set (match_operand:SI 0 "register_operand" "=y,y")
4935         (match_operand:SI 1 "immediate_operand" "Qi,I"))
4936    (clobber (match_scratch:SI 2 "=&z,r"))]
4937   "TARGET_SH3E
4938    && (reload_in_progress || reload_completed)"
4939   "#"
4940   [(set_attr "length" "4")
4941    (set_attr "type" "pcload,move")])
4943 (define_split
4944   [(set (match_operand:SI 0 "register_operand" "")
4945         (match_operand:SI 1 "immediate_operand" ""))
4946    (clobber (match_operand:SI 2 "register_operand" ""))]
4947   "TARGET_SH1"
4948   [(set (match_dup 2) (match_dup 1))
4949    (set (match_dup 0) (match_dup 2))]
4950   "")
4952 (define_split
4953   [(set (match_operand:SI 0 "register_operand" "")
4954         (match_operand:SI 1 "memory_operand" ""))
4955    (clobber (reg:SI R0_REG))]
4956   "TARGET_SH1"
4957   [(set (match_dup 0) (match_dup 1))]
4958   "")
4960 ;; ------------------------------------------------------------------------
4961 ;; Define the real conditional branch instructions.
4962 ;; ------------------------------------------------------------------------
4964 (define_insn "branch_true"
4965   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
4966                            (label_ref (match_operand 0 "" ""))
4967                            (pc)))]
4968   "TARGET_SH1"
4969   "* return output_branch (1, insn, operands);"
4970   [(set_attr "type" "cbranch")])
4972 (define_insn "branch_false"
4973   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
4974                            (label_ref (match_operand 0 "" ""))
4975                            (pc)))]
4976   "TARGET_SH1"
4977   "* return output_branch (0, insn, operands);"
4978   [(set_attr "type" "cbranch")])
4980 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
4981 ;; which destination is too far away.
4982 ;; The const_int_operand is distinct for each branch target; it avoids
4983 ;; unwanted matches with redundant_insn.
4984 (define_insn "block_branch_redirect"
4985   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
4986   "TARGET_SH1"
4987   ""
4988   [(set_attr "length" "0")])
4990 ;; This one has the additional purpose to record a possible scratch register
4991 ;; for the following branch.
4992 (define_insn "indirect_jump_scratch"
4993   [(set (match_operand:SI 0 "register_operand" "=r")
4994         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
4995   "TARGET_SH1"
4996   ""
4997   [(set_attr "length" "0")])
4999 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5000 ;; being pulled into the delay slot of a condbranch that has been made to
5001 ;; jump around the unconditional jump because it was out of range.
5002 (define_insn "stuff_delay_slot"
5003   [(set (pc)
5004         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5005    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5006   "TARGET_SH1"
5007   ""
5008   [(set_attr "length" "0")
5009    (set_attr "cond_delay_slot" "yes")])
5011 ;; Conditional branch insns
5013 (define_expand "beq_media"
5014   [(set (pc)
5015         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5016                           (match_operand:DI 2 "arith_operand" "r,O"))
5017                       (label_ref:DI (match_operand 0 "" ""))
5018                       (pc)))]
5019   "TARGET_SHMEDIA"
5020   "")
5022 (define_insn "*beq_media_i"
5023   [(set (pc)
5024         (if_then_else (match_operator 3 "equality_comparison_operator"
5025                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5026                          (match_operand:DI 2 "arith_operand" "r,O")])
5027                       (match_operand:DI 0 "target_operand" "b,b")
5028                       (pc)))]
5029   "TARGET_SHMEDIA"
5030   "@
5031         b%o3%'  %1, %2, %0
5032         b%o3i%' %1, %2, %0"
5033   [(set_attr "type" "cbranch_media")])
5035 (define_expand "bne_media"
5036   [(set (pc)
5037         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5038                           (match_operand:DI 2 "arith_operand" "r,O"))
5039                       (label_ref:DI (match_operand 0 "" ""))
5040                       (pc)))]
5041   "TARGET_SHMEDIA"
5042   "")
5044 (define_expand "bgt_media"
5045   [(set (pc)
5046         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5047                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5048                       (label_ref:DI (match_operand 0 "" ""))
5049                       (pc)))]
5050   "TARGET_SHMEDIA"
5051   "")
5053 (define_expand "bge_media"
5054   [(set (pc)
5055         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5056                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5057                       (label_ref:DI (match_operand 0 "" ""))
5058                       (pc)))]
5059   "TARGET_SHMEDIA"
5060   "")
5062 (define_expand "bgtu_media"
5063   [(set (pc)
5064         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5065                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5066                       (label_ref:DI (match_operand 0 "" ""))
5067                       (pc)))]
5068   "TARGET_SHMEDIA"
5069   "")
5071 (define_expand "bgeu_media"
5072   [(set (pc)
5073         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5074                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5075                       (label_ref:DI (match_operand 0 "" ""))
5076                       (pc)))]
5077   "TARGET_SHMEDIA"
5078   "")
5080 (define_insn "*bgt_media_i"
5081   [(set (pc)
5082         (if_then_else (match_operator 3 "greater_comparison_operator"
5083                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5084                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5085                       (match_operand:DI 0 "target_operand" "b")
5086                       (pc)))]
5087   "TARGET_SHMEDIA"
5088   "b%o3%'       %N1, %N2, %0"
5089   [(set_attr "type" "cbranch_media")])
5091 ;; These are only needed to make invert_jump() happy.
5092 (define_insn "*blt_media_i"
5093   [(set (pc)
5094         (if_then_else (match_operator 3 "less_comparison_operator"
5095                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5096                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5097                       (match_operand:DI 0 "target_operand" "b")
5098                       (pc)))]
5099   "TARGET_SHMEDIA"
5100   "b%o3%'       %N2, %N1, %0"
5101   [(set_attr "type" "cbranch_media")])
5103 (define_expand "beq"
5104   [(set (pc)
5105         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5106                       (label_ref (match_operand 0 "" ""))
5107                       (pc)))]
5108   ""
5109   "
5111   if (TARGET_SHMEDIA)
5112     {
5113       if (GET_MODE (sh_compare_op0) != DImode)
5114         {
5115           rtx tmp = gen_reg_rtx (DImode);
5117           emit_insn (gen_seq (tmp));
5118           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5119           DONE;
5120         }
5122       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5123       emit_jump_insn (gen_beq_media (operands[0],
5124                                      sh_compare_op0, sh_compare_op1));
5125       DONE;
5126     }
5128   from_compare (operands, EQ);
5131 (define_expand "bne"
5132   [(set (pc)
5133         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5134                       (label_ref (match_operand 0 "" ""))
5135                       (pc)))]
5136   ""
5137   "
5139   if (TARGET_SHMEDIA)
5140     {
5141       if (GET_MODE (sh_compare_op0) != DImode)
5142         {
5143           rtx tmp = gen_reg_rtx (DImode);
5145           emit_insn (gen_seq (tmp));
5146           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5147           DONE;
5148         }
5150       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5151       emit_jump_insn (gen_bne_media (operands[0],
5152                                      sh_compare_op0, sh_compare_op1));
5153       DONE;
5154     }
5156   from_compare (operands, EQ);
5159 (define_expand "bgt"
5160   [(set (pc)
5161         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5162                       (label_ref (match_operand 0 "" ""))
5163                       (pc)))]
5164   ""
5165   "
5167   if (TARGET_SHMEDIA)
5168     {
5169       if (GET_MODE (sh_compare_op0) != DImode)
5170         {
5171           rtx tmp = gen_reg_rtx (DImode);
5173           emit_insn (gen_sgt (tmp));
5174           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5175           DONE;
5176         }
5178       if (sh_compare_op0 != const0_rtx)
5179         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5180       if (sh_compare_op1 != const0_rtx)
5181         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5182       emit_jump_insn (gen_bgt_media (operands[0],
5183                                      sh_compare_op0, sh_compare_op1));
5184       DONE;
5185     }
5187   from_compare (operands, GT);
5190 (define_expand "blt"
5191   [(set (pc)
5192         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5193                       (label_ref (match_operand 0 "" ""))
5194                       (pc)))]
5195   ""
5196   "
5198   if (TARGET_SHMEDIA)
5199     {
5200       if (GET_MODE (sh_compare_op0) != DImode)
5201         {
5202           rtx tmp = gen_reg_rtx (DImode);
5204           emit_insn (gen_slt (tmp));
5205           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5206           DONE;
5207         }
5209       if (sh_compare_op0 != const0_rtx)
5210         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5211       if (sh_compare_op1 != const0_rtx)
5212         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5213       emit_jump_insn (gen_bgt_media (operands[0],
5214                                      sh_compare_op1, sh_compare_op0));
5215       DONE;
5216     }
5218   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5219     {
5220       rtx tmp = sh_compare_op0;
5221       sh_compare_op0 = sh_compare_op1;
5222       sh_compare_op1 = tmp;
5223       emit_insn (gen_bgt (operands[0]));
5224       DONE;
5225     }
5226   from_compare (operands, GE);
5229 (define_expand "ble"
5230   [(set (pc)
5231         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5232                       (label_ref (match_operand 0 "" ""))
5233                       (pc)))]
5234   ""
5235   "
5237   if (TARGET_SHMEDIA)
5238     {
5239       if (GET_MODE (sh_compare_op0) != DImode)
5240         {
5241           rtx tmp = gen_reg_rtx (DImode);
5243           emit_insn (gen_sle (tmp));
5244           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5245           DONE;
5246         }
5248       if (sh_compare_op0 != const0_rtx)
5249         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5250       if (sh_compare_op1 != const0_rtx)
5251         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5252       emit_jump_insn (gen_bge_media (operands[0],
5253                                      sh_compare_op1, sh_compare_op0));
5254       DONE;
5255     }
5257   if (TARGET_SH3E
5258       && TARGET_IEEE
5259       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5260     {
5261       rtx tmp = sh_compare_op0;
5262       sh_compare_op0 = sh_compare_op1;
5263       sh_compare_op1 = tmp;
5264       emit_insn (gen_bge (operands[0]));
5265       DONE;
5266     }
5267   from_compare (operands, GT);
5270 (define_expand "bge"
5271   [(set (pc)
5272         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5273                       (label_ref (match_operand 0 "" ""))
5274                       (pc)))]
5275   ""
5276   "
5278   if (TARGET_SHMEDIA)
5279     {
5280       if (GET_MODE (sh_compare_op0) != DImode)
5281         {
5282           rtx tmp = gen_reg_rtx (DImode);
5284           emit_insn (gen_sge (tmp));
5285           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5286           DONE;
5287         }
5289       if (sh_compare_op0 != const0_rtx)
5290         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5291       if (sh_compare_op1 != const0_rtx)
5292         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5293       emit_jump_insn (gen_bge_media (operands[0],
5294                                      sh_compare_op0, sh_compare_op1));
5295       DONE;
5296     }
5298   if (TARGET_SH3E
5299       && ! TARGET_IEEE
5300       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5301     {
5302       rtx tmp = sh_compare_op0;
5303       sh_compare_op0 = sh_compare_op1;
5304       sh_compare_op1 = tmp;
5305       emit_insn (gen_ble (operands[0]));
5306       DONE;
5307     }
5308   from_compare (operands, GE);
5311 (define_expand "bgtu"
5312   [(set (pc)
5313         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5314                       (label_ref (match_operand 0 "" ""))
5315                       (pc)))]
5316   ""
5317   "
5319   if (TARGET_SHMEDIA)
5320     {
5321       if (sh_compare_op0 != const0_rtx)
5322         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5323       if (sh_compare_op1 != const0_rtx)
5324         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5325       emit_jump_insn (gen_bgtu_media (operands[0],
5326                                       sh_compare_op0, sh_compare_op1));
5327       DONE;
5328     }
5330   from_compare (operands, GTU);
5333 (define_expand "bltu"
5334   [(set (pc)
5335         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5336                       (label_ref (match_operand 0 "" ""))
5337                       (pc)))]
5338   ""
5339   "
5341   if (TARGET_SHMEDIA)
5342     {
5343       if (sh_compare_op0 != const0_rtx)
5344         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5345       if (sh_compare_op1 != const0_rtx)
5346         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5347       emit_jump_insn (gen_bgtu_media (operands[0],
5348                                       sh_compare_op1, sh_compare_op0));
5349       DONE;
5350     }
5352   from_compare (operands, GEU);
5355 (define_expand "bgeu"
5356   [(set (pc)
5357         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5358                       (label_ref (match_operand 0 "" ""))
5359                       (pc)))]
5360   ""
5361   "
5363   if (TARGET_SHMEDIA)
5364     {
5365       if (sh_compare_op0 != const0_rtx)
5366         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5367       if (sh_compare_op1 != const0_rtx)
5368         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5369       emit_jump_insn (gen_bgeu_media (operands[0],
5370                                       sh_compare_op0, sh_compare_op1));
5371       DONE;
5372     }
5374   from_compare (operands, GEU);
5377 (define_expand "bleu"
5378   [(set (pc)
5379         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5380                       (label_ref (match_operand 0 "" ""))
5381                       (pc)))]
5382   ""
5383   "
5385   if (TARGET_SHMEDIA)
5386     {
5387       if (sh_compare_op0 != const0_rtx)
5388         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5389       if (sh_compare_op1 != const0_rtx)
5390         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5391       emit_jump_insn (gen_bgeu_media (operands[0],
5392                                       sh_compare_op1, sh_compare_op0));
5393       DONE;
5394     }
5396   from_compare (operands, GTU);
5399 (define_expand "bunordered"
5400   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5401    (set (pc)
5402         (if_then_else (ne (match_dup 1) (const_int 0))
5403                       (label_ref:DI (match_operand 0 "" ""))
5404                       (pc)))]
5405   "TARGET_SHMEDIA"
5406   "
5408   operands[1] = gen_reg_rtx (DImode);
5409   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5410   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5413 ;; ------------------------------------------------------------------------
5414 ;; Jump and linkage insns
5415 ;; ------------------------------------------------------------------------
5417 (define_insn "jump_compact"
5418   [(set (pc)
5419         (label_ref (match_operand 0 "" "")))]
5420   "TARGET_SH1"
5421   "*
5423   /* The length is 16 if the delay slot is unfilled.  */
5424   if (get_attr_length(insn) > 4)
5425     return output_far_jump(insn, operands[0]);
5426   else
5427     return   \"bra      %l0%#\";
5429   [(set_attr "type" "jump")
5430    (set_attr "needs_delay_slot" "yes")])
5432 (define_insn "jump_media"
5433   [(set (pc)
5434         (match_operand:DI 0 "target_operand" "b"))]
5435   "TARGET_SHMEDIA"
5436   "blink        %0, r63"
5437   [(set_attr "type" "jump_media")])
5439 (define_expand "jump"
5440   [(set (pc)
5441         (label_ref (match_operand 0 "" "")))]
5442   ""
5443   "
5445   if (TARGET_SH1)
5446     emit_jump_insn (gen_jump_compact (operands[0]));
5447   else if (TARGET_SHMEDIA)
5448     {
5449       if (reload_in_progress || reload_completed)
5450         FAIL;
5451       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5452                                                          operands[0])));
5453     }
5454   DONE;
5457 (define_insn "force_mode_for_call"
5458   [(use (reg:PSI FPSCR_REG))]
5459   "TARGET_SHCOMPACT"
5460   ""
5461   [(set_attr "length" "0")
5462    (set (attr "fp_mode")
5463         (if_then_else (eq_attr "fpu_single" "yes")
5464                       (const_string "single") (const_string "double")))])
5466 (define_insn "calli"
5467   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5468          (match_operand 1 "" ""))
5469    (use (reg:PSI FPSCR_REG))
5470    (clobber (reg:SI PR_REG))]
5471   "TARGET_SH1"
5472   "jsr  @%0%#"
5473   [(set_attr "type" "call")
5474    (set (attr "fp_mode")
5475         (if_then_else (eq_attr "fpu_single" "yes")
5476                       (const_string "single") (const_string "double")))
5477    (set_attr "needs_delay_slot" "yes")])
5479 ;; This is a pc-rel call, using bsrf, for use with PIC.
5481 (define_insn "calli_pcrel"
5482   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5483          (match_operand 1 "" ""))
5484    (use (reg:PSI FPSCR_REG))
5485    (use (reg:SI PIC_REG))
5486    (use (match_operand 2 "" ""))
5487    (clobber (reg:SI PR_REG))]
5488   "TARGET_SH2"
5489   "bsrf %0\\n%O2:%#"
5490   [(set_attr "type" "call")
5491    (set (attr "fp_mode")
5492         (if_then_else (eq_attr "fpu_single" "yes")
5493                       (const_string "single") (const_string "double")))
5494    (set_attr "needs_delay_slot" "yes")])
5496 (define_insn_and_split "call_pcrel"
5497   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5498          (match_operand 1 "" ""))
5499    (use (reg:PSI FPSCR_REG))
5500    (use (reg:SI PIC_REG))
5501    (clobber (reg:SI PR_REG))
5502    (clobber (match_scratch:SI 2 "=r"))]
5503   "TARGET_SH2"
5504   "#"
5505   "reload_completed"
5506   [(const_int 0)]
5507   "
5509   rtx lab = PATTERN (gen_call_site ());
5511   if (SYMBOL_REF_FLAG (operands[0]))
5512     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5513   else
5514     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5515   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5516   DONE;
5518   [(set_attr "type" "call")
5519    (set (attr "fp_mode")
5520         (if_then_else (eq_attr "fpu_single" "yes")
5521                       (const_string "single") (const_string "double")))
5522    (set_attr "needs_delay_slot" "yes")])
5524 (define_insn "call_compact"
5525   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5526          (match_operand 1 "" ""))
5527    (match_operand 2 "immediate_operand" "n")
5528    (use (reg:SI R0_REG))
5529    (use (reg:SI R1_REG))
5530    (use (reg:PSI FPSCR_REG))
5531    (clobber (reg:SI PR_REG))]
5532   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5533   "jsr  @%0%#"
5534   [(set_attr "type" "call")
5535    (set (attr "fp_mode")
5536         (if_then_else (eq_attr "fpu_single" "yes")
5537                       (const_string "single") (const_string "double")))
5538    (set_attr "needs_delay_slot" "yes")])
5540 (define_insn "call_compact_rettramp"
5541   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5542          (match_operand 1 "" ""))
5543    (match_operand 2 "immediate_operand" "n")
5544    (use (reg:SI R0_REG))
5545    (use (reg:SI R1_REG))
5546    (use (reg:PSI FPSCR_REG))
5547    (clobber (reg:SI R10_REG))
5548    (clobber (reg:SI PR_REG))]
5549   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5550   "jsr  @%0%#"
5551   [(set_attr "type" "call")
5552    (set (attr "fp_mode")
5553         (if_then_else (eq_attr "fpu_single" "yes")
5554                       (const_string "single") (const_string "double")))
5555    (set_attr "needs_delay_slot" "yes")])
5557 (define_insn "call_media"
5558   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5559          (match_operand 1 "" ""))
5560    (clobber (reg:DI PR_MEDIA_REG))]
5561   "TARGET_SHMEDIA"
5562   "blink        %0, r18"
5563   [(set_attr "type" "jump_media")])
5565 (define_insn "call_valuei"
5566   [(set (match_operand 0 "" "=rf")
5567         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5568               (match_operand 2 "" "")))
5569    (use (reg:PSI FPSCR_REG))
5570    (clobber (reg:SI PR_REG))]
5571   "TARGET_SH1"
5572   "jsr  @%1%#"
5573   [(set_attr "type" "call")
5574    (set (attr "fp_mode")
5575         (if_then_else (eq_attr "fpu_single" "yes")
5576                       (const_string "single") (const_string "double")))
5577    (set_attr "needs_delay_slot" "yes")])
5579 (define_insn "call_valuei_pcrel"
5580   [(set (match_operand 0 "" "=rf")
5581         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5582               (match_operand 2 "" "")))
5583    (use (reg:PSI FPSCR_REG))
5584    (use (reg:SI PIC_REG))
5585    (use (match_operand 3 "" ""))
5586    (clobber (reg:SI PR_REG))]
5587   "TARGET_SH2"
5588   "bsrf %1\\n%O3:%#"
5589   [(set_attr "type" "call")
5590    (set (attr "fp_mode")
5591         (if_then_else (eq_attr "fpu_single" "yes")
5592                       (const_string "single") (const_string "double")))
5593    (set_attr "needs_delay_slot" "yes")])
5595 (define_insn_and_split "call_value_pcrel"
5596   [(set (match_operand 0 "" "=rf")
5597         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5598               (match_operand 2 "" "")))
5599    (use (reg:PSI FPSCR_REG))
5600    (use (reg:SI PIC_REG))
5601    (clobber (reg:SI PR_REG))
5602    (clobber (match_scratch:SI 3 "=r"))]
5603   "TARGET_SH2"
5604   "#"
5605   "reload_completed"
5606   [(const_int 0)]
5607   "
5609   rtx lab = PATTERN (gen_call_site ());
5611   if (SYMBOL_REF_FLAG (operands[1]))
5612     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5613   else
5614     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5615   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5616                                          operands[2], lab));
5617   DONE;
5619   [(set_attr "type" "call")
5620    (set (attr "fp_mode")
5621         (if_then_else (eq_attr "fpu_single" "yes")
5622                       (const_string "single") (const_string "double")))
5623    (set_attr "needs_delay_slot" "yes")])
5625 (define_insn "call_value_compact"
5626   [(set (match_operand 0 "" "=rf")
5627         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5628               (match_operand 2 "" "")))
5629    (match_operand 3 "immediate_operand" "n")
5630    (use (reg:SI R0_REG))
5631    (use (reg:SI R1_REG))
5632    (use (reg:PSI FPSCR_REG))
5633    (clobber (reg:SI PR_REG))]
5634   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5635   "jsr  @%1%#"
5636   [(set_attr "type" "call")
5637    (set (attr "fp_mode")
5638         (if_then_else (eq_attr "fpu_single" "yes")
5639                       (const_string "single") (const_string "double")))
5640    (set_attr "needs_delay_slot" "yes")])
5642 (define_insn "call_value_compact_rettramp"
5643   [(set (match_operand 0 "" "=rf")
5644         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5645               (match_operand 2 "" "")))
5646    (match_operand 3 "immediate_operand" "n")
5647    (use (reg:SI R0_REG))
5648    (use (reg:SI R1_REG))
5649    (use (reg:PSI FPSCR_REG))
5650    (clobber (reg:SI R10_REG))
5651    (clobber (reg:SI PR_REG))]
5652   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5653   "jsr  @%1%#"
5654   [(set_attr "type" "call")
5655    (set (attr "fp_mode")
5656         (if_then_else (eq_attr "fpu_single" "yes")
5657                       (const_string "single") (const_string "double")))
5658    (set_attr "needs_delay_slot" "yes")])
5660 (define_insn "call_value_media"
5661   [(set (match_operand 0 "" "=rf")
5662         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5663               (match_operand 2 "" "")))
5664    (clobber (reg:DI PR_MEDIA_REG))]
5665   "TARGET_SHMEDIA"
5666   "blink        %1, r18"
5667   [(set_attr "type" "jump_media")])
5669 (define_expand "call"
5670   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5671                             (match_operand 1 "" ""))
5672               (match_operand 2 "" "")
5673               (use (reg:PSI FPSCR_REG))
5674               (clobber (reg:SI PR_REG))])]
5675   ""
5676   "
5678   if (TARGET_SHMEDIA)
5679     {
5680       operands[0] = XEXP (operands[0], 0);
5681       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5682         {
5683           if (! SYMBOL_REF_FLAG (operands[0]))
5684             {
5685               rtx reg = gen_reg_rtx (Pmode);
5687               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5688               operands[0] = reg;
5689             }
5690           else
5691             {
5692               operands[0] = gen_sym2PIC (operands[0]);
5693               PUT_MODE (operands[0], Pmode);
5694             }
5695         }
5696       if (GET_MODE (operands[0]) == SImode)
5697         {
5698           if (GET_CODE (operands[0]) == REG)
5699             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5700           else if (GET_CODE (operands[0]) == SUBREG)
5701             {
5702               operands[0] = SUBREG_REG (operands[0]);
5703               if (GET_MODE (operands[0]) != DImode)
5704                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5705             }
5706           else
5707             {
5708               operands[0] = shallow_copy_rtx (operands[0]);
5709               PUT_MODE (operands[0], DImode);
5710             }
5711         }
5712       if (! target_reg_operand (operands[0], DImode))
5713         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5714       emit_call_insn (gen_call_media (operands[0], operands[1]));
5715       DONE;
5716     }
5717   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5718     {
5719       rtx cookie_rtx = operands[2];
5720       long cookie = INTVAL (cookie_rtx);
5721       rtx func = XEXP (operands[0], 0);
5722       rtx r0, r1;
5724       if (flag_pic)
5725         {
5726           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5727             {
5728               rtx reg = gen_reg_rtx (Pmode);
5730               emit_insn (gen_symGOTPLT2reg (reg, func));
5731               func = reg;
5732             }
5733           else
5734             func = legitimize_pic_address (func, Pmode, 0);
5735         }
5737       r0 = gen_rtx_REG (SImode, R0_REG);
5738       r1 = gen_rtx_REG (SImode, R1_REG);
5740       /* Since such a call function may use all call-clobbered
5741          registers, we force a mode switch earlier, so that we don't
5742          run out of registers when adjusting fpscr for the call.  */
5743       emit_insn (gen_force_mode_for_call ());
5745       operands[0] = gen_rtx_SYMBOL_REF (SImode,
5746                                         \"__GCC_shcompact_call_trampoline\");
5747       if (flag_pic)
5748         {
5749           rtx reg = gen_reg_rtx (Pmode);
5751           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5752           operands[0] = reg;
5753         }
5754       operands[0] = force_reg (SImode, operands[0]);
5756       emit_move_insn (r0, func);
5757       emit_move_insn (r1, cookie_rtx);
5759       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5760         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5761                                                    operands[2]));
5762       else
5763         emit_call_insn (gen_call_compact (operands[0], operands[1],
5764                                           operands[2]));
5766       DONE;
5767     }
5768   else if (TARGET_SHCOMPACT && flag_pic
5769            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5770            && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
5771     {
5772       rtx reg = gen_reg_rtx (Pmode);
5774       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5775       XEXP (operands[0], 0) = reg;
5776     }
5777   if (flag_pic && TARGET_SH2
5778       && GET_CODE (operands[0]) == MEM
5779       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5780     {
5781       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5782       DONE;
5783     }
5784   else
5785     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5787   emit_call_insn (gen_calli (operands[0], operands[1]));
5788   DONE;
5791 (define_insn "call_pop_compact"
5792   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5793          (match_operand 1 "" ""))
5794    (match_operand 2 "immediate_operand" "n")
5795    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5796                                  (match_operand 3 "immediate_operand" "n")))
5797    (use (reg:SI R0_REG))
5798    (use (reg:SI R1_REG))
5799    (use (reg:PSI FPSCR_REG))
5800    (clobber (reg:SI PR_REG))]
5801   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5802   "jsr  @%0%#"
5803   [(set_attr "type" "call")
5804    (set (attr "fp_mode")
5805         (if_then_else (eq_attr "fpu_single" "yes")
5806                       (const_string "single") (const_string "double")))
5807    (set_attr "needs_delay_slot" "yes")])
5809 (define_insn "call_pop_compact_rettramp"
5810   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5811          (match_operand 1 "" ""))
5812    (match_operand 2 "immediate_operand" "n")
5813    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5814                                  (match_operand 3 "immediate_operand" "n")))
5815    (use (reg:SI R0_REG))
5816    (use (reg:SI R1_REG))
5817    (use (reg:PSI FPSCR_REG))
5818    (clobber (reg:SI R10_REG))
5819    (clobber (reg:SI PR_REG))]
5820   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5821   "jsr  @%0%#"
5822   [(set_attr "type" "call")
5823    (set (attr "fp_mode")
5824         (if_then_else (eq_attr "fpu_single" "yes")
5825                       (const_string "single") (const_string "double")))
5826    (set_attr "needs_delay_slot" "yes")])
5828 (define_expand "call_pop"
5829   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5830                     (match_operand 1 "" ""))
5831              (match_operand 2 "" "")
5832              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5833                                            (match_operand 3 "" "")))])]
5834   "TARGET_SHCOMPACT"
5835   "
5837   if (operands[2] && INTVAL (operands[2]))
5838     {
5839       rtx cookie_rtx = operands[2];
5840       long cookie = INTVAL (cookie_rtx);
5841       rtx func = XEXP (operands[0], 0);
5842       rtx r0, r1;
5844       if (flag_pic)
5845         {
5846           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5847             {
5848               rtx reg = gen_reg_rtx (Pmode);
5850               emit_insn (gen_symGOTPLT2reg (reg, func));
5851               func = reg;
5852             }
5853           else
5854             func = legitimize_pic_address (func, Pmode, 0);
5855         }
5857       r0 = gen_rtx_REG (SImode, R0_REG);
5858       r1 = gen_rtx_REG (SImode, R1_REG);
5860       /* Since such a call function may use all call-clobbered
5861          registers, we force a mode switch earlier, so that we don't
5862          run out of registers when adjusting fpscr for the call.  */
5863       emit_insn (gen_force_mode_for_call ());
5865       operands[0] = gen_rtx_SYMBOL_REF (SImode,
5866                                         \"__GCC_shcompact_call_trampoline\");
5867       if (flag_pic)
5868         {
5869           rtx reg = gen_reg_rtx (Pmode);
5871           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5872           operands[0] = reg;
5873         }
5874       operands[0] = force_reg (SImode, operands[0]);
5876       emit_move_insn (r0, func);
5877       emit_move_insn (r1, cookie_rtx);
5879       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5880         emit_call_insn (gen_call_pop_compact_rettramp
5881                         (operands[0], operands[1], operands[2], operands[3]));
5882       else
5883         emit_call_insn (gen_call_pop_compact
5884                         (operands[0], operands[1], operands[2], operands[3]));
5886       DONE;
5887     }
5889   abort ();
5892 (define_expand "call_value"
5893   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
5894                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
5895                                  (match_operand 2 "" "")))
5896               (match_operand 3 "" "")
5897               (use (reg:PSI FPSCR_REG))
5898               (clobber (reg:SI PR_REG))])]
5899   ""
5900   "
5902   if (TARGET_SHMEDIA)
5903     {
5904       operands[1] = XEXP (operands[1], 0);
5905       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
5906         {
5907           if (! SYMBOL_REF_FLAG (operands[1]))
5908             {
5909               rtx reg = gen_reg_rtx (Pmode);
5911               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5912               operands[1] = reg;
5913             }
5914           else
5915             {
5916               operands[1] = gen_sym2PIC (operands[1]);
5917               PUT_MODE (operands[1], Pmode);
5918             }
5919         }
5920       if (GET_MODE (operands[1]) == SImode)
5921         {
5922           if (GET_CODE (operands[1]) == REG)
5923             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5924           else if (GET_CODE (operands[1]) == SUBREG)
5925             {
5926               operands[1] = SUBREG_REG (operands[1]);
5927               if (GET_MODE (operands[1]) != DImode)
5928                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
5929             }
5930           else
5931             {
5932               operands[1] = shallow_copy_rtx (operands[1]);
5933               PUT_MODE (operands[1], DImode);
5934             }
5935         }
5936       if (! target_reg_operand (operands[1], DImode))
5937         operands[1] = copy_to_mode_reg (DImode, operands[1]);
5938       emit_call_insn (gen_call_value_media (operands[0], operands[1],
5939                                             operands[2]));
5940       DONE;
5941     }
5942   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
5943     {
5944       rtx cookie_rtx = operands[3];
5945       long cookie = INTVAL (cookie_rtx);
5946       rtx func = XEXP (operands[1], 0);
5947       rtx r0, r1;
5949       if (flag_pic)
5950         {
5951           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
5952             {
5953               rtx reg = gen_reg_rtx (Pmode);
5955               emit_insn (gen_symGOTPLT2reg (reg, func));
5956               func = reg;
5957             }
5958           else
5959             func = legitimize_pic_address (func, Pmode, 0);
5960         }
5962       r0 = gen_rtx_REG (SImode, R0_REG);
5963       r1 = gen_rtx_REG (SImode, R1_REG);
5965       /* Since such a call function may use all call-clobbered
5966          registers, we force a mode switch earlier, so that we don't
5967          run out of registers when adjusting fpscr for the call.  */
5968       emit_insn (gen_force_mode_for_call ());
5970       operands[1] = gen_rtx_SYMBOL_REF (SImode,
5971                                         \"__GCC_shcompact_call_trampoline\");
5972       if (flag_pic)
5973         {
5974           rtx reg = gen_reg_rtx (Pmode);
5976           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
5977           operands[1] = reg;
5978         }
5979       operands[1] = force_reg (SImode, operands[1]);
5981       emit_move_insn (r0, func);
5982       emit_move_insn (r1, cookie_rtx);
5984       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5985         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
5986                                                          operands[1],
5987                                                          operands[2],
5988                                                          operands[3]));
5989       else
5990         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
5991                                                 operands[2], operands[3]));
5993       DONE;
5994     }
5995   else if (TARGET_SHCOMPACT && flag_pic
5996            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
5997            && ! SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
5998     {
5999       rtx reg = gen_reg_rtx (Pmode);
6001       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6002       XEXP (operands[1], 0) = reg;
6003     }
6004   if (flag_pic && TARGET_SH2
6005       && GET_CODE (operands[1]) == MEM
6006       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6007     {
6008       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6009                                             operands[2]));
6010       DONE;
6011     }
6012   else
6013     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6015   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6016   DONE;
6019 (define_insn "sibcalli"
6020   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6021          (match_operand 1 "" ""))
6022    (use (reg:PSI FPSCR_REG))
6023    (return)]
6024   "TARGET_SH1"
6025   "jmp  @%0%#"
6026   [(set_attr "needs_delay_slot" "yes")
6027    (set (attr "fp_mode")
6028         (if_then_else (eq_attr "fpu_single" "yes")
6029                       (const_string "single") (const_string "double")))
6030    (set_attr "type" "jump_ind")])
6032 (define_insn "sibcalli_pcrel"
6033   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6034          (match_operand 1 "" ""))
6035    (use (match_operand 2 "" ""))
6036    (use (reg:PSI FPSCR_REG))
6037    (return)]
6038   "TARGET_SH2"
6039   "braf %0\\n%O2:%#"
6040   [(set_attr "needs_delay_slot" "yes")
6041    (set (attr "fp_mode")
6042         (if_then_else (eq_attr "fpu_single" "yes")
6043                       (const_string "single") (const_string "double")))
6044    (set_attr "type" "jump_ind")])
6046 (define_insn_and_split "sibcall_pcrel"
6047   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6048          (match_operand 1 "" ""))
6049    (use (reg:PSI FPSCR_REG))
6050    (clobber (match_scratch:SI 2 "=k"))
6051    (return)]
6052   "TARGET_SH2"
6053   "#"
6054   "reload_completed"
6055   [(const_int 0)]
6056   "
6058   rtx lab = PATTERN (gen_call_site ());
6059   rtx call_insn;
6061   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6062   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6063                                                   lab));
6064   SIBLING_CALL_P (call_insn) = 1;
6065   DONE;
6067   [(set_attr "needs_delay_slot" "yes")
6068    (set (attr "fp_mode")
6069         (if_then_else (eq_attr "fpu_single" "yes")
6070                       (const_string "single") (const_string "double")))
6071    (set_attr "type" "jump_ind")])
6073 (define_insn "sibcall_compact"
6074   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6075          (match_operand 1 "" ""))
6076    (return)
6077    (use (match_operand:SI 2 "register_operand" "z,x"))
6078    (use (reg:SI R1_REG))
6079    (use (reg:PSI FPSCR_REG))
6080    ;; We want to make sure the `x' above will only match MACH_REG
6081    ;; because sibcall_epilogue may clobber MACL_REG.
6082    (clobber (reg:SI MACL_REG))]
6083   "TARGET_SHCOMPACT"
6084   "@
6085         jmp     @%0%#
6086         jmp     @%0\\n  sts     %2, r0"
6087   [(set_attr "needs_delay_slot" "yes,no")
6088    (set_attr "length" "2,4")
6089    (set (attr "fp_mode") (const_string "single"))
6090    (set_attr "type" "jump_ind")])
6092 (define_insn "sibcall_media"
6093   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6094          (match_operand 1 "" ""))
6095    (return)]
6096   "TARGET_SHMEDIA"
6097   "blink        %0, r63"
6098   [(set_attr "type" "jump_media")])
6100 (define_expand "sibcall"
6101   [(parallel
6102     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6103            (match_operand 1 "" ""))
6104      (match_operand 2 "" "")
6105      (use (reg:PSI FPSCR_REG))
6106      (return)])]
6107   ""
6108   "
6110   if (TARGET_SHMEDIA)
6111     {
6112       operands[0] = XEXP (operands[0], 0);
6113       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6114         {
6115           if (! SYMBOL_REF_FLAG (operands[0]))
6116             {
6117               rtx reg = gen_reg_rtx (Pmode);
6119               /* We must not use GOTPLT for sibcalls, because PIC_REG
6120                  must be restored before the PLT code gets to run.  */
6121               emit_insn (gen_symGOT2reg (reg, operands[0]));
6122               operands[0] = reg;
6123             }
6124           else
6125             {
6126               operands[0] = gen_sym2PIC (operands[0]);
6127               PUT_MODE (operands[0], Pmode);
6128             }
6129         }
6130       if (GET_MODE (operands[0]) == SImode)
6131         {
6132           if (GET_CODE (operands[0]) == REG)
6133             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6134           else if (GET_CODE (operands[0]) == SUBREG)
6135             {
6136               operands[0] = SUBREG_REG (operands[0]);
6137               if (GET_MODE (operands[0]) != DImode)
6138                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6139             }
6140           else
6141             {
6142               operands[0] = shallow_copy_rtx (operands[0]);
6143               PUT_MODE (operands[0], DImode);
6144             }
6145         }
6146       if (! target_reg_operand (operands[0], DImode))
6147         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6148       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6149       DONE;
6150     }
6151   else if (TARGET_SHCOMPACT && operands[2]
6152            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6153     {
6154       rtx cookie_rtx = operands[2];
6155       long cookie = INTVAL (cookie_rtx);
6156       rtx func = XEXP (operands[0], 0);
6157       rtx mach, r1;
6159       if (flag_pic)
6160         {
6161           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6162             {
6163               rtx reg = gen_reg_rtx (Pmode);
6165               emit_insn (gen_symGOT2reg (reg, func));
6166               func = reg;
6167             }
6168           else
6169             func = legitimize_pic_address (func, Pmode, 0);
6170         }
6172       /* FIXME: if we could tell whether all argument registers are
6173          already taken, we could decide whether to force the use of
6174          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6175          simple way to tell.  We could use the CALL_COOKIE, but we
6176          can't currently tell a register used for regular argument
6177          passing from one that is unused.  If we leave it up to reload
6178          to decide which register to use, it seems to always choose
6179          R0_REG, which leaves no available registers in SIBCALL_REGS
6180          to hold the address of the trampoline.  */
6181       mach = gen_rtx_REG (SImode, MACH_REG);
6182       r1 = gen_rtx_REG (SImode, R1_REG);
6184       /* Since such a call function may use all call-clobbered
6185          registers, we force a mode switch earlier, so that we don't
6186          run out of registers when adjusting fpscr for the call.  */
6187       emit_insn (gen_force_mode_for_call ());
6189       operands[0] = gen_rtx_SYMBOL_REF (SImode,
6190                                         \"__GCC_shcompact_call_trampoline\");
6191       if (flag_pic)
6192         {
6193           rtx reg = gen_reg_rtx (Pmode);
6195           emit_insn (gen_symGOT2reg (reg, operands[0]));
6196           operands[0] = reg;
6197         }
6198       operands[0] = force_reg (SImode, operands[0]);
6200       /* We don't need a return trampoline, since the callee will
6201          return directly to the upper caller.  */
6202       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6203         {
6204           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6205           cookie_rtx = GEN_INT (cookie);
6206         }
6208       emit_move_insn (mach, func);
6209       emit_move_insn (r1, cookie_rtx);
6211       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6212       DONE;
6213     }
6214   else if (TARGET_SHCOMPACT && flag_pic
6215            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6216            && ! SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6217     {
6218       rtx reg = gen_reg_rtx (Pmode);
6220       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6221       XEXP (operands[0], 0) = reg;
6222     }
6223   if (flag_pic && TARGET_SH2
6224       && GET_CODE (operands[0]) == MEM
6225       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6226       /* The PLT needs the PIC register, but the epilogue would have
6227          to restore it, so we can only use PC-relative PIC calls for
6228          static functions.  */
6229       && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
6230     {
6231       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6232       DONE;
6233     }
6234   else
6235     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6237   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6238   DONE;
6241 (define_expand "sibcall_value"
6242   [(set (match_operand 0 "" "")
6243         (call (match_operand 1 "" "")
6244               (match_operand 2 "" "")))
6245    (match_operand 3 "" "")]
6246   ""
6247   "
6249   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6250   DONE;
6253 (define_insn "call_value_pop_compact"
6254   [(set (match_operand 0 "" "=rf")
6255         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6256               (match_operand 2 "" "")))
6257    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6258                                  (match_operand 4 "immediate_operand" "n")))
6259    (match_operand 3 "immediate_operand" "n")
6260    (use (reg:SI R0_REG))
6261    (use (reg:SI R1_REG))
6262    (use (reg:PSI FPSCR_REG))
6263    (clobber (reg:SI PR_REG))]
6264   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6265   "jsr  @%1%#"
6266   [(set_attr "type" "call")
6267    (set (attr "fp_mode")
6268         (if_then_else (eq_attr "fpu_single" "yes")
6269                       (const_string "single") (const_string "double")))
6270    (set_attr "needs_delay_slot" "yes")])
6272 (define_insn "call_value_pop_compact_rettramp"
6273   [(set (match_operand 0 "" "=rf")
6274         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6275               (match_operand 2 "" "")))
6276    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6277                                  (match_operand 4 "immediate_operand" "n")))
6278    (match_operand 3 "immediate_operand" "n")
6279    (use (reg:SI R0_REG))
6280    (use (reg:SI R1_REG))
6281    (use (reg:PSI FPSCR_REG))
6282    (clobber (reg:SI R10_REG))
6283    (clobber (reg:SI PR_REG))]
6284   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6285   "jsr  @%1%#"
6286   [(set_attr "type" "call")
6287    (set (attr "fp_mode")
6288         (if_then_else (eq_attr "fpu_single" "yes")
6289                       (const_string "single") (const_string "double")))
6290    (set_attr "needs_delay_slot" "yes")])
6292 (define_expand "call_value_pop"
6293   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6294                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6295                                  (match_operand 2 "" "")))
6296               (match_operand 3 "" "")
6297               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6298                                             (match_operand 4 "" "")))])]
6299   "TARGET_SHCOMPACT"
6300   "
6302   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6303     {
6304       rtx cookie_rtx = operands[3];
6305       long cookie = INTVAL (cookie_rtx);
6306       rtx func = XEXP (operands[1], 0);
6307       rtx r0, r1;
6309       if (flag_pic)
6310         {
6311           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_FLAG (func))
6312             {
6313               rtx reg = gen_reg_rtx (Pmode);
6315               emit_insn (gen_symGOTPLT2reg (reg, func));
6316               func = reg;
6317             }
6318           else
6319             func = legitimize_pic_address (func, Pmode, 0);
6320         }
6322       r0 = gen_rtx_REG (SImode, R0_REG);
6323       r1 = gen_rtx_REG (SImode, R1_REG);
6325       /* Since such a call function may use all call-clobbered
6326          registers, we force a mode switch earlier, so that we don't
6327          run out of registers when adjusting fpscr for the call.  */
6328       emit_insn (gen_force_mode_for_call ());
6330       operands[1] = gen_rtx_SYMBOL_REF (SImode,
6331                                         \"__GCC_shcompact_call_trampoline\");
6332       if (flag_pic)
6333         {
6334           rtx reg = gen_reg_rtx (Pmode);
6336           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6337           operands[1] = reg;
6338         }
6339       operands[1] = force_reg (SImode, operands[1]);
6341       emit_move_insn (r0, func);
6342       emit_move_insn (r1, cookie_rtx);
6344       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6345         emit_call_insn (gen_call_value_pop_compact_rettramp
6346                         (operands[0], operands[1], operands[2],
6347                          operands[3], operands[4]));
6348       else
6349         emit_call_insn (gen_call_value_pop_compact
6350                         (operands[0], operands[1], operands[2],
6351                          operands[3], operands[4]));
6353       DONE;
6354     }
6356   abort ();
6359 (define_expand "sibcall_epilogue"
6360   [(return)]
6361   ""
6362   "
6364   sh_expand_epilogue ();
6365   if (TARGET_SHCOMPACT)
6366     {
6367       rtx insn, set;
6369       /* If epilogue clobbers r0, preserve it in macl.  */
6370       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6371         if ((set = single_set (insn))
6372             && GET_CODE (SET_DEST (set)) == REG
6373             && REGNO (SET_DEST (set)) == R0_REG)
6374           {
6375             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6376             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6377             rtx i;
6379             /* We can't tell at this point whether the sibcall is a
6380                sibcall_compact and, if it is, whether it uses r0 or
6381                mach as operand 2, so let the instructions that
6382                preserve r0 be optimized away if r0 turns out to be
6383                dead.  */
6384             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6385             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6386                                                REG_NOTES (i));
6387             i = emit_move_insn (r0, tmp);
6388             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6389                                                REG_NOTES (i));
6390             break;
6391           }
6392     }
6393   DONE;
6396 (define_insn "indirect_jump_compact"
6397   [(set (pc)
6398         (match_operand:SI 0 "arith_reg_operand" "r"))]
6399   "TARGET_SH1"
6400   "jmp  @%0%#"
6401   [(set_attr "needs_delay_slot" "yes")
6402    (set_attr "type" "jump_ind")])
6404 (define_expand "indirect_jump"
6405   [(set (pc)
6406         (match_operand 0 "register_operand" ""))]
6407   ""
6408   "
6410   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6411     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6414 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6415 ;; which can be present in structured code from indirect jumps which can not
6416 ;; be present in structured code.  This allows -fprofile-arcs to work.
6418 ;; For SH1 processors.
6419 (define_insn "casesi_jump_1"
6420   [(set (pc)
6421         (match_operand:SI 0 "register_operand" "r"))
6422    (use (label_ref (match_operand 1 "" "")))]
6423   "TARGET_SH1"
6424   "jmp  @%0%#"
6425   [(set_attr "needs_delay_slot" "yes")
6426    (set_attr "type" "jump_ind")])
6428 ;; For all later processors.
6429 (define_insn "casesi_jump_2"
6430   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6431                       (label_ref (match_operand 1 "" ""))))
6432    (use (label_ref (match_operand 2 "" "")))]
6433   "TARGET_SH2
6434    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6435   "braf %0%#"
6436   [(set_attr "needs_delay_slot" "yes")
6437    (set_attr "type" "jump_ind")])
6439 (define_insn "casesi_jump_media"
6440   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6441    (use (label_ref (match_operand 1 "" "")))]
6442   "TARGET_SHMEDIA"
6443   "blink        %0, r63"
6444   [(set_attr "type" "jump_media")])
6446 ;; Call subroutine returning any type.
6447 ;; ??? This probably doesn't work.
6449 (define_expand "untyped_call"
6450   [(parallel [(call (match_operand 0 "" "")
6451                     (const_int 0))
6452               (match_operand 1 "" "")
6453               (match_operand 2 "" "")])]
6454   "TARGET_SH3E || TARGET_SHMEDIA"
6455   "
6457   int i;
6459   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6461   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6462     {
6463       rtx set = XVECEXP (operands[2], 0, i);
6464       emit_move_insn (SET_DEST (set), SET_SRC (set));
6465     }
6467   /* The optimizer does not know that the call sets the function value
6468      registers we stored in the result block.  We avoid problems by
6469      claiming that all hard registers are used and clobbered at this
6470      point.  */
6471   emit_insn (gen_blockage ());
6473   DONE;
6476 ;; ------------------------------------------------------------------------
6477 ;; Misc insns
6478 ;; ------------------------------------------------------------------------
6480 (define_insn "dect"
6481   [(set (reg:SI T_REG)
6482         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6483    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6484   "TARGET_SH2"
6485   "dt   %0"
6486   [(set_attr "type" "arith")])
6488 (define_insn "nop"
6489   [(const_int 0)]
6490   ""
6491   "nop")
6493 ;; Load address of a label. This is only generated by the casesi expand,
6494 ;; and by machine_dependent_reorg (fixing up fp moves).
6495 ;; This must use unspec, because this only works for labels that are
6496 ;; within range,
6498 (define_insn "mova"
6499   [(set (reg:SI R0_REG)
6500         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6501   "TARGET_SH1"
6502   "mova %O0,r0"
6503   [(set_attr "in_delay_slot" "no")
6504    (set_attr "type" "arith")])
6506 ;; machine_dependent_reorg() will make this a `mova'.
6507 (define_insn "mova_const"
6508   [(set (reg:SI R0_REG)
6509         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6510   "TARGET_SH1"
6511   "#"
6512   [(set_attr "in_delay_slot" "no")
6513    (set_attr "type" "arith")])
6515 (define_expand "GOTaddr2picreg"
6516   [(set (reg:SI R0_REG)
6517         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6518                    UNSPEC_MOVA))
6519    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6520    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6521   "" "
6523   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6524   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6526   if (TARGET_SH5)
6527     operands[1] = gen_datalabel_ref (operands[1]);
6529   if (TARGET_SHMEDIA)
6530     {
6531       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6532       rtx dipic = operands[0];
6533       rtx lab = PATTERN (gen_call_site ());
6534       rtx insn, equiv;
6536       equiv = operands[1];
6537       operands[1] = gen_rtx_MINUS (DImode,
6538                                    operands[1],
6539                                    gen_rtx_CONST
6540                                    (DImode,
6541                                     gen_rtx_MINUS (DImode,
6542                                                    gen_rtx_CONST (DImode,
6543                                                                   lab),
6544                                                    pc_rtx)));
6545       operands[1] = gen_sym2PIC (operands[1]);
6546       PUT_MODE (operands[1], DImode);
6548       if (GET_MODE (dipic) != DImode)
6549         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6551       if (TARGET_SHMEDIA64)
6552         emit_insn (gen_movdi_const (dipic, operands[1]));
6553       else
6554         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6556       emit_insn (gen_ptrel (tr, dipic, lab));
6558       if (GET_MODE (operands[0]) != GET_MODE (tr))
6559         tr = gen_rtx_SUBREG (GET_MODE (operands[0]), tr, 0);
6561       insn = emit_move_insn (operands[0], tr);
6563       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6564                                             REG_NOTES (insn));
6566       DONE;
6567     }
6571 ;; When generating PIC, we must match label_refs especially, because
6572 ;; they do not satisfy LEGITIMATE_PIC_OPERAND_P(), and we don't want
6573 ;; them to do, because they can't be loaded directly into
6574 ;; non-branch-target registers.
6575 (define_insn "*pt"
6576   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6577         (match_operand:DI 1 "" "T"))]
6578   "TARGET_SHMEDIA && flag_pic
6579    && EXTRA_CONSTRAINT_T (operands[1])"
6580   "pt   %1, %0"
6581   [(set_attr "type" "pt_media")
6582    (set_attr "length" "*")])
6584 (define_insn "*ptb"
6585   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6586         (const:DI (unspec:DI [(match_operand:DI 1 "" "T")]
6587                              UNSPEC_DATALABEL)))]
6588   "TARGET_SHMEDIA && flag_pic
6589    && EXTRA_CONSTRAINT_T (operands[1])"
6590   "ptb/u        datalabel %1, %0"
6591   [(set_attr "type" "pt_media")
6592    (set_attr "length" "*")])
6594 (define_insn "ptrel"
6595   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6596         (plus:DI (match_operand:DI 1 "register_operand" "r")
6597               (pc)))
6598    (match_operand:DI 2 "" "")]
6599   "TARGET_SHMEDIA"
6600   "%O2: ptrel/u %1, %0"
6601   [(set_attr "type" "ptabs_media")])
6603 (define_expand "builtin_setjmp_receiver"
6604   [(match_operand 0 "" "")]
6605   "flag_pic"
6606   "
6608   emit_insn (gen_GOTaddr2picreg ());
6609   DONE;
6612 (define_expand "call_site"
6613   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6614   "TARGET_SH1"
6615   "
6617   static HOST_WIDE_INT i = 0;
6618   operands[0] = GEN_INT (i);
6619   i++;
6622 (define_expand "sym_label2reg"
6623   [(set (match_operand:SI 0 "" "")
6624         (const:SI (minus:SI
6625                    (const:SI
6626                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6627                    (const:SI
6628                     (plus:SI
6629                      (match_operand:SI 2 "" "")
6630                      (const_int 2))))))]
6631   "TARGET_SH1" "")
6633 (define_expand "symGOT_load"
6634   [(set (match_dup 2) (match_operand 1 "" ""))
6635    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6636    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6637   ""
6638   "
6640   rtx insn;
6642   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6643   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6645   if (TARGET_SHMEDIA)
6646     {
6647       rtx reg = operands[2];
6649       if (GET_MODE (reg) != DImode)
6650         reg = gen_rtx_SUBREG (DImode, reg, 0);
6652       if (flag_pic > 1)
6653         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6654       else
6655         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6656     }
6657   else
6658     emit_move_insn (operands[2], operands[1]);
6660   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6661                                              operands[2],
6662                                              gen_rtx_REG (Pmode, PIC_REG)));
6664   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6666   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6667                                                                   0), 0, 0),
6668                                         REG_NOTES (insn));
6670   DONE;
6673 (define_expand "sym2GOT"
6674   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6675   ""
6676   "")
6678 (define_expand "symGOT2reg"
6679   [(match_operand 0 "" "") (match_operand 1 "" "")]
6680   ""
6681   "
6683   rtx gotsym, insn;
6685   gotsym = gen_sym2GOT (operands[1]);
6686   PUT_MODE (gotsym, Pmode);
6687   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6689   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6691   DONE;
6694 (define_expand "sym2GOTPLT"
6695   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6696   ""
6697   "")
6699 (define_expand "symGOTPLT2reg"
6700   [(match_operand 0 "" "") (match_operand 1 "" "")]
6701   ""
6702   "
6704   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6705   DONE;
6708 (define_expand "sym2GOTOFF"
6709   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6710   ""
6711   "")
6713 (define_expand "symGOTOFF2reg"
6714   [(match_operand 0 "" "") (match_operand 1 "" "")]
6715   ""
6716   "
6718   rtx gotoffsym, insn;
6719   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6721   gotoffsym = gen_sym2GOTOFF (operands[1]);
6722   PUT_MODE (gotoffsym, Pmode);
6723   emit_move_insn (t, gotoffsym);
6724   insn = emit_move_insn (operands[0],
6725                          gen_rtx_PLUS (Pmode, t,
6726                                        gen_rtx_REG (Pmode, PIC_REG)));
6728   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6729                                         REG_NOTES (insn));
6731   DONE;
6734 (define_expand "symPLT_label2reg"
6735   [(set (match_operand:SI 0 "" "")
6736         (const:SI (minus:SI
6737                    (const:SI
6738                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6739                    (const:SI
6740                     (minus:SI
6741                      (const:SI (plus:SI
6742                                 (match_operand:SI 2 "" "")
6743                                 (const_int 2)))
6744                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6745    ;; Even though the PIC register is not really used by the call
6746    ;; sequence in which this is expanded, the PLT code assumes the PIC
6747    ;; register is set, so we must not skip its initialization.  Since
6748    ;; we only use this expand as part of calling sequences, and never
6749    ;; to take the address of a function, this is the best point to
6750    ;; insert the (use).  Using the PLT to take the address of a
6751    ;; function would be wrong, not only because the PLT entry could
6752    ;; then be called from a function that doesn't initialize the PIC
6753    ;; register to the proper GOT, but also because pointers to the
6754    ;; same function might not compare equal, should they be set by
6755    ;; different shared libraries.
6756    (use (reg:SI PIC_REG))]
6757   "TARGET_SH1"
6758   "")
6760 (define_expand "sym2PIC"
6761   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6762   ""
6763   "")
6765 ;; case instruction for switch statements.
6767 ;; Operand 0 is index
6768 ;; operand 1 is the minimum bound
6769 ;; operand 2 is the maximum bound - minimum bound + 1
6770 ;; operand 3 is CODE_LABEL for the table;
6771 ;; operand 4 is the CODE_LABEL to go to if index out of range.
6773 (define_expand "casesi"
6774   [(match_operand:SI 0 "arith_reg_operand" "")
6775    (match_operand:SI 1 "arith_reg_operand" "")
6776    (match_operand:SI 2 "arith_reg_operand" "")
6777    (match_operand 3 "" "") (match_operand 4 "" "")]
6778   ""
6779   "
6781   rtx reg = gen_reg_rtx (SImode);
6782   rtx reg2 = gen_reg_rtx (SImode);
6783   if (TARGET_SHMEDIA)
6784     {
6785       rtx reg = gen_reg_rtx (DImode);
6786       rtx reg2 = gen_reg_rtx (DImode);
6787       rtx reg3 = gen_reg_rtx (DImode);
6788       rtx reg4 = gen_reg_rtx (DImode);
6789       rtx reg5 = gen_reg_rtx (DImode);
6791       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
6792       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
6793       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
6795       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
6796       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
6797       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
6798       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
6799       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
6800                                                (DImode, operands[3])));
6801       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
6802       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
6803       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
6804       emit_barrier ();
6805       DONE;
6806     }
6807   operands[1] = copy_to_mode_reg (SImode, operands[1]);
6808   operands[2] = copy_to_mode_reg (SImode, operands[2]);
6809   /* If optimizing, casesi_worker depends on the mode of the instruction
6810      before label it 'uses' - operands[3].  */
6811   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
6812                            reg));
6813   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
6814   if (TARGET_SH2)
6815     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
6816   else
6817     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
6818   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
6819      operands[3], but to lab.  We will fix this up in
6820      machine_dependent_reorg.  */
6821   emit_barrier ();
6822   DONE;
6825 (define_expand "casesi_0"
6826   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
6827    (set (match_dup 4) (minus:SI (match_dup 4)
6828                                 (match_operand:SI 1 "arith_operand" "")))
6829    (set (reg:SI T_REG)
6830         (gtu:SI (match_dup 4)
6831                 (match_operand:SI 2 "arith_reg_operand" "")))
6832    (set (pc)
6833         (if_then_else (ne (reg:SI T_REG)
6834                           (const_int 0))
6835                       (label_ref (match_operand 3 "" ""))
6836                       (pc)))]
6837   "TARGET_SH1"
6838   "")
6840 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
6841 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
6842 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
6844 (define_insn "casesi_worker_0"
6845   [(set (match_operand:SI 0 "register_operand" "=r,r")
6846         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
6847                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6848    (clobber (match_scratch:SI 3 "=X,1"))
6849    (clobber (match_scratch:SI 4 "=&z,z"))]
6850   "TARGET_SH1"
6851   "#")
6853 (define_split
6854   [(set (match_operand:SI 0 "register_operand" "")
6855         (unspec:SI [(match_operand:SI 1 "register_operand" "")
6856                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6857    (clobber (match_scratch:SI 3 ""))
6858    (clobber (match_scratch:SI 4 ""))]
6859   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
6860   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6861    (parallel [(set (match_dup 0)
6862               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6863                           (label_ref (match_dup 2))] UNSPEC_CASESI))
6864               (clobber (match_dup 3))])
6865    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6866   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6868 (define_split
6869   [(set (match_operand:SI 0 "register_operand" "")
6870         (unspec:SI [(match_operand:SI 1 "register_operand" "")
6871                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6872    (clobber (match_scratch:SI 3 ""))
6873    (clobber (match_scratch:SI 4 ""))]
6874   "TARGET_SH2 && reload_completed"
6875   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
6876    (parallel [(set (match_dup 0)
6877               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
6878                           (label_ref (match_dup 2))] UNSPEC_CASESI))
6879               (clobber (match_dup 3))])]
6880   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
6882 (define_insn "*casesi_worker"
6883   [(set (match_operand:SI 0 "register_operand" "=r,r")
6884         (unspec:SI [(reg:SI R0_REG)
6885                     (match_operand:SI 1 "register_operand" "0,r")
6886                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
6887    (clobber (match_scratch:SI 3 "=X,1"))]
6888   "TARGET_SH1"
6889   "*
6891   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6893   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6894     abort ();
6896   switch (GET_MODE (diff_vec))
6897     {
6898     case SImode:
6899       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
6900     case HImode:
6901       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
6902     case QImode:
6903       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6904         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
6905       return \"mov.b    @(r0,%1),%0\";
6906     default:
6907       abort ();
6908     }
6910   [(set_attr "length" "4")])
6912 (define_insn "casesi_shift_media"
6913   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6914         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
6915                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
6916                     UNSPEC_CASESI)))]
6917   "TARGET_SHMEDIA"
6918   "*
6920   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
6922   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6923     abort ();
6925   switch (GET_MODE (diff_vec))
6926     {
6927     case SImode:
6928       return \"shlli    %1, 2, %0\";
6929     case HImode:
6930       return \"shlli    %1, 1, %0\";
6931     case QImode:
6932       if (rtx_equal_p (operands[0], operands[1]))
6933         return \"\";
6934       return \"add      %1, r63, %0\";
6935     default:
6936       abort ();
6937     }
6939   [(set_attr "type" "arith_media")])
6941 (define_insn "casesi_load_media"
6942   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
6943         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
6944                          (match_operand 2 "arith_reg_operand" "r")
6945                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
6946   "TARGET_SHMEDIA"
6947   "*
6949   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
6951   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
6952     abort ();
6954   switch (GET_MODE (diff_vec))
6955     {
6956     case SImode:
6957       return \"ldx.l    %1, %2, %0\";
6958     case HImode:
6959 #if 0
6960       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6961         return \"ldx.uw %1, %2, %0\";
6962 #endif
6963       return \"ldx.w    %1, %2, %0\";
6964     case QImode:
6965       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
6966         return \"ldx.ub %1, %2, %0\";
6967       return \"ldx.b    %1, %2, %0\";
6968     default:
6969       abort ();
6970     }
6972   [(set_attr "type" "load_media")])
6974 (define_expand "return"
6975   [(return)]
6976   "reload_completed && ! sh_need_epilogue ()"
6977   "
6979   if (TARGET_SHMEDIA)
6980     {
6981       emit_jump_insn (gen_return_media ());
6982       DONE;
6983     }
6985   if (TARGET_SHCOMPACT
6986       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
6987     {
6988       emit_jump_insn (gen_shcompact_return_tramp ());
6989       DONE;
6990     }
6993 (define_insn "*return_i"
6994   [(return)]
6995   "TARGET_SH1 && ! (TARGET_SHCOMPACT
6996                     && (current_function_args_info.call_cookie
6997                         & CALL_COOKIE_RET_TRAMP (1)))
6998    && reload_completed"
6999   "%@   %#"
7000   [(set_attr "type" "return")
7001    (set_attr "needs_delay_slot" "yes")])
7003 (define_expand "shcompact_return_tramp"
7004   [(return)]
7005   "TARGET_SHCOMPACT
7006    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7007   "
7009   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7010   rtx sym = gen_rtx_SYMBOL_REF (Pmode,
7011                                 \"__GCC_shcompact_return_trampoline\");
7013   if (flag_pic)
7014     emit_insn (gen_symGOTPLT2reg (reg, sym));
7015   else
7016     emit_move_insn (reg, sym);
7018   emit_jump_insn (gen_shcompact_return_tramp_i ());
7019   DONE;
7022 (define_insn "shcompact_return_tramp_i"
7023   [(parallel [(return) (use (reg:SI R0_REG))])]
7024   "TARGET_SHCOMPACT
7025    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7026   "jmp  @r0%#"
7027   [(set_attr "type" "jump_ind")
7028    (set_attr "needs_delay_slot" "yes")])
7030 (define_insn "return_media_i"
7031   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7032   "TARGET_SHMEDIA && reload_completed"
7033   "blink        %0, r63"
7034   [(set_attr "type" "jump_media")])
7036 (define_expand "return_media"
7037   [(return)]
7038   "TARGET_SHMEDIA && reload_completed"
7039   "
7041   int tr_regno = sh_media_register_for_return ();
7042   rtx tr;
7044   if (tr_regno < 0)
7045     {
7046       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7048       tr_regno = TR0_REG;
7049       tr = gen_rtx_REG (DImode, tr_regno);
7050       emit_move_insn (tr, r18);
7051     }
7052   else
7053     tr = gen_rtx_REG (DImode, tr_regno);
7055   emit_jump_insn (gen_return_media_i (tr));
7056   DONE;
7059 (define_insn "shcompact_preserve_incoming_args"
7060   [(set (match_operand:SI 0 "register_operand" "+r")
7061         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7062   "TARGET_SHCOMPACT"
7063   ""
7064   [(set_attr "length" "0")])
7066 (define_insn "shcompact_incoming_args"
7067   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7068    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7069    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7070    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7071    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7072    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7073    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7074    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7075    (set (mem:BLK (reg:SI MACL_REG))
7076         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7077    (use (reg:SI R0_REG))
7078    (clobber (reg:SI R0_REG))
7079    (clobber (reg:SI MACL_REG))
7080    (clobber (reg:SI MACH_REG))
7081    (clobber (reg:SI PR_REG))]
7082   "TARGET_SHCOMPACT"
7083   "jsr  @r0%#"
7084   [(set_attr "needs_delay_slot" "yes")])
7086 (define_insn "shmedia_save_restore_regs_compact"
7087   [(set (reg:SI SP_REG)
7088         (plus:SI (reg:SI SP_REG)
7089                  (match_operand:SI 0 "immediate_operand" "i")))
7090    (use (reg:SI R0_REG))
7091    (clobber (reg:SI PR_REG))]
7092   "TARGET_SHCOMPACT
7093    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7094        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7095   "jsr @r0%#"
7096   [(set_attr "needs_delay_slot" "yes")])
7098 (define_expand "prologue"
7099   [(const_int 0)]
7100   ""
7101   "sh_expand_prologue (); DONE;")
7103 (define_expand "epilogue"
7104   [(return)]
7105   ""
7106   "
7108   sh_expand_epilogue ();
7109   emit_jump_insn (gen_return ());
7110   DONE;
7113 (define_insn "blockage"
7114   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7115   ""
7116   ""
7117   [(set_attr "length" "0")])
7119 ;; ------------------------------------------------------------------------
7120 ;; Scc instructions
7121 ;; ------------------------------------------------------------------------
7123 (define_insn "movt"
7124   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7125         (eq:SI (reg:SI T_REG) (const_int 1)))]
7126   "TARGET_SH1"
7127   "movt %0"
7128   [(set_attr "type" "arith")])
7130 (define_expand "seq"
7131   [(set (match_operand:SI 0 "arith_reg_operand" "")
7132         (match_dup 1))]
7133   ""
7134   "
7136   if (TARGET_SHMEDIA)
7137     {
7138       if (GET_MODE (operands[0]) != DImode)
7139         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7140       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7141       if (sh_compare_op1 != const0_rtx)
7142         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7143                                     ? GET_MODE (sh_compare_op0)
7144                                     : GET_MODE (sh_compare_op1),
7145                                     sh_compare_op1);
7147       switch (GET_MODE (sh_compare_op0))
7148         {
7149         case DImode:
7150           emit_insn (gen_cmpeqdi_media (operands[0],
7151                                         sh_compare_op0, sh_compare_op1));
7152           break;
7154         case SFmode:
7155           if (! TARGET_SHMEDIA_FPU)
7156             FAIL;
7157           emit_insn (gen_cmpeqsf_media (operands[0],
7158                                         sh_compare_op0, sh_compare_op1));
7159           break;
7161         case DFmode:
7162           if (! TARGET_SHMEDIA_FPU)
7163             FAIL;
7164           emit_insn (gen_cmpeqdf_media (operands[0],
7165                                         sh_compare_op0, sh_compare_op1));
7166           break;
7168         default:
7169           FAIL;
7170         }
7171       DONE;
7172     }
7173   operands[1] = prepare_scc_operands (EQ);
7176 (define_expand "slt"
7177   [(set (match_operand:SI 0 "arith_reg_operand" "")
7178         (match_dup 1))]
7179   ""
7180   "
7182   if (TARGET_SHMEDIA)
7183     {
7184       if (GET_MODE (operands[0]) != DImode)
7185         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7186       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7187       if (sh_compare_op1 != const0_rtx)
7188         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7189                                     ? GET_MODE (sh_compare_op0)
7190                                     : GET_MODE (sh_compare_op1),
7191                                     sh_compare_op1);
7193       switch (GET_MODE (sh_compare_op0))
7194         {
7195         case DImode:
7196           emit_insn (gen_cmpgtdi_media (operands[0],
7197                                         sh_compare_op1, sh_compare_op0));
7198           break;
7200         case SFmode:
7201           if (! TARGET_SHMEDIA_FPU)
7202             FAIL;
7203           emit_insn (gen_cmpgtsf_media (operands[0],
7204                                         sh_compare_op1, sh_compare_op0));
7205           break;
7207         case DFmode:
7208           if (! TARGET_SHMEDIA_FPU)
7209             FAIL;
7210           emit_insn (gen_cmpgtdf_media (operands[0],
7211                                         sh_compare_op1, sh_compare_op0));
7212           break;
7214         default:
7215           FAIL;
7216         }
7217       DONE;
7218     }
7219   operands[1] = prepare_scc_operands (LT);
7222 (define_expand "sle"
7223   [(match_operand:SI 0 "arith_reg_operand" "")]
7224   ""
7225   "
7227   rtx tmp = sh_compare_op0;
7229   if (TARGET_SHMEDIA)
7230     {
7231       if (GET_MODE (operands[0]) != DImode)
7232         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7233       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7234       if (sh_compare_op1 != const0_rtx)
7235         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7236                                     ? GET_MODE (sh_compare_op0)
7237                                     : GET_MODE (sh_compare_op1),
7238                                     sh_compare_op1);
7240       switch (GET_MODE (sh_compare_op0))
7241         {
7242         case DImode:
7243           {
7244             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7246             emit_insn (gen_cmpgtdi_media (tmp,
7247                                           sh_compare_op0, sh_compare_op1));
7248             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7249             break;
7250           }
7252         case SFmode:
7253           if (! TARGET_SHMEDIA_FPU)
7254             FAIL;
7255           emit_insn (gen_cmpgesf_media (operands[0],
7256                                         sh_compare_op1, sh_compare_op0));
7257           break;
7259         case DFmode:
7260           if (! TARGET_SHMEDIA_FPU)
7261             FAIL;
7262           emit_insn (gen_cmpgedf_media (operands[0],
7263                                         sh_compare_op1, sh_compare_op0));
7264           break;
7266         default:
7267           FAIL;
7268         }
7269       DONE;
7270     }
7272   sh_compare_op0 = sh_compare_op1;
7273   sh_compare_op1 = tmp;
7274   emit_insn (gen_sge (operands[0]));
7275   DONE;
7278 (define_expand "sgt"
7279   [(set (match_operand:SI 0 "arith_reg_operand" "")
7280         (match_dup 1))]
7281   ""
7282   "
7284   if (TARGET_SHMEDIA)
7285     {
7286       if (GET_MODE (operands[0]) != DImode)
7287         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7288       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7289       if (sh_compare_op1 != const0_rtx)
7290         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7291                                     ? GET_MODE (sh_compare_op0)
7292                                     : GET_MODE (sh_compare_op1),
7293                                     sh_compare_op1);
7295       switch (GET_MODE (sh_compare_op0))
7296         {
7297         case DImode:
7298           emit_insn (gen_cmpgtdi_media (operands[0],
7299                                         sh_compare_op0, sh_compare_op1));
7300           break;
7302         case SFmode:
7303           if (! TARGET_SHMEDIA_FPU)
7304             FAIL;
7305           emit_insn (gen_cmpgtsf_media (operands[0],
7306                                         sh_compare_op0, sh_compare_op1));
7307           break;
7309         case DFmode:
7310           if (! TARGET_SHMEDIA_FPU)
7311             FAIL;
7312           emit_insn (gen_cmpgtdf_media (operands[0],
7313                                         sh_compare_op0, sh_compare_op1));
7314           break;
7316         default:
7317           FAIL;
7318         }
7319       DONE;
7320     }
7321   operands[1] = prepare_scc_operands (GT);
7324 (define_expand "sge"
7325   [(set (match_operand:SI 0 "arith_reg_operand" "")
7326         (match_dup 1))]
7327   ""
7328   "
7330   if (TARGET_SHMEDIA)
7331     {
7332       if (GET_MODE (operands[0]) != DImode)
7333         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7334       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7335       if (sh_compare_op1 != const0_rtx)
7336         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7337                                     ? GET_MODE (sh_compare_op0)
7338                                     : GET_MODE (sh_compare_op1),
7339                                     sh_compare_op1);
7341       switch (GET_MODE (sh_compare_op0))
7342         {
7343         case DImode:
7344           {
7345             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7347             emit_insn (gen_cmpgtdi_media (tmp,
7348                                           sh_compare_op1, sh_compare_op0));
7349             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7350             break;
7351           }
7353         case SFmode:
7354           if (! TARGET_SHMEDIA_FPU)
7355             FAIL;
7356           emit_insn (gen_cmpgesf_media (operands[0],
7357                                         sh_compare_op0, sh_compare_op1));
7358           break;
7360         case DFmode:
7361           if (! TARGET_SHMEDIA_FPU)
7362             FAIL;
7363           emit_insn (gen_cmpgedf_media (operands[0],
7364                                         sh_compare_op0, sh_compare_op1));
7365           break;
7367         default:
7368           FAIL;
7369         }
7370       DONE;
7371     }
7373   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7374     {
7375       if (TARGET_IEEE)
7376         {
7377           rtx lab = gen_label_rtx ();
7378           prepare_scc_operands (EQ);
7379           emit_jump_insn (gen_branch_true (lab));
7380           prepare_scc_operands (GT);
7381           emit_label (lab);
7382           emit_insn (gen_movt (operands[0]));
7383         }
7384       else
7385         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7386       DONE;
7387     }
7388   operands[1] = prepare_scc_operands (GE);
7391 (define_expand "sgtu"
7392   [(set (match_operand:SI 0 "arith_reg_operand" "")
7393         (match_dup 1))]
7394   ""
7395   "
7397   if (TARGET_SHMEDIA)
7398     {
7399       if (GET_MODE (operands[0]) != DImode)
7400         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7401       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7402       if (sh_compare_op1 != const0_rtx)
7403         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7404                                     ? GET_MODE (sh_compare_op0)
7405                                     : GET_MODE (sh_compare_op1),
7406                                     sh_compare_op1);
7408       emit_insn (gen_cmpgtudi_media (operands[0],
7409                                      sh_compare_op0, sh_compare_op1));
7410       DONE;
7411     }
7412   operands[1] = prepare_scc_operands (GTU);
7415 (define_expand "sltu"
7416   [(set (match_operand:SI 0 "arith_reg_operand" "")
7417         (match_dup 1))]
7418   ""
7419   "
7421   if (TARGET_SHMEDIA)
7422     {
7423       if (GET_MODE (operands[0]) != DImode)
7424         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7425       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7426       if (sh_compare_op1 != const0_rtx)
7427         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7428                                     ? GET_MODE (sh_compare_op0)
7429                                     : GET_MODE (sh_compare_op1),
7430                                     sh_compare_op1);
7432       emit_insn (gen_cmpgtudi_media (operands[0],
7433                                      sh_compare_op1, sh_compare_op0));
7434       DONE;
7435     }
7436   operands[1] = prepare_scc_operands (LTU);
7439 (define_expand "sleu"
7440   [(set (match_operand:SI 0 "arith_reg_operand" "")
7441         (match_dup 1))]
7442   ""
7443   "
7445   if (TARGET_SHMEDIA)
7446     {
7447       rtx tmp;
7449       if (GET_MODE (operands[0]) != DImode)
7450         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7451       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7452       if (sh_compare_op1 != const0_rtx)
7453         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7454                                     ? GET_MODE (sh_compare_op0)
7455                                     : GET_MODE (sh_compare_op1),
7456                                     sh_compare_op1);
7458       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7460       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7461       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7463       DONE;
7464     }
7465   operands[1] = prepare_scc_operands (LEU);
7468 (define_expand "sgeu"
7469   [(set (match_operand:SI 0 "arith_reg_operand" "")
7470         (match_dup 1))]
7471   ""
7472   "
7474   if (TARGET_SHMEDIA)
7475     {
7476       rtx tmp;
7478       if (GET_MODE (operands[0]) != DImode)
7479         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7480       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7481       if (sh_compare_op1 != const0_rtx)
7482         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7483                                     ? GET_MODE (sh_compare_op0)
7484                                     : GET_MODE (sh_compare_op1),
7485                                     sh_compare_op1);
7487       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7489       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7490       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7492       DONE;
7493     }
7495   operands[1] = prepare_scc_operands (GEU);
7498 ;; sne moves the complement of the T reg to DEST like this:
7499 ;;      cmp/eq ...
7500 ;;      mov    #-1,temp
7501 ;;      negc   temp,dest
7502 ;;   This is better than xoring compare result with 1 because it does
7503 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7504 ;;   loop.
7506 (define_expand "sne"
7507   [(set (match_dup 2) (const_int -1))
7508    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7509                    (neg:SI (plus:SI (match_dup 1)
7510                                     (match_dup 2))))
7511               (set (reg:SI T_REG)
7512                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7513                           (const_int 0)))])]
7514   ""
7515   "
7517   if (TARGET_SHMEDIA)
7518     {
7519       rtx tmp;
7521       if (GET_MODE (operands[0]) != DImode)
7522         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7524       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7525         FAIL;
7527       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7528       if (sh_compare_op1 != const0_rtx)
7529         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7530                                     ? GET_MODE (sh_compare_op0)
7531                                     : GET_MODE (sh_compare_op1),
7532                                     sh_compare_op1);
7534       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7536       emit_insn (gen_seq (tmp));
7537       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7539       DONE;
7540     }
7542    operands[1] = prepare_scc_operands (EQ);
7543    operands[2] = gen_reg_rtx (SImode);
7546 (define_expand "sunordered"
7547   [(set (match_operand:DI 0 "arith_reg_operand" "")
7548         (unordered:DI (match_dup 1) (match_dup 2)))]
7549   "TARGET_SHMEDIA_FPU"
7550   "
7552   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7553   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7556 ;; Use the same trick for FP sle / sge
7557 (define_expand "movnegt"
7558   [(set (match_dup 2) (const_int -1))
7559    (parallel [(set (match_operand 0 "" "")
7560                    (neg:SI (plus:SI (match_dup 1)
7561                                     (match_dup 2))))
7562               (set (reg:SI T_REG)
7563                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7564                           (const_int 0)))])]
7565   "TARGET_SH1"
7566   "operands[2] = gen_reg_rtx (SImode);")
7568 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7569 ;; This prevents a regression that occurred when we switched from xor to
7570 ;; mov/neg for sne.
7572 (define_split
7573   [(set (match_operand:SI 0 "arith_reg_operand" "")
7574         (plus:SI (reg:SI T_REG)
7575                  (const_int -1)))]
7576   "TARGET_SH1"
7577   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7578    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7579   "")
7581 ;; -------------------------------------------------------------------------
7582 ;; Instructions to cope with inline literal tables
7583 ;; -------------------------------------------------------------------------
7585 ; 2 byte integer in line
7587 (define_insn "consttable_2"
7588  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7589                     (match_operand 1 "" "")]
7590                    UNSPECV_CONST2)]
7591  ""
7592  "*
7594   if (operands[1] != const0_rtx)
7595     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7596   return \"\";
7598  [(set_attr "length" "2")
7599  (set_attr "in_delay_slot" "no")])
7601 ; 4 byte integer in line
7603 (define_insn "consttable_4"
7604  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7605                     (match_operand 1 "" "")]
7606                    UNSPECV_CONST4)]
7607  ""
7608  "*
7610   if (operands[1] != const0_rtx)
7611     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7612   return \"\";
7614  [(set_attr "length" "4")
7615   (set_attr "in_delay_slot" "no")])
7617 ; 8 byte integer in line
7619 (define_insn "consttable_8"
7620  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7621                     (match_operand 1 "" "")]
7622                    UNSPECV_CONST8)]
7623  ""
7624  "*
7626   if (operands[1] != const0_rtx)
7627     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7628   return \"\";
7630  [(set_attr "length" "8")
7631   (set_attr "in_delay_slot" "no")])
7633 ; 4 byte floating point
7635 (define_insn "consttable_sf"
7636  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7637                     (match_operand 1 "" "")]
7638                    UNSPECV_CONST4)]
7639  ""
7640  "*
7642   if (operands[1] != const0_rtx)
7643     {
7644       REAL_VALUE_TYPE d;
7645       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7646       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7647     }
7648   return \"\";
7650  [(set_attr "length" "4")
7651   (set_attr "in_delay_slot" "no")])
7653 ; 8 byte floating point
7655 (define_insn "consttable_df"
7656  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7657                     (match_operand 1 "" "")]
7658                    UNSPECV_CONST8)]
7659  ""
7660  "*
7662   if (operands[1] != const0_rtx)
7663     {
7664       REAL_VALUE_TYPE d;
7665       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7666       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7667     }
7668   return \"\";
7670  [(set_attr "length" "8")
7671   (set_attr "in_delay_slot" "no")])
7673 ;; Alignment is needed for some constant tables; it may also be added for
7674 ;; Instructions at the start of loops, or after unconditional branches.
7675 ;; ??? We would get more accurate lengths if we did instruction
7676 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7677 ;; here is too conservative.
7679 ; align to a two byte boundary
7681 (define_expand "align_2"
7682  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7683  ""
7684  "")
7686 ; align to a four byte boundary
7687 ;; align_4 and align_log are instructions for the starts of loops, or
7688 ;; after unconditional branches, which may take up extra room.
7690 (define_expand "align_4"
7691  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7692  ""
7693  "")
7695 ; align to a cache line boundary
7697 (define_insn "align_log"
7698  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
7699  ""
7700  ""
7701  [(set_attr "length" "0")
7702   (set_attr "in_delay_slot" "no")])
7704 ; emitted at the end of the literal table, used to emit the
7705 ; 32bit branch labels if needed.
7707 (define_insn "consttable_end"
7708   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
7709   ""
7710   "* return output_jump_label_table ();"
7711   [(set_attr "in_delay_slot" "no")])
7713 ; emitted at the end of the window in the literal table.
7715 (define_insn "consttable_window_end"
7716   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
7717   ""
7718   ""
7719   [(set_attr "length" "0")
7720    (set_attr "in_delay_slot" "no")])
7722 ;; -------------------------------------------------------------------------
7723 ;; Misc
7724 ;; -------------------------------------------------------------------------
7726 ;; String/block move insn.
7728 (define_expand "movstrsi"
7729   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
7730                    (mem:BLK (match_operand:BLK 1 "" "")))
7731               (use (match_operand:SI 2 "nonmemory_operand" ""))
7732               (use (match_operand:SI 3 "immediate_operand" ""))
7733               (clobber (reg:SI PR_REG))
7734               (clobber (reg:SI R4_REG))
7735               (clobber (reg:SI R5_REG))
7736               (clobber (reg:SI R0_REG))])]
7737   "TARGET_SH1 && ! TARGET_SH5"
7738   "
7740   if(expand_block_move (operands))
7741      DONE;
7742   else FAIL;
7745 (define_insn "block_move_real"
7746   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7747                    (mem:BLK (reg:SI R5_REG)))
7748               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7749               (clobber (reg:SI PR_REG))
7750               (clobber (reg:SI R0_REG))])]
7751   "TARGET_SH1 && ! TARGET_HARD_SH4"
7752   "jsr  @%0%#"
7753   [(set_attr "type" "sfunc")
7754    (set_attr "needs_delay_slot" "yes")])
7756 (define_insn "block_lump_real"
7757   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7758                    (mem:BLK (reg:SI R5_REG)))
7759               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7760               (use (reg:SI R6_REG))
7761               (clobber (reg:SI PR_REG))
7762               (clobber (reg:SI T_REG))
7763               (clobber (reg:SI R4_REG))
7764               (clobber (reg:SI R5_REG))
7765               (clobber (reg:SI R6_REG))
7766               (clobber (reg:SI R0_REG))])]
7767   "TARGET_SH1 && ! TARGET_HARD_SH4"
7768   "jsr  @%0%#"
7769   [(set_attr "type" "sfunc")
7770    (set_attr "needs_delay_slot" "yes")])
7772 (define_insn "block_move_real_i4"
7773   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7774                    (mem:BLK (reg:SI R5_REG)))
7775               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7776               (clobber (reg:SI PR_REG))
7777               (clobber (reg:SI R0_REG))
7778               (clobber (reg:SI R1_REG))
7779               (clobber (reg:SI R2_REG))])]
7780   "TARGET_HARD_SH4"
7781   "jsr  @%0%#"
7782   [(set_attr "type" "sfunc")
7783    (set_attr "needs_delay_slot" "yes")])
7785 (define_insn "block_lump_real_i4"
7786   [(parallel [(set (mem:BLK (reg:SI R4_REG))
7787                    (mem:BLK (reg:SI R5_REG)))
7788               (use (match_operand:SI 0 "arith_reg_operand" "r"))
7789               (use (reg:SI R6_REG))
7790               (clobber (reg:SI PR_REG))
7791               (clobber (reg:SI T_REG))
7792               (clobber (reg:SI R4_REG))
7793               (clobber (reg:SI R5_REG))
7794               (clobber (reg:SI R6_REG))
7795               (clobber (reg:SI R0_REG))
7796               (clobber (reg:SI R1_REG))
7797               (clobber (reg:SI R2_REG))
7798               (clobber (reg:SI R3_REG))])]
7799   "TARGET_HARD_SH4"
7800   "jsr  @%0%#"
7801   [(set_attr "type" "sfunc")
7802    (set_attr "needs_delay_slot" "yes")])
7804 ;; -------------------------------------------------------------------------
7805 ;; Floating point instructions.
7806 ;; -------------------------------------------------------------------------
7808 ;; ??? All patterns should have a type attribute.
7810 (define_expand "fpu_switch0"
7811   [(set (match_operand:SI 0 "" "") (match_dup 2))
7812    (set (match_dup 1) (mem:PSI (match_dup 0)))]
7813   "TARGET_SH4"
7814   "
7816   operands[1] = get_fpscr_rtx ();
7817   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7818   if (flag_pic)
7819     operands[2] = legitimize_pic_address (operands[2], SImode,
7820                                           no_new_pseudos ? operands[0] : 0);
7823 (define_expand "fpu_switch1"
7824   [(set (match_operand:SI 0 "" "") (match_dup 2))
7825    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
7826    (set (match_dup 1) (mem:PSI (match_dup 3)))]
7827   "TARGET_SH4"
7828   "
7830   operands[1] = get_fpscr_rtx ();
7831   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
7832   if (flag_pic)
7833     operands[2] = legitimize_pic_address (operands[2], SImode,
7834                                           no_new_pseudos ? operands[0] : 0);
7835   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
7838 (define_expand "movpsi"
7839   [(set (match_operand:PSI 0 "register_operand" "")
7840         (match_operand:PSI 1 "general_movsrc_operand" ""))]
7841   "TARGET_SH4"
7842   "")
7844 ;; The c / m alternative is a fake to guide reload to load directly into
7845 ;; fpscr, since reload doesn't know how to use post-increment.
7846 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
7847 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
7848 ;; predicate after reload.
7849 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
7850 ;; like a mac -> gpr move.
7851 (define_insn "fpu_switch"
7852   [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
7853         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
7854   "TARGET_SH4
7855    && (! reload_completed
7856        || true_regnum (operands[0]) != FPSCR_REG
7857        || GET_CODE (operands[1]) != MEM
7858        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
7859   "@
7860         ! precision stays the same
7861         lds.l   %1,fpscr
7862         mov.l   %1,%0
7863         #
7864         lds     %1,fpscr
7865         mov     %1,%0
7866         mov.l   %1,%0
7867         sts     fpscr,%0"
7868   [(set_attr "length" "0,2,2,4,2,2,2,2")
7869    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp")])
7871 (define_split
7872   [(set (reg:PSI FPSCR_REG)
7873         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7874   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
7875   [(set (match_dup 0) (match_dup 0))]
7876   "
7878   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7879                                         gen_rtx (MEM, PSImode,
7880                                                  gen_rtx (POST_INC, Pmode,
7881                                                           operands[0]))));
7882   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7885 (define_split
7886   [(set (reg:PSI FPSCR_REG)
7887         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
7888   "TARGET_SH4"
7889   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
7890   "
7892   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
7893                                         gen_rtx (MEM, PSImode,
7894                                                  gen_rtx (POST_INC, Pmode,
7895                                                           operands[0]))));
7896   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
7899 ;; ??? This uses the fp unit, but has no type indicating that.
7900 ;; If we did that, this would either give a bogus latency or introduce
7901 ;; a bogus FIFO constraint.
7902 ;; Since this insn is currently only used for prologues/epilogues,
7903 ;; it is probably best to claim no function unit, which matches the
7904 ;; current setting.
7905 (define_insn "toggle_sz"
7906   [(set (reg:PSI FPSCR_REG)
7907         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
7908   "TARGET_SH4"
7909   "fschg")
7911 (define_expand "addsf3"
7912   [(set (match_operand:SF 0 "arith_reg_operand" "")
7913         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
7914                  (match_operand:SF 2 "arith_reg_operand" "")))]
7915   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
7916   "
7918   if (TARGET_SH3E)
7919     {
7920       expand_sf_binop (&gen_addsf3_i, operands);
7921       DONE;
7922     }
7925 (define_insn "*addsf3_media"
7926   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
7927         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
7928                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
7929   "TARGET_SHMEDIA_FPU"
7930   "fadd.s       %1, %2, %0"
7931   [(set_attr "type" "fparith_media")])
7933 (define_insn_and_split "unary_sf_op"
7934   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7935         (vec_select:V2SF
7936          (vec_concat:V2SF
7937           (vec_select:SF
7938            (match_dup 0)
7939            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
7940           (match_operator:SF 2 "unary_float_operator"
7941             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7942                             (parallel [(match_operand 4
7943                                         "const_int_operand" "n")]))]))
7944          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
7945   "TARGET_SHMEDIA_FPU"
7946   "#"
7947   "TARGET_SHMEDIA_FPU && reload_completed"
7948   [(set (match_dup 5) (match_dup 6))]
7949   "
7951   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
7952   rtx op1 = gen_rtx_REG (SFmode,
7953                          (true_regnum (operands[1])
7954                           + (INTVAL (operands[4]) ^ endian)));
7956   operands[7] = gen_rtx_REG (SFmode,
7957                              (true_regnum (operands[0])
7958                               + (INTVAL (operands[3]) ^ endian)));
7959   operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
7961   [(set_attr "type" "fparith_media")])
7963 (define_insn_and_split "binary_sf_op"
7964   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
7965         (vec_select:V2SF
7966          (vec_concat:V2SF
7967           (vec_select:SF
7968            (match_dup 0)
7969            (parallel [(not:BI (match_operand 4 "const_int_operand" "n"))]))
7970           (match_operator:SF 3 "binary_float_operator"
7971             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
7972                             (parallel [(match_operand 5
7973                                         "const_int_operand" "n")]))
7974              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
7975                             (parallel [(match_operand 6
7976                                         "const_int_operand" "n")]))]))
7977          (parallel [(not:BI (match_dup 4)) (match_dup 4)])))]
7978   "TARGET_SHMEDIA_FPU"
7979   "#"
7980   "TARGET_SHMEDIA_FPU && reload_completed"
7981   [(set (match_dup 7) (match_dup 8))]
7982   "
7984   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
7985   rtx op1 = gen_rtx_REG (SFmode,
7986                          (true_regnum (operands[1])
7987                           + (INTVAL (operands[5]) ^ endian)));
7988   rtx op2 = gen_rtx_REG (SFmode,
7989                          (true_regnum (operands[2])
7990                           + (INTVAL (operands[6]) ^ endian)));
7992   operands[7] = gen_rtx_REG (SFmode,
7993                              (true_regnum (operands[0])
7994                               + (INTVAL (operands[4]) ^ endian)));
7995   operands[8] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
7997   [(set_attr "type" "fparith_media")])
7999 (define_insn "addsf3_i"
8000   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8001         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8002                  (match_operand:SF 2 "arith_reg_operand" "f")))
8003    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8004   "TARGET_SH3E"
8005   "fadd %2,%0"
8006   [(set_attr "type" "fp")
8007    (set_attr "fp_mode" "single")])
8009 (define_expand "subsf3"
8010   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8011         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8012                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8013   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8014   "
8016   if (TARGET_SH3E)
8017     {
8018       expand_sf_binop (&gen_subsf3_i, operands);
8019       DONE;
8020     }
8023 (define_insn "*subsf3_media"
8024   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8025         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8026                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8027   "TARGET_SHMEDIA_FPU"
8028   "fsub.s       %1, %2, %0"
8029   [(set_attr "type" "fparith_media")])
8031 (define_insn "subsf3_i"
8032   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8033         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8034                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8035    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8036   "TARGET_SH3E"
8037   "fsub %2,%0"
8038   [(set_attr "type" "fp")
8039    (set_attr "fp_mode" "single")])
8041 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8042 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8043 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8044 ;; SH3E, we use a separate insn for SH3E mulsf3.
8046 (define_expand "mulsf3"
8047   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8048         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8049                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8050   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8051   "
8053   if (TARGET_SH4)
8054     expand_sf_binop (&gen_mulsf3_i4, operands);
8055   else if (TARGET_SH3E)
8056     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8057   if (! TARGET_SHMEDIA)
8058     DONE;
8061 (define_insn "*mulsf3_media"
8062   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8063         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8064                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8065   "TARGET_SHMEDIA_FPU"
8066   "fmul.s       %1, %2, %0"
8067   [(set_attr "type" "fparith_media")])
8069 (define_insn "mulsf3_i4"
8070   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8071         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8072                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8073    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8074   "TARGET_SH3E"
8075   "fmul %2,%0"
8076   [(set_attr "type" "fp")
8077    (set_attr "fp_mode" "single")])
8079 (define_insn "mulsf3_ie"
8080   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8081         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8082                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8083   "TARGET_SH3E && ! TARGET_SH4"
8084   "fmul %2,%0"
8085   [(set_attr "type" "fp")])
8087 (define_insn "*mac_media"
8088   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8089         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8090                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8091                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8092   "TARGET_SHMEDIA_FPU"
8093   "fmac.s %1, %2, %0"
8094   [(set_attr "type" "fparith_media")])
8096 (define_insn "*macsf3"
8097   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8098         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8099                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8100                  (match_operand:SF 3 "arith_reg_operand" "0")))
8101    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8102   "TARGET_SH3E && ! TARGET_SH4"
8103   "fmac fr0,%2,%0"
8104   [(set_attr "type" "fp")
8105    (set_attr "fp_mode" "single")])
8107 (define_expand "divsf3"
8108   [(set (match_operand:SF 0 "arith_reg_operand" "")
8109         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8110                 (match_operand:SF 2 "arith_reg_operand" "")))]
8111   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8112   "
8114   if (TARGET_SH3E)
8115     {
8116       expand_sf_binop (&gen_divsf3_i, operands);
8117       DONE;
8118     }
8121 (define_insn "*divsf3_media"
8122   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8123         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8124                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8125   "TARGET_SHMEDIA_FPU"
8126   "fdiv.s       %1, %2, %0"
8127   [(set_attr "type" "fdiv_media")])
8129 (define_insn "divsf3_i"
8130   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8131         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8132                  (match_operand:SF 2 "arith_reg_operand" "f")))
8133    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8134   "TARGET_SH3E"
8135   "fdiv %2,%0"
8136   [(set_attr "type" "fdiv")
8137    (set_attr "fp_mode" "single")])
8139 (define_insn "floatdisf2"
8140   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8141         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8142   "TARGET_SHMEDIA_FPU"
8143   "float.qs %1, %0"
8144   [(set_attr "type" "fpconv_media")])
8146 (define_expand "floatsisf2"
8147   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8148         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8149   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8150   "
8152   if (TARGET_SH4)
8153     {
8154       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8155       DONE;
8156     }
8159 (define_insn "*floatsisf2_media"
8160   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8161         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8162   "TARGET_SHMEDIA_FPU"
8163   "float.ls     %1, %0"
8164   [(set_attr "type" "fpconv_media")])
8166 (define_insn "floatsisf2_i4"
8167   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8168         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8169    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8170   "TARGET_SH4"
8171   "float        %1,%0"
8172   [(set_attr "type" "fp")
8173    (set_attr "fp_mode" "single")])
8175 (define_insn "*floatsisf2_ie"
8176   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8177         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8178   "TARGET_SH3E && ! TARGET_SH4"
8179   "float        %1,%0"
8180   [(set_attr "type" "fp")])
8182 (define_insn "fix_truncsfdi2"
8183   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8184         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8185   "TARGET_SHMEDIA_FPU"
8186   "ftrc.sq %1, %0"
8187   [(set_attr "type" "fpconv_media")])
8189 (define_expand "fix_truncsfsi2"
8190   [(set (match_operand:SI 0 "fpul_operand" "=y")
8191         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8192   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8193   "
8195   if (TARGET_SH4)
8196     {
8197       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8198       DONE;
8199     }
8202 (define_insn "*fix_truncsfsi2_media"
8203   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8204         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8205   "TARGET_SHMEDIA_FPU"
8206   "ftrc.sl      %1, %0"
8207   [(set_attr "type" "fpconv_media")])
8209 (define_insn "fix_truncsfsi2_i4"
8210   [(set (match_operand:SI 0 "fpul_operand" "=y")
8211         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8212    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8213   "TARGET_SH4"
8214   "ftrc %1,%0"
8215   [(set_attr "type" "ftrc_s")
8216    (set_attr "fp_mode" "single")])
8218 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8219 ;; fix_truncsfsi2_i4.
8220 ;; (define_insn "fix_truncsfsi2_i4_2"
8221 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8222 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8223 ;;   (use (reg:PSI FPSCR_REG))
8224 ;;   (clobber (reg:SI FPUL_REG))]
8225 ;;  "TARGET_SH4"
8226 ;;  "#"
8227 ;;  [(set_attr "length" "4")
8228 ;;   (set_attr "fp_mode" "single")])
8230 ;;(define_split
8231 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8232 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8233 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8234 ;;   (clobber (reg:SI FPUL_REG))]
8235 ;;  "TARGET_SH4"
8236 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8237 ;;            (use (match_dup 2))])
8238 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8240 (define_insn "*fixsfsi"
8241   [(set (match_operand:SI 0 "fpul_operand" "=y")
8242         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8243   "TARGET_SH3E && ! TARGET_SH4"
8244   "ftrc %1,%0"
8245   [(set_attr "type" "fp")])
8247 (define_insn "cmpgtsf_t"
8248   [(set (reg:SI T_REG)
8249         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8250                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8251   "TARGET_SH3E && ! TARGET_SH4"
8252   "fcmp/gt      %1,%0"
8253   [(set_attr "type" "fp")
8254    (set_attr "fp_mode" "single")])
8256 (define_insn "cmpeqsf_t"
8257   [(set (reg:SI T_REG)
8258         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8259                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8260   "TARGET_SH3E && ! TARGET_SH4"
8261   "fcmp/eq      %1,%0"
8262   [(set_attr "type" "fp")
8263    (set_attr "fp_mode" "single")])
8265 (define_insn "ieee_ccmpeqsf_t"
8266   [(set (reg:SI T_REG)
8267         (ior:SI (reg:SI T_REG)
8268                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8269                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8270   "TARGET_SH3E && TARGET_IEEE && ! TARGET_SH4"
8271   "* return output_ieee_ccmpeq (insn, operands);"
8272   [(set_attr "length" "4")])
8275 (define_insn "cmpgtsf_t_i4"
8276   [(set (reg:SI T_REG)
8277         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8278                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8279    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8280   "TARGET_SH4"
8281   "fcmp/gt      %1,%0"
8282   [(set_attr "type" "fp")
8283    (set_attr "fp_mode" "single")])
8285 (define_insn "cmpeqsf_t_i4"
8286   [(set (reg:SI T_REG)
8287         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8288                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8289    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8290   "TARGET_SH4"
8291   "fcmp/eq      %1,%0"
8292   [(set_attr "type" "fp")
8293    (set_attr "fp_mode" "single")])
8295 (define_insn "*ieee_ccmpeqsf_t_4"
8296   [(set (reg:SI T_REG)
8297         (ior:SI (reg:SI T_REG)
8298                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8299                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8300    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8301   "TARGET_IEEE && TARGET_SH4"
8302   "* return output_ieee_ccmpeq (insn, operands);"
8303   [(set_attr "length" "4")
8304    (set_attr "fp_mode" "single")])
8306 (define_insn "cmpeqsf_media"
8307   [(set (match_operand:DI 0 "register_operand" "=r")
8308         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8309                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8310   "TARGET_SHMEDIA_FPU"
8311   "fcmpeq.s     %1, %2, %0"
8312   [(set_attr "type" "fcmp_media")])
8314 (define_insn "cmpgtsf_media"
8315   [(set (match_operand:DI 0 "register_operand" "=r")
8316         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8317                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8318   "TARGET_SHMEDIA_FPU"
8319   "fcmpgt.s     %1, %2, %0"
8320   [(set_attr "type" "fcmp_media")])
8322 (define_insn "cmpgesf_media"
8323   [(set (match_operand:DI 0 "register_operand" "=r")
8324         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8325                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8326   "TARGET_SHMEDIA_FPU"
8327   "fcmpge.s     %1, %2, %0"
8328   [(set_attr "type" "fcmp_media")])
8330 (define_insn "cmpunsf_media"
8331   [(set (match_operand:DI 0 "register_operand" "=r")
8332         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8333                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8334   "TARGET_SHMEDIA_FPU"
8335   "fcmpun.s     %1, %2, %0"
8336   [(set_attr "type" "fcmp_media")])
8338 (define_expand "cmpsf"
8339   [(set (reg:SI T_REG)
8340         (compare (match_operand:SF 0 "arith_operand" "")
8341                  (match_operand:SF 1 "arith_operand" "")))]
8342   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8343   "
8345   sh_compare_op0 = operands[0];
8346   sh_compare_op1 = operands[1];
8347   DONE;
8350 (define_expand "negsf2"
8351   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8352         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8353   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8354   "
8356   if (TARGET_SH3E)
8357     {
8358       expand_sf_unop (&gen_negsf2_i, operands);
8359       DONE;
8360     }
8363 (define_insn "*negsf2_media"
8364   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8365         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8366   "TARGET_SHMEDIA_FPU"
8367   "fneg.s       %1, %0"
8368   [(set_attr "type" "fmove_media")])
8370 (define_insn "negsf2_i"
8371   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8372         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8373    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8374   "TARGET_SH3E"
8375   "fneg %0"
8376   [(set_attr "type" "fmove")
8377    (set_attr "fp_mode" "single")])
8379 (define_expand "sqrtsf2"
8380   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8381         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8382   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8383   "
8385   if (TARGET_SH3E)
8386     {
8387       expand_sf_unop (&gen_sqrtsf2_i, operands);
8388       DONE;
8389     }
8392 (define_insn "*sqrtsf2_media"
8393   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8394         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8395   "TARGET_SHMEDIA_FPU"
8396   "fsqrt.s      %1, %0"
8397   [(set_attr "type" "fdiv_media")])
8399 (define_insn "sqrtsf2_i"
8400   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8401         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8402    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8403   "TARGET_SH3E"
8404   "fsqrt        %0"
8405   [(set_attr "type" "fdiv")
8406    (set_attr "fp_mode" "single")])
8408 (define_expand "abssf2"
8409   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8410         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8411   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8412   "
8414   if (TARGET_SH3E)
8415     {
8416       expand_sf_unop (&gen_abssf2_i, operands);
8417       DONE;
8418     }
8421 (define_insn "*abssf2_media"
8422   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8423         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8424   "TARGET_SHMEDIA_FPU"
8425   "fabs.s       %1, %0"
8426   [(set_attr "type" "fmove_media")])
8428 (define_insn "abssf2_i"
8429   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8430         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8431    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8432   "TARGET_SH3E"
8433   "fabs %0"
8434   [(set_attr "type" "fmove")
8435    (set_attr "fp_mode" "single")])
8437 (define_expand "adddf3"
8438   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8439         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8440                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8441   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8442   "
8444   if (TARGET_SH4)
8445     {
8446       expand_df_binop (&gen_adddf3_i, operands);
8447       DONE;
8448     }
8451 (define_insn "*adddf3_media"
8452   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8453         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8454                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8455   "TARGET_SHMEDIA_FPU"
8456   "fadd.d       %1, %2, %0"
8457   [(set_attr "type" "dfparith_media")])
8459 (define_insn "adddf3_i"
8460   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8461         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8462                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8463    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8464   "TARGET_SH4"
8465   "fadd %2,%0"
8466   [(set_attr "type" "dfp_arith")
8467    (set_attr "fp_mode" "double")])
8469 (define_expand "subdf3"
8470   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8471         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8472                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8473   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8474   "
8476   if (TARGET_SH4)
8477     {
8478       expand_df_binop (&gen_subdf3_i, operands);
8479       DONE;
8480     }
8483 (define_insn "*subdf3_media"
8484   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8485         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8486                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8487   "TARGET_SHMEDIA_FPU"
8488   "fsub.d       %1, %2, %0"
8489   [(set_attr "type" "dfparith_media")])
8491 (define_insn "subdf3_i"
8492   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8493         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8494                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8495    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8496   "TARGET_SH4"
8497   "fsub %2,%0"
8498   [(set_attr "type" "dfp_arith")
8499    (set_attr "fp_mode" "double")])
8501 (define_expand "muldf3"
8502   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8503         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8504                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8505   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8506   "
8508   if (TARGET_SH4)
8509     {
8510       expand_df_binop (&gen_muldf3_i, operands);
8511       DONE;
8512     }
8515 (define_insn "*muldf3_media"
8516   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8517         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8518                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8519   "TARGET_SHMEDIA_FPU"
8520   "fmul.d       %1, %2, %0"
8521   [(set_attr "type" "dfmul_media")])
8523 (define_insn "muldf3_i"
8524   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8525         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8526                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8527    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8528   "TARGET_SH4"
8529   "fmul %2,%0"
8530   [(set_attr "type" "dfp_arith")
8531    (set_attr "fp_mode" "double")])
8533 (define_expand "divdf3"
8534   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8535         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8536                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8537   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8538   "
8540   if (TARGET_SH4)
8541     {
8542       expand_df_binop (&gen_divdf3_i, operands);
8543       DONE;
8544     }
8547 (define_insn "*divdf3_media"
8548   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8549         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8550                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8551   "TARGET_SHMEDIA_FPU"
8552   "fdiv.d       %1, %2, %0"
8553   [(set_attr "type" "dfdiv_media")])
8555 (define_insn "divdf3_i"
8556   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8557         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8558                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8559    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8560   "TARGET_SH4"
8561   "fdiv %2,%0"
8562   [(set_attr "type" "dfdiv")
8563    (set_attr "fp_mode" "double")])
8565 (define_insn "floatdidf2"
8566   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8567         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8568   "TARGET_SHMEDIA_FPU"
8569   "float.qd     %1, %0"
8570   [(set_attr "type" "dfpconv_media")])
8572 (define_expand "floatsidf2"
8573   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8574         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8575   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8576   "
8578   if (TARGET_SH4)
8579     {
8580       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8581                                       get_fpscr_rtx ()));
8582       DONE;
8583     }
8586 (define_insn "*floatsidf2_media"
8587   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8588         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8589   "TARGET_SHMEDIA_FPU"
8590   "float.ld     %1, %0"
8591   [(set_attr "type" "dfpconv_media")])
8593 (define_insn "floatsidf2_i"
8594   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8595         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8596    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8597   "TARGET_SH4"
8598   "float        %1,%0"
8599   [(set_attr "type" "dfp_conv")
8600    (set_attr "fp_mode" "double")])
8602 (define_insn "fix_truncdfdi2"
8603   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8604         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8605   "TARGET_SHMEDIA_FPU"
8606   "ftrc.dq      %1, %0"
8607   [(set_attr "type" "dfpconv_media")])
8609 (define_expand "fix_truncdfsi2"
8610   [(set (match_operand:SI 0 "fpul_operand" "")
8611         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8612   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8613   "
8615   if (TARGET_SH4)
8616     {
8617       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8618                                           get_fpscr_rtx ()));
8619       DONE;
8620     }
8623 (define_insn "*fix_truncdfsi2_media"
8624   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8625         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8626   "TARGET_SHMEDIA_FPU"
8627   "ftrc.dl      %1, %0"
8628   [(set_attr "type" "dfpconv_media")])
8630 (define_insn "fix_truncdfsi2_i"
8631   [(set (match_operand:SI 0 "fpul_operand" "=y")
8632         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8633    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8634   "TARGET_SH4"
8635   "ftrc %1,%0"
8636   [(set_attr "type" "dfp_conv")
8637    (set_attr "dfp_comp" "no")
8638    (set_attr "fp_mode" "double")])
8640 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8641 ;; fix_truncdfsi2_i.
8642 ;; (define_insn "fix_truncdfsi2_i4"
8643 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8644 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8645 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8646 ;;    (clobber (reg:SI FPUL_REG))]
8647 ;;   "TARGET_SH4"
8648 ;;   "#"
8649 ;;   [(set_attr "length" "4")
8650 ;;    (set_attr "fp_mode" "double")])
8652 ;; (define_split
8653 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8654 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8655 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8656 ;;    (clobber (reg:SI FPUL_REG))]
8657 ;;   "TARGET_SH4"
8658 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8659 ;;            (use (match_dup 2))])
8660 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
8662 (define_insn "cmpgtdf_t"
8663   [(set (reg:SI T_REG)
8664         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8665                (match_operand:DF 1 "arith_reg_operand" "f")))
8666    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8667   "TARGET_SH4"
8668   "fcmp/gt      %1,%0"
8669   [(set_attr "type" "dfp_cmp")
8670    (set_attr "fp_mode" "double")])
8672 (define_insn "cmpeqdf_t"
8673   [(set (reg:SI T_REG)
8674         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8675                (match_operand:DF 1 "arith_reg_operand" "f")))
8676    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8677   "TARGET_SH4"
8678   "fcmp/eq      %1,%0"
8679   [(set_attr "type" "dfp_cmp")
8680    (set_attr "fp_mode" "double")])
8682 (define_insn "*ieee_ccmpeqdf_t"
8683   [(set (reg:SI T_REG)
8684         (ior:SI (reg:SI T_REG)
8685                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8686                        (match_operand:DF 1 "arith_reg_operand" "f"))))
8687    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8688   "TARGET_IEEE && TARGET_SH4"
8689   "* return output_ieee_ccmpeq (insn, operands);"
8690   [(set_attr "length" "4")
8691    (set_attr "fp_mode" "double")])
8693 (define_insn "cmpeqdf_media"
8694   [(set (match_operand:DI 0 "register_operand" "=r")
8695         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8696                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8697   "TARGET_SHMEDIA_FPU"
8698   "fcmpeq.d     %1,%2,%0"
8699   [(set_attr "type" "fcmp_media")])
8701 (define_insn "cmpgtdf_media"
8702   [(set (match_operand:DI 0 "register_operand" "=r")
8703         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8704                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8705   "TARGET_SHMEDIA_FPU"
8706   "fcmpgt.d     %1,%2,%0"
8707   [(set_attr "type" "fcmp_media")])
8709 (define_insn "cmpgedf_media"
8710   [(set (match_operand:DI 0 "register_operand" "=r")
8711         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8712                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8713   "TARGET_SHMEDIA_FPU"
8714   "fcmpge.d     %1,%2,%0"
8715   [(set_attr "type" "fcmp_media")])
8717 (define_insn "cmpundf_media"
8718   [(set (match_operand:DI 0 "register_operand" "=r")
8719         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
8720                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8721   "TARGET_SHMEDIA_FPU"
8722   "fcmpun.d     %1,%2,%0"
8723   [(set_attr "type" "fcmp_media")])
8725 (define_expand "cmpdf"
8726   [(set (reg:SI T_REG)
8727         (compare (match_operand:DF 0 "arith_operand" "")
8728                  (match_operand:DF 1 "arith_operand" "")))]
8729   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8730   "
8732   sh_compare_op0 = operands[0];
8733   sh_compare_op1 = operands[1];
8734   DONE;
8737 (define_expand "negdf2"
8738   [(set (match_operand:DF 0 "arith_reg_operand" "")
8739         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8740   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8741   "
8743   if (TARGET_SH4)
8744     {
8745       expand_df_unop (&gen_negdf2_i, operands);
8746       DONE;
8747     }
8750 (define_insn "*negdf2_media"
8751   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8752         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8753   "TARGET_SHMEDIA_FPU"
8754   "fneg.d       %1, %0"
8755   [(set_attr "type" "fmove_media")])
8757 (define_insn "negdf2_i"
8758   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8759         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8760    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8761   "TARGET_SH4"
8762   "fneg %0"
8763   [(set_attr "type" "fmove")
8764    (set_attr "fp_mode" "double")])
8766 (define_expand "sqrtdf2"
8767   [(set (match_operand:DF 0 "arith_reg_operand" "")
8768         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8769   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8770   "
8772   if (TARGET_SH4)
8773     {
8774       expand_df_unop (&gen_sqrtdf2_i, operands);
8775       DONE;
8776     }
8779 (define_insn "*sqrtdf2_media"
8780   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8781         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8782   "TARGET_SHMEDIA_FPU"
8783   "fsqrt.d      %1, %0"
8784   [(set_attr "type" "dfdiv_media")])
8786 (define_insn "sqrtdf2_i"
8787   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8788         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8789    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8790   "TARGET_SH4"
8791   "fsqrt        %0"
8792   [(set_attr "type" "dfdiv")
8793    (set_attr "fp_mode" "double")])
8795 (define_expand "absdf2"
8796   [(set (match_operand:DF 0 "arith_reg_operand" "")
8797         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
8798   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8799   "
8801   if (TARGET_SH4)
8802     {
8803       expand_df_unop (&gen_absdf2_i, operands);
8804       DONE;
8805     }
8808 (define_insn "*absdf2_media"
8809   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8810         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8811   "TARGET_SHMEDIA_FPU"
8812   "fabs.d       %1, %0"
8813   [(set_attr "type" "fmove_media")])
8815 (define_insn "absdf2_i"
8816   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
8817         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
8818    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8819   "TARGET_SH4"
8820   "fabs %0"
8821   [(set_attr "type" "fmove")
8822    (set_attr "fp_mode" "double")])
8824 (define_expand "extendsfdf2"
8825   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8826         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
8827   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8828   "
8830   if (TARGET_SH4)
8831     {
8832       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
8833                                         get_fpscr_rtx ()));
8834       DONE;
8835     }
8838 (define_insn "*extendsfdf2_media"
8839   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8840         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8841   "TARGET_SHMEDIA_FPU"
8842   "fcnv.sd      %1, %0"
8843   [(set_attr "type" "dfpconv_media")])
8845 (define_insn "extendsfdf2_i4"
8846   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8847         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
8848    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8849   "TARGET_SH4"
8850   "fcnvsd  %1,%0"
8851   [(set_attr "type" "fp")
8852    (set_attr "fp_mode" "double")])
8854 (define_expand "truncdfsf2"
8855   [(set (match_operand:SF 0 "fpul_operand" "")
8856         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8857   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8858   "
8860   if (TARGET_SH4)
8861     {
8862       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
8863                                        get_fpscr_rtx ()));
8864       DONE;
8865     }
8868 (define_insn "*truncdfsf2_media"
8869   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8870         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8871   "TARGET_SHMEDIA_FPU"
8872   "fcnv.ds      %1, %0"
8873   [(set_attr "type" "dfpconv_media")])
8875 (define_insn "truncdfsf2_i4"
8876   [(set (match_operand:SF 0 "fpul_operand" "=y")
8877         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8878    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8879   "TARGET_SH4"
8880   "fcnvds  %1,%0"
8881   [(set_attr "type" "fp")
8882    (set_attr "fp_mode" "double")])
8884 ;; Bit field extract patterns.  These give better code for packed bitfields,
8885 ;; because they allow auto-increment addresses to be generated.
8887 (define_expand "insv"
8888   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
8889                          (match_operand:SI 1 "immediate_operand" "")
8890                          (match_operand:SI 2 "immediate_operand" ""))
8891         (match_operand:SI 3 "general_operand" ""))]
8892   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
8893   "
8895   rtx addr_target, orig_address, shift_reg, qi_val;
8896   HOST_WIDE_INT bitsize, size, v;
8897   rtx x = operands[3];
8899   /* ??? expmed doesn't care for non-register predicates.  */
8900   if (! memory_operand (operands[0], VOIDmode)
8901       || ! immediate_operand (operands[1], VOIDmode)
8902       || ! immediate_operand (operands[2], VOIDmode)
8903       || ! general_operand (x, VOIDmode))
8904     FAIL;
8905   /* If this isn't a 16 / 24 / 32 bit field, or if
8906      it doesn't start on a byte boundary, then fail.  */
8907   bitsize = INTVAL (operands[1]);
8908   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
8909       || (INTVAL (operands[2]) % 8) != 0)
8910     FAIL;
8912   size = bitsize / 8;
8913   orig_address = XEXP (operands[0], 0);
8914   shift_reg = gen_reg_rtx (SImode);
8915   if (GET_CODE (x) == CONST_INT)
8916     {
8917       v = INTVAL (x);
8918       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
8919     }
8920   else
8921     {
8922       emit_insn (gen_movsi (shift_reg, operands[3]));
8923       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8924     }
8925   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
8927   operands[0] = replace_equiv_address (operands[0], addr_target);
8928   emit_insn (gen_movqi (operands[0], qi_val));
8930   while (size -= 1)
8931     {
8932       if (GET_CODE (x) == CONST_INT)
8933         qi_val
8934           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
8935       else
8936         {
8937           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
8938           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
8939         }
8940       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
8941       emit_insn (gen_movqi (operands[0], qi_val));
8942     }
8944   DONE;
8947 ;; -------------------------------------------------------------------------
8948 ;; Peepholes
8949 ;; -------------------------------------------------------------------------
8951 ;; This matches cases where a stack pointer increment at the start of the
8952 ;; epilogue combines with a stack slot read loading the return value.
8954 (define_peephole
8955   [(set (match_operand:SI 0 "arith_reg_operand" "")
8956         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
8957    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
8958   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
8959   "mov.l        @%1+,%0")
8961 ;; See the comment on the dt combiner pattern above.
8963 (define_peephole
8964   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8965         (plus:SI (match_dup 0)
8966                  (const_int -1)))
8967    (set (reg:SI T_REG)
8968         (eq:SI (match_dup 0)
8969                (const_int 0)))]
8970   "TARGET_SH2"
8971   "dt   %0")
8973 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
8974 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
8975 ;; reload when the constant is too large for a reg+offset address.
8977 ;; ??? We would get much better code if this was done in reload.  This would
8978 ;; require modifying find_reloads_address to recognize that if the constant
8979 ;; is out-of-range for an immediate add, then we get better code by reloading
8980 ;; the constant into a register than by reloading the sum into a register,
8981 ;; since the former is one instruction shorter if the address does not need
8982 ;; to be offsettable.  Unfortunately this does not work, because there is
8983 ;; only one register, r0, that can be used as an index register.  This register
8984 ;; is also the function return value register.  So, if we try to force reload
8985 ;; to use double-reg addresses, then we end up with some instructions that
8986 ;; need to use r0 twice.  The only way to fix this is to change the calling
8987 ;; convention so that r0 is not used to return values.
8989 (define_peephole
8990   [(set (match_operand:SI 0 "register_operand" "=r")
8991         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
8992    (set (mem:SI (match_dup 0))
8993         (match_operand:SI 2 "general_movsrc_operand" ""))]
8994   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
8995   "mov.l        %2,@(%0,%1)")
8997 (define_peephole
8998   [(set (match_operand:SI 0 "register_operand" "=r")
8999         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9000    (set (match_operand:SI 2 "general_movdst_operand" "")
9001         (mem:SI (match_dup 0)))]
9002   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9003   "mov.l        @(%0,%1),%2")
9005 (define_peephole
9006   [(set (match_operand:SI 0 "register_operand" "=r")
9007         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9008    (set (mem:HI (match_dup 0))
9009         (match_operand:HI 2 "general_movsrc_operand" ""))]
9010   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9011   "mov.w        %2,@(%0,%1)")
9013 (define_peephole
9014   [(set (match_operand:SI 0 "register_operand" "=r")
9015         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9016    (set (match_operand:HI 2 "general_movdst_operand" "")
9017         (mem:HI (match_dup 0)))]
9018   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9019   "mov.w        @(%0,%1),%2")
9021 (define_peephole
9022   [(set (match_operand:SI 0 "register_operand" "=r")
9023         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9024    (set (mem:QI (match_dup 0))
9025         (match_operand:QI 2 "general_movsrc_operand" ""))]
9026   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9027   "mov.b        %2,@(%0,%1)")
9029 (define_peephole
9030   [(set (match_operand:SI 0 "register_operand" "=r")
9031         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9032    (set (match_operand:QI 2 "general_movdst_operand" "")
9033         (mem:QI (match_dup 0)))]
9034   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9035   "mov.b        @(%0,%1),%2")
9037 (define_peephole
9038   [(set (match_operand:SI 0 "register_operand" "=r")
9039         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9040    (set (mem:SF (match_dup 0))
9041         (match_operand:SF 2 "general_movsrc_operand" ""))]
9042   "TARGET_SH1 && REGNO (operands[0]) == 0
9043    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9044        || (GET_CODE (operands[2]) == SUBREG
9045            && REGNO (SUBREG_REG (operands[2])) < 16))
9046    && reg_unused_after (operands[0], insn)"
9047   "mov.l        %2,@(%0,%1)")
9049 (define_peephole
9050   [(set (match_operand:SI 0 "register_operand" "=r")
9051         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9052    (set (match_operand:SF 2 "general_movdst_operand" "")
9054         (mem:SF (match_dup 0)))]
9055   "TARGET_SH1 && REGNO (operands[0]) == 0
9056    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9057        || (GET_CODE (operands[2]) == SUBREG
9058            && REGNO (SUBREG_REG (operands[2])) < 16))
9059    && reg_unused_after (operands[0], insn)"
9060   "mov.l        @(%0,%1),%2")
9062 (define_peephole
9063   [(set (match_operand:SI 0 "register_operand" "=r")
9064         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9065    (set (mem:SF (match_dup 0))
9066         (match_operand:SF 2 "general_movsrc_operand" ""))]
9067   "TARGET_SH3E && REGNO (operands[0]) == 0
9068    && ((GET_CODE (operands[2]) == REG
9069         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9070        || (GET_CODE (operands[2]) == SUBREG
9071            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9072    && reg_unused_after (operands[0], insn)"
9073   "fmov{.s|}    %2,@(%0,%1)")
9075 (define_peephole
9076   [(set (match_operand:SI 0 "register_operand" "=r")
9077         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9078    (set (match_operand:SF 2 "general_movdst_operand" "")
9080         (mem:SF (match_dup 0)))]
9081   "TARGET_SH3E && REGNO (operands[0]) == 0
9082    && ((GET_CODE (operands[2]) == REG
9083         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9084        || (GET_CODE (operands[2]) == SUBREG
9085            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9086    && reg_unused_after (operands[0], insn)"
9087   "fmov{.s|}    @(%0,%1),%2")
9089 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9090 (define_insn "sp_switch_1"
9091   [(const_int 1)]
9092   "TARGET_SH1"
9093   "*
9095   rtx xoperands[1];
9097   xoperands[0] = sp_switch;
9098   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9099   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9100   return \"mov r0,r15\";
9102   [(set_attr "length" "10")])
9104 ;; Switch back to the original stack for interrupt functions with the
9105 ;; sp_switch attribute.  */
9106 (define_insn "sp_switch_2"
9107   [(const_int 2)]
9108   "TARGET_SH1"
9109   "mov.l @r15+,r15\;mov.l @r15+,r0"
9110   [(set_attr "length" "4")])
9112 ;; Integer vector moves
9114 (define_expand "movv8qi"
9115   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9116         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9117   "TARGET_SHMEDIA"
9118   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9120 (define_insn "movv8qi_i"
9121   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9122         (match_operand:V8QI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9123   "TARGET_SHMEDIA
9124    && (register_operand (operands[0], V8QImode)
9125        || register_operand (operands[1], V8QImode))"
9126   "@
9127         add     %1, r63, %0
9128         movi    %1, %0
9129         #
9130         ld%M1.q %m1, %0
9131         st%M0.q %m0, %1"
9132   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9133    (set_attr "length" "4,4,16,4,4")])
9135 (define_split
9136   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9137         (subreg:V8QI (const_int 0) 0))]
9138   "TARGET_SHMEDIA"
9139   [(set (match_dup 0)
9140         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9141                             (const_int 0) (const_int 0) (const_int 0)
9142                             (const_int 0) (const_int 0)]))])
9144 (define_split
9145   [(set (match_operand 0 "arith_reg_dest" "")
9146         (match_operand 1 "sh_rep_vec" ""))]
9147   "TARGET_SHMEDIA && reload_completed
9148    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9149    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9150    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9151    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9152        || XVECEXP (operands[1], 0, 1) != const0_rtx)"
9153   [(set (match_dup 0) (match_dup 1))
9154    (match_dup 2)]
9155   "
9157   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9158   rtx elt1 = XVECEXP (operands[1], 0, 1);
9160   if (unit_size > 2)
9161     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9162   else
9163     operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9164   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9165   operands[1] = XVECEXP (operands[1], 0, 0);
9166   if (unit_size < 2)
9167     {
9168       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9169         operands[1] = GEN_INT (TARGET_LITTLE_ENDIAN
9170                                ? INTVAL (operands[1]) + (INTVAL (elt1) << 8)
9171                                : (INTVAL (operands[1]) << 8) + INTVAL (elt1));
9172       else
9173         {
9174           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9175           operands[1]
9176             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9177         }
9178     }
9181 (define_split
9182   [(set (match_operand 0 "arith_reg_dest" "")
9183         (match_operand 1 "sh_const_vec" ""))]
9184   "TARGET_SHMEDIA && reload_completed
9185    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9186    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9187    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9188   [(set (match_dup 0) (match_dup 1))]
9189   "
9191   rtx v = operands[1];
9192   enum machine_mode new_mode
9193     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9195   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9196   operands[1]
9197     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9200 (define_expand "movv2hi"
9201   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9202         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9203   "TARGET_SHMEDIA"
9204   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9206 (define_insn "movv2hi_i"
9207   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9208         (match_operand:V2HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9209   "TARGET_SHMEDIA
9210    && (register_operand (operands[0], V2HImode)
9211        || register_operand (operands[1], V2HImode))"
9212   "@
9213         addz.l  %1, r63, %0
9214         movi    %1, %0
9215         #
9216         ld%M1.l %m1, %0
9217         st%M0.l %m0, %1"
9218   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9219    (set_attr "length" "4,4,16,4,4")])
9221 (define_expand "movv4hi"
9222   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9223         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9224   "TARGET_SHMEDIA"
9225   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9227 (define_insn "movv4hi_i"
9228   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9229         (match_operand:V4HI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9230   "TARGET_SHMEDIA
9231    && (register_operand (operands[0], V4HImode)
9232        || register_operand (operands[1], V4HImode))"
9233   "@
9234         add     %1, r63, %0
9235         movi    %1, %0
9236         #
9237         ld%M1.q %m1, %0
9238         st%M0.q %m0, %1"
9239   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9240    (set_attr "length" "4,4,16,4,4")])
9242 (define_expand "movv2si"
9243   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9244         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9245   "TARGET_SHMEDIA"
9246   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9248 (define_insn "movv2si_i"
9249   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9250         (match_operand:V2SI 1 "general_movsrc_operand" "r,JSU,nW,m,rl"))]
9251   "TARGET_SHMEDIA
9252    && (register_operand (operands[0], V2SImode)
9253        || register_operand (operands[1], V2SImode))"
9254   "@
9255         add     %1, r63, %0
9256         #
9257         #
9258         ld%M1.q %m1, %0
9259         st%M0.q %m0, %1"
9260   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9261    (set_attr "length" "4,4,16,4,4")])
9263 ;; Multimedia Intrinsics
9265 (define_insn "absv2si2"
9266   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9267         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9268   "TARGET_SHMEDIA"
9269   "mabs.l       %1, %0"
9270   [(set_attr "type" "mcmp_media")])
9272 (define_insn "absv4hi2"
9273   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9274         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9275   "TARGET_SHMEDIA"
9276   "mabs.w       %1, %0"
9277   [(set_attr "type" "mcmp_media")])
9279 (define_insn "addv2si3"
9280   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9281         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9282                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9283   "TARGET_SHMEDIA"
9284   "madd.l       %1, %2, %0"
9285   [(set_attr "type" "arith_media")])
9287 (define_insn "addv4hi3"
9288   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9289         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9290                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9291   "TARGET_SHMEDIA"
9292   "madd.w       %1, %2, %0"
9293   [(set_attr "type" "arith_media")])
9295 (define_insn "ssaddv2si3"
9296   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9297         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9298                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9299   "TARGET_SHMEDIA"
9300   "madds.l      %1, %2, %0"
9301   [(set_attr "type" "mcmp_media")])
9303 (define_insn "usaddv8qi3"
9304   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9305         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9306                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9307   "TARGET_SHMEDIA"
9308   "madds.ub     %1, %2, %0"
9309   [(set_attr "type" "mcmp_media")])
9311 (define_insn "ssaddv4hi3"
9312   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9313         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9314                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9315   "TARGET_SHMEDIA"
9316   "madds.w      %1, %2, %0"
9317   [(set_attr "type" "mcmp_media")])
9319 (define_insn "negcmpeqv8qi"
9320   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9321         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9322                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9323   "TARGET_SHMEDIA"
9324   "mcmpeq.b     %N1, %N2, %0"
9325   [(set_attr "type" "mcmp_media")])
9327 (define_insn "negcmpeqv2si"
9328   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9329         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9330                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9331   "TARGET_SHMEDIA"
9332   "mcmpeq.l     %N1, %N2, %0"
9333   [(set_attr "type" "mcmp_media")])
9335 (define_insn "negcmpeqv4hi"
9336   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9337         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9338                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9339   "TARGET_SHMEDIA"
9340   "mcmpeq.w     %N1, %N2, %0"
9341   [(set_attr "type" "mcmp_media")])
9343 (define_insn "negcmpgtuv8qi"
9344   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9345         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rU")
9346                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))))]
9347   "TARGET_SHMEDIA"
9348   "mcmpgt.ub    %N1, %N2, %0"
9349   [(set_attr "type" "mcmp_media")])
9351 (define_insn "negcmpgtv2si"
9352   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9353         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rU")
9354                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9355   "TARGET_SHMEDIA"
9356   "mcmpgt.l     %N1, %N2, %0"
9357   [(set_attr "type" "mcmp_media")])
9359 (define_insn "negcmpgtv4hi"
9360   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9361         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rU")
9362                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9363   "TARGET_SHMEDIA"
9364   "mcmpgt.w     %N1, %N2, %0"
9365   [(set_attr "type" "mcmp_media")])
9367 (define_insn "mcmv"
9368   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9369         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9370                         (match_operand:DI 2 "arith_reg_operand" "r"))
9371                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9372                         (not:DI (match_dup 2)))))]
9373   "TARGET_SHMEDIA"
9374   "mcmv %N1, %2, %0"
9375   [(set_attr "type" "arith_media")])
9377 (define_insn "mcnvs_lw"
9378   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9379         (vec_concat:V4HI
9380          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU"))
9381          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))))]
9382   "TARGET_SHMEDIA"
9383   "mcnvs.lw     %N1, %N2, %0"
9384   [(set_attr "type" "mcmp_media")])
9386 (define_insn "mcnvs_wb"
9387   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9388         (vec_concat:V8QI
9389          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9390          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9391   "TARGET_SHMEDIA"
9392   "mcnvs.wb     %N1, %N2, %0"
9393   [(set_attr "type" "mcmp_media")])
9395 (define_insn "mcnvs_wub"
9396   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9397         (vec_concat:V8QI
9398          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU"))
9399          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))))]
9400   "TARGET_SHMEDIA"
9401   "mcnvs.wub    %N1, %N2, %0"
9402   [(set_attr "type" "mcmp_media")])
9404 (define_insn "mextr_rl"
9405   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9406         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9407                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9408                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9409                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9410   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9411   "*
9413   static char templ[16];
9415   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9416            (int) INTVAL (operands[3]) >> 3);
9417   return templ;
9419   [(set_attr "type" "arith_media")])
9421 (define_insn "*mextr_lr"
9422   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9423         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9424                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9425                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
9426                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9427   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9428   "*
9430   static char templ[16];
9432   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9433            (int) INTVAL (operands[4]) >> 3);
9434   return templ;
9436   [(set_attr "type" "arith_media")])
9438 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9439 ; vector then varies depending on endianness.
9440 (define_expand "mextr1"
9441   [(match_operand:DI 0 "arith_reg_dest" "")
9442    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9443    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9444   "TARGET_SHMEDIA"
9445   "
9447   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9448                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9449   DONE;
9452 (define_expand "mextr2"
9453   [(match_operand:DI 0 "arith_reg_dest" "")
9454    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9455    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9456   "TARGET_SHMEDIA"
9457   "
9459   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9460                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9461   DONE;
9464 (define_expand "mextr3"
9465   [(match_operand:DI 0 "arith_reg_dest" "")
9466    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9467    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9468   "TARGET_SHMEDIA"
9469   "
9471   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9472                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9473   DONE;
9476 (define_expand "mextr4"
9477   [(match_operand:DI 0 "arith_reg_dest" "")
9478    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9479    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9480   "TARGET_SHMEDIA"
9481   "
9483   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9484                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9485   DONE;
9488 (define_expand "mextr5"
9489   [(match_operand:DI 0 "arith_reg_dest" "")
9490    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9491    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9492   "TARGET_SHMEDIA"
9493   "
9495   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9496                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9497   DONE;
9500 (define_expand "mextr6"
9501   [(match_operand:DI 0 "arith_reg_dest" "")
9502    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9503    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9504   "TARGET_SHMEDIA"
9505   "
9507   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9508                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9509   DONE;
9512 (define_expand "mextr7"
9513   [(match_operand:DI 0 "arith_reg_dest" "")
9514    (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
9515    (match_operand:DI 2 "arith_reg_or_0_operand" "rU")]
9516   "TARGET_SHMEDIA"
9517   "
9519   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9520                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9521   DONE;
9524 (define_expand "mmacfx_wl"
9525   [(match_operand:V2SI 0 "arith_reg_dest" "")
9526    (match_operand:V2HI 1 "extend_reg_operand" "")
9527    (match_operand:V2HI 2 "extend_reg_operand" "")
9528    (match_operand:V2SI 3 "arith_reg_operand" "")]
9529   "TARGET_SHMEDIA"
9530   "
9532   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9533                               operands[1], operands[2]));
9534   DONE;
9537 (define_insn "mmacfx_wl_i"
9538   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9539         (ss_plus:V2SI
9540          (match_operand:V2SI 1 "arith_reg_operand" "0")
9541          (ss_truncate:V2SI
9542           (ashift:V2DI
9543            (sign_extend:V2DI
9544             (mult:V2SI
9545              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9546              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9547            (const_int 1)))))]
9548   "TARGET_SHMEDIA"
9549   "mmacfx.wl    %2, %3, %0"
9550   [(set_attr "type" "mac_media")])
9552 (define_expand "mmacnfx_wl"
9553   [(match_operand:V2SI 0 "arith_reg_dest" "")
9554    (match_operand:V2HI 1 "extend_reg_operand" "")
9555    (match_operand:V2HI 2 "extend_reg_operand" "")
9556    (match_operand:V2SI 3 "arith_reg_operand" "")]
9557   "TARGET_SHMEDIA"
9558   "
9560   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9561                                operands[1], operands[2]));
9562   DONE;
9565 (define_insn "mmacnfx_wl_i"
9566   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9567         (ss_minus:V2SI
9568          (match_operand:V2SI 1 "arith_reg_operand" "0")
9569          (ss_truncate:V2SI
9570           (ashift:V2DI
9571            (sign_extend:V2DI
9572             (mult:V2SI
9573              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9574              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9575            (const_int 1)))))]
9576   "TARGET_SHMEDIA"
9577   "mmacnfx.wl   %2, %3, %0"
9578   [(set_attr "type" "mac_media")])
9580 (define_insn "mulv2si3"
9581   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9582         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9583                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9584   "TARGET_SHMEDIA"
9585   "mmul.l       %1, %2, %0"
9586   [(set_attr "type" "d2mpy_media")])
9588 (define_insn "mulv4hi3"
9589   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9590         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9591                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9592   "TARGET_SHMEDIA"
9593   "mmul.w       %1, %2, %0"
9594   [(set_attr "type" "dmpy_media")])
9596 (define_insn "mmulfx_l"
9597   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9598         (ss_truncate:V2SI
9599          (ashiftrt:V2DI
9600           (mult:V2DI
9601            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9602            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9603           (const_int 31))))]
9604   "TARGET_SHMEDIA"
9605   "mmulfx.l     %1, %2, %0"
9606   [(set_attr "type" "d2mpy_media")])
9608 (define_insn "mmulfx_w"
9609   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9610         (ss_truncate:V4HI
9611          (ashiftrt:V4SI
9612           (mult:V4SI
9613            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9614            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9615           (const_int 15))))]
9616   "TARGET_SHMEDIA"
9617   "mmulfx.w     %1, %2, %0"
9618   [(set_attr "type" "dmpy_media")])
9620 (define_insn "mmulfxrp_w"
9621   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9622         (ss_truncate:V4HI
9623          (ashiftrt:V4SI
9624           (plus:V4SI
9625            (mult:V4SI
9626             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9627             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9628            (const_int 16384))
9629           (const_int 15))))]
9630   "TARGET_SHMEDIA"
9631   "mmulfxrp.w   %1, %2, %0"
9632   [(set_attr "type" "dmpy_media")])
9634 (define_expand "mmulhi_wl"
9635   [(match_operand:V2SI 0 "arith_reg_dest" "")
9636    (match_operand:V4HI 1 "arith_reg_operand" "")
9637    (match_operand:V4HI 2 "arith_reg_operand" "")]
9638   "TARGET_SHMEDIA"
9639   "
9641   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9642              (operands[0], operands[1], operands[2]));
9643   DONE;
9646 (define_expand "mmullo_wl"
9647   [(match_operand:V2SI 0 "arith_reg_dest" "")
9648    (match_operand:V4HI 1 "arith_reg_operand" "")
9649    (match_operand:V4HI 2 "arith_reg_operand" "")]
9650   "TARGET_SHMEDIA"
9651   "
9653   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9654              (operands[0], operands[1], operands[2]));
9655   DONE;
9658 (define_insn "mmul23_wl"
9659   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9660         (vec_select:V2SI
9661          (mult:V4SI
9662           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9663           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9664          (parallel [(const_int 2) (const_int 3)])))]
9665   "TARGET_SHMEDIA"
9666   "* return (TARGET_LITTLE_ENDIAN
9667              ? \"mmulhi.wl      %1, %2, %0\"
9668              : \"mmullo.wl      %1, %2, %0\");"
9669   [(set_attr "type" "dmpy_media")])
9671 (define_insn "mmul01_wl"
9672   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9673         (vec_select:V2SI
9674          (mult:V4SI
9675           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9676           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9677          (parallel [(const_int 0) (const_int 1)])))]
9678   "TARGET_SHMEDIA"
9679   "* return (TARGET_LITTLE_ENDIAN
9680              ? \"mmullo.wl      %1, %2, %0\"
9681              : \"mmulhi.wl      %1, %2, %0\");"
9682   [(set_attr "type" "dmpy_media")])
9684 (define_expand "mmulsum_wq"
9685   [(match_operand:DI 0 "arith_reg_dest" "")
9686    (match_operand:V4HI 1 "arith_reg_operand" "")
9687    (match_operand:V4HI 2 "arith_reg_operand" "")
9688    (match_operand:DI 3 "arith_reg_operand" "")]
9689   "TARGET_SHMEDIA"
9690   "
9692   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
9693                                operands[1], operands[2]));
9694   DONE;
9697 (define_insn "mmulsum_wq_i"
9698   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9699         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
9700          (plus:DI
9701           (plus:DI
9702            (vec_select:DI
9703             (mult:V4DI
9704              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
9705              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
9706             (parallel [(const_int 0)]))
9707            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9708                                      (sign_extend:V4DI (match_dup 3)))
9709                           (parallel [(const_int 1)])))
9710           (plus:DI
9711            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9712                                      (sign_extend:V4DI (match_dup 3)))
9713                           (parallel [(const_int 2)]))
9714            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
9715                                      (sign_extend:V4DI (match_dup 3)))
9716                           (parallel [(const_int 3)]))))))]
9717   "TARGET_SHMEDIA"
9718   "mmulsum.wq   %2, %3, %0"
9719   [(set_attr "type" "mac_media")])
9721 (define_expand "mperm_w"
9722   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
9723    (match_operand:V4HI 1 "arith_reg_operand" "r")
9724    (match_operand:QI 2 "extend_reg_or_0_operand" "rU")]
9725   "TARGET_SHMEDIA"
9726   "
9728   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
9729              (operands[0], operands[1], operands[2]));
9730   DONE;
9733 ; This use of vec_select isn't exactly correct according to rtl.texi
9734 ; (because not constant), but it seems a straightforward extension.
9735 (define_insn "mperm_w_little"
9736   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9737         (vec_select:V4HI
9738          (match_operand:V4HI 1 "arith_reg_operand" "r")
9739          (parallel
9740           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rU")
9741                             (const_int 2) (const_int 0))
9742            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
9743            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
9744            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
9745   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
9746   "mperm.w      %1, %N2, %0"
9747   [(set_attr "type" "arith_media")])
9749 (define_insn "mperm_w_big"
9750   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9751         (vec_select:V4HI
9752          (match_operand:V4HI 1 "arith_reg_operand" "r")
9753          (parallel
9754           [(zero_extract:QI (not:QI (match_operand:QI 2
9755                                      "extend_reg_or_0_operand" "rU"))
9756                             (const_int 2) (const_int 0))
9757            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
9758            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
9759            (zero_extract:QI (not:QI (match_dup 2))
9760                             (const_int 2) (const_int 6))])))]
9761   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
9762   "mperm.w      %1, %N2, %0"
9763   [(set_attr "type" "arith_media")])
9765 (define_insn "mperm_w0"
9766   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9767         (vec_duplicate:V4HI (truncate:HI (match_operand 1
9768                                           "trunc_hi_operand" "r"))))]
9769   "TARGET_SHMEDIA"
9770   "mperm.w      %1, r63, %0"
9771   [(set_attr "type" "arith_media")])
9773 (define_expand "msad_ubq"
9774   [(match_operand:DI 0 "arith_reg_dest" "")
9775    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
9776    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
9777    (match_operand:DI 3 "arith_reg_operand" "")]
9778   "TARGET_SHMEDIA"
9779   "
9781   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
9782                              operands[1], operands[2]));
9783   DONE;
9786 (define_insn "msad_ubq_i"
9787   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9788         (plus:DI
9789          (plus:DI
9790           (plus:DI
9791            (plus:DI
9792             (match_operand:DI 1 "arith_reg_operand" "0")
9793             (abs:DI (vec_select:DI
9794                      (minus:V8DI
9795                       (zero_extend:V8DI
9796                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "r"))
9797                       (zero_extend:V8DI
9798                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "r")))
9799                      (parallel [(const_int 0)]))))
9800            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9801                                               (zero_extend:V8DI (match_dup 3)))
9802                                   (parallel [(const_int 1)]))))
9803           (plus:DI
9804            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9805                                               (zero_extend:V8DI (match_dup 3)))
9806                                   (parallel [(const_int 2)])))
9807            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9808                                               (zero_extend:V8DI (match_dup 3)))
9809                                   (parallel [(const_int 3)])))))
9810          (plus:DI
9811           (plus:DI
9812            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9813                                               (zero_extend:V8DI (match_dup 3)))
9814                                   (parallel [(const_int 4)])))
9815            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9816                                               (zero_extend:V8DI (match_dup 3)))
9817                                   (parallel [(const_int 5)]))))
9818           (plus:DI
9819            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9820                                               (zero_extend:V8DI (match_dup 3)))
9821                                   (parallel [(const_int 6)])))
9822            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
9823                                               (zero_extend:V8DI (match_dup 3)))
9824                                   (parallel [(const_int 7)])))))))]
9825   "TARGET_SHMEDIA"
9826   "msad.ubq     %N2, %N3, %0"
9827   [(set_attr "type" "mac_media")])
9829 (define_insn "mshalds_l"
9830   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9831         (ss_truncate:V2SI
9832          (ashift:V2DI
9833           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9834           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9835                   (const_int 31)))))]
9836   "TARGET_SHMEDIA"
9837   "mshalds.l    %1, %2, %0"
9838   [(set_attr "type" "mcmp_media")])
9840 (define_insn "mshalds_w"
9841   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9842         (ss_truncate:V4HI
9843          (ashift:V4SI
9844           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9845           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
9846                   (const_int 15)))))]
9847   "TARGET_SHMEDIA"
9848   "mshalds.w    %1, %2, %0"
9849   [(set_attr "type" "mcmp_media")])
9851 (define_insn "ashrv2si3"
9852   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9853         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9854                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9855   "TARGET_SHMEDIA"
9856   "mshard.l     %1, %2, %0"
9857   [(set_attr "type" "arith_media")])
9859 (define_insn "ashrv4hi3"
9860   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9861         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9862                        (match_operand:DI 2 "arith_reg_operand" "r")))]
9863   "TARGET_SHMEDIA"
9864   "mshard.w     %1, %2, %0"
9865   [(set_attr "type" "arith_media")])
9867 (define_insn "mshards_q"
9868   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
9869         (ss_truncate:HI
9870          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
9871                       (match_operand:DI 2 "arith_reg_or_0_operand" "rU"))))]
9872   "TARGET_SHMEDIA"
9873   "mshards.q    %1, %N2, %0"
9874   [(set_attr "type" "mcmp_media")])
9876 (define_expand "mshfhi_b"
9877   [(match_operand:V8QI 0 "arith_reg_dest" "")
9878    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9879    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9880   "TARGET_SHMEDIA"
9881   "
9883   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
9884              (operands[0], operands[1], operands[2]));
9885   DONE;
9888 (define_expand "mshflo_b"
9889   [(match_operand:V8QI 0 "arith_reg_dest" "")
9890    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9891    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU")]
9892   "TARGET_SHMEDIA"
9893   "
9895   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
9896              (operands[0], operands[1], operands[2]));
9897   DONE;
9900 (define_insn "mshf4_b"
9901   [(set
9902     (match_operand:V8QI 0 "arith_reg_dest" "=r")
9903     (vec_select:V8QI
9904      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9905                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9906      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
9907                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
9908   "TARGET_SHMEDIA"
9909   "* return (TARGET_LITTLE_ENDIAN
9910              ? \"mshfhi.b       %N1, %N2, %0\"
9911              : \"mshflo.b       %N1, %N2, %0\");"
9912   [(set_attr "type" "arith_media")])
9914 (define_insn "mshf0_b"
9915   [(set
9916     (match_operand:V8QI 0 "arith_reg_dest" "=r")
9917     (vec_select:V8QI
9918      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rU")
9919                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rU"))
9920      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
9921                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
9922   "TARGET_SHMEDIA"
9923   "* return (TARGET_LITTLE_ENDIAN
9924              ? \"mshflo.b       %N1, %N2, %0\"
9925              : \"mshfhi.b       %N1, %N2, %0\");"
9926   [(set_attr "type" "arith_media")])
9928 (define_expand "mshfhi_l"
9929   [(match_operand:V2SI 0 "arith_reg_dest" "")
9930    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9931    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9932   "TARGET_SHMEDIA"
9933   "
9935   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
9936              (operands[0], operands[1], operands[2]));
9937   DONE;
9940 (define_expand "mshflo_l"
9941   [(match_operand:V2SI 0 "arith_reg_dest" "")
9942    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9943    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU")]
9944   "TARGET_SHMEDIA"
9945   "
9947   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
9948              (operands[0], operands[1], operands[2]));
9949   DONE;
9952 (define_insn "mshf4_l"
9953   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9954         (vec_select:V2SI
9955          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9956                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9957          (parallel [(const_int 1) (const_int 3)])))]
9958   "TARGET_SHMEDIA"
9959   "* return (TARGET_LITTLE_ENDIAN
9960              ? \"mshfhi.l       %N1, %N2, %0\"
9961              : \"mshflo.l       %N1, %N2, %0\");"
9962   [(set_attr "type" "arith_media")])
9964 (define_insn "mshf0_l"
9965   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9966         (vec_select:V2SI
9967          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
9968                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rU"))
9969          (parallel [(const_int 0) (const_int 2)])))]
9970   "TARGET_SHMEDIA"
9971   "* return (TARGET_LITTLE_ENDIAN
9972              ? \"mshflo.l       %N1, %N2, %0\"
9973              : \"mshfhi.l       %N1, %N2, %0\");"
9974   [(set_attr "type" "arith_media")])
9976 (define_expand "mshfhi_w"
9977   [(match_operand:V4HI 0 "arith_reg_dest" "")
9978    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9979    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
9980   "TARGET_SHMEDIA"
9981   "
9983   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
9984              (operands[0], operands[1], operands[2]));
9985   DONE;
9988 (define_expand "mshflo_w"
9989   [(match_operand:V4HI 0 "arith_reg_dest" "")
9990    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
9991    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU")]
9992   "TARGET_SHMEDIA"
9993   "
9995   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
9996              (operands[0], operands[1], operands[2]));
9997   DONE;
10000 (define_insn "mshf4_w"
10001   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10002         (vec_select:V4HI
10003          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10004                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10005          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10006   "TARGET_SHMEDIA"
10007   "* return (TARGET_LITTLE_ENDIAN
10008              ? \"mshfhi.w       %N1, %N2, %0\"
10009              : \"mshflo.w       %N1, %N2, %0\");"
10010   [(set_attr "type" "arith_media")])
10012 (define_insn "mshf0_w"
10013   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10014         (vec_select:V4HI
10015          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10016                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rU"))
10017          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10018   "TARGET_SHMEDIA"
10019   "* return (TARGET_LITTLE_ENDIAN
10020              ? \"mshflo.w       %N1, %N2, %0\"
10021              : \"mshfhi.w       %N1, %N2, %0\");"
10022   [(set_attr "type" "arith_media")])
10024 (define_insn "mshflo_w_x"
10025   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10026         (vec_select:V4HI
10027          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rU")
10028                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rU"))
10029          (parallel [(const_int 0) (const_int 2) (const_int 1) (const_int 3)])))]
10030   "TARGET_SHMEDIA"
10031   "mshflo.w     %N1, %N2, %0"
10032   [(set_attr "type" "arith_media")])
10034 /* These are useful to expand ANDs and as combiner patterns.  */
10035 (define_insn_and_split "mshfhi_l_di"
10036   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10037         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU,f")
10038                              (const_int 32))
10039                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU,?f")
10040                         (const_int -4294967296))))]
10041   "TARGET_SHMEDIA"
10042   "@
10043         mshfhi.l        %N1, %N2, %0
10044         #"
10045   "TARGET_SHMEDIA && reload_completed
10046    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10047   [(set (match_dup 3) (match_dup 4))
10048    (set (match_dup 5) (match_dup 6))]
10049   "
10051   operands[3] = gen_lowpart (SImode, operands[0]);
10052   operands[4] = gen_highpart (SImode, operands[1]);
10053   operands[5] = gen_highpart (SImode, operands[0]);
10054   operands[6] = gen_highpart (SImode, operands[2]);
10056   [(set_attr "type" "arith_media")])
10058 (define_insn "*mshfhi_l_di_rev"
10059   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10060         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10061                         (const_int -4294967296))
10062                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10063                              (const_int 32))))]
10064   "TARGET_SHMEDIA"
10065   "mshfhi.l     %N2, %N1, %0"
10066   [(set_attr "type" "arith_media")])
10068 (define_split
10069   [(set (match_operand:DI 0 "arith_reg_dest" "")
10070         (ior:DI (zero_extend:DI (match_operand:SI 1
10071                                               "extend_reg_or_0_operand" ""))
10072                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10073                         (const_int -4294967296))))
10074    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10075   "TARGET_SHMEDIA"
10076   [(const_int 0)]
10077   "
10079   emit_insn (gen_ashldi3_media (operands[3],
10080                                 simplify_gen_subreg (DImode, operands[1],
10081                                                      SImode, 0),
10082                                 GEN_INT (32)));
10083   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10084   DONE;
10087 (define_insn "mshflo_l_di"
10088   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10089         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10090                         (const_int 4294967295))
10091                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10092                            (const_int 32))))]
10093                                 
10094   "TARGET_SHMEDIA"
10095   "mshflo.l     %N1, %N2, %0"
10096   [(set_attr "type" "arith_media")])
10098 (define_insn "*mshflo_l_di_rev"
10099   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10100         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10101                            (const_int 32))
10102                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10103                         (const_int 4294967295))))]
10104                                 
10105   "TARGET_SHMEDIA"
10106   "mshflo.l     %N2, %N1, %0"
10107   [(set_attr "type" "arith_media")])
10109 ;; Combiner pattern for trampoline initialization.
10110 (define_insn_and_split "*double_shori"
10111   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10112         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10113                            (const_int 32))
10114                 (match_operand:DI 2 "const_int_operand" "n")))]
10115   "TARGET_SHMEDIA
10116    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10117   "#"
10118   "rtx_equal_p (operands[0], operands[1])"
10119   [(const_int 0)]
10120   "
10122   HOST_WIDE_INT v = INTVAL (operands[2]);
10124   emit_insn (gen_shori_media (operands[0], operands[0],
10125              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10126   emit_insn (gen_shori_media (operands[0], operands[0],
10127                               gen_int_mode (v, HImode)));
10128   DONE;
10132 (define_insn "*mshflo_l_di_x"
10133   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10134         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10135                                  "rU"))
10136                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rU")
10137                            (const_int 32))))]
10138                                 
10139   "TARGET_SHMEDIA"
10140   "mshflo.l     %N1, %N2, %0"
10141   [(set_attr "type" "arith_media")])
10143 (define_insn_and_split "concat_v2sf"
10144   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10145 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,0,f")
10146         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rU,f,f")
10147                          (match_operand:SF 2 "register_operand" "rU,f,f")))]
10148                                 
10149   "TARGET_SHMEDIA"
10150   "@
10151         mshflo.l        %N1, %N2, %0
10152         #
10153         #"
10154   "TARGET_SHMEDIA && reload_completed
10155    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10156   [(set (match_dup 3) (match_dup 1))
10157    (set (match_dup 4) (match_dup 2))]
10158   "
10160   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10161   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10163   [(set_attr "type" "arith_media")])
10165 (define_insn "*mshflo_l_di_x_rev"
10166   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10167         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rU")
10168                            (const_int 32))
10169                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rU"))))]
10170                                 
10171   "TARGET_SHMEDIA"
10172   "mshflo.l     %N2, %N1, %0"
10173   [(set_attr "type" "arith_media")])
10175 (define_insn "ashlv2si3"
10176   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10177         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10178                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10179   "TARGET_SHMEDIA"
10180   "mshlld.l     %1, %2, %0"
10181   [(set_attr "type" "arith_media")])
10183 (define_insn "ashlv4hi3"
10184   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10185         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10186                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10187   "TARGET_SHMEDIA"
10188   "mshlld.w     %1, %2, %0"
10189   [(set_attr "type" "arith_media")])
10191 (define_insn "lshrv2si3"
10192   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10193         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10194                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10195   "TARGET_SHMEDIA"
10196   "mshlrd.l     %1, %2, %0"
10197   [(set_attr "type" "arith_media")])
10199 (define_insn "lshrv4hi3"
10200   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10201         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10202                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10203   "TARGET_SHMEDIA"
10204   "mshlrd.w     %1, %2, %0"
10205   [(set_attr "type" "arith_media")])
10207 (define_insn "subv2si3"
10208   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10209         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10210                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10211   "TARGET_SHMEDIA"
10212   "msub.l       %N1, %2, %0"
10213   [(set_attr "type" "arith_media")])
10215 (define_insn "subv4hi3"
10216   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10217         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10218                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10219   "TARGET_SHMEDIA"
10220   "msub.w       %N1, %2, %0"
10221   [(set_attr "type" "arith_media")])
10223 (define_insn "sssubv2si3"
10224   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10225         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rU")
10226                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10227   "TARGET_SHMEDIA"
10228   "msubs.l      %N1, %2, %0"
10229   [(set_attr "type" "mcmp_media")])
10231 (define_insn "ussubv8qi3"
10232   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10233         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10234                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10235   "TARGET_SHMEDIA"
10236   "msubs.ub     %1, %2, %0"
10237   [(set_attr "type" "mcmp_media")])
10239 (define_insn "sssubv4hi3"
10240   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10241         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rU")
10242                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10243   "TARGET_SHMEDIA"
10244   "msubs.w      %N1, %2, %0"
10245   [(set_attr "type" "mcmp_media")])
10247 ;; Floating Point Intrinsics
10249 (define_insn "fcosa_s"
10250   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10251         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10252                    UNSPEC_FCOSA))]
10253   "TARGET_SHMEDIA"
10254   "fcosa.s      %1, %0"
10255   [(set_attr "type" "atrans_media")])
10257 (define_insn "fsina_s"
10258   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10259         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10260                    UNSPEC_FSINA))]
10261   "TARGET_SHMEDIA"
10262   "fsina.s      %1, %0"
10263   [(set_attr "type" "atrans_media")])
10265 (define_insn "fipr"
10266   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10267         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10268                                                     "fp_arith_reg_operand" "f")
10269                                                    (match_operand:V4SF 2
10270                                                     "fp_arith_reg_operand" "f"))
10271                                          (parallel [(const_int 0)]))
10272                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10273                                          (parallel [(const_int 1)])))
10274                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10275                                          (parallel [(const_int 2)]))
10276                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10277                                          (parallel [(const_int 3)])))))]
10278   "TARGET_SHMEDIA"
10279   "fipr %1, %2, %0"
10280   [(set_attr "type" "fparith_media")])
10282 (define_insn "fsrra_s"
10283   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10284         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10285                    UNSPEC_FSRRA))]
10286   "TARGET_SHMEDIA"
10287   "fsrra.s      %1, %0"
10288   [(set_attr "type" "atrans_media")])
10290 (define_insn "ftrv"
10291   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10292         (plus:V4SF
10293          (plus:V4SF
10294           (mult:V4SF
10295            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10296                             (parallel [(const_int 0) (const_int 5)
10297                                        (const_int 10) (const_int 15)]))
10298            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10299           (mult:V4SF
10300            (vec_select:V4SF (match_dup 1)
10301                             (parallel [(const_int 4) (const_int 9)
10302                                        (const_int 14) (const_int 3)]))
10303            (vec_select:V4SF (match_dup 2)
10304                             (parallel [(const_int 1) (const_int 2)
10305                                       (const_int 3) (const_int 0)]))))
10306          (plus:V4SF
10307           (mult:V4SF
10308            (vec_select:V4SF (match_dup 1)
10309                             (parallel [(const_int 8) (const_int 13)
10310                                        (const_int 2) (const_int 7)]))
10311            (vec_select:V4SF (match_dup 2)
10312                             (parallel [(const_int 2) (const_int 3)
10313                                        (const_int 0) (const_int 1)])))
10314           (mult:V4SF
10315            (vec_select:V4SF (match_dup 1)
10316                             (parallel [(const_int 12) (const_int 1)
10317                                        (const_int 6) (const_int 11)]))
10318            (vec_select:V4SF (match_dup 2)
10319                             (parallel [(const_int 3) (const_int 0)
10320                                        (const_int 1) (const_int 2)]))))))]
10321   "TARGET_SHMEDIA"
10322   "ftrv %1, %2, %0"
10323   [(set_attr "type" "fparith_media")])
10325 (define_insn "nsb"
10326   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10327         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10328                    UNSPEC_NSB))]
10329   "TARGET_SHMEDIA"
10330   "nsb  %1, %0"
10331   [(set_attr "type" "arith_media")])
10333 (define_insn "nsbsi"
10334   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10335         (zero_extend:SI
10336          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10337                     UNSPEC_NSB)))]
10338   "TARGET_SHMEDIA"
10339   "nsb  %1, %0"
10340   [(set_attr "type" "arith_media")])
10342 (define_insn "nsbdi"
10343   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10344         (zero_extend:DI
10345          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10346                     UNSPEC_NSB)))]
10347   "TARGET_SHMEDIA"
10348   "nsb  %1, %0"
10349   [(set_attr "type" "arith_media")])
10351 (define_expand "ffsdi2"
10352   [(set (match_operand:DI 0 "arith_reg_dest" "")
10353         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10354   "TARGET_SHMEDIA"
10355   "
10357   rtx scratch = gen_reg_rtx (DImode);
10358   rtx last;
10360   emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10361   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10362   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10363   emit_insn (gen_nsbdi (scratch, scratch));
10364   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10365   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10366   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10367   REG_NOTES (last)
10368     = gen_rtx_EXPR_LIST (REG_EQUAL,
10369                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10370   DONE;
10373 (define_expand "ffssi2"
10374   [(set (match_operand:SI 0 "arith_reg_dest" "")
10375         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10376   "TARGET_SHMEDIA"
10377   "
10379   rtx scratch = gen_reg_rtx (SImode);
10380   rtx discratch = gen_reg_rtx (DImode);
10381   rtx last;
10383   emit_insn (gen_adddi3z_media (discratch, operands[1],
10384                                 force_reg (SImode, GEN_INT (-1))));
10385   emit_insn (gen_andcdi3 (discratch, discratch,
10386                           simplify_gen_subreg (DImode, operands[1],
10387                                                SImode, 0)));
10388   emit_insn (gen_nsbsi (scratch, discratch));
10389   last = emit_insn (gen_subsi3 (operands[0],
10390                                 force_reg (SImode, GEN_INT (-64)), scratch));
10391   REG_NOTES (last)
10392     = gen_rtx_EXPR_LIST (REG_EQUAL,
10393                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10394   DONE;
10397 (define_insn "byterev"
10398   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10399         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10400                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10401                                     (const_int 4) (const_int 3) (const_int 2)
10402                                     (const_int 1) (const_int 0)])))]
10403   "TARGET_SHMEDIA"
10404   "byterev      %1, %0"
10405   [(set_attr "type" "arith_media")])
10407 ;; The following description  models the
10408 ;; SH4 pipeline using the DFA based scheduler. 
10409 ;; The DFA based description is better way to model 
10410 ;; a superscalar pipeline as compared to function unit
10411 ;; reservation model.   
10412 ;; 1. The function unit based model is oriented to describe at most one 
10413 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple 
10414 ;;    pipeline units by same insn. This can be done using DFA based description.
10415 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10416 ;; 3. Writing all unit reservations for an instruction class is more natural description 
10417 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the 
10418 ;;    old function unit based model.
10419 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10422 ;; Two automata are defined to reduce number of states
10423 ;; which a single large automaton will have.(Factoring)
10425 (define_automaton "inst_pipeline,fpu_pipe")
10427 ;; This unit is basically the decode unit of the processor.
10428 ;; Since SH4 is a dual issue machine,it is as if there are two 
10429 ;; units so that any insn can be processed by either one
10430 ;; of the decoding unit.
10432 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10435 ;; The fixed point arithmetic calculator(?? EX Unit).
10437 (define_cpu_unit  "int" "inst_pipeline")
10439 ;; f1_1 and f1_2 are floating point units.Actually there is
10440 ;; a f1 unit which can overlap with other f1 unit but
10441 ;; not another F1 unit.It is as though there were two
10442 ;; f1 units.
10444 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10446 ;; The floating point units (except FS - F2 always precedes it.)
10448 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10450 ;; This is basically the MA unit of SH4
10451 ;; used in LOAD/STORE pipeline.
10453 (define_cpu_unit "memory" "inst_pipeline")
10455 ;; However, there are LS group insns that don't use it, even ones that
10456 ;; complete in 0 cycles.  So we use an extra unit for the issue of LS insns.
10457 (define_cpu_unit "load_store" "inst_pipeline")
10459 ;; The address calculator used for branch instructions.
10460 ;; This will be reserved after "issue" of branch instructions
10461 ;; and this is to make sure that no two branch instructions 
10462 ;; can be issued in parallel. 
10464 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10466 ;; ----------------------------------------------------
10467 ;; This reservation is to simplify the dual issue description.
10469 (define_reservation  "issue"  "pipe_01|pipe_02")
10471 ;; This is to express the locking of D stage.
10472 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10474 (define_reservation  "d_lock" "pipe_01+pipe_02")
10476 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10477 (define_reservation "F01" "F0+F1")
10479 ;; This is to simplify description where F1,F2,FS
10480 ;; are used simultaneously.
10482 (define_reservation "fpu" "F1+F2")
10484 ;; This is to highlight the fact that f1 
10485 ;; cannot overlap with F1.
10487 (exclusion_set  "f1_1,f1_2" "F1")
10489 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10491 ;; Although reg moves have a latency of zero 
10492 ;; we need to highlight that they use D stage
10493 ;; for one cycle.
10495 ;; Group:       MT
10497 (define_insn_reservation "reg_mov" 0
10498   (and (eq_attr "pipe_model" "sh4")
10499        (eq_attr "type" "move"))
10500   "issue")
10502 ;; Group:       LS
10504 (define_insn_reservation "freg_mov" 0
10505   (and (eq_attr "pipe_model" "sh4")
10506        (eq_attr "type" "fmove"))
10507   "issue+load_store")
10509 ;; We don't model all pipeline stages; we model the issue ('D') stage
10510 ;; inasmuch as we allow only two instructions to issue simultanously,
10511 ;; and CO instructions prevent any simultanous issue of another instruction.
10512 ;; (This uses pipe_01 and pipe_02).
10513 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10514 ;; Double issue of EX / BR insns is prevented by using the int unit /
10515 ;; pcr_addrcalc unit in the EX stage.
10516 ;; Double issue of BR / LS instructions is prevented by using the
10517 ;; pcr_addrcalc / load_store unit in the issue cycle.
10518 ;; Double issue of FE instructions is prevented by using F0 in the first
10519 ;; pipeline stage after the first D stage.
10520 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10521 ;; (except in the cases outlined above), nor to describe the FS stage after
10522 ;; the F2 stage.
10524 ;; Other MT  group intructions(1 step operations)
10525 ;; Group:       MT
10526 ;; Latency:     1
10527 ;; Issue Rate:  1
10529 (define_insn_reservation "mt" 1
10530   (and (eq_attr "pipe_model" "sh4")
10531        (eq_attr "type" "mt_group"))
10532   "issue")
10534 ;; Fixed Point Arithmetic Instructions(1 step operations)
10535 ;; Group:       EX
10536 ;; Latency:     1
10537 ;; Issue Rate:  1
10539 (define_insn_reservation "sh4_simple_arith" 1 
10540   (and (eq_attr "pipe_model" "sh4")
10541        (eq_attr "insn_class" "ex_group"))
10542   "issue,int")
10544 ;; Load and store instructions have no alignment peculiarities for the SH4,
10545 ;; but they use the load-store unit, which they share with the fmove type
10546 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10547 ;; Loads have a latency of two.
10548 ;; However, call insns can only paired with a preceding insn, and have
10549 ;; a delay slot, so that we want two more insns to be scheduled between the
10550 ;; load of the function address and the call.  This is equivalent to a
10551 ;; latency of three.
10552 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10553 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10554 ;; We only do this for SImode loads of general registers, to make the work
10555 ;; for ADJUST_COST easier.
10557 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10558 ;; Group:       LS
10559 ;; Latency:     2
10560 ;; Issue Rate:  1
10562 (define_insn_reservation "sh4_load" 2
10563   (and (eq_attr "pipe_model" "sh4")
10564        (eq_attr "type" "load,pcload"))
10565   "issue+load_store,nothing,memory")
10567 ;; calls / sfuncs need an extra instruction for their delay slot.
10568 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10569 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10570 ;; count of a dynamic shift.
10571 (define_insn_reservation "sh4_load_si" 3
10572   (and (eq_attr "pipe_model" "sh4")
10573        (eq_attr "type" "load_si,pcload_si"))
10574   "issue+load_store,nothing,memory")
10576 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10578 ;; The load latency is upped to three higher if the dependent insn does
10579 ;; double precision computation.  We want the 'default' latency to reflect
10580 ;; that increased latency because otherwise the insn priorities won't
10581 ;; allow proper scheduling.
10582 (define_insn_reservation "sh4_fload" 3
10583   (and (eq_attr "pipe_model" "sh4")
10584        (eq_attr "type" "fload,pcfload"))
10585   "issue+load_store,nothing,memory")
10587 ;; (define_bypass 2 "sh4_fload" "!")
10589 (define_insn_reservation "sh4_store" 1
10590   (and (eq_attr "pipe_model" "sh4")
10591        (eq_attr "type" "store"))
10592   "issue+load_store,nothing,memory")
10594 ;; Load Store instructions.
10595 ;; Group:       LS
10596 ;; Latency:     1
10597 ;; Issue Rate:  1
10599 (define_insn_reservation "sh4_gp_fpul" 1
10600   (and (eq_attr "pipe_model" "sh4")
10601        (eq_attr "type" "gp_fpul"))
10602   "issue+load_store")
10604 ;; Load Store instructions.
10605 ;; Group:       LS
10606 ;; Latency:     3
10607 ;; Issue Rate:  1
10609 (define_insn_reservation "sh4_fpul_gp" 3
10610   (and (eq_attr "pipe_model" "sh4")
10611        (eq_attr "type" "fpul_gp"))
10612   "issue+load_store")
10614 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10615 ;; Group:       BR
10616 ;; Latency when taken:  2 (or 1)
10617 ;; Issue Rate:  1
10618 ;; The latency is 1 when displacement is 0.
10619 ;; We can't really do much with the latency, even if we could express it,
10620 ;; but the pairing restrictions are useful to take into account.
10621 ;; ??? If the branch is likely, we might want to fill the delay slot;
10622 ;; if the branch is likely, but not very likely, should we pretend to use
10623 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10625 (define_insn_reservation "sh4_branch"  1
10626   (and (eq_attr "pipe_model" "sh4")
10627        (eq_attr "type" "cbranch,jump"))
10628   "issue+pcr_addrcalc")
10630 ;; Branch Far (JMP,RTS,BRAF)
10631 ;; Group:       CO
10632 ;; Latency:     3
10633 ;; Issue Rate:  2
10634 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10635 ;; can't be distinguished from bra for the "jump" pattern.
10637 (define_insn_reservation "sh4_return" 3
10638   (and (eq_attr "pipe_model" "sh4")
10639        (eq_attr "type" "return,jump_ind"))
10640          "d_lock*2")
10642 ;; RTE
10643 ;; Group:       CO
10644 ;; Latency:     5
10645 ;; Issue Rate:  5
10646 ;; this instruction can be executed in any of the pipelines 
10647 ;; and blocks the pipeline for next 4 stages.
10649 (define_insn_reservation "sh4_return_from_exp" 5
10650   (and (eq_attr "pipe_model" "sh4")
10651        (eq_attr "type" "rte"))
10652   "d_lock*5")
10654 ;; OCBP, OCBWB
10655 ;; Group:       CO
10656 ;; Latency:     1-5
10657 ;; Issue Rate:  1
10659 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10660 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10661 (define_insn_reservation "ocbwb"  6
10662   (and (eq_attr "pipe_model" "sh4")
10663        (eq_attr "type" "cwb"))
10664   "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10665                 
10666 ;; LDS to PR,JSR
10667 ;; Group:       CO
10668 ;; Latency:     3
10669 ;; Issue Rate:  2
10670 ;; The SX stage is blocked for last 2 cycles.
10671 ;; OTOH, the only time that has an effect for insns generated by the compiler
10672 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10673 ;; or when we are doing a function call - and we don't do inter-function
10674 ;; scheduling.  For the function call case, it's really best that we end with
10675 ;; something that models an rts.
10677 (define_insn_reservation "sh4_lds_to_pr" 3 
10678   (and (eq_attr "pipe_model" "sh4")
10679        (eq_attr "type" "prset") )
10680   "d_lock*2")
10682 ;; calls introduce a longisch delay that is likely to flush the pipelines
10683 ;; of the caller's instructions.  Ordinary functions tend to end with a
10684 ;; load to restore a register (in the delay slot of rts), while sfuncs
10685 ;; tend to end with an EX or MT insn.  But that is not actually relevant,
10686 ;; since there are no instructions that contend for memory access early.
10687 ;; We could, of course, provide exact scheduling information for specific
10688 ;; sfuncs, if that should prove useful.
10690 (define_insn_reservation "sh4_call" 16 
10691   (and (eq_attr "pipe_model" "sh4")
10692        (eq_attr "type" "call,sfunc"))
10693   "d_lock*16")
10695 ;; LDS.L to PR 
10696 ;; Group:       CO
10697 ;; Latency:     3
10698 ;; Issue Rate:  2
10699 ;; The SX unit is blocked for last 2 cycles.
10701 (define_insn_reservation "ldsmem_to_pr"  3
10702   (and (eq_attr "pipe_model" "sh4")
10703        (eq_attr "type" "pload"))
10704   "d_lock*2")
10706 ;; STS from PR
10707 ;; Group:       CO
10708 ;; Latency:     2
10709 ;; Issue Rate:  2
10710 ;; The SX unit in second and third cycles.
10712 (define_insn_reservation "sts_from_pr" 2
10713   (and (eq_attr "pipe_model" "sh4")
10714        (eq_attr "type" "prget"))
10715   "d_lock*2")
10717 ;; STS.L from PR
10718 ;; Group:       CO
10719 ;; Latency:     2
10720 ;; Issue Rate:  2
10722 (define_insn_reservation "sh4_prstore_mem" 2 
10723   (and (eq_attr "pipe_model" "sh4")
10724        (eq_attr "type" "pstore"))
10725   "d_lock*2,nothing,memory")
10727 ;; LDS to FPSCR
10728 ;; Group:       CO
10729 ;; Latency:     4
10730 ;; Issue Rate:  1
10731 ;; F1 is blocked for last three cycles. 
10733 (define_insn_reservation "fpscr_load" 4
10734   (and (eq_attr "pipe_model" "sh4")
10735        (eq_attr "type" "gp_fpscr"))
10736   "d_lock,nothing,F1*3")
10738 ;; LDS.L to FPSCR
10739 ;; Group:       CO
10740 ;; Latency:     1 / 4
10741 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
10742 ;; Issue Rate:  1
10743 ;; F1 is blocked for last three cycles.
10745 (define_insn_reservation "fpscr_load_mem" 4
10746   (and (eq_attr "pipe_model" "sh4")
10747        (eq_attr "type"  "mem_fpscr"))
10748   "d_lock,nothing,(F1+memory),F1*2")
10751 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
10752 ;; Group:       CO
10753 ;; Latency:     4 / 4
10754 ;; Issue Rate:  1
10756 (define_insn_reservation "multi" 4
10757   (and (eq_attr "pipe_model" "sh4")
10758        (eq_attr "type" "smpy,dmpy"))
10759   "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
10761 ;; Fixed STS from MACL / MACH
10762 ;; Group:       CO
10763 ;; Latency:     3
10764 ;; Issue Rate:  1
10766 (define_insn_reservation "sh4_mac_gp" 3
10767   (and (eq_attr "pipe_model" "sh4")
10768        (eq_attr "type" "mac_gp"))
10769   "d_lock")
10772 ;; Single precision floating point computation FCMP/EQ,
10773 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
10774 ;; Group:       FE
10775 ;; Latency:     3/4
10776 ;; Issue Rate:  1
10778 (define_insn_reservation "fp_arith"  3
10779   (and (eq_attr "pipe_model" "sh4")
10780        (eq_attr "type" "fp"))
10781   "issue,F01,F2")
10783 (define_insn_reservation "fp_arith_ftrc"  3
10784   (and (eq_attr "pipe_model" "sh4")
10785        (eq_attr "type" "ftrc_s"))
10786   "issue,F01,F2")
10788 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
10790 ;; Single Precision FDIV/SQRT
10791 ;; Group:       FE
10792 ;; Latency:     12/13 (FDIV); 11/12 (FSQRT)
10793 ;; Issue Rate:  1
10794 ;; We describe fdiv here; fsqrt is actually one cycle faster.
10796 (define_insn_reservation "fp_div" 12
10797   (and (eq_attr "pipe_model" "sh4")
10798        (eq_attr "type" "fdiv"))
10799   "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
10801 ;; Double Precision floating point computation
10802 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
10803 ;; Group:       FE
10804 ;; Latency:     (3,4)/5
10805 ;; Issue Rate:  1
10807 (define_insn_reservation "dp_float" 4
10808   (and (eq_attr "pipe_model" "sh4")
10809        (eq_attr "type" "dfp_conv"))
10810   "issue,F01,F1+F2,F2")
10812 ;; Double-precision floating-point (FADD,FMUL,FSUB) 
10813 ;; Group:       FE
10814 ;; Latency:     (7,8)/9
10815 ;; Issue Rate:  1
10817 (define_insn_reservation "fp_double_arith" 8
10818   (and (eq_attr "pipe_model" "sh4")
10819        (eq_attr "type" "dfp_arith"))
10820   "issue,F01,F1+F2,fpu*4,F2")
10822 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT) 
10823 ;; Group:       CO
10824 ;; Latency:     3/5
10825 ;; Issue Rate:  2
10827 (define_insn_reservation "fp_double_cmp" 3 
10828   (and (eq_attr "pipe_model" "sh4")
10829        (eq_attr "type" "dfp_cmp"))
10830   "d_lock,(d_lock+F01),F1+F2,F2")
10832 ;; Double precision FDIV/SQRT
10833 ;; Group:       FE
10834 ;; Latency:     (24,25)/26
10835 ;; Issue Rate:  1
10837 (define_insn_reservation "dp_div" 25
10838   (and (eq_attr "pipe_model" "sh4")
10839        (eq_attr "type" "dfdiv"))
10840   "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
10843 ;; Use the branch-not-taken case to model arith3 insns.  For the branch taken
10844 ;; case, we'd get a d_lock instead of issue at the end.
10845 (define_insn_reservation "arith3" 3
10846   (and (eq_attr "pipe_model" "sh4")
10847        (eq_attr "type" "arith3"))
10848   "issue,d_lock+pcr_addrcalc,issue")
10850 ;; arith3b insns schedule the same no matter if the branch is taken or not.
10851 (define_insn_reservation "arith3b" 2
10852   (and (eq_attr "pipe_model" "sh4")
10853        (eq_attr "type" "arith3"))
10854   "issue,d_lock+pcr_addrcalc")