2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / config / sh / sh.md
blobaa63209dbf608d5206d259d2ca65e5ef1cd73492
1 ;;- Machine description for Renesas / SuperH SH.
2 ;;  Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 ;;  Free Software Foundation, Inc.
4 ;;  Contributed by Steve Chamberlain (sac@cygnus.com).
5 ;;  Improved by Jim Wilson (wilson@cygnus.com).
7 ;; This file is part of 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 (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"
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         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 == trunc_int_for_mode (val, SImode))
4052             {
4053               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4054                                              operands[0]);
4055               break;
4056             }
4057           /* Try movi / mshflo.l w/ r63.  */
4058           val2 = val + ((HOST_WIDE_INT) -1 << 32);
4059           if ((HOST_WIDE_INT) val2 < 0 && CONST_OK_FOR_I16 (val2))
4060             {
4061               operands[1] = gen_mshflo_l_di (operands[0], operands[0],
4062                                              GEN_INT (0));
4063               break;
4064             }
4065         }
4066       val2 = high;
4067       operands[1] = gen_shori_media (operands[0], operands[0], GEN_INT (low));
4068     }
4069   while (0);
4070   operands[2] = GEN_INT (val2);
4073 (define_split
4074   [(set (match_operand:DI 0 "arith_reg_operand" "")
4075         (match_operand:DI 1 "immediate_operand" ""))]
4076   "TARGET_SHMEDIA && reload_completed
4077    && GET_CODE (operands[1]) == CONST_DOUBLE"
4078   [(set (match_dup 0) (match_dup 2))
4079   (set (match_dup 0)
4080        (ior:DI (ashift:DI (match_dup 0) (const_int 16))
4081                (zero_extend:DI (truncate:HI (match_dup 1)))))]
4082   "
4084   unsigned HOST_WIDE_INT low = CONST_DOUBLE_LOW (operands[1]);
4085   unsigned HOST_WIDE_INT high = CONST_DOUBLE_HIGH (operands[1]);
4086   unsigned HOST_WIDE_INT val = low;
4087   unsigned HOST_WIDE_INT sign;
4089   /* Sign-extend the 16 least-significant bits.  */
4090   val &= 0xffff;
4091   val ^= 0x8000;
4092   val -= 0x8000;
4093   operands[1] = GEN_INT (val);
4095   /* Arithmetic shift right the double-word by 16 bits.  */
4096   low >>= 16;
4097   low |= (high & 0xffff) << (HOST_BITS_PER_WIDE_INT - 16);
4098   high >>= 16;
4099   sign = 1;
4100   sign <<= (HOST_BITS_PER_WIDE_INT - 16 - 1);
4101   high ^= sign;
4102   high -= sign;
4104   /* This will only be true if high is a sign-extension of low, i.e.,
4105      it must be either 0 or (unsigned)-1, and be zero iff the
4106      most-significant bit of low is set.  */
4107   if (high + (low >> (HOST_BITS_PER_WIDE_INT - 1)) == 0)
4108     operands[2] = GEN_INT (low);
4109   else
4110     operands[2] = immed_double_const (low, high, DImode);
4113 (define_insn "shori_media"
4114   [(set (match_operand:DI 0 "arith_reg_operand" "=r,r")
4115         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0,0")
4116                            (const_int 16))
4117                 (zero_extend:DI
4118                  (truncate:HI
4119                   (match_operand:DI 2 "immediate_operand" "I16C16,nF")))))]
4120   "TARGET_SHMEDIA"
4121   "@
4122         shori   %u2, %0
4123         #"
4124   [(set_attr "type" "arith_media,*")])
4126 (define_expand "movdi"
4127   [(set (match_operand:DI 0 "general_movdst_operand" "")
4128         (match_operand:DI 1 "general_movsrc_operand" ""))]
4129   ""
4130   "{ if (prepare_move_operands (operands, DImode)) DONE; }")
4132 (define_insn "movdf_media"
4133   [(set (match_operand:DF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4134         (match_operand:DF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4135   "TARGET_SHMEDIA_FPU
4136    && (register_operand (operands[0], DFmode)
4137        || sh_register_operand (operands[1], DFmode))"
4138   "@
4139         fmov.d  %1, %0
4140         fmov.qd %N1, %0
4141         fmov.dq %1, %0
4142         add     %1, r63, %0
4143         #
4144         fld%M1.d        %m1, %0
4145         fst%M0.d        %m0, %1
4146         ld%M1.q %m1, %0
4147         st%M0.q %m0, %N1"
4148   [(set_attr "type" "fmove_media,fload_media,dfpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4150 (define_insn "movdf_media_nofpu"
4151   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4152         (match_operand:DF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4153   "TARGET_SHMEDIA
4154    && (register_operand (operands[0], DFmode)
4155        || sh_register_operand (operands[1], DFmode))"
4156   "@
4157         add     %1, r63, %0
4158         #
4159         ld%M1.q %m1, %0
4160         st%M0.q %m0, %N1"
4161   [(set_attr "type" "arith_media,*,load_media,store_media")])
4163 (define_split
4164   [(set (match_operand:DF 0 "arith_reg_operand" "")
4165         (match_operand:DF 1 "immediate_operand" ""))]
4166   "TARGET_SHMEDIA && reload_completed"
4167   [(set (match_dup 3) (match_dup 2))]
4168   "
4170   int endian = WORDS_BIG_ENDIAN ? 1 : 0;
4171   long values[2];
4172   REAL_VALUE_TYPE value;
4174   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4175   REAL_VALUE_TO_TARGET_DOUBLE (value, values);
4177   if (HOST_BITS_PER_WIDE_INT >= 64)
4178     operands[2] = immed_double_const ((unsigned long) values[endian]
4179                                       | ((HOST_WIDE_INT) values[1 - endian]
4180                                          << 32), 0, DImode);
4181   else if (HOST_BITS_PER_WIDE_INT == 32)
4182     operands[2] = immed_double_const (values[endian], values[1 - endian],
4183                                       DImode);
4184   else
4185     abort ();
4187   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4190 ;; ??? This should be a define expand.
4192 (define_insn "movdf_k"
4193   [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
4194         (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
4195   "TARGET_SH1
4196    && (! TARGET_SH4 || reload_completed
4197        /* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
4198        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4199        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4200    && (arith_reg_operand (operands[0], DFmode)
4201        || arith_reg_operand (operands[1], DFmode))"
4202   "* return output_movedouble (insn, operands, DFmode);"
4203   [(set_attr "length" "4")
4204    (set_attr "type" "move,pcload,load,store")])
4206 ;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
4207 ;; However, the d/F/c/z alternative cannot be split directly; it is converted
4208 ;; with special code in machine_dependent_reorg into a load of the R0_REG and
4209 ;; the d/m/c/X alternative, which is split later into single-precision
4210 ;; instructions.  And when not optimizing, no splits are done before fixing
4211 ;; up pcloads, so we need usable length information for that.
4212 (define_insn "movdf_i4"
4213   [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
4214         (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
4215    (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c"))
4216    (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))]
4217   "TARGET_SH4
4218    && (arith_reg_operand (operands[0], DFmode)
4219        || arith_reg_operand (operands[1], DFmode))"
4220   "@
4221         fmov    %1,%0
4222         #
4223         #
4224         fmov.d  %1,%0
4225         fmov.d  %1,%0
4226         #
4227         #
4228         #
4229         #
4230         #"
4231   [(set_attr_alternative "length"
4232      [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
4233       (const_int 4)
4234       (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
4235       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4236       (if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 6))
4237       (const_int 4)
4238       (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
4239       ;; We can't use 4-byte push/pop on SHcompact, so we have to
4240       ;; increment or decrement r15 explicitly.
4241       (if_then_else
4242        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4243        (const_int 10) (const_int 8))
4244       (if_then_else
4245        (ne (symbol_ref "TARGET_SHCOMPACT") (const_int 0))
4246        (const_int 10) (const_int 8))])
4247    (set_attr "type" "fmove,move,pcfload,fload,store,pcload,load,store,load,fload")
4248    (set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
4249    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4250                                            (const_string "double")
4251                                            (const_string "none")))])
4253 ;; Moving DFmode between fp/general registers through memory
4254 ;; (the top of the stack) is faster than moving through fpul even for
4255 ;; little endian.  Because the type of an instruction is important for its
4256 ;; scheduling,  it is beneficial to split these operations, rather than
4257 ;; emitting them in one single chunk, even if this will expose a stack
4258 ;; use that will prevent scheduling of other stack accesses beyond this
4259 ;; instruction.
4260 (define_split
4261   [(set (match_operand:DF 0 "register_operand" "")
4262         (match_operand:DF 1 "register_operand" ""))
4263    (use (match_operand:PSI 2 "fpscr_operand" ""))
4264    (clobber (match_scratch:SI 3 "=X"))]
4265   "TARGET_SH4 && reload_completed
4266    && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)"
4267   [(const_int 0)]
4268   "
4270   rtx insn, tos;
4272   if (TARGET_SH5 && true_regnum (operands[1]) < 16)
4273     {
4274       emit_move_insn (stack_pointer_rtx,
4275                       plus_constant (stack_pointer_rtx, -8));
4276       tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4277     }
4278   else
4279     tos = gen_rtx (MEM, DFmode, gen_rtx (PRE_DEC, Pmode, stack_pointer_rtx));
4280   insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2]));
4281   if (! (TARGET_SH5 && true_regnum (operands[1]) < 16))
4282     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4283   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4284     tos = gen_rtx_MEM (DFmode, stack_pointer_rtx);
4285   else
4286     tos = gen_rtx (MEM, DFmode, gen_rtx (POST_INC, Pmode, stack_pointer_rtx));
4287   insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2]));
4288   if (TARGET_SH5 && true_regnum (operands[0]) < 16)
4289     emit_move_insn (stack_pointer_rtx, plus_constant (stack_pointer_rtx, 8));
4290   else
4291     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
4292   DONE;
4295 ;; local-alloc sometimes allocates scratch registers even when not required,
4296 ;; so we must be prepared to handle these.
4298 ;; Remove the use and clobber from a movdf_i4 so that we can use movdf_k.
4299 (define_split
4300   [(set (match_operand:DF 0 "general_movdst_operand" "")
4301         (match_operand:DF 1 "general_movsrc_operand"  ""))
4302    (use (match_operand:PSI 2 "fpscr_operand" ""))
4303    (clobber (match_scratch:SI 3 ""))]
4304   "TARGET_SH4
4305    && reload_completed
4306    && true_regnum (operands[0]) < 16
4307    && true_regnum (operands[1]) < 16"
4308   [(set (match_dup 0) (match_dup 1))]
4309   "
4311   /* If this was a reg <-> mem operation with base + index reg addressing,
4312      we have to handle this in a special way.  */
4313   rtx mem = operands[0];
4314   int store_p = 1;
4315   if (! memory_operand (mem, DFmode))
4316     {
4317       mem = operands[1];
4318       store_p = 0;
4319     }
4320   if (GET_CODE (mem) == SUBREG && SUBREG_BYTE (mem) == 0)
4321     mem = SUBREG_REG (mem);
4322   if (GET_CODE (mem) == MEM)
4323     {
4324       rtx addr = XEXP (mem, 0);
4325       if (GET_CODE (addr) == PLUS
4326           && GET_CODE (XEXP (addr, 0)) == REG
4327           && GET_CODE (XEXP (addr, 1)) == REG)
4328         {
4329           int offset;
4330           rtx reg0 = gen_rtx (REG, Pmode, 0);
4331           rtx regop = operands[store_p], word0 ,word1;
4333           if (GET_CODE (regop) == SUBREG)
4334             alter_subreg (&regop);
4335           if (REGNO (XEXP (addr, 0)) == REGNO (XEXP (addr, 1)))
4336             offset = 2;
4337           else
4338             offset = 4;
4339           mem = copy_rtx (mem);
4340           PUT_MODE (mem, SImode);
4341           word0 = gen_rtx (SUBREG, SImode, regop, 0);
4342           alter_subreg (&word0);
4343           word1 = gen_rtx (SUBREG, SImode, regop, 4);
4344           alter_subreg (&word1);
4345           if (store_p || ! refers_to_regno_p (REGNO (word0),
4346                                               REGNO (word0) + 1, addr, 0))
4347             {
4348               emit_insn (store_p
4349                          ? gen_movsi_ie (mem, word0)
4350                          : gen_movsi_ie (word0, mem));
4351               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4352               mem = copy_rtx (mem);
4353               emit_insn (store_p
4354                          ? gen_movsi_ie (mem, word1)
4355                          : gen_movsi_ie (word1, mem));
4356               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4357             }
4358           else
4359             {
4360               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (offset)));
4361               emit_insn (gen_movsi_ie (word1, mem));
4362               emit_insn (gen_addsi3 (reg0, reg0, GEN_INT (-offset)));
4363               mem = copy_rtx (mem);
4364               emit_insn (gen_movsi_ie (word0, mem));
4365             }
4366           DONE;
4367         }
4368     }
4371 ;; Split away the clobber of r0 after machine_dependent_reorg has fixed pcloads.
4372 (define_split
4373   [(set (match_operand:DF 0 "register_operand" "")
4374         (match_operand:DF 1 "memory_operand"  ""))
4375    (use (match_operand:PSI 2 "fpscr_operand" ""))
4376    (clobber (reg:SI R0_REG))]
4377   "TARGET_SH4 && reload_completed"
4378   [(parallel [(set (match_dup 0) (match_dup 1))
4379               (use (match_dup 2))
4380               (clobber (scratch:SI))])]
4381   "")
4383 (define_expand "reload_indf"
4384   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
4385                    (match_operand:DF 1 "immediate_operand" "FQ"))
4386               (use (reg:PSI FPSCR_REG))
4387               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
4388   "TARGET_SH1"
4389   "")
4391 (define_expand "reload_outdf"
4392   [(parallel [(set (match_operand:DF 0 "register_operand" "=r,f")
4393                    (match_operand:DF 1 "register_operand" "af,r"))
4394               (clobber (match_operand:SI 2 "register_operand" "=&y,y"))])]
4395   "TARGET_SH1"
4396   "")
4398 ;; Simplify no-op moves.
4399 (define_split
4400   [(set (match_operand:SF 0 "register_operand" "")
4401         (match_operand:SF 1 "register_operand" ""))
4402    (use (match_operand:PSI 2 "fpscr_operand" ""))
4403    (clobber (match_scratch:SI 3 ""))]
4404   "TARGET_SH2E && reload_completed
4405    && true_regnum (operands[0]) == true_regnum (operands[1])"
4406   [(set (match_dup 0) (match_dup 0))]
4407   "")
4409 ;; fmovd substitute post-reload splits
4410 (define_split
4411   [(set (match_operand:DF 0 "register_operand" "")
4412         (match_operand:DF 1 "register_operand" ""))
4413    (use (match_operand:PSI 2 "fpscr_operand" ""))
4414    (clobber (match_scratch:SI 3 ""))]
4415   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4416    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4417    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4418   [(const_int 0)]
4419   "
4421   int dst = true_regnum (operands[0]), src = true_regnum (operands[1]);
4422   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst),
4423                            gen_rtx (REG, SFmode, src), operands[2]));
4424   emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode, dst + 1),
4425                            gen_rtx (REG, SFmode, src + 1), operands[2]));
4426   DONE;
4429 (define_split
4430   [(set (match_operand:DF 0 "register_operand" "")
4431         (mem:DF (match_operand:SI 1 "register_operand" "")))
4432    (use (match_operand:PSI 2 "fpscr_operand" ""))
4433    (clobber (match_scratch:SI 3 ""))]
4434   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4435    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))
4436    && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))"
4437   [(const_int 0)]
4438   "
4440   int regno = true_regnum (operands[0]);
4441   rtx insn;
4442   rtx mem2 = gen_rtx (MEM, SFmode, gen_rtx (POST_INC, Pmode, operands[1]));
4444   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4445                                            regno + !! TARGET_LITTLE_ENDIAN),
4446                                   mem2, operands[2]));
4447   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[1], NULL_RTX);
4448   insn = emit_insn (gen_movsf_ie (gen_rtx (REG, SFmode,
4449                                            regno + ! TARGET_LITTLE_ENDIAN),
4450                                   gen_rtx (MEM, SFmode, operands[1]),
4451                                   operands[2]));
4452   DONE;
4455 (define_split
4456   [(set (match_operand:DF 0 "register_operand" "")
4457         (match_operand:DF 1 "memory_operand" ""))
4458    (use (match_operand:PSI 2 "fpscr_operand" ""))
4459    (clobber (match_scratch:SI 3 ""))]
4460   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4461    && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))"
4462   [(const_int 0)]
4463   "
4465   int regno = true_regnum (operands[0]);
4466   rtx addr, insn, adjust = NULL_RTX;
4467   rtx mem2 = copy_rtx (operands[1]);
4468   rtx reg0 = gen_rtx_REG (SFmode, regno + !! TARGET_LITTLE_ENDIAN);
4469   rtx reg1 = gen_rtx_REG (SFmode, regno + ! TARGET_LITTLE_ENDIAN);
4471   PUT_MODE (mem2, SFmode);
4472   operands[1] = copy_rtx (mem2);
4473   addr = XEXP (mem2, 0);
4474   if (GET_CODE (addr) != POST_INC)
4475     {
4476       /* If we have to modify the stack pointer, the value that we have
4477          read with post-increment might be modified by an interrupt,
4478          so write it back.  */
4479       if (REGNO (addr) == STACK_POINTER_REGNUM)
4480         adjust = gen_push_e (reg0);
4481       else
4482         adjust = gen_addsi3 (addr, addr, GEN_INT (-4));
4483       XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr);
4484     }
4485   addr = XEXP (addr, 0);
4486   insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2]));
4487   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4488   insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2]));
4489   if (adjust)
4490     emit_insn (adjust);
4491   else
4492     REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC, addr, NULL_RTX);
4493   DONE;
4496 (define_split
4497   [(set (match_operand:DF 0 "memory_operand" "")
4498         (match_operand:DF 1 "register_operand" ""))
4499    (use (match_operand:PSI 2 "fpscr_operand" ""))
4500    (clobber (match_scratch:SI 3 ""))]
4501   "TARGET_SH4 && ! TARGET_FMOVD && reload_completed
4502    && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))"
4503   [(const_int 0)]
4504   "
4506   int regno = true_regnum (operands[1]);
4507   rtx insn, addr, adjust = NULL_RTX;
4509   operands[0] = copy_rtx (operands[0]);
4510   PUT_MODE (operands[0], SFmode);
4511   insn = emit_insn (gen_movsf_ie (operands[0],
4512                                   gen_rtx (REG, SFmode,
4513                                            regno + ! TARGET_LITTLE_ENDIAN),
4514                                   operands[2]));
4515   operands[0] = copy_rtx (operands[0]);
4516   addr = XEXP (operands[0], 0);
4517   if (GET_CODE (addr) != PRE_DEC)
4518     {
4519       adjust = gen_addsi3 (addr, addr, GEN_INT (4));
4520       emit_insn_before (adjust, insn);
4521       XEXP (operands[0], 0) = addr = gen_rtx (PRE_DEC, SImode, addr);
4522     }
4523   addr = XEXP (addr, 0);
4524   if (! adjust)
4525     REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4526   insn = emit_insn (gen_movsf_ie (operands[0],
4527                                   gen_rtx (REG, SFmode,
4528                                            regno + !! TARGET_LITTLE_ENDIAN),
4529                                   operands[2]));
4530   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, addr, NULL_RTX);
4531   DONE;
4534 ;; If the output is a register and the input is memory or a register, we have
4535 ;; to be careful and see which word needs to be loaded first.
4537 (define_split
4538   [(set (match_operand:DF 0 "general_movdst_operand" "")
4539         (match_operand:DF 1 "general_movsrc_operand" ""))]
4540   "TARGET_SH1 && reload_completed"
4541   [(set (match_dup 2) (match_dup 3))
4542    (set (match_dup 4) (match_dup 5))]
4543   "
4545   int regno;
4547   if ((GET_CODE (operands[0]) == MEM
4548        && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
4549       || (GET_CODE (operands[1]) == MEM
4550           && GET_CODE (XEXP (operands[1], 0)) == POST_INC))
4551     FAIL;
4553   if (GET_CODE (operands[0]) == REG)
4554     regno = REGNO (operands[0]);
4555   else if (GET_CODE (operands[0]) == SUBREG)
4556     regno = subreg_regno (operands[0]);
4557   else if (GET_CODE (operands[0]) == MEM)
4558     regno = -1;
4559   else
4560     abort ();
4562   if (regno == -1
4563       || ! refers_to_regno_p (regno, regno + 1, operands[1], 0))
4564     {
4565       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
4566       operands[3] = operand_subword (operands[1], 0, 0, DFmode);
4567       operands[4] = operand_subword (operands[0], 1, 0, DFmode);
4568       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
4569     }
4570   else
4571     {
4572       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
4573       operands[3] = operand_subword (operands[1], 1, 0, DFmode);
4574       operands[4] = operand_subword (operands[0], 0, 0, DFmode);
4575       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
4576     }
4578   if (operands[2] == 0 || operands[3] == 0
4579       || operands[4] == 0 || operands[5] == 0)
4580     FAIL;
4583 ;; If a base address generated by LEGITIMIZE_ADDRESS for SImode is
4584 ;; used only once, let combine add in the index again.
4586 (define_split
4587   [(set (match_operand:SI 0 "register_operand" "")
4588         (match_operand:SI 1 "" ""))
4589    (clobber (match_operand 2 "register_operand" ""))]
4590   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4591   [(use (reg:SI R0_REG))]
4592   "
4594   rtx addr, reg, const_int;
4596   if (GET_CODE (operands[1]) != MEM)
4597     FAIL;
4598   addr = XEXP (operands[1], 0);
4599   if (GET_CODE (addr) != PLUS)
4600     FAIL;
4601   reg = XEXP (addr, 0);
4602   const_int = XEXP (addr, 1);
4603   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4604          && GET_CODE (const_int) == CONST_INT))
4605     FAIL;
4606   emit_move_insn (operands[2], const_int);
4607   emit_move_insn (operands[0],
4608                   change_address (operands[1], VOIDmode,
4609                                   gen_rtx_PLUS (SImode, reg, operands[2])));
4610   DONE;
4613 (define_split
4614   [(set (match_operand:SI 1 "" "")
4615         (match_operand:SI 0 "register_operand" ""))
4616    (clobber (match_operand 2 "register_operand" ""))]
4617   "TARGET_SH1 && ! reload_in_progress && ! reload_completed"
4618   [(use (reg:SI R0_REG))]
4619   "
4621   rtx addr, reg, const_int;
4623   if (GET_CODE (operands[1]) != MEM)
4624     FAIL;
4625   addr = XEXP (operands[1], 0);
4626   if (GET_CODE (addr) != PLUS)
4627     FAIL;
4628   reg = XEXP (addr, 0);
4629   const_int = XEXP (addr, 1);
4630   if (! (BASE_REGISTER_RTX_P (reg) && INDEX_REGISTER_RTX_P (operands[2])
4631          && GET_CODE (const_int) == CONST_INT))
4632     FAIL;
4633   emit_move_insn (operands[2], const_int);
4634   emit_move_insn (change_address (operands[1], VOIDmode,
4635                                   gen_rtx_PLUS (SImode, reg, operands[2])),
4636                   operands[0]);
4637   DONE;
4640 (define_expand "movdf"
4641   [(set (match_operand:DF 0 "general_movdst_operand" "")
4642         (match_operand:DF 1 "general_movsrc_operand" ""))]
4643   ""
4644   "
4646   if (prepare_move_operands (operands, DFmode)) DONE;
4647   if (TARGET_SHMEDIA)
4648     {
4649       if (TARGET_SHMEDIA_FPU)
4650         emit_insn (gen_movdf_media (operands[0], operands[1]));
4651       else
4652         emit_insn (gen_movdf_media_nofpu (operands[0], operands[1]));
4653       DONE;
4654     }
4655   if (TARGET_SH4)
4656     {
4657       emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ()));
4658       DONE;
4659     }
4662 ;;This is incompatible with the way gcc uses subregs.
4663 ;;(define_insn "movv2sf_i"
4664 ;;  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,m")
4665 ;;      (match_operand:V2SF 1 "nonimmediate_operand" "f,m,f"))]
4666 ;;  "TARGET_SHMEDIA_FPU
4667 ;;   && (fp_arith_reg_operand (operands[0], V2SFmode)
4668 ;;       || fp_arith_reg_operand (operands[1], V2SFmode))"
4669 ;;  "@
4670 ;;      #
4671 ;;      fld%M1.p        %m1, %0
4672 ;;      fst%M0.p        %m0, %1"
4673 ;;  [(set_attr "type" "*,fload_media,fstore_media")])
4675 (define_insn_and_split "movv2sf_i"
4676   [(set (match_operand:V2SF 0 "general_movdst_operand" "=f,rf,r,m,mf")
4677         (match_operand:V2SF 1 "general_operand" "fm,rfm?,F?,f,rfZ?"))]
4678   "TARGET_SHMEDIA_FPU"
4679   "#"
4680   "TARGET_SHMEDIA_FPU && reload_completed"
4681   [(set (match_dup 0) (match_dup 1))]
4682   "
4684   operands[0] = simplify_gen_subreg (DFmode, operands[0], V2SFmode, 0);
4685   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2SFmode, 0);
4688 (define_expand "movv2sf"
4689   [(set (match_operand:V2SF 0 "general_movdst_operand" "")
4690         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
4691   "TARGET_SHMEDIA_FPU"
4692   "
4694   if (prepare_move_operands (operands, V2SFmode))
4695     DONE;
4698 (define_expand "addv2sf3"
4699   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4700    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4701    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4702   "TARGET_SHMEDIA_FPU"
4703   "
4705   sh_expand_binop_v2sf (PLUS, operands[0], operands[1], operands[2]);
4706   DONE;
4709 (define_expand "subv2sf3"
4710   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4711    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4712    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4713   "TARGET_SHMEDIA_FPU"
4714   "
4716   sh_expand_binop_v2sf (MINUS, operands[0], operands[1], operands[2]);
4717   DONE;
4720 (define_expand "mulv2sf3"
4721   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4722    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4723    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4724   "TARGET_SHMEDIA_FPU"
4725   "
4727   sh_expand_binop_v2sf (MULT, operands[0], operands[1], operands[2]);
4728   DONE;
4731 (define_expand "divv2sf3"
4732   [(match_operand:V2SF 0 "fp_arith_reg_operand" "")
4733    (match_operand:V2SF 1 "fp_arith_reg_operand" "")
4734    (match_operand:V2SF 2 "fp_arith_reg_operand" "")]
4735   "TARGET_SHMEDIA_FPU"
4736   "
4738   sh_expand_binop_v2sf (DIV, operands[0], operands[1], operands[2]);
4739   DONE;
4742 (define_insn_and_split "*movv4sf_i"
4743   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=f,f,m")
4744         (match_operand:V4SF 1 "general_operand" "fZ,m,fZ"))]
4745   "TARGET_SHMEDIA_FPU"
4746   "#"
4747   "&& reload_completed"
4748   [(const_int 0)]
4749   "
4751   int i;
4753   for (i = 0; i < 4/2; i++)
4754     {
4755       rtx x, y;
4757       if (GET_CODE (operands[0]) == MEM)
4758         x = gen_rtx_MEM (V2SFmode,
4759                          plus_constant (XEXP (operands[0], 0),
4760                                         i * GET_MODE_SIZE (V2SFmode)));
4761       else
4762         x = simplify_gen_subreg (V2SFmode, operands[0], V4SFmode, i * 8);
4764       if (GET_CODE (operands[1]) == MEM)
4765         y = gen_rtx_MEM (V2SFmode,
4766                          plus_constant (XEXP (operands[1], 0),
4767                                         i * GET_MODE_SIZE (V2SFmode)));
4768       else
4769         y = simplify_gen_subreg (V2SFmode, operands[1], V4SFmode, i * 8);
4771       emit_insn (gen_movv2sf_i (x, y));
4772     }
4774   DONE;
4776   [(set_attr "length" "8")])
4778 (define_expand "movv4sf"
4779   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
4780         (match_operand:V4SF 1 "general_operand" ""))]
4781   "TARGET_SHMEDIA_FPU"
4782   "
4784   if (prepare_move_operands (operands, V4SFmode))
4785     DONE;
4788 (define_insn_and_split "*movv16sf_i"
4789   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4790         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4791   "TARGET_SHMEDIA_FPU"
4792   "#"
4793   "&& reload_completed"
4794   [(const_int 0)]
4795   "
4797   int i;
4799   for (i = 0; i < 16/2; i++)
4800     {
4801       rtx x,y;
4803       if (GET_CODE (operands[0]) == MEM)
4804         x = gen_rtx_MEM (V2SFmode,
4805                          plus_constant (XEXP (operands[0], 0),
4806                                         i * GET_MODE_SIZE (V2SFmode)));
4807       else
4808         {
4809           x = gen_rtx_SUBREG (V2SFmode, operands[0], i * 8);
4810           alter_subreg (&x);
4811         }
4813       if (GET_CODE (operands[1]) == MEM)
4814         y = gen_rtx_MEM (V2SFmode,
4815                          plus_constant (XEXP (operands[1], 0),
4816                                         i * GET_MODE_SIZE (V2SFmode)));
4817       else
4818         {
4819           y = gen_rtx_SUBREG (V2SFmode, operands[1], i * 8);
4820           alter_subreg (&y);
4821         }
4823       emit_insn (gen_movv2sf_i (x, y));
4824     }
4826   DONE;
4828   [(set_attr "length" "32")])
4830 (define_expand "movv16sf"
4831   [(set (match_operand:V16SF 0 "nonimmediate_operand" "=f,f,m")
4832         (match_operand:V16SF 1 "nonimmediate_operand" "f,m,f"))]
4833   "TARGET_SHMEDIA_FPU"
4834   "
4836   if (prepare_move_operands (operands, V16SFmode))
4837     DONE;
4840 (define_insn "movsf_media"
4841   [(set (match_operand:SF 0 "general_movdst_operand" "=f,f,r,r,r,f,m,r,m")
4842         (match_operand:SF 1 "general_movsrc_operand" "f,rZ,f,r,F,m,f,m,rZ"))]
4843   "TARGET_SHMEDIA_FPU
4844    && (register_operand (operands[0], SFmode)
4845        || sh_register_operand (operands[1], SFmode))"
4846   "@
4847         fmov.s  %1, %0
4848         fmov.ls %N1, %0
4849         fmov.sl %1, %0
4850         add.l   %1, r63, %0
4851         #
4852         fld%M1.s        %m1, %0
4853         fst%M0.s        %m0, %1
4854         ld%M1.l %m1, %0
4855         st%M0.l %m0, %N1"
4856   [(set_attr "type" "fmove_media,fload_media,fpconv_media,arith_media,*,fload_media,fstore_media,load_media,store_media")])
4858 (define_insn "movsf_media_nofpu"
4859   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m")
4860         (match_operand:SF 1 "general_movsrc_operand" "r,F,m,rZ"))]
4861   "TARGET_SHMEDIA
4862    && (register_operand (operands[0], SFmode)
4863        || sh_register_operand (operands[1], SFmode))"
4864   "@
4865         add.l   %1, r63, %0
4866         #
4867         ld%M1.l %m1, %0
4868         st%M0.l %m0, %N1"
4869   [(set_attr "type" "arith_media,*,load_media,store_media")])
4871 (define_split
4872   [(set (match_operand:SF 0 "arith_reg_operand" "")
4873         (match_operand:SF 1 "immediate_operand" ""))]
4874   "TARGET_SHMEDIA && reload_completed
4875    && ! FP_REGISTER_P (true_regnum (operands[0]))"
4876   [(set (match_dup 3) (match_dup 2))]
4877   "
4879   long values;
4880   REAL_VALUE_TYPE value;
4882   REAL_VALUE_FROM_CONST_DOUBLE (value, operands[1]);
4883   REAL_VALUE_TO_TARGET_SINGLE (value, values);
4884   operands[2] = GEN_INT (values);
4886   operands[3] = gen_rtx_REG (DImode, true_regnum (operands[0]));
4889 (define_insn "movsf_i"
4890   [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
4891         (match_operand:SF 1 "general_movsrc_operand"  "r,G,FQ,mr,r,r,l"))]
4892   "TARGET_SH1
4893    && (! TARGET_SH2E
4894        /* ??? We provide some insn so that direct_{load,store}[SFmode] get set */
4895        || (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 3)
4896        || (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 3))
4897    && (arith_reg_operand (operands[0], SFmode)
4898        || arith_reg_operand (operands[1], SFmode))"
4899   "@
4900         mov     %1,%0
4901         mov     #0,%0
4902         mov.l   %1,%0
4903         mov.l   %1,%0
4904         mov.l   %1,%0
4905         lds     %1,%0
4906         sts     %1,%0"
4907   [(set_attr "type" "move,move,pcload,load,store,move,move")])
4909 ;; We may not split the ry/yr/XX alternatives to movsi_ie, since
4910 ;; update_flow_info would not know where to put REG_EQUAL notes
4911 ;; when the destination changes mode.
4912 (define_insn "movsf_ie"
4913   [(set (match_operand:SF 0 "general_movdst_operand"
4914          "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
4915         (match_operand:SF 1 "general_movsrc_operand"
4916           "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
4917    (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"))
4918    (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
4920   "TARGET_SH2E
4921    && (arith_reg_operand (operands[0], SFmode)
4922        || arith_reg_operand (operands[1], SFmode)
4923        || arith_reg_operand (operands[3], SImode)
4924        || (fpul_operand (operands[0], SFmode)
4925            && memory_operand (operands[1], SFmode)
4926            && GET_CODE (XEXP (operands[1], 0)) == POST_INC)
4927        || (fpul_operand (operands[1], SFmode)
4928            && memory_operand (operands[0], SFmode)
4929            && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC))"
4930   "@
4931         fmov    %1,%0
4932         mov     %1,%0
4933         fldi0   %0
4934         fldi1   %0
4935         #
4936         fmov.s  %1,%0
4937         fmov.s  %1,%0
4938         mov.l   %1,%0
4939         mov.l   %1,%0
4940         mov.l   %1,%0
4941         fsts    fpul,%0
4942         flds    %1,fpul
4943         lds.l   %1,%0
4944         #
4945         sts     %1,%0
4946         lds     %1,%0
4947         sts.l   %1,%0
4948         lds.l   %1,%0
4949         ! move optimized away"
4950   [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,store,pcload,load,store,fmove,fmove,load,*,fpul_gp,gp_fpul,store,load,nil")
4951    (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*")
4952    (set_attr "length" "*,*,*,*,4,*,*,*,*,*,2,2,2,4,2,2,2,2,0")
4953    (set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
4954                                            (const_string "single")
4955                                            (const_string "none")))])
4957 (define_split
4958   [(set (match_operand:SF 0 "register_operand" "")
4959         (match_operand:SF 1 "register_operand" ""))
4960    (use (match_operand:PSI 2 "fpscr_operand" ""))
4961    (clobber (reg:SI FPUL_REG))]
4962   "TARGET_SH1"
4963   [(parallel [(set (reg:SF FPUL_REG) (match_dup 1))
4964               (use (match_dup 2))
4965               (clobber (scratch:SI))])
4966    (parallel [(set (match_dup 0) (reg:SF FPUL_REG))
4967               (use (match_dup 2))
4968               (clobber (scratch:SI))])]
4969   "")
4971 (define_expand "movsf"
4972   [(set (match_operand:SF 0 "general_movdst_operand" "")
4973         (match_operand:SF 1 "general_movsrc_operand" ""))]
4974   ""
4975   "
4977   if (prepare_move_operands (operands, SFmode))
4978     DONE;
4979   if (TARGET_SHMEDIA)
4980     {
4981       if (TARGET_SHMEDIA_FPU)
4982         emit_insn (gen_movsf_media (operands[0], operands[1]));
4983       else
4984         emit_insn (gen_movsf_media_nofpu (operands[0], operands[1]));
4985       DONE;
4986     }
4987   if (TARGET_SH2E)
4988     {
4989       emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ()));
4990       DONE;
4991     }
4994 (define_insn "mov_nop"
4995   [(set (match_operand 0 "any_register_operand" "") (match_dup 0))]
4996   "TARGET_SH2E"
4997   ""
4998   [(set_attr "length" "0")
4999    (set_attr "type" "nil")])
5001 (define_expand "reload_insf"
5002   [(parallel [(set (match_operand:SF 0 "register_operand" "=a")
5003                    (match_operand:SF 1 "immediate_operand" "FQ"))
5004               (use (reg:PSI FPSCR_REG))
5005               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5006   "TARGET_SH1"
5007   "")
5009 (define_expand "reload_insi"
5010   [(parallel [(set (match_operand:SF 0 "register_operand" "=y")
5011                    (match_operand:SF 1 "immediate_operand" "FQ"))
5012               (clobber (match_operand:SI 2 "register_operand" "=&z"))])]
5013   "TARGET_SH1"
5014   "")
5016 (define_insn "*movsi_y"
5017   [(set (match_operand:SI 0 "register_operand" "=y,y")
5018         (match_operand:SI 1 "immediate_operand" "Qi,I08"))
5019    (clobber (match_scratch:SI 2 "=&z,r"))]
5020   "TARGET_SH2E
5021    && (reload_in_progress || reload_completed)"
5022   "#"
5023   [(set_attr "length" "4")
5024    (set_attr "type" "pcload,move")])
5026 (define_split
5027   [(set (match_operand:SI 0 "register_operand" "")
5028         (match_operand:SI 1 "immediate_operand" ""))
5029    (clobber (match_operand:SI 2 "register_operand" ""))]
5030   "TARGET_SH1"
5031   [(set (match_dup 2) (match_dup 1))
5032    (set (match_dup 0) (match_dup 2))]
5033   "")
5035 (define_split
5036   [(set (match_operand:SI 0 "register_operand" "")
5037         (match_operand:SI 1 "memory_operand" ""))
5038    (clobber (reg:SI R0_REG))]
5039   "TARGET_SH1"
5040   [(set (match_dup 0) (match_dup 1))]
5041   "")
5043 ;; ------------------------------------------------------------------------
5044 ;; Define the real conditional branch instructions.
5045 ;; ------------------------------------------------------------------------
5047 (define_insn "branch_true"
5048   [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
5049                            (label_ref (match_operand 0 "" ""))
5050                            (pc)))]
5051   "TARGET_SH1"
5052   "* return output_branch (1, insn, operands);"
5053   [(set_attr "type" "cbranch")])
5055 (define_insn "branch_false"
5056   [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
5057                            (label_ref (match_operand 0 "" ""))
5058                            (pc)))]
5059   "TARGET_SH1"
5060   "* return output_branch (0, insn, operands);"
5061   [(set_attr "type" "cbranch")])
5063 ;; Patterns to prevent reorg from re-combining a condbranch with a branch
5064 ;; which destination is too far away.
5065 ;; The const_int_operand is distinct for each branch target; it avoids
5066 ;; unwanted matches with redundant_insn.
5067 (define_insn "block_branch_redirect"
5068   [(set (pc) (unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BBR))]
5069   "TARGET_SH1"
5070   ""
5071   [(set_attr "length" "0")])
5073 ;; This one has the additional purpose to record a possible scratch register
5074 ;; for the following branch.
5075 ;; ??? Unfortunately, just setting the scratch register is not good enough,
5076 ;; because the insn then might be deemed dead and deleted.  And we can't
5077 ;; make the use in the jump insn explicit because that would disable
5078 ;; delay slot scheduling from the target.
5079 (define_insn "indirect_jump_scratch"
5080   [(set (match_operand:SI 0 "register_operand" "=r")
5081         (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
5082    (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
5083   "TARGET_SH1"
5084   ""
5085   [(set_attr "length" "0")])
5087 ;; This one is used to preemt an insn from beyond the bra / braf / jmp
5088 ;; being pulled into the delay slot of a condbranch that has been made to
5089 ;; jump around the unconditional jump because it was out of range.
5090 (define_insn "stuff_delay_slot"
5091   [(set (pc)
5092         (unspec [(match_operand 0 "const_int_operand" "") (pc)] UNSPEC_BBR))
5093    (set (reg:SI T_REG) (match_operand 1 "const_int_operand" ""))]
5094   "TARGET_SH1"
5095   ""
5096   [(set_attr "length" "0")
5097    (set_attr "cond_delay_slot" "yes")])
5099 ;; Conditional branch insns
5101 (define_expand "beq_media"
5102   [(set (pc)
5103         (if_then_else (eq (match_operand:DI 1 "arith_reg_operand" "r,r")
5104                           (match_operand:DI 2 "arith_operand" "r,I06"))
5105                       (label_ref:DI (match_operand 0 "" ""))
5106                       (pc)))]
5107   "TARGET_SHMEDIA"
5108   "")
5110 (define_insn "*beq_media_i"
5111   [(set (pc)
5112         (if_then_else (match_operator 3 "equality_comparison_operator"
5113                         [(match_operand:DI 1 "arith_reg_operand" "r,r")
5114                          (match_operand:DI 2 "arith_operand" "r,I06")])
5115                       (match_operand:DI 0 "target_operand" "b,b")
5116                       (pc)))]
5117   "TARGET_SHMEDIA"
5118   "@
5119         b%o3%'  %1, %2, %0
5120         b%o3i%' %1, %2, %0"
5121   [(set_attr "type" "cbranch_media")])
5123 (define_expand "bne_media"
5124   [(set (pc)
5125         (if_then_else (ne (match_operand:DI 1 "arith_reg_operand" "r,r")
5126                           (match_operand:DI 2 "arith_operand" "r,I06"))
5127                       (label_ref:DI (match_operand 0 "" ""))
5128                       (pc)))]
5129   "TARGET_SHMEDIA"
5130   "")
5132 (define_expand "bgt_media"
5133   [(set (pc)
5134         (if_then_else (gt (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5135                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5136                       (label_ref:DI (match_operand 0 "" ""))
5137                       (pc)))]
5138   "TARGET_SHMEDIA"
5139   "")
5141 (define_expand "bge_media"
5142   [(set (pc)
5143         (if_then_else (ge (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5144                           (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5145                       (label_ref:DI (match_operand 0 "" ""))
5146                       (pc)))]
5147   "TARGET_SHMEDIA"
5148   "")
5150 (define_expand "bgtu_media"
5151   [(set (pc)
5152         (if_then_else (gtu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5153                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5154                       (label_ref:DI (match_operand 0 "" ""))
5155                       (pc)))]
5156   "TARGET_SHMEDIA"
5157   "")
5159 (define_expand "bgeu_media"
5160   [(set (pc)
5161         (if_then_else (geu (match_operand:DI 1 "arith_reg_or_0_operand" "r")
5162                            (match_operand:DI 2 "arith_reg_or_0_operand" "r"))
5163                       (label_ref:DI (match_operand 0 "" ""))
5164                       (pc)))]
5165   "TARGET_SHMEDIA"
5166   "")
5168 (define_insn "*bgt_media_i"
5169   [(set (pc)
5170         (if_then_else (match_operator 3 "greater_comparison_operator"
5171                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5172                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5173                       (match_operand:DI 0 "target_operand" "b")
5174                       (pc)))]
5175   "TARGET_SHMEDIA"
5176   "b%o3%'       %N1, %N2, %0"
5177   [(set_attr "type" "cbranch_media")])
5179 ;; These are only needed to make invert_jump() happy.
5180 (define_insn "*blt_media_i"
5181   [(set (pc)
5182         (if_then_else (match_operator 3 "less_comparison_operator"
5183                         [(match_operand:DI 1 "arith_reg_or_0_operand" "rN")
5184                          (match_operand:DI 2 "arith_reg_or_0_operand" "rN")])
5185                       (match_operand:DI 0 "target_operand" "b")
5186                       (pc)))]
5187   "TARGET_SHMEDIA"
5188   "b%o3%'       %N2, %N1, %0"
5189   [(set_attr "type" "cbranch_media")])
5191 (define_expand "beq"
5192   [(set (pc)
5193         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5194                       (label_ref (match_operand 0 "" ""))
5195                       (pc)))]
5196   ""
5197   "
5199   if (TARGET_SHMEDIA)
5200     {
5201       if (GET_MODE (sh_compare_op0) != DImode)
5202         {
5203           rtx tmp = gen_reg_rtx (DImode);
5205           emit_insn (gen_seq (tmp));
5206           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5207           DONE;
5208         }
5210       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5211       emit_jump_insn (gen_beq_media (operands[0],
5212                                      sh_compare_op0, sh_compare_op1));
5213       DONE;
5214     }
5216   from_compare (operands, EQ);
5219 (define_expand "bne"
5220   [(set (pc)
5221         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5222                       (label_ref (match_operand 0 "" ""))
5223                       (pc)))]
5224   ""
5225   "
5227   if (TARGET_SHMEDIA)
5228     {
5229       if (GET_MODE (sh_compare_op0) != DImode)
5230         {
5231           rtx tmp = gen_reg_rtx (DImode);
5233           emit_insn (gen_seq (tmp));
5234           emit_jump_insn (gen_beq_media (operands[0], tmp, const0_rtx));
5235           DONE;
5236         }
5238       sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5239       emit_jump_insn (gen_bne_media (operands[0],
5240                                      sh_compare_op0, sh_compare_op1));
5241       DONE;
5242     }
5244   from_compare (operands, EQ);
5247 (define_expand "bgt"
5248   [(set (pc)
5249         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5250                       (label_ref (match_operand 0 "" ""))
5251                       (pc)))]
5252   ""
5253   "
5255   if (TARGET_SHMEDIA)
5256     {
5257       if (GET_MODE (sh_compare_op0) != DImode)
5258         {
5259           rtx tmp = gen_reg_rtx (DImode);
5261           emit_insn (gen_sgt (tmp));
5262           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5263           DONE;
5264         }
5266       if (sh_compare_op0 != const0_rtx)
5267         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5268       if (sh_compare_op1 != const0_rtx)
5269         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5270       emit_jump_insn (gen_bgt_media (operands[0],
5271                                      sh_compare_op0, sh_compare_op1));
5272       DONE;
5273     }
5275   from_compare (operands, GT);
5278 (define_expand "blt"
5279   [(set (pc)
5280         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5281                       (label_ref (match_operand 0 "" ""))
5282                       (pc)))]
5283   ""
5284   "
5286   if (TARGET_SHMEDIA)
5287     {
5288       if (GET_MODE (sh_compare_op0) != DImode)
5289         {
5290           rtx tmp = gen_reg_rtx (DImode);
5292           emit_insn (gen_slt (tmp));
5293           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5294           DONE;
5295         }
5297       if (sh_compare_op0 != const0_rtx)
5298         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5299       if (sh_compare_op1 != const0_rtx)
5300         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5301       emit_jump_insn (gen_bgt_media (operands[0],
5302                                      sh_compare_op1, sh_compare_op0));
5303       DONE;
5304     }
5306   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5307     {
5308       rtx tmp = sh_compare_op0;
5309       sh_compare_op0 = sh_compare_op1;
5310       sh_compare_op1 = tmp;
5311       emit_insn (gen_bgt (operands[0]));
5312       DONE;
5313     }
5314   from_compare (operands, GE);
5317 (define_expand "ble"
5318   [(set (pc)
5319         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5320                       (label_ref (match_operand 0 "" ""))
5321                       (pc)))]
5322   ""
5323   "
5325   if (TARGET_SHMEDIA)
5326     {
5327       if (GET_MODE (sh_compare_op0) != DImode)
5328         {
5329           rtx tmp = gen_reg_rtx (DImode);
5331           emit_insn (gen_sle (tmp));
5332           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5333           DONE;
5334         }
5336       if (sh_compare_op0 != const0_rtx)
5337         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5338       if (sh_compare_op1 != const0_rtx)
5339         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5340       emit_jump_insn (gen_bge_media (operands[0],
5341                                      sh_compare_op1, sh_compare_op0));
5342       DONE;
5343     }
5345   if (TARGET_SH2E
5346       && TARGET_IEEE
5347       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5348     {
5349       rtx tmp = sh_compare_op0;
5350       sh_compare_op0 = sh_compare_op1;
5351       sh_compare_op1 = tmp;
5352       emit_insn (gen_bge (operands[0]));
5353       DONE;
5354     }
5355   from_compare (operands, GT);
5358 (define_expand "bge"
5359   [(set (pc)
5360         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5361                       (label_ref (match_operand 0 "" ""))
5362                       (pc)))]
5363   ""
5364   "
5366   if (TARGET_SHMEDIA)
5367     {
5368       if (GET_MODE (sh_compare_op0) != DImode)
5369         {
5370           rtx tmp = gen_reg_rtx (DImode);
5372           emit_insn (gen_sge (tmp));
5373           emit_jump_insn (gen_bne_media (operands[0], tmp, const0_rtx));
5374           DONE;
5375         }
5377       if (sh_compare_op0 != const0_rtx)
5378         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5379       if (sh_compare_op1 != const0_rtx)
5380         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5381       emit_jump_insn (gen_bge_media (operands[0],
5382                                      sh_compare_op0, sh_compare_op1));
5383       DONE;
5384     }
5386   if (TARGET_SH2E
5387       && ! TARGET_IEEE
5388       && GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
5389     {
5390       rtx tmp = sh_compare_op0;
5391       sh_compare_op0 = sh_compare_op1;
5392       sh_compare_op1 = tmp;
5393       emit_insn (gen_ble (operands[0]));
5394       DONE;
5395     }
5396   from_compare (operands, GE);
5399 (define_expand "bgtu"
5400   [(set (pc)
5401         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5402                       (label_ref (match_operand 0 "" ""))
5403                       (pc)))]
5404   ""
5405   "
5407   if (TARGET_SHMEDIA)
5408     {
5409       if (sh_compare_op0 != const0_rtx)
5410         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5411       if (sh_compare_op1 != const0_rtx)
5412         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5413       emit_jump_insn (gen_bgtu_media (operands[0],
5414                                       sh_compare_op0, sh_compare_op1));
5415       DONE;
5416     }
5418   from_compare (operands, GTU);
5421 (define_expand "bltu"
5422   [(set (pc)
5423         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5424                       (label_ref (match_operand 0 "" ""))
5425                       (pc)))]
5426   ""
5427   "
5429   if (TARGET_SHMEDIA)
5430     {
5431       if (sh_compare_op0 != const0_rtx)
5432         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5433       if (sh_compare_op1 != const0_rtx)
5434         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5435       emit_jump_insn (gen_bgtu_media (operands[0],
5436                                       sh_compare_op1, sh_compare_op0));
5437       DONE;
5438     }
5440   from_compare (operands, GEU);
5443 (define_expand "bgeu"
5444   [(set (pc)
5445         (if_then_else (ne (reg:SI T_REG) (const_int 0))
5446                       (label_ref (match_operand 0 "" ""))
5447                       (pc)))]
5448   ""
5449   "
5451   if (TARGET_SHMEDIA)
5452     {
5453       if (sh_compare_op0 != const0_rtx)
5454         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5455       if (sh_compare_op1 != const0_rtx)
5456         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5457       emit_jump_insn (gen_bgeu_media (operands[0],
5458                                       sh_compare_op0, sh_compare_op1));
5459       DONE;
5460     }
5462   from_compare (operands, GEU);
5465 (define_expand "bleu"
5466   [(set (pc)
5467         (if_then_else (eq (reg:SI T_REG) (const_int 0))
5468                       (label_ref (match_operand 0 "" ""))
5469                       (pc)))]
5470   ""
5471   "
5473   if (TARGET_SHMEDIA)
5474     {
5475       if (sh_compare_op0 != const0_rtx)
5476         sh_compare_op0 = force_reg (DImode, sh_compare_op0);
5477       if (sh_compare_op1 != const0_rtx)
5478         sh_compare_op1 = force_reg (DImode, sh_compare_op1);
5479       emit_jump_insn (gen_bgeu_media (operands[0],
5480                                       sh_compare_op1, sh_compare_op0));
5481       DONE;
5482     }
5484   from_compare (operands, GTU);
5487 (define_expand "bunordered"
5488   [(set (match_dup 1) (unordered:DI (match_dup 2) (match_dup 3)))
5489    (set (pc)
5490         (if_then_else (ne (match_dup 1) (const_int 0))
5491                       (label_ref:DI (match_operand 0 "" ""))
5492                       (pc)))]
5493   "TARGET_SHMEDIA"
5494   "
5496   operands[1] = gen_reg_rtx (DImode);
5497   operands[2] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
5498   operands[3] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
5501 ;; ------------------------------------------------------------------------
5502 ;; Jump and linkage insns
5503 ;; ------------------------------------------------------------------------
5505 (define_insn "jump_compact"
5506   [(set (pc)
5507         (label_ref (match_operand 0 "" "")))]
5508   "TARGET_SH1"
5509   "*
5511   /* The length is 16 if the delay slot is unfilled.  */
5512   if (get_attr_length(insn) > 4)
5513     return output_far_jump(insn, operands[0]);
5514   else
5515     return   \"bra      %l0%#\";
5517   [(set_attr "type" "jump")
5518    (set_attr "needs_delay_slot" "yes")])
5520 ;; ??? It would be much saner to explicitly use the scratch register
5521 ;; in the jump insn, and have indirect_jump_scratch only set it,
5522 ;; but fill_simple_delay_slots would refuse to do delay slot filling
5523 ;; from the target then, as it uses simplejump_p.
5524 ;;(define_insn "jump_compact_far"
5525 ;;  [(set (pc)
5526 ;;      (label_ref (match_operand 0 "" "")))
5527 ;;   (use (match_operand 1 "register_operand" "r")]
5528 ;;  "TARGET_SH1"
5529 ;;  "* return output_far_jump(insn, operands[0], operands[1]);"
5530 ;;  [(set_attr "type" "jump")
5531 ;;   (set_attr "needs_delay_slot" "yes")])
5533 (define_insn "jump_media"
5534   [(set (pc)
5535         (match_operand:DI 0 "target_operand" "b"))]
5536   "TARGET_SHMEDIA"
5537   "blink        %0, r63"
5538   [(set_attr "type" "jump_media")])
5540 (define_expand "jump"
5541   [(set (pc)
5542         (label_ref (match_operand 0 "" "")))]
5543   ""
5544   "
5546   if (TARGET_SH1)
5547     emit_jump_insn (gen_jump_compact (operands[0]));
5548   else if (TARGET_SHMEDIA)
5549     {
5550       if (reload_in_progress || reload_completed)
5551         FAIL;
5552       emit_jump_insn (gen_jump_media (gen_rtx_LABEL_REF (DImode,
5553                                                          operands[0])));
5554     }
5555   DONE;
5558 (define_insn "force_mode_for_call"
5559   [(use (reg:PSI FPSCR_REG))]
5560   "TARGET_SHCOMPACT"
5561   ""
5562   [(set_attr "length" "0")
5563    (set (attr "fp_mode")
5564         (if_then_else (eq_attr "fpu_single" "yes")
5565                       (const_string "single") (const_string "double")))])
5567 (define_insn "calli"
5568   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5569          (match_operand 1 "" ""))
5570    (use (reg:PSI FPSCR_REG))
5571    (clobber (reg:SI PR_REG))]
5572   "TARGET_SH1"
5573   "jsr  @%0%#"
5574   [(set_attr "type" "call")
5575    (set (attr "fp_mode")
5576         (if_then_else (eq_attr "fpu_single" "yes")
5577                       (const_string "single") (const_string "double")))
5578    (set_attr "needs_delay_slot" "yes")
5579    (set_attr "fp_set" "unknown")])
5581 ;; This is a pc-rel call, using bsrf, for use with PIC.
5583 (define_insn "calli_pcrel"
5584   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5585          (match_operand 1 "" ""))
5586    (use (reg:PSI FPSCR_REG))
5587    (use (reg:SI PIC_REG))
5588    (use (match_operand 2 "" ""))
5589    (clobber (reg:SI PR_REG))]
5590   "TARGET_SH2"
5591   "bsrf %0\\n%O2:%#"
5592   [(set_attr "type" "call")
5593    (set (attr "fp_mode")
5594         (if_then_else (eq_attr "fpu_single" "yes")
5595                       (const_string "single") (const_string "double")))
5596    (set_attr "needs_delay_slot" "yes")
5597    (set_attr "fp_set" "unknown")])
5599 (define_insn_and_split "call_pcrel"
5600   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
5601          (match_operand 1 "" ""))
5602    (use (reg:PSI FPSCR_REG))
5603    (use (reg:SI PIC_REG))
5604    (clobber (reg:SI PR_REG))
5605    (clobber (match_scratch:SI 2 "=r"))]
5606   "TARGET_SH2"
5607   "#"
5608   "reload_completed"
5609   [(const_int 0)]
5610   "
5612   rtx lab = PATTERN (gen_call_site ());
5614   if (SYMBOL_REF_LOCAL_P (operands[0]))
5615     emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
5616   else
5617     emit_insn (gen_symPLT_label2reg (operands[2], operands[0], lab));
5618   emit_call_insn (gen_calli_pcrel (operands[2], operands[1], lab));
5619   DONE;
5621   [(set_attr "type" "call")
5622    (set (attr "fp_mode")
5623         (if_then_else (eq_attr "fpu_single" "yes")
5624                       (const_string "single") (const_string "double")))
5625    (set_attr "needs_delay_slot" "yes")
5626    (set_attr "fp_set" "unknown")])
5628 (define_insn "call_compact"
5629   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5630          (match_operand 1 "" ""))
5631    (match_operand 2 "immediate_operand" "n")
5632    (use (reg:SI R0_REG))
5633    (use (reg:SI R1_REG))
5634    (use (reg:PSI FPSCR_REG))
5635    (clobber (reg:SI PR_REG))]
5636   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5637   "jsr  @%0%#"
5638   [(set_attr "type" "call")
5639    (set (attr "fp_mode")
5640         (if_then_else (eq_attr "fpu_single" "yes")
5641                       (const_string "single") (const_string "double")))
5642    (set_attr "needs_delay_slot" "yes")])
5644 (define_insn "call_compact_rettramp"
5645   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5646          (match_operand 1 "" ""))
5647    (match_operand 2 "immediate_operand" "n")
5648    (use (reg:SI R0_REG))
5649    (use (reg:SI R1_REG))
5650    (use (reg:PSI FPSCR_REG))
5651    (clobber (reg:SI R10_REG))
5652    (clobber (reg:SI PR_REG))]
5653   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5654   "jsr  @%0%#"
5655   [(set_attr "type" "call")
5656    (set (attr "fp_mode")
5657         (if_then_else (eq_attr "fpu_single" "yes")
5658                       (const_string "single") (const_string "double")))
5659    (set_attr "needs_delay_slot" "yes")])
5661 (define_insn "call_media"
5662   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "b"))
5663          (match_operand 1 "" ""))
5664    (clobber (reg:DI PR_MEDIA_REG))]
5665   "TARGET_SHMEDIA"
5666   "blink        %0, r18"
5667   [(set_attr "type" "jump_media")])
5669 (define_insn "call_valuei"
5670   [(set (match_operand 0 "" "=rf")
5671         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5672               (match_operand 2 "" "")))
5673    (use (reg:PSI FPSCR_REG))
5674    (clobber (reg:SI PR_REG))]
5675   "TARGET_SH1"
5676   "jsr  @%1%#"
5677   [(set_attr "type" "call")
5678    (set (attr "fp_mode")
5679         (if_then_else (eq_attr "fpu_single" "yes")
5680                       (const_string "single") (const_string "double")))
5681    (set_attr "needs_delay_slot" "yes")
5682    (set_attr "fp_set" "unknown")])
5684 (define_insn "call_valuei_pcrel"
5685   [(set (match_operand 0 "" "=rf")
5686         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5687               (match_operand 2 "" "")))
5688    (use (reg:PSI FPSCR_REG))
5689    (use (reg:SI PIC_REG))
5690    (use (match_operand 3 "" ""))
5691    (clobber (reg:SI PR_REG))]
5692   "TARGET_SH2"
5693   "bsrf %1\\n%O3:%#"
5694   [(set_attr "type" "call")
5695    (set (attr "fp_mode")
5696         (if_then_else (eq_attr "fpu_single" "yes")
5697                       (const_string "single") (const_string "double")))
5698    (set_attr "needs_delay_slot" "yes")
5699    (set_attr "fp_set" "unknown")])
5701 (define_insn_and_split "call_value_pcrel"
5702   [(set (match_operand 0 "" "=rf")
5703         (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" ""))
5704               (match_operand 2 "" "")))
5705    (use (reg:PSI FPSCR_REG))
5706    (use (reg:SI PIC_REG))
5707    (clobber (reg:SI PR_REG))
5708    (clobber (match_scratch:SI 3 "=r"))]
5709   "TARGET_SH2"
5710   "#"
5711   "reload_completed"
5712   [(const_int 0)]
5713   "
5715   rtx lab = PATTERN (gen_call_site ());
5717   if (SYMBOL_REF_LOCAL_P (operands[1]))
5718     emit_insn (gen_sym_label2reg (operands[3], operands[1], lab));
5719   else
5720     emit_insn (gen_symPLT_label2reg (operands[3], operands[1], lab));
5721   emit_call_insn (gen_call_valuei_pcrel (operands[0], operands[3],
5722                                          operands[2], lab));
5723   DONE;
5725   [(set_attr "type" "call")
5726    (set (attr "fp_mode")
5727         (if_then_else (eq_attr "fpu_single" "yes")
5728                       (const_string "single") (const_string "double")))
5729    (set_attr "needs_delay_slot" "yes")
5730    (set_attr "fp_set" "unknown")])
5732 (define_insn "call_value_compact"
5733   [(set (match_operand 0 "" "=rf")
5734         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5735               (match_operand 2 "" "")))
5736    (match_operand 3 "immediate_operand" "n")
5737    (use (reg:SI R0_REG))
5738    (use (reg:SI R1_REG))
5739    (use (reg:PSI FPSCR_REG))
5740    (clobber (reg:SI PR_REG))]
5741   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5742   "jsr  @%1%#"
5743   [(set_attr "type" "call")
5744    (set (attr "fp_mode")
5745         (if_then_else (eq_attr "fpu_single" "yes")
5746                       (const_string "single") (const_string "double")))
5747    (set_attr "needs_delay_slot" "yes")])
5749 (define_insn "call_value_compact_rettramp"
5750   [(set (match_operand 0 "" "=rf")
5751         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
5752               (match_operand 2 "" "")))
5753    (match_operand 3 "immediate_operand" "n")
5754    (use (reg:SI R0_REG))
5755    (use (reg:SI R1_REG))
5756    (use (reg:PSI FPSCR_REG))
5757    (clobber (reg:SI R10_REG))
5758    (clobber (reg:SI PR_REG))]
5759   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
5760   "jsr  @%1%#"
5761   [(set_attr "type" "call")
5762    (set (attr "fp_mode")
5763         (if_then_else (eq_attr "fpu_single" "yes")
5764                       (const_string "single") (const_string "double")))
5765    (set_attr "needs_delay_slot" "yes")])
5767 (define_insn "call_value_media"
5768   [(set (match_operand 0 "" "=rf")
5769         (call (mem:DI (match_operand:DI 1 "target_reg_operand" "b"))
5770               (match_operand 2 "" "")))
5771    (clobber (reg:DI PR_MEDIA_REG))]
5772   "TARGET_SHMEDIA"
5773   "blink        %1, r18"
5774   [(set_attr "type" "jump_media")])
5776 (define_expand "call"
5777   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5778                             (match_operand 1 "" ""))
5779               (match_operand 2 "" "")
5780               (use (reg:PSI FPSCR_REG))
5781               (clobber (reg:SI PR_REG))])]
5782   ""
5783   "
5785   if (TARGET_SHMEDIA)
5786     {
5787       operands[0] = XEXP (operands[0], 0);
5788       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
5789         {
5790           if (! SYMBOL_REF_LOCAL_P (operands[0]))
5791             {
5792               rtx reg = gen_reg_rtx (Pmode);
5794               emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5795               operands[0] = reg;
5796             }
5797           else
5798             {
5799               operands[0] = gen_sym2PIC (operands[0]);
5800               PUT_MODE (operands[0], Pmode);
5801             }
5802         }
5803       if (GET_MODE (operands[0]) == SImode)
5804         {
5805           if (GET_CODE (operands[0]) == REG)
5806             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5807           else if (GET_CODE (operands[0]) == SUBREG)
5808             {
5809               operands[0] = SUBREG_REG (operands[0]);
5810               if (GET_MODE (operands[0]) != DImode)
5811                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
5812             }
5813           else
5814             {
5815               operands[0] = shallow_copy_rtx (operands[0]);
5816               PUT_MODE (operands[0], DImode);
5817             }
5818         }
5819       if (! target_reg_operand (operands[0], DImode))
5820         operands[0] = copy_to_mode_reg (DImode, operands[0]);
5821       emit_call_insn (gen_call_media (operands[0], operands[1]));
5822       DONE;
5823     }
5824   else if (TARGET_SHCOMPACT && operands[2] && INTVAL (operands[2]))
5825     {
5826       rtx cookie_rtx = operands[2];
5827       long cookie = INTVAL (cookie_rtx);
5828       rtx func = XEXP (operands[0], 0);
5829       rtx r0, r1;
5831       if (flag_pic)
5832         {
5833           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5834             {
5835               rtx reg = gen_reg_rtx (Pmode);
5837               emit_insn (gen_symGOTPLT2reg (reg, func));
5838               func = reg;
5839             }
5840           else
5841             func = legitimize_pic_address (func, Pmode, 0);
5842         }
5844       r0 = gen_rtx_REG (SImode, R0_REG);
5845       r1 = gen_rtx_REG (SImode, R1_REG);
5847       /* Since such a call function may use all call-clobbered
5848          registers, we force a mode switch earlier, so that we don't
5849          run out of registers when adjusting fpscr for the call.  */
5850       emit_insn (gen_force_mode_for_call ());
5852       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5853       if (flag_pic)
5854         {
5855           rtx reg = gen_reg_rtx (Pmode);
5857           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5858           operands[0] = reg;
5859         }
5860       operands[0] = force_reg (SImode, operands[0]);
5862       emit_move_insn (r0, func);
5863       emit_move_insn (r1, cookie_rtx);
5865       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5866         emit_call_insn (gen_call_compact_rettramp (operands[0], operands[1],
5867                                                    operands[2]));
5868       else
5869         emit_call_insn (gen_call_compact (operands[0], operands[1],
5870                                           operands[2]));
5872       DONE;
5873     }
5874   else if (TARGET_SHCOMPACT && flag_pic
5875            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
5876            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
5877     {
5878       rtx reg = gen_reg_rtx (Pmode);
5880       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[0], 0)));
5881       XEXP (operands[0], 0) = reg;
5882     }
5883   if (flag_pic && TARGET_SH2
5884       && GET_CODE (operands[0]) == MEM
5885       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5886     {
5887       emit_call_insn (gen_call_pcrel (XEXP (operands[0], 0), operands[1]));
5888       DONE;
5889     }
5890   else
5891   {
5892     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
5893     operands[1] = operands[2];
5894   }
5896   emit_call_insn (gen_calli (operands[0], operands[1]));
5897   DONE;
5900 (define_insn "call_pop_compact"
5901   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5902          (match_operand 1 "" ""))
5903    (match_operand 2 "immediate_operand" "n")
5904    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5905                                  (match_operand 3 "immediate_operand" "n")))
5906    (use (reg:SI R0_REG))
5907    (use (reg:SI R1_REG))
5908    (use (reg:PSI FPSCR_REG))
5909    (clobber (reg:SI PR_REG))]
5910   "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5911   "jsr  @%0%#"
5912   [(set_attr "type" "call")
5913    (set (attr "fp_mode")
5914         (if_then_else (eq_attr "fpu_single" "yes")
5915                       (const_string "single") (const_string "double")))
5916    (set_attr "needs_delay_slot" "yes")])
5918 (define_insn "call_pop_compact_rettramp"
5919   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
5920          (match_operand 1 "" ""))
5921    (match_operand 2 "immediate_operand" "n")
5922    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5923                                  (match_operand 3 "immediate_operand" "n")))
5924    (use (reg:SI R0_REG))
5925    (use (reg:SI R1_REG))
5926    (use (reg:PSI FPSCR_REG))
5927    (clobber (reg:SI R10_REG))
5928    (clobber (reg:SI PR_REG))]
5929   "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))"
5930   "jsr  @%0%#"
5931   [(set_attr "type" "call")
5932    (set (attr "fp_mode")
5933         (if_then_else (eq_attr "fpu_single" "yes")
5934                       (const_string "single") (const_string "double")))
5935    (set_attr "needs_delay_slot" "yes")])
5937 (define_expand "call_pop"
5938   [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
5939                     (match_operand 1 "" ""))
5940              (match_operand 2 "" "")
5941              (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
5942                                            (match_operand 3 "" "")))])]
5943   "TARGET_SHCOMPACT"
5944   "
5946   if (operands[2] && INTVAL (operands[2]))
5947     {
5948       rtx cookie_rtx = operands[2];
5949       long cookie = INTVAL (cookie_rtx);
5950       rtx func = XEXP (operands[0], 0);
5951       rtx r0, r1;
5953       if (flag_pic)
5954         {
5955           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
5956             {
5957               rtx reg = gen_reg_rtx (Pmode);
5959               emit_insn (gen_symGOTPLT2reg (reg, func));
5960               func = reg;
5961             }
5962           else
5963             func = legitimize_pic_address (func, Pmode, 0);
5964         }
5966       r0 = gen_rtx_REG (SImode, R0_REG);
5967       r1 = gen_rtx_REG (SImode, R1_REG);
5969       /* Since such a call function may use all call-clobbered
5970          registers, we force a mode switch earlier, so that we don't
5971          run out of registers when adjusting fpscr for the call.  */
5972       emit_insn (gen_force_mode_for_call ());
5974       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
5975       if (flag_pic)
5976         {
5977           rtx reg = gen_reg_rtx (Pmode);
5979           emit_insn (gen_symGOTPLT2reg (reg, operands[0]));
5980           operands[0] = reg;
5981         }
5982       operands[0] = force_reg (SImode, operands[0]);
5984       emit_move_insn (r0, func);
5985       emit_move_insn (r1, cookie_rtx);
5987       if (cookie & CALL_COOKIE_RET_TRAMP (1))
5988         emit_call_insn (gen_call_pop_compact_rettramp
5989                         (operands[0], operands[1], operands[2], operands[3]));
5990       else
5991         emit_call_insn (gen_call_pop_compact
5992                         (operands[0], operands[1], operands[2], operands[3]));
5994       DONE;
5995     }
5997   abort ();
6000 (define_expand "call_value"
6001   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6002                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6003                                  (match_operand 2 "" "")))
6004               (match_operand 3 "" "")
6005               (use (reg:PSI FPSCR_REG))
6006               (clobber (reg:SI PR_REG))])]
6007   ""
6008   "
6010   if (TARGET_SHMEDIA)
6011     {
6012       operands[1] = XEXP (operands[1], 0);
6013       if (flag_pic && GET_CODE (operands[1]) == SYMBOL_REF)
6014         {
6015           if (! SYMBOL_REF_LOCAL_P (operands[1]))
6016             {
6017               rtx reg = gen_reg_rtx (Pmode);
6019               emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6020               operands[1] = reg;
6021             }
6022           else
6023             {
6024               operands[1] = gen_sym2PIC (operands[1]);
6025               PUT_MODE (operands[1], Pmode);
6026             }
6027         }
6028       if (GET_MODE (operands[1]) == SImode)
6029         {
6030           if (GET_CODE (operands[1]) == REG)
6031             operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6032           else if (GET_CODE (operands[1]) == SUBREG)
6033             {
6034               operands[1] = SUBREG_REG (operands[1]);
6035               if (GET_MODE (operands[1]) != DImode)
6036                 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0);
6037             }
6038           else
6039             {
6040               operands[1] = shallow_copy_rtx (operands[1]);
6041               PUT_MODE (operands[1], DImode);
6042             }
6043         }
6044       if (! target_reg_operand (operands[1], DImode))
6045         operands[1] = copy_to_mode_reg (DImode, operands[1]);
6046       emit_call_insn (gen_call_value_media (operands[0], operands[1],
6047                                             operands[2]));
6048       DONE;
6049     }
6050   else if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6051     {
6052       rtx cookie_rtx = operands[3];
6053       long cookie = INTVAL (cookie_rtx);
6054       rtx func = XEXP (operands[1], 0);
6055       rtx r0, r1;
6057       if (flag_pic)
6058         {
6059           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6060             {
6061               rtx reg = gen_reg_rtx (Pmode);
6063               emit_insn (gen_symGOTPLT2reg (reg, func));
6064               func = reg;
6065             }
6066           else
6067             func = legitimize_pic_address (func, Pmode, 0);
6068         }
6070       r0 = gen_rtx_REG (SImode, R0_REG);
6071       r1 = gen_rtx_REG (SImode, R1_REG);
6073       /* Since such a call function may use all call-clobbered
6074          registers, we force a mode switch earlier, so that we don't
6075          run out of registers when adjusting fpscr for the call.  */
6076       emit_insn (gen_force_mode_for_call ());
6078       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6079       if (flag_pic)
6080         {
6081           rtx reg = gen_reg_rtx (Pmode);
6083           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6084           operands[1] = reg;
6085         }
6086       operands[1] = force_reg (SImode, operands[1]);
6088       emit_move_insn (r0, func);
6089       emit_move_insn (r1, cookie_rtx);
6091       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6092         emit_call_insn (gen_call_value_compact_rettramp (operands[0],
6093                                                          operands[1],
6094                                                          operands[2],
6095                                                          operands[3]));
6096       else
6097         emit_call_insn (gen_call_value_compact (operands[0], operands[1],
6098                                                 operands[2], operands[3]));
6100       DONE;
6101     }
6102   else if (TARGET_SHCOMPACT && flag_pic
6103            && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
6104            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[1], 0)))
6105     {
6106       rtx reg = gen_reg_rtx (Pmode);
6108       emit_insn (gen_symGOTPLT2reg (reg, XEXP (operands[1], 0)));
6109       XEXP (operands[1], 0) = reg;
6110     }
6111   if (flag_pic && TARGET_SH2
6112       && GET_CODE (operands[1]) == MEM
6113       && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6114     {
6115       emit_call_insn (gen_call_value_pcrel (operands[0], XEXP (operands[1], 0),
6116                                             operands[2]));
6117       DONE;
6118     }
6119   else
6120     operands[1] = force_reg (SImode, XEXP (operands[1], 0));
6122   emit_call_insn (gen_call_valuei (operands[0], operands[1], operands[2]));
6123   DONE;
6126 (define_insn "sibcalli"
6127   [(call (mem:SI (match_operand:SI 0 "register_operand" "k"))
6128          (match_operand 1 "" ""))
6129    (use (reg:PSI FPSCR_REG))
6130    (return)]
6131   "TARGET_SH1"
6132   "jmp  @%0%#"
6133   [(set_attr "needs_delay_slot" "yes")
6134    (set (attr "fp_mode")
6135         (if_then_else (eq_attr "fpu_single" "yes")
6136                       (const_string "single") (const_string "double")))
6137    (set_attr "type" "jump_ind")])
6139 (define_insn "sibcalli_pcrel"
6140   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k"))
6141          (match_operand 1 "" ""))
6142    (use (match_operand 2 "" ""))
6143    (use (reg:PSI FPSCR_REG))
6144    (return)]
6145   "TARGET_SH2"
6146   "braf %0\\n%O2:%#"
6147   [(set_attr "needs_delay_slot" "yes")
6148    (set (attr "fp_mode")
6149         (if_then_else (eq_attr "fpu_single" "yes")
6150                       (const_string "single") (const_string "double")))
6151    (set_attr "type" "jump_ind")])
6153 (define_insn_and_split "sibcall_pcrel"
6154   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" ""))
6155          (match_operand 1 "" ""))
6156    (use (reg:PSI FPSCR_REG))
6157    (clobber (match_scratch:SI 2 "=k"))
6158    (return)]
6159   "TARGET_SH2"
6160   "#"
6161   "reload_completed"
6162   [(const_int 0)]
6163   "
6165   rtx lab = PATTERN (gen_call_site ());
6166   rtx call_insn;
6168   emit_insn (gen_sym_label2reg (operands[2], operands[0], lab));
6169   call_insn = emit_call_insn (gen_sibcalli_pcrel (operands[2], operands[1],
6170                                                   lab));
6171   SIBLING_CALL_P (call_insn) = 1;
6172   DONE;
6174   [(set_attr "needs_delay_slot" "yes")
6175    (set (attr "fp_mode")
6176         (if_then_else (eq_attr "fpu_single" "yes")
6177                       (const_string "single") (const_string "double")))
6178    (set_attr "type" "jump_ind")])
6180 (define_insn "sibcall_compact"
6181   [(call (mem:SI (match_operand:SI 0 "register_operand" "k,k"))
6182          (match_operand 1 "" ""))
6183    (return)
6184    (use (match_operand:SI 2 "register_operand" "z,x"))
6185    (use (reg:SI R1_REG))
6186    (use (reg:PSI FPSCR_REG))
6187    ;; We want to make sure the `x' above will only match MACH_REG
6188    ;; because sibcall_epilogue may clobber MACL_REG.
6189    (clobber (reg:SI MACL_REG))]
6190   "TARGET_SHCOMPACT"
6191   "@
6192         jmp     @%0%#
6193         jmp     @%0\\n  sts     %2, r0"
6194   [(set_attr "needs_delay_slot" "yes,no")
6195    (set_attr "length" "2,4")
6196    (set (attr "fp_mode") (const_string "single"))
6197    (set_attr "type" "jump_ind")])
6199 (define_insn "sibcall_media"
6200   [(call (mem:DI (match_operand:DI 0 "target_reg_operand" "k"))
6201          (match_operand 1 "" ""))
6202    (use (reg:SI PR_MEDIA_REG))
6203    (return)]
6204   "TARGET_SHMEDIA"
6205   "blink        %0, r63"
6206   [(set_attr "type" "jump_media")])
6208 (define_expand "sibcall"
6209   [(parallel
6210     [(call (mem:SI (match_operand 0 "arith_reg_operand" ""))
6211            (match_operand 1 "" ""))
6212      (match_operand 2 "" "")
6213      (use (reg:PSI FPSCR_REG))
6214      (return)])]
6215   ""
6216   "
6218   if (TARGET_SHMEDIA)
6219     {
6220       operands[0] = XEXP (operands[0], 0);
6221       if (flag_pic && GET_CODE (operands[0]) == SYMBOL_REF)
6222         {
6223           if (! SYMBOL_REF_LOCAL_P (operands[0]))
6224             {
6225               rtx reg = gen_reg_rtx (Pmode);
6227               /* We must not use GOTPLT for sibcalls, because PIC_REG
6228                  must be restored before the PLT code gets to run.  */
6229               emit_insn (gen_symGOT2reg (reg, operands[0]));
6230               operands[0] = reg;
6231             }
6232           else
6233             {
6234               operands[0] = gen_sym2PIC (operands[0]);
6235               PUT_MODE (operands[0], Pmode);
6236             }
6237         }
6238       if (GET_MODE (operands[0]) == SImode)
6239         {
6240           if (GET_CODE (operands[0]) == REG)
6241             operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6242           else if (GET_CODE (operands[0]) == SUBREG)
6243             {
6244               operands[0] = SUBREG_REG (operands[0]);
6245               if (GET_MODE (operands[0]) != DImode)
6246                 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6247             }
6248           else
6249             {
6250               operands[0] = shallow_copy_rtx (operands[0]);
6251               PUT_MODE (operands[0], DImode);
6252             }
6253         }
6254       if (! target_reg_operand (operands[0], DImode))
6255         operands[0] = copy_to_mode_reg (DImode, operands[0]);
6256       emit_call_insn (gen_sibcall_media (operands[0], operands[1]));
6257       DONE;
6258     }
6259   else if (TARGET_SHCOMPACT && operands[2]
6260            && (INTVAL (operands[2]) & ~ CALL_COOKIE_RET_TRAMP (1)))
6261     {
6262       rtx cookie_rtx = operands[2];
6263       long cookie = INTVAL (cookie_rtx);
6264       rtx func = XEXP (operands[0], 0);
6265       rtx mach, r1;
6267       if (flag_pic)
6268         {
6269           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6270             {
6271               rtx reg = gen_reg_rtx (Pmode);
6273               emit_insn (gen_symGOT2reg (reg, func));
6274               func = reg;
6275             }
6276           else
6277             func = legitimize_pic_address (func, Pmode, 0);
6278         }
6280       /* FIXME: if we could tell whether all argument registers are
6281          already taken, we could decide whether to force the use of
6282          MACH_REG or to stick to R0_REG.  Unfortunately, there's no
6283          simple way to tell.  We could use the CALL_COOKIE, but we
6284          can't currently tell a register used for regular argument
6285          passing from one that is unused.  If we leave it up to reload
6286          to decide which register to use, it seems to always choose
6287          R0_REG, which leaves no available registers in SIBCALL_REGS
6288          to hold the address of the trampoline.  */
6289       mach = gen_rtx_REG (SImode, MACH_REG);
6290       r1 = gen_rtx_REG (SImode, R1_REG);
6292       /* Since such a call function may use all call-clobbered
6293          registers, we force a mode switch earlier, so that we don't
6294          run out of registers when adjusting fpscr for the call.  */
6295       emit_insn (gen_force_mode_for_call ());
6297       operands[0] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6298       if (flag_pic)
6299         {
6300           rtx reg = gen_reg_rtx (Pmode);
6302           emit_insn (gen_symGOT2reg (reg, operands[0]));
6303           operands[0] = reg;
6304         }
6305       operands[0] = force_reg (SImode, operands[0]);
6307       /* We don't need a return trampoline, since the callee will
6308          return directly to the upper caller.  */
6309       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6310         {
6311           cookie &= ~ CALL_COOKIE_RET_TRAMP (1);
6312           cookie_rtx = GEN_INT (cookie);
6313         }
6315       emit_move_insn (mach, func);
6316       emit_move_insn (r1, cookie_rtx);
6318       emit_call_insn (gen_sibcall_compact (operands[0], operands[1], mach));
6319       DONE;
6320     }
6321   else if (TARGET_SHCOMPACT && flag_pic
6322            && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6323            && ! SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6324     {
6325       rtx reg = gen_reg_rtx (Pmode);
6327       emit_insn (gen_symGOT2reg (reg, XEXP (operands[0], 0)));
6328       XEXP (operands[0], 0) = reg;
6329     }
6330   if (flag_pic && TARGET_SH2
6331       && GET_CODE (operands[0]) == MEM
6332       && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
6333       /* The PLT needs the PIC register, but the epilogue would have
6334          to restore it, so we can only use PC-relative PIC calls for
6335          static functions.  */
6336       && SYMBOL_REF_LOCAL_P (XEXP (operands[0], 0)))
6337     {
6338       emit_call_insn (gen_sibcall_pcrel (XEXP (operands[0], 0), operands[1]));
6339       DONE;
6340     }
6341   else
6342     operands[0] = force_reg (SImode, XEXP (operands[0], 0));
6344   emit_call_insn (gen_sibcalli (operands[0], operands[1]));
6345   DONE;
6348 (define_expand "sibcall_value"
6349   [(set (match_operand 0 "" "")
6350         (call (match_operand 1 "" "")
6351               (match_operand 2 "" "")))
6352    (match_operand 3 "" "")]
6353   ""
6354   "
6356   emit_call_insn (gen_sibcall (operands[1], operands[2], operands[3]));
6357   DONE;
6360 (define_insn "call_value_pop_compact"
6361   [(set (match_operand 0 "" "=rf")
6362         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6363               (match_operand 2 "" "")))
6364    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6365                                  (match_operand 4 "immediate_operand" "n")))
6366    (match_operand 3 "immediate_operand" "n")
6367    (use (reg:SI R0_REG))
6368    (use (reg:SI R1_REG))
6369    (use (reg:PSI FPSCR_REG))
6370    (clobber (reg:SI PR_REG))]
6371   "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6372   "jsr  @%1%#"
6373   [(set_attr "type" "call")
6374    (set (attr "fp_mode")
6375         (if_then_else (eq_attr "fpu_single" "yes")
6376                       (const_string "single") (const_string "double")))
6377    (set_attr "needs_delay_slot" "yes")])
6379 (define_insn "call_value_pop_compact_rettramp"
6380   [(set (match_operand 0 "" "=rf")
6381         (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))
6382               (match_operand 2 "" "")))
6383    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6384                                  (match_operand 4 "immediate_operand" "n")))
6385    (match_operand 3 "immediate_operand" "n")
6386    (use (reg:SI R0_REG))
6387    (use (reg:SI R1_REG))
6388    (use (reg:PSI FPSCR_REG))
6389    (clobber (reg:SI R10_REG))
6390    (clobber (reg:SI PR_REG))]
6391   "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))"
6392   "jsr  @%1%#"
6393   [(set_attr "type" "call")
6394    (set (attr "fp_mode")
6395         (if_then_else (eq_attr "fpu_single" "yes")
6396                       (const_string "single") (const_string "double")))
6397    (set_attr "needs_delay_slot" "yes")])
6399 (define_expand "call_value_pop"
6400   [(parallel [(set (match_operand 0 "arith_reg_operand" "")
6401                    (call (mem:SI (match_operand 1 "arith_reg_operand" ""))
6402                                  (match_operand 2 "" "")))
6403               (match_operand 3 "" "")
6404               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
6405                                             (match_operand 4 "" "")))])]
6406   "TARGET_SHCOMPACT"
6407   "
6409   if (TARGET_SHCOMPACT && operands[3] && INTVAL (operands[3]))
6410     {
6411       rtx cookie_rtx = operands[3];
6412       long cookie = INTVAL (cookie_rtx);
6413       rtx func = XEXP (operands[1], 0);
6414       rtx r0, r1;
6416       if (flag_pic)
6417         {
6418           if (GET_CODE (func) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (func))
6419             {
6420               rtx reg = gen_reg_rtx (Pmode);
6422               emit_insn (gen_symGOTPLT2reg (reg, func));
6423               func = reg;
6424             }
6425           else
6426             func = legitimize_pic_address (func, Pmode, 0);
6427         }
6429       r0 = gen_rtx_REG (SImode, R0_REG);
6430       r1 = gen_rtx_REG (SImode, R1_REG);
6432       /* Since such a call function may use all call-clobbered
6433          registers, we force a mode switch earlier, so that we don't
6434          run out of registers when adjusting fpscr for the call.  */
6435       emit_insn (gen_force_mode_for_call ());
6437       operands[1] = function_symbol (\"__GCC_shcompact_call_trampoline\");
6438       if (flag_pic)
6439         {
6440           rtx reg = gen_reg_rtx (Pmode);
6442           emit_insn (gen_symGOTPLT2reg (reg, operands[1]));
6443           operands[1] = reg;
6444         }
6445       operands[1] = force_reg (SImode, operands[1]);
6447       emit_move_insn (r0, func);
6448       emit_move_insn (r1, cookie_rtx);
6450       if (cookie & CALL_COOKIE_RET_TRAMP (1))
6451         emit_call_insn (gen_call_value_pop_compact_rettramp
6452                         (operands[0], operands[1], operands[2],
6453                          operands[3], operands[4]));
6454       else
6455         emit_call_insn (gen_call_value_pop_compact
6456                         (operands[0], operands[1], operands[2],
6457                          operands[3], operands[4]));
6459       DONE;
6460     }
6462   abort ();
6465 (define_expand "sibcall_epilogue"
6466   [(return)]
6467   ""
6468   "
6470   sh_expand_epilogue ();
6471   if (TARGET_SHCOMPACT)
6472     {
6473       rtx insn, set;
6475       /* If epilogue clobbers r0, preserve it in macl.  */
6476       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6477         if ((set = single_set (insn))
6478             && GET_CODE (SET_DEST (set)) == REG
6479             && REGNO (SET_DEST (set)) == R0_REG)
6480           {
6481             rtx r0 = gen_rtx_REG (SImode, R0_REG);
6482             rtx tmp = gen_rtx_REG (SImode, MACL_REG);
6483             rtx i;
6485             /* We can't tell at this point whether the sibcall is a
6486                sibcall_compact and, if it is, whether it uses r0 or
6487                mach as operand 2, so let the instructions that
6488                preserve r0 be optimized away if r0 turns out to be
6489                dead.  */
6490             i = emit_insn_before (gen_rtx_SET (SImode, tmp, r0), insn);
6491             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6492                                                REG_NOTES (i));
6493             i = emit_move_insn (r0, tmp);
6494             REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx,
6495                                                REG_NOTES (i));
6496             break;
6497           }
6498     }
6499   DONE;
6502 (define_insn "indirect_jump_compact"
6503   [(set (pc)
6504         (match_operand:SI 0 "arith_reg_operand" "r"))]
6505   "TARGET_SH1"
6506   "jmp  @%0%#"
6507   [(set_attr "needs_delay_slot" "yes")
6508    (set_attr "type" "jump_ind")])
6510 (define_expand "indirect_jump"
6511   [(set (pc)
6512         (match_operand 0 "register_operand" ""))]
6513   ""
6514   "
6516   if (TARGET_SHMEDIA && GET_MODE (operands[0]) == SImode)
6517     operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
6520 ;; The use of operand 1 / 2 helps us distinguish case table jumps
6521 ;; which can be present in structured code from indirect jumps which can not
6522 ;; be present in structured code.  This allows -fprofile-arcs to work.
6524 ;; For SH1 processors.
6525 (define_insn "casesi_jump_1"
6526   [(set (pc)
6527         (match_operand:SI 0 "register_operand" "r"))
6528    (use (label_ref (match_operand 1 "" "")))]
6529   "TARGET_SH1"
6530   "jmp  @%0%#"
6531   [(set_attr "needs_delay_slot" "yes")
6532    (set_attr "type" "jump_ind")])
6534 ;; For all later processors.
6535 (define_insn "casesi_jump_2"
6536   [(set (pc) (plus:SI (match_operand:SI 0 "register_operand" "r")
6537                       (label_ref (match_operand 1 "" ""))))
6538    (use (label_ref (match_operand 2 "" "")))]
6539   "TARGET_SH2
6540    && (! INSN_UID (operands[1]) || prev_real_insn (operands[1]) == insn)"
6541   "braf %0%#"
6542   [(set_attr "needs_delay_slot" "yes")
6543    (set_attr "type" "jump_ind")])
6545 (define_insn "casesi_jump_media"
6546   [(set (pc) (match_operand:DI 0 "target_reg_operand" "b"))
6547    (use (label_ref (match_operand 1 "" "")))]
6548   "TARGET_SHMEDIA"
6549   "blink        %0, r63"
6550   [(set_attr "type" "jump_media")])
6552 ;; Call subroutine returning any type.
6553 ;; ??? This probably doesn't work.
6555 (define_expand "untyped_call"
6556   [(parallel [(call (match_operand 0 "" "")
6557                     (const_int 0))
6558               (match_operand 1 "" "")
6559               (match_operand 2 "" "")])]
6560   "TARGET_SH2E || TARGET_SHMEDIA"
6561   "
6563   int i;
6565   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
6567   for (i = 0; i < XVECLEN (operands[2], 0); i++)
6568     {
6569       rtx set = XVECEXP (operands[2], 0, i);
6570       emit_move_insn (SET_DEST (set), SET_SRC (set));
6571     }
6573   /* The optimizer does not know that the call sets the function value
6574      registers we stored in the result block.  We avoid problems by
6575      claiming that all hard registers are used and clobbered at this
6576      point.  */
6577   emit_insn (gen_blockage ());
6579   DONE;
6582 ;; ------------------------------------------------------------------------
6583 ;; Misc insns
6584 ;; ------------------------------------------------------------------------
6586 (define_insn "dect"
6587   [(set (reg:SI T_REG)
6588         (eq:SI (match_operand:SI 0 "arith_reg_operand" "+r") (const_int 1)))
6589    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
6590   "TARGET_SH2"
6591   "dt   %0"
6592   [(set_attr "type" "arith")])
6594 (define_insn "nop"
6595   [(const_int 0)]
6596   ""
6597   "nop")
6599 ;; Load address of a label. This is only generated by the casesi expand,
6600 ;; and by machine_dependent_reorg (fixing up fp moves).
6601 ;; This must use unspec, because this only works for labels that are
6602 ;; within range,
6604 (define_insn "mova"
6605   [(set (reg:SI R0_REG)
6606         (unspec:SI [(label_ref (match_operand 0 "" ""))] UNSPEC_MOVA))]
6607   "TARGET_SH1"
6608   "mova %O0,r0"
6609   [(set_attr "in_delay_slot" "no")
6610    (set_attr "type" "arith")])
6612 ;; machine_dependent_reorg will make this a `mova'.
6613 (define_insn "mova_const"
6614   [(set (reg:SI R0_REG)
6615         (unspec:SI [(match_operand 0 "immediate_operand" "i")] UNSPEC_MOVA))]
6616   "TARGET_SH1"
6617   "#"
6618   [(set_attr "in_delay_slot" "no")
6619    (set_attr "type" "arith")])
6621 (define_expand "GOTaddr2picreg"
6622   [(set (reg:SI R0_REG)
6623         (unspec:SI [(const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC))]
6624                    UNSPEC_MOVA))
6625    (set (match_dup 0) (const:SI (unspec:SI [(match_dup 1)] UNSPEC_PIC)))
6626    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
6627   "" "
6629   operands[0] = gen_rtx_REG (Pmode, PIC_REG);
6630   operands[1] = gen_rtx_SYMBOL_REF (VOIDmode, GOT_SYMBOL_NAME);
6632   if (TARGET_SH5)
6633     operands[1] = gen_datalabel_ref (operands[1]);
6635   if (TARGET_SHMEDIA)
6636     {
6637       rtx tr = gen_rtx_REG (DImode, TR0_REG);
6638       rtx dipic = operands[0];
6639       rtx lab = PATTERN (gen_call_site ());
6640       rtx insn, equiv;
6642       equiv = operands[1];
6643       operands[1] = gen_rtx_MINUS (DImode,
6644                                    operands[1],
6645                                    gen_rtx_CONST
6646                                    (DImode,
6647                                     gen_rtx_MINUS (DImode,
6648                                                    gen_rtx_CONST (DImode,
6649                                                                   lab),
6650                                                    pc_rtx)));
6651       operands[1] = gen_sym2PIC (operands[1]);
6652       PUT_MODE (operands[1], DImode);
6654       if (GET_MODE (dipic) != DImode)
6655         dipic = gen_rtx_SUBREG (DImode, dipic, 0);
6657       if (TARGET_SHMEDIA64)
6658         emit_insn (gen_movdi_const (dipic, operands[1]));
6659       else
6660         emit_insn (gen_movdi_const_32bit (dipic, operands[1]));
6662       emit_insn (gen_ptrel (tr, dipic, lab));
6664       if (GET_MODE (operands[0]) != GET_MODE (tr))
6665         tr = gen_lowpart (GET_MODE (operands[0]), tr);
6667       insn = emit_move_insn (operands[0], tr);
6669       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, equiv,
6670                                             REG_NOTES (insn));
6672       DONE;
6673     }
6677 (define_insn "*ptb"
6678   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6679         (const:DI (unspec:DI [(match_operand:DI 1 "" "Csy")]
6680                              UNSPEC_DATALABEL)))]
6681   "TARGET_SHMEDIA && flag_pic
6682    && EXTRA_CONSTRAINT_Csy (operands[1])"
6683   "ptb/u        datalabel %1, %0"
6684   [(set_attr "type" "pt_media")
6685    (set_attr "length" "*")])
6687 (define_insn "ptrel"
6688   [(set (match_operand:DI 0 "target_reg_operand" "=b")
6689         (plus:DI (match_operand:DI 1 "register_operand" "r")
6690               (pc)))
6691    (match_operand:DI 2 "" "")]
6692   "TARGET_SHMEDIA"
6693   "%O2: ptrel/u %1, %0"
6694   [(set_attr "type" "ptabs_media")])
6696 (define_expand "builtin_setjmp_receiver"
6697   [(match_operand 0 "" "")]
6698   "flag_pic"
6699   "
6701   emit_insn (gen_GOTaddr2picreg ());
6702   DONE;
6705 (define_expand "call_site"
6706   [(unspec [(match_dup 0)] UNSPEC_CALLER)]
6707   "TARGET_SH1"
6708   "
6710   static HOST_WIDE_INT i = 0;
6711   operands[0] = GEN_INT (i);
6712   i++;
6715 (define_expand "sym_label2reg"
6716   [(set (match_operand:SI 0 "" "")
6717         (const:SI (minus:SI
6718                    (const:SI
6719                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC))
6720                    (const:SI
6721                     (plus:SI
6722                      (match_operand:SI 2 "" "")
6723                      (const_int 2))))))]
6724   "TARGET_SH1" "")
6726 (define_expand "symGOT_load"
6727   [(set (match_dup 2) (match_operand 1 "" ""))
6728    (set (match_dup 3) (plus (match_dup 2) (reg PIC_REG)))
6729    (set (match_operand 0 "" "") (mem (match_dup 3)))]
6730   ""
6731   "
6733   rtx insn;
6735   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6736   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
6738   if (TARGET_SHMEDIA)
6739     {
6740       rtx reg = operands[2];
6742       if (GET_MODE (reg) != DImode)
6743         reg = gen_rtx_SUBREG (DImode, reg, 0);
6745       if (flag_pic > 1)
6746         emit_insn (gen_movdi_const_32bit (reg, operands[1]));
6747       else
6748         emit_insn (gen_movdi_const_16bit (reg, operands[1]));
6749     }
6750   else
6751     emit_move_insn (operands[2], operands[1]);
6753   emit_move_insn (operands[3], gen_rtx_PLUS (Pmode,
6754                                              operands[2],
6755                                              gen_rtx_REG (Pmode, PIC_REG)));
6757   insn = emit_move_insn (operands[0], gen_rtx_MEM (Pmode, operands[3]));
6759   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, XVECEXP (XEXP (operands[1],
6760                                                                   0), 0, 0),
6761                                         REG_NOTES (insn));
6763   DONE;
6766 (define_expand "sym2GOT"
6767   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOT))]
6768   ""
6769   "")
6771 (define_expand "symGOT2reg"
6772   [(match_operand 0 "" "") (match_operand 1 "" "")]
6773   ""
6774   "
6776   rtx gotsym, insn;
6778   gotsym = gen_sym2GOT (operands[1]);
6779   PUT_MODE (gotsym, Pmode);
6780   insn = emit_insn (gen_symGOT_load (operands[0], gotsym));
6782   RTX_UNCHANGING_P (SET_SRC (PATTERN (insn))) = 1;
6784   DONE;
6787 (define_expand "sym2GOTPLT"
6788   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTPLT))]
6789   ""
6790   "")
6792 (define_expand "symGOTPLT2reg"
6793   [(match_operand 0 "" "") (match_operand 1 "" "")]
6794   ""
6795   "
6797   emit_insn (gen_symGOT_load (operands[0], gen_sym2GOTPLT (operands[1])));
6798   DONE;
6801 (define_expand "sym2GOTOFF"
6802   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTOFF))]
6803   ""
6804   "")
6806 (define_expand "symGOTOFF2reg"
6807   [(match_operand 0 "" "") (match_operand 1 "" "")]
6808   ""
6809   "
6811   rtx gotoffsym, insn;
6812   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6814   gotoffsym = gen_sym2GOTOFF (operands[1]);
6815   PUT_MODE (gotoffsym, Pmode);
6816   emit_move_insn (t, gotoffsym);
6817   insn = emit_move_insn (operands[0],
6818                          gen_rtx_PLUS (Pmode, t,
6819                                        gen_rtx_REG (Pmode, PIC_REG)));
6821   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
6822                                         REG_NOTES (insn));
6824   DONE;
6827 (define_expand "symPLT_label2reg"
6828   [(set (match_operand:SI 0 "" "")
6829         (const:SI (minus:SI
6830                    (const:SI
6831                     (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PLT))
6832                    (const:SI
6833                     (minus:SI
6834                      (const:SI (plus:SI
6835                                 (match_operand:SI 2 "" "")
6836                                 (const_int 2)))
6837                      (const:SI (unspec:SI [(pc)] UNSPEC_PIC)))))))
6838    ;; Even though the PIC register is not really used by the call
6839    ;; sequence in which this is expanded, the PLT code assumes the PIC
6840    ;; register is set, so we must not skip its initialization.  Since
6841    ;; we only use this expand as part of calling sequences, and never
6842    ;; to take the address of a function, this is the best point to
6843    ;; insert the (use).  Using the PLT to take the address of a
6844    ;; function would be wrong, not only because the PLT entry could
6845    ;; then be called from a function that doesn't initialize the PIC
6846    ;; register to the proper GOT, but also because pointers to the
6847    ;; same function might not compare equal, should they be set by
6848    ;; different shared libraries.
6849    (use (reg:SI PIC_REG))]
6850   "TARGET_SH1"
6851   "")
6853 (define_expand "sym2PIC"
6854   [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_PIC))]
6855   ""
6856   "")
6858 ;; TLS code generation.
6859 ;; ??? this should be a define_insn_and_split
6860 ;; See the thread [PATCH/RFA] SH TLS support on gcc-patches
6861 ;; <http://gcc.gnu.org/ml/gcc-patches/2003-02/msg01898.html>
6862 ;; for details.
6864 (define_insn "tls_global_dynamic"
6865   [(set (match_operand:SI 0 "register_operand" "=&z")
6866         (unspec:SI [(match_operand:SI 1 "" "")]
6867                     UNSPEC_TLSGD))
6868    (use (reg:PSI FPSCR_REG))
6869    (use (reg:SI PIC_REG))
6870    (clobber (reg:SI PR_REG))
6871    (clobber (scratch:SI))]
6872   "TARGET_SH1"
6873   "*
6875   return \"\\
6876 mov.l\\t1f,r4\\n\\
6877 \\tmova\\t2f,r0\\n\\
6878 \\tmov.l\\t2f,r1\\n\\
6879 \\tadd\\tr0,r1\\n\\
6880 \\tjsr\\t@r1\\n\\
6881 \\tadd\\tr12,r4\\n\\
6882 \\tbra\\t3f\\n\\
6883 \\tnop\\n\\
6884 \\t.align\\t2\\n\\
6885 1:\\t.long\\t%a1@TLSGD\\n\\
6886 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6887 3:\";
6889   [(set_attr "type" "tls_load")
6890    (set_attr "length" "26")])
6892 (define_insn "tls_local_dynamic"
6893   [(set (match_operand:SI 0 "register_operand" "=&z")
6894         (unspec:SI [(match_operand:SI 1 "" "")]
6895                     UNSPEC_TLSLDM))
6896    (use (reg:PSI FPSCR_REG))
6897    (use (reg:SI PIC_REG))
6898    (clobber (reg:SI PR_REG))
6899    (clobber (scratch:SI))]
6900   "TARGET_SH1"
6901   "*
6903   return \"\\
6904 mov.l\\t1f,r4\\n\\
6905 \\tmova\\t2f,r0\\n\\
6906 \\tmov.l\\t2f,r1\\n\\
6907 \\tadd\\tr0,r1\\n\\
6908 \\tjsr\\t@r1\\n\\
6909 \\tadd\\tr12,r4\\n\\
6910 \\tbra\\t3f\\n\\
6911 \\tnop\\n\\
6912 \\t.align\\t2\\n\\
6913 1:\\t.long\\t%a1@TLSLDM\\n\\
6914 2:\\t.long\\t__tls_get_addr@PLT\\n\\
6915 3:\";
6917   [(set_attr "type" "tls_load")
6918    (set_attr "length" "26")])
6920 (define_expand "sym2DTPOFF"
6921   [(const (unspec [(match_operand 0 "" "")] UNSPEC_DTPOFF))]
6922   ""
6923   "")
6925 (define_expand "symDTPOFF2reg"
6926   [(match_operand 0 "" "") (match_operand 1 "" "") (match_operand 2 "" "")]
6927   ""
6928   "
6930   rtx dtpoffsym, insn;
6931   rtx t = no_new_pseudos ? operands[0] : gen_reg_rtx (GET_MODE (operands[0]));
6933   dtpoffsym = gen_sym2DTPOFF (operands[1]);
6934   PUT_MODE (dtpoffsym, Pmode);
6935   emit_move_insn (t, dtpoffsym);
6936   insn = emit_move_insn (operands[0],
6937                          gen_rtx_PLUS (Pmode, t, operands[2]));
6938   DONE;
6941 (define_expand "sym2GOTTPOFF"
6942   [(const (unspec [(match_operand 0 "" "")] UNSPEC_GOTTPOFF))]
6943   ""
6944   "")
6946 (define_insn "tls_initial_exec"
6947   [(set (match_operand:SI 0 "register_operand" "=&r")
6948         (unspec:SI [(match_operand:SI 1 "" "")]
6949                     UNSPEC_TLSIE))
6950    (use (reg:SI GBR_REG))
6951    (use (reg:SI PIC_REG))
6952    (clobber (reg:SI R0_REG))]
6953   ""
6954   "*
6956   return \"\\
6957 mov.l\\t1f,r0\\n\\
6958 \\tstc\\tgbr,%0\\n\\
6959 \\tmov.l\\t@(r0,r12),r0\\n\\
6960 \\tbra\\t2f\\n\\
6961 \\tadd\\tr0,%0\\n\\
6962 \\t.align\\t2\\n\\
6963 1:\\t.long\\t%a1\\n\\
6964 2:\";
6966   [(set_attr "type" "tls_load")
6967    (set_attr "length" "16")])
6969 (define_expand "sym2TPOFF"
6970   [(const (unspec [(match_operand 0 "" "")] UNSPEC_TPOFF))]
6971   ""
6972   "")
6974 (define_expand "symTPOFF2reg"
6975   [(match_operand 0 "" "") (match_operand 1 "" "")]
6976   ""
6977   "
6979   rtx tpoffsym, insn;
6981   tpoffsym = gen_sym2TPOFF (operands[1]);
6982   PUT_MODE (tpoffsym, Pmode);
6983   insn = emit_move_insn (operands[0], tpoffsym);
6984   DONE;
6987 (define_insn "load_gbr"
6988   [(set (match_operand:SI 0 "register_operand" "") (reg:SI GBR_REG))
6989    (use (reg:SI GBR_REG))]
6990   ""
6991   "stc  gbr,%0"
6992   [(set_attr "type" "tls_load")])
6994 ;; case instruction for switch statements.
6996 ;; Operand 0 is index
6997 ;; operand 1 is the minimum bound
6998 ;; operand 2 is the maximum bound - minimum bound + 1
6999 ;; operand 3 is CODE_LABEL for the table;
7000 ;; operand 4 is the CODE_LABEL to go to if index out of range.
7002 (define_expand "casesi"
7003   [(match_operand:SI 0 "arith_reg_operand" "")
7004    (match_operand:SI 1 "arith_reg_operand" "")
7005    (match_operand:SI 2 "arith_reg_operand" "")
7006    (match_operand 3 "" "") (match_operand 4 "" "")]
7007   ""
7008   "
7010   rtx reg = gen_reg_rtx (SImode);
7011   rtx reg2 = gen_reg_rtx (SImode);
7012   if (TARGET_SHMEDIA)
7013     {
7014       rtx reg = gen_reg_rtx (DImode);
7015       rtx reg2 = gen_reg_rtx (DImode);
7016       rtx reg3 = gen_reg_rtx (DImode);
7017       rtx reg4 = gen_reg_rtx (DImode);
7018       rtx reg5 = gen_reg_rtx (DImode);
7020       operands[0] = convert_modes (DImode, SImode, operands[0], 0);
7021       operands[1] = convert_modes (DImode, SImode, operands[1], 0);
7022       operands[2] = convert_modes (DImode, SImode, operands[2], 1);
7024       emit_jump_insn (gen_bgt_media (operands[4], operands[1], operands[0]));
7025       emit_move_insn (reg, gen_rtx_MINUS (DImode, operands[0], operands[1]));
7026       emit_jump_insn (gen_bgtu_media (operands[4], reg, operands[2]));
7027       emit_insn (gen_casesi_shift_media (reg2, reg, operands[3]));
7028       emit_move_insn (reg3, gen_datalabel_ref (gen_rtx_LABEL_REF
7029                                                (DImode, operands[3])));
7030       emit_insn (gen_casesi_load_media (reg4, reg3, reg2, operands[3]));
7031       emit_move_insn (reg5, gen_rtx_PLUS (DImode, reg3, reg4));
7032       emit_jump_insn (gen_casesi_jump_media (reg5, operands[3]));
7033       emit_barrier ();
7034       DONE;
7035     }
7036   operands[1] = copy_to_mode_reg (SImode, operands[1]);
7037   operands[2] = copy_to_mode_reg (SImode, operands[2]);
7038   /* If optimizing, casesi_worker depends on the mode of the instruction
7039      before label it 'uses' - operands[3].  */
7040   emit_insn (gen_casesi_0 (operands[0], operands[1], operands[2], operands[4],
7041                            reg));
7042   emit_insn (gen_casesi_worker_0 (reg2, reg, operands[3]));
7043   if (TARGET_SH2)
7044     emit_jump_insn (gen_casesi_jump_2 (reg2, gen_label_rtx (), operands[3]));
7045   else
7046     emit_jump_insn (gen_casesi_jump_1 (reg2, operands[3]));
7047   /* For SH2 and newer, the ADDR_DIFF_VEC is not actually relative to
7048      operands[3], but to lab.  We will fix this up in
7049      machine_dependent_reorg.  */
7050   emit_barrier ();
7051   DONE;
7054 (define_expand "casesi_0"
7055   [(set (match_operand:SI 4 "" "") (match_operand:SI 0 "arith_reg_operand" ""))
7056    (set (match_dup 4) (minus:SI (match_dup 4)
7057                                 (match_operand:SI 1 "arith_operand" "")))
7058    (set (reg:SI T_REG)
7059         (gtu:SI (match_dup 4)
7060                 (match_operand:SI 2 "arith_reg_operand" "")))
7061    (set (pc)
7062         (if_then_else (ne (reg:SI T_REG)
7063                           (const_int 0))
7064                       (label_ref (match_operand 3 "" ""))
7065                       (pc)))]
7066   "TARGET_SH1"
7067   "")
7069 ;; ??? reload might clobber r0 if we use it explicitly in the RTL before
7070 ;; reload; using a R0_REGS pseudo reg is likely to give poor code.
7071 ;; So we keep the use of r0 hidden in a R0_REGS clobber until after reload.
7073 (define_insn "casesi_worker_0"
7074   [(set (match_operand:SI 0 "register_operand" "=r,r")
7075         (unspec:SI [(match_operand:SI 1 "register_operand" "0,r")
7076                  (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7077    (clobber (match_scratch:SI 3 "=X,1"))
7078    (clobber (match_scratch:SI 4 "=&z,z"))]
7079   "TARGET_SH1"
7080   "#")
7082 (define_split
7083   [(set (match_operand:SI 0 "register_operand" "")
7084         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7085                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7086    (clobber (match_scratch:SI 3 ""))
7087    (clobber (match_scratch:SI 4 ""))]
7088   "TARGET_SH1 && ! TARGET_SH2 && reload_completed"
7089   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7090    (parallel [(set (match_dup 0)
7091               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7092                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7093               (clobber (match_dup 3))])
7094    (set (match_dup 0) (plus:SI (match_dup 0) (reg:SI R0_REG)))]
7095   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7097 (define_split
7098   [(set (match_operand:SI 0 "register_operand" "")
7099         (unspec:SI [(match_operand:SI 1 "register_operand" "")
7100                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7101    (clobber (match_scratch:SI 3 ""))
7102    (clobber (match_scratch:SI 4 ""))]
7103   "TARGET_SH2 && reload_completed"
7104   [(set (reg:SI R0_REG) (unspec:SI [(label_ref (match_dup 2))] UNSPEC_MOVA))
7105    (parallel [(set (match_dup 0)
7106               (unspec:SI [(reg:SI R0_REG) (match_dup 1)
7107                           (label_ref (match_dup 2))] UNSPEC_CASESI))
7108               (clobber (match_dup 3))])]
7109   "if (GET_CODE (operands[2]) == CODE_LABEL) LABEL_NUSES (operands[2])++;")
7111 (define_insn "*casesi_worker"
7112   [(set (match_operand:SI 0 "register_operand" "=r,r")
7113         (unspec:SI [(reg:SI R0_REG)
7114                     (match_operand:SI 1 "register_operand" "0,r")
7115                     (label_ref (match_operand 2 "" ""))] UNSPEC_CASESI))
7116    (clobber (match_scratch:SI 3 "=X,1"))]
7117   "TARGET_SH1"
7118   "*
7120   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7122   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7123     abort ();
7125   switch (GET_MODE (diff_vec))
7126     {
7127     case SImode:
7128       return \"shll2    %1\;mov.l       @(r0,%1),%0\";
7129     case HImode:
7130       return \"add      %1,%1\;mov.w    @(r0,%1),%0\";
7131     case QImode:
7132       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7133         return \"mov.b  @(r0,%1),%0\;extu.b     %0,%0\";
7134       return \"mov.b    @(r0,%1),%0\";
7135     default:
7136       abort ();
7137     }
7139   [(set_attr "length" "4")])
7141 (define_insn "casesi_shift_media"
7142   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7143         (ashift:DI (match_operand:DI 1 "arith_reg_operand" "r")
7144                    (unspec:DI [(label_ref:DI (match_operand 2 "" ""))]
7145                     UNSPEC_CASESI)))]
7146   "TARGET_SHMEDIA"
7147   "*
7149   rtx diff_vec = PATTERN (next_real_insn (operands[2]));
7151   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7152     abort ();
7154   switch (GET_MODE (diff_vec))
7155     {
7156     case SImode:
7157       return \"shlli    %1, 2, %0\";
7158     case HImode:
7159       return \"shlli    %1, 1, %0\";
7160     case QImode:
7161       if (rtx_equal_p (operands[0], operands[1]))
7162         return \"\";
7163       return \"add      %1, r63, %0\";
7164     default:
7165       abort ();
7166     }
7168   [(set_attr "type" "arith_media")])
7170 (define_insn "casesi_load_media"
7171   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
7172         (mem:DI (unspec [(match_operand 1 "arith_reg_operand" "r")
7173                          (match_operand 2 "arith_reg_operand" "r")
7174                          (label_ref:DI (match_operand 3 "" ""))] 2)))]
7175   "TARGET_SHMEDIA"
7176   "*
7178   rtx diff_vec = PATTERN (next_real_insn (operands[3]));
7180   if (GET_CODE (diff_vec) != ADDR_DIFF_VEC)
7181     abort ();
7183   switch (GET_MODE (diff_vec))
7184     {
7185     case SImode:
7186       return \"ldx.l    %1, %2, %0\";
7187     case HImode:
7188 #if 0
7189       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7190         return \"ldx.uw %1, %2, %0\";
7191 #endif
7192       return \"ldx.w    %1, %2, %0\";
7193     case QImode:
7194       if (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned)
7195         return \"ldx.ub %1, %2, %0\";
7196       return \"ldx.b    %1, %2, %0\";
7197     default:
7198       abort ();
7199     }
7201   [(set_attr "type" "load_media")])
7203 (define_expand "return"
7204   [(return)]
7205   "reload_completed && ! sh_need_epilogue ()"
7206   "
7208   if (TARGET_SHMEDIA)
7209     {
7210       emit_jump_insn (gen_return_media ());
7211       DONE;
7212     }
7214   if (TARGET_SHCOMPACT
7215       && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1)))
7216     {
7217       emit_jump_insn (gen_shcompact_return_tramp ());
7218       DONE;
7219     }
7222 (define_insn "*return_i"
7223   [(return)]
7224   "TARGET_SH1 && ! (TARGET_SHCOMPACT
7225                     && (current_function_args_info.call_cookie
7226                         & CALL_COOKIE_RET_TRAMP (1)))
7227    && reload_completed"
7228   "%@   %#"
7229   [(set_attr "type" "return")
7230    (set_attr "needs_delay_slot" "yes")])
7232 (define_expand "shcompact_return_tramp"
7233   [(return)]
7234   "TARGET_SHCOMPACT
7235    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7236   "
7238   rtx reg = gen_rtx_REG (Pmode, R0_REG);
7239   rtx sym = function_symbol (\"__GCC_shcompact_return_trampoline\");
7241   if (flag_pic)
7242     emit_insn (gen_symGOTPLT2reg (reg, sym));
7243   else
7244     emit_move_insn (reg, sym);
7246   emit_jump_insn (gen_shcompact_return_tramp_i ());
7247   DONE;
7250 (define_insn "shcompact_return_tramp_i"
7251   [(parallel [(return) (use (reg:SI R0_REG))])]
7252   "TARGET_SHCOMPACT
7253    && (current_function_args_info.call_cookie & CALL_COOKIE_RET_TRAMP (1))"
7254   "jmp  @r0%#"
7255   [(set_attr "type" "jump_ind")
7256    (set_attr "needs_delay_slot" "yes")])
7258 (define_insn "return_media_i"
7259   [(parallel [(return) (use (match_operand:DI 0 "target_reg_operand" "k"))])]
7260   "TARGET_SHMEDIA && reload_completed"
7261   "blink        %0, r63"
7262   [(set_attr "type" "jump_media")])
7264 (define_insn "return_media_rte"
7265   [(return)]
7266   "TARGET_SHMEDIA && reload_completed && current_function_interrupt"
7267   "rte"
7268   [(set_attr "type" "jump_media")])
7270 (define_expand "return_media"
7271   [(return)]
7272   "TARGET_SHMEDIA && reload_completed"
7273   "
7275   int tr_regno = sh_media_register_for_return ();
7276   rtx tr;
7278   if (current_function_interrupt)
7279     {
7280       emit_jump_insn (gen_return_media_rte ());
7281       DONE;
7282     }
7283   if (tr_regno < 0)
7284     {
7285       rtx r18 = gen_rtx_REG (DImode, PR_MEDIA_REG);
7287       if (! call_used_regs[TR0_REG] || fixed_regs[TR0_REG])
7288         abort ();
7289       tr_regno = TR0_REG;
7290       tr = gen_rtx_REG (DImode, tr_regno);
7291       emit_move_insn (tr, r18);
7292     }
7293   else
7294     tr = gen_rtx_REG (DImode, tr_regno);
7296   emit_jump_insn (gen_return_media_i (tr));
7297   DONE;
7300 (define_insn "shcompact_preserve_incoming_args"
7301   [(set (match_operand:SI 0 "register_operand" "+r")
7302         (unspec:SI [(match_dup 0)] UNSPEC_COMPACT_ARGS))]
7303   "TARGET_SHCOMPACT"
7304   ""
7305   [(set_attr "length" "0")])
7307 (define_insn "shcompact_incoming_args"
7308   [(set (reg:SI R2_REG) (unspec:SI [(reg:SI R2_REG)] UNSPEC_COMPACT_ARGS))
7309    (set (reg:SI R3_REG) (unspec:SI [(reg:SI R3_REG)] UNSPEC_COMPACT_ARGS))
7310    (set (reg:SI R4_REG) (unspec:SI [(reg:SI R4_REG)] UNSPEC_COMPACT_ARGS))
7311    (set (reg:SI R5_REG) (unspec:SI [(reg:SI R5_REG)] UNSPEC_COMPACT_ARGS))
7312    (set (reg:SI R6_REG) (unspec:SI [(reg:SI R6_REG)] UNSPEC_COMPACT_ARGS))
7313    (set (reg:SI R7_REG) (unspec:SI [(reg:SI R7_REG)] UNSPEC_COMPACT_ARGS))
7314    (set (reg:SI R8_REG) (unspec:SI [(reg:SI R8_REG)] UNSPEC_COMPACT_ARGS))
7315    (set (reg:SI R9_REG) (unspec:SI [(reg:SI R9_REG)] UNSPEC_COMPACT_ARGS))
7316    (set (mem:BLK (reg:SI MACL_REG))
7317         (unspec:BLK [(reg:SI MACH_REG)] UNSPEC_COMPACT_ARGS))
7318    (use (reg:SI R0_REG))
7319    (clobber (reg:SI R0_REG))
7320    (clobber (reg:SI MACL_REG))
7321    (clobber (reg:SI MACH_REG))
7322    (clobber (reg:SI PR_REG))]
7323   "TARGET_SHCOMPACT"
7324   "jsr  @r0%#"
7325   [(set_attr "needs_delay_slot" "yes")])
7327 (define_insn "shmedia_save_restore_regs_compact"
7328   [(set (reg:SI SP_REG)
7329         (plus:SI (reg:SI SP_REG)
7330                  (match_operand:SI 0 "immediate_operand" "i")))
7331    (use (reg:SI R0_REG))
7332    (clobber (reg:SI PR_REG))]
7333   "TARGET_SHCOMPACT
7334    && (INTVAL (operands[0]) == SHMEDIA_REGS_STACK_ADJUST ()
7335        || INTVAL (operands[0]) == - SHMEDIA_REGS_STACK_ADJUST ())"
7336   "jsr @r0%#"
7337   [(set_attr "needs_delay_slot" "yes")])
7339 (define_expand "prologue"
7340   [(const_int 0)]
7341   ""
7342   "sh_expand_prologue (); DONE;")
7344 (define_expand "epilogue"
7345   [(return)]
7346   ""
7347   "
7349   sh_expand_epilogue ();
7350   emit_jump_insn (gen_return ());
7351   DONE;
7354 (define_expand "eh_return"
7355   [(use (match_operand 0 "register_operand" ""))]
7356   ""
7358   rtx tmp, ra = operands[0];
7360   if (TARGET_SHMEDIA64)
7361     emit_insn (gen_eh_set_ra_di (ra));
7362   else
7363     emit_insn (gen_eh_set_ra_si (ra));
7365   DONE;
7368 ;; Clobber the return address on the stack.  We can't expand this
7369 ;; until we know where it will be put in the stack frame.
7371 (define_insn "eh_set_ra_si"
7372   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7373    (clobber (match_scratch:SI 1 "=&r"))]
7374   "! TARGET_SHMEDIA64"
7375   "#")
7377 (define_insn "eh_set_ra_di"
7378   [(unspec [(match_operand:DI 0 "register_operand" "r")] UNSPEC_EH_RETURN)
7379    (clobber (match_scratch:DI 1 "=&r"))]
7380   "TARGET_SHMEDIA64"
7381   "#")
7383 (define_split
7384   [(unspec [(match_operand 0 "register_operand" "")] UNSPEC_EH_RETURN)
7385    (clobber (match_scratch 1 ""))]
7386   "reload_completed"
7387   [(const_int 0)]
7388   "
7390   sh_set_return_address (operands[0], operands[1]);
7391   DONE;
7394 (define_insn "blockage"
7395   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7396   ""
7397   ""
7398   [(set_attr "length" "0")])
7400 ;; ------------------------------------------------------------------------
7401 ;; Scc instructions
7402 ;; ------------------------------------------------------------------------
7404 (define_insn "movt"
7405   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
7406         (eq:SI (reg:SI T_REG) (const_int 1)))]
7407   "TARGET_SH1"
7408   "movt %0"
7409   [(set_attr "type" "arith")])
7411 (define_expand "seq"
7412   [(set (match_operand:SI 0 "arith_reg_operand" "")
7413         (match_dup 1))]
7414   ""
7415   "
7417   if (TARGET_SHMEDIA)
7418     {
7419       if (GET_MODE (operands[0]) != DImode)
7420         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7421       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7422       if (sh_compare_op1 != const0_rtx)
7423         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7424                                     ? GET_MODE (sh_compare_op0)
7425                                     : GET_MODE (sh_compare_op1),
7426                                     sh_compare_op1);
7428       switch (GET_MODE (sh_compare_op0))
7429         {
7430         case DImode:
7431           emit_insn (gen_cmpeqdi_media (operands[0],
7432                                         sh_compare_op0, sh_compare_op1));
7433           break;
7435         case SFmode:
7436           if (! TARGET_SHMEDIA_FPU)
7437             FAIL;
7438           emit_insn (gen_cmpeqsf_media (operands[0],
7439                                         sh_compare_op0, sh_compare_op1));
7440           break;
7442         case DFmode:
7443           if (! TARGET_SHMEDIA_FPU)
7444             FAIL;
7445           emit_insn (gen_cmpeqdf_media (operands[0],
7446                                         sh_compare_op0, sh_compare_op1));
7447           break;
7449         default:
7450           FAIL;
7451         }
7452       DONE;
7453     }
7454   if (sh_expand_t_scc (EQ, operands[0]))
7455     DONE;
7456   if (! rtx_equal_function_value_matters)
7457     FAIL;
7458   operands[1] = prepare_scc_operands (EQ);
7461 (define_expand "slt"
7462   [(set (match_operand:SI 0 "arith_reg_operand" "")
7463         (match_dup 1))]
7464   ""
7465   "
7467   if (TARGET_SHMEDIA)
7468     {
7469       if (GET_MODE (operands[0]) != DImode)
7470         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7471       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7472       if (sh_compare_op1 != const0_rtx)
7473         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7474                                     ? GET_MODE (sh_compare_op0)
7475                                     : GET_MODE (sh_compare_op1),
7476                                     sh_compare_op1);
7478       switch (GET_MODE (sh_compare_op0))
7479         {
7480         case DImode:
7481           emit_insn (gen_cmpgtdi_media (operands[0],
7482                                         sh_compare_op1, sh_compare_op0));
7483           break;
7485         case SFmode:
7486           if (! TARGET_SHMEDIA_FPU)
7487             FAIL;
7488           emit_insn (gen_cmpgtsf_media (operands[0],
7489                                         sh_compare_op1, sh_compare_op0));
7490           break;
7492         case DFmode:
7493           if (! TARGET_SHMEDIA_FPU)
7494             FAIL;
7495           emit_insn (gen_cmpgtdf_media (operands[0],
7496                                         sh_compare_op1, sh_compare_op0));
7497           break;
7499         default:
7500           FAIL;
7501         }
7502       DONE;
7503     }
7504   if (! rtx_equal_function_value_matters)
7505     FAIL;
7506   operands[1] = prepare_scc_operands (LT);
7509 (define_expand "sle"
7510   [(match_operand:SI 0 "arith_reg_operand" "")]
7511   ""
7512   "
7514   rtx tmp = sh_compare_op0;
7516   if (TARGET_SHMEDIA)
7517     {
7518       if (GET_MODE (operands[0]) != DImode)
7519         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7520       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7521       if (sh_compare_op1 != const0_rtx)
7522         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7523                                     ? GET_MODE (sh_compare_op0)
7524                                     : GET_MODE (sh_compare_op1),
7525                                     sh_compare_op1);
7527       switch (GET_MODE (sh_compare_op0))
7528         {
7529         case DImode:
7530           {
7531             tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7533             emit_insn (gen_cmpgtdi_media (tmp,
7534                                           sh_compare_op0, sh_compare_op1));
7535             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7536             break;
7537           }
7539         case SFmode:
7540           if (! TARGET_SHMEDIA_FPU)
7541             FAIL;
7542           emit_insn (gen_cmpgesf_media (operands[0],
7543                                         sh_compare_op1, sh_compare_op0));
7544           break;
7546         case DFmode:
7547           if (! TARGET_SHMEDIA_FPU)
7548             FAIL;
7549           emit_insn (gen_cmpgedf_media (operands[0],
7550                                         sh_compare_op1, sh_compare_op0));
7551           break;
7553         default:
7554           FAIL;
7555         }
7556       DONE;
7557     }
7559   sh_compare_op0 = sh_compare_op1;
7560   sh_compare_op1 = tmp;
7561   emit_insn (gen_sge (operands[0]));
7562   DONE;
7565 (define_expand "sgt"
7566   [(set (match_operand:SI 0 "arith_reg_operand" "")
7567         (match_dup 1))]
7568   ""
7569   "
7571   if (TARGET_SHMEDIA)
7572     {
7573       if (GET_MODE (operands[0]) != DImode)
7574         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7575       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7576       if (sh_compare_op1 != const0_rtx)
7577         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7578                                     ? GET_MODE (sh_compare_op0)
7579                                     : GET_MODE (sh_compare_op1),
7580                                     sh_compare_op1);
7582       switch (GET_MODE (sh_compare_op0))
7583         {
7584         case DImode:
7585           emit_insn (gen_cmpgtdi_media (operands[0],
7586                                         sh_compare_op0, sh_compare_op1));
7587           break;
7589         case SFmode:
7590           if (! TARGET_SHMEDIA_FPU)
7591             FAIL;
7592           emit_insn (gen_cmpgtsf_media (operands[0],
7593                                         sh_compare_op0, sh_compare_op1));
7594           break;
7596         case DFmode:
7597           if (! TARGET_SHMEDIA_FPU)
7598             FAIL;
7599           emit_insn (gen_cmpgtdf_media (operands[0],
7600                                         sh_compare_op0, sh_compare_op1));
7601           break;
7603         default:
7604           FAIL;
7605         }
7606       DONE;
7607     }
7608   if (! rtx_equal_function_value_matters)
7609     FAIL;
7610   operands[1] = prepare_scc_operands (GT);
7613 (define_expand "sge"
7614   [(set (match_operand:SI 0 "arith_reg_operand" "")
7615         (match_dup 1))]
7616   ""
7617   "
7619   if (TARGET_SHMEDIA)
7620     {
7621       if (GET_MODE (operands[0]) != DImode)
7622         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7623       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7624       if (sh_compare_op1 != const0_rtx)
7625         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7626                                     ? GET_MODE (sh_compare_op0)
7627                                     : GET_MODE (sh_compare_op1),
7628                                     sh_compare_op1);
7630       switch (GET_MODE (sh_compare_op0))
7631         {
7632         case DImode:
7633           {
7634             rtx tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7636             emit_insn (gen_cmpgtdi_media (tmp,
7637                                           sh_compare_op1, sh_compare_op0));
7638             emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7639             break;
7640           }
7642         case SFmode:
7643           if (! TARGET_SHMEDIA_FPU)
7644             FAIL;
7645           emit_insn (gen_cmpgesf_media (operands[0],
7646                                         sh_compare_op0, sh_compare_op1));
7647           break;
7649         case DFmode:
7650           if (! TARGET_SHMEDIA_FPU)
7651             FAIL;
7652           emit_insn (gen_cmpgedf_media (operands[0],
7653                                         sh_compare_op0, sh_compare_op1));
7654           break;
7656         default:
7657           FAIL;
7658         }
7659       DONE;
7660     }
7662   if (! rtx_equal_function_value_matters)
7663     FAIL;
7664   if (GET_MODE_CLASS (GET_MODE (sh_compare_op0)) == MODE_FLOAT)
7665     {
7666       if (TARGET_IEEE)
7667         {
7668           rtx lab = gen_label_rtx ();
7669           prepare_scc_operands (EQ);
7670           emit_jump_insn (gen_branch_true (lab));
7671           prepare_scc_operands (GT);
7672           emit_label (lab);
7673           emit_insn (gen_movt (operands[0]));
7674         }
7675       else
7676         emit_insn (gen_movnegt (operands[0], prepare_scc_operands (LT)));
7677       DONE;
7678     }
7679   operands[1] = prepare_scc_operands (GE);
7682 (define_expand "sgtu"
7683   [(set (match_operand:SI 0 "arith_reg_operand" "")
7684         (match_dup 1))]
7685   ""
7686   "
7688   if (TARGET_SHMEDIA)
7689     {
7690       if (GET_MODE (operands[0]) != DImode)
7691         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7692       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7693       if (sh_compare_op1 != const0_rtx)
7694         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7695                                     ? GET_MODE (sh_compare_op0)
7696                                     : GET_MODE (sh_compare_op1),
7697                                     sh_compare_op1);
7699       emit_insn (gen_cmpgtudi_media (operands[0],
7700                                      sh_compare_op0, sh_compare_op1));
7701       DONE;
7702     }
7703   if (! rtx_equal_function_value_matters)
7704     FAIL;
7705   operands[1] = prepare_scc_operands (GTU);
7708 (define_expand "sltu"
7709   [(set (match_operand:SI 0 "arith_reg_operand" "")
7710         (match_dup 1))]
7711   ""
7712   "
7714   if (TARGET_SHMEDIA)
7715     {
7716       if (GET_MODE (operands[0]) != DImode)
7717         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7718       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7719       if (sh_compare_op1 != const0_rtx)
7720         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7721                                     ? GET_MODE (sh_compare_op0)
7722                                     : GET_MODE (sh_compare_op1),
7723                                     sh_compare_op1);
7725       emit_insn (gen_cmpgtudi_media (operands[0],
7726                                      sh_compare_op1, sh_compare_op0));
7727       DONE;
7728     }
7729   if (! rtx_equal_function_value_matters)
7730     FAIL;
7731   operands[1] = prepare_scc_operands (LTU);
7734 (define_expand "sleu"
7735   [(set (match_operand:SI 0 "arith_reg_operand" "")
7736         (match_dup 1))]
7737   ""
7738   "
7740   if (TARGET_SHMEDIA)
7741     {
7742       rtx tmp;
7744       if (GET_MODE (operands[0]) != DImode)
7745         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7746       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7747       if (sh_compare_op1 != const0_rtx)
7748         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7749                                     ? GET_MODE (sh_compare_op0)
7750                                     : GET_MODE (sh_compare_op1),
7751                                     sh_compare_op1);
7753       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7755       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op0, sh_compare_op1));
7756       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7758       DONE;
7759     }
7760   if (! rtx_equal_function_value_matters)
7761     FAIL;
7762   operands[1] = prepare_scc_operands (LEU);
7765 (define_expand "sgeu"
7766   [(set (match_operand:SI 0 "arith_reg_operand" "")
7767         (match_dup 1))]
7768   ""
7769   "
7771   if (TARGET_SHMEDIA)
7772     {
7773       rtx tmp;
7775       if (GET_MODE (operands[0]) != DImode)
7776         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7777       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7778       if (sh_compare_op1 != const0_rtx)
7779         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7780                                     ? GET_MODE (sh_compare_op0)
7781                                     : GET_MODE (sh_compare_op1),
7782                                     sh_compare_op1);
7784       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7786       emit_insn (gen_cmpgtudi_media (tmp, sh_compare_op1, sh_compare_op0));
7787       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7789       DONE;
7790     }
7792   if (! rtx_equal_function_value_matters)
7793     FAIL;
7794   operands[1] = prepare_scc_operands (GEU);
7797 ;; sne moves the complement of the T reg to DEST like this:
7798 ;;      cmp/eq ...
7799 ;;      mov    #-1,temp
7800 ;;      negc   temp,dest
7801 ;;   This is better than xoring compare result with 1 because it does
7802 ;;   not require r0 and further, the -1 may be CSE-ed or lifted out of a
7803 ;;   loop.
7805 (define_expand "sne"
7806   [(set (match_dup 2) (const_int -1))
7807    (parallel [(set (match_operand:SI 0 "arith_reg_operand" "")
7808                    (neg:SI (plus:SI (match_dup 1)
7809                                     (match_dup 2))))
7810               (set (reg:SI T_REG)
7811                    (ne:SI (ior:SI (match_dup 1) (match_dup 2))
7812                           (const_int 0)))])]
7813   ""
7814   "
7816   if (TARGET_SHMEDIA)
7817     {
7818       rtx tmp;
7820       if (GET_MODE (operands[0]) != DImode)
7821         operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0);
7823       if (! TARGET_SHMEDIA_FPU && GET_MODE (sh_compare_op0) != DImode)
7824         FAIL;
7826       sh_compare_op0 = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7827       if (sh_compare_op1 != const0_rtx)
7828         sh_compare_op1 = force_reg (GET_MODE (sh_compare_op1) == VOIDmode
7829                                     ? GET_MODE (sh_compare_op0)
7830                                     : GET_MODE (sh_compare_op1),
7831                                     sh_compare_op1);
7833       tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
7835       emit_insn (gen_seq (tmp));
7836       emit_insn (gen_cmpeqdi_media (operands[0], tmp, const0_rtx));
7838       DONE;
7839     }
7841   if (sh_expand_t_scc (NE, operands[0]))
7842     DONE;
7843   if (! rtx_equal_function_value_matters)
7844     FAIL;
7845   operands[1] = prepare_scc_operands (EQ);
7846   operands[2] = gen_reg_rtx (SImode);
7849 (define_expand "sunordered"
7850   [(set (match_operand:DI 0 "arith_reg_operand" "")
7851         (unordered:DI (match_dup 1) (match_dup 2)))]
7852   "TARGET_SHMEDIA_FPU"
7853   "
7855   operands[1] = force_reg (GET_MODE (sh_compare_op0), sh_compare_op0);
7856   operands[2] = force_reg (GET_MODE (sh_compare_op1), sh_compare_op1);
7859 ;; Use the same trick for FP sle / sge
7860 (define_expand "movnegt"
7861   [(set (match_dup 2) (const_int -1))
7862    (parallel [(set (match_operand 0 "" "")
7863                    (neg:SI (plus:SI (match_dup 1)
7864                                     (match_dup 2))))
7865               (set (reg:SI T_REG)
7866                    (ne:SI (ior:SI (match_operand 1 "" "") (match_dup 2))
7867                           (const_int 0)))])]
7868   "TARGET_SH1"
7869   "operands[2] = gen_reg_rtx (SImode);")
7871 ;; Recognize mov #-1/negc/neg sequence, and change it to movt/add #-1.
7872 ;; This prevents a regression that occurred when we switched from xor to
7873 ;; mov/neg for sne.
7875 (define_split
7876   [(set (match_operand:SI 0 "arith_reg_operand" "")
7877         (plus:SI (reg:SI T_REG)
7878                  (const_int -1)))]
7879   "TARGET_SH1"
7880   [(set (match_dup 0) (eq:SI (reg:SI T_REG) (const_int 1)))
7881    (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))]
7882   "")
7884 ;; -------------------------------------------------------------------------
7885 ;; Instructions to cope with inline literal tables
7886 ;; -------------------------------------------------------------------------
7888 ; 2 byte integer in line
7890 (define_insn "consttable_2"
7891  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7892                     (match_operand 1 "" "")]
7893                    UNSPECV_CONST2)]
7894  ""
7895  "*
7897   if (operands[1] != const0_rtx)
7898     assemble_integer (operands[0], 2, BITS_PER_UNIT * 2, 1);
7899   return \"\";
7901  [(set_attr "length" "2")
7902  (set_attr "in_delay_slot" "no")])
7904 ; 4 byte integer in line
7906 (define_insn "consttable_4"
7907  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7908                     (match_operand 1 "" "")]
7909                    UNSPECV_CONST4)]
7910  ""
7911  "*
7913   if (operands[1] != const0_rtx)
7914     assemble_integer (operands[0], 4, BITS_PER_UNIT * 4, 1);
7915   return \"\";
7917  [(set_attr "length" "4")
7918   (set_attr "in_delay_slot" "no")])
7920 ; 8 byte integer in line
7922 (define_insn "consttable_8"
7923  [(unspec_volatile [(match_operand:SI 0 "general_operand" "=g")
7924                     (match_operand 1 "" "")]
7925                    UNSPECV_CONST8)]
7926  ""
7927  "*
7929   if (operands[1] != const0_rtx)
7930     assemble_integer (operands[0], 8, BITS_PER_UNIT * 8, 1);
7931   return \"\";
7933  [(set_attr "length" "8")
7934   (set_attr "in_delay_slot" "no")])
7936 ; 4 byte floating point
7938 (define_insn "consttable_sf"
7939  [(unspec_volatile [(match_operand:SF 0 "general_operand" "=g")
7940                     (match_operand 1 "" "")]
7941                    UNSPECV_CONST4)]
7942  ""
7943  "*
7945   if (operands[1] != const0_rtx)
7946     {
7947       REAL_VALUE_TYPE d;
7948       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7949       assemble_real (d, SFmode, GET_MODE_ALIGNMENT (SFmode));
7950     }
7951   return \"\";
7953  [(set_attr "length" "4")
7954   (set_attr "in_delay_slot" "no")])
7956 ; 8 byte floating point
7958 (define_insn "consttable_df"
7959  [(unspec_volatile [(match_operand:DF 0 "general_operand" "=g")
7960                     (match_operand 1 "" "")]
7961                    UNSPECV_CONST8)]
7962  ""
7963  "*
7965   if (operands[1] != const0_rtx)
7966     {
7967       REAL_VALUE_TYPE d;
7968       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
7969       assemble_real (d, DFmode, GET_MODE_ALIGNMENT (DFmode));
7970     }
7971   return \"\";
7973  [(set_attr "length" "8")
7974   (set_attr "in_delay_slot" "no")])
7976 ;; Alignment is needed for some constant tables; it may also be added for
7977 ;; Instructions at the start of loops, or after unconditional branches.
7978 ;; ??? We would get more accurate lengths if we did instruction
7979 ;; alignment based on the value of INSN_CURRENT_ADDRESS; the approach used
7980 ;; here is too conservative.
7982 ; align to a two byte boundary
7984 (define_expand "align_2"
7985  [(unspec_volatile [(const_int 1)] UNSPECV_ALIGN)]
7986  ""
7987  "")
7989 ; align to a four byte boundary
7990 ;; align_4 and align_log are instructions for the starts of loops, or
7991 ;; after unconditional branches, which may take up extra room.
7993 (define_expand "align_4"
7994  [(unspec_volatile [(const_int 2)] UNSPECV_ALIGN)]
7995  ""
7996  "")
7998 ; align to a cache line boundary
8000 (define_insn "align_log"
8001  [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPECV_ALIGN)]
8002  ""
8003  ""
8004  [(set_attr "length" "0")
8005   (set_attr "in_delay_slot" "no")])
8007 ; emitted at the end of the literal table, used to emit the
8008 ; 32bit branch labels if needed.
8010 (define_insn "consttable_end"
8011   [(unspec_volatile [(const_int 0)] UNSPECV_CONST_END)]
8012   ""
8013   "* return output_jump_label_table ();"
8014   [(set_attr "in_delay_slot" "no")])
8016 ; emitted at the end of the window in the literal table.
8018 (define_insn "consttable_window_end"
8019   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_WINDOW_END)]
8020   ""
8021   ""
8022   [(set_attr "length" "0")
8023    (set_attr "in_delay_slot" "no")])
8025 ;; -------------------------------------------------------------------------
8026 ;; Misc
8027 ;; -------------------------------------------------------------------------
8029 ;; String/block move insn.
8031 (define_expand "movstrsi"
8032   [(parallel [(set (mem:BLK (match_operand:BLK 0 "" ""))
8033                    (mem:BLK (match_operand:BLK 1 "" "")))
8034               (use (match_operand:SI 2 "nonmemory_operand" ""))
8035               (use (match_operand:SI 3 "immediate_operand" ""))
8036               (clobber (reg:SI PR_REG))
8037               (clobber (reg:SI R4_REG))
8038               (clobber (reg:SI R5_REG))
8039               (clobber (reg:SI R0_REG))])]
8040   "TARGET_SH1 && ! TARGET_SH5"
8041   "
8043   if(expand_block_move (operands))
8044      DONE;
8045   else FAIL;
8048 (define_insn "block_move_real"
8049   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8050                    (mem:BLK (reg:SI R5_REG)))
8051               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8052               (clobber (reg:SI PR_REG))
8053               (clobber (reg:SI R0_REG))])]
8054   "TARGET_SH1 && ! TARGET_HARD_SH4"
8055   "jsr  @%0%#"
8056   [(set_attr "type" "sfunc")
8057    (set_attr "needs_delay_slot" "yes")])
8059 (define_insn "block_lump_real"
8060   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8061                    (mem:BLK (reg:SI R5_REG)))
8062               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8063               (use (reg:SI R6_REG))
8064               (clobber (reg:SI PR_REG))
8065               (clobber (reg:SI T_REG))
8066               (clobber (reg:SI R4_REG))
8067               (clobber (reg:SI R5_REG))
8068               (clobber (reg:SI R6_REG))
8069               (clobber (reg:SI R0_REG))])]
8070   "TARGET_SH1 && ! TARGET_HARD_SH4"
8071   "jsr  @%0%#"
8072   [(set_attr "type" "sfunc")
8073    (set_attr "needs_delay_slot" "yes")])
8075 (define_insn "block_move_real_i4"
8076   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8077                    (mem:BLK (reg:SI R5_REG)))
8078               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8079               (clobber (reg:SI PR_REG))
8080               (clobber (reg:SI R0_REG))
8081               (clobber (reg:SI R1_REG))
8082               (clobber (reg:SI R2_REG))])]
8083   "TARGET_HARD_SH4"
8084   "jsr  @%0%#"
8085   [(set_attr "type" "sfunc")
8086    (set_attr "needs_delay_slot" "yes")])
8088 (define_insn "block_lump_real_i4"
8089   [(parallel [(set (mem:BLK (reg:SI R4_REG))
8090                    (mem:BLK (reg:SI R5_REG)))
8091               (use (match_operand:SI 0 "arith_reg_operand" "r"))
8092               (use (reg:SI R6_REG))
8093               (clobber (reg:SI PR_REG))
8094               (clobber (reg:SI T_REG))
8095               (clobber (reg:SI R4_REG))
8096               (clobber (reg:SI R5_REG))
8097               (clobber (reg:SI R6_REG))
8098               (clobber (reg:SI R0_REG))
8099               (clobber (reg:SI R1_REG))
8100               (clobber (reg:SI R2_REG))
8101               (clobber (reg:SI R3_REG))])]
8102   "TARGET_HARD_SH4"
8103   "jsr  @%0%#"
8104   [(set_attr "type" "sfunc")
8105    (set_attr "needs_delay_slot" "yes")])
8107 ;; -------------------------------------------------------------------------
8108 ;; Floating point instructions.
8109 ;; -------------------------------------------------------------------------
8111 ;; ??? All patterns should have a type attribute.
8113 (define_expand "fpu_switch0"
8114   [(set (match_operand:SI 0 "" "") (match_dup 2))
8115    (set (match_dup 1) (mem:PSI (match_dup 0)))]
8116   "TARGET_SH4"
8117   "
8119   operands[1] = get_fpscr_rtx ();
8120   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8121   if (flag_pic)
8122     operands[2] = legitimize_pic_address (operands[2], SImode,
8123                                           no_new_pseudos ? operands[0] : 0);
8126 (define_expand "fpu_switch1"
8127   [(set (match_operand:SI 0 "" "") (match_dup 2))
8128    (set (match_dup 3) (plus:SI (match_dup 0) (const_int 4)))
8129    (set (match_dup 1) (mem:PSI (match_dup 3)))]
8130   "TARGET_SH4"
8131   "
8133   operands[1] = get_fpscr_rtx ();
8134   operands[2] = gen_rtx_SYMBOL_REF (SImode, \"__fpscr_values\");
8135   if (flag_pic)
8136     operands[2] = legitimize_pic_address (operands[2], SImode,
8137                                           no_new_pseudos ? operands[0] : 0);
8138   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
8141 (define_expand "movpsi"
8142   [(set (match_operand:PSI 0 "register_operand" "")
8143         (match_operand:PSI 1 "general_movsrc_operand" ""))]
8144   "TARGET_SH4"
8145   "")
8147 ;; The c / m alternative is a fake to guide reload to load directly into
8148 ;; fpscr, since reload doesn't know how to use post-increment.
8149 ;; GO_IF_LEGITIMATE_ADDRESS guards about bogus addresses before reload,
8150 ;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's
8151 ;; predicate after reload.
8152 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
8153 ;; like a mac -> gpr move.
8154 (define_insn "fpu_switch"
8155   [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
8156         (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
8157   "TARGET_SH2E
8158    && (! reload_completed
8159        || true_regnum (operands[0]) != FPSCR_REG
8160        || GET_CODE (operands[1]) != MEM
8161        || GET_CODE (XEXP (operands[1], 0)) != PLUS)"
8162   "@
8163         ! precision stays the same
8164         lds.l   %1,fpscr
8165         mov.l   %1,%0
8166         #
8167         lds     %1,fpscr
8168         mov     %1,%0
8169         mov.l   %1,%0
8170         sts     fpscr,%0
8171         sts.l   fpscr,%0"
8172   [(set_attr "length" "0,2,2,4,2,2,2,2,2")
8173    (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
8175 (define_split
8176   [(set (reg:PSI FPSCR_REG)
8177         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8178   "TARGET_SH4 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
8179   [(set (match_dup 0) (match_dup 0))]
8180   "
8182   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8183                                         gen_rtx (MEM, PSImode,
8184                                                  gen_rtx (POST_INC, Pmode,
8185                                                           operands[0]))));
8186   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8189 (define_split
8190   [(set (reg:PSI FPSCR_REG)
8191         (mem:PSI (match_operand:SI 0 "register_operand" "")))]
8192   "TARGET_SH4"
8193   [(set (match_dup 0) (plus:SI (match_dup 0) (const_int -4)))]
8194   "
8196   rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
8197                                         gen_rtx (MEM, PSImode,
8198                                                  gen_rtx (POST_INC, Pmode,
8199                                                           operands[0]))));
8200   REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, operands[0], NULL_RTX);
8203 ;; ??? This uses the fp unit, but has no type indicating that.
8204 ;; If we did that, this would either give a bogus latency or introduce
8205 ;; a bogus FIFO constraint.
8206 ;; Since this insn is currently only used for prologues/epilogues,
8207 ;; it is probably best to claim no function unit, which matches the
8208 ;; current setting.
8209 (define_insn "toggle_sz"
8210   [(set (reg:PSI FPSCR_REG)
8211         (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))]
8212   "TARGET_SH4"
8213   "fschg"
8214   [(set_attr "fp_set" "unknown")])
8216 (define_expand "addsf3"
8217   [(set (match_operand:SF 0 "arith_reg_operand" "")
8218         (plus:SF (match_operand:SF 1 "arith_reg_operand" "")
8219                  (match_operand:SF 2 "arith_reg_operand" "")))]
8220   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8221   "
8223   if (TARGET_SH2E)
8224     {
8225       expand_sf_binop (&gen_addsf3_i, operands);
8226       DONE;
8227     }
8230 (define_insn "*addsf3_media"
8231   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8232         (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8233                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8234   "TARGET_SHMEDIA_FPU"
8235   "fadd.s       %1, %2, %0"
8236   [(set_attr "type" "fparith_media")])
8238 (define_insn_and_split "unary_sf_op"
8239   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8240         (vec_select:V2SF
8241          (vec_concat:V2SF
8242           (vec_select:SF
8243            (match_dup 0)
8244            (parallel [(not:BI (match_operand 3 "const_int_operand" "n"))]))
8245           (match_operator:SF 2 "unary_float_operator"
8246             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8247                             (parallel [(match_operand 4
8248                                         "const_int_operand" "n")]))]))
8249          (parallel [(not:BI (match_dup 3)) (match_dup 3)])))]
8250   "TARGET_SHMEDIA_FPU"
8251   "#"
8252   "TARGET_SHMEDIA_FPU && reload_completed"
8253   [(set (match_dup 5) (match_dup 6))]
8254   "
8256   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8257   rtx op1 = gen_rtx_REG (SFmode,
8258                          (true_regnum (operands[1])
8259                           + (INTVAL (operands[4]) ^ endian)));
8261   operands[7] = gen_rtx_REG (SFmode,
8262                              (true_regnum (operands[0])
8263                               + (INTVAL (operands[3]) ^ endian)));
8264   operands[6] = gen_rtx (GET_CODE (operands[2]), SFmode, op1);
8266   [(set_attr "type" "fparith_media")])
8268 (define_insn_and_split "binary_sf_op"
8269   [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
8270         (vec_select:V2SF
8271          (vec_concat:V2SF
8272           (vec_select:SF
8273            (match_dup 0)
8274            (parallel [(match_operand 7 "const_int_operand" "n")]))
8275           (match_operator:SF 3 "binary_float_operator"
8276             [(vec_select:SF (match_operand:V2SF 1 "fp_arith_reg_operand" "f")
8277                             (parallel [(match_operand 5
8278                                         "const_int_operand" "n")]))
8279              (vec_select:SF (match_operand:V2SF 2 "fp_arith_reg_operand" "f")
8280                             (parallel [(match_operand 6
8281                                         "const_int_operand" "n")]))]))
8282          (parallel [(match_dup 7) (match_operand 4 "const_int_operand" "n")])))]
8283   "TARGET_SHMEDIA_FPU && INTVAL (operands[4]) != INTVAL (operands[7])"
8284   "#"
8285   "&& reload_completed"
8286   [(set (match_dup 8) (match_dup 9))]
8287   "
8289   int endian = TARGET_LITTLE_ENDIAN ? 0 : 1;
8290   rtx op1 = gen_rtx_REG (SFmode,
8291                          (true_regnum (operands[1])
8292                           + (INTVAL (operands[5]) ^ endian)));
8293   rtx op2 = gen_rtx_REG (SFmode,
8294                          (true_regnum (operands[2])
8295                           + (INTVAL (operands[6]) ^ endian)));
8297   operands[8] = gen_rtx_REG (SFmode,
8298                              (true_regnum (operands[0])
8299                               + (INTVAL (operands[4]) ^ endian)));
8300   operands[9] = gen_rtx (GET_CODE (operands[3]), SFmode, op1, op2);
8302   [(set_attr "type" "fparith_media")])
8304 (define_insn "addsf3_i"
8305   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8306         (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0")
8307                  (match_operand:SF 2 "arith_reg_operand" "f")))
8308    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8309   "TARGET_SH2E"
8310   "fadd %2,%0"
8311   [(set_attr "type" "fp")
8312    (set_attr "fp_mode" "single")])
8314 (define_expand "subsf3"
8315   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8316         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8317                   (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8318   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8319   "
8321   if (TARGET_SH2E)
8322     {
8323       expand_sf_binop (&gen_subsf3_i, operands);
8324       DONE;
8325     }
8328 (define_insn "*subsf3_media"
8329   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8330         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8331                   (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8332   "TARGET_SHMEDIA_FPU"
8333   "fsub.s       %1, %2, %0"
8334   [(set_attr "type" "fparith_media")])
8336 (define_insn "subsf3_i"
8337   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8338         (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")
8339                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8340    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8341   "TARGET_SH2E"
8342   "fsub %2,%0"
8343   [(set_attr "type" "fp")
8344    (set_attr "fp_mode" "single")])
8346 ;; Unfortunately, the combiner is unable to cope with the USE of the FPSCR
8347 ;; register in feeding fp instructions.  Thus, we cannot generate fmac for
8348 ;; mixed-precision SH4 targets.  To allow it to be still generated for the
8349 ;; SH3E, we use a separate insn for SH3E mulsf3.
8351 (define_expand "mulsf3"
8352   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8353         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "")
8354                  (match_operand:SF 2 "fp_arith_reg_operand" "")))]
8355   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8356   "
8358   if (TARGET_SH4)
8359     expand_sf_binop (&gen_mulsf3_i4, operands);
8360   else if (TARGET_SH2E)
8361     emit_insn (gen_mulsf3_ie (operands[0], operands[1], operands[2]));
8362   if (! TARGET_SHMEDIA)
8363     DONE;
8366 (define_insn "*mulsf3_media"
8367   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8368         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8369                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8370   "TARGET_SHMEDIA_FPU"
8371   "fmul.s       %1, %2, %0"
8372   [(set_attr "type" "fparith_media")])
8374 (define_insn "mulsf3_i4"
8375   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8376         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8377                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))
8378    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8379   "TARGET_SH2E"
8380   "fmul %2,%0"
8381   [(set_attr "type" "fp")
8382    (set_attr "fp_mode" "single")])
8384 (define_insn "mulsf3_ie"
8385   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8386         (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0")
8387                  (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8388   "TARGET_SH2E && ! TARGET_SH4"
8389   "fmul %2,%0"
8390   [(set_attr "type" "fp")])
8392 (define_insn "*mac_media"
8393   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8394         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%f")
8395                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8396                  (match_operand:SF 3 "fp_arith_reg_operand" "0")))]
8397   "TARGET_SHMEDIA_FPU"
8398   "fmac.s %1, %2, %0"
8399   [(set_attr "type" "fparith_media")])
8401 (define_insn "*macsf3"
8402   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8403         (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w")
8404                           (match_operand:SF 2 "fp_arith_reg_operand" "f"))
8405                  (match_operand:SF 3 "arith_reg_operand" "0")))
8406    (use (match_operand:PSI 4 "fpscr_operand" "c"))]
8407   "TARGET_SH2E && ! TARGET_SH4"
8408   "fmac fr0,%2,%0"
8409   [(set_attr "type" "fp")
8410    (set_attr "fp_mode" "single")])
8412 (define_expand "divsf3"
8413   [(set (match_operand:SF 0 "arith_reg_operand" "")
8414         (div:SF (match_operand:SF 1 "arith_reg_operand" "")
8415                 (match_operand:SF 2 "arith_reg_operand" "")))]
8416   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8417   "
8419   if (TARGET_SH2E)
8420     {
8421       expand_sf_binop (&gen_divsf3_i, operands);
8422       DONE;
8423     }
8426 (define_insn "*divsf3_media"
8427   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8428         (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")
8429                 (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8430   "TARGET_SHMEDIA_FPU"
8431   "fdiv.s       %1, %2, %0"
8432   [(set_attr "type" "fdiv_media")])
8434 (define_insn "divsf3_i"
8435   [(set (match_operand:SF 0 "arith_reg_operand" "=f")
8436         (div:SF (match_operand:SF 1 "arith_reg_operand" "0")
8437                  (match_operand:SF 2 "arith_reg_operand" "f")))
8438    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8439   "TARGET_SH2E"
8440   "fdiv %2,%0"
8441   [(set_attr "type" "fdiv")
8442    (set_attr "fp_mode" "single")])
8444 (define_insn "floatdisf2"
8445   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8446         (float:SF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8447   "TARGET_SHMEDIA_FPU"
8448   "float.qs %1, %0"
8449   [(set_attr "type" "fpconv_media")])
8451 (define_expand "floatsisf2"
8452   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8453         (float:SF (match_operand:SI 1 "fpul_operand" "")))]
8454   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8455   "
8457   if (TARGET_SH4)
8458     {
8459       emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8460       DONE;
8461     }
8464 (define_insn "*floatsisf2_media"
8465   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8466         (float:SF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8467   "TARGET_SHMEDIA_FPU"
8468   "float.ls     %1, %0"
8469   [(set_attr "type" "fpconv_media")])
8471 (define_insn "floatsisf2_i4"
8472   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8473         (float:SF (match_operand:SI 1 "fpul_operand" "y")))
8474    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8475   "TARGET_SH4"
8476   "float        %1,%0"
8477   [(set_attr "type" "fp")
8478    (set_attr "fp_mode" "single")])
8480 (define_insn "*floatsisf2_ie"
8481   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8482         (float:SF (match_operand:SI 1 "fpul_operand" "y")))]
8483   "TARGET_SH2E && ! TARGET_SH4"
8484   "float        %1,%0"
8485   [(set_attr "type" "fp")])
8487 (define_insn "fix_truncsfdi2"
8488   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8489         (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8490   "TARGET_SHMEDIA_FPU"
8491   "ftrc.sq %1, %0"
8492   [(set_attr "type" "fpconv_media")])
8494 (define_expand "fix_truncsfsi2"
8495   [(set (match_operand:SI 0 "fpul_operand" "=y")
8496         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8497   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8498   "
8500   if (TARGET_SH4)
8501     {
8502       emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], get_fpscr_rtx ()));
8503       DONE;
8504     }
8507 (define_insn "*fix_truncsfsi2_media"
8508   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8509         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8510   "TARGET_SHMEDIA_FPU"
8511   "ftrc.sl      %1, %0"
8512   [(set_attr "type" "fpconv_media")])
8514 (define_insn "fix_truncsfsi2_i4"
8515   [(set (match_operand:SI 0 "fpul_operand" "=y")
8516         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8517    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8518   "TARGET_SH4"
8519   "ftrc %1,%0"
8520   [(set_attr "type" "ftrc_s")
8521    (set_attr "fp_mode" "single")])
8523 ;; ??? This pattern is used nowhere.  fix_truncsfsi2 always expands to
8524 ;; fix_truncsfsi2_i4.
8525 ;; (define_insn "fix_truncsfsi2_i4_2"
8526 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8527 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8528 ;;   (use (reg:PSI FPSCR_REG))
8529 ;;   (clobber (reg:SI FPUL_REG))]
8530 ;;  "TARGET_SH4"
8531 ;;  "#"
8532 ;;  [(set_attr "length" "4")
8533 ;;   (set_attr "fp_mode" "single")])
8535 ;;(define_split
8536 ;;  [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8537 ;;      (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))
8538 ;;   (use (match_operand:PSI 2 "fpscr_operand" "c"))
8539 ;;   (clobber (reg:SI FPUL_REG))]
8540 ;;  "TARGET_SH4"
8541 ;;  [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8542 ;;            (use (match_dup 2))])
8543 ;;   (set (match_dup 0) (reg:SI FPUL_REG))])
8545 (define_insn "*fixsfsi"
8546   [(set (match_operand:SI 0 "fpul_operand" "=y")
8547         (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8548   "TARGET_SH2E && ! TARGET_SH4"
8549   "ftrc %1,%0"
8550   [(set_attr "type" "fp")])
8552 (define_insn "cmpgtsf_t"
8553   [(set (reg:SI T_REG)
8554         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8555                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8556   "TARGET_SH2E && ! TARGET_SH4"
8557   "fcmp/gt      %1,%0"
8558   [(set_attr "type" "fp")
8559    (set_attr "fp_mode" "single")])
8561 (define_insn "cmpeqsf_t"
8562   [(set (reg:SI T_REG)
8563         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8564                (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8565   "TARGET_SH2E && ! TARGET_SH4"
8566   "fcmp/eq      %1,%0"
8567   [(set_attr "type" "fp")
8568    (set_attr "fp_mode" "single")])
8570 (define_insn "ieee_ccmpeqsf_t"
8571   [(set (reg:SI T_REG)
8572         (ior:SI (reg:SI T_REG)
8573                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8574                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))]
8575   "TARGET_SH2E && TARGET_IEEE && ! TARGET_SH4"
8576   "* return output_ieee_ccmpeq (insn, operands);"
8577   [(set_attr "length" "4")])
8580 (define_insn "cmpgtsf_t_i4"
8581   [(set (reg:SI T_REG)
8582         (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8583                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8584    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8585   "TARGET_SH4"
8586   "fcmp/gt      %1,%0"
8587   [(set_attr "type" "fp")
8588    (set_attr "fp_mode" "single")])
8590 (define_insn "cmpeqsf_t_i4"
8591   [(set (reg:SI T_REG)
8592         (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8593                (match_operand:SF 1 "fp_arith_reg_operand" "f")))
8594    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8595   "TARGET_SH4"
8596   "fcmp/eq      %1,%0"
8597   [(set_attr "type" "fp")
8598    (set_attr "fp_mode" "single")])
8600 (define_insn "*ieee_ccmpeqsf_t_4"
8601   [(set (reg:SI T_REG)
8602         (ior:SI (reg:SI T_REG)
8603                 (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f")
8604                        (match_operand:SF 1 "fp_arith_reg_operand" "f"))))
8605    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8606   "TARGET_IEEE && TARGET_SH4"
8607   "* return output_ieee_ccmpeq (insn, operands);"
8608   [(set_attr "length" "4")
8609    (set_attr "fp_mode" "single")])
8611 (define_insn "cmpeqsf_media"
8612   [(set (match_operand:DI 0 "register_operand" "=r")
8613         (eq:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8614                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8615   "TARGET_SHMEDIA_FPU"
8616   "fcmpeq.s     %1, %2, %0"
8617   [(set_attr "type" "fcmp_media")])
8619 (define_insn "cmpgtsf_media"
8620   [(set (match_operand:DI 0 "register_operand" "=r")
8621         (gt:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8622                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8623   "TARGET_SHMEDIA_FPU"
8624   "fcmpgt.s     %1, %2, %0"
8625   [(set_attr "type" "fcmp_media")])
8627 (define_insn "cmpgesf_media"
8628   [(set (match_operand:DI 0 "register_operand" "=r")
8629         (ge:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8630                (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8631   "TARGET_SHMEDIA_FPU"
8632   "fcmpge.s     %1, %2, %0"
8633   [(set_attr "type" "fcmp_media")])
8635 (define_insn "cmpunsf_media"
8636   [(set (match_operand:DI 0 "register_operand" "=r")
8637         (unordered:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")
8638                       (match_operand:SF 2 "fp_arith_reg_operand" "f")))]
8639   "TARGET_SHMEDIA_FPU"
8640   "fcmpun.s     %1, %2, %0"
8641   [(set_attr "type" "fcmp_media")])
8643 (define_expand "cmpsf"
8644   [(set (reg:SI T_REG)
8645         (compare (match_operand:SF 0 "arith_operand" "")
8646                  (match_operand:SF 1 "arith_operand" "")))]
8647   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8648   "
8650   sh_compare_op0 = operands[0];
8651   sh_compare_op1 = operands[1];
8652   DONE;
8655 (define_expand "negsf2"
8656   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8657         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8658   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8659   "
8661   if (TARGET_SH2E)
8662     {
8663       expand_sf_unop (&gen_negsf2_i, operands);
8664       DONE;
8665     }
8668 (define_insn "*negsf2_media"
8669   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8670         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8671   "TARGET_SHMEDIA_FPU"
8672   "fneg.s       %1, %0"
8673   [(set_attr "type" "fmove_media")])
8675 (define_insn "negsf2_i"
8676   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8677         (neg:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8678    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8679   "TARGET_SH2E"
8680   "fneg %0"
8681   [(set_attr "type" "fmove")
8682    (set_attr "fp_mode" "single")])
8684 (define_expand "sqrtsf2"
8685   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8686         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8687   "TARGET_SH3E || TARGET_SHMEDIA_FPU"
8688   "
8690   if (TARGET_SH3E)
8691     {
8692       expand_sf_unop (&gen_sqrtsf2_i, operands);
8693       DONE;
8694     }
8697 (define_insn "*sqrtsf2_media"
8698   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8699         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8700   "TARGET_SHMEDIA_FPU"
8701   "fsqrt.s      %1, %0"
8702   [(set_attr "type" "fdiv_media")])
8704 (define_insn "sqrtsf2_i"
8705   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8706         (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8707    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8708   "TARGET_SH3E"
8709   "fsqrt        %0"
8710   [(set_attr "type" "fdiv")
8711    (set_attr "fp_mode" "single")])
8713 (define_expand "abssf2"
8714   [(set (match_operand:SF 0 "fp_arith_reg_operand" "")
8715         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
8716   "TARGET_SH2E || TARGET_SHMEDIA_FPU"
8717   "
8719   if (TARGET_SH2E)
8720     {
8721       expand_sf_unop (&gen_abssf2_i, operands);
8722       DONE;
8723     }
8726 (define_insn "*abssf2_media"
8727   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8728         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
8729   "TARGET_SHMEDIA_FPU"
8730   "fabs.s       %1, %0"
8731   [(set_attr "type" "fmove_media")])
8733 (define_insn "abssf2_i"
8734   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
8735         (abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "0")))
8736    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8737   "TARGET_SH2E"
8738   "fabs %0"
8739   [(set_attr "type" "fmove")
8740    (set_attr "fp_mode" "single")])
8742 (define_expand "adddf3"
8743   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8744         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8745                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8746   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8747   "
8749   if (TARGET_SH4)
8750     {
8751       expand_df_binop (&gen_adddf3_i, operands);
8752       DONE;
8753     }
8756 (define_insn "*adddf3_media"
8757   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8758         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8759                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8760   "TARGET_SHMEDIA_FPU"
8761   "fadd.d       %1, %2, %0"
8762   [(set_attr "type" "dfparith_media")])
8764 (define_insn "adddf3_i"
8765   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8766         (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8767                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8768    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8769   "TARGET_SH4"
8770   "fadd %2,%0"
8771   [(set_attr "type" "dfp_arith")
8772    (set_attr "fp_mode" "double")])
8774 (define_expand "subdf3"
8775   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8776         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8777                   (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8778   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8779   "
8781   if (TARGET_SH4)
8782     {
8783       expand_df_binop (&gen_subdf3_i, operands);
8784       DONE;
8785     }
8788 (define_insn "*subdf3_media"
8789   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8790         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8791                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8792   "TARGET_SHMEDIA_FPU"
8793   "fsub.d       %1, %2, %0"
8794   [(set_attr "type" "dfparith_media")])
8796 (define_insn "subdf3_i"
8797   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8798         (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8799                   (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8800    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8801   "TARGET_SH4"
8802   "fsub %2,%0"
8803   [(set_attr "type" "dfp_arith")
8804    (set_attr "fp_mode" "double")])
8806 (define_expand "muldf3"
8807   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8808         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8809                  (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8810   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8811   "
8813   if (TARGET_SH4)
8814     {
8815       expand_df_binop (&gen_muldf3_i, operands);
8816       DONE;
8817     }
8820 (define_insn "*muldf3_media"
8821   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8822         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%f")
8823                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8824   "TARGET_SHMEDIA_FPU"
8825   "fmul.d       %1, %2, %0"
8826   [(set_attr "type" "dfmul_media")])
8828 (define_insn "muldf3_i"
8829   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8830         (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0")
8831                  (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8832    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8833   "TARGET_SH4"
8834   "fmul %2,%0"
8835   [(set_attr "type" "dfp_arith")
8836    (set_attr "fp_mode" "double")])
8838 (define_expand "divdf3"
8839   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8840         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "")
8841                 (match_operand:DF 2 "fp_arith_reg_operand" "")))]
8842   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8843   "
8845   if (TARGET_SH4)
8846     {
8847       expand_df_binop (&gen_divdf3_i, operands);
8848       DONE;
8849     }
8852 (define_insn "*divdf3_media"
8853   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8854         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")
8855                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
8856   "TARGET_SHMEDIA_FPU"
8857   "fdiv.d       %1, %2, %0"
8858   [(set_attr "type" "dfdiv_media")])
8860 (define_insn "divdf3_i"
8861   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8862         (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0")
8863                 (match_operand:DF 2 "fp_arith_reg_operand" "f")))
8864    (use (match_operand:PSI 3 "fpscr_operand" "c"))]
8865   "TARGET_SH4"
8866   "fdiv %2,%0"
8867   [(set_attr "type" "dfdiv")
8868    (set_attr "fp_mode" "double")])
8870 (define_insn "floatdidf2"
8871   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8872         (float:DF (match_operand:DI 1 "fp_arith_reg_operand" "f")))]
8873   "TARGET_SHMEDIA_FPU"
8874   "float.qd     %1, %0"
8875   [(set_attr "type" "dfpconv_media")])
8877 (define_expand "floatsidf2"
8878   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
8879         (float:DF (match_operand:SI 1 "fpul_operand" "")))]
8880   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8881   "
8883   if (TARGET_SH4)
8884     {
8885       emit_df_insn (gen_floatsidf2_i (operands[0], operands[1],
8886                                       get_fpscr_rtx ()));
8887       DONE;
8888     }
8891 (define_insn "*floatsidf2_media"
8892   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8893         (float:DF (match_operand:SI 1 "fp_arith_reg_operand" "f")))]
8894   "TARGET_SHMEDIA_FPU"
8895   "float.ld     %1, %0"
8896   [(set_attr "type" "dfpconv_media")])
8898 (define_insn "floatsidf2_i"
8899   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
8900         (float:DF (match_operand:SI 1 "fpul_operand" "y")))
8901    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8902   "TARGET_SH4"
8903   "float        %1,%0"
8904   [(set_attr "type" "dfp_conv")
8905    (set_attr "fp_mode" "double")])
8907 (define_insn "fix_truncdfdi2"
8908   [(set (match_operand:DI 0 "fp_arith_reg_operand" "=f")
8909         (fix:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8910   "TARGET_SHMEDIA_FPU"
8911   "ftrc.dq      %1, %0"
8912   [(set_attr "type" "dfpconv_media")])
8914 (define_expand "fix_truncdfsi2"
8915   [(set (match_operand:SI 0 "fpul_operand" "")
8916         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "")))]
8917   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
8918   "
8920   if (TARGET_SH4)
8921     {
8922       emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1],
8923                                           get_fpscr_rtx ()));
8924       DONE;
8925     }
8928 (define_insn "*fix_truncdfsi2_media"
8929   [(set (match_operand:SI 0 "fp_arith_reg_operand" "=f")
8930         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
8931   "TARGET_SHMEDIA_FPU"
8932   "ftrc.dl      %1, %0"
8933   [(set_attr "type" "dfpconv_media")])
8935 (define_insn "fix_truncdfsi2_i"
8936   [(set (match_operand:SI 0 "fpul_operand" "=y")
8937         (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f")))
8938    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8939   "TARGET_SH4"
8940   "ftrc %1,%0"
8941   [(set_attr "type" "dfp_conv")
8942    (set_attr "dfp_comp" "no")
8943    (set_attr "fp_mode" "double")])
8945 ;; ??? This pattern is used nowhere.  fix_truncdfsi2 always expands to
8946 ;; fix_truncdfsi2_i.
8947 ;; (define_insn "fix_truncdfsi2_i4"
8948 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8949 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8950 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8951 ;;    (clobber (reg:SI FPUL_REG))]
8952 ;;   "TARGET_SH4"
8953 ;;   "#"
8954 ;;   [(set_attr "length" "4")
8955 ;;    (set_attr "fp_mode" "double")])
8957 ;; (define_split
8958 ;;   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
8959 ;;      (fix:SI (match_operand:DF 1 "arith_reg_operand" "f")))
8960 ;;    (use (match_operand:PSI 2 "fpscr_operand" "c"))
8961 ;;    (clobber (reg:SI FPUL_REG))]
8962 ;;   "TARGET_SH4"
8963 ;;   [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1)))
8964 ;;            (use (match_dup 2))])
8965 ;;    (set (match_dup 0) (reg:SI FPUL_REG))])
8967 (define_insn "cmpgtdf_t"
8968   [(set (reg:SI T_REG)
8969         (gt:SI (match_operand:DF 0 "arith_reg_operand" "f")
8970                (match_operand:DF 1 "arith_reg_operand" "f")))
8971    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8972   "TARGET_SH4"
8973   "fcmp/gt      %1,%0"
8974   [(set_attr "type" "dfp_cmp")
8975    (set_attr "fp_mode" "double")])
8977 (define_insn "cmpeqdf_t"
8978   [(set (reg:SI T_REG)
8979         (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8980                (match_operand:DF 1 "arith_reg_operand" "f")))
8981    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8982   "TARGET_SH4"
8983   "fcmp/eq      %1,%0"
8984   [(set_attr "type" "dfp_cmp")
8985    (set_attr "fp_mode" "double")])
8987 (define_insn "*ieee_ccmpeqdf_t"
8988   [(set (reg:SI T_REG)
8989         (ior:SI (reg:SI T_REG)
8990                 (eq:SI (match_operand:DF 0 "arith_reg_operand" "f")
8991                        (match_operand:DF 1 "arith_reg_operand" "f"))))
8992    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
8993   "TARGET_IEEE && TARGET_SH4"
8994   "* return output_ieee_ccmpeq (insn, operands);"
8995   [(set_attr "length" "4")
8996    (set_attr "fp_mode" "double")])
8998 (define_insn "cmpeqdf_media"
8999   [(set (match_operand:DI 0 "register_operand" "=r")
9000         (eq:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9001                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9002   "TARGET_SHMEDIA_FPU"
9003   "fcmpeq.d     %1,%2,%0"
9004   [(set_attr "type" "fcmp_media")])
9006 (define_insn "cmpgtdf_media"
9007   [(set (match_operand:DI 0 "register_operand" "=r")
9008         (gt:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9009                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9010   "TARGET_SHMEDIA_FPU"
9011   "fcmpgt.d     %1,%2,%0"
9012   [(set_attr "type" "fcmp_media")])
9014 (define_insn "cmpgedf_media"
9015   [(set (match_operand:DI 0 "register_operand" "=r")
9016         (ge:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9017                (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9018   "TARGET_SHMEDIA_FPU"
9019   "fcmpge.d     %1,%2,%0"
9020   [(set_attr "type" "fcmp_media")])
9022 (define_insn "cmpundf_media"
9023   [(set (match_operand:DI 0 "register_operand" "=r")
9024         (unordered:DI (match_operand:DF 1 "fp_arith_reg_operand" "f")
9025                       (match_operand:DF 2 "fp_arith_reg_operand" "f")))]
9026   "TARGET_SHMEDIA_FPU"
9027   "fcmpun.d     %1,%2,%0"
9028   [(set_attr "type" "fcmp_media")])
9030 (define_expand "cmpdf"
9031   [(set (reg:SI T_REG)
9032         (compare (match_operand:DF 0 "arith_operand" "")
9033                  (match_operand:DF 1 "arith_operand" "")))]
9034   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9035   "
9037   sh_compare_op0 = operands[0];
9038   sh_compare_op1 = operands[1];
9039   DONE;
9042 (define_expand "negdf2"
9043   [(set (match_operand:DF 0 "arith_reg_operand" "")
9044         (neg:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9045   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9046   "
9048   if (TARGET_SH4)
9049     {
9050       expand_df_unop (&gen_negdf2_i, operands);
9051       DONE;
9052     }
9055 (define_insn "*negdf2_media"
9056   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9057         (neg:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9058   "TARGET_SHMEDIA_FPU"
9059   "fneg.d       %1, %0"
9060   [(set_attr "type" "fmove_media")])
9062 (define_insn "negdf2_i"
9063   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9064         (neg:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9065    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9066   "TARGET_SH4"
9067   "fneg %0"
9068   [(set_attr "type" "fmove")
9069    (set_attr "fp_mode" "double")])
9071 (define_expand "sqrtdf2"
9072   [(set (match_operand:DF 0 "arith_reg_operand" "")
9073         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9074   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9075   "
9077   if (TARGET_SH4)
9078     {
9079       expand_df_unop (&gen_sqrtdf2_i, operands);
9080       DONE;
9081     }
9084 (define_insn "*sqrtdf2_media"
9085   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9086         (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9087   "TARGET_SHMEDIA_FPU"
9088   "fsqrt.d      %1, %0"
9089   [(set_attr "type" "dfdiv_media")])
9091 (define_insn "sqrtdf2_i"
9092   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9093         (sqrt:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9094    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9095   "TARGET_SH4"
9096   "fsqrt        %0"
9097   [(set_attr "type" "dfdiv")
9098    (set_attr "fp_mode" "double")])
9100 (define_expand "absdf2"
9101   [(set (match_operand:DF 0 "arith_reg_operand" "")
9102         (abs:DF (match_operand:DF 1 "arith_reg_operand" "")))]
9103   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9104   "
9106   if (TARGET_SH4)
9107     {
9108       expand_df_unop (&gen_absdf2_i, operands);
9109       DONE;
9110     }
9113 (define_insn "*absdf2_media"
9114   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9115         (abs:DF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9116   "TARGET_SHMEDIA_FPU"
9117   "fabs.d       %1, %0"
9118   [(set_attr "type" "fmove_media")])
9120 (define_insn "absdf2_i"
9121   [(set (match_operand:DF 0 "arith_reg_operand" "=f")
9122         (abs:DF (match_operand:DF 1 "arith_reg_operand" "0")))
9123    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9124   "TARGET_SH4"
9125   "fabs %0"
9126   [(set_attr "type" "fmove")
9127    (set_attr "fp_mode" "double")])
9129 (define_expand "extendsfdf2"
9130   [(set (match_operand:DF 0 "fp_arith_reg_operand" "")
9131         (float_extend:DF (match_operand:SF 1 "fpul_operand" "")))]
9132   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9133   "
9135   if (TARGET_SH4)
9136     {
9137       emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1],
9138                                         get_fpscr_rtx ()));
9139       DONE;
9140     }
9143 (define_insn "*extendsfdf2_media"
9144   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9145         (float_extend:DF (match_operand:SF 1 "fp_arith_reg_operand" "f")))]
9146   "TARGET_SHMEDIA_FPU"
9147   "fcnv.sd      %1, %0"
9148   [(set_attr "type" "dfpconv_media")])
9150 (define_insn "extendsfdf2_i4"
9151   [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f")
9152         (float_extend:DF (match_operand:SF 1 "fpul_operand" "y")))
9153    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9154   "TARGET_SH4"
9155   "fcnvsd  %1,%0"
9156   [(set_attr "type" "fp")
9157    (set_attr "fp_mode" "double")])
9159 (define_expand "truncdfsf2"
9160   [(set (match_operand:SF 0 "fpul_operand" "")
9161         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "")))]
9162   "TARGET_SH4 || TARGET_SHMEDIA_FPU"
9163   "
9165   if (TARGET_SH4)
9166     {
9167       emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1],
9168                                        get_fpscr_rtx ()));
9169       DONE;
9170     }
9173 (define_insn "*truncdfsf2_media"
9174   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
9175         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))]
9176   "TARGET_SHMEDIA_FPU"
9177   "fcnv.ds      %1, %0"
9178   [(set_attr "type" "dfpconv_media")])
9180 (define_insn "truncdfsf2_i4"
9181   [(set (match_operand:SF 0 "fpul_operand" "=y")
9182         (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f")))
9183    (use (match_operand:PSI 2 "fpscr_operand" "c"))]
9184   "TARGET_SH4"
9185   "fcnvds  %1,%0"
9186   [(set_attr "type" "fp")
9187    (set_attr "fp_mode" "double")])
9189 ;; Bit field extract patterns.  These give better code for packed bitfields,
9190 ;; because they allow auto-increment addresses to be generated.
9192 (define_expand "insv"
9193   [(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "")
9194                          (match_operand:SI 1 "immediate_operand" "")
9195                          (match_operand:SI 2 "immediate_operand" ""))
9196         (match_operand:SI 3 "general_operand" ""))]
9197   "TARGET_SH1 && ! TARGET_LITTLE_ENDIAN"
9198   "
9200   rtx addr_target, orig_address, shift_reg, qi_val;
9201   HOST_WIDE_INT bitsize, size, v;
9202   rtx x = operands[3];
9204   /* ??? expmed doesn't care for non-register predicates.  */
9205   if (! memory_operand (operands[0], VOIDmode)
9206       || ! immediate_operand (operands[1], VOIDmode)
9207       || ! immediate_operand (operands[2], VOIDmode)
9208       || ! general_operand (x, VOIDmode))
9209     FAIL;
9210   /* If this isn't a 16 / 24 / 32 bit field, or if
9211      it doesn't start on a byte boundary, then fail.  */
9212   bitsize = INTVAL (operands[1]);
9213   if (bitsize < 16 || bitsize > 32 || bitsize % 8 != 0
9214       || (INTVAL (operands[2]) % 8) != 0)
9215     FAIL;
9217   size = bitsize / 8;
9218   orig_address = XEXP (operands[0], 0);
9219   shift_reg = gen_reg_rtx (SImode);
9220   if (GET_CODE (x) == CONST_INT)
9221     {
9222       v = INTVAL (x);
9223       qi_val = force_reg (QImode, GEN_INT (trunc_int_for_mode (v, QImode)));
9224     }
9225   else
9226     {
9227       emit_insn (gen_movsi (shift_reg, operands[3]));
9228       qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9229     }
9230   addr_target = copy_addr_to_reg (plus_constant (orig_address, size - 1));
9232   operands[0] = replace_equiv_address (operands[0], addr_target);
9233   emit_insn (gen_movqi (operands[0], qi_val));
9235   while (size -= 1)
9236     {
9237       if (GET_CODE (x) == CONST_INT)
9238         qi_val
9239           = force_reg (QImode, GEN_INT (trunc_int_for_mode (v >>= 8, QImode)));
9240       else
9241         {
9242           emit_insn (gen_lshrsi3_k (shift_reg, shift_reg, GEN_INT (8)));
9243           qi_val = gen_rtx_SUBREG (QImode, shift_reg, 3);
9244         }
9245       emit_insn (gen_addsi3 (addr_target, addr_target, GEN_INT (-1)));
9246       emit_insn (gen_movqi (operands[0], qi_val));
9247     }
9249   DONE;
9252 ;; -------------------------------------------------------------------------
9253 ;; Peepholes
9254 ;; -------------------------------------------------------------------------
9256 ;; This matches cases where a stack pointer increment at the start of the
9257 ;; epilogue combines with a stack slot read loading the return value.
9259 (define_peephole
9260   [(set (match_operand:SI 0 "arith_reg_operand" "")
9261         (mem:SI (match_operand:SI 1 "arith_reg_operand" "")))
9262    (set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))]
9263   "TARGET_SH1 && REGNO (operands[1]) != REGNO (operands[0])"
9264   "mov.l        @%1+,%0")
9266 ;; See the comment on the dt combiner pattern above.
9268 (define_peephole
9269   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
9270         (plus:SI (match_dup 0)
9271                  (const_int -1)))
9272    (set (reg:SI T_REG)
9273         (eq:SI (match_dup 0)
9274                (const_int 0)))]
9275   "TARGET_SH2"
9276   "dt   %0")
9278 ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn'
9279 ;; to `mov #k,r0; mov.l @(r0,r15),rn'.  These sequences are generated by
9280 ;; reload when the constant is too large for a reg+offset address.
9282 ;; ??? We would get much better code if this was done in reload.  This would
9283 ;; require modifying find_reloads_address to recognize that if the constant
9284 ;; is out-of-range for an immediate add, then we get better code by reloading
9285 ;; the constant into a register than by reloading the sum into a register,
9286 ;; since the former is one instruction shorter if the address does not need
9287 ;; to be offsettable.  Unfortunately this does not work, because there is
9288 ;; only one register, r0, that can be used as an index register.  This register
9289 ;; is also the function return value register.  So, if we try to force reload
9290 ;; to use double-reg addresses, then we end up with some instructions that
9291 ;; need to use r0 twice.  The only way to fix this is to change the calling
9292 ;; convention so that r0 is not used to return values.
9294 (define_peephole
9295   [(set (match_operand:SI 0 "register_operand" "=r")
9296         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9297    (set (mem:SI (match_dup 0))
9298         (match_operand:SI 2 "general_movsrc_operand" ""))]
9299   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9300   "mov.l        %2,@(%0,%1)")
9302 (define_peephole
9303   [(set (match_operand:SI 0 "register_operand" "=r")
9304         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9305    (set (match_operand:SI 2 "general_movdst_operand" "")
9306         (mem:SI (match_dup 0)))]
9307   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9308   "mov.l        @(%0,%1),%2")
9310 (define_peephole
9311   [(set (match_operand:SI 0 "register_operand" "=r")
9312         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9313    (set (mem:HI (match_dup 0))
9314         (match_operand:HI 2 "general_movsrc_operand" ""))]
9315   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9316   "mov.w        %2,@(%0,%1)")
9318 (define_peephole
9319   [(set (match_operand:SI 0 "register_operand" "=r")
9320         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9321    (set (match_operand:HI 2 "general_movdst_operand" "")
9322         (mem:HI (match_dup 0)))]
9323   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9324   "mov.w        @(%0,%1),%2")
9326 (define_peephole
9327   [(set (match_operand:SI 0 "register_operand" "=r")
9328         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9329    (set (mem:QI (match_dup 0))
9330         (match_operand:QI 2 "general_movsrc_operand" ""))]
9331   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9332   "mov.b        %2,@(%0,%1)")
9334 (define_peephole
9335   [(set (match_operand:SI 0 "register_operand" "=r")
9336         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9337    (set (match_operand:QI 2 "general_movdst_operand" "")
9338         (mem:QI (match_dup 0)))]
9339   "TARGET_SH1 && REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)"
9340   "mov.b        @(%0,%1),%2")
9342 (define_peephole
9343   [(set (match_operand:SI 0 "register_operand" "=r")
9344         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9345    (set (mem:SF (match_dup 0))
9346         (match_operand:SF 2 "general_movsrc_operand" ""))]
9347   "TARGET_SH1 && REGNO (operands[0]) == 0
9348    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9349        || (GET_CODE (operands[2]) == SUBREG
9350            && REGNO (SUBREG_REG (operands[2])) < 16))
9351    && reg_unused_after (operands[0], insn)"
9352   "mov.l        %2,@(%0,%1)")
9354 (define_peephole
9355   [(set (match_operand:SI 0 "register_operand" "=r")
9356         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9357    (set (match_operand:SF 2 "general_movdst_operand" "")
9359         (mem:SF (match_dup 0)))]
9360   "TARGET_SH1 && REGNO (operands[0]) == 0
9361    && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16)
9362        || (GET_CODE (operands[2]) == SUBREG
9363            && REGNO (SUBREG_REG (operands[2])) < 16))
9364    && reg_unused_after (operands[0], insn)"
9365   "mov.l        @(%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:SF (match_dup 0))
9371         (match_operand:SF 2 "general_movsrc_operand" ""))]
9372   "TARGET_SH2E && REGNO (operands[0]) == 0
9373    && ((GET_CODE (operands[2]) == REG
9374         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9375        || (GET_CODE (operands[2]) == SUBREG
9376            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9377    && reg_unused_after (operands[0], insn)"
9378   "fmov{.s|}    %2,@(%0,%1)")
9380 (define_peephole
9381   [(set (match_operand:SI 0 "register_operand" "=r")
9382         (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
9383    (set (match_operand:SF 2 "general_movdst_operand" "")
9385         (mem:SF (match_dup 0)))]
9386   "TARGET_SH2E && REGNO (operands[0]) == 0
9387    && ((GET_CODE (operands[2]) == REG
9388         && FP_OR_XD_REGISTER_P (REGNO (operands[2])))
9389        || (GET_CODE (operands[2]) == SUBREG
9390            && FP_OR_XD_REGISTER_P (REGNO (SUBREG_REG (operands[2])))))
9391    && reg_unused_after (operands[0], insn)"
9392   "fmov{.s|}    @(%0,%1),%2")
9394 ;; Switch to a new stack with its address in sp_switch (a SYMBOL_REF).  */
9395 (define_insn "sp_switch_1"
9396   [(const_int 1)]
9397   "TARGET_SH1"
9398   "*
9400   rtx xoperands[1];
9402   xoperands[0] = sp_switch;
9403   output_asm_insn (\"mov.l r0,@-r15\;mov.l %0,r0\", xoperands);
9404   output_asm_insn (\"mov.l @r0,r0\;mov.l r15,@-r0\", xoperands);
9405   return \"mov r0,r15\";
9407   [(set_attr "length" "10")])
9409 ;; Switch back to the original stack for interrupt functions with the
9410 ;; sp_switch attribute.  */
9411 (define_insn "sp_switch_2"
9412   [(const_int 2)]
9413   "TARGET_SH1"
9414   "mov.l @r15+,r15\;mov.l @r15+,r0"
9415   [(set_attr "length" "4")])
9417 ;; Integer vector moves
9419 (define_expand "movv8qi"
9420   [(set (match_operand:V8QI 0 "general_movdst_operand" "")
9421         (match_operand:V8QI 1 "general_movsrc_operand" ""))]
9422   "TARGET_SHMEDIA"
9423   "{ if (prepare_move_operands (operands, V8QImode)) DONE; }")
9425 (define_insn "movv8qi_i"
9426   [(set (match_operand:V8QI 0 "general_movdst_operand" "=r,r,r,rl,m")
9427         (match_operand:V8QI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9428   "TARGET_SHMEDIA
9429    && (register_operand (operands[0], V8QImode)
9430        || sh_register_operand (operands[1], V8QImode))"
9431   "@
9432         add     %1, r63, %0
9433         movi    %1, %0
9434         #
9435         ld%M1.q %m1, %0
9436         st%M0.q %m0, %N1"
9437   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9438    (set_attr "length" "4,4,16,4,4")])
9440 (define_split
9441   [(set (match_operand:V8QI 0 "arith_reg_dest" "")
9442         (subreg:V8QI (const_int 0) 0))]
9443   "TARGET_SHMEDIA"
9444   [(set (match_dup 0)
9445         (const_vector:V8QI [(const_int 0) (const_int 0) (const_int 0)
9446                             (const_int 0) (const_int 0) (const_int 0)
9447                             (const_int 0) (const_int 0)]))])
9449 (define_split
9450   [(set (match_operand 0 "arith_reg_dest" "")
9451         (match_operand 1 "sh_rep_vec" ""))]
9452   "TARGET_SHMEDIA && reload_completed
9453    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9454    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9455    && GET_MODE_SIZE (GET_MODE (operands[0])) == 8
9456    && (XVECEXP (operands[1], 0, 0) != const0_rtx
9457        || XVECEXP (operands[1], 0, 1) != const0_rtx)
9458    && (XVECEXP (operands[1], 0, 0) != constm1_rtx
9459        || XVECEXP (operands[1], 0, 1) != constm1_rtx)"
9460   [(set (match_dup 0) (match_dup 1))
9461    (match_dup 2)]
9462   "
9464   int unit_size = GET_MODE_UNIT_SIZE (GET_MODE (operands[1]));
9465   rtx elt1 = XVECEXP (operands[1], 0, 1);
9467   if (unit_size > 2)
9468     operands[2] = gen_mshflo_l (operands[0], operands[0], operands[0]);
9469   else
9470     {
9471       if (unit_size < 2)
9472         operands[0] = gen_rtx_REG (V4HImode, true_regnum (operands[0]));
9473       operands[2] = gen_mperm_w0 (operands[0], operands[0]);
9474     }
9475   operands[0] = gen_rtx_REG (DImode, true_regnum (operands[0]));
9476   operands[1] = XVECEXP (operands[1], 0, 0);
9477   if (unit_size < 2)
9478     {
9479       if (GET_CODE (operands[1]) == CONST_INT && GET_CODE (elt1) == CONST_INT)
9480         operands[1]
9481           = GEN_INT (TARGET_LITTLE_ENDIAN
9482                      ? (INTVAL (operands[1]) & 0xff) + (INTVAL (elt1) << 8)
9483                      : (INTVAL (operands[1]) << 8) + (INTVAL (elt1) & 0xff));
9484       else
9485         {
9486           operands[0] = gen_rtx_REG (V2QImode, true_regnum (operands[0]));
9487           operands[1]
9488             = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, operands[1], elt1));
9489         }
9490     }
9493 (define_split
9494   [(set (match_operand 0 "arith_reg_dest" "")
9495         (match_operand 1 "sh_const_vec" ""))]
9496   "TARGET_SHMEDIA && reload_completed
9497    && GET_MODE (operands[0]) == GET_MODE (operands[1])
9498    && VECTOR_MODE_SUPPORTED_P (GET_MODE (operands[0]))
9499    && operands[1] != CONST0_RTX (GET_MODE (operands[1]))"
9500   [(set (match_dup 0) (match_dup 1))]
9501   "
9503   rtx v = operands[1];
9504   enum machine_mode new_mode
9505     = mode_for_size (GET_MODE_BITSIZE (GET_MODE (v)), MODE_INT, 0);
9507   operands[0] = gen_rtx_REG (new_mode, true_regnum (operands[0]));
9508   operands[1]
9509     = simplify_subreg (new_mode, operands[1], GET_MODE (operands[1]), 0);
9512 (define_expand "movv2hi"
9513   [(set (match_operand:V2HI 0 "general_movdst_operand" "")
9514         (match_operand:V2HI 1 "general_movsrc_operand" ""))]
9515   "TARGET_SHMEDIA"
9516   "{ if (prepare_move_operands (operands, V2HImode)) DONE; }")
9518 (define_insn "movv2hi_i"
9519   [(set (match_operand:V2HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9520         (match_operand:V2HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9521   "TARGET_SHMEDIA
9522    && (register_operand (operands[0], V2HImode)
9523        || sh_register_operand (operands[1], V2HImode))"
9524   "@
9525         addz.l  %1, r63, %0
9526         movi    %1, %0
9527         #
9528         ld%M1.l %m1, %0
9529         st%M0.l %m0, %N1"
9530   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9531    (set_attr "length" "4,4,16,4,4")])
9533 (define_expand "movv4hi"
9534   [(set (match_operand:V4HI 0 "general_movdst_operand" "")
9535         (match_operand:V4HI 1 "general_movsrc_operand" ""))]
9536   "TARGET_SHMEDIA"
9537   "{ if (prepare_move_operands (operands, V4HImode)) DONE; }")
9539 (define_insn "movv4hi_i"
9540   [(set (match_operand:V4HI 0 "general_movdst_operand" "=r,r,r,rl,m")
9541         (match_operand:V4HI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9542   "TARGET_SHMEDIA
9543    && (register_operand (operands[0], V4HImode)
9544        || sh_register_operand (operands[1], V4HImode))"
9545   "@
9546         add     %1, r63, %0
9547         movi    %1, %0
9548         #
9549         ld%M1.q %m1, %0
9550         st%M0.q %m0, %N1"
9551   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9552    (set_attr "length" "4,4,16,4,4")])
9554 (define_expand "movv2si"
9555   [(set (match_operand:V2SI 0 "general_movdst_operand" "")
9556         (match_operand:V2SI 1 "general_movsrc_operand" ""))]
9557   "TARGET_SHMEDIA"
9558   "{ if (prepare_move_operands (operands, V2SImode)) DONE; }")
9560 (define_insn "movv2si_i"
9561   [(set (match_operand:V2SI 0 "general_movdst_operand" "=r,r,r,rl,m")
9562         (match_operand:V2SI 1 "general_movsrc_operand" "r,I16C16Z,nW,m,rlZ"))]
9563   "TARGET_SHMEDIA
9564    && (register_operand (operands[0], V2SImode)
9565        || sh_register_operand (operands[1], V2SImode))"
9566   "@
9567         add     %1, r63, %0
9568         #
9569         #
9570         ld%M1.q %m1, %0
9571         st%M0.q %m0, %N1"
9572   [(set_attr "type"   "arith_media,arith_media,*,load_media,store_media")
9573    (set_attr "length" "4,4,16,4,4")])
9575 ;; Multimedia Intrinsics
9577 (define_insn "absv2si2"
9578   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9579         (abs:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")))]
9580   "TARGET_SHMEDIA"
9581   "mabs.l       %1, %0"
9582   [(set_attr "type" "mcmp_media")])
9584 (define_insn "absv4hi2"
9585   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9586         (abs:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")))]
9587   "TARGET_SHMEDIA"
9588   "mabs.w       %1, %0"
9589   [(set_attr "type" "mcmp_media")])
9591 (define_insn "addv2si3"
9592   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9593         (plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9594                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9595   "TARGET_SHMEDIA"
9596   "madd.l       %1, %2, %0"
9597   [(set_attr "type" "arith_media")])
9599 (define_insn "addv4hi3"
9600   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9601         (plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9602                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9603   "TARGET_SHMEDIA"
9604   "madd.w       %1, %2, %0"
9605   [(set_attr "type" "arith_media")])
9607 (define_insn "ssaddv2si3"
9608   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9609         (ss_plus:V2SI (match_operand:V2SI 1 "arith_reg_operand" "%r")
9610                       (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9611   "TARGET_SHMEDIA"
9612   "madds.l      %1, %2, %0"
9613   [(set_attr "type" "mcmp_media")])
9615 (define_insn "usaddv8qi3"
9616   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9617         (us_plus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "%r")
9618                       (match_operand:V8QI 2 "arith_reg_operand" "r")))]
9619   "TARGET_SHMEDIA"
9620   "madds.ub     %1, %2, %0"
9621   [(set_attr "type" "mcmp_media")])
9623 (define_insn "ssaddv4hi3"
9624   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9625         (ss_plus:V4HI (match_operand:V4HI 1 "arith_reg_operand" "%r")
9626                       (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9627   "TARGET_SHMEDIA"
9628   "madds.w      %1, %2, %0"
9629   [(set_attr "type" "mcmp_media")])
9631 (define_insn "negcmpeqv8qi"
9632   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9633         (neg:V8QI (eq:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9634                            (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9635   "TARGET_SHMEDIA"
9636   "mcmpeq.b     %N1, %N2, %0"
9637   [(set_attr "type" "mcmp_media")])
9639 (define_insn "negcmpeqv2si"
9640   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9641         (neg:V2SI (eq:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9642                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9643   "TARGET_SHMEDIA"
9644   "mcmpeq.l     %N1, %N2, %0"
9645   [(set_attr "type" "mcmp_media")])
9647 (define_insn "negcmpeqv4hi"
9648   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9649         (neg:V4HI (eq:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9650                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9651   "TARGET_SHMEDIA"
9652   "mcmpeq.w     %N1, %N2, %0"
9653   [(set_attr "type" "mcmp_media")])
9655 (define_insn "negcmpgtuv8qi"
9656   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9657         (neg:V8QI (gtu:V8QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "%rZ")
9658                             (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))))]
9659   "TARGET_SHMEDIA"
9660   "mcmpgt.ub    %N1, %N2, %0"
9661   [(set_attr "type" "mcmp_media")])
9663 (define_insn "negcmpgtv2si"
9664   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9665         (neg:V2SI (gt:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "%rZ")
9666                            (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9667   "TARGET_SHMEDIA"
9668   "mcmpgt.l     %N1, %N2, %0"
9669   [(set_attr "type" "mcmp_media")])
9671 (define_insn "negcmpgtv4hi"
9672   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9673         (neg:V4HI (gt:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "%rZ")
9674                            (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9675   "TARGET_SHMEDIA"
9676   "mcmpgt.w     %N1, %N2, %0"
9677   [(set_attr "type" "mcmp_media")])
9679 (define_insn "mcmv"
9680   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9681         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9682                         (match_operand:DI 2 "arith_reg_operand" "r"))
9683                 (and:DI (match_operand:DI 3 "arith_reg_operand" "0")
9684                         (not:DI (match_dup 2)))))]
9685   "TARGET_SHMEDIA"
9686   "mcmv %N1, %2, %0"
9687   [(set_attr "type" "arith_media")])
9689 (define_insn "mcnvs_lw"
9690   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9691         (vec_concat:V4HI
9692          (ss_truncate:V2HI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ"))
9693          (ss_truncate:V2HI (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))))]
9694   "TARGET_SHMEDIA"
9695   "mcnvs.lw     %N1, %N2, %0"
9696   [(set_attr "type" "mcmp_media")])
9698 (define_insn "mcnvs_wb"
9699   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9700         (vec_concat:V8QI
9701          (ss_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9702          (ss_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9703   "TARGET_SHMEDIA"
9704   "mcnvs.wb     %N1, %N2, %0"
9705   [(set_attr "type" "mcmp_media")])
9707 (define_insn "mcnvs_wub"
9708   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
9709         (vec_concat:V8QI
9710          (us_truncate:V4QI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ"))
9711          (us_truncate:V4QI (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))))]
9712   "TARGET_SHMEDIA"
9713   "mcnvs.wub    %N1, %N2, %0"
9714   [(set_attr "type" "mcmp_media")])
9716 (define_insn "mextr_rl"
9717   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9718         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9719                              (match_operand:HI 3 "mextr_bit_offset" "i"))
9720                (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9721                           (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9722   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9723   "*
9725   static char templ[16];
9727   sprintf (templ, \"mextr%d\\t%%N1, %%N2, %%0\",
9728            (int) INTVAL (operands[3]) >> 3);
9729   return templ;
9731   [(set_attr "type" "arith_media")])
9733 (define_insn "*mextr_lr"
9734   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
9735         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9736                            (match_operand:HI 3 "mextr_bit_offset" "i"))
9737                (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
9738                             (match_operand:HI 4 "mextr_bit_offset" "i"))))]
9739   "TARGET_SHMEDIA && INTVAL (operands[3]) + INTVAL (operands[4]) == 64"
9740   "*
9742   static char templ[16];
9744   sprintf (templ, \"mextr%d\\t%%N2, %%N1, %%0\",
9745            (int) INTVAL (operands[4]) >> 3);
9746   return templ;
9748   [(set_attr "type" "arith_media")])
9750 ; mextrN can be modelled with vec_select / vec_concat, but the selection
9751 ; vector then varies depending on endianness.
9752 (define_expand "mextr1"
9753   [(match_operand:DI 0 "arith_reg_dest" "")
9754    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9755    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9756   "TARGET_SHMEDIA"
9757   "
9759   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9760                            GEN_INT (1 * 8), GEN_INT (7 * 8)));
9761   DONE;
9764 (define_expand "mextr2"
9765   [(match_operand:DI 0 "arith_reg_dest" "")
9766    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9767    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9768   "TARGET_SHMEDIA"
9769   "
9771   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9772                            GEN_INT (2 * 8), GEN_INT (6 * 8)));
9773   DONE;
9776 (define_expand "mextr3"
9777   [(match_operand:DI 0 "arith_reg_dest" "")
9778    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9779    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9780   "TARGET_SHMEDIA"
9781   "
9783   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9784                            GEN_INT (3 * 8), GEN_INT (5 * 8)));
9785   DONE;
9788 (define_expand "mextr4"
9789   [(match_operand:DI 0 "arith_reg_dest" "")
9790    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9791    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9792   "TARGET_SHMEDIA"
9793   "
9795   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9796                            GEN_INT (4 * 8), GEN_INT (4 * 8)));
9797   DONE;
9800 (define_expand "mextr5"
9801   [(match_operand:DI 0 "arith_reg_dest" "")
9802    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9803    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9804   "TARGET_SHMEDIA"
9805   "
9807   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9808                            GEN_INT (5 * 8), GEN_INT (3 * 8)));
9809   DONE;
9812 (define_expand "mextr6"
9813   [(match_operand:DI 0 "arith_reg_dest" "")
9814    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9815    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9816   "TARGET_SHMEDIA"
9817   "
9819   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9820                            GEN_INT (6 * 8), GEN_INT (2 * 8)));
9821   DONE;
9824 (define_expand "mextr7"
9825   [(match_operand:DI 0 "arith_reg_dest" "")
9826    (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
9827    (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")]
9828   "TARGET_SHMEDIA"
9829   "
9831   emit_insn (gen_mextr_rl (operands[0], operands[1], operands[2],
9832                            GEN_INT (7 * 8), GEN_INT (1 * 8)));
9833   DONE;
9836 (define_expand "mmacfx_wl"
9837   [(match_operand:V2SI 0 "arith_reg_dest" "")
9838    (match_operand:V2HI 1 "extend_reg_operand" "")
9839    (match_operand:V2HI 2 "extend_reg_operand" "")
9840    (match_operand:V2SI 3 "arith_reg_operand" "")]
9841   "TARGET_SHMEDIA"
9842   "
9844   emit_insn (gen_mmacfx_wl_i (operands[0], operands[3],
9845                               operands[1], operands[2]));
9846   DONE;
9849 (define_insn "mmacfx_wl_i"
9850   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9851         (ss_plus:V2SI
9852          (match_operand:V2SI 1 "arith_reg_operand" "0")
9853          (ss_truncate:V2SI
9854           (ashift:V2DI
9855            (sign_extend:V2DI
9856             (mult:V2SI
9857              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9858              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9859            (const_int 1)))))]
9860   "TARGET_SHMEDIA"
9861   "mmacfx.wl    %2, %3, %0"
9862   [(set_attr "type" "mac_media")])
9864 (define_expand "mmacnfx_wl"
9865   [(match_operand:V2SI 0 "arith_reg_dest" "")
9866    (match_operand:V2HI 1 "extend_reg_operand" "")
9867    (match_operand:V2HI 2 "extend_reg_operand" "")
9868    (match_operand:V2SI 3 "arith_reg_operand" "")]
9869   "TARGET_SHMEDIA"
9870   "
9872   emit_insn (gen_mmacnfx_wl_i (operands[0], operands[3],
9873                                operands[1], operands[2]));
9874   DONE;
9877 (define_insn "mmacnfx_wl_i"
9878   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9879         (ss_minus:V2SI
9880          (match_operand:V2SI 1 "arith_reg_operand" "0")
9881          (ss_truncate:V2SI
9882           (ashift:V2DI
9883            (sign_extend:V2DI
9884             (mult:V2SI
9885              (sign_extend:V2SI (match_operand:V2HI 2 "extend_reg_operand" "r"))
9886              (sign_extend:V2SI (match_operand:V2HI 3 "extend_reg_operand" "r"))))
9887            (const_int 1)))))]
9888   "TARGET_SHMEDIA"
9889   "mmacnfx.wl   %2, %3, %0"
9890   [(set_attr "type" "mac_media")])
9892 (define_insn "mulv2si3"
9893   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9894         (mult:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
9895                    (match_operand:V2SI 2 "arith_reg_operand" "r")))]
9896   "TARGET_SHMEDIA"
9897   "mmul.l       %1, %2, %0"
9898   [(set_attr "type" "d2mpy_media")])
9900 (define_insn "mulv4hi3"
9901   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9902         (mult:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
9903                    (match_operand:V4HI 2 "arith_reg_operand" "r")))]
9904   "TARGET_SHMEDIA"
9905   "mmul.w       %1, %2, %0"
9906   [(set_attr "type" "dmpy_media")])
9908 (define_insn "mmulfx_l"
9909   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9910         (ss_truncate:V2SI
9911          (ashiftrt:V2DI
9912           (mult:V2DI
9913            (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
9914            (sign_extend:V2DI (match_operand:V2SI 2 "arith_reg_operand" "r")))
9915           (const_int 31))))]
9916   "TARGET_SHMEDIA"
9917   "mmulfx.l     %1, %2, %0"
9918   [(set_attr "type" "d2mpy_media")])
9920 (define_insn "mmulfx_w"
9921   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9922         (ss_truncate:V4HI
9923          (ashiftrt:V4SI
9924           (mult:V4SI
9925            (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9926            (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9927           (const_int 15))))]
9928   "TARGET_SHMEDIA"
9929   "mmulfx.w     %1, %2, %0"
9930   [(set_attr "type" "dmpy_media")])
9932 (define_insn "mmulfxrp_w"
9933   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
9934         (ss_truncate:V4HI
9935          (ashiftrt:V4SI
9936           (plus:V4SI
9937            (mult:V4SI
9938             (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9939             (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9940            (const_int 16384))
9941           (const_int 15))))]
9942   "TARGET_SHMEDIA"
9943   "mmulfxrp.w   %1, %2, %0"
9944   [(set_attr "type" "dmpy_media")])
9946 (define_expand "mmulhi_wl"
9947   [(match_operand:V2SI 0 "arith_reg_dest" "")
9948    (match_operand:V4HI 1 "arith_reg_operand" "")
9949    (match_operand:V4HI 2 "arith_reg_operand" "")]
9950   "TARGET_SHMEDIA"
9951   "
9953   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul23_wl : gen_mmul01_wl)
9954              (operands[0], operands[1], operands[2]));
9955   DONE;
9958 (define_expand "mmullo_wl"
9959   [(match_operand:V2SI 0 "arith_reg_dest" "")
9960    (match_operand:V4HI 1 "arith_reg_operand" "")
9961    (match_operand:V4HI 2 "arith_reg_operand" "")]
9962   "TARGET_SHMEDIA"
9963   "
9965   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mmul01_wl : gen_mmul23_wl)
9966              (operands[0], operands[1], operands[2]));
9967   DONE;
9970 (define_insn "mmul23_wl"
9971   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9972         (vec_select:V2SI
9973          (mult:V4SI
9974           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9975           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9976          (parallel [(const_int 2) (const_int 3)])))]
9977   "TARGET_SHMEDIA"
9978   "* return (TARGET_LITTLE_ENDIAN
9979              ? \"mmulhi.wl      %1, %2, %0\"
9980              : \"mmullo.wl      %1, %2, %0\");"
9981   [(set_attr "type" "dmpy_media")])
9983 (define_insn "mmul01_wl"
9984   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
9985         (vec_select:V2SI
9986          (mult:V4SI
9987           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
9988           (sign_extend:V4SI (match_operand:V4HI 2 "arith_reg_operand" "r")))
9989          (parallel [(const_int 0) (const_int 1)])))]
9990   "TARGET_SHMEDIA"
9991   "* return (TARGET_LITTLE_ENDIAN
9992              ? \"mmullo.wl      %1, %2, %0\"
9993              : \"mmulhi.wl      %1, %2, %0\");"
9994   [(set_attr "type" "dmpy_media")])
9996 (define_expand "mmulsum_wq"
9997   [(match_operand:DI 0 "arith_reg_dest" "")
9998    (match_operand:V4HI 1 "arith_reg_operand" "")
9999    (match_operand:V4HI 2 "arith_reg_operand" "")
10000    (match_operand:DI 3 "arith_reg_operand" "")]
10001   "TARGET_SHMEDIA"
10002   "
10004   emit_insn (gen_mmulsum_wq_i (operands[0], operands[3],
10005                                operands[1], operands[2]));
10006   DONE;
10009 (define_insn "mmulsum_wq_i"
10010   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10011         (plus:DI (match_operand:DI 1 "arith_reg_operand" "0")
10012          (plus:DI
10013           (plus:DI
10014            (vec_select:DI
10015             (mult:V4DI
10016              (sign_extend:V4DI (match_operand:V4HI 2 "arith_reg_operand" "r"))
10017              (sign_extend:V4DI (match_operand:V4HI 3 "arith_reg_operand" "r")))
10018             (parallel [(const_int 0)]))
10019            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10020                                      (sign_extend:V4DI (match_dup 3)))
10021                           (parallel [(const_int 1)])))
10022           (plus:DI
10023            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10024                                      (sign_extend:V4DI (match_dup 3)))
10025                           (parallel [(const_int 2)]))
10026            (vec_select:DI (mult:V4DI (sign_extend:V4DI (match_dup 2))
10027                                      (sign_extend:V4DI (match_dup 3)))
10028                           (parallel [(const_int 3)]))))))]
10029   "TARGET_SHMEDIA"
10030   "mmulsum.wq   %2, %3, %0"
10031   [(set_attr "type" "mac_media")])
10033 (define_expand "mperm_w"
10034   [(match_operand:V4HI 0 "arith_reg_dest" "=r")
10035    (match_operand:V4HI 1 "arith_reg_operand" "r")
10036    (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")]
10037   "TARGET_SHMEDIA"
10038   "
10040   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mperm_w_little : gen_mperm_w_big)
10041              (operands[0], operands[1], operands[2]));
10042   DONE;
10045 ; This use of vec_select isn't exactly correct according to rtl.texi
10046 ; (because not constant), but it seems a straightforward extension.
10047 (define_insn "mperm_w_little"
10048   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10049         (vec_select:V4HI
10050          (match_operand:V4HI 1 "arith_reg_operand" "r")
10051          (parallel
10052           [(zero_extract:QI (match_operand:QI 2 "extend_reg_or_0_operand" "rZ")
10053                             (const_int 2) (const_int 0))
10054            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 2))
10055            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 4))
10056            (zero_extract:QI (match_dup 2) (const_int 2) (const_int 6))])))]
10057   "TARGET_SHMEDIA && TARGET_LITTLE_ENDIAN"
10058   "mperm.w      %1, %N2, %0"
10059   [(set_attr "type" "arith_media")])
10061 (define_insn "mperm_w_big"
10062   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10063         (vec_select:V4HI
10064          (match_operand:V4HI 1 "arith_reg_operand" "r")
10065          (parallel
10066           [(zero_extract:QI (not:QI (match_operand:QI 2
10067                                      "extend_reg_or_0_operand" "rZ"))
10068                             (const_int 2) (const_int 0))
10069            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 2))
10070            (zero_extract:QI (not:QI (match_dup 2)) (const_int 2) (const_int 4))
10071            (zero_extract:QI (not:QI (match_dup 2))
10072                             (const_int 2) (const_int 6))])))]
10073   "TARGET_SHMEDIA && ! TARGET_LITTLE_ENDIAN"
10074   "mperm.w      %1, %N2, %0"
10075   [(set_attr "type" "arith_media")])
10077 (define_insn "mperm_w0"
10078   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10079         (vec_duplicate:V4HI (truncate:HI (match_operand 1
10080                                           "trunc_hi_operand" "r"))))]
10081   "TARGET_SHMEDIA"
10082   "mperm.w      %1, r63, %0"
10083   [(set_attr "type" "arith_media")])
10085 (define_expand "msad_ubq"
10086   [(match_operand:DI 0 "arith_reg_dest" "")
10087    (match_operand:V8QI 1 "arith_reg_or_0_operand" "")
10088    (match_operand:V8QI 2 "arith_reg_or_0_operand" "")
10089    (match_operand:DI 3 "arith_reg_operand" "")]
10090   "TARGET_SHMEDIA"
10091   "
10093   emit_insn (gen_msad_ubq_i (operands[0], operands[3],
10094                              operands[1], operands[2]));
10095   DONE;
10098 (define_insn "msad_ubq_i"
10099   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10100         (plus:DI
10101          (plus:DI
10102           (plus:DI
10103            (plus:DI
10104             (match_operand:DI 1 "arith_reg_operand" "0")
10105             (abs:DI (vec_select:DI
10106                      (minus:V8DI
10107                       (zero_extend:V8DI
10108                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10109                       (zero_extend:V8DI
10110                        (match_operand:V8QI 3 "arith_reg_or_0_operand" "rZ")))
10111                      (parallel [(const_int 0)]))))
10112            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10113                                               (zero_extend:V8DI (match_dup 3)))
10114                                   (parallel [(const_int 1)]))))
10115           (plus:DI
10116            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10117                                               (zero_extend:V8DI (match_dup 3)))
10118                                   (parallel [(const_int 2)])))
10119            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10120                                               (zero_extend:V8DI (match_dup 3)))
10121                                   (parallel [(const_int 3)])))))
10122          (plus:DI
10123           (plus:DI
10124            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10125                                               (zero_extend:V8DI (match_dup 3)))
10126                                   (parallel [(const_int 4)])))
10127            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10128                                               (zero_extend:V8DI (match_dup 3)))
10129                                   (parallel [(const_int 5)]))))
10130           (plus:DI
10131            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10132                                               (zero_extend:V8DI (match_dup 3)))
10133                                   (parallel [(const_int 6)])))
10134            (abs:DI (vec_select:DI (minus:V8DI (zero_extend:V8DI (match_dup 2))
10135                                               (zero_extend:V8DI (match_dup 3)))
10136                                   (parallel [(const_int 7)])))))))]
10137   "TARGET_SHMEDIA"
10138   "msad.ubq     %N2, %N3, %0"
10139   [(set_attr "type" "mac_media")])
10141 (define_insn "mshalds_l"
10142   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10143         (ss_truncate:V2SI
10144          (ashift:V2DI
10145           (sign_extend:V2DI (match_operand:V2SI 1 "arith_reg_operand" "r"))
10146           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10147                   (const_int 31)))))]
10148   "TARGET_SHMEDIA"
10149   "mshalds.l    %1, %2, %0"
10150   [(set_attr "type" "mcmp_media")])
10152 (define_insn "mshalds_w"
10153   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10154         (ss_truncate:V4HI
10155          (ashift:V4SI
10156           (sign_extend:V4SI (match_operand:V4HI 1 "arith_reg_operand" "r"))
10157           (and:DI (match_operand:DI 2 "arith_reg_operand" "r")
10158                   (const_int 15)))))]
10159   "TARGET_SHMEDIA"
10160   "mshalds.w    %1, %2, %0"
10161   [(set_attr "type" "mcmp_media")])
10163 (define_insn "ashrv2si3"
10164   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10165         (ashiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10166                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10167   "TARGET_SHMEDIA"
10168   "mshard.l     %1, %2, %0"
10169   [(set_attr "type" "arith_media")])
10171 (define_insn "ashrv4hi3"
10172   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10173         (ashiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10174                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10175   "TARGET_SHMEDIA"
10176   "mshard.w     %1, %2, %0"
10177   [(set_attr "type" "arith_media")])
10179 (define_insn "mshards_q"
10180   [(set (match_operand:HI 0 "arith_reg_dest" "=r")
10181         (ss_truncate:HI
10182          (ashiftrt:DI (match_operand:DI 1 "arith_reg_operand" "r")
10183                       (match_operand:DI 2 "arith_reg_or_0_operand" "rZ"))))]
10184   "TARGET_SHMEDIA"
10185   "mshards.q    %1, %N2, %0"
10186   [(set_attr "type" "mcmp_media")])
10188 (define_expand "mshfhi_b"
10189   [(match_operand:V8QI 0 "arith_reg_dest" "")
10190    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10191    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10192   "TARGET_SHMEDIA"
10193   "
10195   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_b : gen_mshf0_b)
10196              (operands[0], operands[1], operands[2]));
10197   DONE;
10200 (define_expand "mshflo_b"
10201   [(match_operand:V8QI 0 "arith_reg_dest" "")
10202    (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10203    (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ")]
10204   "TARGET_SHMEDIA"
10205   "
10207   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_b : gen_mshf4_b)
10208              (operands[0], operands[1], operands[2]));
10209   DONE;
10212 (define_insn "mshf4_b"
10213   [(set
10214     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10215     (vec_select:V8QI
10216      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10217                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10218      (parallel [(const_int 4) (const_int 12) (const_int 5) (const_int 13)
10219                 (const_int 6) (const_int 14) (const_int 7) (const_int 15)])))]
10220   "TARGET_SHMEDIA"
10221   "* return (TARGET_LITTLE_ENDIAN
10222              ? \"mshfhi.b       %N1, %N2, %0\"
10223              : \"mshflo.b       %N1, %N2, %0\");"
10224   [(set_attr "type" "arith_media")])
10226 (define_insn "mshf0_b"
10227   [(set
10228     (match_operand:V8QI 0 "arith_reg_dest" "=r")
10229     (vec_select:V8QI
10230      (vec_concat:V16QI (match_operand:V8QI 1 "arith_reg_or_0_operand" "rZ")
10231                        (match_operand:V8QI 2 "arith_reg_or_0_operand" "rZ"))
10232      (parallel [(const_int 0) (const_int 8) (const_int 1) (const_int 9)
10233                 (const_int 2) (const_int 10) (const_int 3) (const_int 11)])))]
10234   "TARGET_SHMEDIA"
10235   "* return (TARGET_LITTLE_ENDIAN
10236              ? \"mshflo.b       %N1, %N2, %0\"
10237              : \"mshfhi.b       %N1, %N2, %0\");"
10238   [(set_attr "type" "arith_media")])
10240 (define_expand "mshfhi_l"
10241   [(match_operand:V2SI 0 "arith_reg_dest" "")
10242    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10243    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10244   "TARGET_SHMEDIA"
10245   "
10247   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_l : gen_mshf0_l)
10248              (operands[0], operands[1], operands[2]));
10249   DONE;
10252 (define_expand "mshflo_l"
10253   [(match_operand:V2SI 0 "arith_reg_dest" "")
10254    (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10255    (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ")]
10256   "TARGET_SHMEDIA"
10257   "
10259   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_l : gen_mshf4_l)
10260              (operands[0], operands[1], operands[2]));
10261   DONE;
10264 (define_insn "mshf4_l"
10265   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10266         (vec_select:V2SI
10267          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10268                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10269          (parallel [(const_int 1) (const_int 3)])))]
10270   "TARGET_SHMEDIA"
10271   "* return (TARGET_LITTLE_ENDIAN
10272              ? \"mshfhi.l       %N1, %N2, %0\"
10273              : \"mshflo.l       %N1, %N2, %0\");"
10274   [(set_attr "type" "arith_media")])
10276 (define_insn "mshf0_l"
10277   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10278         (vec_select:V2SI
10279          (vec_concat:V4SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10280                           (match_operand:V2SI 2 "arith_reg_or_0_operand" "rZ"))
10281          (parallel [(const_int 0) (const_int 2)])))]
10282   "TARGET_SHMEDIA"
10283   "* return (TARGET_LITTLE_ENDIAN
10284              ? \"mshflo.l       %N1, %N2, %0\"
10285              : \"mshfhi.l       %N1, %N2, %0\");"
10286   [(set_attr "type" "arith_media")])
10288 (define_expand "mshfhi_w"
10289   [(match_operand:V4HI 0 "arith_reg_dest" "")
10290    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10291    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10292   "TARGET_SHMEDIA"
10293   "
10295   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf4_w : gen_mshf0_w)
10296              (operands[0], operands[1], operands[2]));
10297   DONE;
10300 (define_expand "mshflo_w"
10301   [(match_operand:V4HI 0 "arith_reg_dest" "")
10302    (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10303    (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ")]
10304   "TARGET_SHMEDIA"
10305   "
10307   emit_insn ((TARGET_LITTLE_ENDIAN ? gen_mshf0_w : gen_mshf4_w)
10308              (operands[0], operands[1], operands[2]));
10309   DONE;
10312 (define_insn "mshf4_w"
10313   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10314         (vec_select:V4HI
10315          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10316                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10317          (parallel [(const_int 2) (const_int 6) (const_int 3) (const_int 7)])))]
10318   "TARGET_SHMEDIA"
10319   "* return (TARGET_LITTLE_ENDIAN
10320              ? \"mshfhi.w       %N1, %N2, %0\"
10321              : \"mshflo.w       %N1, %N2, %0\");"
10322   [(set_attr "type" "arith_media")])
10324 (define_insn "mshf0_w"
10325   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10326         (vec_select:V4HI
10327          (vec_concat:V8HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10328                           (match_operand:V4HI 2 "arith_reg_or_0_operand" "rZ"))
10329          (parallel [(const_int 0) (const_int 4) (const_int 1) (const_int 5)])))]
10330   "TARGET_SHMEDIA"
10331   "* return (TARGET_LITTLE_ENDIAN
10332              ? \"mshflo.w       %N1, %N2, %0\"
10333              : \"mshfhi.w       %N1, %N2, %0\");"
10334   [(set_attr "type" "arith_media")])
10336 (define_insn "mshflo_w_x"
10337   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10338         (vec_select:V4HI
10339          (vec_concat:V4HI (match_operand:V2HI 1 "extend_reg_or_0_operand" "rZ")
10340                           (match_operand:V2HI 2 "extend_reg_or_0_operand" "rZ"))
10341          (parallel [(const_int 2) (const_int 0) (const_int 3) (const_int 1)])))]
10342   "TARGET_SHMEDIA"
10343   "mshflo.w     %N1, %N2, %0"
10344   [(set_attr "type" "arith_media")])
10346 /* These are useful to expand ANDs and as combiner patterns.  */
10347 (define_insn_and_split "mshfhi_l_di"
10348   [(set (match_operand:DI 0 "arith_reg_dest" "=r,f")
10349         (ior:DI (lshiftrt:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ,f")
10350                              (const_int 32))
10351                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ,?f")
10352                         (const_int -4294967296))))]
10353   "TARGET_SHMEDIA"
10354   "@
10355         mshfhi.l        %N1, %N2, %0
10356         #"
10357   "TARGET_SHMEDIA && reload_completed
10358    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10359   [(set (match_dup 3) (match_dup 4))
10360    (set (match_dup 5) (match_dup 6))]
10361   "
10363   operands[3] = gen_lowpart (SImode, operands[0]);
10364   operands[4] = gen_highpart (SImode, operands[1]);
10365   operands[5] = gen_highpart (SImode, operands[0]);
10366   operands[6] = gen_highpart (SImode, operands[2]);
10368   [(set_attr "type" "arith_media")])
10370 (define_insn "*mshfhi_l_di_rev"
10371   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10372         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10373                         (const_int -4294967296))
10374                 (lshiftrt:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10375                              (const_int 32))))]
10376   "TARGET_SHMEDIA"
10377   "mshfhi.l     %N2, %N1, %0"
10378   [(set_attr "type" "arith_media")])
10380 (define_split
10381   [(set (match_operand:DI 0 "arith_reg_dest" "")
10382         (ior:DI (zero_extend:DI (match_operand:SI 1
10383                                               "extend_reg_or_0_operand" ""))
10384                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "")
10385                         (const_int -4294967296))))
10386    (clobber (match_operand:DI 3 "arith_reg_dest" ""))]
10387   "TARGET_SHMEDIA"
10388   [(const_int 0)]
10389   "
10391   emit_insn (gen_ashldi3_media (operands[3],
10392                                 simplify_gen_subreg (DImode, operands[1],
10393                                                      SImode, 0),
10394                                 GEN_INT (32)));
10395   emit_insn (gen_mshfhi_l_di (operands[0], operands[3], operands[2]));
10396   DONE;
10399 (define_insn "mshflo_l_di"
10400   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10401         (ior:DI (and:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10402                         (const_int 4294967295))
10403                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10404                            (const_int 32))))]
10406   "TARGET_SHMEDIA"
10407   "mshflo.l     %N1, %N2, %0"
10408   [(set_attr "type" "arith_media")])
10410 (define_insn "*mshflo_l_di_rev"
10411   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10412         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10413                            (const_int 32))
10414                 (and:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10415                         (const_int 4294967295))))]
10417   "TARGET_SHMEDIA"
10418   "mshflo.l     %N2, %N1, %0"
10419   [(set_attr "type" "arith_media")])
10421 ;; Combiner pattern for trampoline initialization.
10422 (define_insn_and_split "*double_shori"
10423   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10424         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_operand" "0")
10425                            (const_int 32))
10426                 (match_operand:DI 2 "const_int_operand" "n")))]
10427   "TARGET_SHMEDIA
10428    && INTVAL (operands[2]) == trunc_int_for_mode (INTVAL (operands[2]), SImode)"
10429   "#"
10430   "rtx_equal_p (operands[0], operands[1])"
10431   [(const_int 0)]
10432   "
10434   HOST_WIDE_INT v = INTVAL (operands[2]);
10436   emit_insn (gen_shori_media (operands[0], operands[0],
10437              gen_int_mode (INTVAL (operands[2]) >> 16, HImode)));
10438   emit_insn (gen_shori_media (operands[0], operands[0],
10439                               gen_int_mode (v, HImode)));
10440   DONE;
10444 (define_insn "*mshflo_l_di_x"
10445   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10446         (ior:DI (zero_extend:DI (match_operand:SI 1 "extend_reg_or_0_operand"
10447                                  "rZ"))
10448                 (ashift:DI (match_operand:DI 2 "arith_reg_or_0_operand" "rZ")
10449                            (const_int 32))))]
10451   "TARGET_SHMEDIA"
10452   "mshflo.l     %N1, %N2, %0"
10453   [(set_attr "type" "arith_media")])
10455 (define_insn_and_split "concat_v2sf"
10456   [(set (match_operand:V2SF 0 "register_operand" "=r,f,f?")
10457 ;;      (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,0,f")
10458         (vec_concat:V2SF (match_operand:SF 1 "register_operand" "rZ,f,f")
10459                          (match_operand:SF 2 "register_operand" "rZ,f,f")))]
10461   "TARGET_SHMEDIA"
10462   "@
10463         mshflo.l        %N1, %N2, %0
10464         #
10465         #"
10466   "TARGET_SHMEDIA && reload_completed
10467    && ! GENERAL_REGISTER_P (true_regnum (operands[0]))"
10468   [(set (match_dup 3) (match_dup 1))
10469    (set (match_dup 4) (match_dup 2))]
10470   "
10472   operands[3] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 0);
10473   operands[4] = simplify_gen_subreg (SFmode, operands[0], V2SFmode, 4);
10475   [(set_attr "type" "arith_media")])
10477 (define_insn "*mshflo_l_di_x_rev"
10478   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10479         (ior:DI (ashift:DI (match_operand:DI 1 "arith_reg_or_0_operand" "rZ")
10480                            (const_int 32))
10481                 (zero_extend:DI (match_operand:SI 2 "extend_reg_or_0_operand" "rZ"))))]
10483   "TARGET_SHMEDIA"
10484   "mshflo.l     %N2, %N1, %0"
10485   [(set_attr "type" "arith_media")])
10487 (define_insn "ashlv2si3"
10488   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10489         (ashift:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10490                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10491   "TARGET_SHMEDIA"
10492   "mshlld.l     %1, %2, %0"
10493   [(set_attr "type" "arith_media")])
10495 (define_insn "ashlv4hi3"
10496   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10497         (ashift:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10498                      (match_operand:DI 2 "arith_reg_operand" "r")))]
10499   "TARGET_SHMEDIA"
10500   "mshlld.w     %1, %2, %0"
10501   [(set_attr "type" "arith_media")])
10503 (define_insn "lshrv2si3"
10504   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10505         (lshiftrt:V2SI (match_operand:V2SI 1 "arith_reg_operand" "r")
10506                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10507   "TARGET_SHMEDIA"
10508   "mshlrd.l     %1, %2, %0"
10509   [(set_attr "type" "arith_media")])
10511 (define_insn "lshrv4hi3"
10512   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10513         (lshiftrt:V4HI (match_operand:V4HI 1 "arith_reg_operand" "r")
10514                        (match_operand:DI 2 "arith_reg_operand" "r")))]
10515   "TARGET_SHMEDIA"
10516   "mshlrd.w     %1, %2, %0"
10517   [(set_attr "type" "arith_media")])
10519 (define_insn "subv2si3"
10520   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10521         (minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10522                     (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10523   "TARGET_SHMEDIA"
10524   "msub.l       %N1, %2, %0"
10525   [(set_attr "type" "arith_media")])
10527 (define_insn "subv4hi3"
10528   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10529         (minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10530                     (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10531   "TARGET_SHMEDIA"
10532   "msub.w       %N1, %2, %0"
10533   [(set_attr "type" "arith_media")])
10535 (define_insn "sssubv2si3"
10536   [(set (match_operand:V2SI 0 "arith_reg_dest" "=r")
10537         (ss_minus:V2SI (match_operand:V2SI 1 "arith_reg_or_0_operand" "rZ")
10538                        (match_operand:V2SI 2 "arith_reg_operand" "r")))]
10539   "TARGET_SHMEDIA"
10540   "msubs.l      %N1, %2, %0"
10541   [(set_attr "type" "mcmp_media")])
10543 (define_insn "ussubv8qi3"
10544   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10545         (us_minus:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10546                        (match_operand:V8QI 2 "arith_reg_operand" "r")))]
10547   "TARGET_SHMEDIA"
10548   "msubs.ub     %1, %2, %0"
10549   [(set_attr "type" "mcmp_media")])
10551 (define_insn "sssubv4hi3"
10552   [(set (match_operand:V4HI 0 "arith_reg_dest" "=r")
10553         (ss_minus:V4HI (match_operand:V4HI 1 "arith_reg_or_0_operand" "rZ")
10554                        (match_operand:V4HI 2 "arith_reg_operand" "r")))]
10555   "TARGET_SHMEDIA"
10556   "msubs.w      %N1, %2, %0"
10557   [(set_attr "type" "mcmp_media")])
10559 ;; Floating Point Intrinsics
10561 (define_insn "fcosa_s"
10562   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10563         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10564                    UNSPEC_FCOSA))]
10565   "TARGET_SHMEDIA"
10566   "fcosa.s      %1, %0"
10567   [(set_attr "type" "atrans_media")])
10569 (define_insn "fsina_s"
10570   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10571         (unspec:SF [(match_operand:SI 1 "fp_arith_reg_operand" "f")]
10572                    UNSPEC_FSINA))]
10573   "TARGET_SHMEDIA"
10574   "fsina.s      %1, %0"
10575   [(set_attr "type" "atrans_media")])
10577 (define_insn "fipr"
10578   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10579         (plus:SF (plus:SF (vec_select:SF (mult:V4SF (match_operand:V4SF 1
10580                                                     "fp_arith_reg_operand" "f")
10581                                                    (match_operand:V4SF 2
10582                                                     "fp_arith_reg_operand" "f"))
10583                                          (parallel [(const_int 0)]))
10584                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10585                                          (parallel [(const_int 1)])))
10586                  (plus:SF (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10587                                          (parallel [(const_int 2)]))
10588                           (vec_select:SF (mult:V4SF (match_dup 1) (match_dup 2))
10589                                          (parallel [(const_int 3)])))))]
10590   "TARGET_SHMEDIA"
10591   "fipr.s       %1, %2, %0"
10592   [(set_attr "type" "fparith_media")])
10594 (define_insn "fsrra_s"
10595   [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f")
10596         (unspec:SF [(match_operand:SF 1 "fp_arith_reg_operand" "f")]
10597                    UNSPEC_FSRRA))]
10598   "TARGET_SHMEDIA"
10599   "fsrra.s      %1, %0"
10600   [(set_attr "type" "atrans_media")])
10602 (define_insn "ftrv"
10603   [(set (match_operand:V4SF 0 "fp_arith_reg_operand" "=f")
10604         (plus:V4SF
10605          (plus:V4SF
10606           (mult:V4SF
10607            (vec_select:V4SF (match_operand:V16SF 1 "fp_arith_reg_operand" "f")
10608                             (parallel [(const_int 0) (const_int 5)
10609                                        (const_int 10) (const_int 15)]))
10610            (match_operand:V4SF 2 "fp_arith_reg_operand" "f"))
10611           (mult:V4SF
10612            (vec_select:V4SF (match_dup 1)
10613                             (parallel [(const_int 4) (const_int 9)
10614                                        (const_int 14) (const_int 3)]))
10615            (vec_select:V4SF (match_dup 2)
10616                             (parallel [(const_int 1) (const_int 2)
10617                                        (const_int 3) (const_int 0)]))))
10618          (plus:V4SF
10619           (mult:V4SF
10620            (vec_select:V4SF (match_dup 1)
10621                             (parallel [(const_int 8) (const_int 13)
10622                                        (const_int 2) (const_int 7)]))
10623            (vec_select:V4SF (match_dup 2)
10624                             (parallel [(const_int 2) (const_int 3)
10625                                        (const_int 0) (const_int 1)])))
10626           (mult:V4SF
10627            (vec_select:V4SF (match_dup 1)
10628                             (parallel [(const_int 12) (const_int 1)
10629                                        (const_int 6) (const_int 11)]))
10630            (vec_select:V4SF (match_dup 2)
10631                             (parallel [(const_int 3) (const_int 0)
10632                                        (const_int 1) (const_int 2)]))))))]
10633   "TARGET_SHMEDIA"
10634   "ftrv.s %1, %2, %0"
10635   [(set_attr "type" "fparith_media")])
10637 (define_insn "nsb"
10638   [(set (match_operand:QI 0 "arith_reg_dest" "=r")
10639         (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10640                    UNSPEC_NSB))]
10641   "TARGET_SHMEDIA"
10642   "nsb  %1, %0"
10643   [(set_attr "type" "arith_media")])
10645 (define_insn "nsbsi"
10646   [(set (match_operand:SI 0 "arith_reg_dest" "=r")
10647         (zero_extend:SI
10648          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10649                     UNSPEC_NSB)))]
10650   "TARGET_SHMEDIA"
10651   "nsb  %1, %0"
10652   [(set_attr "type" "arith_media")])
10654 (define_insn "nsbdi"
10655   [(set (match_operand:DI 0 "arith_reg_dest" "=r")
10656         (zero_extend:DI
10657          (unspec:QI [(match_operand:DI 1 "arith_reg_operand" "r")]
10658                     UNSPEC_NSB)))]
10659   "TARGET_SHMEDIA"
10660   "nsb  %1, %0"
10661   [(set_attr "type" "arith_media")])
10663 (define_expand "ffsdi2"
10664   [(set (match_operand:DI 0 "arith_reg_dest" "")
10665         (ffs:DI (match_operand:DI 1 "arith_reg_operand" "")))]
10666   "TARGET_SHMEDIA"
10667   "
10669   rtx scratch = gen_reg_rtx (DImode);
10670   rtx last;
10672   emit_insn (gen_adddi3 (scratch, operands[1], GEN_INT (-1)));
10673   emit_insn (gen_xordi3 (scratch, operands[1], scratch));
10674   emit_insn (gen_lshrdi3_media (scratch, scratch, const1_rtx));
10675   emit_insn (gen_nsbdi (scratch, scratch));
10676   emit_insn (gen_adddi3 (scratch, scratch, GEN_INT (-64)));
10677   emit_insn (gen_movdicc_false (scratch, operands[1], const0_rtx, scratch));
10678   last = emit_insn (gen_subdi3 (operands[0], const0_rtx, scratch));
10679   REG_NOTES (last)
10680     = gen_rtx_EXPR_LIST (REG_EQUAL,
10681                          gen_rtx_FFS (DImode, operands[0]), REG_NOTES (last));
10682   DONE;
10685 (define_expand "ffssi2"
10686   [(set (match_operand:SI 0 "arith_reg_dest" "")
10687         (ffs:SI (match_operand:SI 1 "arith_reg_operand" "")))]
10688   "TARGET_SHMEDIA"
10689   "
10691   rtx scratch = gen_reg_rtx (SImode);
10692   rtx discratch = gen_reg_rtx (DImode);
10693   rtx last;
10695   emit_insn (gen_adddi3 (discratch,
10696                          simplify_gen_subreg (DImode, operands[1], SImode, 0),
10697                          GEN_INT (-1)));
10698   emit_insn (gen_andcdi3 (discratch,
10699                           simplify_gen_subreg (DImode, operands[1], SImode, 0),
10700                           discratch));
10701   emit_insn (gen_nsbsi (scratch, discratch));
10702   last = emit_insn (gen_subsi3 (operands[0],
10703                                 force_reg (SImode, GEN_INT (63)), scratch));
10704   REG_NOTES (last)
10705     = gen_rtx_EXPR_LIST (REG_EQUAL,
10706                          gen_rtx_FFS (SImode, operands[0]), REG_NOTES (last));
10707   DONE;
10710 (define_insn "byterev"
10711   [(set (match_operand:V8QI 0 "arith_reg_dest" "=r")
10712         (vec_select:V8QI (match_operand:V8QI 1 "arith_reg_operand" "r")
10713                          (parallel [(const_int 7) (const_int 6) (const_int 5)
10714                                     (const_int 4) (const_int 3) (const_int 2)
10715                                     (const_int 1) (const_int 0)])))]
10716   "TARGET_SHMEDIA"
10717   "byterev      %1, %0"
10718   [(set_attr "type" "arith_media")])
10720 (define_insn "prefetch"
10721   [(prefetch (match_operand:QI 0 "address_operand" "p")
10722              (match_operand:SI 1 "const_int_operand" "n")
10723              (match_operand:SI 2 "const_int_operand" "n"))]
10724   "TARGET_SHMEDIA"
10725   "*
10727   operands[0] = gen_rtx_MEM (QImode, operands[0]);
10728   output_asm_insn (\"ld%M0.b    %m0,r63\", operands);
10729   return \"\";
10731   [(set_attr "type" "other")])
10733 ;; The following description  models the
10734 ;; SH4 pipeline using the DFA based scheduler.
10735 ;; The DFA based description is better way to model
10736 ;; a superscalar pipeline as compared to function unit
10737 ;; reservation model.
10738 ;; 1. The function unit based model is oriented to describe at most one
10739 ;;    unit reservation by each insn. It is difficult to model unit reservations in multiple
10740 ;;    pipeline units by same insn. This can be done using DFA based description.
10741 ;; 2. The execution performance of DFA based scheduler does not depend on processor complexity.
10742 ;; 3. Writing all unit reservations for an instruction class is more natural description
10743 ;;    of the pipeline and makes interface of the hazard recognizer simpler than the
10744 ;;    old function unit based model.
10745 ;; 4. The DFA model is richer and is a part of greater overall framework of RCSP.
10748 ;; Two automata are defined to reduce number of states
10749 ;; which a single large automaton will have.(Factoring)
10751 (define_automaton "inst_pipeline,fpu_pipe")
10753 ;; This unit is basically the decode unit of the processor.
10754 ;; Since SH4 is a dual issue machine,it is as if there are two
10755 ;; units so that any insn can be processed by either one
10756 ;; of the decoding unit.
10758 (define_cpu_unit "pipe_01,pipe_02" "inst_pipeline")
10761 ;; The fixed point arithmetic calculator(?? EX Unit).
10763 (define_cpu_unit  "int" "inst_pipeline")
10765 ;; f1_1 and f1_2 are floating point units.Actually there is
10766 ;; a f1 unit which can overlap with other f1 unit but
10767 ;; not another F1 unit.It is as though there were two
10768 ;; f1 units.
10770 (define_cpu_unit "f1_1,f1_2" "fpu_pipe")
10772 ;; The floating point units (except FS - F2 always precedes it.)
10774 (define_cpu_unit "F0,F1,F2,F3" "fpu_pipe")
10776 ;; This is basically the MA unit of SH4
10777 ;; used in LOAD/STORE pipeline.
10779 (define_cpu_unit "memory" "inst_pipeline")
10781 ;; However, there are LS group insns that don't use it, even ones that
10782 ;; complete in 0 cycles.  So we use an extra unit for the issue of LS insns.
10783 (define_cpu_unit "load_store" "inst_pipeline")
10785 ;; The address calculator used for branch instructions.
10786 ;; This will be reserved after "issue" of branch instructions
10787 ;; and this is to make sure that no two branch instructions
10788 ;; can be issued in parallel.
10790 (define_cpu_unit "pcr_addrcalc" "inst_pipeline")
10792 ;; ----------------------------------------------------
10793 ;; This reservation is to simplify the dual issue description.
10795 (define_reservation  "issue"  "pipe_01|pipe_02")
10797 ;; This is to express the locking of D stage.
10798 ;; Note that the issue of a CO group insn also effectively locks the D stage.
10800 (define_reservation  "d_lock" "pipe_01+pipe_02")
10802 ;; Every FE instruction but fipr / ftrv starts with issue and this.
10803 (define_reservation "F01" "F0+F1")
10805 ;; This is to simplify description where F1,F2,FS
10806 ;; are used simultaneously.
10808 (define_reservation "fpu" "F1+F2")
10810 ;; This is to highlight the fact that f1
10811 ;; cannot overlap with F1.
10813 (exclusion_set  "f1_1,f1_2" "F1")
10815 (define_insn_reservation "nil" 0 (eq_attr "type" "nil") "nothing")
10817 ;; Although reg moves have a latency of zero
10818 ;; we need to highlight that they use D stage
10819 ;; for one cycle.
10821 ;; Group:       MT
10823 (define_insn_reservation "reg_mov" 0
10824   (and (eq_attr "pipe_model" "sh4")
10825        (eq_attr "type" "move"))
10826   "issue")
10828 ;; Group:       LS
10830 (define_insn_reservation "freg_mov" 0
10831   (and (eq_attr "pipe_model" "sh4")
10832        (eq_attr "type" "fmove"))
10833   "issue+load_store")
10835 ;; We don't model all pipeline stages; we model the issue ('D') stage
10836 ;; inasmuch as we allow only two instructions to issue simultaneously,
10837 ;; and CO instructions prevent any simultaneous issue of another instruction.
10838 ;; (This uses pipe_01 and pipe_02).
10839 ;; Double issue of EX insns is prevented by using the int unit in the EX stage.
10840 ;; Double issue of EX / BR insns is prevented by using the int unit /
10841 ;; pcr_addrcalc unit in the EX stage.
10842 ;; Double issue of BR / LS instructions is prevented by using the
10843 ;; pcr_addrcalc / load_store unit in the issue cycle.
10844 ;; Double issue of FE instructions is prevented by using F0 in the first
10845 ;; pipeline stage after the first D stage.
10846 ;; There is no need to describe the [ES]X / [MN]A / S stages after a D stage
10847 ;; (except in the cases outlined above), nor to describe the FS stage after
10848 ;; the F2 stage.
10850 ;; Other MT  group instructions(1 step operations)
10851 ;; Group:       MT
10852 ;; Latency:     1
10853 ;; Issue Rate:  1
10855 (define_insn_reservation "mt" 1
10856   (and (eq_attr "pipe_model" "sh4")
10857        (eq_attr "type" "mt_group"))
10858   "issue")
10860 ;; Fixed Point Arithmetic Instructions(1 step operations)
10861 ;; Group:       EX
10862 ;; Latency:     1
10863 ;; Issue Rate:  1
10865 (define_insn_reservation "sh4_simple_arith" 1
10866   (and (eq_attr "pipe_model" "sh4")
10867        (eq_attr "insn_class" "ex_group"))
10868   "issue,int")
10870 ;; Load and store instructions have no alignment peculiarities for the SH4,
10871 ;; but they use the load-store unit, which they share with the fmove type
10872 ;; insns (fldi[01]; fmov frn,frm; flds; fsts; fabs; fneg) .
10873 ;; Loads have a latency of two.
10874 ;; However, call insns can only paired with a preceding insn, and have
10875 ;; a delay slot, so that we want two more insns to be scheduled between the
10876 ;; load of the function address and the call.  This is equivalent to a
10877 ;; latency of three.
10878 ;; ADJUST_COST can only properly handle reductions of the cost, so we
10879 ;; use a latency of three here, which gets multiplied by 10 to yield 30.
10880 ;; We only do this for SImode loads of general registers, to make the work
10881 ;; for ADJUST_COST easier.
10883 ;; Load Store instructions. (MOV.[BWL]@(d,GBR)
10884 ;; Group:       LS
10885 ;; Latency:     2
10886 ;; Issue Rate:  1
10888 (define_insn_reservation "sh4_load" 2
10889   (and (eq_attr "pipe_model" "sh4")
10890        (eq_attr "type" "load,pcload"))
10891   "issue+load_store,nothing,memory")
10893 ;; calls / sfuncs need an extra instruction for their delay slot.
10894 ;; Moreover, estimating the latency for SImode loads as 3 will also allow
10895 ;; adjust_cost to meaningfully bump it back up to 3 if they load the shift
10896 ;; count of a dynamic shift.
10897 (define_insn_reservation "sh4_load_si" 3
10898   (and (eq_attr "pipe_model" "sh4")
10899        (eq_attr "type" "load_si,pcload_si"))
10900   "issue+load_store,nothing,memory")
10902 ;; (define_bypass 2 "sh4_load_si" "!sh4_call")
10904 ;; The load latency is upped to three higher if the dependent insn does
10905 ;; double precision computation.  We want the 'default' latency to reflect
10906 ;; that increased latency because otherwise the insn priorities won't
10907 ;; allow proper scheduling.
10908 (define_insn_reservation "sh4_fload" 3
10909   (and (eq_attr "pipe_model" "sh4")
10910        (eq_attr "type" "fload,pcfload"))
10911   "issue+load_store,nothing,memory")
10913 ;; (define_bypass 2 "sh4_fload" "!")
10915 (define_insn_reservation "sh4_store" 1
10916   (and (eq_attr "pipe_model" "sh4")
10917        (eq_attr "type" "store"))
10918   "issue+load_store,nothing,memory")
10920 ;; Load Store instructions.
10921 ;; Group:       LS
10922 ;; Latency:     1
10923 ;; Issue Rate:  1
10925 (define_insn_reservation "sh4_gp_fpul" 1
10926   (and (eq_attr "pipe_model" "sh4")
10927        (eq_attr "type" "gp_fpul"))
10928   "issue+load_store")
10930 ;; Load Store instructions.
10931 ;; Group:       LS
10932 ;; Latency:     3
10933 ;; Issue Rate:  1
10935 (define_insn_reservation "sh4_fpul_gp" 3
10936   (and (eq_attr "pipe_model" "sh4")
10937        (eq_attr "type" "fpul_gp"))
10938   "issue+load_store")
10940 ;; Branch (BF,BF/S,BT,BT/S,BRA)
10941 ;; Group:       BR
10942 ;; Latency when taken:  2 (or 1)
10943 ;; Issue Rate:  1
10944 ;; The latency is 1 when displacement is 0.
10945 ;; We can't really do much with the latency, even if we could express it,
10946 ;; but the pairing restrictions are useful to take into account.
10947 ;; ??? If the branch is likely, we might want to fill the delay slot;
10948 ;; if the branch is likely, but not very likely, should we pretend to use
10949 ;; a resource that CO instructions use, to get a pairable delay slot insn?
10951 (define_insn_reservation "sh4_branch"  1
10952   (and (eq_attr "pipe_model" "sh4")
10953        (eq_attr "type" "cbranch,jump"))
10954   "issue+pcr_addrcalc")
10956 ;; Branch Far (JMP,RTS,BRAF)
10957 ;; Group:       CO
10958 ;; Latency:     3
10959 ;; Issue Rate:  2
10960 ;; ??? Scheduling happens before branch shortening, and hence jmp and braf
10961 ;; can't be distinguished from bra for the "jump" pattern.
10963 (define_insn_reservation "sh4_return" 3
10964   (and (eq_attr "pipe_model" "sh4")
10965        (eq_attr "type" "return,jump_ind"))
10966          "d_lock*2")
10968 ;; RTE
10969 ;; Group:       CO
10970 ;; Latency:     5
10971 ;; Issue Rate:  5
10972 ;; this instruction can be executed in any of the pipelines
10973 ;; and blocks the pipeline for next 4 stages.
10975 (define_insn_reservation "sh4_return_from_exp" 5
10976   (and (eq_attr "pipe_model" "sh4")
10977        (eq_attr "type" "rte"))
10978   "d_lock*5")
10980 ;; OCBP, OCBWB
10981 ;; Group:       CO
10982 ;; Latency:     1-5
10983 ;; Issue Rate:  1
10985 ;; cwb is used for the sequence ocbwb @%0; extu.w %0,%2; or %1,%2; mov.l %0,@%2
10986 ;; ocbwb on its own would be "d_lock,nothing,memory*5"
10987 (define_insn_reservation "ocbwb"  6
10988   (and (eq_attr "pipe_model" "sh4")
10989        (eq_attr "type" "cwb"))
10990   "d_lock*2,(d_lock+memory)*3,issue+load_store+memory,memory*2")
10992 ;; LDS to PR,JSR
10993 ;; Group:       CO
10994 ;; Latency:     3
10995 ;; Issue Rate:  2
10996 ;; The SX stage is blocked for last 2 cycles.
10997 ;; OTOH, the only time that has an effect for insns generated by the compiler
10998 ;; is when lds to PR is followed by sts from PR - and that is highly unlikely -
10999 ;; or when we are doing a function call - and we don't do inter-function
11000 ;; scheduling.  For the function call case, it's really best that we end with
11001 ;; something that models an rts.
11003 (define_insn_reservation "sh4_lds_to_pr" 3
11004   (and (eq_attr "pipe_model" "sh4")
11005        (eq_attr "type" "prset") )
11006   "d_lock*2")
11008 ;; calls introduce a longisch delay that is likely to flush the pipelines
11009 ;; of the caller's instructions.  Ordinary functions tend to end with a
11010 ;; load to restore a register (in the delay slot of rts), while sfuncs
11011 ;; tend to end with an EX or MT insn.  But that is not actually relevant,
11012 ;; since there are no instructions that contend for memory access early.
11013 ;; We could, of course, provide exact scheduling information for specific
11014 ;; sfuncs, if that should prove useful.
11016 (define_insn_reservation "sh4_call" 16
11017   (and (eq_attr "pipe_model" "sh4")
11018        (eq_attr "type" "call,sfunc"))
11019   "d_lock*16")
11021 ;; LDS.L to PR
11022 ;; Group:       CO
11023 ;; Latency:     3
11024 ;; Issue Rate:  2
11025 ;; The SX unit is blocked for last 2 cycles.
11027 (define_insn_reservation "ldsmem_to_pr"  3
11028   (and (eq_attr "pipe_model" "sh4")
11029        (eq_attr "type" "pload"))
11030   "d_lock*2")
11032 ;; STS from PR
11033 ;; Group:       CO
11034 ;; Latency:     2
11035 ;; Issue Rate:  2
11036 ;; The SX unit in second and third cycles.
11038 (define_insn_reservation "sts_from_pr" 2
11039   (and (eq_attr "pipe_model" "sh4")
11040        (eq_attr "type" "prget"))
11041   "d_lock*2")
11043 ;; STS.L from PR
11044 ;; Group:       CO
11045 ;; Latency:     2
11046 ;; Issue Rate:  2
11048 (define_insn_reservation "sh4_prstore_mem" 2
11049   (and (eq_attr "pipe_model" "sh4")
11050        (eq_attr "type" "pstore"))
11051   "d_lock*2,nothing,memory")
11053 ;; LDS to FPSCR
11054 ;; Group:       CO
11055 ;; Latency:     4
11056 ;; Issue Rate:  1
11057 ;; F1 is blocked for last three cycles.
11059 (define_insn_reservation "fpscr_load" 4
11060   (and (eq_attr "pipe_model" "sh4")
11061        (eq_attr "type" "gp_fpscr"))
11062   "d_lock,nothing,F1*3")
11064 ;; LDS.L to FPSCR
11065 ;; Group:       CO
11066 ;; Latency:     1 / 4
11067 ;; Latency to update Rn is 1 and latency to update FPSCR is 4
11068 ;; Issue Rate:  1
11069 ;; F1 is blocked for last three cycles.
11071 (define_insn_reservation "fpscr_load_mem" 4
11072   (and (eq_attr "pipe_model" "sh4")
11073        (eq_attr "type"  "mem_fpscr"))
11074   "d_lock,nothing,(F1+memory),F1*2")
11077 ;; Fixed point multiplication (DMULS.L DMULU.L MUL.L MULS.W,MULU.W)
11078 ;; Group:       CO
11079 ;; Latency:     4 / 4
11080 ;; Issue Rate:  1
11082 (define_insn_reservation "multi" 4
11083   (and (eq_attr "pipe_model" "sh4")
11084        (eq_attr "type" "smpy,dmpy"))
11085   "d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2")
11087 ;; Fixed STS from MACL / MACH
11088 ;; Group:       CO
11089 ;; Latency:     3
11090 ;; Issue Rate:  1
11092 (define_insn_reservation "sh4_mac_gp" 3
11093   (and (eq_attr "pipe_model" "sh4")
11094        (eq_attr "type" "mac_gp"))
11095   "d_lock")
11098 ;; Single precision floating point computation FCMP/EQ,
11099 ;; FCMP/GT, FADD, FLOAT, FMAC, FMUL, FSUB, FTRC, FRVHG, FSCHG
11100 ;; Group:       FE
11101 ;; Latency:     3/4
11102 ;; Issue Rate:  1
11104 (define_insn_reservation "fp_arith"  3
11105   (and (eq_attr "pipe_model" "sh4")
11106        (eq_attr "type" "fp"))
11107   "issue,F01,F2")
11109 (define_insn_reservation "fp_arith_ftrc"  3
11110   (and (eq_attr "pipe_model" "sh4")
11111        (eq_attr "type" "ftrc_s"))
11112   "issue,F01,F2")
11114 (define_bypass 1 "fp_arith_ftrc" "sh4_fpul_gp")
11116 ;; Single Precision FDIV/SQRT
11117 ;; Group:       FE
11118 ;; Latency:     12/13 (FDIV); 11/12 (FSQRT)
11119 ;; Issue Rate:  1
11120 ;; We describe fdiv here; fsqrt is actually one cycle faster.
11122 (define_insn_reservation "fp_div" 12
11123   (and (eq_attr "pipe_model" "sh4")
11124        (eq_attr "type" "fdiv"))
11125   "issue,F01+F3,F2+F3,F3*7,F1+F3,F2")
11127 ;; Double Precision floating point computation
11128 ;; (FCNVDS, FCNVSD, FLOAT, FTRC)
11129 ;; Group:       FE
11130 ;; Latency:     (3,4)/5
11131 ;; Issue Rate:  1
11133 (define_insn_reservation "dp_float" 4
11134   (and (eq_attr "pipe_model" "sh4")
11135        (eq_attr "type" "dfp_conv"))
11136   "issue,F01,F1+F2,F2")
11138 ;; Double-precision floating-point (FADD,FMUL,FSUB)
11139 ;; Group:       FE
11140 ;; Latency:     (7,8)/9
11141 ;; Issue Rate:  1
11143 (define_insn_reservation "fp_double_arith" 8
11144   (and (eq_attr "pipe_model" "sh4")
11145        (eq_attr "type" "dfp_arith"))
11146   "issue,F01,F1+F2,fpu*4,F2")
11148 ;; Double-precision FCMP (FCMP/EQ,FCMP/GT)
11149 ;; Group:       CO
11150 ;; Latency:     3/5
11151 ;; Issue Rate:  2
11153 (define_insn_reservation "fp_double_cmp" 3
11154   (and (eq_attr "pipe_model" "sh4")
11155        (eq_attr "type" "dfp_cmp"))
11156   "d_lock,(d_lock+F01),F1+F2,F2")
11158 ;; Double precision FDIV/SQRT
11159 ;; Group:       FE
11160 ;; Latency:     (24,25)/26
11161 ;; Issue Rate:  1
11163 (define_insn_reservation "dp_div" 25
11164   (and (eq_attr "pipe_model" "sh4")
11165        (eq_attr "type" "dfdiv"))
11166   "issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2")
11169 ;; Use the branch-not-taken case to model arith3 insns.  For the branch taken
11170 ;; case, we'd get a d_lock instead of issue at the end.
11171 (define_insn_reservation "arith3" 3
11172   (and (eq_attr "pipe_model" "sh4")
11173        (eq_attr "type" "arith3"))
11174   "issue,d_lock+pcr_addrcalc,issue")
11176 ;; arith3b insns schedule the same no matter if the branch is taken or not.
11177 (define_insn_reservation "arith3b" 2
11178   (and (eq_attr "pipe_model" "sh4")
11179        (eq_attr "type" "arith3"))
11180   "issue,d_lock+pcr_addrcalc")