* config/sh/sh.c (sh_va_arg): Initinalize lab_over.
[official-gcc.git] / gcc / config / sh / sh.md
blobd96227bc938a92a082ecc17bedd785d90d3842ce
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 ;;  2003, 2004 Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to
21 ;; the Free Software Foundation, 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)
138   (UNSPEC_EH_RETURN     19)
139   (UNSPEC_TLSGD         20)
140   (UNSPEC_TLSLDM        21)
141   (UNSPEC_TLSIE         22)
142   (UNSPEC_DTPOFF        23)
143   (UNSPEC_GOTTPOFF      24)
144   (UNSPEC_TPOFF         25)
145   (UNSPEC_RA            26)
147   ;; These are used with unspec_volatile.
148   (UNSPECV_BLOCKAGE     0)
149   (UNSPECV_ALIGN        1)
150   (UNSPECV_CONST2       2)
151   (UNSPECV_CONST4       4)
152   (UNSPECV_CONST8       6)
153   (UNSPECV_WINDOW_END   10)
154   (UNSPECV_CONST_END    11)
157 ;; -------------------------------------------------------------------------
158 ;; Attributes
159 ;; -------------------------------------------------------------------------
161 ;; Target CPU.
163 (define_attr "cpu"
164  "sh1,sh2,sh2e,sh3,sh3e,sh4,sh5"
165   (const (symbol_ref "sh_cpu_attr")))
167 (define_attr "endian" "big,little"
168  (const (if_then_else (symbol_ref "TARGET_LITTLE_ENDIAN")
169                       (const_string "little") (const_string "big"))))
171 ;; Indicate if the default fpu mode is single precision.
172 (define_attr "fpu_single" "yes,no"
173   (const (if_then_else (symbol_ref "TARGET_FPU_SINGLE")
174                          (const_string "yes") (const_string "no"))))
176 (define_attr "fmovd" "yes,no"
177   (const (if_then_else (symbol_ref "TARGET_FMOVD")
178                        (const_string "yes") (const_string "no"))))
179 ;; pipeline model
180 (define_attr "pipe_model" "sh1,sh4,sh5media"
181   (const
182    (cond [(symbol_ref "TARGET_SHMEDIA") (const_string "sh5media")
183           (symbol_ref "TARGET_SUPERSCALAR") (const_string "sh4")]
184          (const_string "sh1"))))
186 ;; cbranch      conditional branch instructions
187 ;; jump         unconditional jumps
188 ;; arith        ordinary arithmetic
189 ;; arith3       a compound insn that behaves similarly to a sequence of
190 ;;              three insns of type arith
191 ;; arith3b      like above, but might end with a redirected branch
192 ;; load         from memory
193 ;; load_si      Likewise, SImode variant for general register.
194 ;; fload        Likewise, but load to fp register.
195 ;; store        to memory
196 ;; move         general purpose register to register
197 ;; mt_group     other sh4 mt instructions
198 ;; fmove        register to register, floating point
199 ;; smpy         word precision integer multiply
200 ;; dmpy         longword or doublelongword precision integer multiply
201 ;; return       rts
202 ;; pload        load of pr reg, which can't be put into delay slot of rts
203 ;; prset        copy register to pr reg, ditto
204 ;; pstore       store of pr reg, which can't be put into delay slot of jsr
205 ;; prget        copy pr to register, ditto
206 ;; pcload       pc relative load of constant value
207 ;; pcfload      Likewise, but load to fp register.
208 ;; pcload_si    Likewise, SImode variant for general register.
209 ;; rte          return from exception
210 ;; sfunc        special function call with known used registers
211 ;; call         function call
212 ;; fp           floating point
213 ;; fdiv         floating point divide (or square root)
214 ;; gp_fpul      move from general purpose register to fpul
215 ;; fpul_gp      move from fpul to general purpose register
216 ;; mac_gp       move from mac[lh] to general purpose register
217 ;; dfp_arith, dfp_cmp,dfp_conv
218 ;; ftrc_s       fix_truncsfsi2_i4
219 ;; dfdiv        double precision floating point divide (or square root)
220 ;; cwb          ic_invalidate_line_i
221 ;; tls_load     load TLS related address
222 ;; arith_media  SHmedia arithmetic, logical, and shift instructions
223 ;; cbranch_media SHmedia conditional branch instructions
224 ;; cmp_media    SHmedia compare instructions
225 ;; dfdiv_media  SHmedia double precision divide and square root
226 ;; dfmul_media  SHmedia double precision multiply instruction
227 ;; dfparith_media SHmedia double precision floating point arithmetic
228 ;; dfpconv_media SHmedia double precision floating point conversions
229 ;; dmpy_media   SHmedia longword multiply
230 ;; fcmp_media   SHmedia floating point compare instructions
231 ;; fdiv_media   SHmedia single precision divide and square root
232 ;; fload_media  SHmedia floating point register load instructions
233 ;; fmove_media  SHmedia floating point register moves (inc. fabs and fneg)
234 ;; fparith_media SHmedia single precision floating point arithmetic
235 ;; fpconv_media SHmedia single precision floating point conversions
236 ;; fstore_media SHmedia floating point register store instructions
237 ;; gettr_media  SHmedia gettr instruction
238 ;; invalidate_line_media SHmedia invalidate_line sequence
239 ;; jump_media   SHmedia unconditional branch instructions
240 ;; load_media   SHmedia general register load instructions
241 ;; pt_media     SHmedia pt instruction (expanded by assembler)
242 ;; ptabs_media  SHmedia ptabs instruction
243 ;; store_media  SHmedia general register store instructions
244 ;; mcmp_media   SHmedia multimedia compare, absolute, saturating ops
245 ;; mac_media    SHmedia mac-style fixed point operations
246 ;; d2mpy_media  SHmedia: two 32 bit integer multiplies
247 ;; atrans       SHmedia approximate transcendental functions
248 ;; ustore_media SHmedia unaligned stores
249 ;; nil          no-op move, will be deleted.
251 (define_attr "type"
252  "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,tls_load,arith_media,cbranch_media,cmp_media,dfdiv_media,dfmul_media,dfparith_media,dfpconv_media,dmpy_media,fcmp_media,fdiv_media,fload_media,fmove_media,fparith_media,fpconv_media,fstore_media,gettr_media,invalidate_line_media,jump_media,load_media,pt_media,ptabs_media,store_media,mcmp_media,mac_media,d2mpy_media,atrans_media,ustore_media,nil,other"
253   (const_string "other"))
255 ;; We define a new attribute namely "insn_class".We use
256 ;; this for the DFA based pipeline description.
258 ;; mt_group      SH4 "mt" group instructions.
260 ;; ex_group      SH4 "ex" group instructions.
262 ;; ls_group      SH4 "ls" group instructions.
265 (define_attr "insn_class"
266   "mt_group,ex_group,ls_group,br_group,fe_group,co_group,none"
267   (cond [(eq_attr "type" "move,mt_group") (const_string "mt_group")
268          (eq_attr "type" "arith,dyn_shift") (const_string "ex_group")
269          (eq_attr "type" "fmove,load,pcload,load_si,pcload_si,fload,pcfload,store,gp_fpul,fpul_gp") (const_string "ls_group")
270          (eq_attr "type" "cbranch,jump") (const_string "br_group")
271          (eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
272            (const_string "fe_group")
273          (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")]
274         (const_string "none")))
275 ;; nil are zero instructions, and arith3 / arith3b are multiple instructions,
276 ;; so these do not belong in an insn group, although they are modeled
277 ;; with their own define_insn_reservations.
279 ;; Indicate what precision must be selected in fpscr for this insn, if any.
281 (define_attr "fp_mode" "single,double,none" (const_string "none"))
283 ;; Indicate if the fpu mode is set by this instruction
284 ;; "unknown" must have the value as "none" in fp_mode, and means
285 ;; that the instruction/abi has left the processor in an unknown
286 ;; state.
287 ;; "none" means that nothing has changed and no mode is set.
288 ;; This attribute is only used for the Renesas ABI.
289 (define_attr "fp_set" "single,double,unknown,none" (const_string "none"))
291 ; If a conditional branch destination is within -252..258 bytes away
292 ; from the instruction it can be 2 bytes long.  Something in the
293 ; range -4090..4100 bytes can be 6 bytes long.  All other conditional
294 ; branches are initially assumed to be 16 bytes long.
295 ; In machine_dependent_reorg, we split all branches that are longer than
296 ; 2 bytes.
298 ;; The maximum range used for SImode constant pool entries is 1018.  A final
299 ;; instruction can add 8 bytes while only being 4 bytes in size, thus we
300 ;; can have a total of 1022 bytes in the pool.  Add 4 bytes for a branch
301 ;; instruction around the pool table, 2 bytes of alignment before the table,
302 ;; and 30 bytes of alignment after the table.  That gives a maximum total
303 ;; pool size of 1058 bytes.
304 ;; Worst case code/pool content size ratio is 1:2 (using asms).
305 ;; Thus, in the worst case, there is one instruction in front of a maximum
306 ;; sized pool, and then there are 1052 bytes of pool for every 508 bytes of
307 ;; code.  For the last n bytes of code, there are 2n + 36 bytes of pool.
308 ;; If we have a forward branch, the initial table will be put after the
309 ;; unconditional branch.
311 ;; ??? We could do much better by keeping track of the actual pcloads within
312 ;; the branch range and in the pcload range in front of the branch range.
314 ;; ??? This looks ugly because genattrtab won't allow if_then_else or cond
315 ;; inside an le.
316 (define_attr "short_cbranch_p" "no,yes"
317   (cond [(ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
318          (const_string "no")
319          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 506))
320          (const_string "yes")
321          (ne (symbol_ref "NEXT_INSN (PREV_INSN (insn)) != insn") (const_int 0))
322          (const_string "no")
323          (leu (plus (minus (match_dup 0) (pc)) (const_int 252)) (const_int 508))
324          (const_string "yes")
325          ] (const_string "no")))
327 (define_attr "med_branch_p" "no,yes"
328   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 990))
329               (const_int 1988))
330          (const_string "yes")
331          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
332          (const_string "no")
333          (leu (plus (minus (match_dup 0) (pc)) (const_int 4092))
334               (const_int 8186))
335          (const_string "yes")
336          ] (const_string "no")))
338 (define_attr "med_cbranch_p" "no,yes"
339   (cond [(leu (plus (minus (match_dup 0) (pc)) (const_int 988))
340               (const_int 1986))
341          (const_string "yes")
342          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
343          (const_string "no")
344          (leu (plus (minus (match_dup 0) (pc)) (const_int 4090))
345                (const_int 8184))
346          (const_string "yes")
347          ] (const_string "no")))
349 (define_attr "braf_branch_p" "no,yes"
350   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
351          (const_string "no")
352          (leu (plus (minus (match_dup 0) (pc)) (const_int 10330))
353               (const_int 20660))
354          (const_string "yes")
355          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
356          (const_string "no")
357          (leu (plus (minus (match_dup 0) (pc)) (const_int 32764))
358               (const_int 65530))
359          (const_string "yes")
360          ] (const_string "no")))
362 (define_attr "braf_cbranch_p" "no,yes"
363   (cond [(ne (symbol_ref "! TARGET_SH2") (const_int 0))
364          (const_string "no")
365          (leu (plus (minus (match_dup 0) (pc)) (const_int 10328))
366               (const_int 20658))
367          (const_string "yes")
368          (ne (symbol_ref "mdep_reorg_phase <= SH_FIXUP_PCLOAD") (const_int 0))
369          (const_string "no")
370          (leu (plus (minus (match_dup 0) (pc)) (const_int 32762))
371               (const_int 65528))
372          (const_string "yes")
373          ] (const_string "no")))
375 ; An unconditional jump in the range -4092..4098 can be 2 bytes long.
376 ; For wider ranges, we need a combination of a code and a data part.
377 ; If we can get a scratch register for a long range jump, the code
378 ; part can be 4 bytes long; otherwise, it must be 8 bytes long.
379 ; If the jump is in the range -32764..32770, the data part can be 2 bytes
380 ; long; otherwise, it must be 6 bytes long.
382 ; All other instructions are two bytes long by default.
384 ;; ??? This should use something like *branch_p (minus (match_dup 0) (pc)),
385 ;; but getattrtab doesn't understand this.
386 (define_attr "length" ""
387   (cond [(eq_attr "type" "cbranch")
388          (cond [(eq_attr "short_cbranch_p" "yes")
389                 (const_int 2)
390                 (eq_attr "med_cbranch_p" "yes")
391                 (const_int 6)
392                 (eq_attr "braf_cbranch_p" "yes")
393                 (const_int 12)
394 ;; ??? using pc is not computed transitively.
395                 (ne (match_dup 0) (match_dup 0))
396                 (const_int 14)
397                 (ne (symbol_ref ("flag_pic")) (const_int 0))
398                 (const_int 24)
399                 ] (const_int 16))
400          (eq_attr "type" "jump")
401          (cond [(eq_attr "med_branch_p" "yes")
402                 (const_int 2)
403                 (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
404                          (symbol_ref "INSN"))
405                      (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
406                          (symbol_ref "code_for_indirect_jump_scratch")))
407                 (if_then_else (eq_attr "braf_branch_p" "yes")
408                               (const_int 6)
409                               (const_int 10))
410                 (eq_attr "braf_branch_p" "yes")
411                 (const_int 10)
412 ;; ??? using pc is not computed transitively.
413                 (ne (match_dup 0) (match_dup 0))
414                 (const_int 12)
415                 (ne (symbol_ref ("flag_pic")) (const_int 0))
416                 (const_int 22)
417                 ] (const_int 14))
418          (eq_attr "type" "pt_media")
419          (if_then_else (ne (symbol_ref "TARGET_SHMEDIA64") (const_int 0))
420                        (const_int 20) (const_int 12))
421          ] (if_then_else (ne (symbol_ref "TARGET_SHMEDIA") (const_int 0))
422                          (const_int 4)
423                          (const_int 2))))
425 ;; (define_function_unit {name} {num-units} {n-users} {test}
426 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
428 ;; Load and store instructions save a cycle if they are aligned on a
429 ;; four byte boundary.  Using a function unit for stores encourages
430 ;; gcc to separate load and store instructions by one instruction,
431 ;; which makes it more likely that the linker will be able to word
432 ;; align them when relaxing.
434 ;; Loads have a latency of two.
435 ;; However, call insns can have a delay slot, so that we want one more
436 ;; insn to be scheduled between the load of the function address and the call.
437 ;; This is equivalent to a latency of three.
438 ;; We cannot use a conflict list for this, because we need to distinguish
439 ;; between the actual call address and the function arguments.
440 ;; ADJUST_COST can only properly handle reductions of the cost, so we
441 ;; use a latency of three here.
442 ;; We only do this for SImode loads of general registers, to make the work
443 ;; for ADJUST_COST easier.
444 (define_function_unit "memory" 1 0
445   (and (eq_attr "pipe_model" "sh1")
446        (eq_attr "type" "load_si,pcload_si"))
447   3 2)
448 (define_function_unit "memory" 1 0
449   (and (eq_attr "pipe_model" "sh1")
450        (eq_attr "type" "load,pcload,pload,store,pstore"))
451   2 2)
453 (define_function_unit "int"    1 0
454   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "arith3,arith3b")) 3 3)
456 (define_function_unit "int"    1 0
457   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dyn_shift")) 2 2)
459 (define_function_unit "int"    1 0
460   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "!arith3,arith3b,dyn_shift")) 1 1)
462 ;; ??? These are approximations.
463 (define_function_unit "mpy"    1 0
464   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "smpy")) 2 2)
465 (define_function_unit "mpy"    1 0
466   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "dmpy")) 3 3)
468 (define_function_unit "fp"     1 0
469   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fp,fmove")) 2 1)
470 (define_function_unit "fp"     1 0
471   (and (eq_attr "pipe_model" "sh1") (eq_attr "type" "fdiv")) 13 12)
474 ;; SH-5 SHmedia scheduling
475 ;; When executing SHmedia code, the SH-5 is a fairly straightforward
476 ;; single-issue machine.  It has four pipelines, the branch unit (br),
477 ;; the integer and multimedia unit (imu), the load/store unit (lsu), and
478 ;; the floating point unit (fpu).
479 ;; Here model the instructions with a latency greater than one cycle.
481 ;; Every instruction on SH-5 occupies the issue resource for at least one
482 ;; cycle.
483 (define_function_unit "sh5issue" 1 0
484   (and (eq_attr "pipe_model" "sh5media")
485        (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)
487 ;; Specify the various types of instruction which have latency > 1
488 (define_function_unit "sh5issue" 1 0
489   (and (eq_attr "pipe_model" "sh5media")
490        (eq_attr "type" "mcmp_media")) 2 1)
492 (define_function_unit "sh5issue" 1 0
493   (and (eq_attr "pipe_model" "sh5media")
494        (eq_attr "type" "dmpy_media,load_media,fcmp_media,mac_media")) 3 1)
495 ;; but see sh_adjust_cost for mac_media exception.
497 (define_function_unit "sh5issue" 1 0
498   (and (eq_attr "pipe_model" "sh5media")
499        (eq_attr "type" "fload_media,fmove_media")) 4 1)
501 (define_function_unit "sh5issue" 1 0
502   (and (eq_attr "pipe_model" "sh5media")
503        (eq_attr "type" "d2mpy_media")) 4 2)
505 (define_function_unit "sh5issue" 1 0
506   (and (eq_attr "pipe_model" "sh5media")
507        (eq_attr "type" "pt_media,ptabs_media")) 5 1)
509 (define_function_unit "sh5issue" 1 0
510   (and (eq_attr "pipe_model" "sh5media")
511        (eq_attr "type" "fparith_media,dfparith_media,fpconv_media,dfpconv_media")) 6 1)
513 (define_function_unit "sh5issue" 1 0
514   (and (eq_attr "pipe_model" "sh5media")
515        (eq_attr "type" "invalidate_line_media")) 7 7)
517 (define_function_unit "sh5issue" 1 0
518   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfmul_media")) 9 4)
520 (define_function_unit "sh5issue" 1 0
521   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "atrans_media")) 10 5)
523 ;; Floating-point divide and square-root occupy an additional resource,
524 ;; which is not internally pipelined.  However, other instructions
525 ;; can continue to issue.
526 (define_function_unit "sh5fds" 1 0
527   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "fdiv_media"))  19 19)
529 (define_function_unit "sh5fds" 1 0
530   (and (eq_attr "pipe_model" "sh5media") (eq_attr "type" "dfdiv_media")) 35 35)
532 ; Definitions for filling branch delay slots.
534 (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
536 ;; ??? This should be (nil) instead of (const_int 0)
537 (define_attr "hit_stack" "yes,no"
538         (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
539                    (const_int 0))
540                (const_string "no")]
541               (const_string "yes")))
543 (define_attr "interrupt_function" "no,yes"
544   (const (symbol_ref "current_function_interrupt")))
546 (define_attr "in_delay_slot" "yes,no"
547   (cond [(eq_attr "type" "cbranch") (const_string "no")
548          (eq_attr "type" "pcload,pcload_si") (const_string "no")
549          (eq_attr "needs_delay_slot" "yes") (const_string "no")
550          (eq_attr "length" "2") (const_string "yes")
551          ] (const_string "no")))
553 (define_attr "cond_delay_slot" "yes,no"
554   (cond [(eq_attr "in_delay_slot" "yes") (const_string "yes")
555          ] (const_string "no")))
557 (define_attr "is_sfunc" ""
558   (if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
560 (define_attr "is_mac_media" ""
561   (if_then_else (eq_attr "type" "mac_media") (const_int 1) (const_int 0)))
563 (define_attr "branch_zero" "yes,no"
564   (cond [(eq_attr "type" "!cbranch") (const_string "no")
565          (ne (symbol_ref "(next_active_insn (insn)\
566                            == (prev_active_insn\
567                                (XEXP (SET_SRC (PATTERN (insn)), 1))))\
568                           && get_attr_length (next_active_insn (insn)) == 2")
569              (const_int 0))
570          (const_string "yes")]
571         (const_string "no")))
573 ;; SH4 Double-precision computation with double-precision result -
574 ;; the two halves are ready at different times.
575 (define_attr "dfp_comp" "yes,no"
576   (cond [(eq_attr "type" "dfp_arith,dfp_conv,dfdiv") (const_string "yes")]
577         (const_string "no")))
579 ;; Insns for which the latency of a preceding fp insn is decreased by one.
580 (define_attr "late_fp_use" "yes,no" (const_string "no"))
581 ;; And feeding insns for which this relevant.
582 (define_attr "any_fp_comp" "yes,no"
583   (cond [(eq_attr "type" "fp,fdiv,ftrc_s,dfp_arith,dfp_conv,dfdiv")
584          (const_string "yes")]
585         (const_string "no")))
587 (define_attr "any_int_load" "yes,no"
588   (cond [(eq_attr "type" "load,load_si,pcload,pcload_si")
589          (const_string "yes")]
590         (const_string "no")))
592 (define_delay
593   (eq_attr "needs_delay_slot" "yes")
594   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
596 ;; On the SH and SH2, the rte instruction reads the return pc from the stack,
597 ;; and thus we can't put a pop instruction in its delay slot.
598 ;; ??? On the SH3, the rte instruction does not use the stack, so a pop
599 ;; instruction can go in the delay slot.
601 ;; Since a normal return (rts) implicitly uses the PR register,
602 ;; we can't allow PR register loads in an rts delay slot.
604 (define_delay
605   (eq_attr "type" "return")
606   [(and (eq_attr "in_delay_slot" "yes")
607         (ior (and (eq_attr "interrupt_function" "no")
608                   (eq_attr "type" "!pload,prset"))
609              (and (eq_attr "interrupt_function" "yes")
610                   (ior
611                    (ne (symbol_ref "TARGET_SH3") (const_int 0))
612                    (eq_attr "hit_stack" "no"))))) (nil) (nil)])
614 ;; Since a call implicitly uses the PR register, we can't allow
615 ;; a PR register store in a jsr delay slot.
617 (define_delay
618   (ior (eq_attr "type" "call") (eq_attr "type" "sfunc"))
619   [(and (eq_attr "in_delay_slot" "yes")
620         (eq_attr "type" "!pstore,prget")) (nil) (nil)])
622 ;; Say that we have annulled true branches, since this gives smaller and
623 ;; faster code when branches are predicted as not taken.
625 (define_delay
626   (and (eq_attr "type" "cbranch")
627        (ne (symbol_ref "TARGET_SH2") (const_int 0)))
628   ;; SH2e has a hardware bug that pretty much prohibits the use of
629   ;; annuled delay slots.
630   [(eq_attr "in_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes")
631                                         (not (eq_attr "cpu" "sh2e"))) (nil)])
633 ;; -------------------------------------------------------------------------
634 ;; SImode signed integer comparisons
635 ;; -------------------------------------------------------------------------
637 (define_insn ""
638   [(set (reg:SI T_REG)
639         (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
640                        (match_operand:SI 1 "arith_operand" "K08,r"))
641                (const_int 0)))]
642   "TARGET_SH1"
643   "tst  %1,%0"
644   [(set_attr "type" "mt_group")])
646 ;; ??? Perhaps should only accept reg/constant if the register is reg 0.
647 ;; That would still allow reload to create cmpi instructions, but would
648 ;; perhaps allow forcing the constant into a register when that is better.
649 ;; Probably should use r0 for mem/imm compares, but force constant into a
650 ;; register for pseudo/imm compares.
652 (define_insn "cmpeqsi_t"
653   [(set (reg:SI T_REG)
654         (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
655                (match_operand:SI 1 "arith_operand" "N,rI08,r")))]
656   "TARGET_SH1"
657   "@
658         tst     %0,%0
659         cmp/eq  %1,%0
660         cmp/eq  %1,%0"
661    [(set_attr "type" "mt_group")])
663 (define_insn "cmpgtsi_t"
664   [(set (reg:SI T_REG)
665         (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
666                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
667   "TARGET_SH1"
668   "@
669         cmp/gt  %1,%0
670         cmp/pl  %0"
671    [(set_attr "type" "mt_group")])
673 (define_insn "cmpgesi_t"
674   [(set (reg:SI T_REG)
675         (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
676                (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
677   "TARGET_SH1"
678   "@
679         cmp/ge  %1,%0
680         cmp/pz  %0"
681    [(set_attr "type" "mt_group")])
683 ;; -------------------------------------------------------------------------
684 ;; SImode unsigned integer comparisons
685 ;; -------------------------------------------------------------------------
687 (define_insn "cmpgeusi_t"
688   [(set (reg:SI T_REG)
689         (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
690                 (match_operand:SI 1 "arith_reg_operand" "r")))]
691   "TARGET_SH1"
692   "cmp/hs       %1,%0"
693    [(set_attr "type" "mt_group")])
695 (define_insn "cmpgtusi_t"
696   [(set (reg:SI T_REG)
697         (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
698                 (match_operand:SI 1 "arith_reg_operand" "r")))]
699   "TARGET_SH1"
700   "cmp/hi       %1,%0"
701    [(set_attr "type" "mt_group")])
703 ;; We save the compare operands in the cmpxx patterns and use them when
704 ;; we generate the branch.
706 (define_expand "cmpsi"
707   [(set (reg:SI T_REG)
708         (compare (match_operand:SI 0 "cmpsi_operand" "")
709                  (match_operand:SI 1 "arith_operand" "")))]
710   "TARGET_SH1"
711   "
713   if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == T_REG
714       && GET_CODE (operands[1]) != CONST_INT)
715     operands[0] = copy_to_mode_reg (SImode, operands[0]);
716   sh_compare_op0 = operands[0];
717   sh_compare_op1 = operands[1];
718   DONE;
721 ;; -------------------------------------------------------------------------
722 ;; DImode signed integer comparisons
723 ;; -------------------------------------------------------------------------
725 ;; ??? Could get better scheduling by splitting the initial test from the
726 ;; rest of the insn after reload.  However, the gain would hardly justify
727 ;; the sh.md size increase necessary to do that.
729 (define_insn ""
730   [(set (reg:SI T_REG)
731         (eq:SI (and:DI (match_operand:DI 0 "arith_reg_operand" "r")
732                        (match_operand:DI 1 "arith_operand" "r"))
733                (const_int 0)))]
734   "TARGET_SH1"
735   "* return output_branchy_insn (EQ, \"tst\\t%S1,%S0\;bf\\t%l9\;tst\\t%R1,%R0\",
736                                  insn, operands);"
737   [(set_attr "length" "6")
738    (set_attr "type" "arith3b")])
740 (define_insn "cmpeqdi_t"
741   [(set (reg:SI T_REG)
742         (eq:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
743                (match_operand:DI 1 "arith_reg_or_0_operand" "N,r")))]
744   "TARGET_SH1"
745   "@
746         tst     %S0,%S0\;bf     %,Ldi%=\;tst    %R0,%R0\\n%,Ldi%=:
747         cmp/eq  %S1,%S0\;bf     %,Ldi%=\;cmp/eq %R1,%R0\\n%,Ldi%=:"
748   [(set_attr "length" "6")
749    (set_attr "type" "arith3b")])
751 (define_split
752   [(set (reg:SI T_REG)
753         (eq:SI (match_operand:DI 0 "arith_reg_operand" "")
754                (match_operand:DI 1 "arith_reg_or_0_operand" "")))]
755 ;; If we applied this split when not optimizing, it would only be
756 ;; applied during the machine-dependent reorg, when no new basic blocks
757 ;; may be created.
758   "TARGET_SH1 && reload_completed && optimize"
759   [(set (reg:SI T_REG) (eq:SI (match_dup 2) (match_dup 3)))
760    (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
761                            (label_ref (match_dup 6))
762                            (pc)))
763    (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5)))
764    (match_dup 6)]
765   "
767   operands[2]
768     = gen_rtx_REG (SImode,
769                    true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0));
770   operands[3]
771     = (operands[1] == const0_rtx
772        ? const0_rtx
773        : gen_rtx_REG (SImode,
774                       true_regnum (operands[1])
775                       + (TARGET_LITTLE_ENDIAN ? 1 : 0)));
776   operands[4] = gen_lowpart (SImode, operands[0]);
777   operands[5] = gen_lowpart (SImode, operands[1]);
778   operands[6] = gen_label_rtx ();
781 (define_insn "cmpgtdi_t"
782   [(set (reg:SI T_REG)
783         (gt:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
784                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
785   "TARGET_SH2"
786   "@
787         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/gt\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:
788         tst\\t%S0,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/pl\\t%S0\;cmp/hi\\t%S0,%R0\\n%,Ldi%=:"
789   [(set_attr "length" "8")
790    (set_attr "type" "arith3")])
792 (define_insn "cmpgedi_t"
793   [(set (reg:SI T_REG)
794         (ge:SI (match_operand:DI 0 "arith_reg_operand" "r,r")
795                (match_operand:DI 1 "arith_reg_or_0_operand" "r,N")))]
796   "TARGET_SH2"
797   "@
798         cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/ge\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:
799         cmp/pz\\t%S0"
800   [(set_attr "length" "8,2")
801    (set_attr "type" "arith3,mt_group")])
803 ;; -------------------------------------------------------------------------
804 ;; DImode unsigned integer comparisons
805 ;; -------------------------------------------------------------------------
807 (define_insn "cmpgeudi_t"
808   [(set (reg:SI T_REG)
809         (geu:SI (match_operand:DI 0 "arith_reg_operand" "r")
810                 (match_operand:DI 1 "arith_reg_operand" "r")))]
811   "TARGET_SH2"
812   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hs\\t%S1,%S0\;cmp/hs\\t%R1,%R0\\n%,Ldi%=:"
813   [(set_attr "length" "8")
814    (set_attr "type" "arith3")])
816 (define_insn "cmpgtudi_t"
817   [(set (reg:SI T_REG)
818         (gtu:SI (match_operand:DI 0 "arith_reg_operand" "r")
819                 (match_operand:DI 1 "arith_reg_operand" "r")))]
820   "TARGET_SH2"
821   "cmp/eq\\t%S1,%S0\;bf{.|/}s\\t%,Ldi%=\;cmp/hi\\t%S1,%S0\;cmp/hi\\t%R1,%R0\\n%,Ldi%=:"
822   [(set_attr "length" "8")
823    (set_attr "type" "arith3")])
825 (define_insn "cmpeqdi_media"
826   [(set (match_operand:DI 0 "register_operand" "=r")
827         (eq:DI (match_operand:DI 1 "register_operand" "%r")
828                (match_operand:DI 2 "arith_reg_or_0_operand" "Nr")))]
829   "TARGET_SHMEDIA"
830   "cmpeq        %1, %N2, %0"
831   [(set_attr "type" "cmp_media")])
833 (define_insn "cmpgtdi_media"
834   [(set (match_operand:DI 0 "register_operand" "=r")
835         (gt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
836                (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
837   "TARGET_SHMEDIA"
838   "cmpgt        %N1, %N2, %0"
839   [(set_attr "type" "cmp_media")])
841 (define_insn "cmpgtudi_media"
842   [(set (match_operand:DI 0 "register_operand" "=r")
843         (gtu:DI (match_operand:DI 1 "arith_reg_or_0_operand" "Nr")
844                 (match_operand:DI 2 "arith_reg_or_0_operand" "rN")))]
845   "TARGET_SHMEDIA"
846   "cmpgtu       %N1, %N2, %0"
847   [(set_attr "type" "cmp_media")])
849 ;; We save the compare operands in the cmpxx patterns and use them when
850 ;; we generate the branch.
852 (define_expand "cmpdi"
853   [(set (reg:SI T_REG)
854         (compare (match_operand:DI 0 "arith_operand" "")
855                  (match_operand:DI 1 "arith_operand" "")))]
856   "TARGET_SH2 || TARGET_SHMEDIA"
857   "
859   sh_compare_op0 = operands[0];
860   sh_compare_op1 = operands[1];
861   DONE;
863 ;; -------------------------------------------------------------------------
864 ;; Conditional move instructions
865 ;; -------------------------------------------------------------------------
867 ;; The insn names may seem reversed, but note that cmveq performs the move
868 ;; if op1 == 0, and cmvne does it if op1 != 0.
870 (define_insn "movdicc_false"
871   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
872         (if_then_else:DI (eq (match_operand:DI 1 "arith_reg_operand" "r")
873                              (const_int 0))
874          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
875          (match_operand:DI 3 "arith_reg_operand" "0")))]
876   "TARGET_SHMEDIA"
877   "cmveq        %1, %N2, %0"
878   [(set_attr "type" "arith_media")])
880 (define_insn "movdicc_true"
881   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
882         (if_then_else:DI (ne (match_operand:DI 1 "arith_reg_operand" "r")
883                              (const_int 0))
884          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")
885          (match_operand:DI 3 "arith_reg_operand" "0")))]
886   "TARGET_SHMEDIA"
887   "cmvne        %1, %N2, %0"
888   [(set_attr "type" "arith_media")])
890 (define_expand "movdicc"
891   [(set (match_operand:DI 0 "register_operand" "")
892         (if_then_else:DI (match_operand 1 "comparison_operator" "")
893                          (match_operand:DI 2 "register_operand" "")
894                          (match_operand:DI 3 "register_operand" "")))]
895   "TARGET_SHMEDIA"
896   "
898   if ((GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)
899       && GET_MODE (sh_compare_op0) == DImode
900       && sh_compare_op1 == const0_rtx)
901     operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
902                                   sh_compare_op0, sh_compare_op1);
903   else
904     {
905       rtx tmp;
907       if (no_new_pseudos)
908         FAIL;
910       tmp = gen_reg_rtx (DImode);
912       switch (GET_CODE (operands[1]))
913         {
914         case EQ:
915           emit_insn (gen_seq (tmp));
916           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
917           break;
919         case NE:
920           emit_insn (gen_seq (tmp));
921           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
922           break;
924         case GT:
925           emit_insn (gen_sgt (tmp));
926           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
927           break;
929         case LT:
930           emit_insn (gen_slt (tmp));
931           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
932           break;
934         case GE:
935           emit_insn (gen_slt (tmp));
936           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
937           break;
939         case LE:
940           emit_insn (gen_sgt (tmp));
941           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
942           break;
944         case GTU:
945           emit_insn (gen_sgtu (tmp));
946           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
947           break;
949         case LTU:
950           emit_insn (gen_sltu (tmp));
951           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
952           break;
954         case GEU:
955           emit_insn (gen_sltu (tmp));
956           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
957           break;
959         case LEU:
960           emit_insn (gen_sgtu (tmp));
961           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
962           break;
964         case UNORDERED:
965           emit_insn (gen_sunordered (tmp));
966           operands[1] = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
967           break;
969         case ORDERED:
970           emit_insn (gen_sunordered (tmp));
971           operands[1] = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
972           break;
974         case UNEQ:
975         case UNGE:
976         case UNGT:
977         case UNLE:
978         case UNLT:
979         case LTGT:
980           FAIL;
982         default:
983           abort ();
984         }
985     }
988 ;; -------------------------------------------------------------------------
989 ;; Addition instructions
990 ;; -------------------------------------------------------------------------
992 (define_expand "adddi3"
993   [(set (match_operand:DI 0 "arith_reg_operand" "")
994         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
995                  (match_operand:DI 2 "arith_operand" "")))]
996   ""
997   "
999   if (TARGET_SH1)
1000     {
1001       if (no_new_pseudos && ! arith_reg_operand (operands[2], DImode))
1002         FAIL;
1003       operands[2] = force_reg (DImode, operands[2]);
1004       emit_insn (gen_adddi3_compact (operands[0], operands[1], operands[2]));
1005       DONE;
1006     }
1009 (define_insn "*adddi3_media"
1010   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
1011         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
1012                  (match_operand:DI 2 "arith_operand" "r,I10")))]
1013   "TARGET_SHMEDIA"
1014   "@
1015         add     %1, %2, %0
1016         addi    %1, %2, %0"
1017   [(set_attr "type" "arith_media")])
1019 (define_insn "adddi3z_media"
1020   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1021         (zero_extend:DI
1022          (plus:SI (match_operand:SI 1 "extend_reg_operand" "r")
1023                   (match_operand:SI 2 "extend_reg_or_0_operand" "rN"))))]
1024   "TARGET_SHMEDIA"
1025   "addz.l       %1, %N2, %0"
1026   [(set_attr "type" "arith_media")])
1028 (define_insn "adddi3_compact"
1029   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1030         (plus:DI (match_operand:DI 1 "arith_reg_operand" "%0")
1031                  (match_operand:DI 2 "arith_reg_operand" "r")))
1032    (clobber (reg:SI T_REG))]
1033   "TARGET_SH1"
1034   "#"
1035   [(set_attr "length" "6")])
1037 (define_split
1038   [(set (match_operand:DI 0 "arith_reg_operand" "")
1039         (plus:DI (match_operand:DI 1 "arith_reg_operand" "")
1040                  (match_operand:DI 2 "arith_reg_operand" "")))
1041    (clobber (reg:SI T_REG))]
1042   "TARGET_SH1 && reload_completed"
1043   [(const_int 0)]
1044   "
1046   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1047   high0 = gen_rtx_REG (SImode,
1048                        true_regnum (operands[0])
1049                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1050   high2 = gen_rtx_REG (SImode,
1051                        true_regnum (operands[2])
1052                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1053   emit_insn (gen_clrt ());
1054   emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2])));
1055   emit_insn (gen_addc1 (high0, high0, high2));
1056   DONE;
1059 (define_insn "addc"
1060   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1061         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1062                           (match_operand:SI 2 "arith_reg_operand" "r"))
1063                  (reg:SI T_REG)))
1064    (set (reg:SI T_REG)
1065         (ltu:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 1)))]
1066   "TARGET_SH1"
1067   "addc %2,%0"
1068   [(set_attr "type" "arith")])
1070 (define_insn "addc1"
1071   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1072         (plus:SI (plus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1073                           (match_operand:SI 2 "arith_reg_operand" "r"))
1074                  (reg:SI T_REG)))
1075    (clobber (reg:SI T_REG))]
1076   "TARGET_SH1"
1077   "addc %2,%0"
1078   [(set_attr "type" "arith")])
1080 (define_expand "addsi3"
1081   [(set (match_operand:SI 0 "arith_reg_operand" "")
1082         (plus:SI (match_operand:SI 1 "arith_operand" "")
1083                  (match_operand:SI 2 "arith_operand" "")))]
1084   ""
1085   "
1087   if (TARGET_SHMEDIA)
1088     operands[1] = force_reg (SImode, operands[1]);
1091 (define_insn "addsi3_media"
1092   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
1093         (plus:SI (match_operand:SI 1 "extend_reg_operand" "%r,r")
1094                  (match_operand:SI 2 "arith_operand" "r,I10")))]
1095   "TARGET_SHMEDIA"
1096   "@
1097         add.l   %1, %2, %0
1098         addi.l  %1, %2, %0"
1099   [(set_attr "type" "arith_media")])
1101 (define_insn "*addsi3_compact"
1102   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1103         (plus:SI (match_operand:SI 1 "arith_operand" "%0")
1104                  (match_operand:SI 2 "arith_operand" "rI08")))]
1105   "TARGET_SH1"
1106   "add  %2,%0"
1107   [(set_attr "type" "arith")])
1109 ;; -------------------------------------------------------------------------
1110 ;; Subtraction instructions
1111 ;; -------------------------------------------------------------------------
1113 (define_expand "subdi3"
1114   [(set (match_operand:DI 0 "arith_reg_operand" "")
1115         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "")
1116                   (match_operand:DI 2 "arith_reg_operand" "")))]
1117   ""
1118   "
1120   if (TARGET_SH1)
1121     {
1122       operands[1] = force_reg (DImode, operands[1]);
1123       emit_insn (gen_subdi3_compact (operands[0], operands[1], operands[2]));
1124       DONE;
1125     }
1128 (define_insn "*subdi3_media"
1129   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1130         (minus:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rN")
1131                   (match_operand:DI 2 "arith_reg_operand" "r")))]
1132   "TARGET_SHMEDIA"
1133   "sub  %N1, %2, %0"
1134   [(set_attr "type" "arith_media")])
1136 (define_insn "subdi3_compact"
1137   [(set (match_operand:DI 0 "arith_reg_operand" "=&r")
1138         (minus:DI (match_operand:DI 1 "arith_reg_operand" "0")
1139                  (match_operand:DI 2 "arith_reg_operand" "r")))
1140    (clobber (reg:SI T_REG))]
1141   "TARGET_SH1"
1142   "#"
1143   [(set_attr "length" "6")])
1145 (define_split
1146   [(set (match_operand:DI 0 "arith_reg_operand" "")
1147         (minus:DI (match_operand:DI 1 "arith_reg_operand" "")
1148                   (match_operand:DI 2 "arith_reg_operand" "")))
1149    (clobber (reg:SI T_REG))]
1150   "TARGET_SH1 && reload_completed"
1151   [(const_int 0)]
1152   "
1154   rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]);
1155   high0 = gen_rtx_REG (SImode,
1156                        true_regnum (operands[0])
1157                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1158   high2 = gen_rtx_REG (SImode,
1159                        true_regnum (operands[2])
1160                        + (TARGET_LITTLE_ENDIAN ? 1 : 0));
1161   emit_insn (gen_clrt ());
1162   emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2])));
1163   emit_insn (gen_subc1 (high0, high0, high2));
1164   DONE;
1167 (define_insn "subc"
1168   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1169         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1170                             (match_operand:SI 2 "arith_reg_operand" "r"))
1171                   (reg:SI T_REG)))
1172    (set (reg:SI T_REG)
1173         (gtu:SI (minus:SI (minus:SI (match_dup 1) (match_dup 2))
1174                           (reg:SI T_REG))
1175                 (match_dup 1)))]
1176   "TARGET_SH1"
1177   "subc %2,%0"
1178   [(set_attr "type" "arith")])
1180 (define_insn "subc1"
1181   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1182         (minus:SI (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1183                             (match_operand:SI 2 "arith_reg_operand" "r"))
1184                   (reg:SI T_REG)))
1185    (clobber (reg:SI T_REG))]
1186   "TARGET_SH1"
1187   "subc %2,%0"
1188   [(set_attr "type" "arith")])
1190 (define_insn "*subsi3_internal"
1191   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1192         (minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
1193                   (match_operand:SI 2 "arith_reg_operand" "r")))]
1194   "TARGET_SH1"
1195   "sub  %2,%0"
1196   [(set_attr "type" "arith")])
1198 (define_insn "*subsi3_media"
1199   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
1200         (minus:SI (match_operand:SI 1 "extend_reg_or_0_operand" "rN")
1201                   (match_operand:SI 2 "extend_reg_operand" "r")))]
1202   "TARGET_SHMEDIA"
1203   "sub.l        %N1, %2, %0"
1204   [(set_attr "type" "arith_media")])
1206 ;; Convert `constant - reg' to `neg rX; add rX, #const' since this
1207 ;; will sometimes save one instruction.  Otherwise we might get
1208 ;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
1209 ;; are the same.
1211 (define_expand "subsi3"
1212   [(set (match_operand:SI 0 "arith_reg_operand" "")
1213         (minus:SI (match_operand:SI 1 "arith_operand" "")
1214                   (match_operand:SI 2 "arith_reg_operand" "")))]
1215   ""
1216   "
1218   if (TARGET_SH1 && GET_CODE (operands[1]) == CONST_INT)
1219     {
1220       emit_insn (gen_negsi2 (operands[0], operands[2]));
1221       emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
1222       DONE;
1223     }
1224   if (TARGET_SHMEDIA)
1225     {
1226       if (no_new_pseudos && ! arith_reg_or_0_operand (operands[1], SImode))
1227         FAIL;
1228       if (operands[1] != const0_rtx)
1229         operands[1] = force_reg (SImode, operands[1]);
1230     }
1233 ;; -------------------------------------------------------------------------
1234 ;; Division instructions
1235 ;; -------------------------------------------------------------------------
1237 ;; We take advantage of the library routines which don't clobber as many
1238 ;; registers as a normal function call would.
1240 ;; The INSN_REFERENCES_ARE_DELAYED in sh.h is problematic because it
1241 ;; also has an effect on the register that holds the address of the sfunc.
1242 ;; To make this work, we have an extra dummy insn that shows the use
1243 ;; of this register for reorg.
1245 (define_insn "use_sfunc_addr"
1246   [(set (reg:SI PR_REG)
1247         (unspec:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_SFUNC))]
1248   "TARGET_SH1 && check_use_sfunc_addr (insn, operands[0])"
1249   ""
1250   [(set_attr "length" "0")])
1252 ;; We must use a pseudo-reg forced to reg 0 in the SET_DEST rather than
1253 ;; hard register 0.  If we used hard register 0, then the next instruction
1254 ;; would be a move from hard register 0 to a pseudo-reg.  If the pseudo-reg
1255 ;; gets allocated to a stack slot that needs its address reloaded, then
1256 ;; there is nothing to prevent reload from using r0 to reload the address.
1257 ;; This reload would clobber the value in r0 we are trying to store.
1258 ;; If we let reload allocate r0, then this problem can never happen.
1260 (define_insn "udivsi3_i1"
1261   [(set (match_operand:SI 0 "register_operand" "=z")
1262         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1263    (clobber (reg:SI T_REG))
1264    (clobber (reg:SI PR_REG))
1265    (clobber (reg:SI R4_REG))
1266    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1267   "TARGET_SH1 && ! TARGET_SH4"
1268   "jsr  @%1%#"
1269   [(set_attr "type" "sfunc")
1270    (set_attr "needs_delay_slot" "yes")])
1272 ; Since shmedia-nofpu code could be linked against shcompact code, and
1273 ; the udivsi3 libcall has the same name, we must consider all registers
1274 ; clobbered that are in the union of the registers clobbered by the
1275 ; shmedia and the shcompact implementation.  Note, if the shcompact
1276 ; implementation actually used shcompact code, we'd need to clobber
1277 ; also r23 and fr23.
1278 (define_insn "udivsi3_i1_media"
1279   [(set (match_operand:SI 0 "register_operand" "=z")
1280         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1281    (clobber (reg:SI T_MEDIA_REG))
1282    (clobber (reg:SI PR_MEDIA_REG))
1283    (clobber (reg:SI R20_REG))
1284    (clobber (reg:SI R21_REG))
1285    (clobber (reg:SI R22_REG))
1286    (clobber (reg:DI TR0_REG))
1287    (clobber (reg:DI TR1_REG))
1288    (clobber (reg:DI TR2_REG))
1289    (use (match_operand:DI 1 "target_operand" "b"))]
1290   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1291   "blink        %1, r18"
1292   [(set_attr "type" "sfunc")
1293    (set_attr "needs_delay_slot" "yes")])
1295 (define_expand "udivsi3_i4_media"
1296   [(set (match_dup 3)
1297         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
1298    (set (match_dup 4)
1299         (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1300    (set (match_dup 5) (float:DF (match_dup 3)))
1301    (set (match_dup 6) (float:DF (match_dup 4)))
1302    (set (match_dup 7) (div:DF (match_dup 5) (match_dup 6)))
1303    (set (match_dup 8) (fix:DI (match_dup 7)))
1304    (set (match_operand:SI 0 "register_operand" "")
1305         (truncate:SI (match_dup 8)))]
1306   "TARGET_SHMEDIA_FPU"
1307   "
1309   operands[3] = gen_reg_rtx (DImode);
1310   operands[4] = gen_reg_rtx (DImode);
1311   operands[5] = gen_reg_rtx (DFmode);
1312   operands[6] = gen_reg_rtx (DFmode);
1313   operands[7] = gen_reg_rtx (DFmode);
1314   operands[8] = gen_reg_rtx (DImode);
1317 (define_insn "udivsi3_i4"
1318   [(set (match_operand:SI 0 "register_operand" "=y")
1319         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1320    (clobber (reg:SI T_REG))
1321    (clobber (reg:SI PR_REG))
1322    (clobber (reg:DF DR0_REG))
1323    (clobber (reg:DF DR2_REG))
1324    (clobber (reg:DF DR4_REG))
1325    (clobber (reg:SI R0_REG))
1326    (clobber (reg:SI R1_REG))
1327    (clobber (reg:SI R4_REG))
1328    (clobber (reg:SI R5_REG))
1329    (use (reg:PSI FPSCR_REG))
1330    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1331   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1332   "jsr  @%1%#"
1333   [(set_attr "type" "sfunc")
1334    (set_attr "fp_mode" "double")
1335    (set_attr "needs_delay_slot" "yes")])
1337 (define_insn "udivsi3_i4_single"
1338   [(set (match_operand:SI 0 "register_operand" "=y")
1339         (udiv:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1340    (clobber (reg:SI T_REG))
1341    (clobber (reg:SI PR_REG))
1342    (clobber (reg:DF DR0_REG))
1343    (clobber (reg:DF DR2_REG))
1344    (clobber (reg:DF DR4_REG))
1345    (clobber (reg:SI R0_REG))
1346    (clobber (reg:SI R1_REG))
1347    (clobber (reg:SI R4_REG))
1348    (clobber (reg:SI R5_REG))
1349    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1350   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1351   "jsr  @%1%#"
1352   [(set_attr "type" "sfunc")
1353    (set_attr "needs_delay_slot" "yes")])
1355 (define_expand "udivsi3"
1356   [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
1357    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1358    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1359    (parallel [(set (match_operand:SI 0 "register_operand" "")
1360                    (udiv:SI (reg:SI R4_REG)
1361                             (reg:SI R5_REG)))
1362               (clobber (reg:SI T_REG))
1363               (clobber (reg:SI PR_REG))
1364               (clobber (reg:SI R4_REG))
1365               (use (match_dup 3))])]
1366   ""
1367   "
1369   rtx first, last;
1371   operands[3] = gen_reg_rtx (Pmode);
1372   /* Emit the move of the address to a pseudo outside of the libcall.  */
1373   if (TARGET_HARD_SH4 && TARGET_SH2E)
1374     {
1375       emit_move_insn (operands[3], function_symbol (\"__udivsi3_i4\"));
1376       if (TARGET_FPU_SINGLE)
1377         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1378       else
1379         last = gen_udivsi3_i4 (operands[0], operands[3]);
1380     }
1381   else if (TARGET_SHMEDIA_FPU)
1382     {
1383       operands[1] = force_reg (SImode, operands[1]);
1384       operands[2] = force_reg (SImode, operands[2]);
1385       emit_insn (gen_udivsi3_i4_media (operands[0], operands[1], operands[2]));
1386       DONE;
1387     }
1388   else if (TARGET_SH5)
1389     {
1390       emit_move_insn (operands[3],
1391                       function_symbol (TARGET_FPU_ANY
1392                                        ? \"__udivsi3_i4\"
1393                                        : \"__udivsi3\"));
1395       if (TARGET_SHMEDIA)
1396         last = gen_udivsi3_i1_media (operands[0],
1397                                      Pmode == DImode
1398                                      ? operands[3]
1399                                      : gen_rtx_SUBREG (DImode, operands[3],
1400                                                        0));
1401       else if (TARGET_FPU_ANY)
1402         last = gen_udivsi3_i4_single (operands[0], operands[3]);
1403       else
1404         last = gen_udivsi3_i1 (operands[0], operands[3]);
1405     }
1406   else
1407     {
1408       emit_move_insn (operands[3], function_symbol (\"__udivsi3\"));
1409       last = gen_udivsi3_i1 (operands[0], operands[3]);
1410     }
1411   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1412   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1413   last = emit_insn (last);
1414   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1415      invariant code motion can move it.  */
1416   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1417   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1418   DONE;
1421 (define_insn "divsi3_i1"
1422   [(set (match_operand:SI 0 "register_operand" "=z")
1423         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1424    (clobber (reg:SI T_REG))
1425    (clobber (reg:SI PR_REG))
1426    (clobber (reg:SI R1_REG))
1427    (clobber (reg:SI R2_REG))
1428    (clobber (reg:SI R3_REG))
1429    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1430   "TARGET_SH1 && ! TARGET_SH4"
1431   "jsr  @%1%#"
1432   [(set_attr "type" "sfunc")
1433    (set_attr "needs_delay_slot" "yes")])
1435 ; Since shmedia-nofpu code could be linked against shcompact code, and
1436 ; the sdivsi3 libcall has the same name, we must consider all registers
1437 ; clobbered that are in the union of the registers clobbered by the
1438 ; shmedia and the shcompact implementation.  Note, if the shcompact
1439 ; implementation actually used shcompact code, we'd need to clobber
1440 ; also r22, r23 and fr23.
1441 (define_insn "divsi3_i1_media"
1442   [(set (match_operand:SI 0 "register_operand" "=z")
1443         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1444    (clobber (reg:SI T_MEDIA_REG))
1445    (clobber (reg:SI PR_MEDIA_REG))
1446    (clobber (reg:SI R1_REG))
1447    (clobber (reg:SI R2_REG))
1448    (clobber (reg:SI R3_REG))
1449    (clobber (reg:SI R20_REG))
1450    (clobber (reg:SI R21_REG))
1451    (clobber (reg:DI TR0_REG))
1452    (clobber (reg:DI TR1_REG))
1453    (clobber (reg:DI TR2_REG))
1454    (use (match_operand:DI 1 "target_operand" "b"))]
1455   "TARGET_SHMEDIA && ! TARGET_SHMEDIA_FPU"
1456   "blink        %1, r18"
1457   [(set_attr "type" "sfunc")])
1459 (define_expand "divsi3_i4_media"
1460   [(set (match_dup 3) (float:DF (match_operand:SI 1 "register_operand" "r")))
1461    (set (match_dup 4) (float:DF (match_operand:SI 2 "register_operand" "r")))
1462    (set (match_dup 5) (div:DF (match_dup 3) (match_dup 4)))
1463    (set (match_operand:SI 0 "register_operand" "=r")
1464         (fix:SI (match_dup 5)))]
1465   "TARGET_SHMEDIA_FPU"
1466   "
1468   operands[3] = gen_reg_rtx (DFmode);
1469   operands[4] = gen_reg_rtx (DFmode);
1470   operands[5] = gen_reg_rtx (DFmode);
1473 (define_insn "divsi3_i4"
1474   [(set (match_operand:SI 0 "register_operand" "=y")
1475         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1476    (clobber (reg:SI PR_REG))
1477    (clobber (reg:DF DR0_REG))
1478    (clobber (reg:DF DR2_REG))
1479    (use (reg:PSI FPSCR_REG))
1480    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1481   "TARGET_SH4 && ! TARGET_FPU_SINGLE"
1482   "jsr  @%1%#"
1483   [(set_attr "type" "sfunc")
1484    (set_attr "fp_mode" "double")
1485    (set_attr "needs_delay_slot" "yes")])
1487 (define_insn "divsi3_i4_single"
1488   [(set (match_operand:SI 0 "register_operand" "=y")
1489         (div:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1490    (clobber (reg:SI PR_REG))
1491    (clobber (reg:DF DR0_REG))
1492    (clobber (reg:DF DR2_REG))
1493    (clobber (reg:SI R2_REG))
1494    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
1495   "(TARGET_HARD_SH4 || TARGET_SHCOMPACT) && TARGET_FPU_SINGLE"
1496   "jsr  @%1%#"
1497   [(set_attr "type" "sfunc")
1498    (set_attr "needs_delay_slot" "yes")])
1500 (define_expand "divsi3"
1501   [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
1502    (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1503    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1504    (parallel [(set (match_operand:SI 0 "register_operand" "")
1505                    (div:SI (reg:SI R4_REG)
1506                            (reg:SI R5_REG)))
1507               (clobber (reg:SI T_REG))
1508               (clobber (reg:SI PR_REG))
1509               (clobber (reg:SI R1_REG))
1510               (clobber (reg:SI R2_REG))
1511               (clobber (reg:SI R3_REG))
1512               (use (match_dup 3))])]
1513   ""
1514   "
1516   rtx first, last;
1518   operands[3] = gen_reg_rtx (Pmode);
1519   /* Emit the move of the address to a pseudo outside of the libcall.  */
1520   if (TARGET_HARD_SH4 && TARGET_SH2E)
1521     {
1522       emit_move_insn (operands[3], function_symbol (\"__sdivsi3_i4\"));
1523       if (TARGET_FPU_SINGLE)
1524         last = gen_divsi3_i4_single (operands[0], operands[3]);
1525       else
1526         last = gen_divsi3_i4 (operands[0], operands[3]);
1527     }
1528   else if (TARGET_SHMEDIA_FPU)
1529     {
1530       operands[1] = force_reg (SImode, operands[1]);
1531       operands[2] = force_reg (SImode, operands[2]);
1532       emit_insn (gen_divsi3_i4_media (operands[0], operands[1], operands[2]));
1533       DONE;
1534     }
1535   else if (TARGET_SH5)
1536     {
1537       emit_move_insn (operands[3],
1538                       function_symbol (TARGET_FPU_ANY
1539                                        ? \"__sdivsi3_i4\"
1540                                        : \"__sdivsi3\"));
1542       if (TARGET_SHMEDIA)
1543         last = gen_divsi3_i1_media (operands[0],
1544                                     Pmode == DImode
1545                                     ? operands[3]
1546                                     : gen_rtx_SUBREG (DImode, operands[3],
1547                                                       0));
1548       else if (TARGET_FPU_ANY)
1549         last = gen_divsi3_i4_single (operands[0], operands[3]);
1550       else
1551         last = gen_divsi3_i1 (operands[0], operands[3]);
1552     }
1553   else
1554     {
1555       emit_move_insn (operands[3], function_symbol (\"__sdivsi3\"));
1556       last = gen_divsi3_i1 (operands[0], operands[3]);
1557     }
1558   first = emit_move_insn (gen_rtx_REG (SImode, 4), operands[1]);
1559   emit_move_insn (gen_rtx_REG (SImode, 5), operands[2]);
1560   last = emit_insn (last);
1561   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1562      invariant code motion can move it.  */
1563   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1564   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1565   DONE;
1568 ;; -------------------------------------------------------------------------
1569 ;; Multiplication instructions
1570 ;; -------------------------------------------------------------------------
1572 (define_insn "umulhisi3_i"
1573   [(set (reg:SI MACL_REG)
1574         (mult:SI (zero_extend:SI
1575                   (match_operand:HI 0 "arith_reg_operand" "r"))
1576                  (zero_extend:SI
1577                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1578   "TARGET_SH1"
1579   "mulu.w       %1,%0"
1580   [(set_attr "type" "smpy")])
1582 (define_insn "mulhisi3_i"
1583   [(set (reg:SI MACL_REG)
1584         (mult:SI (sign_extend:SI
1585                   (match_operand:HI 0 "arith_reg_operand" "r"))
1586                  (sign_extend:SI
1587                   (match_operand:HI 1 "arith_reg_operand" "r"))))]
1588   "TARGET_SH1"
1589   "muls.w       %1,%0"
1590   [(set_attr "type" "smpy")])
1592 (define_expand "mulhisi3"
1593   [(set (reg:SI MACL_REG)
1594         (mult:SI (sign_extend:SI
1595                   (match_operand:HI 1 "arith_reg_operand" ""))
1596                  (sign_extend:SI
1597                   (match_operand:HI 2 "arith_reg_operand" ""))))
1598    (set (match_operand:SI 0 "arith_reg_operand" "")
1599         (reg:SI MACL_REG))]
1600   "TARGET_SH1"
1601   "
1603   rtx first, last;
1605   first = emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
1606   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1607   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1608      invariant code motion can move it.  */
1609   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1610   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1611   /* expand_binop can't find a suitable code in umul_widen_optab to
1612      make a REG_EQUAL note from, so make one here.
1613      See also smulsi3_highpart.
1614      ??? Alternatively, we could put this at the calling site of expand_binop,
1615      i.e. expand_expr.  */
1616   REG_NOTES (last)
1617     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1618                          REG_NOTES (last));
1619   DONE;
1622 (define_expand "umulhisi3"
1623   [(set (reg:SI MACL_REG)
1624         (mult:SI (zero_extend:SI
1625                   (match_operand:HI 1 "arith_reg_operand" ""))
1626                  (zero_extend:SI
1627                   (match_operand:HI 2 "arith_reg_operand" ""))))
1628    (set (match_operand:SI 0 "arith_reg_operand" "")
1629         (reg:SI MACL_REG))]
1630   "TARGET_SH1"
1631   "
1633   rtx first, last;
1635   first = emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
1636   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
1637   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1638      invariant code motion can move it.  */
1639   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1640   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1641   /* expand_binop can't find a suitable code in umul_widen_optab to
1642      make a REG_EQUAL note from, so make one here.
1643      See also smulsi3_highpart.
1644      ??? Alternatively, we could put this at the calling site of expand_binop,
1645      i.e. expand_expr.  */
1646   REG_NOTES (last)
1647     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1648                          REG_NOTES (last));
1649   DONE;
1652 ;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
1653 ;; a call to a routine which clobbers known registers.
1655 (define_insn ""
1656   [(set (match_operand:SI 1 "register_operand" "=z")
1657         (mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
1658    (clobber (reg:SI MACL_REG))
1659    (clobber (reg:SI T_REG))
1660    (clobber (reg:SI PR_REG))
1661    (clobber (reg:SI R3_REG))
1662    (clobber (reg:SI R2_REG))
1663    (clobber (reg:SI R1_REG))
1664    (use (match_operand:SI 0 "arith_reg_operand" "r"))]
1665   "TARGET_SH1"
1666   "jsr  @%0%#"
1667   [(set_attr "type" "sfunc")
1668    (set_attr "needs_delay_slot" "yes")])
1670 (define_expand "mulsi3_call"
1671   [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
1672    (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
1673    (parallel[(set (match_operand:SI 0 "register_operand" "")
1674                   (mult:SI (reg:SI R4_REG)
1675                            (reg:SI R5_REG)))
1676              (clobber (reg:SI MACL_REG))
1677              (clobber (reg:SI T_REG))
1678              (clobber (reg:SI PR_REG))
1679              (clobber (reg:SI R3_REG))
1680              (clobber (reg:SI R2_REG))
1681              (clobber (reg:SI R1_REG))
1682              (use (match_operand:SI 3 "register_operand" ""))])]
1683   "TARGET_SH1"
1684   "")
1686 (define_insn "mul_l"
1687   [(set (reg:SI MACL_REG)
1688         (mult:SI (match_operand:SI 0 "arith_reg_operand" "r")
1689                  (match_operand:SI 1 "arith_reg_operand" "r")))]
1690   "TARGET_SH2"
1691   "mul.l        %1,%0"
1692   [(set_attr "type" "dmpy")])
1694 (define_expand "mulsi3"
1695   [(set (reg:SI MACL_REG)
1696         (mult:SI  (match_operand:SI 1 "arith_reg_operand" "")
1697                   (match_operand:SI 2 "arith_reg_operand" "")))
1698    (set (match_operand:SI 0 "arith_reg_operand" "")
1699         (reg:SI MACL_REG))]
1700   "TARGET_SH1"
1701   "
1703   rtx first, last;
1705   if (!TARGET_SH2)
1706     {
1707       /* The address must be set outside the libcall,
1708          since it goes into a pseudo.  */
1709       rtx sym = function_symbol (\"__mulsi3\");
1710       rtx addr = force_reg (SImode, sym);
1711       rtx insns = gen_mulsi3_call (operands[0], operands[1],
1712                                    operands[2], addr);
1713       first = insns;
1714       last = emit_insn (insns);
1715     }
1716   else
1717     {
1718       rtx macl = gen_rtx_REG (SImode, MACL_REG);
1720       first = emit_insn (gen_mul_l (operands[1], operands[2]));
1721       /* consec_sets_giv can only recognize the first insn that sets a
1722          giv as the giv insn.  So we must tag this also with a REG_EQUAL
1723          note.  */
1724       last = emit_insn (gen_movsi_i ((operands[0]), macl));
1725     }
1726   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1727      invariant code motion can move it.  */
1728   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1729   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1730   DONE;
1733 (define_insn "mulsidi3_i"
1734   [(set (reg:SI MACH_REG)
1735         (truncate:SI
1736          (lshiftrt:DI
1737           (mult:DI
1738            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1739            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1740           (const_int 32))))
1741    (set (reg:SI MACL_REG)
1742         (mult:SI (match_dup 0)
1743                  (match_dup 1)))]
1744   "TARGET_SH2"
1745   "dmuls.l      %1,%0"
1746   [(set_attr "type" "dmpy")])
1748 (define_expand "mulsidi3"
1749   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1750         (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1751                  (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1752   "TARGET_SH2 || TARGET_SHMEDIA"
1753   "
1755   if (TARGET_SH2)
1756     {
1757        emit_insn (gen_mulsidi3_compact (operands[0], operands[1],
1758                                         operands[2]));
1759        DONE;
1760     }
1763 (define_insn "mulsidi3_media"
1764   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1765         (mult:DI (sign_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1766                  (sign_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1767   "TARGET_SHMEDIA"
1768   "muls.l       %1, %2, %0"
1769   [(set_attr "type" "dmpy_media")])
1771 (define_insn "mulsidi3_compact"
1772   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1773         (mult:DI
1774          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1775          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1776    (clobber (reg:SI MACH_REG))
1777    (clobber (reg:SI MACL_REG))]
1778   "TARGET_SH2"
1779   "#")
1781 (define_split
1782   [(set (match_operand:DI 0 "arith_reg_operand" "")
1783         (mult:DI
1784          (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1785          (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1786    (clobber (reg:SI MACH_REG))
1787    (clobber (reg:SI MACL_REG))]
1788   "TARGET_SH2"
1789   [(const_int 0)]
1790   "
1792   rtx low_dst = gen_lowpart (SImode, operands[0]);
1793   rtx high_dst = gen_highpart (SImode, operands[0]);
1795   emit_insn (gen_mulsidi3_i (operands[1], operands[2]));
1797   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1798   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1799   /* We need something to tag the possible REG_EQUAL notes on to.  */
1800   emit_move_insn (operands[0], operands[0]);
1801   DONE;
1804 (define_insn "umulsidi3_i"
1805   [(set (reg:SI MACH_REG)
1806         (truncate:SI
1807          (lshiftrt:DI
1808           (mult:DI
1809            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1810            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1811           (const_int 32))))
1812    (set (reg:SI MACL_REG)
1813         (mult:SI (match_dup 0)
1814                  (match_dup 1)))]
1815   "TARGET_SH2"
1816   "dmulu.l      %1,%0"
1817   [(set_attr "type" "dmpy")])
1819 (define_expand "umulsidi3"
1820   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1821         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1822                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))]
1823   "TARGET_SH2 || TARGET_SHMEDIA"
1824   "
1826   if (TARGET_SH2)
1827     {
1828        emit_insn (gen_umulsidi3_compact (operands[0], operands[1],
1829                                          operands[2]));
1830        DONE;
1831     }
1834 (define_insn "umulsidi3_media"
1835   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1836         (mult:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "%r"))
1837                  (zero_extend:DI (match_operand:SI 2 "extend_reg_operand" "r"))))]
1838   "TARGET_SHMEDIA"
1839   "mulu.l       %1, %2, %0"
1840   [(set_attr "type" "dmpy_media")])
1842 (define_insn "umulsidi3_compact"
1843   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
1844         (mult:DI
1845          (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
1846          (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
1847    (clobber (reg:SI MACH_REG))
1848    (clobber (reg:SI MACL_REG))]
1849   "TARGET_SH2"
1850   "#")
1852 (define_split
1853   [(set (match_operand:DI 0 "arith_reg_operand" "")
1854         (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1855                  (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))
1856    (clobber (reg:SI MACH_REG))
1857    (clobber (reg:SI MACL_REG))]
1858   "TARGET_SH2"
1859   [(const_int 0)]
1860   "
1862   rtx low_dst = gen_lowpart (SImode, operands[0]);
1863   rtx high_dst = gen_highpart (SImode, operands[0]);
1865   emit_insn (gen_umulsidi3_i (operands[1], operands[2]));
1867   emit_move_insn (low_dst, gen_rtx_REG (SImode, MACL_REG));
1868   emit_move_insn (high_dst, gen_rtx_REG (SImode, MACH_REG));
1869   /* We need something to tag the possible REG_EQUAL notes on to.  */
1870   emit_move_insn (operands[0], operands[0]);
1871   DONE;
1874 (define_insn "smulsi3_highpart_i"
1875   [(set (reg:SI MACH_REG)
1876         (truncate:SI
1877          (lshiftrt:DI
1878           (mult:DI
1879            (sign_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1880            (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1881           (const_int 32))))
1882    (clobber (reg:SI MACL_REG))]
1883   "TARGET_SH2"
1884   "dmuls.l      %1,%0"
1885   [(set_attr "type" "dmpy")])
1887 (define_expand "smulsi3_highpart"
1888   [(parallel
1889     [(set (reg:SI MACH_REG)
1890           (truncate:SI
1891            (lshiftrt:DI
1892             (mult:DI
1893              (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1894              (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1895             (const_int 32))))
1896     (clobber (reg:SI MACL_REG))])
1897    (set (match_operand:SI 0 "arith_reg_operand" "")
1898         (reg:SI MACH_REG))]
1899   "TARGET_SH2"
1900   "
1902   rtx first, last;
1904   first = emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
1905   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1906   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1907      invariant code motion can move it.  */
1908   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1909   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1910   /* expand_binop can't find a suitable code in mul_highpart_optab to
1911      make a REG_EQUAL note from, so make one here.
1912      See also {,u}mulhisi.
1913      ??? Alternatively, we could put this at the calling site of expand_binop,
1914      i.e. expand_mult_highpart.  */
1915   REG_NOTES (last)
1916     = gen_rtx_EXPR_LIST (REG_EQUAL, copy_rtx (SET_SRC (single_set (first))),
1917                          REG_NOTES (last));
1918   DONE;
1921 (define_insn "umulsi3_highpart_i"
1922   [(set (reg:SI MACH_REG)
1923         (truncate:SI
1924          (lshiftrt:DI
1925           (mult:DI
1926            (zero_extend:DI (match_operand:SI 0 "arith_reg_operand" "r"))
1927            (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r")))
1928           (const_int 32))))
1929    (clobber (reg:SI MACL_REG))]
1930   "TARGET_SH2"
1931   "dmulu.l      %1,%0"
1932   [(set_attr "type" "dmpy")])
1934 (define_expand "umulsi3_highpart"
1935   [(parallel
1936     [(set (reg:SI MACH_REG)
1937           (truncate:SI
1938            (lshiftrt:DI
1939             (mult:DI
1940              (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
1941              (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
1942             (const_int 32))))
1943     (clobber (reg:SI MACL_REG))])
1944    (set (match_operand:SI 0 "arith_reg_operand" "")
1945         (reg:SI MACH_REG))]
1946   "TARGET_SH2"
1947   "
1949   rtx first, last;
1951   first = emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
1952   last = emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
1953   /* Wrap the sequence in REG_LIBCALL / REG_RETVAL notes so that loop
1954      invariant code motion can move it.  */
1955   REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last, REG_NOTES (first));
1956   REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
1957   DONE;
1960 ;; -------------------------------------------------------------------------
1961 ;; Logical operations
1962 ;; -------------------------------------------------------------------------
1964 (define_insn "*andsi3_compact"
1965   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
1966         (and:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
1967                 (match_operand:SI 2 "logical_operand" "r,K08")))]
1968   "TARGET_SH1"
1969   "and  %2,%0"
1970   [(set_attr "type" "arith")])
1972 ;; If the constant is 255, then emit an extu.b instruction instead of an
1973 ;; and, since that will give better code.
1975 (define_expand "andsi3"
1976   [(set (match_operand:SI 0 "arith_reg_operand" "")
1977         (and:SI (match_operand:SI 1 "arith_reg_operand" "")
1978                 (match_operand:SI 2 "logical_operand" "")))]
1979   "TARGET_SH1"
1980   "
1982   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 255)
1983     {
1984       emit_insn (gen_zero_extendqisi2 (operands[0],
1985                                        gen_lowpart (QImode, operands[1])));
1986       DONE;
1987     }
1990 (define_insn_and_split "anddi3"
1991   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r,r")
1992         (and:DI (match_operand:DI 1 "arith_reg_operand" "%r,r,r")
1993                 (match_operand:DI 2 "and_operand" "r,I10,J16")))]
1994   "TARGET_SHMEDIA"
1995   "@
1996         and     %1, %2, %0
1997         andi    %1, %2, %0
1998         #"
1999   "reload_completed
2000    && ! logical_operand (operands[2], DImode)"
2001   [(const_int 0)]
2002   "
2004   if (INTVAL (operands[2]) == (unsigned) 0xffffffff)
2005     emit_insn (gen_mshflo_l_di (operands[0], operands[1], CONST0_RTX (DImode)));
2006   else
2007     emit_insn (gen_mshfhi_l_di (operands[0], CONST0_RTX (DImode), operands[1]));
2008   DONE;
2010   [(set_attr "type" "arith_media")])
2012 (define_insn "andcdi3"
2013   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2014         (and:DI (match_operand:DI 1 "arith_reg_operand" "r")
2015                 (not:DI (match_operand:DI 2 "arith_reg_operand" "r"))))]
2016   "TARGET_SHMEDIA"
2017   "andc %1,%2,%0"
2018   [(set_attr "type" "arith_media")])
2020 (define_insn "iorsi3"
2021   [(set (match_operand:SI 0 "arith_reg_operand" "=r,z")
2022         (ior:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2023                 (match_operand:SI 2 "logical_operand" "r,K08")))]
2024   "TARGET_SH1"
2025   "or   %2,%0"
2026   [(set_attr "type" "arith")])
2028 (define_insn "iordi3"
2029   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2030         (ior:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2031                 (match_operand:DI 2 "logical_operand" "r,I10")))]
2032   "TARGET_SHMEDIA"
2033   "@
2034         or      %1, %2, %0
2035         ori     %1, %2, %0"
2036   [(set_attr "type" "arith_media")])
2038 (define_insn "xorsi3"
2039   [(set (match_operand:SI 0 "arith_reg_operand" "=z,r")
2040         (xor:SI (match_operand:SI 1 "arith_reg_operand" "%0,0")
2041                 (match_operand:SI 2 "logical_operand" "K08,r")))]
2042   "TARGET_SH1"
2043   "xor  %2,%0"
2044   [(set_attr "type" "arith")])
2046 (define_insn "xordi3"
2047   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2048         (xor:DI (match_operand:DI 1 "arith_reg_operand" "%r,r")
2049                 (match_operand:DI 2 "shmedia_6bit_operand" "r,I06")))]
2050   "TARGET_SHMEDIA"
2051   "@
2052         xor     %1, %2, %0
2053         xori    %1, %2, %0"
2054   [(set_attr "type" "arith_media")])
2056 ;; Combiner bridge pattern for 2 * sign extend -> logical op -> truncate.
2057 ;; converts 2 * sign extend -> logical op into logical op -> sign extend
2058 (define_split
2059   [(set (match_operand:DI 0 "arith_reg_operand" "")
2060         (sign_extend:DI (match_operator 4 "binary_logical_operator"
2061                           [(match_operand 1 "any_register_operand" "")
2062                            (match_operand 2 "any_register_operand" "")])))]
2063   "TARGET_SHMEDIA"
2064   [(set (match_dup 5) (match_dup 4))
2065    (set (match_dup 0) (sign_extend:DI (match_dup 5)))]
2068   enum machine_mode inmode = GET_MODE (operands[1]);
2069   int offset = 0;
2071   if (GET_CODE (operands[0]) == SUBREG)
2072     {
2073       offset = SUBREG_BYTE (operands[0]);
2074       operands[0] = SUBREG_REG (operands[0]);
2075     }
2076   if (GET_CODE (operands[0]) != REG)
2077     abort ();
2078   if (! TARGET_LITTLE_ENDIAN)
2079     offset += 8 - GET_MODE_SIZE (inmode);
2080   operands[5] = gen_rtx_SUBREG (inmode, operands[0], offset);
2083 ;; -------------------------------------------------------------------------
2084 ;; Shifts and rotates
2085 ;; -------------------------------------------------------------------------
2087 (define_expand "rotldi3"
2088   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2089         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2090                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2091   "TARGET_SHMEDIA"
2092   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2094 (define_insn "rotldi3_mextr"
2095   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2096         (rotate:DI (match_operand:DI 1 "arith_reg_operand" "r")
2097                    (match_operand:HI 2 "mextr_bit_offset" "i")))]
2098   "TARGET_SHMEDIA"
2099   "*
2101   static char templ[16];
2103   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\",
2104            8 - (int) (INTVAL (operands[2]) >> 3));
2105   return templ;
2107   [(set_attr "type" "arith_media")])
2109 (define_expand "rotrdi3"
2110   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2111         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2112                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2113   "TARGET_SHMEDIA"
2114   "if (! mextr_bit_offset (operands[2], HImode)) FAIL;")
2116 (define_insn "rotrdi3_mextr"
2117   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
2118         (rotatert:DI (match_operand:DI 1 "arith_reg_operand" "r")
2119                      (match_operand:HI 2 "mextr_bit_offset" "i")))]
2120   "TARGET_SHMEDIA"
2121   "*
2123   static char templ[16];
2125   sprintf (templ, \"mextr%d\\t%%1,%%1,%%0\", (int) INTVAL (operands[2]) >> 3);
2126   return templ;
2128   [(set_attr "type" "arith_media")])
2130 (define_insn "rotlsi3_1"
2131   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2132         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2133                    (const_int 1)))
2134    (set (reg:SI T_REG)
2135         (lshiftrt:SI (match_dup 1) (const_int 31)))]
2136   "TARGET_SH1"
2137   "rotl %0"
2138   [(set_attr "type" "arith")])
2140 (define_insn "rotlsi3_31"
2141   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2142         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "0")
2143                    (const_int 31)))
2144    (clobber (reg:SI T_REG))]
2145   "TARGET_SH1"
2146   "rotr %0"
2147   [(set_attr "type" "arith")])
2149 (define_insn "rotlsi3_16"
2150   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2151         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "r")
2152                    (const_int 16)))]
2153   "TARGET_SH1"
2154   "swap.w       %1,%0"
2155   [(set_attr "type" "arith")])
2157 (define_expand "rotlsi3"
2158   [(set (match_operand:SI 0 "arith_reg_operand" "")
2159         (rotate:SI (match_operand:SI 1 "arith_reg_operand" "")
2160                    (match_operand:SI 2 "immediate_operand" "")))]
2161   "TARGET_SH1"
2162   "
2164   static const char rot_tab[] = {
2165     000, 000, 000, 000, 000, 000, 010, 001,
2166     001, 001, 011, 013, 003, 003, 003, 003,
2167     003, 003, 003, 003, 003, 013, 012, 002,
2168     002, 002, 010, 000, 000, 000, 000, 000,
2169   };
2171   int count, choice;
2173   if (GET_CODE (operands[2]) != CONST_INT)
2174     FAIL;
2175   count = INTVAL (operands[2]);
2176   choice = rot_tab[count];
2177   if (choice & 010 && SH_DYNAMIC_SHIFT_COST <= 1)
2178     FAIL;
2179   choice &= 7;
2180   switch (choice)
2181     {
2182     case 0:
2183       emit_move_insn (operands[0], operands[1]);
2184       count -= (count & 16) * 2;
2185       break;
2186     case 3:
2187      emit_insn (gen_rotlsi3_16 (operands[0], operands[1]));
2188      count -= 16;
2189      break;
2190     case 1:
2191     case 2:
2192       {
2193         rtx parts[2];
2194         parts[0] = gen_reg_rtx (SImode);
2195         parts[1] = gen_reg_rtx (SImode);
2196         emit_insn (gen_rotlsi3_16 (parts[2-choice], operands[1]));
2197         emit_move_insn (parts[choice-1], operands[1]);
2198         emit_insn (gen_ashlsi3 (parts[0], parts[0], GEN_INT (8)));
2199         emit_insn (gen_lshrsi3 (parts[1], parts[1], GEN_INT (8)));
2200         emit_insn (gen_iorsi3 (operands[0], parts[0], parts[1]));
2201         count = (count & ~16) - 8;
2202       }
2203     }
2205   for (; count > 0; count--)
2206     emit_insn (gen_rotlsi3_1 (operands[0], operands[0]));
2207   for (; count < 0; count++)
2208     emit_insn (gen_rotlsi3_31 (operands[0], operands[0]));
2210   DONE;
2213 (define_insn "*rotlhi3_8"
2214   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2215         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "r")
2216                    (const_int 8)))]
2217   "TARGET_SH1"
2218   "swap.b       %1,%0"
2219   [(set_attr "type" "arith")])
2221 (define_expand "rotlhi3"
2222   [(set (match_operand:HI 0 "arith_reg_operand" "")
2223         (rotate:HI (match_operand:HI 1 "arith_reg_operand" "")
2224                    (match_operand:HI 2 "immediate_operand" "")))]
2225   "TARGET_SH1"
2226   "
2228   if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8)
2229     FAIL;
2233 ;; shift left
2235 ;; This pattern is used by init_expmed for computing the costs of shift
2236 ;; insns.
2238 (define_insn_and_split "ashlsi3_std"
2239   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r,r,r")
2240         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0,0,0,0")
2241                    (match_operand:SI 2 "nonmemory_operand" "r,M,P27,?ri")))
2242    (clobber (match_scratch:SI 3 "=X,X,X,&r"))]
2243   "TARGET_SH3
2244    || (TARGET_SH1 && GET_CODE (operands[2]) == CONST_INT
2245        && CONST_OK_FOR_P27 (INTVAL (operands[2])))"
2246   "@
2247    shld %2,%0
2248    add  %0,%0
2249    shll%O2      %0
2250    #"
2251   "TARGET_SH3
2252    && reload_completed
2253    && GET_CODE (operands[2]) == CONST_INT
2254    && ! CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2255   [(set (match_dup 3) (match_dup 2))
2256    (parallel
2257     [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 3)))
2258      (clobber (match_dup 4))])]
2259   "operands[4] = gen_rtx_SCRATCH (SImode);"
2260   [(set_attr "length" "*,*,*,4")
2261    (set_attr "type" "dyn_shift,arith,arith,arith")])
2263 (define_insn "ashlhi3_k"
2264   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
2265         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0")
2266                    (match_operand:HI 2 "const_int_operand" "M,P27")))]
2267   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))"
2268   "@
2269         add     %0,%0
2270         shll%O2 %0"
2271   [(set_attr "type" "arith")])
2273 (define_insn "ashlsi3_n"
2274   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2275         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0")
2276                    (match_operand:SI 2 "const_int_operand" "n")))
2277    (clobber (reg:SI T_REG))]
2278   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2279   "#"
2280   [(set (attr "length")
2281         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2282                (const_string "2")
2283                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2284                (const_string "4")
2285                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2286                (const_string "6")]
2287               (const_string "8")))
2288    (set_attr "type" "arith")])
2290 (define_split
2291   [(set (match_operand:SI 0 "arith_reg_operand" "")
2292         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2293                    (match_operand:SI 2 "const_int_operand" "")))
2294    (clobber (reg:SI T_REG))]
2295   "TARGET_SH1 && reload_completed"
2296   [(use (reg:SI R0_REG))]
2297   "
2299   gen_shifty_op (ASHIFT, operands);
2300   DONE;
2303 (define_insn "ashlsi3_media"
2304   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2305         (ashift:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2306                    (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2307   "TARGET_SHMEDIA"
2308   "@
2309         shlld.l %1, %2, %0
2310         shlli.l %1, %2, %0"
2311   [(set_attr "type" "arith_media")])
2313 (define_expand "ashlsi3"
2314   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2315                    (ashift:SI (match_operand:SI 1 "arith_reg_operand" "")
2316                               (match_operand:SI 2 "nonmemory_operand" "")))
2317               (clobber (reg:SI T_REG))])]
2318   ""
2319   "
2321   if (TARGET_SHMEDIA)
2322     {
2323       emit_insn (gen_ashlsi3_media (operands[0], operands[1], operands[2]));
2324       DONE;
2325     }
2326   if (GET_CODE (operands[2]) == CONST_INT
2327       && sh_dynamicalize_shift_p (operands[2]))
2328     operands[2] = force_reg (SImode, operands[2]);
2329   if (TARGET_SH3)
2330     {
2331       emit_insn (gen_ashlsi3_std (operands[0], operands[1], operands[2]));
2332       DONE;
2333     }
2334   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2335     FAIL;
2338 (define_insn "ashlhi3"
2339   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
2340         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0")
2341                    (match_operand:HI 2 "const_int_operand" "n")))
2342    (clobber (reg:SI T_REG))]
2343   "TARGET_SH1"
2344   "#"
2345   [(set (attr "length")
2346         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2347                (const_string "2")
2348                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2349                (const_string "4")]
2350               (const_string "6")))
2351    (set_attr "type" "arith")])
2353 (define_split
2354   [(set (match_operand:HI 0 "arith_reg_operand" "")
2355         (ashift:HI (match_operand:HI 1 "arith_reg_operand" "")
2356                    (match_operand:HI 2 "const_int_operand" "")))
2357    (clobber (reg:SI T_REG))]
2358   "TARGET_SH1 && reload_completed"
2359   [(use (reg:SI R0_REG))]
2360   "
2362   gen_shifty_hi_op (ASHIFT, operands);
2363   DONE;
2367 ; arithmetic shift right
2370 (define_insn "ashrsi3_k"
2371   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2372         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2373                      (match_operand:SI 2 "const_int_operand" "M")))
2374    (clobber (reg:SI T_REG))]
2375   "TARGET_SH1 && INTVAL (operands[2]) == 1"
2376   "shar %0"
2377   [(set_attr "type" "arith")])
2379 ;; We can't do HImode right shifts correctly unless we start out with an
2380 ;; explicit zero / sign extension; doing that would result in worse overall
2381 ;; code, so just let the machine independent code widen the mode.
2382 ;; That's why we don't have ashrhi3_k / lshrhi3_k / lshrhi3_m / lshrhi3 .
2385 ;; ??? This should be a define expand.
2387 (define_insn "ashrsi2_16"
2388   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2389         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "r")
2390                      (const_int 16)))]
2391   "TARGET_SH1"
2392   "#"
2393   [(set_attr "length" "4")])
2395 (define_split
2396   [(set (match_operand:SI 0 "arith_reg_operand" "")
2397         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2398                      (const_int 16)))]
2399   "TARGET_SH1"
2400   [(set (match_dup 0) (rotate:SI (match_dup 1) (const_int 16)))
2401    (set (match_dup 0) (sign_extend:SI (match_dup 2)))]
2402   "operands[2] = gen_lowpart (HImode, operands[0]);")
2404 ;; ??? This should be a define expand.
2406 (define_insn "ashrsi2_31"
2407   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2408         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2409                      (const_int 31)))
2410    (clobber (reg:SI T_REG))]
2411   "TARGET_SH1"
2412   "#"
2413   [(set_attr "length" "4")])
2415 (define_split
2416   [(set (match_operand:SI 0 "arith_reg_operand" "")
2417         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2418                      (const_int 31)))
2419    (clobber (reg:SI T_REG))]
2420   "TARGET_SH1"
2421   [(const_int 0)]
2422   "
2424   emit_insn (gen_ashlsi_c (operands[0], operands[1]));
2425   emit_insn (gen_subc1 (operands[0], operands[0], operands[0]));
2426   DONE;
2429 (define_insn "ashlsi_c"
2430   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2431         (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") (const_int 1)))
2432    (set (reg:SI T_REG)
2433         (lt:SI (match_dup 1) (const_int 0)))]
2434   "TARGET_SH1"
2435   "shll %0"
2436   [(set_attr "type" "arith")])
2438 (define_insn "ashrsi3_d"
2439   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2440         (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2441                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2442   "TARGET_SH3"
2443   "shad %2,%0"
2444   [(set_attr "type" "dyn_shift")])
2446 (define_insn "ashrsi3_n"
2447   [(set (reg:SI R4_REG)
2448         (ashiftrt:SI (reg:SI R4_REG)
2449                      (match_operand:SI 0 "const_int_operand" "i")))
2450    (clobber (reg:SI T_REG))
2451    (clobber (reg:SI PR_REG))
2452    (use (match_operand:SI 1 "arith_reg_operand" "r"))]
2453   "TARGET_SH1"
2454   "jsr  @%1%#"
2455   [(set_attr "type" "sfunc")
2456    (set_attr "needs_delay_slot" "yes")])
2458 (define_insn "ashrsi3_media"
2459   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2460         (ashiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2461                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2462   "TARGET_SHMEDIA"
2463   "@
2464         shard.l %1, %2, %0
2465         shari.l %1, %2, %0"
2466   [(set_attr "type" "arith_media")])
2468 (define_expand "ashrsi3"
2469   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2470                    (ashiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2471                                 (match_operand:SI 2 "nonmemory_operand" "")))
2472               (clobber (reg:SI T_REG))])]
2473   ""
2474   "
2476   if (TARGET_SHMEDIA)
2477     {
2478       emit_insn (gen_ashrsi3_media (operands[0], operands[1], operands[2]));
2479       DONE;
2480     }
2481   if (expand_ashiftrt (operands))
2482     DONE;
2483   else
2484     FAIL;
2487 ;; logical shift right
2489 (define_insn "lshrsi3_d"
2490   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2491         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2492                      (neg:SI (match_operand:SI 2 "arith_reg_operand" "r"))))]
2493   "TARGET_SH3"
2494   "shld %2,%0"
2495   [(set_attr "type" "dyn_shift")])
2497 ;;  Only the single bit shift clobbers the T bit.
2499 (define_insn "lshrsi3_m"
2500   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2501         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2502                      (match_operand:SI 2 "const_int_operand" "M")))
2503    (clobber (reg:SI T_REG))]
2504   "TARGET_SH1 && CONST_OK_FOR_M (INTVAL (operands[2]))"
2505   "shlr %0"
2506   [(set_attr "type" "arith")])
2508 (define_insn "lshrsi3_k"
2509   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2510         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2511                      (match_operand:SI 2 "const_int_operand" "P27")))]
2512   "TARGET_SH1 && CONST_OK_FOR_P27 (INTVAL (operands[2]))
2513    && ! CONST_OK_FOR_M (INTVAL (operands[2]))"
2514   "shlr%O2      %0"
2515   [(set_attr "type" "arith")])
2517 (define_insn "lshrsi3_n"
2518   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2519         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2520                      (match_operand:SI 2 "const_int_operand" "n")))
2521    (clobber (reg:SI T_REG))]
2522   "TARGET_SH1 && ! sh_dynamicalize_shift_p (operands[2])"
2523   "#"
2524   [(set (attr "length")
2525         (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1))
2526                (const_string "2")
2527                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2))
2528                (const_string "4")
2529                (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 3))
2530                (const_string "6")]
2531               (const_string "8")))
2532    (set_attr "type" "arith")])
2534 (define_split
2535   [(set (match_operand:SI 0 "arith_reg_operand" "")
2536         (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2537                      (match_operand:SI 2 "const_int_operand" "")))
2538    (clobber (reg:SI T_REG))]
2539   "TARGET_SH1 && reload_completed"
2540   [(use (reg:SI R0_REG))]
2541   "
2543   gen_shifty_op (LSHIFTRT, operands);
2544   DONE;
2547 (define_insn "lshrsi3_media"
2548   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
2549         (lshiftrt:SI (match_operand:SI 1 "extend_reg_operand" "r,r")
2550                      (match_operand:SI 2 "nonmemory_operand" "r,n")))]
2551   "TARGET_SHMEDIA"
2552   "@
2553         shlrd.l %1, %2, %0
2554         shlri.l %1, %2, %0"
2555   [(set_attr "type" "arith_media")])
2557 (define_expand "lshrsi3"
2558   [(parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
2559                    (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "")
2560                                 (match_operand:SI 2 "nonmemory_operand" "")))
2561               (clobber (reg:SI T_REG))])]
2562   ""
2563   "
2565   if (TARGET_SHMEDIA)
2566     {
2567       emit_insn (gen_lshrsi3_media (operands[0], operands[1], operands[2]));
2568       DONE;
2569     }
2570   if (GET_CODE (operands[2]) == CONST_INT
2571       && sh_dynamicalize_shift_p (operands[2]))
2572     operands[2] = force_reg (SImode, operands[2]);
2573   if (TARGET_SH3 && arith_reg_operand (operands[2], GET_MODE (operands[2])))
2574     {
2575       rtx count = copy_to_mode_reg (SImode, operands[2]);
2576       emit_insn (gen_negsi2 (count, count));
2577       emit_insn (gen_lshrsi3_d (operands[0], operands[1], count));
2578       DONE;
2579     }
2580   if (! immediate_operand (operands[2], GET_MODE (operands[2])))
2581     FAIL;
2584 ;; ??? This should be a define expand.
2586 (define_insn "ashldi3_k"
2587   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2588         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
2589                    (const_int 1)))
2590    (clobber (reg:SI T_REG))]
2591   "TARGET_SH1"
2592   "shll %R0\;rotcl      %S0"
2593   [(set_attr "length" "4")
2594    (set_attr "type" "arith")])
2596 (define_insn "ashldi3_media"
2597   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2598         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2599                    (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2600   "TARGET_SHMEDIA"
2601   "@
2602         shlld   %1, %2, %0
2603         shlli   %1, %2, %0"
2604   [(set_attr "type" "arith_media")])
2606 (define_expand "ashldi3"
2607   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2608                    (ashift:DI (match_operand:DI 1 "arith_reg_operand" "")
2609                               (match_operand:DI 2 "immediate_operand" "")))
2610               (clobber (reg:SI T_REG))])]
2611   ""
2612   "
2614   if (TARGET_SHMEDIA)
2615     {
2616       emit_insn (gen_ashldi3_media (operands[0], operands[1], operands[2]));
2617       DONE;
2618     }
2619   if (GET_CODE (operands[2]) != CONST_INT
2620       || INTVAL (operands[2]) != 1)
2621     FAIL;
2624 ;; ??? This should be a define expand.
2626 (define_insn "lshrdi3_k"
2627   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2628         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2629                      (const_int 1)))
2630    (clobber (reg:SI T_REG))]
2631   "TARGET_SH1"
2632   "shlr %S0\;rotcr      %R0"
2633   [(set_attr "length" "4")
2634    (set_attr "type" "arith")])
2636 (define_insn "lshrdi3_media"
2637   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2638         (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2639                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2640   "TARGET_SHMEDIA"
2641   "@
2642         shlrd   %1, %2, %0
2643         shlri   %1, %2, %0"
2644   [(set_attr "type" "arith_media")])
2646 (define_expand "lshrdi3"
2647   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2648                    (lshiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2649                                (match_operand:DI 2 "immediate_operand" "")))
2650              (clobber (reg:SI T_REG))])]
2651   ""
2652   "
2654   if (TARGET_SHMEDIA)
2655     {
2656       emit_insn (gen_lshrdi3_media (operands[0], operands[1], operands[2]));
2657       DONE;
2658     }
2659   if (GET_CODE (operands[2]) != CONST_INT
2660       || INTVAL (operands[2]) != 1)
2661     FAIL;
2664 ;; ??? This should be a define expand.
2666 (define_insn "ashrdi3_k"
2667   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2668         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "0")
2669                      (const_int 1)))
2670    (clobber (reg:SI T_REG))]
2671   "TARGET_SH1"
2672   "shar %S0\;rotcr      %R0"
2673   [(set_attr "length" "4")
2674    (set_attr "type" "arith")])
2676 (define_insn "ashrdi3_media"
2677   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
2678         (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r,r")
2679                      (match_operand:DI 2 "nonmemory_operand" "r,n")))]
2680   "TARGET_SHMEDIA"
2681   "@
2682         shard   %1, %2, %0
2683         shari   %1, %2, %0"
2684   [(set_attr "type" "arith_media")])
2686 (define_expand "ashrdi3"
2687   [(parallel [(set (match_operand:DI 0 "arith_reg_operand" "")
2688                    (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "")
2689                                 (match_operand:DI 2 "immediate_operand" "")))
2690               (clobber (reg:SI T_REG))])]
2691   ""
2692   "
2694   if (TARGET_SHMEDIA)
2695     {
2696       emit_insn (gen_ashrdi3_media (operands[0], operands[1], operands[2]));
2697       DONE;
2698     }
2699   if (GET_CODE (operands[2]) != CONST_INT
2700       || INTVAL (operands[2]) != 1)
2701     FAIL;
2704 ;; combined left/right shift
2706 (define_split
2707   [(set (match_operand:SI 0 "register_operand" "")
2708         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2709                            (match_operand:SI 2 "const_int_operand" ""))
2710                 (match_operand:SI 3 "const_int_operand" "")))]
2711   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2712   [(use (reg:SI R0_REG))]
2713   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2714    DONE;")
2716 (define_split
2717   [(set (match_operand:SI 0 "register_operand" "")
2718         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
2719                            (match_operand:SI 2 "const_int_operand" ""))
2720                 (match_operand:SI 3 "const_int_operand" "")))
2721    (clobber (reg:SI T_REG))]
2722   "TARGET_SH1 && reload_completed && (unsigned)INTVAL (operands[2]) < 32"
2723   [(use (reg:SI R0_REG))]
2724   "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL;
2725    DONE;")
2727 (define_insn ""
2728   [(set (match_operand:SI 0 "register_operand" "=r")
2729         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2730                            (match_operand:SI 2 "const_int_operand" "n"))
2731                 (match_operand:SI 3 "const_int_operand" "n")))
2732    (clobber (reg:SI T_REG))]
2733   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 1"
2734  "#"
2735   [(set (attr "length")
2736         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2737                (const_string "4")
2738                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2739                (const_string "6")
2740                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2741                (const_string "8")
2742                (eq (symbol_ref "shl_and_length (insn)") (const_int 5))
2743                (const_string "10")
2744                (eq (symbol_ref "shl_and_length (insn)") (const_int 6))
2745                (const_string "12")
2746                (eq (symbol_ref "shl_and_length (insn)") (const_int 7))
2747                (const_string "14")
2748                (eq (symbol_ref "shl_and_length (insn)") (const_int 8))
2749                (const_string "16")]
2750               (const_string "18")))
2751    (set_attr "type" "arith")])
2753 (define_insn ""
2754   [(set (match_operand:SI 0 "register_operand" "=z")
2755         (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0")
2756                            (match_operand:SI 2 "const_int_operand" "n"))
2757                 (match_operand:SI 3 "const_int_operand" "n")))
2758    (clobber (reg:SI T_REG))]
2759   "TARGET_SH1 && shl_and_kind (operands[2], operands[3], 0) == 2"
2760  "#"
2761   [(set (attr "length")
2762         (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2))
2763                (const_string "4")
2764                (eq (symbol_ref "shl_and_length (insn)") (const_int 3))
2765                (const_string "6")
2766                (eq (symbol_ref "shl_and_length (insn)") (const_int 4))
2767                (const_string "8")]
2768               (const_string "10")))
2769    (set_attr "type" "arith")])
2771 ;; shift left / and combination with a scratch register: The combine pass
2772 ;; does not accept the individual instructions, even though they are
2773 ;; cheap.  But it needs a precise description so that it is usable after
2774 ;; reload.
2775 (define_insn "and_shl_scratch"
2776   [(set (match_operand:SI 0 "register_operand" "=r,&r")
2777         (lshiftrt:SI
2778          (ashift:SI
2779           (and:SI
2780            (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0")
2781                         (match_operand:SI 2 "const_int_operand" "N,n"))
2782            (match_operand:SI 3 "" "0,r"))
2783           (match_operand:SI 4 "const_int_operand" "n,n"))
2784          (match_operand:SI 5 "const_int_operand" "n,n")))
2785    (clobber (reg:SI T_REG))]
2786   "TARGET_SH1"
2787   "#"
2788   [(set (attr "length")
2789         (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2))
2790                (const_string "4")
2791                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3))
2792                (const_string "6")
2793                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4))
2794                (const_string "8")
2795                (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5))
2796                (const_string "10")]
2797               (const_string "12")))
2798    (set_attr "type" "arith")])
2800 (define_split
2801   [(set (match_operand:SI 0 "register_operand" "")
2802         (lshiftrt:SI
2803          (ashift:SI
2804           (and:SI
2805            (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
2806                         (match_operand:SI 2 "const_int_operand" ""))
2807            (match_operand:SI 3 "register_operand" ""))
2808           (match_operand:SI 4 "const_int_operand" ""))
2809          (match_operand:SI 5 "const_int_operand" "")))
2810    (clobber (reg:SI T_REG))]
2811   "TARGET_SH1"
2812   [(use (reg:SI R0_REG))]
2813   "
2815   rtx and_source = operands[rtx_equal_p (operands[0], operands[1]) ? 3 : 1];
2817   if (INTVAL (operands[2]))
2818     {
2819       gen_shifty_op (LSHIFTRT, operands);
2820     }
2821   emit_insn (gen_andsi3 (operands[0], operands[0], and_source));
2822   operands[2] = operands[4];
2823   gen_shifty_op (ASHIFT, operands);
2824   if (INTVAL (operands[5]))
2825     {
2826       operands[2] = operands[5];
2827       gen_shifty_op (LSHIFTRT, operands);
2828     }
2829   DONE;
2832 ;; signed left/right shift combination.
2833 (define_split
2834   [(set (match_operand:SI 0 "register_operand" "")
2835         (sign_extract:SI
2836          (ashift:SI (match_operand:SI 1 "register_operand" "")
2837                     (match_operand:SI 2 "const_int_operand" ""))
2838          (match_operand:SI 3 "const_int_operand" "")
2839          (const_int 0)))
2840    (clobber (reg:SI T_REG))]
2841   "TARGET_SH1"
2842   [(use (reg:SI R0_REG))]
2843   "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL;
2844    DONE;")
2846 (define_insn "shl_sext_ext"
2847   [(set (match_operand:SI 0 "register_operand" "=r")
2848         (sign_extract:SI
2849          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2850                     (match_operand:SI 2 "const_int_operand" "n"))
2851          (match_operand:SI 3 "const_int_operand" "n")
2852          (const_int 0)))
2853    (clobber (reg:SI T_REG))]
2854   "TARGET_SH1 && (unsigned)shl_sext_kind (operands[2], operands[3], 0) - 1 < 5"
2855   "#"
2856   [(set (attr "length")
2857         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1))
2858                (const_string "2")
2859                (eq (symbol_ref "shl_sext_length (insn)") (const_int 2))
2860                (const_string "4")
2861                (eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2862                (const_string "6")
2863                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2864                (const_string "8")
2865                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2866                (const_string "10")
2867                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2868                (const_string "12")
2869                (eq (symbol_ref "shl_sext_length (insn)") (const_int 7))
2870                (const_string "14")
2871                (eq (symbol_ref "shl_sext_length (insn)") (const_int 8))
2872                (const_string "16")]
2873               (const_string "18")))
2874     (set_attr "type" "arith")])
2876 (define_insn "shl_sext_sub"
2877   [(set (match_operand:SI 0 "register_operand" "=z")
2878         (sign_extract:SI
2879          (ashift:SI (match_operand:SI 1 "register_operand" "0")
2880                     (match_operand:SI 2 "const_int_operand" "n"))
2881          (match_operand:SI 3 "const_int_operand" "n")
2882          (const_int 0)))
2883    (clobber (reg:SI T_REG))]
2884   "TARGET_SH1 && (shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6"
2885   "#"
2886   [(set (attr "length")
2887         (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3))
2888                (const_string "6")
2889                (eq (symbol_ref "shl_sext_length (insn)") (const_int 4))
2890                (const_string "8")
2891                (eq (symbol_ref "shl_sext_length (insn)") (const_int 5))
2892                (const_string "10")
2893                (eq (symbol_ref "shl_sext_length (insn)") (const_int 6))
2894                (const_string "12")]
2895               (const_string "14")))
2896     (set_attr "type" "arith")])
2898 ;; These patterns are found in expansions of DImode shifts by 16, and
2899 ;; allow the xtrct instruction to be generated from C source.
2901 (define_insn "xtrct_left"
2902   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2903         (ior:SI (ashift:SI (match_operand:SI 1 "arith_reg_operand" "r")
2904                            (const_int 16))
2905                 (lshiftrt:SI (match_operand:SI 2 "arith_reg_operand" "0")
2906                              (const_int 16))))]
2907   "TARGET_SH1"
2908   "xtrct        %1,%0"
2909   [(set_attr "type" "arith")])
2911 (define_insn "xtrct_right"
2912   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2913         (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0")
2914                              (const_int 16))
2915                 (ashift:SI (match_operand:SI 2 "arith_reg_operand" "r")
2916                            (const_int 16))))]
2917   "TARGET_SH1"
2918   "xtrct        %2,%0"
2919   [(set_attr "type" "arith")])
2921 ;; -------------------------------------------------------------------------
2922 ;; Unary arithmetic
2923 ;; -------------------------------------------------------------------------
2925 (define_insn "negc"
2926   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2927         (neg:SI (plus:SI (reg:SI T_REG)
2928                          (match_operand:SI 1 "arith_reg_operand" "r"))))
2929    (set (reg:SI T_REG)
2930         (ne:SI (ior:SI (reg:SI T_REG) (match_dup 1))
2931                (const_int 0)))]
2932   "TARGET_SH1"
2933   "negc %1,%0"
2934   [(set_attr "type" "arith")])
2936 (define_insn "*negdi_media"
2937   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
2938         (neg:DI (match_operand:DI 1 "arith_reg_operand" "r")))]
2939   "TARGET_SHMEDIA"
2940   "sub  r63, %1, %0"
2941   [(set_attr "type" "arith_media")])
2943 (define_expand "negdi2"
2944   [(set (match_operand:DI 0 "arith_reg_operand" "")
2945         (neg:DI (match_operand:DI 1 "arith_reg_operand" "")))]
2946   ""
2947   "
2949   if (TARGET_SH1)
2950     {
2951       int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1);
2952       int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0);
2954       rtx low_src = operand_subword (operands[1], low_word, 0, DImode);
2955       rtx high_src = operand_subword (operands[1], high_word, 0, DImode);
2957       rtx low_dst = operand_subword (operands[0], low_word, 1, DImode);
2958       rtx high_dst = operand_subword (operands[0], high_word, 1, DImode);
2960       emit_insn (gen_clrt ());
2961       emit_insn (gen_negc (low_dst, low_src));
2962       emit_insn (gen_negc (high_dst, high_src));
2963       DONE;
2964     }
2967 (define_insn "negsi2"
2968   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2969         (neg:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2970   "TARGET_SH1"
2971   "neg  %1,%0"
2972   [(set_attr "type" "arith")])
2974 (define_insn "one_cmplsi2"
2975   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
2976         (not:SI (match_operand:SI 1 "arith_reg_operand" "r")))]
2977   "TARGET_SH1"
2978   "not  %1,%0"
2979   [(set_attr "type" "arith")])
2981 (define_expand "one_cmpldi2"
2982   [(set (match_operand:DI 0 "arith_reg_operand" "")
2983         (xor:DI (match_operand:DI 1 "arith_reg_operand" "")
2984                 (const_int -1)))]
2985   "TARGET_SHMEDIA" "")
2987 ;; -------------------------------------------------------------------------
2988 ;; Zero extension instructions
2989 ;; -------------------------------------------------------------------------
2991 (define_insn "zero_extendsidi2"
2992   [(set (match_operand:DI 0 "register_operand" "=r")
2993         (zero_extend:DI (match_operand:SI 1 "extend_reg_operand" "r")))]
2994   "TARGET_SHMEDIA"
2995   "addz.l       %1, r63, %0"
2996   [(set_attr "type" "arith_media")])
2998 (define_insn "zero_extendhidi2"
2999   [(set (match_operand:DI 0 "register_operand" "=r,r")
3000         (zero_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3001   "TARGET_SHMEDIA"
3002   "@
3003         #
3004         ld%M1.uw        %m1, %0"
3005   [(set_attr "type" "*,load_media")])
3007 (define_split
3008   [(set (match_operand:DI 0 "register_operand" "")
3009         (zero_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3010   "TARGET_SHMEDIA && reload_completed"
3011   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3012    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
3013   "
3015   if (GET_CODE (operands[1]) == TRUNCATE)
3016     operands[1] = XEXP (operands[1], 0);
3019 ;; ??? when a truncated input to a zero_extend is reloaded, reload will
3020 ;; reload the entire truncate expression.
3021 (define_insn_and_split "*loaddi_trunc"
3022   [(set (match_operand 0 "int_gpr_dest" "=r")
3023         (truncate (match_operand:DI 1 "memory_operand" "m")))]
3024   "TARGET_SHMEDIA && reload_completed"
3025   "#"
3026   "TARGET_SHMEDIA && reload_completed"
3027   [(set (match_dup 0) (match_dup 1))]
3028   "operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));")
3030 (define_insn "zero_extendqidi2"
3031   [(set (match_operand:DI 0 "register_operand" "=r,r")
3032         (zero_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3033   "TARGET_SHMEDIA"
3034   "@
3035         andi    %1, 255, %0
3036         ld%M1.ub        %m1, %0"
3037   [(set_attr "type" "arith_media,load_media")])
3039 (define_expand "zero_extendhisi2"
3040   [(set (match_operand:SI 0 "arith_reg_operand" "")
3041         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "")))]
3042   ""
3043   "
3045   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], HImode))
3046     operands[1] = copy_to_mode_reg (HImode, operands[1]);
3049 (define_insn "*zero_extendhisi2_compact"
3050   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3051         (zero_extend:SI (match_operand:HI 1 "arith_reg_operand" "r")))]
3052   "TARGET_SH1"
3053   "extu.w       %1,%0"
3054   [(set_attr "type" "arith")])
3056 (define_insn "*zero_extendhisi2_media"
3057   [(set (match_operand:SI 0 "register_operand" "=r,r")
3058         (zero_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3059   "TARGET_SHMEDIA"
3060   "@
3061         #
3062         ld%M1.uw        %m1, %0"
3063   [(set_attr "type" "arith_media,load_media")])
3065 (define_split
3066   [(set (match_operand:SI 0 "register_operand" "")
3067         (zero_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3068   "TARGET_SHMEDIA && reload_completed"
3069   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3070    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))]
3071   "
3073   if (GET_CODE (operands[1]) == TRUNCATE)
3074     operands[1] = XEXP (operands[1], 0);
3077 (define_expand "zero_extendqisi2"
3078   [(set (match_operand:SI 0 "arith_reg_operand" "")
3079         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "")))]
3080   ""
3081   "
3083   if (! TARGET_SHMEDIA && ! arith_reg_operand (operands[1], QImode))
3084     operands[1] = copy_to_mode_reg (QImode, operands[1]);
3087 (define_insn "*zero_extendqisi2_compact"
3088   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
3089         (zero_extend:SI (match_operand:QI 1 "arith_reg_operand" "r")))]
3090   "TARGET_SH1"
3091   "extu.b       %1,%0"
3092   [(set_attr "type" "arith")])
3094 (define_insn "*zero_extendqisi2_media"
3095   [(set (match_operand:SI 0 "register_operand" "=r,r")
3096         (zero_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3097   "TARGET_SHMEDIA"
3098   "@
3099         andi    %1, 255, %0
3100         ld%M1.ub        %m1, %0"
3101   [(set_attr "type" "arith_media,load_media")])
3103 (define_insn "zero_extendqihi2"
3104   [(set (match_operand:HI 0 "arith_reg_operand" "=r")
3105         (zero_extend:HI (match_operand:QI 1 "arith_reg_operand" "r")))]
3106   "TARGET_SH1"
3107   "extu.b       %1,%0"
3108   [(set_attr "type" "arith")])
3110 ;; -------------------------------------------------------------------------
3111 ;; Sign extension instructions
3112 ;; -------------------------------------------------------------------------
3114 ;; ??? This should be a define expand.
3115 ;; ??? Or perhaps it should be dropped?
3117 ;; convert_move generates good code for SH[1-4].
3118 (define_insn "extendsidi2"
3119   [(set (match_operand:DI 0 "register_operand" "=r,r")
3120         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
3121   "TARGET_SHMEDIA"
3122   "@
3123         add.l   %1, r63, %0
3124         ld%M1.l %m1, %0"
3125   [(set_attr "type" "arith_media,load_media")])
3127 (define_insn "extendhidi2"
3128   [(set (match_operand:DI 0 "register_operand" "=r,r")
3129         (sign_extend:DI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3130   "TARGET_SHMEDIA"
3131   "@
3132         #
3133         ld%M1.w %m1, %0"
3134   [(set_attr "type" "*,load_media")])
3136 (define_split
3137   [(set (match_operand:DI 0 "register_operand" "")
3138         (sign_extend:DI (match_operand:HI 1 "extend_reg_operand" "")))]
3139   "TARGET_SHMEDIA && reload_completed"
3140   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 48)))
3141    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
3142   "
3144   if (GET_CODE (operands[1]) == TRUNCATE)
3145     operands[1] = XEXP (operands[1], 0);
3148 (define_insn "extendqidi2"
3149   [(set (match_operand:DI 0 "register_operand" "=r,r")
3150         (sign_extend:DI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3151   "TARGET_SHMEDIA"
3152   "@
3153         #
3154         ld%M1.b %m1, %0"
3155   [(set_attr "type" "*,load_media")])
3157 (define_split
3158   [(set (match_operand:DI 0 "register_operand" "")
3159         (sign_extend:DI (match_operand:QI 1 "extend_reg_operand" "")))]
3160   "TARGET_SHMEDIA && reload_completed"
3161   [(set (match_dup 0) (ashift:DI (subreg:DI (match_dup 1) 0) (const_int 56)))
3162    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
3163   "
3165   if (GET_CODE (operands[1]) == TRUNCATE)
3166     operands[1] = XEXP (operands[1], 0);
3169 (define_expand "extendhisi2"
3170   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3171         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3172   ""
3173   "")
3175 (define_insn "*extendhisi2_compact"
3176   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3177         (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))]
3178   "TARGET_SH1"
3179   "@
3180         exts.w  %1,%0
3181         mov.w   %1,%0"
3182   [(set_attr "type" "arith,load")])
3184 (define_insn "*extendhisi2_media"
3185   [(set (match_operand:SI 0 "register_operand" "=r,r")
3186         (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))]
3187   "TARGET_SHMEDIA"
3188   "@
3189         #
3190         ld%M1.w %m1, %0"
3191   [(set_attr "type" "arith_media,load_media")])
3193 (define_split
3194   [(set (match_operand:SI 0 "register_operand" "")
3195         (sign_extend:SI (match_operand:HI 1 "extend_reg_operand" "")))]
3196   "TARGET_SHMEDIA && reload_completed"
3197   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 16)))
3198    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))]
3199   "
3201   if (GET_CODE (operands[1]) == TRUNCATE)
3202     operands[1] = XEXP (operands[1], 0);
3205 (define_expand "extendqisi2"
3206   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3207         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3208   ""
3209   "")
3211 (define_insn "*extendqisi2_compact"
3212   [(set (match_operand:SI 0 "arith_reg_operand" "=r,r")
3213         (sign_extend:SI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3214   "TARGET_SH1"
3215   "@
3216         exts.b  %1,%0
3217         mov.b   %1,%0"
3218   [(set_attr "type" "arith,load")])
3220 (define_insn "*extendqisi2_media"
3221   [(set (match_operand:SI 0 "register_operand" "=r,r")
3222         (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))]
3223   "TARGET_SHMEDIA"
3224   "@
3225         #
3226         ld%M1.b %m1, %0"
3227   [(set_attr "type" "arith_media,load_media")])
3229 (define_split
3230   [(set (match_operand:SI 0 "register_operand" "")
3231         (sign_extend:SI (match_operand:QI 1 "extend_reg_operand" "")))]
3232   "TARGET_SHMEDIA && reload_completed"
3233   [(set (match_dup 0) (ashift:SI (subreg:SI (match_dup 1) 0) (const_int 24)))
3234    (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))]
3235    "
3237   if (GET_CODE (operands[1]) == TRUNCATE)
3238     operands[1] = XEXP (operands[1], 0);
3241 (define_insn "extendqihi2"
3242   [(set (match_operand:HI 0 "arith_reg_operand" "=r,r")
3243         (sign_extend:HI (match_operand:QI 1 "general_movsrc_operand" "r,m")))]
3244   "TARGET_SH1"
3245   "@
3246         exts.b  %1,%0
3247         mov.b   %1,%0"
3248   [(set_attr "type" "arith,load")])
3250 /* It would seem useful to combine the truncXi patterns into the movXi
3251    patterns, but unary operators are ignored when matching constraints,
3252    so we need separate patterns.  */
3253 (define_insn "truncdisi2"
3254   [(set (match_operand:SI 0 "general_movdst_operand" "=r,m,m,f,r,f")
3255         (truncate:SI (match_operand:DI 1 "register_operand" "r,r,f,r,f,f")))]
3256   "TARGET_SHMEDIA"
3257   "@
3258         add.l   %1, r63, %0
3259         st%M0.l %m0, %1
3260         fst%M0.s        %m0, %T1
3261         fmov.ls %1, %0
3262         fmov.sl %T1, %0
3263         fmov.s  %T1, %0"
3264   [(set_attr "type"   "arith_media,store_media,fstore_media,fload_media,fpconv_media,fmove_media")])
3267 (define_insn "truncdihi2"
3268   [(set (match_operand:HI 0 "general_movdst_operand" "=?r,m")
3269         (truncate:HI (match_operand:DI 1 "register_operand" "r,r")))]
3270   "TARGET_SHMEDIA"
3271   "@
3272         shlli\\t%1,48,%0\;shlri\\t%0,48,%0
3273         st%M0.w %m0, %1"
3274   [(set_attr "type"   "arith_media,store_media")
3275    (set_attr "length" "8,4")])
3277 ; N.B. This should agree with LOAD_EXTEND_OP and movqi.
3278 ; Because we use zero extension, we can't provide signed QImode compares
3279 ; using a simple compare or conditional banch insn.
3280 (define_insn "truncdiqi2"
3281   [(set (match_operand:QI 0 "general_movdst_operand" "=r,m")
3282         (truncate:QI (match_operand:DI 1 "register_operand" "r,r")))]
3283   "TARGET_SHMEDIA"
3284   "@
3285         andi    %1, 255, %0
3286         st%M0.b %m0, %1"
3287   [(set_attr "type"   "arith_media,store")])
3289 ;; -------------------------------------------------------------------------
3290 ;; Move instructions
3291 ;; -------------------------------------------------------------------------
3293 ;; define push and pop so it is easy for sh.c
3294 ;; We can't use push and pop on SHcompact because the stack must always
3295 ;; be 8-byte aligned.
3297 (define_expand "push"
3298   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
3299         (match_operand:SI 0 "register_operand" "r,l,x"))]
3300   "TARGET_SH1 && ! TARGET_SH5"
3301   "")
3303 (define_expand "pop"
3304   [(set (match_operand:SI 0 "register_operand" "=r,l,x")
3305         (mem:SI (post_inc:SI (reg:SI SP_REG))))]
3306   "TARGET_SH1 && ! TARGET_SH5"
3307   "")
3309 (define_expand "push_e"
3310   [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG)))
3311                    (match_operand:SF 0 "" ""))
3312               (use (reg:PSI FPSCR_REG))
3313               (clobber (scratch:SI))])]
3314   "TARGET_SH1 && ! TARGET_SH5"
3315   "")
3317 (define_insn "push_fpul"
3318   [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (reg:SF FPUL_REG))]
3319   "TARGET_SH2E && ! TARGET_SH5"
3320   "sts.l        fpul,@-r15"
3321   [(set_attr "type" "store")
3322    (set_attr "late_fp_use" "yes")
3323    (set_attr "hit_stack" "yes")])
3325 ;; DFmode pushes for sh4 require a lot of what is defined for movdf_i4,
3326 ;; so use that.
3327 (define_expand "push_4"
3328   [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG)))
3329                    (match_operand:DF 0 "" ""))
3330               (use (reg:PSI FPSCR_REG))
3331               (clobber (scratch:SI))])]
3332   "TARGET_SH1 && ! TARGET_SH5"
3333   "")
3335 (define_expand "pop_e"
3336   [(parallel [(set (match_operand:SF 0 "" "")
3337               (mem:SF (post_inc:SI (reg:SI SP_REG))))
3338               (use (reg:PSI FPSCR_REG))
3339               (clobber (scratch:SI))])]
3340   "TARGET_SH1 && ! TARGET_SH5"
3341   "")
3343 (define_insn "pop_fpul"
3344   [(set (reg:SF FPUL_REG) (mem:SF (post_inc:SI (reg:SI SP_REG))))]
3345   "TARGET_SH2E && ! TARGET_SH5"
3346   "lds.l        @r15+,fpul"
3347   [(set_attr "type" "load")
3348    (set_attr "hit_stack" "yes")])
3350 (define_expand "pop_4"
3351   [(parallel [(set (match_operand:DF 0 "" "")
3352                    (mem:DF (post_inc:SI (reg:SI SP_REG))))
3353               (use (reg:PSI FPSCR_REG))
3354               (clobber (scratch:SI))])]
3355   "TARGET_SH1 && ! TARGET_SH5"
3356   "")
3358 (define_expand "push_fpscr"
3359   [(const_int 0)]
3360   "TARGET_SH2E"
3361   "
3363   rtx insn = emit_insn (gen_fpu_switch (gen_rtx_MEM (PSImode,
3364                                                  gen_rtx_PRE_DEC (Pmode,
3365                                                           stack_pointer_rtx)),
3366                                         get_fpscr_rtx ()));
3367   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3368   DONE;
3371 (define_expand "pop_fpscr"
3372   [(const_int 0)]
3373   "TARGET_SH2E"
3374   "
3376   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
3377                                         gen_rtx_MEM (PSImode,
3378                                                  gen_rtx_POST_INC (Pmode,
3379                                                           stack_pointer_rtx))));
3380   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
3381   DONE;
3384 ;; These two patterns can happen as the result of optimization, when
3385 ;; comparisons get simplified to a move of zero or 1 into the T reg.
3386 ;; They don't disappear completely, because the T reg is a fixed hard reg.
3388 (define_insn "clrt"
3389   [(set (reg:SI T_REG) (const_int 0))]
3390   "TARGET_SH1"
3391   "clrt")
3393 (define_insn "sett"
3394   [(set (reg:SI T_REG) (const_int 1))]
3395   "TARGET_SH1"
3396   "sett")
3398 ;; t/r must come after r/r, lest reload will try to reload stuff like
3399 ;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
3400 ;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
3401 (define_insn "movsi_i"
3402   [(set (match_operand:SI 0 "general_movdst_operand"
3403             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,r")
3404         (match_operand:SI 1 "general_movsrc_operand"
3405          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,i"))]
3406   "TARGET_SH1
3407    && ! TARGET_SH2E
3408    && (register_operand (operands[0], SImode)
3409        || register_operand (operands[1], SImode))"
3410   "@
3411         mov.l   %1,%0
3412         mov     %1,%0
3413         cmp/pl  %1
3414         mov.l   %1,%0
3415         sts     %1,%0
3416         sts     %1,%0
3417         movt    %0
3418         mov.l   %1,%0
3419         sts.l   %1,%0
3420         sts.l   %1,%0
3421         lds     %1,%0
3422         lds     %1,%0
3423         lds.l   %1,%0
3424         lds.l   %1,%0
3425         fake    %1,%0"
3426   [(set_attr "type" "pcload_si,move,mt_group,load_si,mac_gp,prget,move,store,store,pstore,move,prset,load,pload,pcload_si")
3427    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
3429 ;; t/r must come after r/r, lest reload will try to reload stuff like
3430 ;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
3431 ;; ??? This allows moves from macl to fpul to be recognized, but these moves
3432 ;; will require a reload.
3433 ;; ??? We can't include f/f because we need the proper FPSCR setting when
3434 ;; TARGET_FMOVD is in effect, and mode switching is done before reload.
3435 (define_insn "movsi_ie"
3436   [(set (match_operand:SI 0 "general_movdst_operand"
3437             "=r,r,t,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
3438         (match_operand:SI 1 "general_movsrc_operand"
3439          "Q,rI08,r,mr,x,l,t,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
3440   "TARGET_SH2E
3441    && (register_operand (operands[0], SImode)
3442        || register_operand (operands[1], SImode))"
3443   "@
3444         mov.l   %1,%0
3445         mov     %1,%0
3446         cmp/pl  %1
3447         mov.l   %1,%0
3448         sts     %1,%0
3449         sts     %1,%0
3450         movt    %0
3451         mov.l   %1,%0
3452         sts.l   %1,%0
3453         sts.l   %1,%0
3454         lds     %1,%0
3455         lds     %1,%0
3456         lds.l   %1,%0
3457         lds.l   %1,%0
3458         lds.l   %1,%0
3459         sts.l   %1,%0
3460         fake    %1,%0
3461         lds     %1,%0
3462         sts     %1,%0
3463         fsts    fpul,%0
3464         flds    %1,fpul
3465         fmov    %1,%0
3466         ! move optimized away"
3467   [(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,fmove,fmove,fmove,nil")
3468    (set_attr "late_fp_use" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*")
3469    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,0")])
3471 (define_insn "movsi_i_lowpart"
3472   [(set (strict_low_part (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
3473         (match_operand:SI 1 "general_movsrc_operand" "Q,rI08,mr,x,l,t,r,i"))]
3474    "TARGET_SH1
3475     && (register_operand (operands[0], SImode)
3476         || register_operand (operands[1], SImode))"
3477   "@
3478         mov.l   %1,%0
3479         mov     %1,%0
3480         mov.l   %1,%0
3481         sts     %1,%0
3482         sts     %1,%0
3483         movt    %0
3484         mov.l   %1,%0
3485         fake    %1,%0"
3486   [(set_attr "type" "pcload,move,load,move,prget,move,store,pcload")])
3488 (define_insn_and_split "load_ra"
3489   [(set (match_operand:SI 0 "general_movdst_operand" "")
3490         (unspec:SI [(match_operand 1 "register_operand" "")] UNSPEC_RA))]
3491   "TARGET_SH1"
3492   "#"
3493   "&& ! rtx_equal_function_value_matters"
3494   [(set (match_dup 0) (match_dup 1))]
3495   "
3497   if (TARGET_SHCOMPACT && current_function_has_nonlocal_label)
3498     operands[1] = gen_rtx_MEM (SImode, return_address_pointer_rtx);
3501 (define_insn "*movsi_media"
3502   [(set (match_operand:SI 0 "general_movdst_operand"
3503                 "=r,r,r,r,m,f,m,f,r,f,*b,r,b")
3504         (match_operand:SI 1 "general_movsrc_operand"
3505          "r,I16C16,nCpg,m,rZ,m,f,rZ,f,f,r,*b,Csy"))]
3506   "TARGET_SHMEDIA_FPU
3507    && (register_operand (operands[0], SImode)
3508        || sh_register_operand (operands[1], SImode))"
3509   "@
3510         add.l   %1, r63, %0
3511         movi    %1, %0
3512         #
3513         ld%M1.l %m1, %0
3514         st%M0.l %m0, %N1
3515         fld%M1.s        %m1, %0
3516         fst%M0.s        %m0, %1
3517         fmov.ls %N1, %0
3518         fmov.sl %1, %0
3519         fmov.s  %1, %0
3520         ptabs   %1, %0
3521         gettr   %1, %0
3522         pt      %1, %0"
3523   [(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")
3524    (set_attr "length" "4,4,8,4,4,4,4,4,4,4,4,4,12")])
3526 (define_insn "*movsi_media_nofpu"
3527   [(set (match_operand:SI 0 "general_movdst_operand"
3528                 "=r,r,r,r,m,*b,r,b")
3529         (match_operand:SI 1 "general_movsrc_operand"
3530          "r,I16C16,nCpg,m,rZ,r,*b,Csy"))]
3531   "TARGET_SHMEDIA
3532    && (register_operand (operands[0], SImode)
3533        || sh_register_operand (operands[1], SImode))"
3534   "@
3535         add.l   %1, r63, %0
3536         movi    %1, %0
3537         #
3538         ld%M1.l %m1, %0
3539         st%M0.l %m0, %N1
3540         ptabs   %1, %0
3541         gettr   %1, %0
3542         pt      %1, %0"
3543   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3544    (set_attr "length" "4,4,8,4,4,4,4,12")])
3546 (define_split
3547   [(set (match_operand:SI 0 "arith_reg_operand" "")
3548         (match_operand:SI 1 "immediate_operand" ""))]
3549   "TARGET_SHMEDIA && reload_completed
3550    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3551   [(set (subreg:DI (match_dup 0) 0) (match_dup 2))]
3552   "
3554   operands[2] = shallow_copy_rtx (operands[1]);
3555   PUT_MODE (operands[2], DImode);
3558 (define_split
3559   [(set (match_operand:SI 0 "register_operand" "")
3560         (match_operand:SI 1 "immediate_operand" ""))]
3561   "TARGET_SHMEDIA && reload_completed
3562    && ((GET_CODE (operands[1]) == CONST_INT
3563         && ! CONST_OK_FOR_I16 (INTVAL (operands[1])))
3564        || GET_CODE (operands[1]) == CONST_DOUBLE)"
3565   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3567 (define_expand "movsi"
3568   [(set (match_operand:SI 0 "general_movdst_operand" "")
3569         (match_operand:SI 1 "general_movsrc_operand" ""))]
3570   ""
3571   "{ if (prepare_move_operands (operands, SImode)) DONE; }")
3573 (define_expand "ic_invalidate_line"
3574   [(parallel [(unspec_volatile [(match_operand:SI 0 "register_operand" "+r")
3575                                 (match_dup 1)] UNSPEC_ICACHE)
3576               (clobber (scratch:SI))])]
3577   "TARGET_HARD_SH4 || TARGET_SH5"
3578   "
3580   if (TARGET_SHMEDIA)
3581     {
3582       emit_insn (gen_ic_invalidate_line_media (operands[0]));
3583       DONE;
3584     }
3585   else if (TARGET_SHCOMPACT)
3586     {
3587       operands[1] = function_symbol (\"__ic_invalidate\");
3588       operands[1] = force_reg (Pmode, operands[1]);
3589       emit_insn (gen_ic_invalidate_line_compact (operands[0], operands[1]));
3590       DONE;
3591     }
3592   operands[0] = force_reg (Pmode, operands[0]);
3593   operands[1] = force_reg (Pmode, GEN_INT (trunc_int_for_mode (0xf0000008,
3594                                                                Pmode)));
3597 ;; The address %0 is assumed to be 4-aligned at least.  Thus, by ORing
3598 ;; 0xf0000008, we get the low-oder bits *1*00 (binary), which fits
3599 ;; the requirement *1*00 for associative address writes.  The alignment of
3600 ;; %0 implies that its least significant bit is cleared,
3601 ;; thus we clear the V bit of a matching entry if there is one.
3602 (define_insn "ic_invalidate_line_i"
3603   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
3604                      (match_operand:SI 1 "register_operand" "r")]
3605                      UNSPEC_ICACHE)
3606    (clobber (match_scratch:SI 2 "=&r"))]
3607   "TARGET_HARD_SH4"
3608   "ocbwb\\t@%0\;extu.w\\t%0,%2\;or\\t%1,%2\;mov.l\\t%0,@%2"
3609   [(set_attr "length" "8")
3610    (set_attr "type" "cwb")])
3612 ;; ??? could make arg 0 an offsettable memory operand to allow to save
3613 ;; an add in the code that calculates the address.
3614 (define_insn "ic_invalidate_line_media"
3615   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
3616                     UNSPEC_ICACHE)]
3617   "TARGET_SHMEDIA"
3618   "ocbwb        %0,0\;synco\;icbi       %0, 0\;synci"
3619   [(set_attr "length" "16")
3620    (set_attr "type" "invalidate_line_media")])
3622 (define_insn "ic_invalidate_line_compact"
3623   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3624                      (match_operand:SI 1 "register_operand" "r")]
3625                     UNSPEC_ICACHE)
3626    (clobber (reg:SI PR_REG))]
3627   "TARGET_SHCOMPACT"
3628   "jsr @%1%#"
3629   [(set_attr "type" "sfunc")
3630    (set_attr "needs_delay_slot" "yes")])
3632 (define_expand "initialize_trampoline"
3633   [(match_operand:SI 0 "" "")
3634    (match_operand:SI 1 "" "")
3635    (match_operand:SI 2 "" "")]
3636   "TARGET_SHCOMPACT"
3637   "
3639   rtx sfun, tramp;
3641   tramp = force_reg (Pmode, operands[0]);
3642   sfun = force_reg (Pmode, function_symbol (\"__init_trampoline\"));
3643   emit_move_insn (gen_rtx_REG (SImode, R2_REG), operands[1]);
3644   emit_move_insn (gen_rtx_REG (SImode, R3_REG), operands[2]);
3646   emit_insn (gen_initialize_trampoline_compact (tramp, sfun));
3647   DONE;
3650 (define_insn "initialize_trampoline_compact"
3651   [(unspec_volatile [(match_operand:SI 0 "register_operand" "z")
3652                      (match_operand:SI 1 "register_operand" "r")
3653                      (reg:SI R2_REG) (reg:SI R3_REG)]
3654                     UNSPEC_INIT_TRAMP)
3656    (clobber (reg:SI PR_REG))]
3657   "TARGET_SHCOMPACT"
3658   "jsr @%1%#"
3659   [(set_attr "type" "sfunc")
3660    (set_attr "needs_delay_slot" "yes")])
3662 (define_insn "movqi_i"
3663   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,m,r,r,l")
3664         (match_operand:QI 1 "general_movsrc_operand"  "ri,m,r,t,l,r"))]
3665   "TARGET_SH1
3666    && (arith_reg_operand (operands[0], QImode)
3667        || arith_reg_operand (operands[1], QImode))"
3668   "@
3669         mov     %1,%0
3670         mov.b   %1,%0
3671         mov.b   %1,%0
3672         movt    %0
3673         sts     %1,%0
3674         lds     %1,%0"
3675  [(set_attr "type" "move,load,store,move,move,move")])
3677 (define_insn "*movqi_media"
3678   [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m")
3679         (match_operand:QI 1 "general_movsrc_operand" "r,I16C16,m,rZ"))]
3680   "TARGET_SHMEDIA
3681    && (arith_reg_operand (operands[0], QImode)
3682        || arith_reg_or_0_operand (operands[1], QImode))"
3683   "@
3684         add.l   %1, r63, %0
3685         movi    %1, %0
3686         ld%M1.ub        %m1, %0
3687         st%M0.b %m0, %N1"
3688   [(set_attr "type" "arith_media,arith_media,load_media,store_media")])
3690 (define_expand "movqi"
3691   [(set (match_operand:QI 0 "general_operand" "")
3692         (match_operand:QI 1 "general_operand"  ""))]
3693   ""
3694   "{ if (prepare_move_operands (operands, QImode)) DONE; }")
3696 (define_expand "reload_inqi"
3697   [(set (match_operand:SI 2 "" "=&r")
3698         (match_operand:QI 1 "inqhi_operand" ""))
3699    (set (match_operand:QI 0 "arith_reg_operand" "=r")
3700         (truncate:QI (match_dup 3)))]
3701   "TARGET_SHMEDIA"
3702   "
3704   rtx inner = XEXP (operands[1], 0);
3705   int regno = REGNO (inner);
3707   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3708   operands[1] = gen_rtx_REG (SImode, regno);
3709   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3712 /* When storing r0, we have to avoid reg+reg addressing.  */
3713 (define_insn "movhi_i"
3714   [(set (match_operand:HI 0 "general_movdst_operand"   "=r,r,r,r,m,r,l,r")
3715         (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))]
3716   "TARGET_SH1
3717    && (arith_reg_operand (operands[0], HImode)
3718        || arith_reg_operand (operands[1], HImode))
3719    && (GET_CODE (operands[0]) != MEM
3720        || GET_CODE (XEXP (operands[0], 0)) != PLUS
3721        || GET_CODE (XEXP (XEXP (operands[0], 0), 1)) != REG
3722        || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))"
3723   "@
3724         mov.w   %1,%0
3725         mov     %1,%0
3726         mov.w   %1,%0
3727         movt    %0
3728         mov.w   %1,%0
3729         sts     %1,%0
3730         lds     %1,%0
3731         fake    %1,%0"
3732   [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")])
3734 (define_insn "*movhi_media"
3735   [(set (match_operand:HI 0 "general_movdst_operand"     "=r,r,r,r,m")
3736         (match_operand:HI 1 "general_movsrc_operand" "r,I16C16,n,m,rZ"))]
3737   "TARGET_SHMEDIA
3738    && (arith_reg_operand (operands[0], HImode)
3739        || arith_reg_or_0_operand (operands[1], HImode))"
3740   "@
3741         add.l   %1, r63, %0
3742         movi    %1, %0
3743         #
3744         ld%M1.w %m1, %0
3745         st%M0.w %m0, %N1"
3746   [(set_attr "type" "arith_media,arith_media,*,load_media,store_media")])
3748 (define_split
3749   [(set (match_operand:HI 0 "register_operand" "")
3750         (match_operand:HI 1 "immediate_operand" ""))]
3751   "TARGET_SHMEDIA && reload_completed
3752    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3753   [(set (subreg:DI (match_dup 0) 0) (match_dup 1))])
3755 (define_expand "movhi"
3756   [(set (match_operand:HI 0 "general_movdst_operand" "")
3757         (match_operand:HI 1 "general_movsrc_operand"  ""))]
3758   ""
3759   "{ if (prepare_move_operands (operands, HImode)) DONE; }")
3761 (define_expand "reload_inhi"
3762   [(set (match_operand:SI 2 "" "=&r")
3763         (match_operand:HI 1 "inqhi_operand" ""))
3764    (set (match_operand:HI 0 "arith_reg_operand" "=r")
3765         (truncate:HI (match_dup 3)))]
3766   "TARGET_SHMEDIA"
3767   "
3769   rtx inner = XEXP (operands[1], 0);
3770   int regno = REGNO (inner);
3772   regno += HARD_REGNO_NREGS (regno, GET_MODE (inner)) - 1;
3773   operands[1] = gen_rtx_REG (SImode, regno);
3774   operands[3] = gen_rtx_REG (DImode, REGNO (operands[2]));
3777 ;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
3778 ;; compiled with -m2 -ml -O3 -funroll-loops
3779 (define_insn "*movdi_i"
3780   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
3781         (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
3782   "TARGET_SH1
3783    && (arith_reg_operand (operands[0], DImode)
3784        || arith_reg_operand (operands[1], DImode))"
3785   "* return output_movedouble (insn, operands, DImode);"
3786   [(set_attr "length" "4")
3787    (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
3789 ;; If the output is a register and the input is memory or a register, we have
3790 ;; to be careful and see which word needs to be loaded first.
3792 (define_split
3793   [(set (match_operand:DI 0 "general_movdst_operand" "")
3794         (match_operand:DI 1 "general_movsrc_operand" ""))]
3795   "TARGET_SH1 && reload_completed"
3796   [(set (match_dup 2) (match_dup 3))
3797    (set (match_dup 4) (match_dup 5))]
3798   "
3800   int regno;
3802   if ((GET_CODE (operands[0]) == MEM
3803        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
3804       || (GET_CODE (operands[1]) == MEM
3805           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
3806     FAIL;
3808   if (GET_CODE (operands[0]) == REG)
3809     regno = REGNO (operands[0]);
3810   else if (GET_CODE (operands[0]) == SUBREG)
3811     regno = subreg_regno (operands[0]);
3812   else if (GET_CODE (operands[0]) == MEM)
3813     regno = -1;
3814   else
3815     abort ();
3817   if (regno == -1
3818       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
3819     {
3820       operands[2] = operand_subword (operands[0], 0, 0, DImode);
3821       operands[3] = operand_subword (operands[1], 0, 0, DImode);
3822       operands[4] = operand_subword (operands[0], 1, 0, DImode);
3823       operands[5] = operand_subword (operands[1], 1, 0, DImode);
3824     }
3825   else
3826     {
3827       operands[2] = operand_subword (operands[0], 1, 0, DImode);
3828       operands[3] = operand_subword (operands[1], 1, 0, DImode);
3829       operands[4] = operand_subword (operands[0], 0, 0, DImode);
3830       operands[5] = operand_subword (operands[1], 0, 0, DImode);
3831     }
3833   if (operands[2] == 0 || operands[3] == 0
3834       || operands[4] == 0 || operands[5] == 0)
3835     FAIL;
3838 (define_insn "*movdi_media"
3839   [(set (match_operand:DI 0 "general_movdst_operand"
3840                  "=r,r,r,rl,m,f,m,f,r,f,*b,r,b")
3841         (match_operand:DI 1 "general_movsrc_operand"
3842          "r,I16C16,nCpgF,m,rlZ,m,f,rZ,f,f,r,*b,Csy"))]
3843   "TARGET_SHMEDIA_FPU
3844    && (register_operand (operands[0], DImode)
3845        || sh_register_operand (operands[1], DImode))"
3846   "@
3847         add     %1, r63, %0
3848         movi    %1, %0
3849         #
3850         ld%M1.q %m1, %0
3851         st%M0.q %m0, %N1
3852         fld%M1.d        %m1, %0
3853         fst%M0.d        %m0, %1
3854         fmov.qd %N1, %0
3855         fmov.dq %1, %0
3856         fmov.d  %1, %0
3857         ptabs   %1, %0
3858         gettr   %1, %0
3859         pt      %1, %0"
3860   [(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")
3861    (set_attr "length" "4,4,16,4,4,4,4,4,4,4,4,4,*")])
3863 (define_insn "*movdi_media_nofpu"
3864   [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,rl,m,*b,r,b")
3865         (match_operand:DI 1 "general_movsrc_operand" "r,I16C16,nCpgF,m,rlZ,r,*b,Csy"))]
3866   "TARGET_SHMEDIA
3867    && (register_operand (operands[0], DImode)
3868        || sh_register_operand (operands[1], DImode))"
3869   "@
3870         add     %1, r63, %0
3871         movi    %1, %0
3872         #
3873         ld%M1.q %m1, %0
3874         st%M0.q %m0, %N1
3875         ptabs   %1, %0
3876         gettr   %1, %0
3877         pt      %1, %0"
3878   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media,ptabs_media,gettr_media,pt_media")
3879    (set_attr "length" "4,4,16,4,4,4,4,*")])
3881 (define_split
3882   [(set (match_operand:DI 0 "arith_reg_operand" "")
3883         (match_operand:DI 1 "immediate_operand" ""))]
3884   "TARGET_SHMEDIA && reload_completed
3885    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3886   [(set (match_dup 0) (match_dup 1))]
3887   "
3889   rtx insn;
3891   if (TARGET_SHMEDIA64)
3892     insn = emit_insn (gen_movdi_const (operands[0], operands[1]));
3893   else
3894     insn = emit_insn (gen_movdi_const_32bit (operands[0], operands[1]));
3896   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
3897                                         REG_NOTES (insn));
3899   DONE;
3902 (define_expand "movdi_const"
3903   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3904         (const:DI (sign_extend:DI
3905                    (truncate:HI
3906                     (ashiftrt:DI
3907                      (match_operand:DI 1 "immediate_operand" "s")
3908                      (const_int 48))))))
3909    (set (match_dup 0)
3910         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3911                 (zero_extend:DI
3912                  (truncate:HI
3913                   (const:DI
3914                    (sign_extend:DI
3915                     (truncate:HI
3916                      (ashiftrt:SI
3917                       (match_dup 1)
3918                       (const_int 32)))))))))
3919    (set (match_dup 0)
3920         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3921                 (zero_extend:DI
3922                  (truncate:HI
3923                   (const:DI
3924                    (sign_extend:DI
3925                     (truncate:HI
3926                      (ashiftrt:SI
3927                       (match_dup 1)
3928                       (const_int 16)))))))))
3929    (set (match_dup 0)
3930         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3931                 (zero_extend:DI
3932                  (truncate:HI
3933                   (const:DI
3934                    (sign_extend:DI
3935                     (truncate:HI
3936                      (match_dup 1))))))))]
3937   "TARGET_SHMEDIA64 && reload_completed
3938    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3939   "
3941   sh_mark_label (operands[1], 4);
3944 (define_expand "movdi_const_32bit"
3945   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3946         (const:DI (sign_extend:DI
3947                    (truncate:HI
3948                     (ashiftrt:DI
3949                      (match_operand:DI 1 "immediate_operand" "s")
3950                      (const_int 16))))))
3951    (set (match_dup 0)
3952         (ior:DI (ashift:DI (match_dup 0) (const_int 16))
3953                 (zero_extend:DI
3954                  (truncate:HI
3955                   (const:DI
3956                    (sign_extend:DI
3957                     (truncate:HI
3958                      (match_dup 1))))))))]
3959   "TARGET_SHMEDIA32 && reload_completed
3960    && MOVI_SHORI_BASE_OPERAND_P (operands[1])"
3961   "
3963   sh_mark_label (operands[1], 2);
3966 (define_expand "movdi_const_16bit"
3967   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
3968         (const:DI (sign_extend:DI
3969                    (truncate:HI
3970                     (match_operand:DI 1 "immediate_operand" "s")))))]
3971   "TARGET_SHMEDIA && flag_pic && reload_completed
3972    && GET_CODE (operands[1]) == SYMBOL_REF"
3973   "")
3975 (define_split
3976   [(set (match_operand:DI 0 "arith_reg_operand" "")
3977         (match_operand:DI 1 "immediate_operand" ""))]
3978   "TARGET_SHMEDIA && reload_completed
3979    && GET_CODE (operands[1]) == CONST_INT
3980    && ! CONST_OK_FOR_I16 (INTVAL (operands[1]))"
3981   [(set (match_dup 0) (match_dup 2))
3982    (match_dup 1)]
3983   "
3985   unsigned HOST_WIDE_INT val = INTVAL (operands[1]);
3986   unsigned HOST_WIDE_INT low = val;
3987   unsigned HOST_WIDE_INT high = val;
3988   unsigned HOST_WIDE_INT sign;
3989   unsigned HOST_WIDE_INT val2 = val ^ (val-1);
3991   /* Sign-extend the 16 least-significant bits.  */
3992   low &= 0xffff;
3993   low ^= 0x8000;
3994   low -= 0x8000;
3996   /* Arithmetic shift right the word by 16 bits.  */
3997   high >>= 16;
3998   sign = 1;
3999   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4000   high ^= sign;
4001   high -= sign;
4002   do
4003     {
4004       /* If we can't generate the constant with a two-insn movi / shori
4005          sequence, try some other strategies.  */
4006       if (! CONST_OK_FOR_I16 (high))
4007         {
4008           /* Try constant load / left shift.  We know VAL != 0.  */
4009           val2 = val ^ (val-1);
4010           if (val2 > 0x1ffff)
4011             {
4012               int trailing_zeroes = exact_log2 ((val2 >> 16) + 1) + 15;
4014               if (CONST_OK_FOR_I16 (val >> trailing_zeroes)
4015                   || (! CONST_OK_FOR_I16 (high >> 16)
4016                       && CONST_OK_FOR_I16 (val >> (trailing_zeroes + 16))))
4017                 {
4018                   val2 = (HOST_WIDE_INT) val >> trailing_zeroes;
4019                   operands[1] = gen_ashldi3_media (operands[0], operands[0],
4020                                                    GEN_INT (trailing_zeroes));
4021                   break;
4022                 }
4023             }
4024           /* Try constant load / right shift.  */
4025           val2 = (val >> 15) + 1;
4026           if (val2 == (val2 & -val2))
4027             {
4028               int shift = 49 - exact_log2 (val2);
4030               val2 = trunc_int_for_mode (val << shift, DImode);
4031               if (CONST_OK_FOR_I16 (val2))
4032                 {
4033                   operands[1] = gen_lshrdi3_media (operands[0], operands[0],
4034                                                    GEN_INT (shift));
4035                   break;
4036                 }
4037             }
4038           /* Try mperm.w .  */
4039           val2 = val & 0xffff;
4040           if ((val >> 16 & 0xffff) == val2
4041               && (val >> 32 & 0xffff) == val2
4042               && (val >> 48 & 0xffff) == val2)
4043             {
4044               val2 = (HOST_WIDE_INT) val >> 48;
4045               operands[1] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
4046               operands[1] = gen_mperm_w0 (operands[1], operands[1]);
4047               break;
4048             }
4049           /* Try movi / mshflo.l  */
4050           val2 = (HOST_WIDE_INT) val >> 32;
4051           if (val2 == ((unsigned HOST_WIDE_INT)
4052                         trunc_int_for_mode (val, SImode)))
4053             {
4054               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4055                                              operands[0]);
4056               break;
4057             }
4058           /* Try movi / mshflo.l w/ r63.  */
4059           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4060           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4061             {
4062               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4063                                              const0_rtx);
4064               break;
4065             }
4066         }
4067       val2 = high;
4068       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4069     }
4070   while (0);
4071   operands[2] = GEN_INT (val2);
4074 (define_split
4075   [(set (match_operand:DI 0 "arith_reg_operand" "")
4076         (match_operand:DI 1 "immediate_operand" ""))]
4077   "TARGET_SHMEDIA && reload_completed
4078    && GET_CODE (operands[1]) == CONST_DOUBLE"
4079   [(set (match_dup 0) (match_dup 2))
4080   (set (match_dup 0)
4081        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4082                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4083   "
4085   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4086   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4087   unsigned HOST_WIDE_INT val = low;
4088   unsigned HOST_WIDE_INT sign;
4090   /* Sign-extend the 16 least-significant bits.  */
4091   val &= 0xffff;
4092   val ^= 0x8000;
4093   val -= 0x8000;
4094   operands[1] = GEN_INT (val);
4096   /* Arithmetic shift right the double-word by 16 bits.  */
4097   low >>= 16;
4098   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4099   high >>= 16;
4100   sign = 1;
4101   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4102   high ^= sign;
4103   high -= sign;
4105   /* This will only be true if high is a sign-extension of low, i.e.,
4106      it must be either 0 or (unsigned)-1, and be zero iff the
4107      most-significant bit of low is set.  */
4108   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4109     operands[2] = GEN_INT (low);
4110   else
4111     operands[2] = immed_double_const (low, high, DImode);
4114 (define_insn "shori_media"
4115   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4116         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4117                            (const_int 16))
4118                 (zero_extend:DI
4119                  (truncate:HI
4120                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4121   "TARGET_SHMEDIA"
4122   "@
4123         shori   %u2, %0
4124         #"
4125   [(set_attr "type" "arith_media,*")])
4127 (define_expand "movdi"
4128   [(set (match_operand:DI 0 "general_movdst_operand" "")
4129         (match_operand:DI 1 "general_movsrc_operand" ""))]
4130   ""
4131   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4133 (define_insn "movdf_media"
4134   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4135         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4136   "TARGET_SHMEDIA_FPU
4137    && (register_operand (operands[0], DFmode)
4138        || sh_register_operand (operands[1], DFmode))"
4139   "@
4140         fmov.d  %1, %0
4141         fmov.qd %N1, %0
4142         fmov.dq %1, %0
4143         add     %1, r63, %0
4144         #
4145         fld%M1.d        %m1, %0
4146         fst%M0.d        %m0, %1
4147         ld%M1.q %m1, %0
4148         st%M0.q %m0, %N1"
4149   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4151 (define_insn "movdf_media_nofpu"
4152   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4153         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4154   "TARGET_SHMEDIA
4155    && (register_operand (operands[0], DFmode)
4156        || sh_register_operand (operands[1], DFmode))"
4157   "@
4158         add     %1, r63, %0
4159         #
4160         ld%M1.q %m1, %0
4161         st%M0.q %m0, %N1"
4162   [(set_attr "type" "arith_media,*,load_media,store_media")])
4164 (define_split
4165   [(set (match_operand:DF 0 "arith_reg_operand" "")
4166         (match_operand:DF 1 "immediate_operand" ""))]
4167   "TARGET_SHMEDIA && reload_completed"
4168   [(set (match_dup 3) (match_dup 2))]
4169   "
4171   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4172   long values[2];
4173   REAL_VALUE_TYPE value;
4175   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4176   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4178   if (HOST_BITS_PER_WIDE_INT >= 64)
4179     operands[2] = immed_double_const ((unsigned long) values[endian]
4180                                       | ((HOST_WIDE_INT) values[1 - endian]
4181                                          << 32), 0, DImode);
4182   else if (HOST_BITS_PER_WIDE_INT == 32)
4183     operands[2] = immed_double_const (values[endian], values[1 - endian],
4184                                       DImode);
4185   else
4186     abort ();
4188   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4191 ;; ??? This should be a define expand.
4193 (define_insn "movdf_k"
4194   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4195         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4196   "TARGET_SH1
4197    && (! TARGET_SH4 || reload_completed
4198        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4199        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4200        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4201    && (arith_reg_operand (operands[0], DFmode)
4202        || arith_reg_operand (operands[1], DFmode))"
4203   "* return output_movedouble (insn, operands, DFmode);"
4204   [(set_attr "length" "4")
4205    (set_attr "type" "move,pcload,load,store")])
4207 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4208 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4209 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4210 ;; the d/m/c/X alternative, which is split later into single-precision
4211 ;; instructions.  And when not optimizing, no splits are done before fixing
4212 ;; up pcloads, so we need usable length information for that.
4213 (define_insn "movdf_i4"
4214   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4215         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4216    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4217    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4218   "TARGET_SH4
4219    && (arith_reg_operand (operands[0], DFmode)
4220        || arith_reg_operand (operands[1], DFmode))"
4221   "@
4222         fmov    %1,%0
4223         #
4224         #
4225         fmov.d  %1,%0
4226         fmov.d  %1,%0
4227         #
4228         #
4229         #
4230         #
4231         #"
4232   [(set_attr_alternative "length"
4233      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4234       (const_int 4)
4235       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4236       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4237       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4238       (const_int 4)
4239       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4240       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4241       ;; increment or decrement r15 explicitly.
4242       (if_then_else
4243        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4244        (const_int 10) (const_int 8))
4245       (if_then_else
4246        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4247        (const_int 10) (const_int 8))])
4248    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4249    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4250    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4251                                            (const_string "double")
4252                                            (const_string "none")))])
4254 ;; Moving DFmode between fp/general registers through memory
4255 ;; (the top of the stack) is faster than moving through fpul even for
4256 ;; little endian.  Because the type of an instruction is important for its
4257 ;; scheduling,  it is beneficial to split these operations, rather than
4258 ;; emitting them in one single chunk, even if this will expose a stack
4259 ;; use that will prevent scheduling of other stack accesses beyond this
4260 ;; instruction.
4261 (define_split
4262   [(set (match_operand:DF 0 "register_operand" "")
4263         (match_operand:DF 1 "register_operand" ""))
4264    (use (match_operand:PSI 2 "fpscr_operand" ""))
4265    (clobber (match_scratch:SI 3 "=X"))]
4266   "TARGET_SH4 && reload_completed
4267    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4268   [(const_int 0)]
4269   "
4271   rtx insn, tos;
4273   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4274     {
4275       emit_move_insn (stack_pointer_rtx,
4276                       plus_constant (stack_pointer_rtx, -8));
4277       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4278     }
4279   else
4280     tos = gen_rtx_MEM (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
4281   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4282   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4283     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4284   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4285     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4286   else
4287     tos = gen_rtx_MEM (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
4288   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4289   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4290     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4291   else
4292     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, stack_pointer_rtx, NULL_RTX);
4293   DONE;
4296 ;; local-alloc sometimes allocates scratch registers even when not required,
4297 ;; so we must be prepared to handle these.
4299 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4300 (define_split
4301   [(set (match_operand:DF 0 "general_movdst_operand" "")
4302         (match_operand:DF 1 "general_movsrc_operand"  ""))
4303    (use (match_operand:PSI 2 "fpscr_operand" ""))
4304    (clobber (match_scratch:SI 3 ""))]
4305   "TARGET_SH4
4306    && reload_completed
4307    && true_regnum (operands[0]) < 16
4308    && true_regnum (operands[1]) < 16"
4309   [(set (match_dup 0) (match_dup 1))]
4310   "
4312   /* If this was a reg <-> mem operation with base + index reg addressing,
4313      we have to handle this in a special way.  */
4314   rtx mem = operands[0];
4315   int store_p = 1;
4316   if (! memory_operand (mem, DFmode))
4317     {
4318       mem = operands[1];
4319       store_p = 0;
4320     }
4321   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4322     mem = SUBREG_REG (mem);
4323   if (GET_CODE (mem) == MEM)
4324     {
4325       rtx addr = XEXP (mem, 0);
4326       if (GET_CODE (addr) == PLUS
4327           && GET_CODE (XEXP (addr, 0)) == REG
4328           && GET_CODE (XEXP (addr, 1)) == REG)
4329         {
4330           int offset;
4331           rtx reg0 = gen_rtx_REG (Pmode, 0);
4332           rtx regop = operands[store_p], word0 ,word1;
4334           if (GET_CODE (regop) == SUBREG)
4335             alter_subreg (&regop);
4336           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4337             offset = 2;
4338           else
4339             offset = 4;
4340           mem = copy_rtx (mem);
4341           PUT_MODE (mem, SImode);
4342           word0 = gen_rtx_SUBREG (SImode, regop, 0);
4343           alter_subreg (&word0);
4344           word1 = gen_rtx_SUBREG (SImode, regop, 4);
4345           alter_subreg (&word1);
4346           if (store_p || ! refers_to_regno_p (REGNO (word0),
4347                                               REGNO (word0) + 1, addr, 0))
4348             {
4349               emit_insn (store_p
4350                          ? gen_movsi_ie (mem, word0)
4351                          : gen_movsi_ie (word0, mem));
4352               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4353               mem = copy_rtx (mem);
4354               emit_insn (store_p
4355                          ? gen_movsi_ie (mem, word1)
4356                          : gen_movsi_ie (word1, mem));
4357               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4358             }
4359           else
4360             {
4361               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4362               emit_insn (gen_movsi_ie (word1, mem));
4363               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4364               mem = copy_rtx (mem);
4365               emit_insn (gen_movsi_ie (word0, mem));
4366             }
4367           DONE;
4368         }
4369     }
4372 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4373 (define_split
4374   [(set (match_operand:DF 0 "register_operand" "")
4375         (match_operand:DF 1 "memory_operand"  ""))
4376    (use (match_operand:PSI 2 "fpscr_operand" ""))
4377    (clobber (reg:SI R0_REG))]
4378   "TARGET_SH4 && reload_completed"
4379   [(parallel [(set (match_dup 0) (match_dup 1))
4380               (use (match_dup 2))
4381               (clobber (scratch:SI))])]
4382   "")
4384 (define_expand "reload_indf"
4385   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4386                    (match_operand:DF 1 "immediate_operand" "FQ"))
4387               (use (reg:PSI FPSCR_REG))
4388               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4389   "TARGET_SH1"
4390   "")
4392 (define_expand "reload_outdf"
4393   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4394                    (match_operand:DF 1 "register_operand" "af,r"))
4395               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4396   "TARGET_SH1"
4397   "")
4399 ;; Simplify no-op moves.
4400 (define_split
4401   [(set (match_operand:SF 0 "register_operand" "")
4402         (match_operand:SF 1 "register_operand" ""))
4403    (use (match_operand:PSI 2 "fpscr_operand" ""))
4404    (clobber (match_scratch:SI 3 ""))]
4405   "TARGET_SH2E && reload_completed
4406    && true_regnum (operands[0]) == true_regnum (operands[1])"
4407   [(set (match_dup 0) (match_dup 0))]
4408   "")
4410 ;; fmovd substitute post-reload splits
4411 (define_split
4412   [(set (match_operand:DF 0 "register_operand" "")
4413         (match_operand:DF 1 "register_operand" ""))
4414    (use (match_operand:PSI 2 "fpscr_operand" ""))
4415    (clobber (match_scratch:SI 3 ""))]
4416   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4417    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4418    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4419   [(const_int 0)]
4420   "
4422   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4423   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst),
4424                            gen_rtx_REG (SFmode, src), operands[2]));
4425   emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1),
4426                            gen_rtx_REG (SFmode, src + 1), operands[2]));
4427   DONE;
4430 (define_split
4431   [(set (match_operand:DF 0 "register_operand" "")
4432         (mem:DF (match_operand:SI 1 "register_operand" "")))
4433    (use (match_operand:PSI 2 "fpscr_operand" ""))
4434    (clobber (match_scratch:SI 3 ""))]
4435   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4436    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4437    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4438   [(const_int 0)]
4439   "
4441   int regno = true_regnum (operands[0]);
4442   rtx insn;
4443   rtx mem2 = gen_rtx_MEM (SFmode, gen_rtx_POST_INC (Pmode, operands[1]));
4445   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4446                                            regno + !! TARGET_LITTLE_ENDIAN),
4447                                   mem2, operands[2]));
4448   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[1], NULL_RTX);
4449   insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode,
4450                                            regno + ! TARGET_LITTLE_ENDIAN),
4451                                   gen_rtx_MEM (SFmode, operands[1]),
4452                                   operands[2]));
4453   DONE;
4456 (define_split
4457   [(set (match_operand:DF 0 "register_operand" "")
4458         (match_operand:DF 1 "memory_operand" ""))
4459    (use (match_operand:PSI 2 "fpscr_operand" ""))
4460    (clobber (match_scratch:SI 3 ""))]
4461   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4462    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4463   [(const_int 0)]
4464   "
4466   int regno = true_regnum (operands[0]);
4467   rtx addr, insn, adjust = NULL_RTX;
4468   rtx mem2 = copy_rtx (operands[1]);
4469   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4470   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4472   PUT_MODE (mem2, SFmode);
4473   operands[1] = copy_rtx (mem2);
4474   addr = XEXP (mem2, 0);
4475   if (GET_CODE (addr) != POST_INC)
4476     {
4477       /* If we have to modify the stack pointer, the value that we have
4478          read with post-increment might be modified by an interrupt,
4479          so write it back.  */
4480       if (REGNO (addr) == STACK_POINTER_REGNUM)
4481         adjust = gen_push_e (reg0);
4482       else
4483         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4484       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4485     }
4486   addr = XEXP (addr, 0);
4487   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4488   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4489   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4490   if (adjust)
4491     emit_insn (adjust);
4492   else
4493     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4494   DONE;
4497 (define_split
4498   [(set (match_operand:DF 0 "memory_operand" "")
4499         (match_operand:DF 1 "register_operand" ""))
4500    (use (match_operand:PSI 2 "fpscr_operand" ""))
4501    (clobber (match_scratch:SI 3 ""))]
4502   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4503    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4504   [(const_int 0)]
4505   "
4507   int regno = true_regnum (operands[1]);
4508   rtx insn, addr, adjust = NULL_RTX;
4510   operands[0] = copy_rtx (operands[0]);
4511   PUT_MODE (operands[0], SFmode);
4512   insn = emit_insn (gen_movsf_ie (operands[0],
4513                                   gen_rtx_REG (SFmode,
4514                                            regno + ! TARGET_LITTLE_ENDIAN),
4515                                   operands[2]));
4516   operands[0] = copy_rtx (operands[0]);
4517   addr = XEXP (operands[0], 0);
4518   if (GET_CODE (addr) != PRE_DEC)
4519     {
4520       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4521       emit_insn_before (adjust, insn);
4522       XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr);
4523     }
4524   addr = XEXP (addr, 0);
4525   if (! adjust)
4526     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4527   insn = emit_insn (gen_movsf_ie (operands[0],
4528                                   gen_rtx_REG (SFmode,
4529                                            regno + !! TARGET_LITTLE_ENDIAN),
4530                                   operands[2]));
4531   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4532   DONE;
4535 ;; If the output is a register and the input is memory or a register, we have
4536 ;; to be careful and see which word needs to be loaded first.
4538 (define_split
4539   [(set (match_operand:DF 0 "general_movdst_operand" "")
4540         (match_operand:DF 1 "general_movsrc_operand" ""))]
4541   "TARGET_SH1 && reload_completed"
4542   [(set (match_dup 2) (match_dup 3))
4543    (set (match_dup 4) (match_dup 5))]
4544   "
4546   int regno;
4548   if ((GET_CODE (operands[0]) == MEM
4549        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4550       || (GET_CODE (operands[1]) == MEM
4551           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4552     FAIL;
4554   if (GET_CODE (operands[0]) == REG)
4555     regno = REGNO (operands[0]);
4556   else if (GET_CODE (operands[0]) == SUBREG)
4557     regno = subreg_regno (operands[0]);
4558   else if (GET_CODE (operands[0]) == MEM)
4559     regno = -1;
4560   else
4561     abort ();
4563   if (regno == -1
4564       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4565     {
4566       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4567       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4568       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4569       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4570     }
4571   else
4572     {
4573       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4574       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4575       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4576       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4577     }
4579   if (operands[2] == 0 || operands[3] == 0
4580       || operands[4] == 0 || operands[5] == 0)
4581     FAIL;
4584 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4585 ;; used only once, let combine add in the index again.
4587 (define_split
4588   [(set (match_operand:SI 0 "register_operand" "")
4589         (match_operand:SI 1 "" ""))
4590    (clobber (match_operand 2 "register_operand" ""))]
4591   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4592   [(use (reg:SI R0_REG))]
4593   "
4595   rtx addr, reg, const_int;
4597   if (GET_CODE (operands[1]) != MEM)
4598     FAIL;
4599   addr = XEXP (operands[1], 0);
4600   if (GET_CODE (addr) != PLUS)
4601     FAIL;
4602   reg = XEXP (addr, 0);
4603   const_int = XEXP (addr, 1);
4604   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4605          && GET_CODE (const_int) == CONST_INT))
4606     FAIL;
4607   emit_move_insn (operands[2], const_int);
4608   emit_move_insn (operands[0],
4609                   change_address (operands[1], VOIDmode,
4610                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4611   DONE;
4614 (define_split
4615   [(set (match_operand:SI 1 "" "")
4616         (match_operand:SI 0 "register_operand" ""))
4617    (clobber (match_operand 2 "register_operand" ""))]
4618   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4619   [(use (reg:SI R0_REG))]
4620   "
4622   rtx addr, reg, const_int;
4624   if (GET_CODE (operands[1]) != MEM)
4625     FAIL;
4626   addr = XEXP (operands[1], 0);
4627   if (GET_CODE (addr) != PLUS)
4628     FAIL;
4629   reg = XEXP (addr, 0);
4630   const_int = XEXP (addr, 1);
4631   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4632          && GET_CODE (const_int) == CONST_INT))
4633     FAIL;
4634   emit_move_insn (operands[2], const_int);
4635   emit_move_insn (change_address (operands[1], VOIDmode,
4636                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4637                   operands[0]);
4638   DONE;
4641 (define_expand "movdf"
4642   [(set (match_operand:DF 0 "general_movdst_operand" "")
4643         (match_operand:DF 1 "general_movsrc_operand" ""))]
4644   ""
4645   "
4647   if (prepare_move_operands (operands, DFmode)) DONE;
4648   if (TARGET_SHMEDIA)
4649     {
4650       if (TARGET_SHMEDIA_FPU)
4651         emit_insn (gen_movdf_media (operands[0], operands[1]));
4652       else
4653         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4654       DONE;
4655     }
4656   if (TARGET_SH4)
4657     {
4658       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4659       DONE;
4660     }
4663 ;;This is incompatible with the way gcc uses subregs.
4664 ;;(define_insn "movv2sf_i"
4665 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4666 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4667 ;;  "TARGET_SHMEDIA_FPU
4668 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4669 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4670 ;;  "@
4671 ;;      #
4672 ;;      fld%M1.p        %m1, %0
4673 ;;      fst%M0.p        %m0, %1"
4674 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4676 (define_insn_and_split "movv2sf_i"
4677   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4678         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4679   "TARGET_SHMEDIA_FPU"
4680   "#"
4681   "TARGET_SHMEDIA_FPU && reload_completed"
4682   [(set (match_dup 0) (match_dup 1))]
4683   "
4685   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4686   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4689 (define_expand "movv2sf"
4690   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4691         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4692   "TARGET_SHMEDIA_FPU"
4693   "
4695   if (prepare_move_operands (operands, V2SFmode))
4696     DONE;
4699 (define_expand "addv2sf3"
4700   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4701    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4702    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4703   "TARGET_SHMEDIA_FPU"
4704   "
4706   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4707   DONE;
4710 (define_expand "subv2sf3"
4711   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4712    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4713    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4714   "TARGET_SHMEDIA_FPU"
4715   "
4717   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4718   DONE;
4721 (define_expand "mulv2sf3"
4722   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4723    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4724    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4725   "TARGET_SHMEDIA_FPU"
4726   "
4728   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4729   DONE;
4732 (define_expand "divv2sf3"
4733   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4734    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4735    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4736   "TARGET_SHMEDIA_FPU"
4737   "
4739   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4740   DONE;
4743 (define_insn_and_split "*movv4sf_i"
4744   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4745         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4746   "TARGET_SHMEDIA_FPU"
4747   "#"
4748   "&& reload_completed"
4749   [(const_int 0)]
4750   "
4752   int i;
4754   for (i = 0; i < 4/2; i++)
4755     {
4756       rtx x, y;
4758       if (GET_CODE (operands[0]) == MEM)
4759         x = gen_rtx_MEM (V2SFmode,
4760                          plus_constant (XEXP (operands[0], 0),
4761                                         i * GET_MODE_SIZE (V2SFmode)));
4762       else
4763         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4765       if (GET_CODE (operands[1]) == MEM)
4766         y = gen_rtx_MEM (V2SFmode,
4767                          plus_constant (XEXP (operands[1], 0),
4768                                         i * GET_MODE_SIZE (V2SFmode)));
4769       else
4770         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4772       emit_insn (gen_movv2sf_i (x, y));
4773     }
4775   DONE;
4777   [(set_attr "length" "8")])
4779 (define_expand "movv4sf"
4780   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4781         (match_operand:V4SF 1 "general_operand" ""))]
4782   "TARGET_SHMEDIA_FPU"
4783   "
4785   if (prepare_move_operands (operands, V4SFmode))
4786     DONE;
4789 (define_insn_and_split "*movv16sf_i"
4790   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4791         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4792   "TARGET_SHMEDIA_FPU"
4793   "#"
4794   "&& reload_completed"
4795   [(const_int 0)]
4796   "
4798   int i;
4800   for (i = 0; i < 16/2; i++)
4801     {
4802       rtx x,y;
4804       if (GET_CODE (operands[0]) == MEM)
4805         x = gen_rtx_MEM (V2SFmode,
4806                          plus_constant (XEXP (operands[0], 0),
4807                                         i * GET_MODE_SIZE (V2SFmode)));
4808       else
4809         {
4810           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4811           alter_subreg (&x);
4812         }
4814       if (GET_CODE (operands[1]) == MEM)
4815         y = gen_rtx_MEM (V2SFmode,
4816                          plus_constant (XEXP (operands[1], 0),
4817                                         i * GET_MODE_SIZE (V2SFmode)));
4818       else
4819         {
4820           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4821           alter_subreg (&y);
4822         }
4824       emit_insn (gen_movv2sf_i (x, y));
4825     }
4827   DONE;
4829   [(set_attr "length" "32")])
4831 (define_expand "movv16sf"
4832   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4833         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4834   "TARGET_SHMEDIA_FPU"
4835   "
4837   if (prepare_move_operands (operands, V16SFmode))
4838     DONE;
4841 (define_insn "movsf_media"
4842   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4843         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4844   "TARGET_SHMEDIA_FPU
4845    && (register_operand (operands[0], SFmode)
4846        || sh_register_operand (operands[1], SFmode))"
4847   "@
4848         fmov.s  %1, %0
4849         fmov.ls %N1, %0
4850         fmov.sl %1, %0
4851         add.l   %1, r63, %0
4852         #
4853         fld%M1.s        %m1, %0
4854         fst%M0.s        %m0, %1
4855         ld%M1.l %m1, %0
4856         st%M0.l %m0, %N1"
4857   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4859 (define_insn "movsf_media_nofpu"
4860   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4861         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4862   "TARGET_SHMEDIA
4863    && (register_operand (operands[0], SFmode)
4864        || sh_register_operand (operands[1], SFmode))"
4865   "@
4866         add.l   %1, r63, %0
4867         #
4868         ld%M1.l %m1, %0
4869         st%M0.l %m0, %N1"
4870   [(set_attr "type" "arith_media,*,load_media,store_media")])
4872 (define_split
4873   [(set (match_operand:SF 0 "arith_reg_operand" "")
4874         (match_operand:SF 1 "immediate_operand" ""))]
4875   "TARGET_SHMEDIA && reload_completed
4876    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4877   [(set (match_dup 3) (match_dup 2))]
4878   "
4880   long values;
4881   REAL_VALUE_TYPE value;
4883   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4884   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4885   operands[2] = GEN_INT (values);
4887   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4890 (define_insn "movsf_i"
4891   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4892         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4893   "TARGET_SH1
4894    && (! TARGET_SH2E
4895        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4896        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4897        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4898    && (arith_reg_operand (operands[0], SFmode)
4899        || arith_reg_operand (operands[1], SFmode))"
4900   "@
4901         mov     %1,%0
4902         mov     #0,%0
4903         mov.l   %1,%0
4904         mov.l   %1,%0
4905         mov.l   %1,%0
4906         lds     %1,%0
4907         sts     %1,%0"
4908   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4910 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4911 ;; update_flow_info would not know where to put REG_EQUAL notes
4912 ;; when the destination changes mode.
4913 (define_insn "movsf_ie"
4914   [(set (match_operand:SF 0 "general_movdst_operand"
4915          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4916         (match_operand:SF 1 "general_movsrc_operand"
4917           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4918    (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"))
4919    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4921   "TARGET_SH2E
4922    && (arith_reg_operand (operands[0], SFmode)
4923        || arith_reg_operand (operands[1], SFmode)
4924        || arith_reg_operand (operands[3], SImode)
4925        || (fpul_operand (operands[0], SFmode)
4926            && memory_operand (operands[1], SFmode)
4927            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4928        || (fpul_operand (operands[1], SFmode)
4929            && memory_operand (operands[0], SFmode)
4930            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4931   "@
4932         fmov    %1,%0
4933         mov     %1,%0
4934         fldi0   %0
4935         fldi1   %0
4936         #
4937         fmov.s  %1,%0
4938         fmov.s  %1,%0
4939         mov.l   %1,%0
4940         mov.l   %1,%0
4941         mov.l   %1,%0
4942         fsts    fpul,%0
4943         flds    %1,fpul
4944         lds.l   %1,%0
4945         #
4946         sts     %1,%0
4947         lds     %1,%0
4948         sts.l   %1,%0
4949         lds.l   %1,%0
4950         ! move optimized away"
4951   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4952    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4953    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4954    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4955                                            (const_string "single")
4956                                            (const_string "none")))])
4958 (define_split
4959   [(set (match_operand:SF 0 "register_operand" "")
4960         (match_operand:SF 1 "register_operand" ""))
4961    (use (match_operand:PSI 2 "fpscr_operand" ""))
4962    (clobber (reg:SI FPUL_REG))]
4963   "TARGET_SH1"
4964   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4965               (use (match_dup 2))
4966               (clobber (scratch:SI))])
4967    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4968               (use (match_dup 2))
4969               (clobber (scratch:SI))])]
4970   "")
4972 (define_expand "movsf"
4973   [(set (match_operand:SF 0 "general_movdst_operand" "")
4974         (match_operand:SF 1 "general_movsrc_operand" ""))]
4975   ""
4976   "
4978   if (prepare_move_operands (operands, SFmode))
4979     DONE;
4980   if (TARGET_SHMEDIA)
4981     {
4982       if (TARGET_SHMEDIA_FPU)
4983         emit_insn (gen_movsf_media (operands[0], operands[1]));
4984       else
4985         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4986       DONE;
4987     }
4988   if (TARGET_SH2E)
4989     {
4990       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4991       DONE;
4992     }
4995 (define_insn "mov_nop"
4996   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4997   "TARGET_SH2E"
4998   ""
4999   [(set_attr "length" "0")
5000    (set_attr "type" "nil")])
5002 (define_expand "reload_insf"
5003   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
5004                    (match_operand:SF 1 "immediate_operand" "FQ"))
5005               (use (reg:PSI FPSCR_REG))
5006               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5007   "TARGET_SH1"
5008   "")
5010 (define_expand "reload_insi"
5011   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5012                    (match_operand:SF 1 "immediate_operand" "FQ"))
5013               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5014   "TARGET_SH1"
5015   "")
5017 (define_insn "*movsi_y"
5018   [(set (match_operand:SI 0 "register_operand" "=y,y")
5019         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5020    (clobber (match_scratch:SI 2 "=&z,r"))]
5021   "TARGET_SH2E
5022    && (reload_in_progress || reload_completed)"
5023   "#"
5024   [(set_attr "length" "4")
5025    (set_attr "type" "pcload,move")])
5027 (define_split
5028   [(set (match_operand:SI 0 "register_operand" "")
5029         (match_operand:SI 1 "immediate_operand" ""))
5030    (clobber (match_operand:SI 2 "register_operand" ""))]
5031   "TARGET_SH1"
5032   [(set (match_dup 2) (match_dup 1))
5033    (set (match_dup 0) (match_dup 2))]
5034   "")
5036 (define_split
5037   [(set (match_operand:SI 0 "register_operand" "")
5038         (match_operand:SI 1 "memory_operand" ""))
5039    (clobber (reg:SI R0_REG))]
5040   "TARGET_SH1"
5041   [(set (match_dup 0) (match_dup 1))]
5042   "")
5044 ;; ------------------------------------------------------------------------
5045 ;; Define the real conditional branch instructions.
5046 ;; ------------------------------------------------------------------------
5048 (define_insn "branch_true"
5049   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5050                            (label_ref (match_operand 0 "" ""))
5051                            (pc)))]
5052   "TARGET_SH1"
5053   "* return output_branch (1, insn, operands);"
5054   [(set_attr "type" "cbranch")])
5056 (define_insn "branch_false"
5057   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5058                            (label_ref (match_operand 0 "" ""))
5059                            (pc)))]
5060   "TARGET_SH1"
5061   "* return output_branch (0, insn, operands);"
5062   [(set_attr "type" "cbranch")])
5064 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5065 ;; which destination is too far away.
5066 ;; The const_int_operand is distinct for each branch target; it avoids
5067 ;; unwanted matches with redundant_insn.
5068 (define_insn "block_branch_redirect"
5069   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5070   "TARGET_SH1"
5071   ""
5072   [(set_attr "length" "0")])
5074 ;; This one has the additional purpose to record a possible scratch register
5075 ;; for the following branch.
5076 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5077 ;; because the insn then might be deemed dead and deleted.  And we can't
5078 ;; make the use in the jump insn explicit because that would disable
5079 ;; delay slot scheduling from the target.
5080 (define_insn "indirect_jump_scratch"
5081   [(set (match_operand:SI 0 "register_operand" "=r")
5082         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5083    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5084   "TARGET_SH1"
5085   ""
5086   [(set_attr "length" "0")])
5088 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5089 ;; being pulled into the delay slot of a condbranch that has been made to
5090 ;; jump around the unconditional jump because it was out of range.
5091 (define_insn "stuff_delay_slot"
5092   [(set (pc)
5093         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5094    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5095   "TARGET_SH1"
5096   ""
5097   [(set_attr "length" "0")
5098    (set_attr "cond_delay_slot" "yes")])
5100 ;; Conditional branch insns
5102 (define_expand "beq_media"
5103   [(set (pc)
5104         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5105                           (match_operand:DI 2 "arith_operand" "r,I06"))
5106                       (label_ref:DI (match_operand 0 "" ""))
5107                       (pc)))]
5108   "TARGET_SHMEDIA"
5109   "")
5111 (define_insn "*beq_media_i"
5112   [(set (pc)
5113         (if_then_else (match_operator 3 "equality_comparison_operator"
5114                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5115                          (match_operand:DI 2 "arith_operand" "r,I06")])
5116                       (match_operand:DI 0 "target_operand" "b,b")
5117                       (pc)))]
5118   "TARGET_SHMEDIA"
5119   "@
5120         b%o3%'  %1, %2, %0
5121         b%o3i%' %1, %2, %0"
5122   [(set_attr "type" "cbranch_media")])
5124 (define_expand "bne_media"
5125   [(set (pc)
5126         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5127                           (match_operand:DI 2 "arith_operand" "r,I06"))
5128                       (label_ref:DI (match_operand 0 "" ""))
5129                       (pc)))]
5130   "TARGET_SHMEDIA"
5131   "")
5133 (define_expand "bgt_media"
5134   [(set (pc)
5135         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5136                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5137                       (label_ref:DI (match_operand 0 "" ""))
5138                       (pc)))]
5139   "TARGET_SHMEDIA"
5140   "")
5142 (define_expand "bge_media"
5143   [(set (pc)
5144         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5145                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5146                       (label_ref:DI (match_operand 0 "" ""))
5147                       (pc)))]
5148   "TARGET_SHMEDIA"
5149   "")
5151 (define_expand "bgtu_media"
5152   [(set (pc)
5153         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5154                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5155                       (label_ref:DI (match_operand 0 "" ""))
5156                       (pc)))]
5157   "TARGET_SHMEDIA"
5158   "")
5160 (define_expand "bgeu_media"
5161   [(set (pc)
5162         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5163                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5164                       (label_ref:DI (match_operand 0 "" ""))
5165                       (pc)))]
5166   "TARGET_SHMEDIA"
5167   "")
5169 (define_insn "*bgt_media_i"
5170   [(set (pc)
5171         (if_then_else (match_operator 3 "greater_comparison_operator"
5172                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5173                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5174                       (match_operand:DI 0 "target_operand" "b")
5175                       (pc)))]
5176   "TARGET_SHMEDIA"
5177   "b%o3%'       %N1, %N2, %0"
5178   [(set_attr "type" "cbranch_media")])
5180 ;; These are only needed to make invert_jump() happy.
5181 (define_insn "*blt_media_i"
5182   [(set (pc)
5183         (if_then_else (match_operator 3 "less_comparison_operator"
5184                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5185                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5186                       (match_operand:DI 0 "target_operand" "b")
5187                       (pc)))]
5188   "TARGET_SHMEDIA"
5189   "b%o3%'       %N2, %N1, %0"
5190   [(set_attr "type" "cbranch_media")])
5192 (define_expand "beq"
5193   [(set (pc)
5194         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5195                       (label_ref (match_operand 0 "" ""))
5196                       (pc)))]
5197   ""
5198   "
5200   if (TARGET_SHMEDIA)
5201     {
5202       if (GET_MODE (sh_compare_op0) != DImode)
5203         {
5204           rtx tmp = gen_reg_rtx (DImode);
5206           emit_insn (gen_seq (tmp));
5207           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5208           DONE;
5209         }
5211       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5212       emit_jump_insn (gen_beq_media (operands[0],
5213                                      sh_compare_op0, sh_compare_op1));
5214       DONE;
5215     }
5217   from_compare (operands, EQ);
5220 (define_expand "bne"
5221   [(set (pc)
5222         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5223                       (label_ref (match_operand 0 "" ""))
5224                       (pc)))]
5225   ""
5226   "
5228   if (TARGET_SHMEDIA)
5229     {
5230       if (GET_MODE (sh_compare_op0) != DImode)
5231         {
5232           rtx tmp = gen_reg_rtx (DImode);
5234           emit_insn (gen_seq (tmp));
5235           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5236           DONE;
5237         }
5239       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5240       emit_jump_insn (gen_bne_media (operands[0],
5241                                      sh_compare_op0, sh_compare_op1));
5242       DONE;
5243     }
5245   from_compare (operands, EQ);
5248 (define_expand "bgt"
5249   [(set (pc)
5250         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5251                       (label_ref (match_operand 0 "" ""))
5252                       (pc)))]
5253   ""
5254   "
5256   if (TARGET_SHMEDIA)
5257     {
5258       if (GET_MODE (sh_compare_op0) != DImode)
5259         {
5260           rtx tmp = gen_reg_rtx (DImode);
5262           emit_insn (gen_sgt (tmp));
5263           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5264           DONE;
5265         }
5267       if (sh_compare_op0 != const0_rtx)
5268         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5269       if (sh_compare_op1 != const0_rtx)
5270         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5271       emit_jump_insn (gen_bgt_media (operands[0],
5272                                      sh_compare_op0, sh_compare_op1));
5273       DONE;
5274     }
5276   from_compare (operands, GT);
5279 (define_expand "blt"
5280   [(set (pc)
5281         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5282                       (label_ref (match_operand 0 "" ""))
5283                       (pc)))]
5284   ""
5285   "
5287   if (TARGET_SHMEDIA)
5288     {
5289       if (GET_MODE (sh_compare_op0) != DImode)
5290         {
5291           rtx tmp = gen_reg_rtx (DImode);
5293           emit_insn (gen_slt (tmp));
5294           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5295           DONE;
5296         }
5298       if (sh_compare_op0 != const0_rtx)
5299         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5300       if (sh_compare_op1 != const0_rtx)
5301         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5302       emit_jump_insn (gen_bgt_media (operands[0],
5303                                      sh_compare_op1, sh_compare_op0));
5304       DONE;
5305     }
5307   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5308     {
5309       rtx tmp = sh_compare_op0;
5310       sh_compare_op0 = sh_compare_op1;
5311       sh_compare_op1 = tmp;
5312       emit_insn (gen_bgt (operands[0]));
5313       DONE;
5314     }
5315   from_compare (operands, GE);
5318 (define_expand "ble"
5319   [(set (pc)
5320         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5321                       (label_ref (match_operand 0 "" ""))
5322                       (pc)))]
5323   ""
5324   "
5326   if (TARGET_SHMEDIA)
5327     {
5328       if (GET_MODE (sh_compare_op0) != DImode)
5329         {
5330           rtx tmp = gen_reg_rtx (DImode);
5332           emit_insn (gen_sle (tmp));
5333           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5334           DONE;
5335         }
5337       if (sh_compare_op0 != const0_rtx)
5338         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5339       if (sh_compare_op1 != const0_rtx)
5340         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5341       emit_jump_insn (gen_bge_media (operands[0],
5342                                      sh_compare_op1, sh_compare_op0));
5343       DONE;
5344     }
5346   if (TARGET_SH2E
5347       && TARGET_IEEE
5348       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5349     {
5350       rtx tmp = sh_compare_op0;
5351       sh_compare_op0 = sh_compare_op1;
5352       sh_compare_op1 = tmp;
5353       emit_insn (gen_bge (operands[0]));
5354       DONE;
5355     }
5356   from_compare (operands, GT);
5359 (define_expand "bge"
5360   [(set (pc)
5361         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5362                       (label_ref (match_operand 0 "" ""))
5363                       (pc)))]
5364   ""
5365   "
5367   if (TARGET_SHMEDIA)
5368     {
5369       if (GET_MODE (sh_compare_op0) != DImode)
5370         {
5371           rtx tmp = gen_reg_rtx (DImode);
5373           emit_insn (gen_sge (tmp));
5374           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5375           DONE;
5376         }
5378       if (sh_compare_op0 != const0_rtx)
5379         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5380       if (sh_compare_op1 != const0_rtx)
5381         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5382       emit_jump_insn (gen_bge_media (operands[0],
5383                                      sh_compare_op0, sh_compare_op1));
5384       DONE;
5385     }
5387   if (TARGET_SH2E
5388       && ! TARGET_IEEE
5389       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5390     {
5391       rtx tmp = sh_compare_op0;
5392       sh_compare_op0 = sh_compare_op1;
5393       sh_compare_op1 = tmp;
5394       emit_insn (gen_ble (operands[0]));
5395       DONE;
5396     }
5397   from_compare (operands, GE);
5400 (define_expand "bgtu"
5401   [(set (pc)
5402         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5403                       (label_ref (match_operand 0 "" ""))
5404                       (pc)))]
5405   ""
5406   "
5408   if (TARGET_SHMEDIA)
5409     {
5410       if (sh_compare_op0 != const0_rtx)
5411         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5412       if (sh_compare_op1 != const0_rtx)
5413         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5414       emit_jump_insn (gen_bgtu_media (operands[0],
5415                                       sh_compare_op0, sh_compare_op1));
5416       DONE;
5417     }
5419   from_compare (operands, GTU);
5422 (define_expand "bltu"
5423   [(set (pc)
5424         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5425                       (label_ref (match_operand 0 "" ""))
5426                       (pc)))]
5427   ""
5428   "
5430   if (TARGET_SHMEDIA)
5431     {
5432       if (sh_compare_op0 != const0_rtx)
5433         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5434       if (sh_compare_op1 != const0_rtx)
5435         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5436       emit_jump_insn (gen_bgtu_media (operands[0],
5437                                       sh_compare_op1, sh_compare_op0));
5438       DONE;
5439     }
5441   from_compare (operands, GEU);
5444 (define_expand "bgeu"
5445   [(set (pc)
5446         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5447                       (label_ref (match_operand 0 "" ""))
5448                       (pc)))]
5449   ""
5450   "
5452   if (TARGET_SHMEDIA)
5453     {
5454       if (sh_compare_op0 != const0_rtx)
5455         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5456       if (sh_compare_op1 != const0_rtx)
5457         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5458       emit_jump_insn (gen_bgeu_media (operands[0],
5459                                       sh_compare_op0, sh_compare_op1));
5460       DONE;
5461     }
5463   from_compare (operands, GEU);
5466 (define_expand "bleu"
5467   [(set (pc)
5468         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5469                       (label_ref (match_operand 0 "" ""))
5470                       (pc)))]
5471   ""
5472   "
5474   if (TARGET_SHMEDIA)
5475     {
5476       if (sh_compare_op0 != const0_rtx)
5477         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5478       if (sh_compare_op1 != const0_rtx)
5479         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5480       emit_jump_insn (gen_bgeu_media (operands[0],
5481                                       sh_compare_op1, sh_compare_op0));
5482       DONE;
5483     }
5485   from_compare (operands, GTU);
5488 (define_expand "bunordered"
5489   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5490    (set (pc)
5491         (if_then_else (ne (match_dup 1) (const_int 0))
5492                       (label_ref:DI (match_operand 0 "" ""))
5493                       (pc)))]
5494   "TARGET_SHMEDIA"
5495   "
5497   operands[1] = gen_reg_rtx (DImode);
5498   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5499   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5502 ;; ------------------------------------------------------------------------
5503 ;; Jump and linkage insns
5504 ;; ------------------------------------------------------------------------
5506 (define_insn "jump_compact"
5507   [(set (pc)
5508         (label_ref (match_operand 0 "" "")))]
5509   "TARGET_SH1"
5510   "*
5512   /* The length is 16 if the delay slot is unfilled.  */
5513   if (get_attr_length(insn) > 4)
5514     return output_far_jump(insn, operands[0]);
5515   else
5516     return   \"bra      %l0%#\";
5518   [(set_attr "type" "jump")
5519    (set_attr "needs_delay_slot" "yes")])
5521 ;; ??? It would be much saner to explicitly use the scratch register
5522 ;; in the jump insn, and have indirect_jump_scratch only set it,
5523 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5524 ;; from the target then, as it uses simplejump_p.
5525 ;;(define_insn "jump_compact_far"
5526 ;;  [(set (pc)
5527 ;;      (label_ref (match_operand 0 "" "")))
5528 ;;   (use (match_operand 1 "register_operand" "r")]
5529 ;;  "TARGET_SH1"
5530 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5531 ;;  [(set_attr "type" "jump")
5532 ;;   (set_attr "needs_delay_slot" "yes")])
5534 (define_insn "jump_media"
5535   [(set (pc)
5536         (match_operand:DI 0 "target_operand" "b"))]
5537   "TARGET_SHMEDIA"
5538   "blink        %0, r63"
5539   [(set_attr "type" "jump_media")])
5541 (define_expand "jump"
5542   [(set (pc)
5543         (label_ref (match_operand 0 "" "")))]
5544   ""
5545   "
5547   if (TARGET_SH1)
5548     emit_jump_insn (gen_jump_compact (operands[0]));
5549   else if (TARGET_SHMEDIA)
5550     {
5551       if (reload_in_progress || reload_completed)
5552         FAIL;
5553       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5554                                                          operands[0])));
5555     }
5556   DONE;
5559 (define_insn "force_mode_for_call"
5560   [(use (reg:PSI FPSCR_REG))]
5561   "TARGET_SHCOMPACT"
5562   ""
5563   [(set_attr "length" "0")
5564    (set (attr "fp_mode")
5565         (if_then_else (eq_attr "fpu_single" "yes")
5566                       (const_string "single") (const_string "double")))])
5568 (define_insn "calli"
5569   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5570          (match_operand 1 "" ""))
5571    (use (reg:PSI FPSCR_REG))
5572    (clobber (reg:SI PR_REG))]
5573   "TARGET_SH1"
5574   "jsr  @%0%#"
5575   [(set_attr "type" "call")
5576    (set (attr "fp_mode")
5577         (if_then_else (eq_attr "fpu_single" "yes")
5578                       (const_string "single") (const_string "double")))
5579    (set_attr "needs_delay_slot" "yes")
5580    (set_attr "fp_set" "unknown")])
5582 ;; This is a pc-rel call, using bsrf, for use with PIC.
5584 (define_insn "calli_pcrel"
5585   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5586          (match_operand 1 "" ""))
5587    (use (reg:PSI FPSCR_REG))
5588    (use (reg:SI PIC_REG))
5589    (use (match_operand 2 "" ""))
5590    (clobber (reg:SI PR_REG))]
5591   "TARGET_SH2"
5592   "bsrf %0\\n%O2:%#"
5593   [(set_attr "type" "call")
5594    (set (attr "fp_mode")
5595         (if_then_else (eq_attr "fpu_single" "yes")
5596                       (const_string "single") (const_string "double")))
5597    (set_attr "needs_delay_slot" "yes")
5598    (set_attr "fp_set" "unknown")])
5600 (define_insn_and_split "call_pcrel"
5601   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5602          (match_operand 1 "" ""))
5603    (use (reg:PSI FPSCR_REG))
5604    (use (reg:SI PIC_REG))
5605    (clobber (reg:SI PR_REG))
5606    (clobber (match_scratch:SI 2 "=r"))]
5607   "TARGET_SH2"
5608   "#"
5609   "reload_completed"
5610   [(const_int 0)]
5611   "
5613   rtx lab = PATTERN (gen_call_site ());
5615   if (SYMBOL_REF_LOCAL_P (operands[0]))
5616     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5617   else
5618     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5619   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5620   DONE;
5622   [(set_attr "type" "call")
5623    (set (attr "fp_mode")
5624         (if_then_else (eq_attr "fpu_single" "yes")
5625                       (const_string "single") (const_string "double")))
5626    (set_attr "needs_delay_slot" "yes")
5627    (set_attr "fp_set" "unknown")])
5629 (define_insn "call_compact"
5630   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5631          (match_operand 1 "" ""))
5632    (match_operand 2 "immediate_operand" "n")
5633    (use (reg:SI R0_REG))
5634    (use (reg:SI R1_REG))
5635    (use (reg:PSI FPSCR_REG))
5636    (clobber (reg:SI PR_REG))]
5637   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5638   "jsr  @%0%#"
5639   [(set_attr "type" "call")
5640    (set (attr "fp_mode")
5641         (if_then_else (eq_attr "fpu_single" "yes")
5642                       (const_string "single") (const_string "double")))
5643    (set_attr "needs_delay_slot" "yes")])
5645 (define_insn "call_compact_rettramp"
5646   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5647          (match_operand 1 "" ""))
5648    (match_operand 2 "immediate_operand" "n")
5649    (use (reg:SI R0_REG))
5650    (use (reg:SI R1_REG))
5651    (use (reg:PSI FPSCR_REG))
5652    (clobber (reg:SI R10_REG))
5653    (clobber (reg:SI PR_REG))]
5654   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5655   "jsr  @%0%#"
5656   [(set_attr "type" "call")
5657    (set (attr "fp_mode")
5658         (if_then_else (eq_attr "fpu_single" "yes")
5659                       (const_string "single") (const_string "double")))
5660    (set_attr "needs_delay_slot" "yes")])
5662 (define_insn "call_media"
5663   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5664          (match_operand 1 "" ""))
5665    (clobber (reg:DI PR_MEDIA_REG))]
5666   "TARGET_SHMEDIA"
5667   "blink        %0, r18"
5668   [(set_attr "type" "jump_media")])
5670 (define_insn "call_valuei"
5671   [(set (match_operand 0 "" "=rf")
5672         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5673               (match_operand 2 "" "")))
5674    (use (reg:PSI FPSCR_REG))
5675    (clobber (reg:SI PR_REG))]
5676   "TARGET_SH1"
5677   "jsr  @%1%#"
5678   [(set_attr "type" "call")
5679    (set (attr "fp_mode")
5680         (if_then_else (eq_attr "fpu_single" "yes")
5681                       (const_string "single") (const_string "double")))
5682    (set_attr "needs_delay_slot" "yes")
5683    (set_attr "fp_set" "unknown")])
5685 (define_insn "call_valuei_pcrel"
5686   [(set (match_operand 0 "" "=rf")
5687         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5688               (match_operand 2 "" "")))
5689    (use (reg:PSI FPSCR_REG))
5690    (use (reg:SI PIC_REG))
5691    (use (match_operand 3 "" ""))
5692    (clobber (reg:SI PR_REG))]
5693   "TARGET_SH2"
5694   "bsrf %1\\n%O3:%#"
5695   [(set_attr "type" "call")
5696    (set (attr "fp_mode")
5697         (if_then_else (eq_attr "fpu_single" "yes")
5698                       (const_string "single") (const_string "double")))
5699    (set_attr "needs_delay_slot" "yes")
5700    (set_attr "fp_set" "unknown")])
5702 (define_insn_and_split "call_value_pcrel"
5703   [(set (match_operand 0 "" "=rf")
5704         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5705               (match_operand 2 "" "")))
5706    (use (reg:PSI FPSCR_REG))
5707    (use (reg:SI PIC_REG))
5708    (clobber (reg:SI PR_REG))
5709    (clobber (match_scratch:SI 3 "=r"))]
5710   "TARGET_SH2"
5711   "#"
5712   "reload_completed"
5713   [(const_int 0)]
5714   "
5716   rtx lab = PATTERN (gen_call_site ());
5718   if (SYMBOL_REF_LOCAL_P (operands[1]))
5719     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5720   else
5721     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5722   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5723                                          operands[2], lab));
5724   DONE;
5726   [(set_attr "type" "call")
5727    (set (attr "fp_mode")
5728         (if_then_else (eq_attr "fpu_single" "yes")
5729                       (const_string "single") (const_string "double")))
5730    (set_attr "needs_delay_slot" "yes")
5731    (set_attr "fp_set" "unknown")])
5733 (define_insn "call_value_compact"
5734   [(set (match_operand 0 "" "=rf")
5735         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5736               (match_operand 2 "" "")))
5737    (match_operand 3 "immediate_operand" "n")
5738    (use (reg:SI R0_REG))
5739    (use (reg:SI R1_REG))
5740    (use (reg:PSI FPSCR_REG))
5741    (clobber (reg:SI PR_REG))]
5742   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5743   "jsr  @%1%#"
5744   [(set_attr "type" "call")
5745    (set (attr "fp_mode")
5746         (if_then_else (eq_attr "fpu_single" "yes")
5747                       (const_string "single") (const_string "double")))
5748    (set_attr "needs_delay_slot" "yes")])
5750 (define_insn "call_value_compact_rettramp"
5751   [(set (match_operand 0 "" "=rf")
5752         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5753               (match_operand 2 "" "")))
5754    (match_operand 3 "immediate_operand" "n")
5755    (use (reg:SI R0_REG))
5756    (use (reg:SI R1_REG))
5757    (use (reg:PSI FPSCR_REG))
5758    (clobber (reg:SI R10_REG))
5759    (clobber (reg:SI PR_REG))]
5760   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5761   "jsr  @%1%#"
5762   [(set_attr "type" "call")
5763    (set (attr "fp_mode")
5764         (if_then_else (eq_attr "fpu_single" "yes")
5765                       (const_string "single") (const_string "double")))
5766    (set_attr "needs_delay_slot" "yes")])
5768 (define_insn "call_value_media"
5769   [(set (match_operand 0 "" "=rf")
5770         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5771               (match_operand 2 "" "")))
5772    (clobber (reg:DI PR_MEDIA_REG))]
5773   "TARGET_SHMEDIA"
5774   "blink        %1, r18"
5775   [(set_attr "type" "jump_media")])
5777 (define_expand "call"
5778   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5779                             (match_operand 1 "" ""))
5780               (match_operand 2 "" "")
5781               (use (reg:PSI FPSCR_REG))
5782               (clobber (reg:SI PR_REG))])]
5783   ""
5784   "
5786   if (TARGET_SHMEDIA)
5787     {
5788       operands[0] = XEXP (operands[0], 0);
5789       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5790         {
5791           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5792             {
5793               rtx reg = gen_reg_rtx (Pmode);
5795               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5796               operands[0] = reg;
5797             }
5798           else
5799             {
5800               operands[0] = gen_sym2PIC (operands[0]);
5801               PUT_MODE (operands[0], Pmode);
5802             }
5803         }
5804       if (GET_MODE (operands[0]) == SImode)
5805         {
5806           if (GET_CODE (operands[0]) == REG)
5807             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5808           else if (GET_CODE (operands[0]) == SUBREG)
5809             {
5810               operands[0] = SUBREG_REG (operands[0]);
5811               if (GET_MODE (operands[0]) != DImode)
5812                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5813             }
5814           else
5815             {
5816               operands[0] = shallow_copy_rtx (operands[0]);
5817               PUT_MODE (operands[0], DImode);
5818             }
5819         }
5820       if (! target_reg_operand (operands[0], DImode))
5821         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5822       emit_call_insn (gen_call_media (operands[0], operands[1]));
5823       DONE;
5824     }
5825   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5826     {
5827       rtx cookie_rtx = operands[2];
5828       long cookie = INTVAL (cookie_rtx);
5829       rtx func = XEXP (operands[0], 0);
5830       rtx r0, r1;
5832       if (flag_pic)
5833         {
5834           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5835             {
5836               rtx reg = gen_reg_rtx (Pmode);
5838               emit_insn (gen_symGOTPLT2reg (reg, func));
5839               func = reg;
5840             }
5841           else
5842             func = legitimize_pic_address (func, Pmode, 0);
5843         }
5845       r0 = gen_rtx_REG (SImode, R0_REG);
5846       r1 = gen_rtx_REG (SImode, R1_REG);
5848       /* Since such a call function may use all call-clobbered
5849          registers, we force a mode switch earlier, so that we don't
5850          run out of registers when adjusting fpscr for the call.  */
5851       emit_insn (gen_force_mode_for_call ());
5853       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5854       if (flag_pic)
5855         {
5856           rtx reg = gen_reg_rtx (Pmode);
5858           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5859           operands[0] = reg;
5860         }
5861       operands[0] = force_reg (SImode, operands[0]);
5863       emit_move_insn (r0, func);
5864       emit_move_insn (r1, cookie_rtx);
5866       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5867         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5868                                                    operands[2]));
5869       else
5870         emit_call_insn (gen_call_compact (operands[0], operands[1],
5871                                           operands[2]));
5873       DONE;
5874     }
5875   else if (TARGET_SHCOMPACT && flag_pic
5876            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5877            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5878     {
5879       rtx reg = gen_reg_rtx (Pmode);
5881       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5882       XEXP (operands[0], 0) = reg;
5883     }
5884   if (flag_pic && TARGET_SH2
5885       && GET_CODE (operands[0]) == MEM
5886       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5887     {
5888       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5889       DONE;
5890     }
5891   else
5892   {
5893     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5894     operands[1] = operands[2];
5895   }
5897   emit_call_insn (gen_calli (operands[0], operands[1]));
5898   DONE;
5901 (define_insn "call_pop_compact"
5902   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5903          (match_operand 1 "" ""))
5904    (match_operand 2 "immediate_operand" "n")
5905    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5906                                  (match_operand 3 "immediate_operand" "n")))
5907    (use (reg:SI R0_REG))
5908    (use (reg:SI R1_REG))
5909    (use (reg:PSI FPSCR_REG))
5910    (clobber (reg:SI PR_REG))]
5911   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5912   "jsr  @%0%#"
5913   [(set_attr "type" "call")
5914    (set (attr "fp_mode")
5915         (if_then_else (eq_attr "fpu_single" "yes")
5916                       (const_string "single") (const_string "double")))
5917    (set_attr "needs_delay_slot" "yes")])
5919 (define_insn "call_pop_compact_rettramp"
5920   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5921          (match_operand 1 "" ""))
5922    (match_operand 2 "immediate_operand" "n")
5923    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5924                                  (match_operand 3 "immediate_operand" "n")))
5925    (use (reg:SI R0_REG))
5926    (use (reg:SI R1_REG))
5927    (use (reg:PSI FPSCR_REG))
5928    (clobber (reg:SI R10_REG))
5929    (clobber (reg:SI PR_REG))]
5930   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5931   "jsr  @%0%#"
5932   [(set_attr "type" "call")
5933    (set (attr "fp_mode")
5934         (if_then_else (eq_attr "fpu_single" "yes")
5935                       (const_string "single") (const_string "double")))
5936    (set_attr "needs_delay_slot" "yes")])
5938 (define_expand "call_pop"
5939   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5940                     (match_operand 1 "" ""))
5941              (match_operand 2 "" "")
5942              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5943                                            (match_operand 3 "" "")))])]
5944   "TARGET_SHCOMPACT"
5945   "
5947   if (operands[2] && INTVAL (operands[2]))
5948     {
5949       rtx cookie_rtx = operands[2];
5950       long cookie = INTVAL (cookie_rtx);
5951       rtx func = XEXP (operands[0], 0);
5952       rtx r0, r1;
5954       if (flag_pic)
5955         {
5956           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5957             {
5958               rtx reg = gen_reg_rtx (Pmode);
5960               emit_insn (gen_symGOTPLT2reg (reg, func));
5961               func = reg;
5962             }
5963           else
5964             func = legitimize_pic_address (func, Pmode, 0);
5965         }
5967       r0 = gen_rtx_REG (SImode, R0_REG);
5968       r1 = gen_rtx_REG (SImode, R1_REG);
5970       /* Since such a call function may use all call-clobbered
5971          registers, we force a mode switch earlier, so that we don't
5972          run out of registers when adjusting fpscr for the call.  */
5973       emit_insn (gen_force_mode_for_call ());
5975       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5976       if (flag_pic)
5977         {
5978           rtx reg = gen_reg_rtx (Pmode);
5980           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5981           operands[0] = reg;
5982         }
5983       operands[0] = force_reg (SImode, operands[0]);
5985       emit_move_insn (r0, func);
5986       emit_move_insn (r1, cookie_rtx);
5988       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5989         emit_call_insn (gen_call_pop_compact_rettramp
5990                         (operands[0], operands[1], operands[2], operands[3]));
5991       else
5992         emit_call_insn (gen_call_pop_compact
5993                         (operands[0], operands[1], operands[2], operands[3]));
5995       DONE;
5996     }
5998   abort ();
6001 (define_expand "call_value"
6002   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6003                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6004                                  (match_operand 2 "" "")))
6005               (match_operand 3 "" "")
6006               (use (reg:PSI FPSCR_REG))
6007               (clobber (reg:SI PR_REG))])]
6008   ""
6009   "
6011   if (TARGET_SHMEDIA)
6012     {
6013       operands[1] = XEXP (operands[1], 0);
6014       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6015         {
6016           if (! SYMBOL_REF_LOCAL_P (operands[1]))
6017             {
6018               rtx reg = gen_reg_rtx (Pmode);
6020               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6021               operands[1] = reg;
6022             }
6023           else
6024             {
6025               operands[1] = gen_sym2PIC (operands[1]);
6026               PUT_MODE (operands[1], Pmode);
6027             }
6028         }
6029       if (GET_MODE (operands[1]) == SImode)
6030         {
6031           if (GET_CODE (operands[1]) == REG)
6032             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6033           else if (GET_CODE (operands[1]) == SUBREG)
6034             {
6035               operands[1] = SUBREG_REG (operands[1]);
6036               if (GET_MODE (operands[1]) != DImode)
6037                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6038             }
6039           else
6040             {
6041               operands[1] = shallow_copy_rtx (operands[1]);
6042               PUT_MODE (operands[1], DImode);
6043             }
6044         }
6045       if (! target_reg_operand (operands[1], DImode))
6046         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6047       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6048                                             operands[2]));
6049       DONE;
6050     }
6051   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6052     {
6053       rtx cookie_rtx = operands[3];
6054       long cookie = INTVAL (cookie_rtx);
6055       rtx func = XEXP (operands[1], 0);
6056       rtx r0, r1;
6058       if (flag_pic)
6059         {
6060           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6061             {
6062               rtx reg = gen_reg_rtx (Pmode);
6064               emit_insn (gen_symGOTPLT2reg (reg, func));
6065               func = reg;
6066             }
6067           else
6068             func = legitimize_pic_address (func, Pmode, 0);
6069         }
6071       r0 = gen_rtx_REG (SImode, R0_REG);
6072       r1 = gen_rtx_REG (SImode, R1_REG);
6074       /* Since such a call function may use all call-clobbered
6075          registers, we force a mode switch earlier, so that we don't
6076          run out of registers when adjusting fpscr for the call.  */
6077       emit_insn (gen_force_mode_for_call ());
6079       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6080       if (flag_pic)
6081         {
6082           rtx reg = gen_reg_rtx (Pmode);
6084           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6085           operands[1] = reg;
6086         }
6087       operands[1] = force_reg (SImode, operands[1]);
6089       emit_move_insn (r0, func);
6090       emit_move_insn (r1, cookie_rtx);
6092       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6093         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6094                                                          operands[1],
6095                                                          operands[2],
6096                                                          operands[3]));
6097       else
6098         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6099                                                 operands[2], operands[3]));
6101       DONE;
6102     }
6103   else if (TARGET_SHCOMPACT && flag_pic
6104            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6105            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6106     {
6107       rtx reg = gen_reg_rtx (Pmode);
6109       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6110       XEXP (operands[1], 0) = reg;
6111     }
6112   if (flag_pic && TARGET_SH2
6113       && GET_CODE (operands[1]) == MEM
6114       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6115     {
6116       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6117                                             operands[2]));
6118       DONE;
6119     }
6120   else
6121     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6123   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6124   DONE;
6127 (define_insn "sibcalli"
6128   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6129          (match_operand 1 "" ""))
6130    (use (reg:PSI FPSCR_REG))
6131    (return)]
6132   "TARGET_SH1"
6133   "jmp  @%0%#"
6134   [(set_attr "needs_delay_slot" "yes")
6135    (set (attr "fp_mode")
6136         (if_then_else (eq_attr "fpu_single" "yes")
6137                       (const_string "single") (const_string "double")))
6138    (set_attr "type" "jump_ind")])
6140 (define_insn "sibcalli_pcrel"
6141   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6142          (match_operand 1 "" ""))
6143    (use (match_operand 2 "" ""))
6144    (use (reg:PSI FPSCR_REG))
6145    (return)]
6146   "TARGET_SH2"
6147   "braf %0\\n%O2:%#"
6148   [(set_attr "needs_delay_slot" "yes")
6149    (set (attr "fp_mode")
6150         (if_then_else (eq_attr "fpu_single" "yes")
6151                       (const_string "single") (const_string "double")))
6152    (set_attr "type" "jump_ind")])
6154 (define_insn_and_split "sibcall_pcrel"
6155   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6156          (match_operand 1 "" ""))
6157    (use (reg:PSI FPSCR_REG))
6158    (clobber (match_scratch:SI 2 "=k"))
6159    (return)]
6160   "TARGET_SH2"
6161   "#"
6162   "reload_completed"
6163   [(const_int 0)]
6164   "
6166   rtx lab = PATTERN (gen_call_site ());
6167   rtx call_insn;
6169   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6170   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6171                                                   lab));
6172   SIBLING_CALL_P (call_insn) = 1;
6173   DONE;
6175   [(set_attr "needs_delay_slot" "yes")
6176    (set (attr "fp_mode")
6177         (if_then_else (eq_attr "fpu_single" "yes")
6178                       (const_string "single") (const_string "double")))
6179    (set_attr "type" "jump_ind")])
6181 (define_insn "sibcall_compact"
6182   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6183          (match_operand 1 "" ""))
6184    (return)
6185    (use (match_operand:SI 2 "register_operand" "z,x"))
6186    (use (reg:SI R1_REG))
6187    (use (reg:PSI FPSCR_REG))
6188    ;; We want to make sure the `x' above will only match MACH_REG
6189    ;; because sibcall_epilogue may clobber MACL_REG.
6190    (clobber (reg:SI MACL_REG))]
6191   "TARGET_SHCOMPACT"
6192   "@
6193         jmp     @%0%#
6194         jmp     @%0\\n  sts     %2, r0"
6195   [(set_attr "needs_delay_slot" "yes,no")
6196    (set_attr "length" "2,4")
6197    (set (attr "fp_mode") (const_string "single"))
6198    (set_attr "type" "jump_ind")])
6200 (define_insn "sibcall_media"
6201   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6202          (match_operand 1 "" ""))
6203    (use (reg:SI PR_MEDIA_REG))
6204    (return)]
6205   "TARGET_SHMEDIA"
6206   "blink        %0, r63"
6207   [(set_attr "type" "jump_media")])
6209 (define_expand "sibcall"
6210   [(parallel
6211     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6212            (match_operand 1 "" ""))
6213      (match_operand 2 "" "")
6214      (use (reg:PSI FPSCR_REG))
6215      (return)])]
6216   ""
6217   "
6219   if (TARGET_SHMEDIA)
6220     {
6221       operands[0] = XEXP (operands[0], 0);
6222       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6223         {
6224           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6225             {
6226               rtx reg = gen_reg_rtx (Pmode);
6228               /* We must not use GOTPLT for sibcalls, because PIC_REG
6229                  must be restored before the PLT code gets to run.  */
6230               emit_insn (gen_symGOT2reg (reg, operands[0]));
6231               operands[0] = reg;
6232             }
6233           else
6234             {
6235               operands[0] = gen_sym2PIC (operands[0]);
6236               PUT_MODE (operands[0], Pmode);
6237             }
6238         }
6239       if (GET_MODE (operands[0]) == SImode)
6240         {
6241           if (GET_CODE (operands[0]) == REG)
6242             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6243           else if (GET_CODE (operands[0]) == SUBREG)
6244             {
6245               operands[0] = SUBREG_REG (operands[0]);
6246               if (GET_MODE (operands[0]) != DImode)
6247                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6248             }
6249           else
6250             {
6251               operands[0] = shallow_copy_rtx (operands[0]);
6252               PUT_MODE (operands[0], DImode);
6253             }
6254         }
6255       if (! target_reg_operand (operands[0], DImode))
6256         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6257       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6258       DONE;
6259     }
6260   else if (TARGET_SHCOMPACT && operands[2]
6261            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6262     {
6263       rtx cookie_rtx = operands[2];
6264       long cookie = INTVAL (cookie_rtx);
6265       rtx func = XEXP (operands[0], 0);
6266       rtx mach, r1;
6268       if (flag_pic)
6269         {
6270           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6271             {
6272               rtx reg = gen_reg_rtx (Pmode);
6274               emit_insn (gen_symGOT2reg (reg, func));
6275               func = reg;
6276             }
6277           else
6278             func = legitimize_pic_address (func, Pmode, 0);
6279         }
6281       /* FIXME: if we could tell whether all argument registers are
6282          already taken, we could decide whether to force the use of
6283          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6284          simple way to tell.  We could use the CALL_COOKIE, but we
6285          can't currently tell a register used for regular argument
6286          passing from one that is unused.  If we leave it up to reload
6287          to decide which register to use, it seems to always choose
6288          R0_REG, which leaves no available registers in SIBCALL_REGS
6289          to hold the address of the trampoline.  */
6290       mach = gen_rtx_REG (SImode, MACH_REG);
6291       r1 = gen_rtx_REG (SImode, R1_REG);
6293       /* Since such a call function may use all call-clobbered
6294          registers, we force a mode switch earlier, so that we don't
6295          run out of registers when adjusting fpscr for the call.  */
6296       emit_insn (gen_force_mode_for_call ());
6298       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6299       if (flag_pic)
6300         {
6301           rtx reg = gen_reg_rtx (Pmode);
6303           emit_insn (gen_symGOT2reg (reg, operands[0]));
6304           operands[0] = reg;
6305         }
6306       operands[0] = force_reg (SImode, operands[0]);
6308       /* We don't need a return trampoline, since the callee will
6309          return directly to the upper caller.  */
6310       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6311         {
6312           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6313           cookie_rtx = GEN_INT (cookie);
6314         }
6316       emit_move_insn (mach, func);
6317       emit_move_insn (r1, cookie_rtx);
6319       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6320       DONE;
6321     }
6322   else if (TARGET_SHCOMPACT && flag_pic
6323            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6324            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6325     {
6326       rtx reg = gen_reg_rtx (Pmode);
6328       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6329       XEXP (operands[0], 0) = reg;
6330     }
6331   if (flag_pic && TARGET_SH2
6332       && GET_CODE (operands[0]) == MEM
6333       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6334       /* The PLT needs the PIC register, but the epilogue would have
6335          to restore it, so we can only use PC-relative PIC calls for
6336          static functions.  */
6337       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6338     {
6339       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6340       DONE;
6341     }
6342   else
6343     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6345   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6346   DONE;
6349 (define_expand "sibcall_value"
6350   [(set (match_operand 0 "" "")
6351         (call (match_operand 1 "" "")
6352               (match_operand 2 "" "")))
6353    (match_operand 3 "" "")]
6354   ""
6355   "
6357   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6358   DONE;
6361 (define_insn "call_value_pop_compact"
6362   [(set (match_operand 0 "" "=rf")
6363         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6364               (match_operand 2 "" "")))
6365    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6366                                  (match_operand 4 "immediate_operand" "n")))
6367    (match_operand 3 "immediate_operand" "n")
6368    (use (reg:SI R0_REG))
6369    (use (reg:SI R1_REG))
6370    (use (reg:PSI FPSCR_REG))
6371    (clobber (reg:SI PR_REG))]
6372   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6373   "jsr  @%1%#"
6374   [(set_attr "type" "call")
6375    (set (attr "fp_mode")
6376         (if_then_else (eq_attr "fpu_single" "yes")
6377                       (const_string "single") (const_string "double")))
6378    (set_attr "needs_delay_slot" "yes")])
6380 (define_insn "call_value_pop_compact_rettramp"
6381   [(set (match_operand 0 "" "=rf")
6382         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6383               (match_operand 2 "" "")))
6384    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6385                                  (match_operand 4 "immediate_operand" "n")))
6386    (match_operand 3 "immediate_operand" "n")
6387    (use (reg:SI R0_REG))
6388    (use (reg:SI R1_REG))
6389    (use (reg:PSI FPSCR_REG))
6390    (clobber (reg:SI R10_REG))
6391    (clobber (reg:SI PR_REG))]
6392   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6393   "jsr  @%1%#"
6394   [(set_attr "type" "call")
6395    (set (attr "fp_mode")
6396         (if_then_else (eq_attr "fpu_single" "yes")
6397                       (const_string "single") (const_string "double")))
6398    (set_attr "needs_delay_slot" "yes")])
6400 (define_expand "call_value_pop"
6401   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6402                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6403                                  (match_operand 2 "" "")))
6404               (match_operand 3 "" "")
6405               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6406                                             (match_operand 4 "" "")))])]
6407   "TARGET_SHCOMPACT"
6408   "
6410   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6411     {
6412       rtx cookie_rtx = operands[3];
6413       long cookie = INTVAL (cookie_rtx);
6414       rtx func = XEXP (operands[1], 0);
6415       rtx r0, r1;
6417       if (flag_pic)
6418         {
6419           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6420             {
6421               rtx reg = gen_reg_rtx (Pmode);
6423               emit_insn (gen_symGOTPLT2reg (reg, func));
6424               func = reg;
6425             }
6426           else
6427             func = legitimize_pic_address (func, Pmode, 0);
6428         }
6430       r0 = gen_rtx_REG (SImode, R0_REG);
6431       r1 = gen_rtx_REG (SImode, R1_REG);
6433       /* Since such a call function may use all call-clobbered
6434          registers, we force a mode switch earlier, so that we don't
6435          run out of registers when adjusting fpscr for the call.  */
6436       emit_insn (gen_force_mode_for_call ());
6438       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6439       if (flag_pic)
6440         {
6441           rtx reg = gen_reg_rtx (Pmode);
6443           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6444           operands[1] = reg;
6445         }
6446       operands[1] = force_reg (SImode, operands[1]);
6448       emit_move_insn (r0, func);
6449       emit_move_insn (r1, cookie_rtx);
6451       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6452         emit_call_insn (gen_call_value_pop_compact_rettramp
6453                         (operands[0], operands[1], operands[2],
6454                          operands[3], operands[4]));
6455       else
6456         emit_call_insn (gen_call_value_pop_compact
6457                         (operands[0], operands[1], operands[2],
6458                          operands[3], operands[4]));
6460       DONE;
6461     }
6463   abort ();
6466 (define_expand "sibcall_epilogue"
6467   [(return)]
6468   ""
6469   "
6471   sh_expand_epilogue (1);
6472   if (TARGET_SHCOMPACT)
6473     {
6474       rtx insn, set;
6476       /* If epilogue clobbers r0, preserve it in macl.  */
6477       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6478         if ((set = single_set (insn))
6479             && GET_CODE (SET_DEST (set)) == REG
6480             && REGNO (SET_DEST (set)) == R0_REG)
6481           {
6482             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6483             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6484             rtx i;
6486             /* We can't tell at this point whether the sibcall is a
6487                sibcall_compact and, if it is, whether it uses r0 or
6488                mach as operand 2, so let the instructions that
6489                preserve r0 be optimized away if r0 turns out to be
6490                dead.  */
6491             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6492             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6493                                                REG_NOTES (i));
6494             i = emit_move_insn (r0, tmp);
6495             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6496                                                REG_NOTES (i));
6497             break;
6498           }
6499     }
6500   DONE;
6503 (define_insn "indirect_jump_compact"
6504   [(set (pc)
6505         (match_operand:SI 0 "arith_reg_operand" "r"))]
6506   "TARGET_SH1"
6507   "jmp  @%0%#"
6508   [(set_attr "needs_delay_slot" "yes")
6509    (set_attr "type" "jump_ind")])
6511 (define_expand "indirect_jump"
6512   [(set (pc)
6513         (match_operand 0 "register_operand" ""))]
6514   ""
6515   "
6517   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6518     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6521 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6522 ;; which can be present in structured code from indirect jumps which can not
6523 ;; be present in structured code.  This allows -fprofile-arcs to work.
6525 ;; For SH1 processors.
6526 (define_insn "casesi_jump_1"
6527   [(set (pc)
6528         (match_operand:SI 0 "register_operand" "r"))
6529    (use (label_ref (match_operand 1 "" "")))]
6530   "TARGET_SH1"
6531   "jmp  @%0%#"
6532   [(set_attr "needs_delay_slot" "yes")
6533    (set_attr "type" "jump_ind")])
6535 ;; For all later processors.
6536 (define_insn "casesi_jump_2"
6537   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6538                       (label_ref (match_operand 1 "" ""))))
6539    (use (label_ref (match_operand 2 "" "")))]
6540   "TARGET_SH2
6541    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6542   "braf %0%#"
6543   [(set_attr "needs_delay_slot" "yes")
6544    (set_attr "type" "jump_ind")])
6546 (define_insn "casesi_jump_media"
6547   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6548    (use (label_ref (match_operand 1 "" "")))]
6549   "TARGET_SHMEDIA"
6550   "blink        %0, r63"
6551   [(set_attr "type" "jump_media")])
6553 ;; Call subroutine returning any type.
6554 ;; ??? This probably doesn't work.
6556 (define_expand "untyped_call"
6557   [(parallel [(call (match_operand 0 "" "")
6558                     (const_int 0))
6559               (match_operand 1 "" "")
6560               (match_operand 2 "" "")])]
6561   "TARGET_SH2E || TARGET_SHMEDIA"
6562   "
6564   int i;
6566   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6568   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6569     {
6570       rtx set = XVECEXP (operands[2], 0, i);
6571       emit_move_insn (SET_DEST (set), SET_SRC (set));
6572     }
6574   /* The optimizer does not know that the call sets the function value
6575      registers we stored in the result block.  We avoid problems by
6576      claiming that all hard registers are used and clobbered at this
6577      point.  */
6578   emit_insn (gen_blockage ());
6580   DONE;
6583 ;; ------------------------------------------------------------------------
6584 ;; Misc insns
6585 ;; ------------------------------------------------------------------------
6587 (define_insn "dect"
6588   [(set (reg:SI T_REG)
6589         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6590    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6591   "TARGET_SH2"
6592   "dt   %0"
6593   [(set_attr "type" "arith")])
6595 (define_insn "nop"
6596   [(const_int 0)]
6597   ""
6598   "nop")
6600 ;; Load address of a label. This is only generated by the casesi expand,
6601 ;; and by machine_dependent_reorg (fixing up fp moves).
6602 ;; This must use unspec, because this only works for labels that are
6603 ;; within range,
6605 (define_insn "mova"
6606   [(set (reg:SI R0_REG)
6607         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6608   "TARGET_SH1"
6609   "mova %O0,r0"
6610   [(set_attr "in_delay_slot" "no")
6611    (set_attr "type" "arith")])
6613 ;; machine_dependent_reorg will make this a `mova'.
6614 (define_insn "mova_const"
6615   [(set (reg:SI R0_REG)
6616         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6617   "TARGET_SH1"
6618   "#"
6619   [(set_attr "in_delay_slot" "no")
6620    (set_attr "type" "arith")])
6622 (define_expand "GOTaddr2picreg"
6623   [(set (reg:SI R0_REG)
6624         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6625                    UNSPEC_MOVA))
6626    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6627    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6628   "" "
6630   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6631   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6633   if (TARGET_SH5)
6634     operands[1] = gen_datalabel_ref (operands[1]);
6636   if (TARGET_SHMEDIA)
6637     {
6638       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6639       rtx dipic = operands[0];
6640       rtx lab = PATTERN (gen_call_site ());
6641       rtx insn, equiv;
6643       equiv = operands[1];
6644       operands[1] = gen_rtx_MINUS (DImode,
6645                                    operands[1],
6646                                    gen_rtx_CONST
6647                                    (DImode,
6648                                     gen_rtx_MINUS (DImode,
6649                                                    gen_rtx_CONST (DImode,
6650                                                                   lab),
6651                                                    pc_rtx)));
6652       operands[1] = gen_sym2PIC (operands[1]);
6653       PUT_MODE (operands[1], DImode);
6655       if (GET_MODE (dipic) != DImode)
6656         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6658       if (TARGET_SHMEDIA64)
6659         emit_insn (gen_movdi_const (dipic, operands[1]));
6660       else
6661         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6663       emit_insn (gen_ptrel (tr, dipic, lab));
6665       if (GET_MODE (operands[0]) != GET_MODE (tr))
6666         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6668       insn = emit_move_insn (operands[0], tr);
6670       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6671                                             REG_NOTES (insn));
6673       DONE;
6674     }
6678 (define_insn "*ptb"
6679   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6680         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6681                              UNSPEC_DATALABEL)))]
6682   "TARGET_SHMEDIA && flag_pic
6683    && EXTRA_CONSTRAINT_Csy (operands[1])"
6684   "ptb/u        datalabel %1, %0"
6685   [(set_attr "type" "pt_media")
6686    (set_attr "length" "*")])
6688 (define_insn "ptrel"
6689   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6690         (plus:DI (match_operand:DI 1 "register_operand" "r")
6691               (pc)))
6692    (match_operand:DI 2 "" "")]
6693   "TARGET_SHMEDIA"
6694   "%O2: ptrel/u %1, %0"
6695   [(set_attr "type" "ptabs_media")])
6697 (define_expand "builtin_setjmp_receiver"
6698   [(match_operand 0 "" "")]
6699   "flag_pic"
6700   "
6702   emit_insn (gen_GOTaddr2picreg ());
6703   DONE;
6706 (define_expand "call_site"
6707   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6708   "TARGET_SH1"
6709   "
6711   static HOST_WIDE_INT i = 0;
6712   operands[0] = GEN_INT (i);
6713   i++;
6716 (define_expand "sym_label2reg"
6717   [(set (match_operand:SI 0 "" "")
6718         (const:SI (minus:SI
6719                    (const:SI
6720                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6721                    (const:SI
6722                     (plus:SI
6723                      (match_operand:SI 2 "" "")
6724                      (const_int 2))))))]
6725   "TARGET_SH1" "")
6727 (define_expand "symGOT_load"
6728   [(set (match_dup 2) (match_operand 1 "" ""))
6729    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6730    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6731   ""
6732   "
6734   rtx insn;
6736   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6737   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6739   if (TARGET_SHMEDIA)
6740     {
6741       rtx reg = operands[2];
6743       if (GET_MODE (reg) != DImode)
6744         reg = gen_rtx_SUBREG (DImode, reg, 0);
6746       if (flag_pic > 1)
6747         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6748       else
6749         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6750     }
6751   else
6752     emit_move_insn (operands[2], operands[1]);
6754   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6755                                              operands[2],
6756                                              gen_rtx_REG (Pmode, PIC_REG)));
6758   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6760   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6761                                                                   0), 0, 0),
6762                                         REG_NOTES (insn));
6764   DONE;
6767 (define_expand "sym2GOT"
6768   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6769   ""
6770   "")
6772 (define_expand "symGOT2reg"
6773   [(match_operand 0 "" "") (match_operand 1 "" "")]
6774   ""
6775   "
6777   rtx gotsym, insn;
6779   gotsym = gen_sym2GOT (operands[1]);
6780   PUT_MODE (gotsym, Pmode);
6781   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6783   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6785   DONE;
6788 (define_expand "sym2GOTPLT"
6789   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6790   ""
6791   "")
6793 (define_expand "symGOTPLT2reg"
6794   [(match_operand 0 "" "") (match_operand 1 "" "")]
6795   ""
6796   "
6798   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6799   DONE;
6802 (define_expand "sym2GOTOFF"
6803   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6804   ""
6805   "")
6807 (define_expand "symGOTOFF2reg"
6808   [(match_operand 0 "" "") (match_operand 1 "" "")]
6809   ""
6810   "
6812   rtx gotoffsym, insn;
6813   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6815   gotoffsym = gen_sym2GOTOFF (operands[1]);
6816   PUT_MODE (gotoffsym, Pmode);
6817   emit_move_insn (t, gotoffsym);
6818   insn = emit_move_insn (operands[0],
6819                          gen_rtx_PLUS (Pmode, t,
6820                                        gen_rtx_REG (Pmode, PIC_REG)));
6822   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6823                                         REG_NOTES (insn));
6825   DONE;
6828 (define_expand "symPLT_label2reg"
6829   [(set (match_operand:SI 0 "" "")
6830         (const:SI (minus:SI
6831                    (const:SI
6832                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6833                    (const:SI
6834                     (minus:SI
6835                      (const:SI (plus:SI
6836                                 (match_operand:SI 2 "" "")
6837                                 (const_int 2)))
6838                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6839    ;; Even though the PIC register is not really used by the call
6840    ;; sequence in which this is expanded, the PLT code assumes the PIC
6841    ;; register is set, so we must not skip its initialization.  Since
6842    ;; we only use this expand as part of calling sequences, and never
6843    ;; to take the address of a function, this is the best point to
6844    ;; insert the (use).  Using the PLT to take the address of a
6845    ;; function would be wrong, not only because the PLT entry could
6846    ;; then be called from a function that doesn't initialize the PIC
6847    ;; register to the proper GOT, but also because pointers to the
6848    ;; same function might not compare equal, should they be set by
6849    ;; different shared libraries.
6850    (use (reg:SI PIC_REG))]
6851   "TARGET_SH1"
6852   "")
6854 (define_expand "sym2PIC"
6855   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6856   ""
6857   "")
6859 ;; TLS code generation.
6860 ;; ??? this should be a define_insn_and_split
6861 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6862 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6863 ;; for details.
6865 (define_insn "tls_global_dynamic"
6866   [(set (match_operand:SI 0 "register_operand" "=&z")
6867         (call (unspec:SI [(match_operand:SI 1 "" "")]
6868                           UNSPEC_TLSGD)
6869               (const_int 0)))
6870    (use (reg:PSI FPSCR_REG))
6871    (use (reg:SI PIC_REG))
6872    (clobber (reg:SI PR_REG))
6873    (clobber (scratch:SI))]
6874   "TARGET_SH1"
6875   "*
6877   return \"\\
6878 mov.l\\t1f,r4\\n\\
6879 \\tmova\\t2f,r0\\n\\
6880 \\tmov.l\\t2f,r1\\n\\
6881 \\tadd\\tr0,r1\\n\\
6882 \\tjsr\\t@r1\\n\\
6883 \\tadd\\tr12,r4\\n\\
6884 \\tbra\\t3f\\n\\
6885 \\tnop\\n\\
6886 \\t.align\\t2\\n\\
6887 1:\\t.long\\t%a1@TLSGD\\n\\
6888 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6889 3:\";
6891   [(set_attr "type" "tls_load")
6892    (set_attr "length" "26")])
6894 (define_insn "tls_local_dynamic"
6895   [(set (match_operand:SI 0 "register_operand" "=&z")
6896         (call (unspec:SI [(match_operand:SI 1 "" "")]
6897                           UNSPEC_TLSLDM)
6898               (const_int 0)))
6899    (use (reg:PSI FPSCR_REG))
6900    (use (reg:SI PIC_REG))
6901    (clobber (reg:SI PR_REG))
6902    (clobber (scratch:SI))]
6903   "TARGET_SH1"
6904   "*
6906   return \"\\
6907 mov.l\\t1f,r4\\n\\
6908 \\tmova\\t2f,r0\\n\\
6909 \\tmov.l\\t2f,r1\\n\\
6910 \\tadd\\tr0,r1\\n\\
6911 \\tjsr\\t@r1\\n\\
6912 \\tadd\\tr12,r4\\n\\
6913 \\tbra\\t3f\\n\\
6914 \\tnop\\n\\
6915 \\t.align\\t2\\n\\
6916 1:\\t.long\\t%a1@TLSLDM\\n\\
6917 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6918 3:\";
6920   [(set_attr "type" "tls_load")
6921    (set_attr "length" "26")])
6923 (define_expand "sym2DTPOFF"
6924   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6925   ""
6926   "")
6928 (define_expand "symDTPOFF2reg"
6929   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6930   ""
6931   "
6933   rtx dtpoffsym, insn;
6934   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6936   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6937   PUT_MODE (dtpoffsym, Pmode);
6938   emit_move_insn (t, dtpoffsym);
6939   insn = emit_move_insn (operands[0],
6940                          gen_rtx_PLUS (Pmode, t, operands[2]));
6941   DONE;
6944 (define_expand "sym2GOTTPOFF"
6945   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6946   ""
6947   "")
6949 (define_insn "tls_initial_exec"
6950   [(set (match_operand:SI 0 "register_operand" "=&r")
6951         (unspec:SI [(match_operand:SI 1 "" "")]
6952                     UNSPEC_TLSIE))
6953    (use (reg:SI GBR_REG))
6954    (use (reg:SI PIC_REG))
6955    (clobber (reg:SI R0_REG))]
6956   ""
6957   "*
6959   return \"\\
6960 mov.l\\t1f,r0\\n\\
6961 \\tstc\\tgbr,%0\\n\\
6962 \\tmov.l\\t@(r0,r12),r0\\n\\
6963 \\tbra\\t2f\\n\\
6964 \\tadd\\tr0,%0\\n\\
6965 \\t.align\\t2\\n\\
6966 1:\\t.long\\t%a1\\n\\
6967 2:\";
6969   [(set_attr "type" "tls_load")
6970    (set_attr "length" "16")])
6972 (define_expand "sym2TPOFF"
6973   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6974   ""
6975   "")
6977 (define_expand "symTPOFF2reg"
6978   [(match_operand 0 "" "") (match_operand 1 "" "")]
6979   ""
6980   "
6982   rtx tpoffsym, insn;
6984   tpoffsym = gen_sym2TPOFF (operands[1]);
6985   PUT_MODE (tpoffsym, Pmode);
6986   insn = emit_move_insn (operands[0], tpoffsym);
6987   DONE;
6990 (define_insn "load_gbr"
6991   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6992    (use (reg:SI GBR_REG))]
6993   ""
6994   "stc  gbr,%0"
6995   [(set_attr "type" "tls_load")])
6997 ;; case instruction for switch statements.
6999 ;; Operand 0 is index
7000 ;; operand 1 is the minimum bound
7001 ;; operand 2 is the maximum bound - minimum bound + 1
7002 ;; operand 3 is CODE_LABEL for the table;
7003 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7005 (define_expand "casesi"
7006   [(match_operand:SI 0 "arith_reg_operand" "")
7007    (match_operand:SI 1 "arith_reg_operand" "")
7008    (match_operand:SI 2 "arith_reg_operand" "")
7009    (match_operand 3 "" "") (match_operand 4 "" "")]
7010   ""
7011   "
7013   rtx reg = gen_reg_rtx (SImode);
7014   rtx reg2 = gen_reg_rtx (SImode);
7015   if (TARGET_SHMEDIA)
7016     {
7017       rtx reg = gen_reg_rtx (DImode);
7018       rtx reg2 = gen_reg_rtx (DImode);
7019       rtx reg3 = gen_reg_rtx (DImode);
7020       rtx reg4 = gen_reg_rtx (DImode);
7021       rtx reg5 = gen_reg_rtx (DImode);
7023       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7024       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7025       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7027       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7028       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7029       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7030       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7031       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7032                                                (DImode, operands[3])));
7033       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7034       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7035       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7036       emit_barrier ();
7037       DONE;
7038     }
7039   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7040   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7041   /* If optimizing, casesi_worker depends on the mode of the instruction
7042      before label it 'uses' - operands[3].  */
7043   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7044                            reg));
7045   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7046   if (TARGET_SH2)
7047     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7048   else
7049     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7050   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7051      operands[3], but to lab.  We will fix this up in
7052      machine_dependent_reorg.  */
7053   emit_barrier ();
7054   DONE;
7057 (define_expand "casesi_0"
7058   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7059    (set (match_dup 4) (minus:SI (match_dup 4)
7060                                 (match_operand:SI 1 "arith_operand" "")))
7061    (set (reg:SI T_REG)
7062         (gtu:SI (match_dup 4)
7063                 (match_operand:SI 2 "arith_reg_operand" "")))
7064    (set (pc)
7065         (if_then_else (ne (reg:SI T_REG)
7066                           (const_int 0))
7067                       (label_ref (match_operand 3 "" ""))
7068                       (pc)))]
7069   "TARGET_SH1"
7070   "")
7072 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7073 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7074 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7076 (define_insn "casesi_worker_0"
7077   [(set (match_operand:SI 0 "register_operand" "=r,r")
7078         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7079                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7080    (clobber (match_scratch:SI 3 "=X,1"))
7081    (clobber (match_scratch:SI 4 "=&z,z"))]
7082   "TARGET_SH1"
7083   "#")
7085 (define_split
7086   [(set (match_operand:SI 0 "register_operand" "")
7087         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7088                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7089    (clobber (match_scratch:SI 3 ""))
7090    (clobber (match_scratch:SI 4 ""))]
7091   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7092   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7093    (parallel [(set (match_dup 0)
7094               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7095                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7096               (clobber (match_dup 3))])
7097    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7098   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7100 (define_split
7101   [(set (match_operand:SI 0 "register_operand" "")
7102         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7103                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7104    (clobber (match_scratch:SI 3 ""))
7105    (clobber (match_scratch:SI 4 ""))]
7106   "TARGET_SH2 && reload_completed"
7107   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7108    (parallel [(set (match_dup 0)
7109               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7110                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7111               (clobber (match_dup 3))])]
7112   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7114 (define_insn "casesi_worker_1"
7115   [(set (match_operand:SI 0 "register_operand" "=r,r")
7116         (unspec:SI [(reg:SI R0_REG)
7117                     (match_operand:SI 1 "register_operand" "0,r")
7118                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7119    (clobber (match_scratch:SI 3 "=X,1"))]
7120   "TARGET_SH1"
7121   "*
7123   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7125   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7126     abort ();
7128   switch (GET_MODE (diff_vec))
7129     {
7130     case SImode:
7131       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7132     case HImode:
7133       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7134     case QImode:
7135       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7136         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7137       return \"mov.b    @(r0,%1),%0\";
7138     default:
7139       abort ();
7140     }
7142   [(set_attr "length" "4")])
7144 (define_insn "casesi_worker_2"
7145   [(set (match_operand:SI 0 "register_operand" "=r,r")
7146         (unspec:SI [(reg:SI R0_REG)
7147                     (match_operand:SI 1 "register_operand" "0,r")
7148                     (label_ref (match_operand 2 "" ""))
7149                     (label_ref (match_operand 3 "" ""))] UNSPEC_CASESI))
7150    (clobber (match_operand:SI 4 "" "=X,1"))]
7151   "TARGET_SH2 && reload_completed && flag_pic"
7152   "*
7154   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7155   const char *load;
7157   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7158     abort ();
7160   switch (GET_MODE (diff_vec))
7161     {
7162     case SImode:
7163       output_asm_insn (\"shll2    %1\", operands);
7164       load = \"mov.l    @(r0,%1),%0\"; break;
7165     case HImode:
7166       output_asm_insn (\"add    %1,%1\", operands);
7167       load = \"mov.w    @(r0,%1),%0\"; break;
7168     case QImode:
7169       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7170         load = \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7171       else
7172         load = \"mov.b  @(r0,%1),%0\";
7173       break;
7174     default:
7175       abort ();
7176     }
7177   output_asm_insn (\"add\tr0,%1\;mova\t%O3,r0\\n\", operands);
7178   return load;
7180   [(set_attr "length" "8")])
7182 (define_insn "casesi_shift_media"
7183   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7184         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7185                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7186                     UNSPEC_CASESI)))]
7187   "TARGET_SHMEDIA"
7188   "*
7190   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7192   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7193     abort ();
7195   switch (GET_MODE (diff_vec))
7196     {
7197     case SImode:
7198       return \"shlli    %1, 2, %0\";
7199     case HImode:
7200       return \"shlli    %1, 1, %0\";
7201     case QImode:
7202       if (rtx_equal_p (operands[0], operands[1]))
7203         return \"\";
7204       return \"add      %1, r63, %0\";
7205     default:
7206       abort ();
7207     }
7209   [(set_attr "type" "arith_media")])
7211 (define_insn "casesi_load_media"
7212   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7213         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7214                          (match_operand 2 "arith_reg_operand" "r")
7215                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7216   "TARGET_SHMEDIA"
7217   "*
7219   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7221   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7222     abort ();
7224   switch (GET_MODE (diff_vec))
7225     {
7226     case SImode:
7227       return \"ldx.l    %1, %2, %0\";
7228     case HImode:
7229 #if 0
7230       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7231         return \"ldx.uw %1, %2, %0\";
7232 #endif
7233       return \"ldx.w    %1, %2, %0\";
7234     case QImode:
7235       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7236         return \"ldx.ub %1, %2, %0\";
7237       return \"ldx.b    %1, %2, %0\";
7238     default:
7239       abort ();
7240     }
7242   [(set_attr "type" "load_media")])
7244 (define_expand "return"
7245   [(return)]
7246   "reload_completed && ! sh_need_epilogue ()"
7247   "
7249   if (TARGET_SHMEDIA)
7250     {
7251       emit_jump_insn (gen_return_media ());
7252       DONE;
7253     }
7255   if (TARGET_SHCOMPACT
7256       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7257     {
7258       emit_jump_insn (gen_shcompact_return_tramp ());
7259       DONE;
7260     }
7263 (define_insn "*return_i"
7264   [(return)]
7265   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7266                     && (current_function_args_info.call_cookie
7267                         & CALL_COOKIE_RET_TRAMP (1)))
7268    && reload_completed"
7269   "%@   %#"
7270   [(set_attr "type" "return")
7271    (set_attr "needs_delay_slot" "yes")])
7273 (define_expand "shcompact_return_tramp"
7274   [(return)]
7275   "TARGET_SHCOMPACT
7276    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7277   "
7279   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7280   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7282   if (flag_pic)
7283     emit_insn (gen_symGOTPLT2reg (reg, sym));
7284   else
7285     emit_move_insn (reg, sym);
7287   emit_jump_insn (gen_shcompact_return_tramp_i ());
7288   DONE;
7291 (define_insn "shcompact_return_tramp_i"
7292   [(parallel [(return) (use (reg:SI R0_REG))])]
7293   "TARGET_SHCOMPACT
7294    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7295   "jmp  @r0%#"
7296   [(set_attr "type" "jump_ind")
7297    (set_attr "needs_delay_slot" "yes")])
7299 (define_insn "return_media_i"
7300   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7301   "TARGET_SHMEDIA && reload_completed"
7302   "blink        %0, r63"
7303   [(set_attr "type" "jump_media")])
7305 (define_insn "return_media_rte"
7306   [(return)]
7307   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7308   "rte"
7309   [(set_attr "type" "jump_media")])
7311 (define_expand "return_media"
7312   [(return)]
7313   "TARGET_SHMEDIA && reload_completed"
7314   "
7316   int tr_regno = sh_media_register_for_return ();
7317   rtx tr;
7319   if (current_function_interrupt)
7320     {
7321       emit_jump_insn (gen_return_media_rte ());
7322       DONE;
7323     }
7324   if (tr_regno < 0)
7325     {
7326       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7328       if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7329         abort ();
7330       tr_regno = TR0_REG;
7331       tr = gen_rtx_REG (DImode, tr_regno);
7332       emit_move_insn (tr, r18);
7333     }
7334   else
7335     tr = gen_rtx_REG (DImode, tr_regno);
7337   emit_jump_insn (gen_return_media_i (tr));
7338   DONE;
7341 (define_insn "shcompact_preserve_incoming_args"
7342   [(set (match_operand:SI 0 "register_operand" "+r")
7343         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7344   "TARGET_SHCOMPACT"
7345   ""
7346   [(set_attr "length" "0")])
7348 (define_insn "shcompact_incoming_args"
7349   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7350    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7351    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7352    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7353    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7354    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7355    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7356    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7357    (set (mem:BLK (reg:SI MACL_REG))
7358         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7359    (use (reg:SI R0_REG))
7360    (clobber (reg:SI R0_REG))
7361    (clobber (reg:SI MACL_REG))
7362    (clobber (reg:SI MACH_REG))
7363    (clobber (reg:SI PR_REG))]
7364   "TARGET_SHCOMPACT"
7365   "jsr  @r0%#"
7366   [(set_attr "needs_delay_slot" "yes")])
7368 (define_insn "shmedia_save_restore_regs_compact"
7369   [(set (reg:SI SP_REG)
7370         (plus:SI (reg:SI SP_REG)
7371                  (match_operand:SI 0 "immediate_operand" "i")))
7372    (use (reg:SI R0_REG))
7373    (clobber (reg:SI PR_REG))]
7374   "TARGET_SHCOMPACT
7375    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7376        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7377   "jsr @r0%#"
7378   [(set_attr "needs_delay_slot" "yes")])
7380 (define_expand "prologue"
7381   [(const_int 0)]
7382   ""
7383   "sh_expand_prologue (); DONE;")
7385 (define_expand "epilogue"
7386   [(return)]
7387   ""
7388   "
7390   sh_expand_epilogue (0);
7391   emit_jump_insn (gen_return ());
7392   DONE;
7395 (define_expand "eh_return"
7396   [(use (match_operand 0 "register_operand" ""))]
7397   ""
7399   rtx ra = operands[0];
7401   if (TARGET_SHMEDIA64)
7402     emit_insn (gen_eh_set_ra_di (ra));
7403   else
7404     emit_insn (gen_eh_set_ra_si (ra));
7406   DONE;
7409 ;; Clobber the return address on the stack.  We can't expand this
7410 ;; until we know where it will be put in the stack frame.
7412 (define_insn "eh_set_ra_si"
7413   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7414    (clobber (match_scratch:SI 1 "=&r"))]
7415   "! TARGET_SHMEDIA64"
7416   "#")
7418 (define_insn "eh_set_ra_di"
7419   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7420    (clobber (match_scratch:DI 1 "=&r"))]
7421   "TARGET_SHMEDIA64"
7422   "#")
7424 (define_split
7425   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7426    (clobber (match_scratch 1 ""))]
7427   "reload_completed"
7428   [(const_int 0)]
7429   "
7431   sh_set_return_address (operands[0], operands[1]);
7432   DONE;
7435 (define_insn "blockage"
7436   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7437   ""
7438   ""
7439   [(set_attr "length" "0")])
7441 ;; ------------------------------------------------------------------------
7442 ;; Scc instructions
7443 ;; ------------------------------------------------------------------------
7445 (define_insn "movt"
7446   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7447         (eq:SI (reg:SI T_REG) (const_int 1)))]
7448   "TARGET_SH1"
7449   "movt %0"
7450   [(set_attr "type" "arith")])
7452 (define_expand "seq"
7453   [(set (match_operand:SI 0 "arith_reg_operand" "")
7454         (match_dup 1))]
7455   ""
7456   "
7458   if (TARGET_SHMEDIA)
7459     {
7460       if (GET_MODE (operands[0]) != DImode)
7461         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7462       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7463       if (sh_compare_op1 != const0_rtx)
7464         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7465                                     ? GET_MODE (sh_compare_op0)
7466                                     : GET_MODE (sh_compare_op1),
7467                                     sh_compare_op1);
7469       switch (GET_MODE (sh_compare_op0))
7470         {
7471         case DImode:
7472           emit_insn (gen_cmpeqdi_media (operands[0],
7473                                         sh_compare_op0, sh_compare_op1));
7474           break;
7476         case SFmode:
7477           if (! TARGET_SHMEDIA_FPU)
7478             FAIL;
7479           emit_insn (gen_cmpeqsf_media (operands[0],
7480                                         sh_compare_op0, sh_compare_op1));
7481           break;
7483         case DFmode:
7484           if (! TARGET_SHMEDIA_FPU)
7485             FAIL;
7486           emit_insn (gen_cmpeqdf_media (operands[0],
7487                                         sh_compare_op0, sh_compare_op1));
7488           break;
7490         default:
7491           FAIL;
7492         }
7493       DONE;
7494     }
7495   if (sh_expand_t_scc (EQ, operands[0]))
7496     DONE;
7497   if (! rtx_equal_function_value_matters)
7498     FAIL;
7499   operands[1] = prepare_scc_operands (EQ);
7502 (define_expand "slt"
7503   [(set (match_operand:SI 0 "arith_reg_operand" "")
7504         (match_dup 1))]
7505   ""
7506   "
7508   if (TARGET_SHMEDIA)
7509     {
7510       if (GET_MODE (operands[0]) != DImode)
7511         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7512       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7513       if (sh_compare_op1 != const0_rtx)
7514         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7515                                     ? GET_MODE (sh_compare_op0)
7516                                     : GET_MODE (sh_compare_op1),
7517                                     sh_compare_op1);
7519       switch (GET_MODE (sh_compare_op0))
7520         {
7521         case DImode:
7522           emit_insn (gen_cmpgtdi_media (operands[0],
7523                                         sh_compare_op1, sh_compare_op0));
7524           break;
7526         case SFmode:
7527           if (! TARGET_SHMEDIA_FPU)
7528             FAIL;
7529           emit_insn (gen_cmpgtsf_media (operands[0],
7530                                         sh_compare_op1, sh_compare_op0));
7531           break;
7533         case DFmode:
7534           if (! TARGET_SHMEDIA_FPU)
7535             FAIL;
7536           emit_insn (gen_cmpgtdf_media (operands[0],
7537                                         sh_compare_op1, sh_compare_op0));
7538           break;
7540         default:
7541           FAIL;
7542         }
7543       DONE;
7544     }
7545   if (! rtx_equal_function_value_matters)
7546     FAIL;
7547   operands[1] = prepare_scc_operands (LT);
7550 (define_expand "sle"
7551   [(match_operand:SI 0 "arith_reg_operand" "")]
7552   ""
7553   "
7555   rtx tmp = sh_compare_op0;
7557   if (TARGET_SHMEDIA)
7558     {
7559       if (GET_MODE (operands[0]) != DImode)
7560         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7561       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7562       if (sh_compare_op1 != const0_rtx)
7563         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7564                                     ? GET_MODE (sh_compare_op0)
7565                                     : GET_MODE (sh_compare_op1),
7566                                     sh_compare_op1);
7568       switch (GET_MODE (sh_compare_op0))
7569         {
7570         case DImode:
7571           {
7572             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7574             emit_insn (gen_cmpgtdi_media (tmp,
7575                                           sh_compare_op0, sh_compare_op1));
7576             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7577             break;
7578           }
7580         case SFmode:
7581           if (! TARGET_SHMEDIA_FPU)
7582             FAIL;
7583           emit_insn (gen_cmpgesf_media (operands[0],
7584                                         sh_compare_op1, sh_compare_op0));
7585           break;
7587         case DFmode:
7588           if (! TARGET_SHMEDIA_FPU)
7589             FAIL;
7590           emit_insn (gen_cmpgedf_media (operands[0],
7591                                         sh_compare_op1, sh_compare_op0));
7592           break;
7594         default:
7595           FAIL;
7596         }
7597       DONE;
7598     }
7600   sh_compare_op0 = sh_compare_op1;
7601   sh_compare_op1 = tmp;
7602   emit_insn (gen_sge (operands[0]));
7603   DONE;
7606 (define_expand "sgt"
7607   [(set (match_operand:SI 0 "arith_reg_operand" "")
7608         (match_dup 1))]
7609   ""
7610   "
7612   if (TARGET_SHMEDIA)
7613     {
7614       if (GET_MODE (operands[0]) != DImode)
7615         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7616       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7617       if (sh_compare_op1 != const0_rtx)
7618         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7619                                     ? GET_MODE (sh_compare_op0)
7620                                     : GET_MODE (sh_compare_op1),
7621                                     sh_compare_op1);
7623       switch (GET_MODE (sh_compare_op0))
7624         {
7625         case DImode:
7626           emit_insn (gen_cmpgtdi_media (operands[0],
7627                                         sh_compare_op0, sh_compare_op1));
7628           break;
7630         case SFmode:
7631           if (! TARGET_SHMEDIA_FPU)
7632             FAIL;
7633           emit_insn (gen_cmpgtsf_media (operands[0],
7634                                         sh_compare_op0, sh_compare_op1));
7635           break;
7637         case DFmode:
7638           if (! TARGET_SHMEDIA_FPU)
7639             FAIL;
7640           emit_insn (gen_cmpgtdf_media (operands[0],
7641                                         sh_compare_op0, sh_compare_op1));
7642           break;
7644         default:
7645           FAIL;
7646         }
7647       DONE;
7648     }
7649   if (! rtx_equal_function_value_matters)
7650     FAIL;
7651   operands[1] = prepare_scc_operands (GT);
7654 (define_expand "sge"
7655   [(set (match_operand:SI 0 "arith_reg_operand" "")
7656         (match_dup 1))]
7657   ""
7658   "
7660   if (TARGET_SHMEDIA)
7661     {
7662       if (GET_MODE (operands[0]) != DImode)
7663         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7664       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7665       if (sh_compare_op1 != const0_rtx)
7666         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7667                                     ? GET_MODE (sh_compare_op0)
7668                                     : GET_MODE (sh_compare_op1),
7669                                     sh_compare_op1);
7671       switch (GET_MODE (sh_compare_op0))
7672         {
7673         case DImode:
7674           {
7675             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7677             emit_insn (gen_cmpgtdi_media (tmp,
7678                                           sh_compare_op1, sh_compare_op0));
7679             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7680             break;
7681           }
7683         case SFmode:
7684           if (! TARGET_SHMEDIA_FPU)
7685             FAIL;
7686           emit_insn (gen_cmpgesf_media (operands[0],
7687                                         sh_compare_op0, sh_compare_op1));
7688           break;
7690         case DFmode:
7691           if (! TARGET_SHMEDIA_FPU)
7692             FAIL;
7693           emit_insn (gen_cmpgedf_media (operands[0],
7694                                         sh_compare_op0, sh_compare_op1));
7695           break;
7697         default:
7698           FAIL;
7699         }
7700       DONE;
7701     }
7703   if (! rtx_equal_function_value_matters)
7704     FAIL;
7705   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7706     {
7707       if (TARGET_IEEE)
7708         {
7709           rtx lab = gen_label_rtx ();
7710           prepare_scc_operands (EQ);
7711           emit_jump_insn (gen_branch_true (lab));
7712           prepare_scc_operands (GT);
7713           emit_label (lab);
7714           emit_insn (gen_movt (operands[0]));
7715         }
7716       else
7717         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7718       DONE;
7719     }
7720   operands[1] = prepare_scc_operands (GE);
7723 (define_expand "sgtu"
7724   [(set (match_operand:SI 0 "arith_reg_operand" "")
7725         (match_dup 1))]
7726   ""
7727   "
7729   if (TARGET_SHMEDIA)
7730     {
7731       if (GET_MODE (operands[0]) != DImode)
7732         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7733       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7734       if (sh_compare_op1 != const0_rtx)
7735         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7736                                     ? GET_MODE (sh_compare_op0)
7737                                     : GET_MODE (sh_compare_op1),
7738                                     sh_compare_op1);
7740       emit_insn (gen_cmpgtudi_media (operands[0],
7741                                      sh_compare_op0, sh_compare_op1));
7742       DONE;
7743     }
7744   if (! rtx_equal_function_value_matters)
7745     FAIL;
7746   operands[1] = prepare_scc_operands (GTU);
7749 (define_expand "sltu"
7750   [(set (match_operand:SI 0 "arith_reg_operand" "")
7751         (match_dup 1))]
7752   ""
7753   "
7755   if (TARGET_SHMEDIA)
7756     {
7757       if (GET_MODE (operands[0]) != DImode)
7758         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7759       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7760       if (sh_compare_op1 != const0_rtx)
7761         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7762                                     ? GET_MODE (sh_compare_op0)
7763                                     : GET_MODE (sh_compare_op1),
7764                                     sh_compare_op1);
7766       emit_insn (gen_cmpgtudi_media (operands[0],
7767                                      sh_compare_op1, sh_compare_op0));
7768       DONE;
7769     }
7770   if (! rtx_equal_function_value_matters)
7771     FAIL;
7772   operands[1] = prepare_scc_operands (LTU);
7775 (define_expand "sleu"
7776   [(set (match_operand:SI 0 "arith_reg_operand" "")
7777         (match_dup 1))]
7778   ""
7779   "
7781   if (TARGET_SHMEDIA)
7782     {
7783       rtx tmp;
7785       if (GET_MODE (operands[0]) != DImode)
7786         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7787       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7788       if (sh_compare_op1 != const0_rtx)
7789         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7790                                     ? GET_MODE (sh_compare_op0)
7791                                     : GET_MODE (sh_compare_op1),
7792                                     sh_compare_op1);
7794       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7796       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7797       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7799       DONE;
7800     }
7801   if (! rtx_equal_function_value_matters)
7802     FAIL;
7803   operands[1] = prepare_scc_operands (LEU);
7806 (define_expand "sgeu"
7807   [(set (match_operand:SI 0 "arith_reg_operand" "")
7808         (match_dup 1))]
7809   ""
7810   "
7812   if (TARGET_SHMEDIA)
7813     {
7814       rtx tmp;
7816       if (GET_MODE (operands[0]) != DImode)
7817         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7818       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7819       if (sh_compare_op1 != const0_rtx)
7820         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7821                                     ? GET_MODE (sh_compare_op0)
7822                                     : GET_MODE (sh_compare_op1),
7823                                     sh_compare_op1);
7825       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7827       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7828       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7830       DONE;
7831     }
7833   if (! rtx_equal_function_value_matters)
7834     FAIL;
7835   operands[1] = prepare_scc_operands (GEU);
7838 ;; sne moves the complement of the T reg to DEST like this:
7839 ;;      cmp/eq ...
7840 ;;      mov    #-1,temp
7841 ;;      negc   temp,dest
7842 ;;   This is better than xoring compare result with 1 because it does
7843 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7844 ;;   loop.
7846 (define_expand "sne"
7847   [(set (match_dup 2) (const_int -1))
7848    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7849                    (neg:SI (plus:SI (match_dup 1)
7850                                     (match_dup 2))))
7851               (set (reg:SI T_REG)
7852                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7853                           (const_int 0)))])]
7854   ""
7855   "
7857   if (TARGET_SHMEDIA)
7858     {
7859       rtx tmp;
7861       if (GET_MODE (operands[0]) != DImode)
7862         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7864       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7865         FAIL;
7867       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7868       if (sh_compare_op1 != const0_rtx)
7869         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7870                                     ? GET_MODE (sh_compare_op0)
7871                                     : GET_MODE (sh_compare_op1),
7872                                     sh_compare_op1);
7874       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7876       emit_insn (gen_seq (tmp));
7877       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7879       DONE;
7880     }
7882   if (sh_expand_t_scc (NE, operands[0]))
7883     DONE;
7884   if (! rtx_equal_function_value_matters)
7885     FAIL;
7886   operands[1] = prepare_scc_operands (EQ);
7887   operands[2] = gen_reg_rtx (SImode);
7890 (define_expand "sunordered"
7891   [(set (match_operand:DI 0 "arith_reg_operand" "")
7892         (unordered:DI (match_dup 1) (match_dup 2)))]
7893   "TARGET_SHMEDIA_FPU"
7894   "
7896   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7897   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7900 ;; Use the same trick for FP sle / sge
7901 (define_expand "movnegt"
7902   [(set (match_dup 2) (const_int -1))
7903    (parallel [(set (match_operand 0 "" "")
7904                    (neg:SI (plus:SI (match_dup 1)
7905                                     (match_dup 2))))
7906               (set (reg:SI T_REG)
7907                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7908                           (const_int 0)))])]
7909   "TARGET_SH1"
7910   "operands[2] = gen_reg_rtx (SImode);")
7912 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7913 ;; This prevents a regression that occurred when we switched from xor to
7914 ;; mov/neg for sne.
7916 (define_split
7917   [(set (match_operand:SI 0 "arith_reg_operand" "")
7918         (plus:SI (reg:SI T_REG)
7919                  (const_int -1)))]
7920   "TARGET_SH1"
7921   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7922    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7923   "")
7925 ;; -------------------------------------------------------------------------
7926 ;; Instructions to cope with inline literal tables
7927 ;; -------------------------------------------------------------------------
7929 ; 2 byte integer in line
7931 (define_insn "consttable_2"
7932  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7933                     (match_operand 1 "" "")]
7934                    UNSPECV_CONST2)]
7935  ""
7936  "*
7938   if (operands[1] != const0_rtx)
7939     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7940   return \"\";
7942  [(set_attr "length" "2")
7943  (set_attr "in_delay_slot" "no")])
7945 ; 4 byte integer in line
7947 (define_insn "consttable_4"
7948  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7949                     (match_operand 1 "" "")]
7950                    UNSPECV_CONST4)]
7951  ""
7952  "*
7954   if (operands[1] != const0_rtx)
7955     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7956   return \"\";
7958  [(set_attr "length" "4")
7959   (set_attr "in_delay_slot" "no")])
7961 ; 8 byte integer in line
7963 (define_insn "consttable_8"
7964  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7965                     (match_operand 1 "" "")]
7966                    UNSPECV_CONST8)]
7967  ""
7968  "*
7970   if (operands[1] != const0_rtx)
7971     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7972   return \"\";
7974  [(set_attr "length" "8")
7975   (set_attr "in_delay_slot" "no")])
7977 ; 4 byte floating point
7979 (define_insn "consttable_sf"
7980  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7981                     (match_operand 1 "" "")]
7982                    UNSPECV_CONST4)]
7983  ""
7984  "*
7986   if (operands[1] != const0_rtx)
7987     {
7988       REAL_VALUE_TYPE d;
7989       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7990       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7991     }
7992   return \"\";
7994  [(set_attr "length" "4")
7995   (set_attr "in_delay_slot" "no")])
7997 ; 8 byte floating point
7999 (define_insn "consttable_df"
8000  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
8001                     (match_operand 1 "" "")]
8002                    UNSPECV_CONST8)]
8003  ""
8004  "*
8006   if (operands[1] != const0_rtx)
8007     {
8008       REAL_VALUE_TYPE d;
8009       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
8010       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
8011     }
8012   return \"\";
8014  [(set_attr "length" "8")
8015   (set_attr "in_delay_slot" "no")])
8017 ;; Alignment is needed for some constant tables; it may also be added for
8018 ;; Instructions at the start of loops, or after unconditional branches.
8019 ;; ??? We would get more accurate lengths if we did instruction
8020 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
8021 ;; here is too conservative.
8023 ; align to a two byte boundary
8025 (define_expand "align_2"
8026  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
8027  ""
8028  "")
8030 ; align to a four byte boundary
8031 ;; align_4 and align_log are instructions for the starts of loops, or
8032 ;; after unconditional branches, which may take up extra room.
8034 (define_expand "align_4"
8035  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
8036  ""
8037  "")
8039 ; align to a cache line boundary
8041 (define_insn "align_log"
8042  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8043  ""
8044  ""
8045  [(set_attr "length" "0")
8046   (set_attr "in_delay_slot" "no")])
8048 ; emitted at the end of the literal table, used to emit the
8049 ; 32bit branch labels if needed.
8051 (define_insn "consttable_end"
8052   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8053   ""
8054   "* return output_jump_label_table ();"
8055   [(set_attr "in_delay_slot" "no")])
8057 ; emitted at the end of the window in the literal table.
8059 (define_insn "consttable_window_end"
8060   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8061   ""
8062   ""
8063   [(set_attr "length" "0")
8064    (set_attr "in_delay_slot" "no")])
8066 ;; -------------------------------------------------------------------------
8067 ;; Misc
8068 ;; -------------------------------------------------------------------------
8070 ;; String/block move insn.
8072 (define_expand "movstrsi"
8073   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8074                    (mem:BLK (match_operand:BLK 1 "" "")))
8075               (use (match_operand:SI 2 "nonmemory_operand" ""))
8076               (use (match_operand:SI 3 "immediate_operand" ""))
8077               (clobber (reg:SI PR_REG))
8078               (clobber (reg:SI R4_REG))
8079               (clobber (reg:SI R5_REG))
8080               (clobber (reg:SI R0_REG))])]
8081   "TARGET_SH1 && ! TARGET_SH5"
8082   "
8084   if(expand_block_move (operands))
8085      DONE;
8086   else FAIL;
8089 (define_insn "block_move_real"
8090   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8091                    (mem:BLK (reg:SI R5_REG)))
8092               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8093               (clobber (reg:SI PR_REG))
8094               (clobber (reg:SI R0_REG))])]
8095   "TARGET_SH1 && ! TARGET_HARD_SH4"
8096   "jsr  @%0%#"
8097   [(set_attr "type" "sfunc")
8098    (set_attr "needs_delay_slot" "yes")])
8100 (define_insn "block_lump_real"
8101   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8102                    (mem:BLK (reg:SI R5_REG)))
8103               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8104               (use (reg:SI R6_REG))
8105               (clobber (reg:SI PR_REG))
8106               (clobber (reg:SI T_REG))
8107               (clobber (reg:SI R4_REG))
8108               (clobber (reg:SI R5_REG))
8109               (clobber (reg:SI R6_REG))
8110               (clobber (reg:SI R0_REG))])]
8111   "TARGET_SH1 && ! TARGET_HARD_SH4"
8112   "jsr  @%0%#"
8113   [(set_attr "type" "sfunc")
8114    (set_attr "needs_delay_slot" "yes")])
8116 (define_insn "block_move_real_i4"
8117   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8118                    (mem:BLK (reg:SI R5_REG)))
8119               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8120               (clobber (reg:SI PR_REG))
8121               (clobber (reg:SI R0_REG))
8122               (clobber (reg:SI R1_REG))
8123               (clobber (reg:SI R2_REG))])]
8124   "TARGET_HARD_SH4"
8125   "jsr  @%0%#"
8126   [(set_attr "type" "sfunc")
8127    (set_attr "needs_delay_slot" "yes")])
8129 (define_insn "block_lump_real_i4"
8130   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8131                    (mem:BLK (reg:SI R5_REG)))
8132               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8133               (use (reg:SI R6_REG))
8134               (clobber (reg:SI PR_REG))
8135               (clobber (reg:SI T_REG))
8136               (clobber (reg:SI R4_REG))
8137               (clobber (reg:SI R5_REG))
8138               (clobber (reg:SI R6_REG))
8139               (clobber (reg:SI R0_REG))
8140               (clobber (reg:SI R1_REG))
8141               (clobber (reg:SI R2_REG))
8142               (clobber (reg:SI R3_REG))])]
8143   "TARGET_HARD_SH4"
8144   "jsr  @%0%#"
8145   [(set_attr "type" "sfunc")
8146    (set_attr "needs_delay_slot" "yes")])
8148 ;; -------------------------------------------------------------------------
8149 ;; Floating point instructions.
8150 ;; -------------------------------------------------------------------------
8152 ;; ??? All patterns should have a type attribute.
8154 (define_expand "fpu_switch0"
8155   [(set (match_operand:SI 0 "" "") (match_dup 2))
8156    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8157   "TARGET_SH4"
8158   "
8160   operands[1] = get_fpscr_rtx ();
8161   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8162   if (flag_pic)
8163     operands[2] = legitimize_pic_address (operands[2], SImode,
8164                                           no_new_pseudos ? operands[0] : 0);
8167 (define_expand "fpu_switch1"
8168   [(set (match_operand:SI 0 "" "") (match_dup 2))
8169    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8170    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8171   "TARGET_SH4"
8172   "
8174   operands[1] = get_fpscr_rtx ();
8175   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8176   if (flag_pic)
8177     operands[2] = legitimize_pic_address (operands[2], SImode,
8178                                           no_new_pseudos ? operands[0] : 0);
8179   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8182 (define_expand "movpsi"
8183   [(set (match_operand:PSI 0 "register_operand" "")
8184         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8185   "TARGET_SH4"
8186   "")
8188 ;; The c / m alternative is a fake to guide reload to load directly into
8189 ;; fpscr, since reload doesn't know how to use post-increment.
8190 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8191 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8192 ;; predicate after reload.
8193 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8194 ;; like a mac -> gpr move.
8195 (define_insn "fpu_switch"
8196   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8197         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8198   "TARGET_SH2E
8199    && (! reload_completed
8200        || true_regnum (operands[0]) != FPSCR_REG
8201        || GET_CODE (operands[1]) != MEM
8202        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8203   "@
8204         ! precision stays the same
8205         lds.l   %1,fpscr
8206         mov.l   %1,%0
8207         #
8208         lds     %1,fpscr
8209         mov     %1,%0
8210         mov.l   %1,%0
8211         sts     fpscr,%0
8212         sts.l   fpscr,%0"
8213   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8214    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8216 (define_split
8217   [(set (reg:PSI FPSCR_REG)
8218         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8219   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8220   [(set (match_dup 0) (match_dup 0))]
8221   "
8223   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8224                                         gen_rtx_MEM (PSImode,
8225                                                  gen_rtx_POST_INC (Pmode,
8226                                                           operands[0]))));
8227   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8230 (define_split
8231   [(set (reg:PSI FPSCR_REG)
8232         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8233   "TARGET_SH4"
8234   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8235   "
8237   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8238                                         gen_rtx_MEM (PSImode,
8239                                                  gen_rtx_POST_INC (Pmode,
8240                                                           operands[0]))));
8241   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, operands[0], NULL_RTX);
8244 ;; ??? This uses the fp unit, but has no type indicating that.
8245 ;; If we did that, this would either give a bogus latency or introduce
8246 ;; a bogus FIFO constraint.
8247 ;; Since this insn is currently only used for prologues/epilogues,
8248 ;; it is probably best to claim no function unit, which matches the
8249 ;; current setting.
8250 (define_insn "toggle_sz"
8251   [(set (reg:PSI FPSCR_REG)
8252         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8253   "TARGET_SH4"
8254   "fschg"
8255   [(set_attr "fp_set" "unknown")])
8257 (define_expand "addsf3"
8258   [(set (match_operand:SF 0 "arith_reg_operand" "")
8259         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8260                  (match_operand:SF 2 "arith_reg_operand" "")))]
8261   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8262   "
8264   if (TARGET_SH2E)
8265     {
8266       expand_sf_binop (&gen_addsf3_i, operands);
8267       DONE;
8268     }
8271 (define_insn "*addsf3_media"
8272   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8273         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8274                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8275   "TARGET_SHMEDIA_FPU"
8276   "fadd.s       %1, %2, %0"
8277   [(set_attr "type" "fparith_media")])
8279 (define_insn_and_split "unary_sf_op"
8280   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8281         (vec_select:V2SF
8282          (vec_concat:V2SF
8283           (vec_select:SF
8284            (match_dup 0)
8285            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8286           (match_operator:SF 2 "unary_float_operator"
8287             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8288                             (parallel [(match_operand 4
8289                                         "const_int_operand" "n")]))]))
8290          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8291   "TARGET_SHMEDIA_FPU"
8292   "#"
8293   "TARGET_SHMEDIA_FPU && reload_completed"
8294   [(set (match_dup 5) (match_dup 6))]
8295   "
8297   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8298   rtx op1 = gen_rtx_REG (SFmode,
8299                          (true_regnum (operands[1])
8300                           + (INTVAL (operands[4]) ^ endian)));
8302   operands[7] = gen_rtx_REG (SFmode,
8303                              (true_regnum (operands[0])
8304                               + (INTVAL (operands[3]) ^ endian)));
8305   operands[6] = gen_rtx_fmt_e (GET_CODE (operands[2]), SFmode, op1);
8307   [(set_attr "type" "fparith_media")])
8309 (define_insn_and_split "binary_sf_op"
8310   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8311         (vec_select:V2SF
8312          (vec_concat:V2SF
8313           (vec_select:SF
8314            (match_dup 0)
8315            (parallel [(match_operand 7 "const_int_operand" "n")]))
8316           (match_operator:SF 3 "binary_float_operator"
8317             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8318                             (parallel [(match_operand 5
8319                                         "const_int_operand" "n")]))
8320              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8321                             (parallel [(match_operand 6
8322                                         "const_int_operand" "n")]))]))
8323          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8324   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8325   "#"
8326   "&& reload_completed"
8327   [(set (match_dup 8) (match_dup 9))]
8328   "
8330   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8331   rtx op1 = gen_rtx_REG (SFmode,
8332                          (true_regnum (operands[1])
8333                           + (INTVAL (operands[5]) ^ endian)));
8334   rtx op2 = gen_rtx_REG (SFmode,
8335                          (true_regnum (operands[2])
8336                           + (INTVAL (operands[6]) ^ endian)));
8338   operands[8] = gen_rtx_REG (SFmode,
8339                              (true_regnum (operands[0])
8340                               + (INTVAL (operands[4]) ^ endian)));
8341   operands[9] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SFmode, op1, op2);
8343   [(set_attr "type" "fparith_media")])
8345 (define_insn "addsf3_i"
8346   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8347         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8348                  (match_operand:SF 2 "arith_reg_operand" "f")))
8349    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8350   "TARGET_SH2E"
8351   "fadd %2,%0"
8352   [(set_attr "type" "fp")
8353    (set_attr "fp_mode" "single")])
8355 (define_expand "subsf3"
8356   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8357         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8358                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8359   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8360   "
8362   if (TARGET_SH2E)
8363     {
8364       expand_sf_binop (&gen_subsf3_i, operands);
8365       DONE;
8366     }
8369 (define_insn "*subsf3_media"
8370   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8371         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8372                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8373   "TARGET_SHMEDIA_FPU"
8374   "fsub.s       %1, %2, %0"
8375   [(set_attr "type" "fparith_media")])
8377 (define_insn "subsf3_i"
8378   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8379         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8380                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8381    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8382   "TARGET_SH2E"
8383   "fsub %2,%0"
8384   [(set_attr "type" "fp")
8385    (set_attr "fp_mode" "single")])
8387 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8388 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8389 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8390 ;; SH3E, we use a separate insn for SH3E mulsf3.
8392 (define_expand "mulsf3"
8393   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8394         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8395                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8396   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8397   "
8399   if (TARGET_SH4)
8400     expand_sf_binop (&gen_mulsf3_i4, operands);
8401   else if (TARGET_SH2E)
8402     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8403   if (! TARGET_SHMEDIA)
8404     DONE;
8407 (define_insn "*mulsf3_media"
8408   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8409         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8410                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8411   "TARGET_SHMEDIA_FPU"
8412   "fmul.s       %1, %2, %0"
8413   [(set_attr "type" "fparith_media")])
8415 (define_insn "mulsf3_i4"
8416   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8417         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8418                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8419    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8420   "TARGET_SH2E"
8421   "fmul %2,%0"
8422   [(set_attr "type" "fp")
8423    (set_attr "fp_mode" "single")])
8425 (define_insn "mulsf3_ie"
8426   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8427         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8428                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8429   "TARGET_SH2E && ! TARGET_SH4"
8430   "fmul %2,%0"
8431   [(set_attr "type" "fp")])
8433 (define_insn "*mac_media"
8434   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8435         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8436                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8437                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8438   "TARGET_SHMEDIA_FPU"
8439   "fmac.s %1, %2, %0"
8440   [(set_attr "type" "fparith_media")])
8442 (define_insn "*macsf3"
8443   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8444         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8445                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8446                  (match_operand:SF 3 "arith_reg_operand" "0")))
8447    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8448   "TARGET_SH2E && ! TARGET_SH4"
8449   "fmac fr0,%2,%0"
8450   [(set_attr "type" "fp")
8451    (set_attr "fp_mode" "single")])
8453 (define_expand "divsf3"
8454   [(set (match_operand:SF 0 "arith_reg_operand" "")
8455         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8456                 (match_operand:SF 2 "arith_reg_operand" "")))]
8457   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8458   "
8460   if (TARGET_SH2E)
8461     {
8462       expand_sf_binop (&gen_divsf3_i, operands);
8463       DONE;
8464     }
8467 (define_insn "*divsf3_media"
8468   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8469         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8470                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8471   "TARGET_SHMEDIA_FPU"
8472   "fdiv.s       %1, %2, %0"
8473   [(set_attr "type" "fdiv_media")])
8475 (define_insn "divsf3_i"
8476   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8477         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8478                  (match_operand:SF 2 "arith_reg_operand" "f")))
8479    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8480   "TARGET_SH2E"
8481   "fdiv %2,%0"
8482   [(set_attr "type" "fdiv")
8483    (set_attr "fp_mode" "single")])
8485 (define_insn "floatdisf2"
8486   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8487         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8488   "TARGET_SHMEDIA_FPU"
8489   "float.qs %1, %0"
8490   [(set_attr "type" "fpconv_media")])
8492 (define_expand "floatsisf2"
8493   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8494         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8495   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8496   "
8498   if (TARGET_SH4)
8499     {
8500       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8501       DONE;
8502     }
8505 (define_insn "*floatsisf2_media"
8506   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8507         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8508   "TARGET_SHMEDIA_FPU"
8509   "float.ls     %1, %0"
8510   [(set_attr "type" "fpconv_media")])
8512 (define_insn "floatsisf2_i4"
8513   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8514         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8515    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8516   "TARGET_SH4"
8517   "float        %1,%0"
8518   [(set_attr "type" "fp")
8519    (set_attr "fp_mode" "single")])
8521 (define_insn "*floatsisf2_ie"
8522   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8523         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8524   "TARGET_SH2E && ! TARGET_SH4"
8525   "float        %1,%0"
8526   [(set_attr "type" "fp")])
8528 (define_insn "fix_truncsfdi2"
8529   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8530         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8531   "TARGET_SHMEDIA_FPU"
8532   "ftrc.sq %1, %0"
8533   [(set_attr "type" "fpconv_media")])
8535 (define_expand "fix_truncsfsi2"
8536   [(set (match_operand:SI 0 "fpul_operand" "=y")
8537         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8538   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8539   "
8541   if (TARGET_SH4)
8542     {
8543       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8544       DONE;
8545     }
8548 (define_insn "*fix_truncsfsi2_media"
8549   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8550         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8551   "TARGET_SHMEDIA_FPU"
8552   "ftrc.sl      %1, %0"
8553   [(set_attr "type" "fpconv_media")])
8555 (define_insn "fix_truncsfsi2_i4"
8556   [(set (match_operand:SI 0 "fpul_operand" "=y")
8557         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8558    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8559   "TARGET_SH4"
8560   "ftrc %1,%0"
8561   [(set_attr "type" "ftrc_s")
8562    (set_attr "fp_mode" "single")])
8564 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8565 ;; fix_truncsfsi2_i4.
8566 ;; (define_insn "fix_truncsfsi2_i4_2"
8567 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8568 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8569 ;;   (use (reg:PSI FPSCR_REG))
8570 ;;   (clobber (reg:SI FPUL_REG))]
8571 ;;  "TARGET_SH4"
8572 ;;  "#"
8573 ;;  [(set_attr "length" "4")
8574 ;;   (set_attr "fp_mode" "single")])
8576 ;;(define_split
8577 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8578 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8579 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8580 ;;   (clobber (reg:SI FPUL_REG))]
8581 ;;  "TARGET_SH4"
8582 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8583 ;;            (use (match_dup 2))])
8584 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8586 (define_insn "*fixsfsi"
8587   [(set (match_operand:SI 0 "fpul_operand" "=y")
8588         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8589   "TARGET_SH2E && ! TARGET_SH4"
8590   "ftrc %1,%0"
8591   [(set_attr "type" "fp")])
8593 (define_insn "cmpgtsf_t"
8594   [(set (reg:SI T_REG)
8595         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8596                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8597   "TARGET_SH2E && ! TARGET_SH4"
8598   "fcmp/gt      %1,%0"
8599   [(set_attr "type" "fp")
8600    (set_attr "fp_mode" "single")])
8602 (define_insn "cmpeqsf_t"
8603   [(set (reg:SI T_REG)
8604         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8605                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8606   "TARGET_SH2E && ! TARGET_SH4"
8607   "fcmp/eq      %1,%0"
8608   [(set_attr "type" "fp")
8609    (set_attr "fp_mode" "single")])
8611 (define_insn "ieee_ccmpeqsf_t"
8612   [(set (reg:SI T_REG)
8613         (ior:SI (reg:SI T_REG)
8614                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8615                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8616   "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8617   "* return output_ieee_ccmpeq (insn, operands);"
8618   [(set_attr "length" "4")])
8621 (define_insn "cmpgtsf_t_i4"
8622   [(set (reg:SI T_REG)
8623         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8624                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8625    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8626   "TARGET_SH4"
8627   "fcmp/gt      %1,%0"
8628   [(set_attr "type" "fp")
8629    (set_attr "fp_mode" "single")])
8631 (define_insn "cmpeqsf_t_i4"
8632   [(set (reg:SI T_REG)
8633         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8634                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8635    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8636   "TARGET_SH4"
8637   "fcmp/eq      %1,%0"
8638   [(set_attr "type" "fp")
8639    (set_attr "fp_mode" "single")])
8641 (define_insn "*ieee_ccmpeqsf_t_4"
8642   [(set (reg:SI T_REG)
8643         (ior:SI (reg:SI T_REG)
8644                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8645                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8646    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8647   "TARGET_IEEE && TARGET_SH4"
8648   "* return output_ieee_ccmpeq (insn, operands);"
8649   [(set_attr "length" "4")
8650    (set_attr "fp_mode" "single")])
8652 (define_insn "cmpeqsf_media"
8653   [(set (match_operand:DI 0 "register_operand" "=r")
8654         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8655                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8656   "TARGET_SHMEDIA_FPU"
8657   "fcmpeq.s     %1, %2, %0"
8658   [(set_attr "type" "fcmp_media")])
8660 (define_insn "cmpgtsf_media"
8661   [(set (match_operand:DI 0 "register_operand" "=r")
8662         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8663                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8664   "TARGET_SHMEDIA_FPU"
8665   "fcmpgt.s     %1, %2, %0"
8666   [(set_attr "type" "fcmp_media")])
8668 (define_insn "cmpgesf_media"
8669   [(set (match_operand:DI 0 "register_operand" "=r")
8670         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8671                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8672   "TARGET_SHMEDIA_FPU"
8673   "fcmpge.s     %1, %2, %0"
8674   [(set_attr "type" "fcmp_media")])
8676 (define_insn "cmpunsf_media"
8677   [(set (match_operand:DI 0 "register_operand" "=r")
8678         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8679                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8680   "TARGET_SHMEDIA_FPU"
8681   "fcmpun.s     %1, %2, %0"
8682   [(set_attr "type" "fcmp_media")])
8684 (define_expand "cmpsf"
8685   [(set (reg:SI T_REG)
8686         (compare (match_operand:SF 0 "arith_operand" "")
8687                  (match_operand:SF 1 "arith_operand" "")))]
8688   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8689   "
8691   sh_compare_op0 = operands[0];
8692   sh_compare_op1 = operands[1];
8693   DONE;
8696 (define_expand "negsf2"
8697   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8698         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8699   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8700   "
8702   if (TARGET_SH2E)
8703     {
8704       expand_sf_unop (&gen_negsf2_i, operands);
8705       DONE;
8706     }
8709 (define_insn "*negsf2_media"
8710   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8711         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8712   "TARGET_SHMEDIA_FPU"
8713   "fneg.s       %1, %0"
8714   [(set_attr "type" "fmove_media")])
8716 (define_insn "negsf2_i"
8717   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8718         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8719    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8720   "TARGET_SH2E"
8721   "fneg %0"
8722   [(set_attr "type" "fmove")
8723    (set_attr "fp_mode" "single")])
8725 (define_expand "sqrtsf2"
8726   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8727         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8728   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8729   "
8731   if (TARGET_SH3E)
8732     {
8733       expand_sf_unop (&gen_sqrtsf2_i, operands);
8734       DONE;
8735     }
8738 (define_insn "*sqrtsf2_media"
8739   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8740         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8741   "TARGET_SHMEDIA_FPU"
8742   "fsqrt.s      %1, %0"
8743   [(set_attr "type" "fdiv_media")])
8745 (define_insn "sqrtsf2_i"
8746   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8747         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8748    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8749   "TARGET_SH3E"
8750   "fsqrt        %0"
8751   [(set_attr "type" "fdiv")
8752    (set_attr "fp_mode" "single")])
8754 (define_expand "abssf2"
8755   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8756         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8757   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8758   "
8760   if (TARGET_SH2E)
8761     {
8762       expand_sf_unop (&gen_abssf2_i, operands);
8763       DONE;
8764     }
8767 (define_insn "*abssf2_media"
8768   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8769         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8770   "TARGET_SHMEDIA_FPU"
8771   "fabs.s       %1, %0"
8772   [(set_attr "type" "fmove_media")])
8774 (define_insn "abssf2_i"
8775   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8776         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8777    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8778   "TARGET_SH2E"
8779   "fabs %0"
8780   [(set_attr "type" "fmove")
8781    (set_attr "fp_mode" "single")])
8783 (define_expand "adddf3"
8784   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8785         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8786                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8787   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8788   "
8790   if (TARGET_SH4)
8791     {
8792       expand_df_binop (&gen_adddf3_i, operands);
8793       DONE;
8794     }
8797 (define_insn "*adddf3_media"
8798   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8799         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8800                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8801   "TARGET_SHMEDIA_FPU"
8802   "fadd.d       %1, %2, %0"
8803   [(set_attr "type" "dfparith_media")])
8805 (define_insn "adddf3_i"
8806   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8807         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8808                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8809    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8810   "TARGET_SH4"
8811   "fadd %2,%0"
8812   [(set_attr "type" "dfp_arith")
8813    (set_attr "fp_mode" "double")])
8815 (define_expand "subdf3"
8816   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8817         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8818                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8819   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8820   "
8822   if (TARGET_SH4)
8823     {
8824       expand_df_binop (&gen_subdf3_i, operands);
8825       DONE;
8826     }
8829 (define_insn "*subdf3_media"
8830   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8831         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8832                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8833   "TARGET_SHMEDIA_FPU"
8834   "fsub.d       %1, %2, %0"
8835   [(set_attr "type" "dfparith_media")])
8837 (define_insn "subdf3_i"
8838   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8839         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8840                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8841    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8842   "TARGET_SH4"
8843   "fsub %2,%0"
8844   [(set_attr "type" "dfp_arith")
8845    (set_attr "fp_mode" "double")])
8847 (define_expand "muldf3"
8848   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8849         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8850                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8851   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8852   "
8854   if (TARGET_SH4)
8855     {
8856       expand_df_binop (&gen_muldf3_i, operands);
8857       DONE;
8858     }
8861 (define_insn "*muldf3_media"
8862   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8863         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8864                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8865   "TARGET_SHMEDIA_FPU"
8866   "fmul.d       %1, %2, %0"
8867   [(set_attr "type" "dfmul_media")])
8869 (define_insn "muldf3_i"
8870   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8871         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8872                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8873    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8874   "TARGET_SH4"
8875   "fmul %2,%0"
8876   [(set_attr "type" "dfp_arith")
8877    (set_attr "fp_mode" "double")])
8879 (define_expand "divdf3"
8880   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8881         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8882                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8883   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8884   "
8886   if (TARGET_SH4)
8887     {
8888       expand_df_binop (&gen_divdf3_i, operands);
8889       DONE;
8890     }
8893 (define_insn "*divdf3_media"
8894   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8895         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8896                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8897   "TARGET_SHMEDIA_FPU"
8898   "fdiv.d       %1, %2, %0"
8899   [(set_attr "type" "dfdiv_media")])
8901 (define_insn "divdf3_i"
8902   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8903         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8904                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8905    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8906   "TARGET_SH4"
8907   "fdiv %2,%0"
8908   [(set_attr "type" "dfdiv")
8909    (set_attr "fp_mode" "double")])
8911 (define_insn "floatdidf2"
8912   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8913         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8914   "TARGET_SHMEDIA_FPU"
8915   "float.qd     %1, %0"
8916   [(set_attr "type" "dfpconv_media")])
8918 (define_expand "floatsidf2"
8919   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8920         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8921   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8922   "
8924   if (TARGET_SH4)
8925     {
8926       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8927                                       get_fpscr_rtx ()));
8928       DONE;
8929     }
8932 (define_insn "*floatsidf2_media"
8933   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8934         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8935   "TARGET_SHMEDIA_FPU"
8936   "float.ld     %1, %0"
8937   [(set_attr "type" "dfpconv_media")])
8939 (define_insn "floatsidf2_i"
8940   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8941         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8942    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8943   "TARGET_SH4"
8944   "float        %1,%0"
8945   [(set_attr "type" "dfp_conv")
8946    (set_attr "fp_mode" "double")])
8948 (define_insn "fix_truncdfdi2"
8949   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8950         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8951   "TARGET_SHMEDIA_FPU"
8952   "ftrc.dq      %1, %0"
8953   [(set_attr "type" "dfpconv_media")])
8955 (define_expand "fix_truncdfsi2"
8956   [(set (match_operand:SI 0 "fpul_operand" "")
8957         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8958   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8959   "
8961   if (TARGET_SH4)
8962     {
8963       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8964                                           get_fpscr_rtx ()));
8965       DONE;
8966     }
8969 (define_insn "*fix_truncdfsi2_media"
8970   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8971         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8972   "TARGET_SHMEDIA_FPU"
8973   "ftrc.dl      %1, %0"
8974   [(set_attr "type" "dfpconv_media")])
8976 (define_insn "fix_truncdfsi2_i"
8977   [(set (match_operand:SI 0 "fpul_operand" "=y")
8978         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8979    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8980   "TARGET_SH4"
8981   "ftrc %1,%0"
8982   [(set_attr "type" "dfp_conv")
8983    (set_attr "dfp_comp" "no")
8984    (set_attr "fp_mode" "double")])
8986 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8987 ;; fix_truncdfsi2_i.
8988 ;; (define_insn "fix_truncdfsi2_i4"
8989 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8990 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8991 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8992 ;;    (clobber (reg:SI FPUL_REG))]
8993 ;;   "TARGET_SH4"
8994 ;;   "#"
8995 ;;   [(set_attr "length" "4")
8996 ;;    (set_attr "fp_mode" "double")])
8998 ;; (define_split
8999 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9000 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
9001 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
9002 ;;    (clobber (reg:SI FPUL_REG))]
9003 ;;   "TARGET_SH4"
9004 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
9005 ;;            (use (match_dup 2))])
9006 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
9008 (define_insn "cmpgtdf_t"
9009   [(set (reg:SI T_REG)
9010         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
9011                (match_operand:DF 1 "arith_reg_operand" "f")))
9012    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9013   "TARGET_SH4"
9014   "fcmp/gt      %1,%0"
9015   [(set_attr "type" "dfp_cmp")
9016    (set_attr "fp_mode" "double")])
9018 (define_insn "cmpeqdf_t"
9019   [(set (reg:SI T_REG)
9020         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9021                (match_operand:DF 1 "arith_reg_operand" "f")))
9022    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9023   "TARGET_SH4"
9024   "fcmp/eq      %1,%0"
9025   [(set_attr "type" "dfp_cmp")
9026    (set_attr "fp_mode" "double")])
9028 (define_insn "*ieee_ccmpeqdf_t"
9029   [(set (reg:SI T_REG)
9030         (ior:SI (reg:SI T_REG)
9031                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
9032                        (match_operand:DF 1 "arith_reg_operand" "f"))))
9033    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9034   "TARGET_IEEE && TARGET_SH4"
9035   "* return output_ieee_ccmpeq (insn, operands);"
9036   [(set_attr "length" "4")
9037    (set_attr "fp_mode" "double")])
9039 (define_insn "cmpeqdf_media"
9040   [(set (match_operand:DI 0 "register_operand" "=r")
9041         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9042                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9043   "TARGET_SHMEDIA_FPU"
9044   "fcmpeq.d     %1,%2,%0"
9045   [(set_attr "type" "fcmp_media")])
9047 (define_insn "cmpgtdf_media"
9048   [(set (match_operand:DI 0 "register_operand" "=r")
9049         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9050                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9051   "TARGET_SHMEDIA_FPU"
9052   "fcmpgt.d     %1,%2,%0"
9053   [(set_attr "type" "fcmp_media")])
9055 (define_insn "cmpgedf_media"
9056   [(set (match_operand:DI 0 "register_operand" "=r")
9057         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9058                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9059   "TARGET_SHMEDIA_FPU"
9060   "fcmpge.d     %1,%2,%0"
9061   [(set_attr "type" "fcmp_media")])
9063 (define_insn "cmpundf_media"
9064   [(set (match_operand:DI 0 "register_operand" "=r")
9065         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9066                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9067   "TARGET_SHMEDIA_FPU"
9068   "fcmpun.d     %1,%2,%0"
9069   [(set_attr "type" "fcmp_media")])
9071 (define_expand "cmpdf"
9072   [(set (reg:SI T_REG)
9073         (compare (match_operand:DF 0 "arith_operand" "")
9074                  (match_operand:DF 1 "arith_operand" "")))]
9075   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9076   "
9078   sh_compare_op0 = operands[0];
9079   sh_compare_op1 = operands[1];
9080   DONE;
9083 (define_expand "negdf2"
9084   [(set (match_operand:DF 0 "arith_reg_operand" "")
9085         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9086   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9087   "
9089   if (TARGET_SH4)
9090     {
9091       expand_df_unop (&gen_negdf2_i, operands);
9092       DONE;
9093     }
9096 (define_insn "*negdf2_media"
9097   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9098         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9099   "TARGET_SHMEDIA_FPU"
9100   "fneg.d       %1, %0"
9101   [(set_attr "type" "fmove_media")])
9103 (define_insn "negdf2_i"
9104   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9105         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9106    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9107   "TARGET_SH4"
9108   "fneg %0"
9109   [(set_attr "type" "fmove")
9110    (set_attr "fp_mode" "double")])
9112 (define_expand "sqrtdf2"
9113   [(set (match_operand:DF 0 "arith_reg_operand" "")
9114         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9115   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9116   "
9118   if (TARGET_SH4)
9119     {
9120       expand_df_unop (&gen_sqrtdf2_i, operands);
9121       DONE;
9122     }
9125 (define_insn "*sqrtdf2_media"
9126   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9127         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9128   "TARGET_SHMEDIA_FPU"
9129   "fsqrt.d      %1, %0"
9130   [(set_attr "type" "dfdiv_media")])
9132 (define_insn "sqrtdf2_i"
9133   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9134         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9135    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9136   "TARGET_SH4"
9137   "fsqrt        %0"
9138   [(set_attr "type" "dfdiv")
9139    (set_attr "fp_mode" "double")])
9141 (define_expand "absdf2"
9142   [(set (match_operand:DF 0 "arith_reg_operand" "")
9143         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9144   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9145   "
9147   if (TARGET_SH4)
9148     {
9149       expand_df_unop (&gen_absdf2_i, operands);
9150       DONE;
9151     }
9154 (define_insn "*absdf2_media"
9155   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9156         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9157   "TARGET_SHMEDIA_FPU"
9158   "fabs.d       %1, %0"
9159   [(set_attr "type" "fmove_media")])
9161 (define_insn "absdf2_i"
9162   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9163         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9164    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9165   "TARGET_SH4"
9166   "fabs %0"
9167   [(set_attr "type" "fmove")
9168    (set_attr "fp_mode" "double")])
9170 (define_expand "extendsfdf2"
9171   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9172         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9173   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9174   "
9176   if (TARGET_SH4)
9177     {
9178       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9179                                         get_fpscr_rtx ()));
9180       DONE;
9181     }
9184 (define_insn "*extendsfdf2_media"
9185   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9186         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9187   "TARGET_SHMEDIA_FPU"
9188   "fcnv.sd      %1, %0"
9189   [(set_attr "type" "dfpconv_media")])
9191 (define_insn "extendsfdf2_i4"
9192   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9193         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9194    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9195   "TARGET_SH4"
9196   "fcnvsd  %1,%0"
9197   [(set_attr "type" "fp")
9198    (set_attr "fp_mode" "double")])
9200 (define_expand "truncdfsf2"
9201   [(set (match_operand:SF 0 "fpul_operand" "")
9202         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9203   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9204   "
9206   if (TARGET_SH4)
9207     {
9208       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9209                                        get_fpscr_rtx ()));
9210       DONE;
9211     }
9214 (define_insn "*truncdfsf2_media"
9215   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9216         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9217   "TARGET_SHMEDIA_FPU"
9218   "fcnv.ds      %1, %0"
9219   [(set_attr "type" "dfpconv_media")])
9221 (define_insn "truncdfsf2_i4"
9222   [(set (match_operand:SF 0 "fpul_operand" "=y")
9223         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9224    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9225   "TARGET_SH4"
9226   "fcnvds  %1,%0"
9227   [(set_attr "type" "fp")
9228    (set_attr "fp_mode" "double")])
9230 ;; Bit field extract patterns.  These give better code for packed bitfields,
9231 ;; because they allow auto-increment addresses to be generated.
9233 (define_expand "insv"
9234   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9235                          (match_operand:SI 1 "immediate_operand" "")
9236                          (match_operand:SI 2 "immediate_operand" ""))
9237         (match_operand:SI 3 "general_operand" ""))]
9238   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9239   "
9241   rtx addr_target, orig_address, shift_reg, qi_val;
9242   HOST_WIDE_INT bitsize, size, v = 0;
9243   rtx x = operands[3];
9245   /* ??? expmed doesn't care for non-register predicates.  */
9246   if (! memory_operand (operands[0], VOIDmode)
9247       || ! immediate_operand (operands[1], VOIDmode)
9248       || ! immediate_operand (operands[2], VOIDmode)
9249       || ! general_operand (x, VOIDmode))
9250     FAIL;
9251   /* If this isn't a 16 / 24 / 32 bit field, or if
9252      it doesn't start on a byte boundary, then fail.  */
9253   bitsize = INTVAL (operands[1]);
9254   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9255       || (INTVAL (operands[2]) % 8) != 0)
9256     FAIL;
9258   size = bitsize / 8;
9259   orig_address = XEXP (operands[0], 0);
9260   shift_reg = gen_reg_rtx (SImode);
9261   if (GET_CODE (x) == CONST_INT)
9262     {
9263       v = INTVAL (x);
9264       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9265     }
9266   else
9267     {
9268       emit_insn (gen_movsi (shift_reg, operands[3]));
9269       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9270     }
9271   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9273   operands[0] = replace_equiv_address (operands[0], addr_target);
9274   emit_insn (gen_movqi (operands[0], qi_val));
9276   while (size -= 1)
9277     {
9278       if (GET_CODE (x) == CONST_INT)
9279         qi_val
9280           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9281       else
9282         {
9283           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9284           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9285         }
9286       emit_insn (gen_addsi3 (addr_target, addr_target, constm1_rtx));
9287       emit_insn (gen_movqi (operands[0], qi_val));
9288     }
9290   DONE;
9293 ;; -------------------------------------------------------------------------
9294 ;; Peepholes
9295 ;; -------------------------------------------------------------------------
9297 ;; This matches cases where a stack pointer increment at the start of the
9298 ;; epilogue combines with a stack slot read loading the return value.
9300 (define_peephole
9301   [(set (match_operand:SI 0 "arith_reg_operand" "")
9302         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9303    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9304   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9305   "mov.l        @%1+,%0")
9307 ;; See the comment on the dt combiner pattern above.
9309 (define_peephole
9310   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9311         (plus:SI (match_dup 0)
9312                  (const_int -1)))
9313    (set (reg:SI T_REG)
9314         (eq:SI (match_dup 0)
9315                (const_int 0)))]
9316   "TARGET_SH2"
9317   "dt   %0")
9319 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9320 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9321 ;; reload when the constant is too large for a reg+offset address.
9323 ;; ??? We would get much better code if this was done in reload.  This would
9324 ;; require modifying find_reloads_address to recognize that if the constant
9325 ;; is out-of-range for an immediate add, then we get better code by reloading
9326 ;; the constant into a register than by reloading the sum into a register,
9327 ;; since the former is one instruction shorter if the address does not need
9328 ;; to be offsettable.  Unfortunately this does not work, because there is
9329 ;; only one register, r0, that can be used as an index register.  This register
9330 ;; is also the function return value register.  So, if we try to force reload
9331 ;; to use double-reg addresses, then we end up with some instructions that
9332 ;; need to use r0 twice.  The only way to fix this is to change the calling
9333 ;; convention so that r0 is not used to return values.
9335 (define_peephole
9336   [(set (match_operand:SI 0 "register_operand" "=r")
9337         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9338    (set (mem:SI (match_dup 0))
9339         (match_operand:SI 2 "general_movsrc_operand" ""))]
9340   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9341   "mov.l        %2,@(%0,%1)")
9343 (define_peephole
9344   [(set (match_operand:SI 0 "register_operand" "=r")
9345         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9346    (set (match_operand:SI 2 "general_movdst_operand" "")
9347         (mem:SI (match_dup 0)))]
9348   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9349   "mov.l        @(%0,%1),%2")
9351 (define_peephole
9352   [(set (match_operand:SI 0 "register_operand" "=r")
9353         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9354    (set (mem:HI (match_dup 0))
9355         (match_operand:HI 2 "general_movsrc_operand" ""))]
9356   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9357   "mov.w        %2,@(%0,%1)")
9359 (define_peephole
9360   [(set (match_operand:SI 0 "register_operand" "=r")
9361         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9362    (set (match_operand:HI 2 "general_movdst_operand" "")
9363         (mem:HI (match_dup 0)))]
9364   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9365   "mov.w        @(%0,%1),%2")
9367 (define_peephole
9368   [(set (match_operand:SI 0 "register_operand" "=r")
9369         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9370    (set (mem:QI (match_dup 0))
9371         (match_operand:QI 2 "general_movsrc_operand" ""))]
9372   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9373   "mov.b        %2,@(%0,%1)")
9375 (define_peephole
9376   [(set (match_operand:SI 0 "register_operand" "=r")
9377         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9378    (set (match_operand:QI 2 "general_movdst_operand" "")
9379         (mem:QI (match_dup 0)))]
9380   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9381   "mov.b        @(%0,%1),%2")
9383 (define_peephole
9384   [(set (match_operand:SI 0 "register_operand" "=r")
9385         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9386    (set (mem:SF (match_dup 0))
9387         (match_operand:SF 2 "general_movsrc_operand" ""))]
9388   "TARGET_SH1 && REGNO (operands[0]) == 0
9389    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9390        || (GET_CODE (operands[2]) == SUBREG
9391            && REGNO (SUBREG_REG (operands[2])) < 16))
9392    && reg_unused_after (operands[0], insn)"
9393   "mov.l        %2,@(%0,%1)")
9395 (define_peephole
9396   [(set (match_operand:SI 0 "register_operand" "=r")
9397         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9398    (set (match_operand:SF 2 "general_movdst_operand" "")
9400         (mem:SF (match_dup 0)))]
9401   "TARGET_SH1 && REGNO (operands[0]) == 0
9402    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9403        || (GET_CODE (operands[2]) == SUBREG
9404            && REGNO (SUBREG_REG (operands[2])) < 16))
9405    && reg_unused_after (operands[0], insn)"
9406   "mov.l        @(%0,%1),%2")
9408 (define_peephole
9409   [(set (match_operand:SI 0 "register_operand" "=r")
9410         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9411    (set (mem:SF (match_dup 0))
9412         (match_operand:SF 2 "general_movsrc_operand" ""))]
9413   "TARGET_SH2E && REGNO (operands[0]) == 0
9414    && ((GET_CODE (operands[2]) == REG
9415         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9416        || (GET_CODE (operands[2]) == SUBREG
9417            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9418    && reg_unused_after (operands[0], insn)"
9419   "fmov{.s|}    %2,@(%0,%1)")
9421 (define_peephole
9422   [(set (match_operand:SI 0 "register_operand" "=r")
9423         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9424    (set (match_operand:SF 2 "general_movdst_operand" "")
9426         (mem:SF (match_dup 0)))]
9427   "TARGET_SH2E && REGNO (operands[0]) == 0
9428    && ((GET_CODE (operands[2]) == REG
9429         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9430        || (GET_CODE (operands[2]) == SUBREG
9431            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9432    && reg_unused_after (operands[0], insn)"
9433   "fmov{.s|}    @(%0,%1),%2")
9435 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9436 (define_insn "sp_switch_1"
9437   [(const_int 1)]
9438   "TARGET_SH1"
9439   "*
9441   rtx xoperands[1];
9443   xoperands[0] = sp_switch;
9444   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9445   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9446   return \"mov r0,r15\";
9448   [(set_attr "length" "10")])
9450 ;; Switch back to the original stack for interrupt functions with the
9451 ;; sp_switch attribute.  */
9452 (define_insn "sp_switch_2"
9453   [(const_int 2)]
9454   "TARGET_SH1"
9455   "mov.l @r15+,r15\;mov.l @r15+,r0"
9456   [(set_attr "length" "4")])
9458 ;; Integer vector moves
9460 (define_expand "movv8qi"
9461   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9462         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9463   "TARGET_SHMEDIA"
9464   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9466 (define_insn "movv8qi_i"
9467   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9468         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9469   "TARGET_SHMEDIA
9470    && (register_operand (operands[0], V8QImode)
9471        || sh_register_operand (operands[1], V8QImode))"
9472   "@
9473         add     %1, r63, %0
9474         movi    %1, %0
9475         #
9476         ld%M1.q %m1, %0
9477         st%M0.q %m0, %N1"
9478   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9479    (set_attr "length" "4,4,16,4,4")])
9481 (define_split
9482   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9483         (subreg:V8QI (const_int 0) 0))]
9484   "TARGET_SHMEDIA"
9485   [(set (match_dup 0)
9486         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9487                             (const_int 0) (const_int 0) (const_int 0)
9488                             (const_int 0) (const_int 0)]))])
9490 (define_split
9491   [(set (match_operand 0 "arith_reg_dest" "")
9492         (match_operand 1 "sh_rep_vec" ""))]
9493   "TARGET_SHMEDIA && reload_completed
9494    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9495    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9496    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9497    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9498        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9499    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9500        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9501   [(set (match_dup 0) (match_dup 1))
9502    (match_dup 2)]
9503   "
9505   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9506   rtx elt1 = XVECEXP (operands[1], 0, 1);
9508   if (unit_size > 2)
9509     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9510   else
9511     {
9512       if (unit_size < 2)
9513         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9514       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9515     }
9516   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9517   operands[1] = XVECEXP (operands[1], 0, 0);
9518   if (unit_size < 2)
9519     {
9520       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9521         operands[1]
9522           = GEN_INT (TARGET_LITTLE_ENDIAN
9523                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9524                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9525       else
9526         {
9527           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9528           operands[1]
9529             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9530         }
9531     }
9534 (define_split
9535   [(set (match_operand 0 "arith_reg_dest" "")
9536         (match_operand 1 "sh_const_vec" ""))]
9537   "TARGET_SHMEDIA && reload_completed
9538    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9539    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9540    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9541   [(set (match_dup 0) (match_dup 1))]
9542   "
9544   rtx v = operands[1];
9545   enum machine_mode new_mode
9546     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9548   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9549   operands[1]
9550     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9553 (define_expand "movv2hi"
9554   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9555         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9556   "TARGET_SHMEDIA"
9557   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9559 (define_insn "movv2hi_i"
9560   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9561         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9562   "TARGET_SHMEDIA
9563    && (register_operand (operands[0], V2HImode)
9564        || sh_register_operand (operands[1], V2HImode))"
9565   "@
9566         addz.l  %1, r63, %0
9567         movi    %1, %0
9568         #
9569         ld%M1.l %m1, %0
9570         st%M0.l %m0, %N1"
9571   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9572    (set_attr "length" "4,4,16,4,4")])
9574 (define_expand "movv4hi"
9575   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9576         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9577   "TARGET_SHMEDIA"
9578   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9580 (define_insn "movv4hi_i"
9581   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9582         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9583   "TARGET_SHMEDIA
9584    && (register_operand (operands[0], V4HImode)
9585        || sh_register_operand (operands[1], V4HImode))"
9586   "@
9587         add     %1, r63, %0
9588         movi    %1, %0
9589         #
9590         ld%M1.q %m1, %0
9591         st%M0.q %m0, %N1"
9592   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9593    (set_attr "length" "4,4,16,4,4")])
9595 (define_expand "movv2si"
9596   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9597         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9598   "TARGET_SHMEDIA"
9599   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9601 (define_insn "movv2si_i"
9602   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9603         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9604   "TARGET_SHMEDIA
9605    && (register_operand (operands[0], V2SImode)
9606        || sh_register_operand (operands[1], V2SImode))"
9607   "@
9608         add     %1, r63, %0
9609         #
9610         #
9611         ld%M1.q %m1, %0
9612         st%M0.q %m0, %N1"
9613   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9614    (set_attr "length" "4,4,16,4,4")])
9616 ;; Multimedia Intrinsics
9618 (define_insn "absv2si2"
9619   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9620         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9621   "TARGET_SHMEDIA"
9622   "mabs.l       %1, %0"
9623   [(set_attr "type" "mcmp_media")])
9625 (define_insn "absv4hi2"
9626   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9627         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9628   "TARGET_SHMEDIA"
9629   "mabs.w       %1, %0"
9630   [(set_attr "type" "mcmp_media")])
9632 (define_insn "addv2si3"
9633   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9634         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9635                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9636   "TARGET_SHMEDIA"
9637   "madd.l       %1, %2, %0"
9638   [(set_attr "type" "arith_media")])
9640 (define_insn "addv4hi3"
9641   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9642         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9643                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9644   "TARGET_SHMEDIA"
9645   "madd.w       %1, %2, %0"
9646   [(set_attr "type" "arith_media")])
9648 (define_insn "ssaddv2si3"
9649   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9650         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9651                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9652   "TARGET_SHMEDIA"
9653   "madds.l      %1, %2, %0"
9654   [(set_attr "type" "mcmp_media")])
9656 (define_insn "usaddv8qi3"
9657   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9658         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9659                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9660   "TARGET_SHMEDIA"
9661   "madds.ub     %1, %2, %0"
9662   [(set_attr "type" "mcmp_media")])
9664 (define_insn "ssaddv4hi3"
9665   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9666         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9667                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9668   "TARGET_SHMEDIA"
9669   "madds.w      %1, %2, %0"
9670   [(set_attr "type" "mcmp_media")])
9672 (define_insn "negcmpeqv8qi"
9673   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9674         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9675                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9676   "TARGET_SHMEDIA"
9677   "mcmpeq.b     %N1, %N2, %0"
9678   [(set_attr "type" "mcmp_media")])
9680 (define_insn "negcmpeqv2si"
9681   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9682         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9683                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9684   "TARGET_SHMEDIA"
9685   "mcmpeq.l     %N1, %N2, %0"
9686   [(set_attr "type" "mcmp_media")])
9688 (define_insn "negcmpeqv4hi"
9689   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9690         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9691                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9692   "TARGET_SHMEDIA"
9693   "mcmpeq.w     %N1, %N2, %0"
9694   [(set_attr "type" "mcmp_media")])
9696 (define_insn "negcmpgtuv8qi"
9697   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9698         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9699                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9700   "TARGET_SHMEDIA"
9701   "mcmpgt.ub    %N1, %N2, %0"
9702   [(set_attr "type" "mcmp_media")])
9704 (define_insn "negcmpgtv2si"
9705   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9706         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9707                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9708   "TARGET_SHMEDIA"
9709   "mcmpgt.l     %N1, %N2, %0"
9710   [(set_attr "type" "mcmp_media")])
9712 (define_insn "negcmpgtv4hi"
9713   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9714         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9715                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9716   "TARGET_SHMEDIA"
9717   "mcmpgt.w     %N1, %N2, %0"
9718   [(set_attr "type" "mcmp_media")])
9720 (define_insn "mcmv"
9721   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9722         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9723                         (match_operand:DI 2 "arith_reg_operand" "r"))
9724                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9725                         (not:DI (match_dup 2)))))]
9726   "TARGET_SHMEDIA"
9727   "mcmv %N1, %2, %0"
9728   [(set_attr "type" "arith_media")])
9730 (define_insn "mcnvs_lw"
9731   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9732         (vec_concat:V4HI
9733          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9734          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9735   "TARGET_SHMEDIA"
9736   "mcnvs.lw     %N1, %N2, %0"
9737   [(set_attr "type" "mcmp_media")])
9739 (define_insn "mcnvs_wb"
9740   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9741         (vec_concat:V8QI
9742          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9743          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9744   "TARGET_SHMEDIA"
9745   "mcnvs.wb     %N1, %N2, %0"
9746   [(set_attr "type" "mcmp_media")])
9748 (define_insn "mcnvs_wub"
9749   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9750         (vec_concat:V8QI
9751          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9752          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9753   "TARGET_SHMEDIA"
9754   "mcnvs.wub    %N1, %N2, %0"
9755   [(set_attr "type" "mcmp_media")])
9757 (define_insn "mextr_rl"
9758   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9759         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9760                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9761                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9762                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9763   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9764   "*
9766   static char templ[16];
9768   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9769            (int) INTVAL (operands[3]) >> 3);
9770   return templ;
9772   [(set_attr "type" "arith_media")])
9774 (define_insn "*mextr_lr"
9775   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9776         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9777                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9778                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9779                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9780   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9781   "*
9783   static char templ[16];
9785   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9786            (int) INTVAL (operands[4]) >> 3);
9787   return templ;
9789   [(set_attr "type" "arith_media")])
9791 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9792 ; vector then varies depending on endianness.
9793 (define_expand "mextr1"
9794   [(match_operand:DI 0 "arith_reg_dest" "")
9795    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9796    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9797   "TARGET_SHMEDIA"
9798   "
9800   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9801                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9802   DONE;
9805 (define_expand "mextr2"
9806   [(match_operand:DI 0 "arith_reg_dest" "")
9807    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9808    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9809   "TARGET_SHMEDIA"
9810   "
9812   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9813                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9814   DONE;
9817 (define_expand "mextr3"
9818   [(match_operand:DI 0 "arith_reg_dest" "")
9819    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9820    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9821   "TARGET_SHMEDIA"
9822   "
9824   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9825                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9826   DONE;
9829 (define_expand "mextr4"
9830   [(match_operand:DI 0 "arith_reg_dest" "")
9831    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9832    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9833   "TARGET_SHMEDIA"
9834   "
9836   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9837                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9838   DONE;
9841 (define_expand "mextr5"
9842   [(match_operand:DI 0 "arith_reg_dest" "")
9843    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9844    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9845   "TARGET_SHMEDIA"
9846   "
9848   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9849                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9850   DONE;
9853 (define_expand "mextr6"
9854   [(match_operand:DI 0 "arith_reg_dest" "")
9855    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9856    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9857   "TARGET_SHMEDIA"
9858   "
9860   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9861                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9862   DONE;
9865 (define_expand "mextr7"
9866   [(match_operand:DI 0 "arith_reg_dest" "")
9867    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9868    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9869   "TARGET_SHMEDIA"
9870   "
9872   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9873                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9874   DONE;
9877 (define_expand "mmacfx_wl"
9878   [(match_operand:V2SI 0 "arith_reg_dest" "")
9879    (match_operand:V2HI 1 "extend_reg_operand" "")
9880    (match_operand:V2HI 2 "extend_reg_operand" "")
9881    (match_operand:V2SI 3 "arith_reg_operand" "")]
9882   "TARGET_SHMEDIA"
9883   "
9885   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9886                               operands[1], operands[2]));
9887   DONE;
9890 (define_insn "mmacfx_wl_i"
9891   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9892         (ss_plus:V2SI
9893          (match_operand:V2SI 1 "arith_reg_operand" "0")
9894          (ss_truncate:V2SI
9895           (ashift:V2DI
9896            (sign_extend:V2DI
9897             (mult:V2SI
9898              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9899              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9900            (const_int 1)))))]
9901   "TARGET_SHMEDIA"
9902   "mmacfx.wl    %2, %3, %0"
9903   [(set_attr "type" "mac_media")])
9905 (define_expand "mmacnfx_wl"
9906   [(match_operand:V2SI 0 "arith_reg_dest" "")
9907    (match_operand:V2HI 1 "extend_reg_operand" "")
9908    (match_operand:V2HI 2 "extend_reg_operand" "")
9909    (match_operand:V2SI 3 "arith_reg_operand" "")]
9910   "TARGET_SHMEDIA"
9911   "
9913   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9914                                operands[1], operands[2]));
9915   DONE;
9918 (define_insn "mmacnfx_wl_i"
9919   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9920         (ss_minus:V2SI
9921          (match_operand:V2SI 1 "arith_reg_operand" "0")
9922          (ss_truncate:V2SI
9923           (ashift:V2DI
9924            (sign_extend:V2DI
9925             (mult:V2SI
9926              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9927              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9928            (const_int 1)))))]
9929   "TARGET_SHMEDIA"
9930   "mmacnfx.wl   %2, %3, %0"
9931   [(set_attr "type" "mac_media")])
9933 (define_insn "mulv2si3"
9934   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9935         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9936                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9937   "TARGET_SHMEDIA"
9938   "mmul.l       %1, %2, %0"
9939   [(set_attr "type" "d2mpy_media")])
9941 (define_insn "mulv4hi3"
9942   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9943         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9944                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9945   "TARGET_SHMEDIA"
9946   "mmul.w       %1, %2, %0"
9947   [(set_attr "type" "dmpy_media")])
9949 (define_insn "mmulfx_l"
9950   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9951         (ss_truncate:V2SI
9952          (ashiftrt:V2DI
9953           (mult:V2DI
9954            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9955            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9956           (const_int 31))))]
9957   "TARGET_SHMEDIA"
9958   "mmulfx.l     %1, %2, %0"
9959   [(set_attr "type" "d2mpy_media")])
9961 (define_insn "mmulfx_w"
9962   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9963         (ss_truncate:V4HI
9964          (ashiftrt:V4SI
9965           (mult:V4SI
9966            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9967            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9968           (const_int 15))))]
9969   "TARGET_SHMEDIA"
9970   "mmulfx.w     %1, %2, %0"
9971   [(set_attr "type" "dmpy_media")])
9973 (define_insn "mmulfxrp_w"
9974   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9975         (ss_truncate:V4HI
9976          (ashiftrt:V4SI
9977           (plus:V4SI
9978            (mult:V4SI
9979             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9980             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9981            (const_int 16384))
9982           (const_int 15))))]
9983   "TARGET_SHMEDIA"
9984   "mmulfxrp.w   %1, %2, %0"
9985   [(set_attr "type" "dmpy_media")])
9987 (define_expand "mmulhi_wl"
9988   [(match_operand:V2SI 0 "arith_reg_dest" "")
9989    (match_operand:V4HI 1 "arith_reg_operand" "")
9990    (match_operand:V4HI 2 "arith_reg_operand" "")]
9991   "TARGET_SHMEDIA"
9992   "
9994   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9995              (operands[0], operands[1], operands[2]));
9996   DONE;
9999 (define_expand "mmullo_wl"
10000   [(match_operand:V2SI 0 "arith_reg_dest" "")
10001    (match_operand:V4HI 1 "arith_reg_operand" "")
10002    (match_operand:V4HI 2 "arith_reg_operand" "")]
10003   "TARGET_SHMEDIA"
10004   "
10006   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
10007              (operands[0], operands[1], operands[2]));
10008   DONE;
10011 (define_insn "mmul23_wl"
10012   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10013         (vec_select:V2SI
10014          (mult:V4SI
10015           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10016           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10017          (parallel [(const_int 2) (const_int 3)])))]
10018   "TARGET_SHMEDIA"
10019   "* return (TARGET_LITTLE_ENDIAN
10020              ? \"mmulhi.wl      %1, %2, %0\"
10021              : \"mmullo.wl      %1, %2, %0\");"
10022   [(set_attr "type" "dmpy_media")])
10024 (define_insn "mmul01_wl"
10025   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10026         (vec_select:V2SI
10027          (mult:V4SI
10028           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10029           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
10030          (parallel [(const_int 0) (const_int 1)])))]
10031   "TARGET_SHMEDIA"
10032   "* return (TARGET_LITTLE_ENDIAN
10033              ? \"mmullo.wl      %1, %2, %0\"
10034              : \"mmulhi.wl      %1, %2, %0\");"
10035   [(set_attr "type" "dmpy_media")])
10037 (define_expand "mmulsum_wq"
10038   [(match_operand:DI 0 "arith_reg_dest" "")
10039    (match_operand:V4HI 1 "arith_reg_operand" "")
10040    (match_operand:V4HI 2 "arith_reg_operand" "")
10041    (match_operand:DI 3 "arith_reg_operand" "")]
10042   "TARGET_SHMEDIA"
10043   "
10045   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10046                                operands[1], operands[2]));
10047   DONE;
10050 (define_insn "mmulsum_wq_i"
10051   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10052         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10053          (plus:DI
10054           (plus:DI
10055            (vec_select:DI
10056             (mult:V4DI
10057              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10058              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10059             (parallel [(const_int 0)]))
10060            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10061                                      (sign_extend:V4DI (match_dup 3)))
10062                           (parallel [(const_int 1)])))
10063           (plus:DI
10064            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10065                                      (sign_extend:V4DI (match_dup 3)))
10066                           (parallel [(const_int 2)]))
10067            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10068                                      (sign_extend:V4DI (match_dup 3)))
10069                           (parallel [(const_int 3)]))))))]
10070   "TARGET_SHMEDIA"
10071   "mmulsum.wq   %2, %3, %0"
10072   [(set_attr "type" "mac_media")])
10074 (define_expand "mperm_w"
10075   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10076    (match_operand:V4HI 1 "arith_reg_operand" "r")
10077    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10078   "TARGET_SHMEDIA"
10079   "
10081   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10082              (operands[0], operands[1], operands[2]));
10083   DONE;
10086 ; This use of vec_select isn't exactly correct according to rtl.texi
10087 ; (because not constant), but it seems a straightforward extension.
10088 (define_insn "mperm_w_little"
10089   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10090         (vec_select:V4HI
10091          (match_operand:V4HI 1 "arith_reg_operand" "r")
10092          (parallel
10093           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10094                             (const_int 2) (const_int 0))
10095            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10096            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10097            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10098   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10099   "mperm.w      %1, %N2, %0"
10100   [(set_attr "type" "arith_media")])
10102 (define_insn "mperm_w_big"
10103   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10104         (vec_select:V4HI
10105          (match_operand:V4HI 1 "arith_reg_operand" "r")
10106          (parallel
10107           [(zero_extract:QI (not:QI (match_operand:QI 2
10108                                      "extend_reg_or_0_operand" "rZ"))
10109                             (const_int 2) (const_int 0))
10110            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10111            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10112            (zero_extract:QI (not:QI (match_dup 2))
10113                             (const_int 2) (const_int 6))])))]
10114   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10115   "mperm.w      %1, %N2, %0"
10116   [(set_attr "type" "arith_media")])
10118 (define_insn "mperm_w0"
10119   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10120         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10121                                           "trunc_hi_operand" "r"))))]
10122   "TARGET_SHMEDIA"
10123   "mperm.w      %1, r63, %0"
10124   [(set_attr "type" "arith_media")])
10126 (define_expand "msad_ubq"
10127   [(match_operand:DI 0 "arith_reg_dest" "")
10128    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10129    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10130    (match_operand:DI 3 "arith_reg_operand" "")]
10131   "TARGET_SHMEDIA"
10132   "
10134   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10135                              operands[1], operands[2]));
10136   DONE;
10139 (define_insn "msad_ubq_i"
10140   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10141         (plus:DI
10142          (plus:DI
10143           (plus:DI
10144            (plus:DI
10145             (match_operand:DI 1 "arith_reg_operand" "0")
10146             (abs:DI (vec_select:DI
10147                      (minus:V8DI
10148                       (zero_extend:V8DI
10149                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10150                       (zero_extend:V8DI
10151                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10152                      (parallel [(const_int 0)]))))
10153            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10154                                               (zero_extend:V8DI (match_dup 3)))
10155                                   (parallel [(const_int 1)]))))
10156           (plus:DI
10157            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10158                                               (zero_extend:V8DI (match_dup 3)))
10159                                   (parallel [(const_int 2)])))
10160            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10161                                               (zero_extend:V8DI (match_dup 3)))
10162                                   (parallel [(const_int 3)])))))
10163          (plus:DI
10164           (plus:DI
10165            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10166                                               (zero_extend:V8DI (match_dup 3)))
10167                                   (parallel [(const_int 4)])))
10168            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10169                                               (zero_extend:V8DI (match_dup 3)))
10170                                   (parallel [(const_int 5)]))))
10171           (plus:DI
10172            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10173                                               (zero_extend:V8DI (match_dup 3)))
10174                                   (parallel [(const_int 6)])))
10175            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10176                                               (zero_extend:V8DI (match_dup 3)))
10177                                   (parallel [(const_int 7)])))))))]
10178   "TARGET_SHMEDIA"
10179   "msad.ubq     %N2, %N3, %0"
10180   [(set_attr "type" "mac_media")])
10182 (define_insn "mshalds_l"
10183   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10184         (ss_truncate:V2SI
10185          (ashift:V2DI
10186           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10187           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10188                   (const_int 31)))))]
10189   "TARGET_SHMEDIA"
10190   "mshalds.l    %1, %2, %0"
10191   [(set_attr "type" "mcmp_media")])
10193 (define_insn "mshalds_w"
10194   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10195         (ss_truncate:V4HI
10196          (ashift:V4SI
10197           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10198           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10199                   (const_int 15)))))]
10200   "TARGET_SHMEDIA"
10201   "mshalds.w    %1, %2, %0"
10202   [(set_attr "type" "mcmp_media")])
10204 (define_insn "ashrv2si3"
10205   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10206         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10207                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10208   "TARGET_SHMEDIA"
10209   "mshard.l     %1, %2, %0"
10210   [(set_attr "type" "arith_media")])
10212 (define_insn "ashrv4hi3"
10213   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10214         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10215                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10216   "TARGET_SHMEDIA"
10217   "mshard.w     %1, %2, %0"
10218   [(set_attr "type" "arith_media")])
10220 (define_insn "mshards_q"
10221   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10222         (ss_truncate:HI
10223          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10224                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10225   "TARGET_SHMEDIA"
10226   "mshards.q    %1, %N2, %0"
10227   [(set_attr "type" "mcmp_media")])
10229 (define_expand "mshfhi_b"
10230   [(match_operand:V8QI 0 "arith_reg_dest" "")
10231    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10232    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10233   "TARGET_SHMEDIA"
10234   "
10236   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10237              (operands[0], operands[1], operands[2]));
10238   DONE;
10241 (define_expand "mshflo_b"
10242   [(match_operand:V8QI 0 "arith_reg_dest" "")
10243    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10244    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10245   "TARGET_SHMEDIA"
10246   "
10248   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10249              (operands[0], operands[1], operands[2]));
10250   DONE;
10253 (define_insn "mshf4_b"
10254   [(set
10255     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10256     (vec_select:V8QI
10257      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10258                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10259      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10260                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10261   "TARGET_SHMEDIA"
10262   "* return (TARGET_LITTLE_ENDIAN
10263              ? \"mshfhi.b       %N1, %N2, %0\"
10264              : \"mshflo.b       %N1, %N2, %0\");"
10265   [(set_attr "type" "arith_media")])
10267 (define_insn "mshf0_b"
10268   [(set
10269     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10270     (vec_select:V8QI
10271      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10272                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10273      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10274                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10275   "TARGET_SHMEDIA"
10276   "* return (TARGET_LITTLE_ENDIAN
10277              ? \"mshflo.b       %N1, %N2, %0\"
10278              : \"mshfhi.b       %N1, %N2, %0\");"
10279   [(set_attr "type" "arith_media")])
10281 (define_expand "mshfhi_l"
10282   [(match_operand:V2SI 0 "arith_reg_dest" "")
10283    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10284    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10285   "TARGET_SHMEDIA"
10286   "
10288   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10289              (operands[0], operands[1], operands[2]));
10290   DONE;
10293 (define_expand "mshflo_l"
10294   [(match_operand:V2SI 0 "arith_reg_dest" "")
10295    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10296    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10297   "TARGET_SHMEDIA"
10298   "
10300   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10301              (operands[0], operands[1], operands[2]));
10302   DONE;
10305 (define_insn "mshf4_l"
10306   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10307         (vec_select:V2SI
10308          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10309                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10310          (parallel [(const_int 1) (const_int 3)])))]
10311   "TARGET_SHMEDIA"
10312   "* return (TARGET_LITTLE_ENDIAN
10313              ? \"mshfhi.l       %N1, %N2, %0\"
10314              : \"mshflo.l       %N1, %N2, %0\");"
10315   [(set_attr "type" "arith_media")])
10317 (define_insn "mshf0_l"
10318   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10319         (vec_select:V2SI
10320          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10321                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10322          (parallel [(const_int 0) (const_int 2)])))]
10323   "TARGET_SHMEDIA"
10324   "* return (TARGET_LITTLE_ENDIAN
10325              ? \"mshflo.l       %N1, %N2, %0\"
10326              : \"mshfhi.l       %N1, %N2, %0\");"
10327   [(set_attr "type" "arith_media")])
10329 (define_expand "mshfhi_w"
10330   [(match_operand:V4HI 0 "arith_reg_dest" "")
10331    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10332    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10333   "TARGET_SHMEDIA"
10334   "
10336   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10337              (operands[0], operands[1], operands[2]));
10338   DONE;
10341 (define_expand "mshflo_w"
10342   [(match_operand:V4HI 0 "arith_reg_dest" "")
10343    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10344    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10345   "TARGET_SHMEDIA"
10346   "
10348   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10349              (operands[0], operands[1], operands[2]));
10350   DONE;
10353 (define_insn "mshf4_w"
10354   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10355         (vec_select:V4HI
10356          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10357                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10358          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10359   "TARGET_SHMEDIA"
10360   "* return (TARGET_LITTLE_ENDIAN
10361              ? \"mshfhi.w       %N1, %N2, %0\"
10362              : \"mshflo.w       %N1, %N2, %0\");"
10363   [(set_attr "type" "arith_media")])
10365 (define_insn "mshf0_w"
10366   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10367         (vec_select:V4HI
10368          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10369                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10370          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10371   "TARGET_SHMEDIA"
10372   "* return (TARGET_LITTLE_ENDIAN
10373              ? \"mshflo.w       %N1, %N2, %0\"
10374              : \"mshfhi.w       %N1, %N2, %0\");"
10375   [(set_attr "type" "arith_media")])
10377 (define_insn "mshflo_w_x"
10378   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10379         (vec_select:V4HI
10380          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10381                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10382          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10383   "TARGET_SHMEDIA"
10384   "mshflo.w     %N1, %N2, %0"
10385   [(set_attr "type" "arith_media")])
10387 /* These are useful to expand ANDs and as combiner patterns.  */
10388 (define_insn_and_split "mshfhi_l_di"
10389   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10390         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10391                              (const_int 32))
10392                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10393                         (const_int -4294967296))))]
10394   "TARGET_SHMEDIA"
10395   "@
10396         mshfhi.l        %N1, %N2, %0
10397         #"
10398   "TARGET_SHMEDIA && reload_completed
10399    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10400   [(set (match_dup 3) (match_dup 4))
10401    (set (match_dup 5) (match_dup 6))]
10402   "
10404   operands[3] = gen_lowpart (SImode, operands[0]);
10405   operands[4] = gen_highpart (SImode, operands[1]);
10406   operands[5] = gen_highpart (SImode, operands[0]);
10407   operands[6] = gen_highpart (SImode, operands[2]);
10409   [(set_attr "type" "arith_media")])
10411 (define_insn "*mshfhi_l_di_rev"
10412   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10413         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10414                         (const_int -4294967296))
10415                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10416                              (const_int 32))))]
10417   "TARGET_SHMEDIA"
10418   "mshfhi.l     %N2, %N1, %0"
10419   [(set_attr "type" "arith_media")])
10421 (define_split
10422   [(set (match_operand:DI 0 "arith_reg_dest" "")
10423         (ior:DI (zero_extend:DI (match_operand:SI 1
10424                                               "extend_reg_or_0_operand" ""))
10425                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10426                         (const_int -4294967296))))
10427    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10428   "TARGET_SHMEDIA"
10429   [(const_int 0)]
10430   "
10432   emit_insn (gen_ashldi3_media (operands[3],
10433                                 simplify_gen_subreg (DImode, operands[1],
10434                                                      SImode, 0),
10435                                 GEN_INT (32)));
10436   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10437   DONE;
10440 (define_insn "mshflo_l_di"
10441   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10442         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10443                         (const_int 4294967295))
10444                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10445                            (const_int 32))))]
10447   "TARGET_SHMEDIA"
10448   "mshflo.l     %N1, %N2, %0"
10449   [(set_attr "type" "arith_media")])
10451 (define_insn "*mshflo_l_di_rev"
10452   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10453         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10454                            (const_int 32))
10455                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10456                         (const_int 4294967295))))]
10458   "TARGET_SHMEDIA"
10459   "mshflo.l     %N2, %N1, %0"
10460   [(set_attr "type" "arith_media")])
10462 ;; Combiner pattern for trampoline initialization.
10463 (define_insn_and_split "*double_shori"
10464   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10465         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10466                            (const_int 32))
10467                 (match_operand:DI 2 "const_int_operand" "n")))]
10468   "TARGET_SHMEDIA
10469    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10470   "#"
10471   "rtx_equal_p (operands[0], operands[1])"
10472   [(const_int 0)]
10473   "
10475   HOST_WIDE_INT v = INTVAL (operands[2]);
10477   emit_insn (gen_shori_media (operands[0], operands[0],
10478              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10479   emit_insn (gen_shori_media (operands[0], operands[0],
10480                               gen_int_mode (v, HImode)));
10481   DONE;
10485 (define_insn "*mshflo_l_di_x"
10486   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10487         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10488                                  "rZ"))
10489                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10490                            (const_int 32))))]
10492   "TARGET_SHMEDIA"
10493   "mshflo.l     %N1, %N2, %0"
10494   [(set_attr "type" "arith_media")])
10496 (define_insn_and_split "concat_v2sf"
10497   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10498 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10499         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10500                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10502   "TARGET_SHMEDIA"
10503   "@
10504         mshflo.l        %N1, %N2, %0
10505         #
10506         #"
10507   "TARGET_SHMEDIA && reload_completed
10508    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10509   [(set (match_dup 3) (match_dup 1))
10510    (set (match_dup 4) (match_dup 2))]
10511   "
10513   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10514   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10516   [(set_attr "type" "arith_media")])
10518 (define_insn "*mshflo_l_di_x_rev"
10519   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10520         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10521                            (const_int 32))
10522                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10524   "TARGET_SHMEDIA"
10525   "mshflo.l     %N2, %N1, %0"
10526   [(set_attr "type" "arith_media")])
10528 (define_insn "ashlv2si3"
10529   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10530         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10531                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10532   "TARGET_SHMEDIA"
10533   "mshlld.l     %1, %2, %0"
10534   [(set_attr "type" "arith_media")])
10536 (define_insn "ashlv4hi3"
10537   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10538         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10539                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10540   "TARGET_SHMEDIA"
10541   "mshlld.w     %1, %2, %0"
10542   [(set_attr "type" "arith_media")])
10544 (define_insn "lshrv2si3"
10545   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10546         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10547                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10548   "TARGET_SHMEDIA"
10549   "mshlrd.l     %1, %2, %0"
10550   [(set_attr "type" "arith_media")])
10552 (define_insn "lshrv4hi3"
10553   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10554         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10555                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10556   "TARGET_SHMEDIA"
10557   "mshlrd.w     %1, %2, %0"
10558   [(set_attr "type" "arith_media")])
10560 (define_insn "subv2si3"
10561   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10562         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10563                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10564   "TARGET_SHMEDIA"
10565   "msub.l       %N1, %2, %0"
10566   [(set_attr "type" "arith_media")])
10568 (define_insn "subv4hi3"
10569   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10570         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10571                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10572   "TARGET_SHMEDIA"
10573   "msub.w       %N1, %2, %0"
10574   [(set_attr "type" "arith_media")])
10576 (define_insn "sssubv2si3"
10577   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10578         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10579                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10580   "TARGET_SHMEDIA"
10581   "msubs.l      %N1, %2, %0"
10582   [(set_attr "type" "mcmp_media")])
10584 (define_insn "ussubv8qi3"
10585   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10586         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10587                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10588   "TARGET_SHMEDIA"
10589   "msubs.ub     %1, %2, %0"
10590   [(set_attr "type" "mcmp_media")])
10592 (define_insn "sssubv4hi3"
10593   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10594         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10595                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10596   "TARGET_SHMEDIA"
10597   "msubs.w      %N1, %2, %0"
10598   [(set_attr "type" "mcmp_media")])
10600 ;; Floating Point Intrinsics
10602 (define_insn "fcosa_s"
10603   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10604         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10605                    UNSPEC_FCOSA))]
10606   "TARGET_SHMEDIA"
10607   "fcosa.s      %1, %0"
10608   [(set_attr "type" "atrans_media")])
10610 (define_insn "fsina_s"
10611   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10612         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10613                    UNSPEC_FSINA))]
10614   "TARGET_SHMEDIA"
10615   "fsina.s      %1, %0"
10616   [(set_attr "type" "atrans_media")])
10618 (define_insn "fipr"
10619   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10620         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10621                                                     "fp_arith_reg_operand" "f")
10622                                                    (match_operand:V4SF 2
10623                                                     "fp_arith_reg_operand" "f"))
10624                                          (parallel [(const_int 0)]))
10625                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10626                                          (parallel [(const_int 1)])))
10627                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10628                                          (parallel [(const_int 2)]))
10629                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10630                                          (parallel [(const_int 3)])))))]
10631   "TARGET_SHMEDIA"
10632   "fipr.s       %1, %2, %0"
10633   [(set_attr "type" "fparith_media")])
10635 (define_insn "fsrra_s"
10636   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10637         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10638                    UNSPEC_FSRRA))]
10639   "TARGET_SHMEDIA"
10640   "fsrra.s      %1, %0"
10641   [(set_attr "type" "atrans_media")])
10643 (define_insn "ftrv"
10644   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10645         (plus:V4SF
10646          (plus:V4SF
10647           (mult:V4SF
10648            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10649                             (parallel [(const_int 0) (const_int 5)
10650                                        (const_int 10) (const_int 15)]))
10651            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10652           (mult:V4SF
10653            (vec_select:V4SF (match_dup 1)
10654                             (parallel [(const_int 4) (const_int 9)
10655                                        (const_int 14) (const_int 3)]))
10656            (vec_select:V4SF (match_dup 2)
10657                             (parallel [(const_int 1) (const_int 2)
10658                                        (const_int 3) (const_int 0)]))))
10659          (plus:V4SF
10660           (mult:V4SF
10661            (vec_select:V4SF (match_dup 1)
10662                             (parallel [(const_int 8) (const_int 13)
10663                                        (const_int 2) (const_int 7)]))
10664            (vec_select:V4SF (match_dup 2)
10665                             (parallel [(const_int 2) (const_int 3)
10666                                        (const_int 0) (const_int 1)])))
10667           (mult:V4SF
10668            (vec_select:V4SF (match_dup 1)
10669                             (parallel [(const_int 12) (const_int 1)
10670                                        (const_int 6) (const_int 11)]))
10671            (vec_select:V4SF (match_dup 2)
10672                             (parallel [(const_int 3) (const_int 0)
10673                                        (const_int 1) (const_int 2)]))))))]
10674   "TARGET_SHMEDIA"
10675   "ftrv.s %1, %2, %0"
10676   [(set_attr "type" "fparith_media")])
10678 (define_insn "nsb"
10679   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10680         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10681                    UNSPEC_NSB))]
10682   "TARGET_SHMEDIA"
10683   "nsb  %1, %0"
10684   [(set_attr "type" "arith_media")])
10686 (define_insn "nsbsi"
10687   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10688         (zero_extend:SI
10689          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10690                     UNSPEC_NSB)))]
10691   "TARGET_SHMEDIA"
10692   "nsb  %1, %0"
10693   [(set_attr "type" "arith_media")])
10695 (define_insn "nsbdi"
10696   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10697         (zero_extend:DI
10698          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10699                     UNSPEC_NSB)))]
10700   "TARGET_SHMEDIA"
10701   "nsb  %1, %0"
10702   [(set_attr "type" "arith_media")])
10704 (define_expand "ffsdi2"
10705   [(set (match_operand:DI 0 "arith_reg_dest" "")
10706         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10707   "TARGET_SHMEDIA"
10708   "
10710   rtx scratch = gen_reg_rtx (DImode);
10711   rtx last;
10713   emit_insn (gen_adddi3 (scratch, operands[1], constm1_rtx));
10714   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10715   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10716   emit_insn (gen_nsbdi (scratch, scratch));
10717   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10718   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10719   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10720   REG_NOTES (last)
10721     = gen_rtx_EXPR_LIST (REG_EQUAL,
10722                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10723   DONE;
10726 (define_expand "ffssi2"
10727   [(set (match_operand:SI 0 "arith_reg_dest" "")
10728         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10729   "TARGET_SHMEDIA"
10730   "
10732   rtx scratch = gen_reg_rtx (SImode);
10733   rtx discratch = gen_reg_rtx (DImode);
10734   rtx last;
10736   emit_insn (gen_adddi3 (discratch,
10737                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10738                          constm1_rtx));
10739   emit_insn (gen_andcdi3 (discratch,
10740                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10741                           discratch));
10742   emit_insn (gen_nsbsi (scratch, discratch));
10743   last = emit_insn (gen_subsi3 (operands[0],
10744                                 force_reg (SImode, GEN_INT (63)), scratch));
10745   REG_NOTES (last)
10746     = gen_rtx_EXPR_LIST (REG_EQUAL,
10747                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10748   DONE;
10751 (define_insn "byterev"
10752   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10753         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10754                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10755                                     (const_int 4) (const_int 3) (const_int 2)
10756                                     (const_int 1) (const_int 0)])))]
10757   "TARGET_SHMEDIA"
10758   "byterev      %1, %0"
10759   [(set_attr "type" "arith_media")])
10761 (define_insn "prefetch"
10762   [(prefetch (match_operand:QI 0 "address_operand" "p")
10763              (match_operand:SI 1 "const_int_operand" "n")
10764              (match_operand:SI 2 "const_int_operand" "n"))]
10765   "TARGET_SHMEDIA"
10766   "*
10768   operands[0] = gen_rtx_MEM (QImode, operands[0]);
10769   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
10770   return \"\";
10772   [(set_attr "type" "other")])
10774 ;; The following description  models the
10775 ;; SH4 pipeline using the DFA based scheduler.
10776 ;; The DFA based description is better way to model
10777 ;; a superscalar pipeline as compared to function unit
10778 ;; reservation model.
10779 ;; 1. The function unit based model is oriented to describe at most one
10780 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple
10781 ;;    pipeline units by same insn. This can be done using DFA based description.
10782 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10783 ;; 3. Writing all unit reservations for an instruction class is more natural description
10784 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the
10785 ;;    old function unit based model.
10786 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10789 ;; Two automata are defined to reduce number of states
10790 ;; which a single large automaton will have.(Factoring)
10792 (define_automaton "inst_pipeline,fpu_pipe")
10794 ;; This unit is basically the decode unit of the processor.
10795 ;; Since SH4 is a dual issue machine,it is as if there are two
10796 ;; units so that any insn can be processed by either one
10797 ;; of the decoding unit.
10799 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10802 ;; The fixed point arithmetic calculator(?? EX Unit).
10804 (define_cpu_unit  "int" "inst_pipeline")
10806 ;; f1_1 and f1_2 are floating point units.Actually there is
10807 ;; a f1 unit which can overlap with other f1 unit but
10808 ;; not another F1 unit.It is as though there were two
10809 ;; f1 units.
10811 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10813 ;; The floating point units (except FS - F2 always precedes it.)
10815 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10817 ;; This is basically the MA unit of SH4
10818 ;; used in LOAD/STORE pipeline.
10820 (define_cpu_unit "memory" "inst_pipeline")
10822 ;; However, there are LS group insns that don't use it, even ones that
10823 ;; complete in 0 cycles.  So we use an extra unit for the issue of LS insns.
10824 (define_cpu_unit "load_store" "inst_pipeline")
10826 ;; The address calculator used for branch instructions.
10827 ;; This will be reserved after "issue" of branch instructions
10828 ;; and this is to make sure that no two branch instructions
10829 ;; can be issued in parallel.
10831 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10833 ;; ----------------------------------------------------
10834 ;; This reservation is to simplify the dual issue description.
10836 (define_reservation  "issue"  "pipe_01|pipe_02")
10838 ;; This is to express the locking of D stage.
10839 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10841 (define_reservation  "d_lock" "pipe_01+pipe_02")
10843 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10844 (define_reservation "F01" "F0+F1")
10846 ;; This is to simplify description where F1,F2,FS
10847 ;; are used simultaneously.
10849 (define_reservation "fpu" "F1+F2")
10851 ;; This is to highlight the fact that f1
10852 ;; cannot overlap with F1.
10854 (exclusion_set  "f1_1,f1_2" "F1")
10856 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10858 ;; Although reg moves have a latency of zero
10859 ;; we need to highlight that they use D stage
10860 ;; for one cycle.
10862 ;; Group:       MT
10864 (define_insn_reservation "reg_mov" 0
10865   (and (eq_attr "pipe_model" "sh4")
10866        (eq_attr "type" "move"))
10867   "issue")
10869 ;; Group:       LS
10871 (define_insn_reservation "freg_mov" 0
10872   (and (eq_attr "pipe_model" "sh4")
10873        (eq_attr "type" "fmove"))
10874   "issue+load_store")
10876 ;; We don't model all pipeline stages; we model the issue ('D') stage
10877 ;; inasmuch as we allow only two instructions to issue simultaneously,
10878 ;; and CO instructions prevent any simultaneous issue of another instruction.
10879 ;; (This uses pipe_01 and pipe_02).
10880 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10881 ;; Double issue of EX / BR insns is prevented by using the int unit /
10882 ;; pcr_addrcalc unit in the EX stage.
10883 ;; Double issue of BR / LS instructions is prevented by using the
10884 ;; pcr_addrcalc / load_store unit in the issue cycle.
10885 ;; Double issue of FE instructions is prevented by using F0 in the first
10886 ;; pipeline stage after the first D stage.
10887 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10888 ;; (except in the cases outlined above), nor to describe the FS stage after
10889 ;; the F2 stage.
10891 ;; Other MT  group instructions(1 step operations)
10892 ;; Group:       MT
10893 ;; Latency:     1
10894 ;; Issue Rate:  1
10896 (define_insn_reservation "mt" 1
10897   (and (eq_attr "pipe_model" "sh4")
10898        (eq_attr "type" "mt_group"))
10899   "issue")
10901 ;; Fixed Point Arithmetic Instructions(1 step operations)
10902 ;; Group:       EX
10903 ;; Latency:     1
10904 ;; Issue Rate:  1
10906 (define_insn_reservation "sh4_simple_arith" 1
10907   (and (eq_attr "pipe_model" "sh4")
10908        (eq_attr "insn_class" "ex_group"))
10909   "issue,int")
10911 ;; Load and store instructions have no alignment peculiarities for the SH4,
10912 ;; but they use the load-store unit, which they share with the fmove type
10913 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10914 ;; Loads have a latency of two.
10915 ;; However, call insns can only paired with a preceding insn, and have
10916 ;; a delay slot, so that we want two more insns to be scheduled between the
10917 ;; load of the function address and the call.  This is equivalent to a
10918 ;; latency of three.
10919 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10920 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10921 ;; We only do this for SImode loads of general registers, to make the work
10922 ;; for ADJUST_COST easier.
10924 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10925 ;; Group:       LS
10926 ;; Latency:     2
10927 ;; Issue Rate:  1
10929 (define_insn_reservation "sh4_load" 2
10930   (and (eq_attr "pipe_model" "sh4")
10931        (eq_attr "type" "load,pcload"))
10932   "issue+load_store,nothing,memory")
10934 ;; calls / sfuncs need an extra instruction for their delay slot.
10935 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10936 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10937 ;; count of a dynamic shift.
10938 (define_insn_reservation "sh4_load_si" 3
10939   (and (eq_attr "pipe_model" "sh4")
10940        (eq_attr "type" "load_si,pcload_si"))
10941   "issue+load_store,nothing,memory")
10943 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10945 ;; The load latency is upped to three higher if the dependent insn does
10946 ;; double precision computation.  We want the 'default' latency to reflect
10947 ;; that increased latency because otherwise the insn priorities won't
10948 ;; allow proper scheduling.
10949 (define_insn_reservation "sh4_fload" 3
10950   (and (eq_attr "pipe_model" "sh4")
10951        (eq_attr "type" "fload,pcfload"))
10952   "issue+load_store,nothing,memory")
10954 ;; (define_bypass 2 "sh4_fload" "!")
10956 (define_insn_reservation "sh4_store" 1
10957   (and (eq_attr "pipe_model" "sh4")
10958        (eq_attr "type" "store"))
10959   "issue+load_store,nothing,memory")
10961 ;; Load Store instructions.
10962 ;; Group:       LS
10963 ;; Latency:     1
10964 ;; Issue Rate:  1
10966 (define_insn_reservation "sh4_gp_fpul" 1
10967   (and (eq_attr "pipe_model" "sh4")
10968        (eq_attr "type" "gp_fpul"))
10969   "issue+load_store")
10971 ;; Load Store instructions.
10972 ;; Group:       LS
10973 ;; Latency:     3
10974 ;; Issue Rate:  1
10976 (define_insn_reservation "sh4_fpul_gp" 3
10977   (and (eq_attr "pipe_model" "sh4")
10978        (eq_attr "type" "fpul_gp"))
10979   "issue+load_store")
10981 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10982 ;; Group:       BR
10983 ;; Latency when taken:  2 (or 1)
10984 ;; Issue Rate:  1
10985 ;; The latency is 1 when displacement is 0.
10986 ;; We can't really do much with the latency, even if we could express it,
10987 ;; but the pairing restrictions are useful to take into account.
10988 ;; ??? If the branch is likely, we might want to fill the delay slot;
10989 ;; if the branch is likely, but not very likely, should we pretend to use
10990 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10992 (define_insn_reservation "sh4_branch"  1
10993   (and (eq_attr "pipe_model" "sh4")
10994        (eq_attr "type" "cbranch,jump"))
10995   "issue+pcr_addrcalc")
10997 ;; Branch Far (JMP,RTS,BRAF)
10998 ;; Group:       CO
10999 ;; Latency:     3
11000 ;; Issue Rate:  2
11001 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
11002 ;; can't be distinguished from bra for the "jump" pattern.
11004 (define_insn_reservation "sh4_return" 3
11005   (and (eq_attr "pipe_model" "sh4")
11006        (eq_attr "type" "return,jump_ind"))
11007          "d_lock*2")
11009 ;; RTE
11010 ;; Group:       CO
11011 ;; Latency:     5
11012 ;; Issue Rate:  5
11013 ;; this instruction can be executed in any of the pipelines
11014 ;; and blocks the pipeline for next 4 stages.
11016 (define_insn_reservation "sh4_return_from_exp" 5
11017   (and (eq_attr "pipe_model" "sh4")
11018        (eq_attr "type" "rte"))
11019   "d_lock*5")
11021 ;; OCBP, OCBWB
11022 ;; Group:       CO
11023 ;; Latency:     1-5
11024 ;; Issue Rate:  1
11026 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
11027 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
11028 (define_insn_reservation "ocbwb"  6
11029   (and (eq_attr "pipe_model" "sh4")
11030        (eq_attr "type" "cwb"))
11031   "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
11033 ;; LDS to PR,JSR
11034 ;; Group:       CO
11035 ;; Latency:     3
11036 ;; Issue Rate:  2
11037 ;; The SX stage is blocked for last 2 cycles.
11038 ;; OTOH, the only time that has an effect for insns generated by the compiler
11039 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
11040 ;; or when we are doing a function call - and we don't do inter-function
11041 ;; scheduling.  For the function call case, it's really best that we end with
11042 ;; something that models an rts.
11044 (define_insn_reservation "sh4_lds_to_pr" 3
11045   (and (eq_attr "pipe_model" "sh4")
11046        (eq_attr "type" "prset") )
11047   "d_lock*2")
11049 ;; calls introduce a longisch delay that is likely to flush the pipelines
11050 ;; of the caller's instructions.  Ordinary functions tend to end with a
11051 ;; load to restore a register (in the delay slot of rts), while sfuncs
11052 ;; tend to end with an EX or MT insn.  But that is not actually relevant,
11053 ;; since there are no instructions that contend for memory access early.
11054 ;; We could, of course, provide exact scheduling information for specific
11055 ;; sfuncs, if that should prove useful.
11057 (define_insn_reservation "sh4_call" 16
11058   (and (eq_attr "pipe_model" "sh4")
11059        (eq_attr "type" "call,sfunc"))
11060   "d_lock*16")
11062 ;; LDS.L to PR
11063 ;; Group:       CO
11064 ;; Latency:     3
11065 ;; Issue Rate:  2
11066 ;; The SX unit is blocked for last 2 cycles.
11068 (define_insn_reservation "ldsmem_to_pr"  3
11069   (and (eq_attr "pipe_model" "sh4")
11070        (eq_attr "type" "pload"))
11071   "d_lock*2")
11073 ;; STS from PR
11074 ;; Group:       CO
11075 ;; Latency:     2
11076 ;; Issue Rate:  2
11077 ;; The SX unit in second and third cycles.
11079 (define_insn_reservation "sts_from_pr" 2
11080   (and (eq_attr "pipe_model" "sh4")
11081        (eq_attr "type" "prget"))
11082   "d_lock*2")
11084 ;; STS.L from PR
11085 ;; Group:       CO
11086 ;; Latency:     2
11087 ;; Issue Rate:  2
11089 (define_insn_reservation "sh4_prstore_mem" 2
11090   (and (eq_attr "pipe_model" "sh4")
11091        (eq_attr "type" "pstore"))
11092   "d_lock*2,nothing,memory")
11094 ;; LDS to FPSCR
11095 ;; Group:       CO
11096 ;; Latency:     4
11097 ;; Issue Rate:  1
11098 ;; F1 is blocked for last three cycles.
11100 (define_insn_reservation "fpscr_load" 4
11101   (and (eq_attr "pipe_model" "sh4")
11102        (eq_attr "type" "gp_fpscr"))
11103   "d_lock,nothing,F1*3")
11105 ;; LDS.L to FPSCR
11106 ;; Group:       CO
11107 ;; Latency:     1 / 4
11108 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
11109 ;; Issue Rate:  1
11110 ;; F1 is blocked for last three cycles.
11112 (define_insn_reservation "fpscr_load_mem" 4
11113   (and (eq_attr "pipe_model" "sh4")
11114        (eq_attr "type"  "mem_fpscr"))
11115   "d_lock,nothing,(F1+memory),F1*2")
11118 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11119 ;; Group:       CO
11120 ;; Latency:     4 / 4
11121 ;; Issue Rate:  1
11123 (define_insn_reservation "multi" 4
11124   (and (eq_attr "pipe_model" "sh4")
11125        (eq_attr "type" "smpy,dmpy"))
11126   "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11128 ;; Fixed STS from MACL / MACH
11129 ;; Group:       CO
11130 ;; Latency:     3
11131 ;; Issue Rate:  1
11133 (define_insn_reservation "sh4_mac_gp" 3
11134   (and (eq_attr "pipe_model" "sh4")
11135        (eq_attr "type" "mac_gp"))
11136   "d_lock")
11139 ;; Single precision floating point computation FCMP/EQ,
11140 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11141 ;; Group:       FE
11142 ;; Latency:     3/4
11143 ;; Issue Rate:  1
11145 (define_insn_reservation "fp_arith"  3
11146   (and (eq_attr "pipe_model" "sh4")
11147        (eq_attr "type" "fp"))
11148   "issue,F01,F2")
11150 (define_insn_reservation "fp_arith_ftrc"  3
11151   (and (eq_attr "pipe_model" "sh4")
11152        (eq_attr "type" "ftrc_s"))
11153   "issue,F01,F2")
11155 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11157 ;; Single Precision FDIV/SQRT
11158 ;; Group:       FE
11159 ;; Latency:     12/13 (FDIV); 11/12 (FSQRT)
11160 ;; Issue Rate:  1
11161 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11163 (define_insn_reservation "fp_div" 12
11164   (and (eq_attr "pipe_model" "sh4")
11165        (eq_attr "type" "fdiv"))
11166   "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11168 ;; Double Precision floating point computation
11169 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11170 ;; Group:       FE
11171 ;; Latency:     (3,4)/5
11172 ;; Issue Rate:  1
11174 (define_insn_reservation "dp_float" 4
11175   (and (eq_attr "pipe_model" "sh4")
11176        (eq_attr "type" "dfp_conv"))
11177   "issue,F01,F1+F2,F2")
11179 ;; Double-precision floating-point (FADD,FMUL,FSUB)
11180 ;; Group:       FE
11181 ;; Latency:     (7,8)/9
11182 ;; Issue Rate:  1
11184 (define_insn_reservation "fp_double_arith" 8
11185   (and (eq_attr "pipe_model" "sh4")
11186        (eq_attr "type" "dfp_arith"))
11187   "issue,F01,F1+F2,fpu*4,F2")
11189 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
11190 ;; Group:       CO
11191 ;; Latency:     3/5
11192 ;; Issue Rate:  2
11194 (define_insn_reservation "fp_double_cmp" 3
11195   (and (eq_attr "pipe_model" "sh4")
11196        (eq_attr "type" "dfp_cmp"))
11197   "d_lock,(d_lock+F01),F1+F2,F2")
11199 ;; Double precision FDIV/SQRT
11200 ;; Group:       FE
11201 ;; Latency:     (24,25)/26
11202 ;; Issue Rate:  1
11204 (define_insn_reservation "dp_div" 25
11205   (and (eq_attr "pipe_model" "sh4")
11206        (eq_attr "type" "dfdiv"))
11207   "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11210 ;; Use the branch-not-taken case to model arith3 insns.  For the branch taken
11211 ;; case, we'd get a d_lock instead of issue at the end.
11212 (define_insn_reservation "arith3" 3
11213   (and (eq_attr "pipe_model" "sh4")
11214        (eq_attr "type" "arith3"))
11215   "issue,d_lock+pcr_addrcalc,issue")
11217 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11218 (define_insn_reservation "arith3b" 2
11219   (and (eq_attr "pipe_model" "sh4")
11220        (eq_attr "type" "arith3"))
11221   "issue,d_lock+pcr_addrcalc")